diff --git a/unified/extractor/src/languages/swift/swift.rs b/unified/extractor/src/languages/swift/swift.rs index 8242e37a8a3f..dd7c4068a021 100644 --- a/unified/extractor/src/languages/swift/swift.rs +++ b/unified/extractor/src/languages/swift/swift.rs @@ -1044,8 +1044,9 @@ fn translation_rules() -> Vec> { // becomes a `modifier`; its source text is the modifier spelling. rule!((attribute) @m => (modifier #{m})), rule!((declModifier) @m => (modifier #{m})), - // A `super` expression. - rule!((superExpr) => (super_expr)), + // Preserve the `super` keyword as a dedicated expression, normally used + // as the base of a member access (`super.foo`). + rule!((superExpr superKeyword: @keyword) => (super_expr #{keyword})), // Type expressions. A generic type applied with explicit arguments // (`Set`) becomes a `generic_type_expr` whose `base` is the type // name and whose `type_argument`s are the (structured) arguments — the diff --git a/unified/extractor/tests/corpus/swift/expressions/super-expression.output b/unified/extractor/tests/corpus/swift/expressions/super-expression.output new file mode 100644 index 000000000000..21a04195c28b --- /dev/null +++ b/unified/extractor/tests/corpus/swift/expressions/super-expression.output @@ -0,0 +1,184 @@ +class Base { + var value = 0 + + func update() {} +} + +class Derived: Base { + override func update() { + _ = super.value + super.update() + } +} + +--- + +sourceFile + endOfFileToken: endOfFile + statements: + codeBlockItem + item: + classDecl + attributes: + name: identifier "Base" + memberBlock: + memberBlock + leftBrace: { + rightBrace: } + members: + memberBlockItem + decl: + variableDecl + attributes: + modifiers: + bindingSpecifier: var + bindings: + patternBinding + initializer: + initializerClause + equal: = + value: + integerLiteralExpr + literal: integerLiteral "0" + pattern: + identifierPattern + identifier: identifier "value" + memberBlockItem + decl: + functionDecl + attributes: + body: + codeBlock + leftBrace: { + rightBrace: } + statements: + name: identifier "update" + modifiers: + signature: + functionSignature + parameterClause: + functionParameterClause + leftParen: ( + rightParen: ) + parameters: + funcKeyword: func + modifiers: + classKeyword: class + codeBlockItem + item: + classDecl + attributes: + name: identifier "Derived" + inheritanceClause: + inheritanceClause + colon: : + inheritedTypes: + inheritedType + type: + identifierType + name: identifier "Base" + memberBlock: + memberBlock + leftBrace: { + rightBrace: } + members: + memberBlockItem + decl: + functionDecl + attributes: + body: + codeBlock + leftBrace: { + rightBrace: } + statements: + codeBlockItem + item: + infixOperatorExpr + operator: + assignmentExpr + equal: = + leftOperand: + discardAssignmentExpr + wildcard: _ + rightOperand: + memberAccessExpr + period: . + declName: + declReferenceExpr + baseName: identifier "value" + base: + superExpr + superKeyword: super + codeBlockItem + item: + functionCallExpr + leftParen: ( + rightParen: ) + arguments: + additionalTrailingClosures: + calledExpression: + memberAccessExpr + period: . + declName: + declReferenceExpr + baseName: identifier "update" + base: + superExpr + superKeyword: super + name: identifier "update" + modifiers: + declModifier + name: override + signature: + functionSignature + parameterClause: + functionParameterClause + leftParen: ( + rightParen: ) + parameters: + funcKeyword: func + modifiers: + classKeyword: class + +--- + +top_level source="⟨body⟩" + body: + block source="⟨stmt⟩\n\n⟨stmt⟩" + stmt: + class_like_declaration source="⟨modifier⟩ ⟨name_node⟩ {\n ⟨member⟩\n\n ⟨member⟩\n}" + modifier: modifier "class" source="class" + name_node: identifier "Base" source="Base" + member: + variable_declaration source="⟨modifier⟩ ⟨pattern⟩ = ⟨value⟩" + modifier: modifier "var" source="var" + pattern: identifier "value" source="value" + value: int_literal "0" source="0" + function_declaration source="⟨body⟩⟨name_node⟩" + name_node: identifier "update" source="update" + body: block "func update() {}" source="func update() {}" + class_like_declaration source="⟨modifier⟩⟨base_type⟩⟨name_node⟩⟨member⟩" + modifier: modifier "class" source="class" + name_node: identifier "Derived" source="Derived" + base_type: + base_type source="class Derived: ⟨type⟩ {\n override func update() {\n _ = super.value\n super.update()\n }\n}" + type: identifier "Base" source="Base" + member: + function_declaration source="⟨modifier⟩⟨body⟩⟨name_node⟩" + modifier: modifier "override" source="override" + name_node: identifier "update" source="update" + body: + block source="override func update() {\n ⟨stmt⟩\n ⟨stmt⟩\n }" + stmt: + binary_expr source="⟨left⟩ ⟨operator⟩ ⟨right⟩" + left: identifier "_" source="_" + operator: infix_operator "=" source="=" + right: + member_access_expr source="⟨base⟩.⟨member_name_node⟩" + base: super_expr "super" source="super" + member_name_node: identifier "value" source="value" + call_expr source="⟨callee⟩()" + callee: + member_access_expr source="⟨base⟩.⟨member_name_node⟩" + base: super_expr "super" source="super" + member_name_node: identifier "update" source="update" diff --git a/unified/extractor/tests/corpus/swift/expressions/super-expression.swift b/unified/extractor/tests/corpus/swift/expressions/super-expression.swift new file mode 100644 index 000000000000..6d1c37a70d55 --- /dev/null +++ b/unified/extractor/tests/corpus/swift/expressions/super-expression.swift @@ -0,0 +1,12 @@ +class Base { + var value = 0 + + func update() {} +} + +class Derived: Base { + override func update() { + _ = super.value + super.update() + } +} diff --git a/unified/ql/test/library-tests/controlflow/basicblock-slices.expected b/unified/ql/test/library-tests/controlflow/basicblock-slices.expected index 97a1d1a279f0..90d7959906ce 100644 --- a/unified/ql/test/library-tests/controlflow/basicblock-slices.expected +++ b/unified/ql/test/library-tests/controlflow/basicblock-slices.expected @@ -323,7 +323,7 @@ | 390 | cfg.swift:390:1:394:1 | ClassLikeDeclaration | 'ClassLikeDeclaration -V Derived -^ BaseType -V C' | | 391 | cfg.swift:391:3:393:3 | Block | 'Block' | | 391 | cfg.swift:391:3:393:3 | ConstructorDeclaration | 'ConstructorDeclaration' | -| 392 | cfg.swift:392:5:392:9 | | ' -^ ... .init -> Argument -V 0 -^ ... .init(...)' | +| 392 | cfg.swift:392:5:392:9 | super | 'super -^ ... .init -> Argument -V 0 -^ ... .init(...)' | | 396 | cfg.swift:396:1:404:1 | FunctionDeclaration | 'FunctionDeclaration' | | 396 | cfg.swift:396:21:396:21 | x | 'x -^ Block' | | 397 | cfg.swift:397:3:402:3 | TryExpr | 'TryExpr -V Block' |