Skip to content

Commit 27a8a7e

Browse files
authored
Merge pull request #22779 from hvitved/unified-constructor-instance-static
Unified: Add constructors to both static and instance namespaces
2 parents 0490821 + f122c30 commit 27a8a7e

6 files changed

Lines changed: 42 additions & 12 deletions

File tree

‎unified/ql/lib/codeql/unified/internal/NameBindingPlugin.qll‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,27 @@ class NameBindingPlugin extends Unit {
5656

5757
/** Holds if `member` is an instance member. */
5858
predicate isInstanceMember(Member member) {
59-
(member instanceof VariableDeclaration or member instanceof FunctionDeclaration) and
59+
(
60+
member instanceof VariableDeclaration or
61+
member instanceof FunctionDeclaration or
62+
member instanceof ConstructorDeclaration
63+
) and
6064
exists(ClassLikeDeclaration cls | cls.getAMember() = member |
6165
any(NameBindingPlugin p).isInstanceMember(cls, member)
6266
)
6367
}
6468

6569
/**
6670
* Holds if `member` is a non-instance member declared in the context of a class or top-level.
71+
*
72+
* Instance constructors are also considered static members, in order to be able to look them
73+
* up as both instance members (`self.init()`) and static members (`C1.init()`).
6774
*/
6875
predicate isStaticMember(Member member) {
6976
exists(ClassLikeDeclaration cls | cls.getAMember() = member |
7077
not any(NameBindingPlugin p).isInstanceMember(cls, member)
78+
or
79+
member instanceof ConstructorDeclaration
7180
)
7281
or
7382
member = any(TopLevel t).getBody().getAStmt()

‎unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,13 @@ predicate storeStep(NameBindingNode node1, string name, NameBindingNode node2) {
191191
not isPrivateToLocalScope(nameDecl) and
192192
nameDecl.getDeclaration() = member and
193193
node1.isIdentifier(nameDecl) and
194-
name = nameDecl.getName() and
195-
if isInstanceMember(member)
196-
then node2.isInstanceMemberNamespace(cls)
197-
else node2.isStaticMemberNamespace(cls)
194+
name = nameDecl.getName()
195+
|
196+
isInstanceMember(member) and
197+
node2.isInstanceMemberNamespace(cls)
198+
or
199+
isStaticMember(member) and
200+
node2.isStaticMemberNamespace(cls)
198201
)
199202
or
200203
exists(TopLevel top, Stmt stmt, NameBinding nameDecl |

‎unified/ql/lib/codeql/unified/internal/typeinference/TypeInference.qll‎

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -300,13 +300,6 @@ private module Input3 implements InputSig3 {
300300
override AstNode getBody() { result = ConstructorDeclaration.super.getBody() }
301301

302302
override Identifier getNameNode() { result = ConstructorDeclaration.super.getNameNode() }
303-
304-
override predicate isMemberOf(ClassLikeDeclaration cls, Identifier i, string name) {
305-
// todo: constructors can be inherited
306-
this = cls.getAMember() and
307-
i = this.getNameNode() and
308-
name = i.getValue()
309-
}
310303
}
311304

312305
private class EnumConstructorCallable extends ConstructorDeclarationCallable instanceof EnumConstructor

‎unified/ql/test/library-tests/static-name-binding/test.swift‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,7 @@ extension H // $ access=H1
7070

7171
extension A.B.C // $ access=A access=A.B access=A.B.C
7272
: P { } // $ access=P
73+
74+
A() // $ access=A
75+
76+
A.init() // $ access=A access=A.init
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class C1 {
2+
init(_ x: Int) {} // name=C1.init
3+
4+
convenience init() { // name=C1.init_conv
5+
self.init(0) // $ target=C1.init $ SPURIOUS: target=C1.init_conv
6+
}
7+
}
8+
9+
var c11 = C1() // $ type=c11:C1 target=C1.init_conv $ SPURIOUS: target=C1.init
10+
var c12 = C1.init() // $ type=c12:C1 target=C1.init_conv $ SPURIOUS: target=C1.init

‎unified/ql/test/library-tests/type-inference/type-inference.expected‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ inferCertainType
127127
| closures.swift:61:14:61:16 | arg | | closures.swift:60:12:60:13 | T1 |
128128
| closures.swift:66:9:68:9 | FunctionExpr | | {EXTERNAL LOCATION} | Function |
129129
| closures.swift:66:9:68:9 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 |
130+
| constructors.swift:2:12:2:12 | x | | {EXTERNAL LOCATION} | Int |
131+
| constructors.swift:5:9:5:12 | self | | constructors.swift:1:1:7:1 | C1 |
130132
| fields.swift:2:7:2:20 | inheritedField | | {EXTERNAL LOCATION} | Int |
131133
| fields.swift:6:7:6:17 | storedField | | {EXTERNAL LOCATION} | String |
132134
| fields.swift:7:7:7:18 | genericField | | fields.swift:5:22:5:22 | T |
@@ -1047,6 +1049,15 @@ inferType
10471049
| closures.swift:69:5:69:5 | _ | | {EXTERNAL LOCATION} | String |
10481050
| closures.swift:69:5:69:14 | ... = ... | | {EXTERNAL LOCATION} | String |
10491051
| closures.swift:69:9:69:14 | result | | {EXTERNAL LOCATION} | String |
1052+
| constructors.swift:2:12:2:12 | x | | {EXTERNAL LOCATION} | Int |
1053+
| constructors.swift:4:24:6:5 | Block | | constructors.swift:1:1:7:1 | C1 |
1054+
| constructors.swift:5:9:5:12 | self | | constructors.swift:1:1:7:1 | C1 |
1055+
| constructors.swift:5:9:5:20 | ... .init(...) | | constructors.swift:1:1:7:1 | C1 |
1056+
| constructors.swift:5:19:5:19 | 0 | | {EXTERNAL LOCATION} | Int |
1057+
| constructors.swift:9:5:9:7 | c11 | | constructors.swift:1:1:7:1 | C1 |
1058+
| constructors.swift:9:11:9:14 | C1(...) | | constructors.swift:1:1:7:1 | C1 |
1059+
| constructors.swift:10:5:10:7 | c12 | | constructors.swift:1:1:7:1 | C1 |
1060+
| constructors.swift:10:11:10:19 | ... .init(...) | | constructors.swift:1:1:7:1 | C1 |
10501061
| fields.swift:2:7:2:20 | inheritedField | | {EXTERNAL LOCATION} | Int |
10511062
| fields.swift:2:29:2:29 | 0 | | {EXTERNAL LOCATION} | Int |
10521063
| fields.swift:6:7:6:17 | storedField | | {EXTERNAL LOCATION} | String |

0 commit comments

Comments
 (0)