| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
getValue() returns an empty string for various literals
This supports only a minimal set of features but sets up the structure we'll be using for supporting more features.
The restriction to classes was more permanent that anticipated, since top-level scopes instead target a TModuleScope
Scoped imports like 'import class B.C' are mapped to an AST of form
ImportDeclartion
pattern: NamePattern "C"
importedExpr: MemberAccessExpr
base: "B"
member: "C"
The NamePattern introduces a local alias for 'C', but unlike type aliases we also resolve to the ultimate target, when it's coming through an import.
Program was not valid unless these were public
Module names can only be referenced by an import declaration, they cannot appear directly on front of a type name unless the module is also imported.
An `import X` declaration now does two things: - X becomes a local name binding - X is bulk-imported into the local scope The AST mapping now maps it to X with a bulk-importing pattern as a sub-pattern. Module names can no longer be referenced anywhere except as the leading qualifier of an import statement.
There was a problem hiding this comment.
Adds Swift static name binding across classes, inheritance, modules, and imports, supported by extractor mapping improvements.
Changes:
| File | Description |
|---|---|
| unified/ql/test/library-tests/static-name-binding/unqualified-access.swift | Tests inherited unqualified access. |
| unified/ql/test/library-tests/static-name-binding/test.swift | Tests static member resolution. |
| unified/ql/test/library-tests/static-name-binding/test.ql | Implements binding assertions. |
| unified/ql/test/library-tests/static-name-binding/test.expected | Stores expected test results. |
| unified/ql/test/library-tests/static-name-binding/package1/Sources/Target2/File3.swift | Defines imported declarations. |
| unified/ql/test/library-tests/static-name-binding/package1/Sources/Target1/File3.swift | Tests bulk imports. |
| unified/ql/test/library-tests/static-name-binding/package1/Sources/Target1/File2.swift | Tests scoped imports. |
| unified/ql/test/library-tests/static-name-binding/package1/Sources/Target1/File1.swift | Tests module visibility. |
| unified/ql/test/library-tests/static-name-binding/package1/Package.swift | Defines test package targets. |
| unified/ql/test/library-tests/static-name-binding/inheritance.swift | Tests inherited static members. |
| unified/ql/test/library-tests/local-name-binding/test.ql | Uses shared comment utilities. |
| unified/ql/test/library-tests/BasicTest/test.ql | Tests string literal values. |
| unified/ql/test/library-tests/BasicTest/test.expected | Updates string expectations. |
| unified/ql/test/library-tests/BasicTest/strings.swift | Adds string fixture. |
| unified/ql/lib/utils/test/CommentUtil.qll | Extracts inline test metadata. |
| unified/ql/lib/unified.dbscheme | Adds name-pattern sub-pattern relation. |
| unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll | Implements static binding graph. |
| unified/ql/lib/codeql/unified/internal/NameBindingPluginSwift.qll | Adds Swift-specific binding rules. |
| unified/ql/lib/codeql/unified/internal/NameBindingPlugin.qll | Defines language extension points. |
| unified/ql/lib/codeql/unified/internal/LocalNameBinding.qll | Exposes declarations and uncertain scopes. |
| unified/ql/lib/codeql/unified/internal/FacadeAst.qll | Adds file, string, and argument helpers. |
| unified/ql/lib/codeql/unified/internal/dev/debugStaticNameBindingGraph.ql | Adds static graph visualization. |
| unified/ql/lib/codeql/unified/internal/dev/debugLocalNameBindingGraph.ql | Renames local graph query. |
| unified/ql/lib/codeql/unified/internal/Ast.qll | Exposes generated sub-pattern accessors. |
| unified/ql/lib/codeql/files/FileSystem.qll | Exposes the folder module. |
| unified/extractor/tests/corpus/swift/types/qualified-type.swift | Adds qualified-type fixture. |
| unified/extractor/tests/corpus/swift/types/qualified-type.output | Records qualified-type AST. |
| unified/extractor/tests/corpus/swift/optionals-and-errors/optional-enum-case-binding.swift | Adds optional-pattern fixture. |
| unified/extractor/tests/corpus/swift/optionals-and-errors/optional-enum-case-binding.output | Records optional-pattern AST. |
| unified/extractor/tests/corpus/swift/functions/leading-dot-expression-value.output | Updates inferred-type location. |
| unified/extractor/tests/corpus/swift/functions/leading-dot-expression-call.output | Updates inferred-type location. |
| unified/extractor/tests/corpus/swift/expressions/array-type-metatype.swift | Adds array metatype fixture. |
| unified/extractor/tests/corpus/swift/expressions/array-type-metatype.output | Records array metatype AST. |
| unified/extractor/tests/corpus/swift/expressions/array-type-constructor.swift | Adds array constructor fixture. |
| unified/extractor/tests/corpus/swift/expressions/array-type-constructor.output | Records array constructor AST. |
| unified/extractor/tests/corpus/swift/desugar/simple-import-with-single-name.output | Updates bulk-import pattern shape. |
| unified/extractor/tests/corpus/swift/desugar/import-with-dotted-path-two-parts.output | Updates dotted import shape. |
| unified/extractor/tests/corpus/swift/desugar/import-with-deeply-nested-path-three-parts.output | Updates deep import shape. |
| unified/extractor/tests/corpus/swift/control-flow/nested-enum-case-pattern.swift | Adds nested-pattern fixture. |
| unified/extractor/tests/corpus/swift/control-flow/nested-enum-case-pattern.output | Records nested-pattern AST. |
| unified/extractor/src/languages/swift/swift.rs | Expands Swift AST translation. |
| unified/extractor/ast_types.yml | Adds nested name patterns. |
| shared/namebinding/codeql/namebinding/LocalNameBinding.qll | Adds uncertain-scope support. |
Tip
Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
unified/extractor/src/languages/swift/swift.rs:669
expression: (functionCallExpr
calledExpression: @constructor
arguments: _* @elements))
Sorry, something went wrong.
There was a problem hiding this comment.
Impressive work, I really like the design here.
Sorry, something went wrong.
| private import codeql.unified.internal.LocalNameBinding | ||
| private import codeql.unified.internal.NameBindingPlugin | ||
|
|
||
| private newtype TNameBindingNode = |
There was a problem hiding this comment.
I assume we will want to add caching at some point?
Sorry, something went wrong.
There was a problem hiding this comment.
Yes, ideally once some benchmarks are in place so we can measure what we're doing.
Sorry, something went wrong.
Marking Members as uncertain scopes led to inaccurate resolution when a member referred to itself, because the uncertain scope (Member) appeared in the scope chain before the LocalName scope (ClassLikeDeclaration). Meanwhile, one of the arguments for doing it, avoiding base classes etc from hitting the uncertain scope, was already fixed by local scope tree-rewrites. It gets harder to detect if a given access appears in static or instance context, but perhaps we'll probably want to expose such information through a separate predicate anyway.
|
Thanks for the review @hvitved. I answered all the comments, PTAL. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Adds a static name-binding pass, resolving references to static members, including static-like members such as nested classes.
In addition to resolving static members, I also expect this to be responsible for instance-member lookups in classes.
Commit-by-commit review recommended. The PR also contains a lot of drive-by fixes to the AST mapping (some of it to make tests pass, some of it to make it work on real-world projects).
Name-binding graph
Static name resolution is modelled as a graph with edges between them, using the well-known value/store/read step kinds, in addition to inheritance steps.
Cyclic Dependency on Class Hierarchy
Swift allows unqualified access to inherited members, so for example, Foo below could refer to C.Foo or A.Foo.
The base classes themselves can also refer to members inherited by the outer class:
Inheritance thus depends on static name resolution, and static name resolution depends on inheritance. We resolve both in a single recursive layer.
Unqualified Lookups
An unqualified identifier gives rise to a read step from each of the scopes it could potentially be found in. In the above example, we'd get three read steps into Foo, corresponding to the three places we might find Foo.
The local name-binding pass has been augmented to support "uncertain scopes" and report back which uncertain scopes a given name access might be found it. This ensures that locally declared names can shadow lookups in outer (uncertain) scopes. For example, a locally declared Foo in the B class would block the read steps corresponding to C and A, while keeping the one from E.
The read steps currently have no priority/ranking, so there is no shadowing supported between uncertain members. There are ways to sharpen the precision a bit here, but I don't expect it to matter much -- let's only do that if we see a need for it.
Cross-file imports
This PR also adds some support for import resolution for projects with Package.swift files.
Future work