Skip to content

Commit 18f3668

Browse files
authored
Merge pull request #22299 from asgerf/unified/static-name-binding
Unified: Add static name binding pass
2 parents 69573f4 + 719e8b4 commit 18f3668

45 files changed

Lines changed: 1929 additions & 123 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

shared/namebinding/codeql/namebinding/LocalNameBinding.qll

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,12 @@ signature module LocalNameBindingInputSig<LocationSig Location> {
136136
* full control of scope resolution for specific types of references.
137137
*/
138138
default predicate lookupStartsAt(AstNode n, AstNode scope) { none() }
139+
140+
/**
141+
* Holds if the set of names available in `scope` is not known ahead of time,
142+
* and thus any lookup chain that goes through `scope` may need to be reconciled at a later stage.
143+
*/
144+
default predicate uncertainScope(AstNode scope) { none() }
139145
}
140146

141147
/**
@@ -154,6 +160,8 @@ module LocalNameBinding<LocationSig Location, LocalNameBindingInputSig<Location>
154160
implicitDeclInScope(_, this)
155161
or
156162
isTopScope(this)
163+
or
164+
uncertainScope(this)
157165
}
158166
}
159167

@@ -346,13 +354,37 @@ module LocalNameBinding<LocationSig Location, LocalNameBindingInputSig<Location>
346354
or
347355
exists(Scope mid |
348356
lookupInScope(name, lookup, mid) and
349-
not declInScope(_, name, mid) and
350-
not implicitDeclInScope(name, mid) and
357+
not declInScope(name, mid) and
351358
not isTopScope(mid) and
352359
scope = getEnclosingScope(mid)
353360
)
354361
}
355362

363+
private predicate declInScope(string name, AstNode scope) {
364+
declInScope(_, name, scope) or
365+
implicitDeclInScope(name, scope)
366+
}
367+
368+
/**
369+
* Holds if `name`, when resolved from `lookup`, may resolve to one of the uncertain members of `scope`.
370+
*/
371+
pragma[nomagic]
372+
private predicate lookupInUncertainScope(string name, Scope lookup, Scope scope) {
373+
lookupInScope(name, lookup, scope) and
374+
uncertainScope(scope) and
375+
not declInScope(name, scope)
376+
}
377+
378+
/**
379+
* Gets an uncertain scope in which the `accessCand` pair may resolve.
380+
*/
381+
AstNode getAnUncertainScope(AstNode access, string name) {
382+
exists(Scope lookup |
383+
accessCandInLookupScope(access, name, lookup) and
384+
lookupInUncertainScope(name, lookup, result)
385+
)
386+
}
387+
356388
cached
357389
private newtype TLocal =
358390
TExplicitLocal(AstNode definingNode, string name, AstNode scope) {

unified/extractor/ast_types.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ named:
413413
name_pattern:
414414
modifier*: modifier
415415
identifier: identifier
416+
sub_pattern?: pattern
416417

417418
# A pattern matching anything, binding no variables, usually using the syntax "_"
418419
ignore_pattern:

unified/extractor/src/languages/swift/swift.rs

Lines changed: 145 additions & 74 deletions
Large diffs are not rendered by default.
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
switch event {
2+
case let .received(.some(value), timestamp):
3+
print(value, timestamp)
4+
case Type.some(let value):
5+
print(value)
6+
default:
7+
break
8+
}
9+
10+
---
11+
12+
sourceFile
13+
endOfFileToken: endOfFile
14+
statements:
15+
codeBlockItem
16+
item:
17+
expressionStmt
18+
expression:
19+
switchExpr
20+
leftBrace: {
21+
rightBrace: }
22+
cases:
23+
switchCase
24+
label:
25+
switchCaseLabel
26+
colon: :
27+
caseKeyword: case
28+
caseItems:
29+
switchCaseItem
30+
pattern:
31+
valueBindingPattern
32+
pattern:
33+
expressionPattern
34+
expression:
35+
functionCallExpr
36+
leftParen: (
37+
rightParen: )
38+
arguments:
39+
labeledExpr
40+
expression:
41+
functionCallExpr
42+
leftParen: (
43+
rightParen: )
44+
arguments:
45+
labeledExpr
46+
expression:
47+
patternExpr
48+
pattern:
49+
identifierPattern
50+
identifier: identifier "value"
51+
additionalTrailingClosures:
52+
calledExpression:
53+
memberAccessExpr
54+
period: .
55+
declName:
56+
declReferenceExpr
57+
baseName: identifier "some"
58+
trailingComma: ,
59+
labeledExpr
60+
expression:
61+
patternExpr
62+
pattern:
63+
identifierPattern
64+
identifier: identifier "timestamp"
65+
additionalTrailingClosures:
66+
calledExpression:
67+
memberAccessExpr
68+
period: .
69+
declName:
70+
declReferenceExpr
71+
baseName: identifier "received"
72+
bindingSpecifier: let
73+
statements:
74+
codeBlockItem
75+
item:
76+
functionCallExpr
77+
leftParen: (
78+
rightParen: )
79+
arguments:
80+
labeledExpr
81+
expression:
82+
declReferenceExpr
83+
baseName: identifier "value"
84+
trailingComma: ,
85+
labeledExpr
86+
expression:
87+
declReferenceExpr
88+
baseName: identifier "timestamp"
89+
additionalTrailingClosures:
90+
calledExpression:
91+
declReferenceExpr
92+
baseName: identifier "print"
93+
switchCase
94+
label:
95+
switchCaseLabel
96+
colon: :
97+
caseKeyword: case
98+
caseItems:
99+
switchCaseItem
100+
pattern:
101+
expressionPattern
102+
expression:
103+
functionCallExpr
104+
leftParen: (
105+
rightParen: )
106+
arguments:
107+
labeledExpr
108+
expression:
109+
patternExpr
110+
pattern:
111+
valueBindingPattern
112+
pattern:
113+
identifierPattern
114+
identifier: identifier "value"
115+
bindingSpecifier: let
116+
additionalTrailingClosures:
117+
calledExpression:
118+
memberAccessExpr
119+
period: .
120+
declName:
121+
declReferenceExpr
122+
baseName: identifier "some"
123+
base:
124+
declReferenceExpr
125+
baseName: identifier "Type"
126+
statements:
127+
codeBlockItem
128+
item:
129+
functionCallExpr
130+
leftParen: (
131+
rightParen: )
132+
arguments:
133+
labeledExpr
134+
expression:
135+
declReferenceExpr
136+
baseName: identifier "value"
137+
additionalTrailingClosures:
138+
calledExpression:
139+
declReferenceExpr
140+
baseName: identifier "print"
141+
switchCase
142+
label:
143+
switchDefaultLabel
144+
colon: :
145+
defaultKeyword: default
146+
statements:
147+
codeBlockItem
148+
item:
149+
breakStmt
150+
breakKeyword: break
151+
subject:
152+
declReferenceExpr
153+
baseName: identifier "event"
154+
switchKeyword: switch
155+
156+
---
157+
158+
top_level
159+
body:
160+
block
161+
stmt:
162+
switch_expr
163+
value:
164+
name_expr
165+
identifier: identifier "event"
166+
case:
167+
switch_case
168+
pattern:
169+
constructor_pattern
170+
constructor:
171+
member_access_expr
172+
base: inferred_type_expr "."
173+
member: identifier "received"
174+
element:
175+
pattern_element
176+
pattern:
177+
constructor_pattern
178+
constructor:
179+
member_access_expr
180+
base: inferred_type_expr "."
181+
member: identifier "some"
182+
element:
183+
pattern_element
184+
pattern:
185+
name_pattern
186+
identifier: identifier "value"
187+
pattern_element
188+
pattern:
189+
name_pattern
190+
identifier: identifier "timestamp"
191+
body:
192+
block
193+
stmt:
194+
call_expr
195+
callee:
196+
name_expr
197+
identifier: identifier "print"
198+
argument:
199+
argument
200+
value:
201+
name_expr
202+
identifier: identifier "value"
203+
argument
204+
value:
205+
name_expr
206+
identifier: identifier "timestamp"
207+
switch_case
208+
pattern:
209+
constructor_pattern
210+
constructor:
211+
member_access_expr
212+
base:
213+
name_expr
214+
identifier: identifier "Type"
215+
member: identifier "some"
216+
element:
217+
pattern_element
218+
pattern:
219+
name_pattern
220+
identifier: identifier "value"
221+
body:
222+
block
223+
stmt:
224+
call_expr
225+
callee:
226+
name_expr
227+
identifier: identifier "print"
228+
argument:
229+
argument
230+
value:
231+
name_expr
232+
identifier: identifier "value"
233+
switch_case
234+
body:
235+
block
236+
stmt: break_expr "break"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
switch event {
2+
case let .received(.some(value), timestamp):
3+
print(value, timestamp)
4+
case Type.some(let value):
5+
print(value)
6+
default:
7+
break
8+
}

unified/extractor/tests/corpus/swift/desugar/import-with-deeply-nested-path-three-parts.output

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,7 @@ top_level
3737
identifier: identifier "Foundation"
3838
member: identifier "Networking"
3939
member: identifier "URLSession"
40-
pattern: bulk_importing_pattern "import Foundation.Networking.URLSession"
40+
pattern:
41+
name_pattern
42+
identifier: identifier "URLSession"
43+
sub_pattern: bulk_importing_pattern "import Foundation.Networking.URLSession"

unified/extractor/tests/corpus/swift/desugar/import-with-dotted-path-two-parts.output

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,7 @@ top_level
3131
name_expr
3232
identifier: identifier "Foundation"
3333
member: identifier "Networking"
34-
pattern: bulk_importing_pattern "import Foundation.Networking"
34+
pattern:
35+
name_pattern
36+
identifier: identifier "Networking"
37+
sub_pattern: bulk_importing_pattern "import Foundation.Networking"

unified/extractor/tests/corpus/swift/desugar/simple-import-with-single-name.output

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,7 @@ top_level
2525
imported_expr:
2626
name_expr
2727
identifier: identifier "Foundation"
28-
pattern: bulk_importing_pattern "import Foundation"
28+
pattern:
29+
name_pattern
30+
identifier: identifier "Foundation"
31+
sub_pattern: bulk_importing_pattern "import Foundation"

0 commit comments

Comments
 (0)