Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
60baec6
unified: Add test showing problem with literal getValue()
asgerf Aug 6, 2026
51fe273
unified: Fix extraction of literals
asgerf Aug 6, 2026
b71ff8f
unified: Factor some code into CommentUtil.qll
asgerf Aug 6, 2026
c9fc793
unified: Fix mapping for compound type names
asgerf Aug 6, 2026
f50c80a
unified: Initial static name binding pass
asgerf Aug 6, 2026
375924e
unified: Track through aliases
asgerf Aug 6, 2026
db8b97a
unified: Add inheritance steps
asgerf Aug 6, 2026
6341bba
unified: Support unqualified access
asgerf Aug 6, 2026
ee8753b
unified: Allow numbers in key=value comments
asgerf Aug 6, 2026
7e3a4e3
unified: Cross-file name binding
asgerf Aug 6, 2026
574a5c9
unified: Handle bracketed generic array constructors
asgerf Aug 7, 2026
55b96f1
unified: Handle bracketed generic array metatypes
asgerf Aug 7, 2026
171aa7a
unified: Use '.' as location for inferred_type_expr
asgerf Aug 7, 2026
a9792e5
unified: Fix handling of exprPattern
asgerf Aug 7, 2026
8080bac
unified: Add newlines at EOF
asgerf Aug 7, 2026
0cf2871
unified: Update comment
asgerf Aug 7, 2026
a3f21a5
unified: Support scoped imports
asgerf Aug 7, 2026
50f934b
unified: Don't track trivial name aliasse
asgerf Aug 7, 2026
a79c32a
unified: Bulk imports
asgerf Aug 7, 2026
05fe395
unified: Fix access level in test case
asgerf Aug 7, 2026
659da08
unified: Fix incorrect expectation
asgerf Aug 7, 2026
35c54b1
unified: Fix toString and getLocation for TLocalNamespace
asgerf Aug 7, 2026
af2f5a2
unified: Remove location of TModuleRoot
asgerf Aug 7, 2026
b3adb93
unified: Fix handling of unscoped imports
asgerf Aug 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions shared/namebinding/codeql/namebinding/LocalNameBinding.qll
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ signature module LocalNameBindingInputSig<LocationSig Location> {
* full control of scope resolution for specific types of references.
*/
default predicate lookupStartsAt(AstNode n, AstNode scope) { none() }

/**
* Holds if the set of names available in `scope` is not known ahead of time,
* and thus any lookup chain that goes through `scope` may need to be reconciled at a later stage.
*/
default predicate uncertainScope(AstNode scope) { none() }
}

/**
Expand All @@ -154,6 +160,8 @@ module LocalNameBinding<LocationSig Location, LocalNameBindingInputSig<Location>
implicitDeclInScope(_, this)
or
isTopScope(this)
or
uncertainScope(this)
}
}

Expand Down Expand Up @@ -353,6 +361,27 @@ module LocalNameBinding<LocationSig Location, LocalNameBindingInputSig<Location>
)
}

/**
* Holds if `name`, when resolved from `lookup`, may resolve to one of the uncertain members of `scope`.
*/
pragma[nomagic]
private predicate lookupInUncertainScope(string name, Scope lookup, Scope scope) {
lookupInScope(name, lookup, scope) and
uncertainScope(scope) and
not declInScope(_, name, scope) and
not implicitDeclInScope(name, scope)
}

/**
* Gets an uncertain scope that the given `accessCand` pair may resolve to.
*/
AstNode getAnUncertainScope(AstNode access, string name) {
exists(Scope lookup |
accessCandInLookupScope(access, name, lookup) and
lookupInUncertainScope(name, lookup, result)
)
}

