Skip to content

Commit

Permalink
[kotlin2cpg] Second round of fixes (#4542)
Browse files Browse the repository at this point in the history
This includes:
- constructor modifier for class constructors (primary and secondary constructors)
- TypeDecl stubs for methods
- no closure bindings with ref edges to members
  • Loading branch information
max-leuthaeuser authored May 7, 2024
1 parent 9a6b80d commit 3917c67
Show file tree
Hide file tree
Showing 15 changed files with 258 additions and 164 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package io.joern.kotlin2cpg.ast

import io.joern.kotlin2cpg.Constants
import io.joern.kotlin2cpg.KtFileWithMeta
import io.joern.kotlin2cpg.ast.Nodes.namespaceBlockNode
import io.joern.kotlin2cpg.ast.Nodes.operatorCallNode
import io.joern.kotlin2cpg.datastructures.Scope
import io.joern.kotlin2cpg.types.TypeConstants
import io.joern.kotlin2cpg.types.TypeInfoProvider
Expand All @@ -15,6 +13,7 @@ import io.joern.x2cpg.Defines
import io.joern.x2cpg.ValidationMode
import io.joern.x2cpg.datastructures.Global
import io.joern.x2cpg.datastructures.Stack.*
import io.joern.x2cpg.utils.NodeBuilders
import io.joern.x2cpg.utils.NodeBuilders.newMethodReturnNode
import io.shiftleft.codepropertygraph.generated.*
import io.shiftleft.codepropertygraph.generated.nodes.*
Expand Down Expand Up @@ -292,19 +291,19 @@ class AstCreator(fileWithMeta: KtFileWithMeta, xTypeInfoProvider: TypeInfoProvid
for {
node <- importAsts.flatMap(_.root.collectAll[NewImport])
name = getName(node)
} yield Ast(namespaceBlockNode(name, name, relativizedPath))
} yield Ast(NodeBuilders.newNamespaceBlockNode(name, name, relativizedPath))

val packageName = ktFile.getPackageFqName.toString
val node =
if (packageName == Constants.root)
namespaceBlockNode(
NodeBuilders.newNamespaceBlockNode(
NamespaceTraversal.globalNamespaceName,
NamespaceTraversal.globalNamespaceName,
relativizedPath
)
else {
val name = packageName.split("\\.").lastOption.getOrElse("")
namespaceBlockNode(name, packageName, relativizedPath)
NodeBuilders.newNamespaceBlockNode(name, packageName, relativizedPath)
}
methodAstParentStack.push(node)

Expand Down Expand Up @@ -418,7 +417,7 @@ class AstCreator(fileWithMeta: KtFileWithMeta, xTypeInfoProvider: TypeInfoProvid
val componentNAst =
callAst(componentNCallNode, Seq(), Option(componentNIdentifierAst))

val assignmentCallNode = operatorCallNode(
val assignmentCallNode = NodeBuilders.newOperatorCallNode(
Operators.assignment,
s"${entry.getText} = $componentNCallCode",
None,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
package io.joern.kotlin2cpg.ast

import io.joern.kotlin2cpg.Constants
import io.joern.kotlin2cpg.ast.Nodes.modifierNode
import io.joern.kotlin2cpg.ast.Nodes.operatorCallNode
import io.joern.kotlin2cpg.psi.PsiUtils
import io.joern.kotlin2cpg.psi.PsiUtils.nonUnderscoreDestructuringEntries
import io.joern.kotlin2cpg.types.AnonymousObjectContext
import io.joern.kotlin2cpg.types.TypeConstants
import io.joern.kotlin2cpg.types.TypeInfoProvider
import io.joern.x2cpg.Ast
import io.joern.x2cpg.datastructures.Stack.*
import io.joern.x2cpg.Defines
import io.joern.x2cpg.ValidationMode
import io.joern.x2cpg.utils.NodeBuilders
import io.joern.x2cpg.utils.NodeBuilders.newBindingNode
import io.joern.x2cpg.utils.NodeBuilders.newIdentifierNode
import io.joern.x2cpg.utils.NodeBuilders.newMethodReturnNode
import io.joern.x2cpg.utils.NodeBuilders.newModifierNode
import io.shiftleft.codepropertygraph.generated.DispatchTypes
import io.shiftleft.codepropertygraph.generated.EdgeTypes
import io.shiftleft.codepropertygraph.generated.Operators
Expand Down Expand Up @@ -63,6 +63,7 @@ trait AstForDeclarationsCreator(implicit withSchemaValidation: ValidationMode) {
val outBaseTypeFullNames = Option(baseTypeFullNames).filter(_.nonEmpty).getOrElse(Seq(TypeConstants.javaLangObject))
val typeDecl = typeDeclNode(ktClass, className, classFullName, relativizedPath, outBaseTypeFullNames, None)
scope.pushNewScope(typeDecl)
methodAstParentStack.push(typeDecl)

val primaryCtor = ktClass.getPrimaryConstructor
val constructorParams = ktClass.getPrimaryConstructorParameters.asScala.toList
Expand Down Expand Up @@ -100,12 +101,12 @@ trait AstForDeclarationsCreator(implicit withSchemaValidation: ValidationMode) {
val thisAst = astWithRefEdgeMaybe(Constants.this_, thisIdentifier)

val fieldIdentifier = fieldIdentifierNode(decl, decl.getName, decl.getName)
val fieldAccessCall =
operatorCallNode(Operators.fieldAccess, s"${Constants.this_}.${fieldIdentifier.canonicalName}", None)
val fieldAccessCall = NodeBuilders
.newOperatorCallNode(Operators.fieldAccess, s"${Constants.this_}.${fieldIdentifier.canonicalName}", None)
val fieldAccessCallAst = callAst(fieldAccessCall, List(thisAst, Ast(fieldIdentifier)))

val assignmentNode =
operatorCallNode(Operators.assignment, s"${fieldAccessCall.code} = ${decl.getInitializer.getText}")
val assignmentNode = NodeBuilders
.newOperatorCallNode(Operators.assignment, s"${fieldAccessCall.code} = ${decl.getInitializer.getText}")
callAst(assignmentNode, List(fieldAccessCallAst, rhsAst))
}

Expand All @@ -125,7 +126,8 @@ trait AstForDeclarationsCreator(implicit withSchemaValidation: ValidationMode) {
blockNode(ktClass, "", TypeConstants.void),
memberSetCalls ++ memberInitializerSetCalls ++ anonymousInitAsts
),
constructorMethodReturn
constructorMethodReturn,
Seq(newModifierNode(ModifierTypes.CONSTRUCTOR))
)
val node =
newBindingNode(primaryCtorMethodNode.name, primaryCtorMethodNode.signature, primaryCtorMethodNode.fullName)
Expand Down Expand Up @@ -183,7 +185,7 @@ trait AstForDeclarationsCreator(implicit withSchemaValidation: ValidationMode) {

val annotationAsts = ktClass.getAnnotationEntries.asScala.map(astForAnnotationEntry).toSeq

val modifiers = if (isAbstract(ktClass)) List(Ast(modifierNode(ModifierTypes.ABSTRACT))) else Nil
val modifiers = if (isAbstract(ktClass)) List(Ast(NodeBuilders.newModifierNode(ModifierTypes.ABSTRACT))) else Nil

val children = methodAsts ++ List(constructorAst) ++ membersFromPrimaryCtorAsts ++ secondaryConstructorAsts ++
_componentNMethodAsts.toList ++ memberAsts ++ annotationAsts ++ modifiers
Expand All @@ -209,6 +211,7 @@ trait AstForDeclarationsCreator(implicit withSchemaValidation: ValidationMode) {
ast
}
val companionObjectAsts = ktClass.getCompanionObjects.asScala.flatMap(astsForClassOrObject(_, None))
methodAstParentStack.pop()
scope.popScope()

Seq(finalAst.withChildren(annotations.map(astForAnnotationEntry))) ++ companionObjectAsts ++ innerTypeDeclAsts
Expand All @@ -226,11 +229,11 @@ trait AstForDeclarationsCreator(implicit withSchemaValidation: ValidationMode) {

val fieldIdentifier = fieldIdentifierNode(param, paramName, paramName)
val fieldAccessCall =
operatorCallNode(Operators.fieldAccess, s"${Constants.this_}.$paramName", Option(typeFullName))
NodeBuilders.newOperatorCallNode(Operators.fieldAccess, s"${Constants.this_}.$paramName", Option(typeFullName))
val fieldAccessCallAst = callAst(fieldAccessCall, List(thisAst, Ast(fieldIdentifier)))

val assignmentNode =
operatorCallNode(Operators.assignment, s"${fieldAccessCall.code} = ${paramIdentifier.code}")
NodeBuilders.newOperatorCallNode(Operators.assignment, s"${fieldAccessCall.code} = ${paramIdentifier.code}")
callAst(assignmentNode, List(fieldAccessCallAst, paramIdentifierAst))
}

Expand Down Expand Up @@ -275,15 +278,15 @@ trait AstForDeclarationsCreator(implicit withSchemaValidation: ValidationMode) {
val assignmentLhsAst = Ast(assignmentLhsNode).withRefEdge(assignmentLhsNode, localForTmpNode)
val tmpAssignmentAst =
if (isCtor) {
val assignmentRhsNode =
operatorCallNode(
Operators.alloc,
Constants.alloc,
Option(localForTmpNode.typeFullName),
line(expr),
column(expr)
)
val assignmentNode = operatorCallNode(Operators.assignment, s"$tmpName = ${Constants.alloc}", None)
val assignmentRhsNode = NodeBuilders.newOperatorCallNode(
Operators.alloc,
Constants.alloc,
Option(localForTmpNode.typeFullName),
line(expr),
column(expr)
)
val assignmentNode =
NodeBuilders.newOperatorCallNode(Operators.assignment, s"$tmpName = ${Constants.alloc}", None)
callAst(assignmentNode, List(assignmentLhsAst, Ast(assignmentRhsNode)))
} else {
expr.getInitializer match {
Expand All @@ -296,7 +299,8 @@ trait AstForDeclarationsCreator(implicit withSchemaValidation: ValidationMode) {
case expression: KtIfExpression =>
astForIfAsExpression(expression, None, None)
case _ =>
val assignmentNode = operatorCallNode(Operators.assignment, s"$tmpName = ${rhsCall.getText}", None)
val assignmentNode =
NodeBuilders.newOperatorCallNode(Operators.assignment, s"$tmpName = ${rhsCall.getText}", None)
val assignmentRhsAst =
astsForExpression(rhsCall, None).headOption.getOrElse(Ast(unknownNode(rhsCall, Constants.empty)))
callAst(assignmentNode, List(assignmentLhsAst, assignmentRhsAst))
Expand Down Expand Up @@ -393,8 +397,11 @@ trait AstForDeclarationsCreator(implicit withSchemaValidation: ValidationMode) {
val thisAst = Ast(thisIdentifier).withRefEdge(thisIdentifier, thisParam)

val fieldIdentifier = fieldIdentifierNode(valueParam, valueParam.getName, valueParam.getName)
val fieldAccessCall =
operatorCallNode(Operators.fieldAccess, s"${Constants.this_}.${valueParam.getName}", Option(typeFullName))
val fieldAccessCall = NodeBuilders.newOperatorCallNode(
Operators.fieldAccess,
s"${Constants.this_}.${valueParam.getName}",
Option(typeFullName)
)
val fieldAccessCallAst = callAst(fieldAccessCall, List(thisAst, Ast(fieldIdentifier)))
val methodBlockAst = blockAst(
blockNode(valueParam, fieldAccessCall.code, typeFullName),
Expand Down Expand Up @@ -452,7 +459,8 @@ trait AstForDeclarationsCreator(implicit withSchemaValidation: ValidationMode) {
secondaryCtorMethodNode,
constructorParamsAsts,
ctorMethodBlockAsts.headOption.getOrElse(Ast(unknownNode(ctor.getBodyExpression, Constants.empty))),
ctorMethodReturnNode
ctorMethodReturnNode,
Seq(newModifierNode(ModifierTypes.CONSTRUCTOR))
)
}
}
Expand Down Expand Up @@ -482,13 +490,18 @@ trait AstForDeclarationsCreator(implicit withSchemaValidation: ValidationMode) {
scope.addToScope(tmpName, localForTmp)
val localAst = Ast(localForTmp)

val rhsAst = Ast(operatorCallNode(Operators.alloc, Operators.alloc, None))
val rhsAst = Ast(NodeBuilders.newOperatorCallNode(Operators.alloc, Operators.alloc, None))

val identifier = identifierNode(expr, tmpName, tmpName, localForTmp.typeFullName)
val identifierAst = astWithRefEdgeMaybe(identifier.name, identifier)

val assignmentNode =
operatorCallNode(Operators.assignment, s"${identifier.name} = <alloc>", None, line(expr), column(expr))
val assignmentNode = NodeBuilders.newOperatorCallNode(
Operators.assignment,
s"${identifier.name} = <alloc>",
None,
line(expr),
column(expr)
)
val assignmentCallAst = callAst(assignmentNode, List(identifierAst) ++ List(rhsAst))
val initSignature = s"${TypeConstants.void}()"
val initFullName = s"$typeDeclFullName.${TypeConstants.initPrefix}:$initSignature"
Expand Down Expand Up @@ -552,12 +565,13 @@ trait AstForDeclarationsCreator(implicit withSchemaValidation: ValidationMode) {
val typeFullName = registerType(
typeInfoProvider.expressionType(expr.getDelegateExpressionOrInitializer, Defines.UnresolvedNamespace)
)
val rhsAst = Ast(operatorCallNode(Operators.alloc, Operators.alloc, Option(typeFullName)))
val rhsAst = Ast(NodeBuilders.newOperatorCallNode(Operators.alloc, Operators.alloc, Option(typeFullName)))

val identifier = identifierNode(elem, elem.getText, elem.getText, local.typeFullName)
val identifierAst = astWithRefEdgeMaybe(identifier.name, identifier)

val assignmentNode = operatorCallNode(Operators.assignment, expr.getText, None, line(expr), column(expr))
val assignmentNode =
NodeBuilders.newOperatorCallNode(Operators.assignment, expr.getText, None, line(expr), column(expr))
val assignmentCallAst = callAst(assignmentNode, List(identifierAst) ++ List(rhsAst))

val (fullName, signature) =
Expand Down Expand Up @@ -604,12 +618,13 @@ trait AstForDeclarationsCreator(implicit withSchemaValidation: ValidationMode) {
val typeFullName = registerType(
typeInfoProvider.expressionType(expr.getDelegateExpressionOrInitializer, Defines.UnresolvedNamespace)
)
val rhsAst = Ast(operatorCallNode(Operators.alloc, Operators.alloc, None))
val rhsAst = Ast(NodeBuilders.newOperatorCallNode(Operators.alloc, Operators.alloc, None))

val identifier = identifierNode(elem, elem.getText, elem.getText, node.typeFullName)
val identifierAst = astWithRefEdgeMaybe(identifier.name, identifier)

val assignmentNode = operatorCallNode(Operators.assignment, expr.getText, None, line(expr), column(expr))
val assignmentNode =
NodeBuilders.newOperatorCallNode(Operators.assignment, expr.getText, None, line(expr), column(expr))
val assignmentCallAst = callAst(assignmentNode, List(identifierAst) ++ List(rhsAst))
val initSignature = s"${TypeConstants.void}()"
val initFullName = s"$typeFullName${TypeConstants.initPrefix}:$initSignature"
Expand All @@ -635,10 +650,11 @@ trait AstForDeclarationsCreator(implicit withSchemaValidation: ValidationMode) {
scope.addToScope(expr.getName, node)
val localAst = Ast(node)

val rhsAsts = astsForExpression(expr.getDelegateExpressionOrInitializer, Some(2))
val identifier = identifierNode(elem, elem.getText, elem.getText, typeFullName)
val identifierAst = astWithRefEdgeMaybe(identifier.name, identifier)
val assignmentNode = operatorCallNode(Operators.assignment, expr.getText, None, line(expr), column(expr))
val rhsAsts = astsForExpression(expr.getDelegateExpressionOrInitializer, Some(2))
val identifier = identifierNode(elem, elem.getText, elem.getText, typeFullName)
val identifierAst = astWithRefEdgeMaybe(identifier.name, identifier)
val assignmentNode =
NodeBuilders.newOperatorCallNode(Operators.assignment, expr.getText, None, line(expr), column(expr))
val call =
callAst(assignmentNode, List(identifierAst) ++ rhsAsts)
.withChildren(annotations.map(astForAnnotationEntry))
Expand Down
Loading

0 comments on commit 3917c67

Please sign in to comment.