Skip to content

Commit 4a1b6da

Browse files
fix for review comment
1 parent d63c849 commit 4a1b6da

File tree

3 files changed

+53
-23
lines changed

3 files changed

+53
-23
lines changed

joern-cli/frontends/swiftsrc2cpg/src/main/scala/io/joern/swiftsrc2cpg/astcreation/AstCreatorHelper.scala

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -164,28 +164,15 @@ trait AstCreatorHelper(implicit withSchemaValidation: ValidationMode) { this: As
164164

165165
protected def astForIdentifier(node: SwiftNode): Ast = {
166166
val identifierName = code(node)
167-
// scoping rules for self access:
168-
// 1) if identifier is in local method scope it shadows everything else:
169-
if (scope.variableIsInMethodScope(identifierName)) {
170-
val identNode = identifierNode(node, identifierName)
171-
val variableOption = scope.lookupVariable(identifierName)
172-
val tpe = variableOption match {
173-
case Some((_, variableTypeName)) if variableTypeName != Defines.Any => variableTypeName
174-
case None if identNode.typeFullName != Defines.Any => identNode.typeFullName
175-
case _ => Defines.Any
176-
}
177-
identNode.typeFullName = tpe
178-
scope.addVariableReference(identifierName, identNode, tpe, EvaluationStrategies.BY_REFERENCE)
179-
Ast(identNode)
180-
} else if (scope.variableIsInTypeDeclScope(identifierName)) {
181-
// 2) we found it as member of the surrounding type decl:
167+
if (scope.variableIsInTypeDeclScope(identifierName)) {
168+
// we found it as member of the surrounding type decl
182169
// (Swift does not allow to access any member / function of the outer class instance)
183170
val tpe = typeForSelfExpression()
184171
val selfNode = identifierNode(node, "self", "self", tpe)
185172
scope.addVariableReference("self", selfNode, selfNode.typeFullName, EvaluationStrategies.BY_REFERENCE)
186173
fieldAccessAst(node, node, Ast(selfNode), s"self.$identifierName", identifierName, tpe)
187174
} else {
188-
// 3) default handling, it must come from the outer scope somewhere
175+
// otherwise it must come from the outer scope somewhere
189176
val identNode = identifierNode(node, identifierName)
190177
val variableOption = scope.lookupVariable(identifierName)
191178
val tpe = variableOption match {

joern-cli/frontends/swiftsrc2cpg/src/main/scala/io/joern/swiftsrc2cpg/astcreation/AstForDeclSyntaxCreator.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -612,8 +612,10 @@ trait AstForDeclSyntaxCreator(implicit withSchemaValidation: ValidationMode) {
612612
val MethodInfo(methodName, methodFullName, signature, returnType) = methodInfo
613613
val methodFullNameAndSignature = methodInfo.fullNameAndSignature
614614

615-
val shouldCreateFunctionReference =
616-
typeRefIdStack.isEmpty || node.isInstanceOf[ClosureExprSyntax] || node.isInstanceOf[AccessorDeclSyntax]
615+
val shouldCreateFunctionReference = typeRefIdStack.isEmpty ||
616+
methodAstParentStack.headOption.exists(_.isInstanceOf[NewMethod]) ||
617+
node.isInstanceOf[ClosureExprSyntax] ||
618+
node.isInstanceOf[AccessorDeclSyntax]
617619
val methodRefNode_ = if (!shouldCreateFunctionReference) { None }
618620
else { Option(methodRefNode(node, methodName, methodFullNameAndSignature, methodFullNameAndSignature)) }
619621
val capturingRefNode = methodRefNode_.orElse(typeRefIdStack.headOption)

joern-cli/frontends/swiftsrc2cpg/src/test/scala/io/joern/swiftsrc2cpg/passes/ast/SimpleAstCreationPassTest.scala

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -282,10 +282,10 @@ class SimpleAstCreationPassTest extends AstSwiftSrc2CpgSuite {
282282
|class Foo {
283283
| let f: String = "b"
284284
| func foo() -> String {
285-
| func closure() -> String {
285+
| func bar() -> String {
286286
| return handleF(f)
287287
| }
288-
| return closure()
288+
| return bar()
289289
| }
290290
|}
291291
|""".stripMargin)
@@ -297,6 +297,16 @@ class SimpleAstCreationPassTest extends AstSwiftSrc2CpgSuite {
297297
id.typeFullName shouldBe "Test0.swift:<global>.Foo"
298298
fieldName.canonicalName shouldBe "f"
299299
}
300+
301+
val List(fooMethod) = cpg.method.nameExact("foo").l
302+
val List(fooBlock) = fooMethod.astChildren.isBlock.l
303+
val List(barRef) = fooBlock.astChildren.isMethodRef.l
304+
val List(closureBindingSelf) = barRef.captureOut.l
305+
closureBindingSelf.closureBindingId shouldBe Option("Test0.swift:<global>.Foo.foo.bar:self")
306+
307+
val List(barMethod) = cpg.method.nameExact("bar").l
308+
val List(barMethodBlock) = barMethod.astChildren.isBlock.l
309+
barMethodBlock.astChildren.isLocal.name("f") shouldBe empty
300310
}
301311

302312
"have correct structure for implicit self access from within nested functions with shadowing" in {
@@ -306,10 +316,10 @@ class SimpleAstCreationPassTest extends AstSwiftSrc2CpgSuite {
306316
| let f: String = "b"
307317
| func foo() -> String {
308318
| let f: String = "c"
309-
| func closure() -> String {
319+
| func bar() -> String {
310320
| return handleF(f)
311321
| }
312-
| return closure()
322+
| return bar()
313323
| }
314324
|}
315325
|""".stripMargin)
@@ -321,6 +331,23 @@ class SimpleAstCreationPassTest extends AstSwiftSrc2CpgSuite {
321331
fLocal.name shouldBe "f"
322332
fLocal.typeFullName shouldBe Defines.String
323333
}
334+
val List(fooMethod) = cpg.method.nameExact("foo").l
335+
val List(fooBlock) = fooMethod.astChildren.isBlock.l
336+
val List(fooLocalF) = fooBlock.astChildren.isLocal.nameExact("f").l
337+
val List(barRef) = fooBlock.astChildren.isMethodRef.l
338+
val List(closureBindingF, closureBindingSelf) = barRef.captureOut.l
339+
closureBindingF.closureBindingId shouldBe Option("Test0.swift:<global>.Foo.foo.bar:f")
340+
closureBindingF.refOut.head shouldBe fooLocalF
341+
closureBindingF.evaluationStrategy shouldBe EvaluationStrategies.BY_REFERENCE
342+
closureBindingSelf.closureBindingId shouldBe Option("Test0.swift:<global>.Foo.foo.bar:self")
343+
344+
val List(barMethod) = cpg.method.nameExact("bar").l
345+
val List(barMethodBlock) = barMethod.astChildren.isBlock.l
346+
val List(barLocal) = barMethodBlock.astChildren.isLocal.name("f").l
347+
barLocal.closureBindingId shouldBe Option("Test0.swift:<global>.Foo.foo.bar:f")
348+
349+
val List(identifierF) = barMethodBlock.ast.isIdentifier.nameExact("f").l
350+
identifierF.refOut.head shouldBe barLocal
324351
}
325352

326353
"have correct structure for implicit self access except for variable in closure" in {
@@ -329,7 +356,7 @@ class SimpleAstCreationPassTest extends AstSwiftSrc2CpgSuite {
329356
| let f: String = "f"
330357
| class Bar {
331358
| let b = "b"
332-
| func bar() {
359+
| func foo() {
333360
| let compare = { (s1: String, s2: String) -> Bool in
334361
| let f: Int = 1
335362
| handleB(b)
@@ -356,6 +383,20 @@ class SimpleAstCreationPassTest extends AstSwiftSrc2CpgSuite {
356383
fLocal.name shouldBe "f"
357384
fLocal.typeFullName shouldBe Defines.Int
358385
}
386+
387+
val List(fooMethod) = cpg.method.nameExact("foo").l
388+
val List(fooBlock) = fooMethod.astChildren.isBlock.l
389+
val List(compareRef) = fooBlock.ast.isMethodRef.l
390+
compareRef.captureOut shouldBe empty
391+
392+
val List(compareClosure) = cpg.method.nameExact("<lambda>0").l
393+
val List(barMethodBlock) = compareClosure.astChildren.isBlock.l
394+
val List(barLocal) = barMethodBlock.astChildren.isLocal.name("f").l
395+
val List(identifierFFromLocalDecl, identifierFInCall) = barMethodBlock.ast.isIdentifier.nameExact("f").l
396+
identifierFFromLocalDecl.refOut.head shouldBe barLocal
397+
identifierFFromLocalDecl.lineNumber shouldBe Some(8)
398+
identifierFInCall.refOut.head shouldBe barLocal
399+
identifierFInCall.lineNumber shouldBe Some(10)
359400
}
360401

361402
"have correct structure for implicit self access except for parameters" in {

0 commit comments

Comments
 (0)