Skip to content

Commit 76276be

Browse files
more fullname fixes
- fix fullnames with references to extension from libraries - account for modifiers in compiler json output
1 parent 1958518 commit 76276be

File tree

4 files changed

+35
-22
lines changed

4 files changed

+35
-22
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ object AstCreatorHelper {
7070

7171
def cleanType(rawType: String): String = {
7272
if (rawType == Defines.Any) return rawType
73-
val normalizedTpe = StringUtils.normalizeSpace(rawType.stripSuffix(" ()"))
74-
stripGenerics(normalizedTpe) match {
73+
val normalizedName = StringUtils.normalizeSpace(rawType.stripSuffix(" ()"))
74+
stripGenerics(normalizedName) match {
7575
// Empty or problematic types
7676
case "" => Defines.Any
7777
case t if t.contains("?") => Defines.Any

joern-cli/frontends/swiftsrc2cpg/src/main/scala/io/joern/swiftsrc2cpg/utils/GsonTypeInfoReader.scala

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ object GsonTypeInfoReader {
3131
val CallExpr = "call_expr"
3232
val ReturnStmt = "return_stmt"
3333
val DotCallExpr = "dot_syntax_call_expr"
34+
val ClassDecl = "class_decl"
3435
}
3536

3637
/** Safely retrieves a string property from a JsonObject.
@@ -70,11 +71,28 @@ object GsonTypeInfoReader {
7071
val rangeObj = obj.get("range").getAsJsonObject
7172
val start = rangeObj.get("start").getAsInt
7273
val end = rangeObj.get("end").getAsInt
73-
val offset = astNodeKind(obj) match {
74+
75+
// no adjustment needed for zero-length ranges, e.g., for member accesses:
76+
if (start == end) return (start, end)
77+
78+
val endOffset = astNodeKind(obj) match {
7479
case NodeKinds.DotCallExpr => 3 // offsets are off by 2 from SwiftParser for simple dot calls
7580
case _ => 1
7681
}
77-
if (start == end) (start, end) else (start, end + offset)
82+
val startWithModifiers = obj match {
83+
case _ if obj.has("attrs") =>
84+
/** Handles cases where attributes modify the start position of the range. For example, in the presence of
85+
* attributes like `@escaping` or for access modifiers like `static` the start position may need to be adjusted
86+
* to account for the attribute's position because swift-parser does include attributes in the range of the
87+
* associated declaration while swiftc does not.
88+
*/
89+
safeRange(obj.getAsJsonArray("attrs").get(0).getAsJsonObject) match {
90+
case Some((s, e)) if s < start => s
91+
case _ => start
92+
}
93+
case _ => start
94+
}
95+
(startWithModifiers, end + endOffset)
7896
}
7997

8098
/** Safely extracts the source range from a JSON object.

joern-cli/frontends/swiftsrc2cpg/src/main/scala/io/joern/swiftsrc2cpg/utils/SwiftTypesProvider.scala

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -547,14 +547,7 @@ case class SwiftTypesProvider(config: Config, parsedSwiftInvocations: Seq[Seq[St
547547
* Some(demangled type fullname) if successful, None otherwise
548548
*/
549549
private def calculateTypeFullname(mangledName: String): Option[String] = {
550-
mangledNameCache.computeIfAbsent(
551-
mangledName,
552-
_ =>
553-
demangle(mangledName)
554-
.map(removeModifier)
555-
.map(AstCreatorHelper.stripGenerics)
556-
.map(_.replace(" ", "").stripSuffix(".Type"))
557-
)
550+
calculateDeclFullname(mangledName).map(_.stripSuffix(".Type"))
558551
}
559552

560553
/** This regex is designed to clean up Swift demangled type names by extracting meaningful parts and removing internal
@@ -578,7 +571,8 @@ case class SwiftTypesProvider(config: Config, parsedSwiftInvocations: Seq[Seq[St
578571
*
579572
* E.g., `(extension in FooExt)Foo.bar() -> Swift.String` becomes `FooExt.Foo.bar() -> Swift.String`.
580573
*/
581-
private val ExtensionNameRegex: Regex = """\(extension\sin\s([^)]+)\):(.*)""".r
574+
private val ExtensionNameRegex: Regex = """^(.*)\(extension\sin\s([^)]+)\):(.*)""".r
575+
private val ExtensionNameStartRegex: Regex = """^\(extension\sin\s([^)]+)\):(.*)""".r
582576

583577
/** Calculates a demangled declaration fullname from a mangled Swift declaration name.
584578
*
@@ -595,12 +589,13 @@ case class SwiftTypesProvider(config: Config, parsedSwiftInvocations: Seq[Seq[St
595589
mangledName,
596590
_ =>
597591
demangle(mangledName)
592+
.map(n => AstCreatorHelper.stripGenerics(removeModifier(n)))
598593
.map {
599-
case MemberNameRegex(parent, name, rest) => removeModifier(s"$parent$name$rest")
600-
case ExtensionNameRegex(name, rest) => removeModifier(s"$name$rest")
601-
case other => removeModifier(other)
594+
case ExtensionNameStartRegex(name, rest) => s"$name.$rest"
595+
case ExtensionNameRegex(head, name, rest) => s"$head$name.$rest"
596+
case MemberNameRegex(parent, name, rest) => s"$parent$name$rest"
597+
case other => other
602598
}
603-
.map(AstCreatorHelper.stripGenerics)
604599
.map(_.replace(" ", ""))
605600
)
606601
}

joern-cli/frontends/swiftsrc2cpg/src/test/scala/io/joern/swiftsrc2cpg/utils/SwiftCompilerTests.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ class SwiftCompilerTests extends AnyWordSpec with Matchers {
260260
(
261261
"HelloWorldSwift.swift",
262262
"class_decl",
263-
(27, 237),
263+
(20, 237),
264264
Some("SwiftHelloWorldLib.HelloWorld"),
265265
Some("SwiftHelloWorldLib.HelloWorld")
266266
),
@@ -441,7 +441,7 @@ class SwiftCompilerTests extends AnyWordSpec with Matchers {
441441
),
442442
("Main.swift", "return_stmt", (46, 46), Some("Swift.Void"), None),
443443
("Main.swift", "string_literal_expr", (147, 147), Some("Swift.String"), None),
444-
("Main.swift", "struct_decl", (52, 158), Some("SwiftHelloWorld.Main"), Some("SwiftHelloWorld.Main")),
444+
("Main.swift", "struct_decl", (46, 158), Some("SwiftHelloWorld.Main"), Some("SwiftHelloWorld.Main")),
445445
("Main.swift", "type_expr", (112, 112), Some("SwiftHelloWorldLib.HelloWorld"), None),
446446
("Main.swift", "var_decl", (102, 102), Some("SwiftHelloWorldLib.HelloWorld"), None)
447447
)
@@ -618,18 +618,18 @@ class SwiftCompilerTests extends AnyWordSpec with Matchers {
618618
)
619619

620620
helloWorldMappings should contain(
621-
("class_decl", (27, 497), Some("SwiftHelloWorldLib.HelloWorld"), Some("SwiftHelloWorldLib.HelloWorld"))
621+
("class_decl", (20, 497), Some("SwiftHelloWorldLib.HelloWorld"), Some("SwiftHelloWorldLib.HelloWorld"))
622622
)
623623
helloWorldMappings should contain(
624624
(
625625
"constructor_decl",
626-
(381, 405),
626+
(374, 405),
627627
Some("(SwiftHelloWorldLib.HelloWorld.Type)->()->SwiftHelloWorldLib.HelloWorld"),
628628
Some("SwiftHelloWorldLib.HelloWorld.init()->SwiftHelloWorldLib.HelloWorld")
629629
)
630630
)
631631
helloWorldMappings should contain(
632-
("func_decl", (415, 494), Some("()"), Some("SwiftHelloWorldLib.HelloWorld.greet(from:Swift.String)->()"))
632+
("func_decl", (408, 494), Some("()"), Some("SwiftHelloWorldLib.HelloWorld.greet(from:Swift.String)->()"))
633633
)
634634
helloWorldMappings should contain(
635635
(

0 commit comments

Comments
 (0)