cached
private newtype TLocal =
TExplicitLocal(AstNode definingNode, string name, AstNode scope) {
Expand Down
1 change: 1 addition & 0 deletions unified/extractor/ast_types.yml
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@ named:
name_pattern:
modifier*: modifier
identifier: identifier
sub_pattern?: pattern

# A pattern matching anything, binding no variables, usually using the syntax "_"
ignore_pattern:
Expand Down
199 changes: 126 additions & 73 deletions unified/extractor/src/languages/swift/swift.rs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
switch event {
case let .received(.some(value), timestamp):
print(value, timestamp)
default:
break
}

---

sourceFile
endOfFileToken: endOfFile
statements:
codeBlockItem
item:
expressionStmt
expression:
switchExpr
leftBrace: {
rightBrace: }
cases:
switchCase
label:
switchCaseLabel
colon: :
caseKeyword: case
caseItems:
switchCaseItem
pattern:
valueBindingPattern
pattern:
expressionPattern
expression:
functionCallExpr
leftParen: (
rightParen: )
arguments:
labeledExpr
expression:
functionCallExpr
leftParen: (
rightParen: )
arguments:
labeledExpr
expression:
patternExpr
pattern:
identifierPattern
identifier: identifier "value"
additionalTrailingClosures:
calledExpression:
memberAccessExpr
period: .
declName:
declReferenceExpr
baseName: identifier "some"
trailingComma: ,
labeledExpr
expression:
patternExpr
pattern:
identifierPattern
identifier: identifier "timestamp"
additionalTrailingClosures:
calledExpression:
memberAccessExpr
period: .
declName:
declReferenceExpr
baseName: identifier "received"
bindingSpecifier: let
statements:
codeBlockItem
item:
functionCallExpr
leftParen: (
rightParen: )
arguments:
labeledExpr
expression:
declReferenceExpr
baseName: identifier "value"
trailingComma: ,
labeledExpr
expression:
declReferenceExpr
baseName: identifier "timestamp"
additionalTrailingClosures:
calledExpression:
declReferenceExpr
baseName: identifier "print"
switchCase
label:
switchDefaultLabel
colon: :
defaultKeyword: default
statements:
codeBlockItem
item:
breakStmt
breakKeyword: break
subject:
declReferenceExpr
baseName: identifier "event"
switchKeyword: switch

---

top_level
body:
block
stmt:
switch_expr
value:
name_expr
identifier: identifier "event"
case:
switch_case
pattern:
constructor_pattern
constructor:
member_access_expr
base: inferred_type_expr "."
member: identifier "received"
element:
pattern_element
pattern:
constructor_pattern
constructor:
member_access_expr
base: inferred_type_expr "."
member: identifier "some"
element:
pattern_element
pattern:
name_pattern
identifier: identifier "value"
pattern_element
pattern:
name_pattern
identifier: identifier "timestamp"
body:
block
stmt:
call_expr
callee:
name_expr
identifier: identifier "print"
argument:
argument
value:
name_expr
identifier: identifier "value"
argument
value:
name_expr
identifier: identifier "timestamp"
switch_case
body:
block
stmt: break_expr "break"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
switch event {
case let .received(.some(value), timestamp):
print(value, timestamp)
default:
break
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
let values = [Result<Void>]()

---

sourceFile
endOfFileToken: endOfFile
statements:
codeBlockItem
item:
variableDecl
attributes:
modifiers:
bindingSpecifier: let
bindings:
patternBinding
initializer:
initializerClause
equal: =
value:
functionCallExpr
leftParen: (
rightParen: )
arguments:
additionalTrailingClosures:
calledExpression:
arrayExpr
elements:
arrayElement
expression:
genericSpecializationExpr
expression:
declReferenceExpr
baseName: identifier "Result"
genericArgumentClause:
genericArgumentClause
arguments:
genericArgument
argument:
identifierType
name: identifier "Void"
leftAngle: <
rightAngle: >
leftSquare: [
rightSquare: ]
pattern:
identifierPattern
identifier: identifier "values"

---

top_level
body:
block
stmt:
variable_declaration
modifier: modifier "let"
pattern:
name_pattern
identifier: identifier "values"
value:
call_expr
callee:
generic_type_expr
base:
named_type_expr
name: identifier "Array"
type_argument:
generic_type_expr
base:
named_type_expr
name: identifier "Result"
type_argument:
named_type_expr
name: identifier "Void"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let values = [Result<Void>]()
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
let type = [Result<Void>].self

---

sourceFile
endOfFileToken: endOfFile
statements:
codeBlockItem
item:
variableDecl
attributes:
modifiers:
bindingSpecifier: let
bindings:
patternBinding
initializer:
initializerClause
equal: =
value:
memberAccessExpr
period: .
declName:
declReferenceExpr
baseName: self
base:
arrayExpr
elements:
arrayElement
expression:
genericSpecializationExpr
expression:
declReferenceExpr
baseName: identifier "Result"
genericArgumentClause:
genericArgumentClause
arguments:
genericArgument
argument:
identifierType
name: identifier "Void"
leftAngle: <
rightAngle: >
leftSquare: [
rightSquare: ]
pattern:
identifierPattern
identifier: identifier "type"

---

top_level
body:
block
stmt:
variable_declaration
modifier: modifier "let"
pattern:
name_pattern
identifier: identifier "type"
value:
member_access_expr
base:
generic_type_expr
base:
named_type_expr
name: identifier "Array"
type_argument:
generic_type_expr
base:
named_type_expr
name: identifier "Result"
type_argument:
named_type_expr
name: identifier "Void"
member: identifier "self"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let type = [Result<Void>].self
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ top_level
call_expr
callee:
member_access_expr
base: inferred_type_expr ".some"
base: inferred_type_expr "."
member: identifier "some"
argument:
argument
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@ top_level
identifier: identifier "x"
value:
member_access_expr
base: inferred_type_expr ".foo"
base: inferred_type_expr "."
member: identifier "foo"
Loading
Loading