Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ class AstCreator(val config: Config, val global: Global, val parserResult: Parse
case ClassExpression => astForClass(nodeInfo)
case TSInterfaceDeclaration => astForInterface(nodeInfo)
case TSModuleDeclaration => astForModule(nodeInfo)
case Decorator => astForDecorator(nodeInfo)
case TSExportAssignment => astForExportAssignment(nodeInfo)
case ExportNamedDeclaration => astForExportNamedDeclaration(nodeInfo)
case ExportDefaultDeclaration => astForExportDefaultDeclaration(nodeInfo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,31 +58,32 @@ trait AstForDeclarationsCreator(implicit withSchemaValidation: ValidationMode) {
codes.map(_.replace("...", ""))
}

protected def astsForDecorators(elem: BabelNodeInfo): Seq[Ast] = {
private def decoratorElements(elem: BabelNodeInfo): List[BabelNodeInfo] = {
if (hasKey(elem.json, "decorators") && !elem.json("decorators").isNull) {
elem.json("decorators").arr.toList.map(d => astForDecorator(createBabelNodeInfo(d)))
} else Seq.empty
elem.json("decorators").arr.toList.map(createBabelNodeInfo)
} else List.empty
}

private def astForDecorator(decorator: BabelNodeInfo): Ast = {
protected def decoratorExpressionElements(elem: BabelNodeInfo): List[BabelNodeInfo] = {
val exprs = decoratorElements(elem).map(e => createBabelNodeInfo(e.json("expression")))
exprs.collect {
case d if d.node != Identifier && d.node != MemberExpression => d
}
}

protected def astsForDecorators(elem: BabelNodeInfo): List[Ast] = {
decoratorElements(elem).map(d => astForDecorator(d))
}

protected def astForDecorator(decorator: BabelNodeInfo): Ast = {
val exprNode = createBabelNodeInfo(decorator.json("expression"))
exprNode.node match {
case Identifier | MemberExpression =>
val (name, fullName) = namesForDecoratorExpression(code(exprNode.json))
val (name, fullName) = namesForDecoratorExpression(exprNode.code)
annotationAst(annotationNode(decorator, decorator.code, name, fullName), List.empty)
case _ =>
val (name, fullName) = namesForDecoratorExpression(exprNode.code.takeWhile(_ != '('))
annotationAst(annotationNode(decorator, decorator.code, name, fullName), List.empty)
case CallExpression =>
val (name, fullName) = namesForDecoratorExpression(code(exprNode.json("callee")))
val node = annotationNode(decorator, decorator.code, name, fullName)
val assignmentAsts = exprNode.json("arguments").arr.toList.map { arg =>
createBabelNodeInfo(arg).node match {
case AssignmentExpression =>
annotationAssignmentAst(code(arg("left")), code(arg), astForNodeWithFunctionReference(arg("right")))
case _ =>
annotationAssignmentAst("value", code(arg), astForNodeWithFunctionReference(arg))
}
}
annotationAst(node, assignmentAsts)
case _ => Ast()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ trait AstForFunctionsCreator(implicit withSchemaValidation: ValidationMode) { th
}

protected def astForTSDeclareFunction(func: BabelNodeInfo): Ast = {
val functionNode = createMethodDefinitionNode(func)
val functionNode = createMethodDefinitionNode(func, ConstructorContent.empty)
val tpe = typeFor(func)
val possibleTypes = Seq(tpe)
val typeFullName = if (Defines.isBuiltinType(tpe)) tpe else Defines.Any
Expand All @@ -331,10 +331,7 @@ trait AstForFunctionsCreator(implicit withSchemaValidation: ValidationMode) { th
Ast()
}

protected def createMethodDefinitionNode(
func: BabelNodeInfo,
methodBlockContent: List[Ast] = List.empty
): NewMethod = {
protected def createMethodDefinitionNode(func: BabelNodeInfo, methodBlockContent: ConstructorContent): NewMethod = {
val (methodName, methodFullName) = calcMethodNameAndFullName(func)
val methodNode_ = methodNode(func, methodName, func.code, methodFullName, None, parserResult.filename)
val lambdaModifier = if (methodName.startsWith(io.joern.x2cpg.Defines.ClosurePrefix)) {
Expand All @@ -356,6 +353,10 @@ trait AstForFunctionsCreator(implicit withSchemaValidation: ValidationMode) { th
handleParameters(func.json("params").arr.toSeq, mutable.ArrayBuffer.empty[Ast], createLocals = false)
}

val blockAsts =
methodBlockContent.constructorContent.flatMap(m => methodBlockContent.typeDecl.map(astForClassMember(m, _)))
setArgumentIndices(blockAsts)

val methodReturnNode_ = methodReturnNode(func)

methodAstParentStack.pop()
Expand All @@ -370,11 +371,10 @@ trait AstForFunctionsCreator(implicit withSchemaValidation: ValidationMode) { th
parserResult.filename
)

val mAst = if (methodBlockContent.isEmpty) {
val mAst = if (blockAsts.isEmpty) {
methodStubAst(methodNode_, (thisNode +: paramNodes).map(Ast(_)), methodReturnNode_, modifiers)
} else {
setArgumentIndices(methodBlockContent)
val bodyAst = blockAst(NewBlock(), methodBlockContent)
val bodyAst = blockAst(NewBlock(), blockAsts)
methodAstWithAnnotations(
methodNode_,
(thisNode +: paramNodes).map(Ast(_)),
Expand All @@ -396,7 +396,7 @@ trait AstForFunctionsCreator(implicit withSchemaValidation: ValidationMode) { th
func: BabelNodeInfo,
shouldCreateFunctionReference: Boolean = false,
shouldCreateAssignmentCall: Boolean = false,
methodBlockContent: List[Ast] = List.empty
methodBlockContent: ConstructorContent
): MethodAst = {
val (methodName, methodFullName) = calcMethodNameAndFullName(func)

Expand Down Expand Up @@ -456,7 +456,10 @@ trait AstForFunctionsCreator(implicit withSchemaValidation: ValidationMode) { th
}
case _ => createBlockStatementAsts(bodyJson("body"))
}
val methodBlockChildren = methodBlockContent ++ additionalBlockStatements.toList ++ bodyStmtAsts

val methodBlockChildren = methodBlockContent.constructorContent.flatMap(m =>
methodBlockContent.typeDecl.map(astForClassMember(m, _))
) ++ additionalBlockStatements.toList ++ bodyStmtAsts
setArgumentIndices(methodBlockChildren)

val methodReturnNode_ = methodReturnNode(func)
Expand Down Expand Up @@ -500,6 +503,11 @@ trait AstForFunctionsCreator(implicit withSchemaValidation: ValidationMode) { th
func: BabelNodeInfo,
shouldCreateFunctionReference: Boolean = false,
shouldCreateAssignmentCall: Boolean = false
): Ast = createMethodAstAndNode(func, shouldCreateFunctionReference, shouldCreateAssignmentCall).ast
): Ast = createMethodAstAndNode(
func,
shouldCreateFunctionReference,
shouldCreateAssignmentCall,
ConstructorContent.empty
).ast

}
Loading
Loading