mirror of
https://github.com/github/codeql.git
synced 2026-07-29 06:46:46 +02:00
unified: Port import rules to swift-syntax
Retarget imports to the swift-syntax AST, output unchanged. swift-syntax represents the dotted path as a list of `importPathComponent`s, folded into a `name_expr`/`member_access_expr` chain via `member_chain`. A single rule handles both forms via an optional `importKindSpecifier`: a scoped import (`import struct Foo.Bar`) has one and binds the last path component as a `name_pattern`; a plain import (`import Foundation`) has none and uses a `bulk_importing_pattern`. Leading attributes (`@_exported`) and access modifiers (`public`) become `modifier`s. The tree-sitter multi-part `identifier` rule is dropped: swift-syntax qualified names are already `memberAccessExpr` chains, and import paths are `importPathComponent`s. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -911,35 +911,37 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
|
||||
// `forceUnwrapExpr` node (the tree-sitter path used the generic postfix
|
||||
// operator rule instead).
|
||||
rule!((forceUnwrapExpr expression: @e) => (unary_expr operator: (postfix_operator "!") operand: {e})),
|
||||
// A multi-part identifier (for example `Foo.Bar.Baz`) is translated to
|
||||
// a member_access_expr chain with a name_expr base.
|
||||
// ---- Imports ----
|
||||
// An import declaration. The dotted path (a list of
|
||||
// `importPathComponent`s) becomes a `name_expr`/`member_access_expr`
|
||||
// chain (via `member_chain`). A scoped import (`import struct Foo.Bar`)
|
||||
// has an `importKindSpecifier` and binds the last path component as a
|
||||
// `name_pattern`; a plain import (`import Foundation`) has none and uses
|
||||
// a `bulk_importing_pattern` spanning the whole declaration. Any leading
|
||||
// attributes (`@_exported`) and access modifiers (`public`) become
|
||||
// `modifier`s.
|
||||
rule!(
|
||||
(identifier part: _+ @parts)
|
||||
(importDecl
|
||||
attributes: _* @attrs
|
||||
modifiers: _* @mods
|
||||
importKindSpecifier: _? @@kind
|
||||
path: (importPathComponent name: @@parts)*)
|
||||
=>
|
||||
expr { member_chain(&mut ctx, parts) }
|
||||
),
|
||||
// Scoped import declaration (for example `import struct Foo.Bar`):
|
||||
// flatten the identifier parts into a member_access_expr and bind the
|
||||
// final segment as a name_pattern.
|
||||
rule!(
|
||||
(import_declaration scoped_import_kind: @kind name: (identifier part: _+ @parts) @name modifiers: (modifiers)? @mods)
|
||||
=>
|
||||
(import_declaration
|
||||
pattern: (name_pattern identifier: (identifier #{parts.last().unwrap()}))
|
||||
imported_expr: {name}
|
||||
modifier: (modifier #{kind})
|
||||
modifier: {mods})
|
||||
),
|
||||
// Non-scoped import declaration (for example `import Foundation`):
|
||||
// flatten the identifier parts into a member_access_expr and use a
|
||||
// bulk_importing_pattern.
|
||||
rule!(
|
||||
(import_declaration name: @name modifiers: (modifiers)? @mods)
|
||||
=>
|
||||
(import_declaration
|
||||
pattern: (bulk_importing_pattern)
|
||||
imported_expr: {name}
|
||||
modifier: {mods})
|
||||
import_declaration {
|
||||
let pattern = match kind {
|
||||
Some(_) => {
|
||||
let last = *parts.last().ok_or("import has no path")?;
|
||||
tree!((name_pattern identifier: (identifier #{last})))
|
||||
}
|
||||
None => tree!((bulk_importing_pattern)),
|
||||
};
|
||||
tree!((import_declaration
|
||||
modifier: {kind.map(|k| tree!((modifier #{k})))}
|
||||
modifier: {attrs}
|
||||
modifier: {mods}
|
||||
pattern: {pattern}
|
||||
imported_expr: {member_chain(&mut ctx, parts)}))
|
||||
}
|
||||
),
|
||||
// ---- Types and classes ----
|
||||
// Self expression → name_expr
|
||||
|
||||
Reference in New Issue
Block a user