Skip to content

Commit

Permalink
[swiftsrc2cpg] Added support for Classes and Extensions (joernio#4020)
Browse files Browse the repository at this point in the history
  • Loading branch information
max-leuthaeuser authored Jan 4, 2024
1 parent faa9f33 commit a5f3198
Show file tree
Hide file tree
Showing 12 changed files with 870 additions and 36 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package io.joern.c2cpg.astcreation

import io.joern.x2cpg.datastructures.Stack.*
import io.joern.x2cpg.{Ast, ValidationMode}
import io.joern.x2cpg.datastructures.Stack.*
import io.joern.x2cpg.utils.NodeBuilders.newModifierNode
import io.joern.x2cpg.{Ast, ValidationMode}
import io.shiftleft.codepropertygraph.generated.nodes.*
import io.shiftleft.codepropertygraph.generated.{EvaluationStrategies, ModifierTypes}
import org.apache.commons.lang.StringUtils
Expand Down Expand Up @@ -153,7 +151,8 @@ trait AstForFunctionsCreator(implicit withSchemaValidation: ValidationMode) { th

scope.popScope()

val stubAst = methodStubAst(methodNode_, parameterNodes, newMethodReturnNode(funcDecl, registerType(returnType)))
val stubAst =
methodStubAst(methodNode_, parameterNodes.map(Ast(_)), newMethodReturnNode(funcDecl, registerType(returnType)))
val typeDeclAst = createFunctionTypeAndTypeDecl(funcDecl, methodNode_, name, fullname, signature)
stubAst.merge(typeDeclAst)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import io.joern.jssrc2cpg.parser.BabelAst.*
import io.joern.jssrc2cpg.parser.BabelNodeInfo
import io.joern.x2cpg.datastructures.Stack.*
import io.joern.x2cpg.utils.NodeBuilders.{newBindingNode, newModifierNode}
import io.joern.x2cpg.{Ast, AstNodeBuilder, ValidationMode}
import io.joern.x2cpg.{Ast, ValidationMode}
import io.joern.x2cpg.Defines
import io.shiftleft.codepropertygraph.generated.nodes.{Identifier as _, *}
import io.shiftleft.codepropertygraph.generated.{DispatchTypes, EdgeTypes, EvaluationStrategies, ModifierTypes}
Expand Down Expand Up @@ -338,7 +338,7 @@ trait AstForFunctionsCreator(implicit withSchemaValidation: ValidationMode) { th
)

val mAst = if (methodBlockContent.isEmpty) {
methodStubAst(methodNode_, thisNode +: paramNodes, methodReturnNode, modifiers)
methodStubAst(methodNode_, (thisNode +: paramNodes).map(Ast(_)), methodReturnNode, modifiers)
} else {
setArgumentIndices(methodBlockContent)
val bodyAst = blockAst(NewBlock(), methodBlockContent)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.joern.swiftsrc2cpg.astcreation

import io.joern.swiftsrc2cpg.Config
import io.joern.swiftsrc2cpg.datastructures.Scope
import io.joern.swiftsrc2cpg.datastructures.SwiftGlobal
import io.joern.swiftsrc2cpg.parser.SwiftJsonParser.ParseResult
import io.joern.swiftsrc2cpg.parser.SwiftNodeSyntax.*
import io.joern.swiftsrc2cpg.passes.Defines
Expand All @@ -23,7 +24,7 @@ import overflowdb.BatchedUpdate.DiffGraphBuilder

import scala.collection.mutable

class AstCreator(val config: Config, val global: Global, val parserResult: ParseResult)(implicit
class AstCreator(val config: Config, val global: SwiftGlobal, val parserResult: ParseResult)(implicit
withSchemaValidation: ValidationMode
) extends AstCreatorBase(parserResult.filename)
with AstForSwiftTokenCreator
Expand Down Expand Up @@ -91,15 +92,15 @@ class AstCreator(val config: Config, val global: Global, val parserResult: Parse
protected def astForNodeWithFunctionReferenceAndCall(node: SwiftNode): Ast = {
node match {
case func: FunctionDeclSyntax =>
astForFunctionLike(func, shouldCreateFunctionReference = true, shouldCreateAssignmentCall = true)
astForFunctionLike(func, shouldCreateFunctionReference = true, shouldCreateAssignmentCall = true).ast
case _ => astForNode(node)
}
}

protected def astForNodeWithFunctionReference(node: SwiftNode): Ast = {
node match {
case func: FunctionDeclSyntax =>
astForFunctionLike(func, shouldCreateFunctionReference = true)
astForFunctionLike(func, shouldCreateFunctionReference = true).ast
case _ => astForNode(node)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package io.joern.swiftsrc2cpg.astcreation

import io.joern.swiftsrc2cpg.datastructures.*
import io.joern.swiftsrc2cpg.parser.SwiftNodeSyntax.AccessorDeclSyntax
import io.joern.swiftsrc2cpg.parser.SwiftNodeSyntax.ClosureExprSyntax
import io.joern.swiftsrc2cpg.parser.SwiftNodeSyntax.DeinitializerDeclSyntax
import io.joern.swiftsrc2cpg.parser.SwiftNodeSyntax.FunctionDeclSyntax
import io.joern.swiftsrc2cpg.parser.SwiftNodeSyntax.InitializerDeclSyntax
import io.joern.swiftsrc2cpg.parser.SwiftNodeSyntax.SwiftNode
import io.joern.swiftsrc2cpg.passes.Defines
import io.joern.x2cpg.{Ast, ValidationMode}
Expand Down Expand Up @@ -59,9 +63,26 @@ trait AstCreatorHelper(implicit withSchemaValidation: ValidationMode) { this: As
.collect { case methodScopeElement: MethodScopeElement => methodScopeElement.name }
.mkString(":")

private def calcMethodName(func: FunctionDeclSyntax): String = code(func.name)
private def calcMethodName(func: SwiftNode): String = func match {
case f: FunctionDeclSyntax => code(f.name)
case a: AccessorDeclSyntax => code(a.accessorSpecifier)
case d: DeinitializerDeclSyntax => code(d.deinitKeyword)
case i: InitializerDeclSyntax => code(i.initKeyword)
case _ => nextClosureName()
}

protected def calcTypeNameAndFullName(name: String): (String, String) = {
val fullNamePrefix = s"${parserResult.filename}:${computeScopePath(scope.getScopeHead)}:"
val intendedFullName = s"$fullNamePrefix$name"
val postfix = typeFullNameToPostfix.getOrElse(intendedFullName, 0)
val resultingFullName =
if (postfix == 0) intendedFullName
else s"$intendedFullName$postfix"
typeFullNameToPostfix.put(intendedFullName, postfix + 1)
(name, resultingFullName)
}

protected def calcMethodNameAndFullName(func: FunctionDeclSyntax): (String, String) = {
protected def calcMethodNameAndFullName(func: SwiftNode): (String, String) = {
// functionNode.getName is not necessarily unique and thus the full name calculated based on the scope
// is not necessarily unique. Specifically we have this problem with lambda functions which are defined
// in the same scope.
Expand Down
Loading

0 comments on commit a5f3198

Please sign in to comment.