Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement AST parent edges #1479

Draft
wants to merge 59 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
0d809ea
AstProvider first try
maximiliankaul Mar 26, 2024
a3c63b8
fancy kotlin magic
maximiliankaul Mar 28, 2024
dad17e8
Merge branch 'main' into mk/backwards-ast
maximiliankaul Mar 28, 2024
fad8eac
bump
maximiliankaul Mar 28, 2024
bcd6da4
bump
maximiliankaul Mar 28, 2024
d33cb96
use deque instead of stack
maximiliankaul Mar 28, 2024
aab6b0a
revert stuff
maximiliankaul Mar 28, 2024
6af47f1
clean up nodebuilder
maximiliankaul Mar 28, 2024
3c8b959
bump
maximiliankaul Mar 28, 2024
6cc190c
Fixed wrong placement of addDeclaration
oxisto Mar 28, 2024
d006353
Removing implicit receiver
oxisto Mar 28, 2024
7800b56
Fixed most tests
oxisto Mar 28, 2024
6eee05b
Converted Go frontend
oxisto Mar 28, 2024
e37ced0
Update dependency @types/node to v20.12.2 (#1485)
renovate[bot] Mar 31, 2024
46495ca
Fix index out of bounds in `hasSignature` (#1493)
KuechA Apr 3, 2024
024a8eb
Update dependency rollup to v4.14.0 (#1500)
renovate[bot] Apr 4, 2024
3caa91c
Update CODEOWNERS (#1501)
oxisto Apr 4, 2024
a102bff
Fixes incorrect field resolution in base classes (#1490)
oxisto Apr 4, 2024
f737e86
Improved stability of `isDerivedFrom` decisions (#1488)
oxisto Apr 4, 2024
a13a482
Extracted call/cast replacement into separate pass (#1499)
oxisto Apr 5, 2024
317415b
Fix style of docs (#1504)
KuechA Apr 5, 2024
9d30816
Extracting connecting declarations and definitions in C++ to extra pa…
oxisto Apr 5, 2024
89c3622
Update dependency io.github.gradle-nexus:publish-plugin to v2 (#1506)
renovate[bot] Apr 7, 2024
212f398
Python: Add BoolOp and + or (#1509)
maximiliankaul Apr 10, 2024
66fc39b
Handle `ForLoop` in `cyclomaticComplexity` (#1512)
KuechA Apr 10, 2024
7efedbc
Remove confusing warning in compound assignments (#1511)
KuechA Apr 10, 2024
22f2456
Fixing javaparser resultion error (#1510)
konradweiss Apr 10, 2024
784c97f
Merge branch 'main' into mk/backwards-ast
maximiliankaul Apr 18, 2024
b081de1
python++
maximiliankaul Apr 18, 2024
3eeea78
problem nodes instead of TODOs
maximiliankaul Apr 19, 2024
fd7098d
implement ast.Subscript (still missing ast.Slice)
maximiliankaul Apr 23, 2024
10c2680
python: ast.slice
maximiliankaul Apr 23, 2024
8da2b0c
ast.slice step size
maximiliankaul Apr 23, 2024
a46122f
formatting
maximiliankaul Apr 23, 2024
bb66d3a
fix ast parent in python pass
maximiliankaul Apr 23, 2024
0d3b6c0
Merge branch 'mk/issue1542' into mk/backwards-ast
maximiliankaul Apr 23, 2024
76b23e8
new stuff for new expressions
maximiliankaul Apr 23, 2024
deadeb2
Merge branch 'main' into mk/backwards-ast
maximiliankaul Apr 23, 2024
be1731a
merge cleanup
maximiliankaul Apr 23, 2024
a2a85fb
bump
maximiliankaul Apr 29, 2024
7db0e91
C++ translation improvements (#1482)
oxisto Apr 24, 2024
bbc155d
Merge branch 'refs/heads/main' into mk/backwards-ast
maximiliankaul Apr 30, 2024
4026e70
Merge branch 'refs/heads/main' into mk/backwards-ast
maximiliankaul Apr 30, 2024
cfea596
Merge remote-tracking branch 'origin/main' into mk/backwards-ast
oxisto Jun 14, 2024
a86b674
Fixed Go test errors
oxisto Jun 14, 2024
83c58a0
Slightly better
oxisto Jun 14, 2024
c6ed191
Merge remote-tracking branch 'origin/main' into mk/backwards-ast
oxisto Jul 18, 2024
4619295
More fixes in core and analysis
oxisto Jul 18, 2024
bceed73
Fixing more tests
oxisto Jul 18, 2024
449391e
style
maximiliankaul Jul 11, 2024
e455b96
bump
maximiliankaul Jul 23, 2024
f9d7005
AST parent checker
maximiliankaul Jul 23, 2024
c94edba
fix ast parent for callee
maximiliankaul Jul 23, 2024
fc59175
always check AST parents <-> children
maximiliankaul Jul 23, 2024
95b8f05
Added a `withParent` helper function (#1630)
oxisto Jul 24, 2024
18d5782
Merge branch 'main' into mk/backwards-ast
maximiliankaul Jul 26, 2024
be80440
fixing memberexpressions
maximiliankaul Jul 31, 2024
f761ffb
Merge remote-tracking branch 'origin/main' into mk/backwards-ast
maximiliankaul Jul 31, 2024
4b7fe70
FieldDeclaration is no longer part of Assign
maximiliankaul Jul 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import de.fraunhofer.aisec.cpg.graph.statements.DeclarationStatement
import de.fraunhofer.aisec.cpg.graph.statements.ForStatement
import de.fraunhofer.aisec.cpg.graph.statements.expressions.*
import de.fraunhofer.aisec.cpg.passes.EdgeCachePass
import de.fraunhofer.aisec.cpg.passes.astParent
import org.slf4j.Logger
import org.slf4j.LoggerFactory

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import de.fraunhofer.aisec.cpg.graph.statements.expressions.CallExpression
import de.fraunhofer.aisec.cpg.graph.statements.expressions.ConstructExpression
import de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberCallExpression
import de.fraunhofer.aisec.cpg.graph.statements.expressions.Reference
import de.fraunhofer.aisec.cpg.passes.astParent
import org.slf4j.Logger
import org.slf4j.LoggerFactory

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -783,19 +783,34 @@ class ValueEvaluatorTest {
comparison.lhs = aRef
comparison.rhs = newLiteral(1)

var cond = newConditionalExpression(comparison, newLiteral(2), aRef)
var cond =
newConditionalExpression().withChildren {
it.condition = comparison
it.thenExpression = newLiteral(2)
it.elseExpression = aRef
}
assertEquals(1, cond.evaluate())

// handle equals
comparison = newBinaryOperator("==")
comparison.lhs = aRef
comparison.rhs = newLiteral(1)

cond = newConditionalExpression(comparison, newLiteral(2), aRef)
cond =
newConditionalExpression().withChildren {
it.condition = comparison
it.thenExpression = newLiteral(2)
it.elseExpression = aRef
}
assertEquals(2, cond.evaluate())

// handle invalid
cond = newConditionalExpression(newProblemExpression(), newLiteral(2), aRef)
cond =
newConditionalExpression().withChildren {
it.condition = newProblemExpression()
it.thenExpression = newLiteral(2)
it.elseExpression = aRef
}
assertEquals("{}", cond.evaluate())
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,11 +294,11 @@ class ValueEvaluationTests {
declare {
variable("a", t("int")) {
this.initializer =
newConditionalExpression(
ref("b") lt literal(2, t("int")),
literal(3, t("int")),
literal(5, t("int")).inc()
)
newConditionalExpression().withChildren {
it.condition = ref("b") lt literal(2, t("int"))
it.thenExpression = literal(3, t("int"))
it.elseExpression = literal(5, t("int")).inc()
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ abstract class Handler<ResultNode : Node?, HandlerNode, L : LanguageFrontend<in
ScopeProvider by frontend,
NamespaceProvider by frontend,
ContextProvider by frontend,
RawNodeTypeProvider<HandlerNode> {
RawNodeTypeProvider<HandlerNode>,
AstStackProvider by frontend {
protected val map = HashMap<Class<out HandlerNode>, HandlerInterface<ResultNode, HandlerNode>>()
private val typeOfT: Class<*>?

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import de.fraunhofer.aisec.cpg.sarif.PhysicalLocation
import de.fraunhofer.aisec.cpg.sarif.Region
import java.io.File
import java.util.*
import kotlin.collections.ArrayDeque
import org.slf4j.LoggerFactory

/**
Expand Down Expand Up @@ -61,13 +62,16 @@ abstract class LanguageFrontend<AstNode, TypeNode>(
ScopeProvider,
NamespaceProvider,
ContextProvider,
RawNodeTypeProvider<AstNode> {
RawNodeTypeProvider<AstNode>,
AstStackProvider {
val scopeManager: ScopeManager = ctx.scopeManager
val typeManager: TypeManager = ctx.typeManager
val config: TranslationConfiguration = ctx.config

var currentTU: TranslationUnitDeclaration? = null

override val astStack: ArrayDeque<Node> = ArrayDeque()

@Throws(TranslationException::class)
fun parseAll(): List<TranslationUnitDeclaration> {
val units = ArrayList<TranslationUnitDeclaration>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ fun MetadataProvider.newTranslationUnitDeclaration(
): TranslationUnitDeclaration {
val node = TranslationUnitDeclaration()
node.applyMetadata(this, name, rawNode, true)

log(node)

return node
}

Expand All @@ -59,16 +59,16 @@ fun MetadataProvider.newTranslationUnitDeclaration(
* requires an appropriate [MetadataProvider], such as a [LanguageFrontend] as an additional
* prepended argument.
*/
@JvmOverloads
fun MetadataProvider.newFunctionDeclaration(
name: CharSequence?,
localNameOnly: Boolean = false,
rawNode: Any? = null,
rawNode: Any? = null
): FunctionDeclaration {
val node = FunctionDeclaration()
node.applyMetadata(this@MetadataProvider, name, rawNode, localNameOnly)

log(node)

return node
}

Expand All @@ -83,7 +83,7 @@ fun MetadataProvider.newMethodDeclaration(
name: CharSequence?,
isStatic: Boolean = false,
recordDeclaration: RecordDeclaration? = null,
rawNode: Any? = null
rawNode: Any? = null,
): MethodDeclaration {
val node = MethodDeclaration()
node.applyMetadata(this, name, rawNode, defaultNamespace = recordDeclaration?.name)
Expand Down Expand Up @@ -437,6 +437,7 @@ fun MetadataProvider.newNamespaceDeclaration(
node.applyMetadata(this, name, rawNode)

log(node)

return node
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,11 @@ fun MetadataProvider.newUnaryOperator(
@JvmOverloads
fun MetadataProvider.newAssignExpression(
operatorCode: String = "=",
lhs: List<Expression> = listOf(),
rhs: List<Expression> = listOf(),
rawNode: Any? = null
): AssignExpression {
val node = AssignExpression()
node.applyMetadata(this, operatorCode, rawNode, true)
node.operatorCode = operatorCode
node.lhs = lhs
node.rhs = rhs

log(node)

Expand Down Expand Up @@ -183,19 +179,13 @@ fun MetadataProvider.newConstructExpression(
*/
@JvmOverloads
fun MetadataProvider.newConditionalExpression(
condition: Expression,
thenExpression: Expression? = null,
elseExpression: Expression? = null,
type: Type = unknownType(),
rawNode: Any? = null
): ConditionalExpression {
val node = ConditionalExpression()
node.applyMetadata(this, EMPTY_NAME, rawNode, true)

node.type = type
node.condition = condition
node.thenExpression = thenExpression
node.elseExpression = elseExpression

log(node)
return node
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ import de.fraunhofer.aisec.cpg.graph.statements.WhileStatement
import de.fraunhofer.aisec.cpg.graph.statements.expressions.*
import de.fraunhofer.aisec.cpg.graph.statements.expressions.Block
import de.fraunhofer.aisec.cpg.helpers.SubgraphWalker
import de.fraunhofer.aisec.cpg.passes.astParent
import kotlin.math.absoluteValue

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ open class Node :
var astChildren: List<Node> = listOf()
get() = SubgraphWalker.getAstChildren(this)

@Relationship("AST") var astParent: Node? = null

/** Virtual property for accessing [prevEOGEdges] without property edges. */
@PopulatedByPass(EvaluationOrderGraphPass::class)
var prevEOG: List<Node> by PropertyEdgeDelegate(Node::prevEOGEdges, false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import de.fraunhofer.aisec.cpg.frontends.*
import de.fraunhofer.aisec.cpg.graph.Node.Companion.EMPTY_NAME
import de.fraunhofer.aisec.cpg.graph.NodeBuilder.LOGGER
import de.fraunhofer.aisec.cpg.graph.NodeBuilder.log
import de.fraunhofer.aisec.cpg.graph.declarations.Declaration
import de.fraunhofer.aisec.cpg.graph.declarations.TranslationUnitDeclaration
import de.fraunhofer.aisec.cpg.graph.scopes.Scope
import de.fraunhofer.aisec.cpg.graph.statements.expressions.*
import de.fraunhofer.aisec.cpg.graph.types.*
Expand All @@ -39,6 +41,8 @@ import de.fraunhofer.aisec.cpg.passes.inference.IsInferredProvider
import de.fraunhofer.aisec.cpg.sarif.PhysicalLocation
import de.fraunhofer.aisec.cpg.sarif.Region
import java.net.URI
import java.util.*
import kotlin.collections.ArrayDeque
import org.slf4j.LoggerFactory

object NodeBuilder {
Expand Down Expand Up @@ -91,6 +95,10 @@ interface NamespaceProvider : MetadataProvider {
val namespace: Name?
}

interface AstStackProvider : MetadataProvider {
val astStack: ArrayDeque<Node>
}

/**
* Applies various metadata on this [Node], based on the kind of provider in [provider]. This can
* include:
Expand Down Expand Up @@ -148,6 +156,10 @@ fun Node.applyMetadata(
)
}

if (provider is AstStackProvider) {
provider.astStack.lastOrNull().let { this.astParent = it }
}

if (name != null) {
val namespace =
if (provider is NamespaceProvider) {
Expand Down Expand Up @@ -217,14 +229,11 @@ fun MetadataProvider.newAnnotation(name: CharSequence?, rawNode: Any? = null): A
@JvmOverloads
fun MetadataProvider.newAnnotationMember(
name: CharSequence?,
value: Expression?,
rawNode: Any? = null
): AnnotationMember {
val node = AnnotationMember()
node.applyMetadata(this, name, rawNode, true)

node.value = value

log(node)
return node
}
Expand Down Expand Up @@ -380,3 +389,69 @@ private fun <AstNode> Node.setCodeAndLocation(
}
this.location = provider.locationOf(rawNode)
}

context(AstStackProvider, ContextProvider)
fun <T : Node> T.withChildren(
hasScope: Boolean = false,
isGlobalScope: Boolean = false,
init: (T) -> Unit
): T {
val scopeManager =
[email protected]?.scopeManager
?: throw TranslationException(
"Trying to create node children without a ContextProvider. This will fail."
)

(this@AstStackProvider).astStack.addLast(this@withChildren)

if (isGlobalScope && this is TranslationUnitDeclaration) {
scopeManager.resetToGlobal(this)
init(this)
} else if (hasScope) {
scopeManager.enterScope(this)
init(this)
scopeManager.leaveScope(this)
} else {
init(this)
}

(this@AstStackProvider).astStack.removeLast()

return this
}

/**
* This function can be used to set the [Node.astParent] of this node to the current node on the
* [AstStackProvider]'s stack. This is particularly useful if the node was created outside of the
* [withChildren] lambda. This is a usual pattern if the node is optionally wrapped in something
* else.
*
* Example:
* ```kotlin
* val expr = newReference("p")
*
* return if (isDeref) {
* newUnaryOperator("*", prefix = true, postfix = false).withChildren {
* it.input = expr.withParent()
* }
* } else {
* expr
* }
* ```
*/
context(AstStackProvider)
fun <T : Node> T.withParent(): T {
this.astParent = (this@AstStackProvider).astStack.lastOrNull()
return this
}

context(ContextProvider)
fun <T : Declaration> T.declare(): T {
val scopeManager =
[email protected]?.scopeManager
?: throw TranslationException(
"Trying to create node children without a ContextProvider. This will fail."
)
scopeManager.addDeclaration(this)
return this
}
Original file line number Diff line number Diff line change
Expand Up @@ -1088,7 +1088,11 @@ operator fun Expression.plus(rhs: Expression): BinaryOperator {
*/
context(LanguageFrontend<*, *>, StatementHolder)
operator fun Expression.plusAssign(rhs: Expression) {
val node = (this@LanguageFrontend).newAssignExpression("+=", listOf(this), listOf(rhs))
val node =
(this@LanguageFrontend).newAssignExpression("+=").withChildren {
it.rhs = listOf(rhs)
it.lhs = listOf(this)
}

(this@StatementHolder) += node
}
Expand Down Expand Up @@ -1292,8 +1296,10 @@ fun Expression.conditional(
thenExpression: Expression,
elseExpression: Expression
): ConditionalExpression {
val node =
(this@LanguageFrontend).newConditionalExpression(condition, thenExpression, elseExpression)
val node = (this@LanguageFrontend).newConditionalExpression()
node.condition = condition
node.thenExpression = thenExpression
node.elseExpression = elseExpression

if (this@Holder is StatementHolder) {
(this@Holder) += node
Expand Down Expand Up @@ -1326,7 +1332,11 @@ infix fun Expression.assign(init: AssignExpression.() -> Expression): AssignExpr
*/
context(LanguageFrontend<*, *>, Holder<out Node>)
infix fun Expression.assign(rhs: Expression): AssignExpression {
val node = (this@LanguageFrontend).newAssignExpression("=", listOf(this), listOf(rhs))
val node =
(this@LanguageFrontend).newAssignExpression("=").withChildren {
it.rhs = listOf(rhs)
it.lhs = listOf(this)
}

if (this@Holder is StatementHolder) {
this@Holder += node
Expand All @@ -1341,7 +1351,11 @@ infix fun Expression.assign(rhs: Expression): AssignExpression {
*/
context(LanguageFrontend<*, *>, Holder<out Node>)
infix fun Expression.assignPlus(rhs: Expression): AssignExpression {
val node = (this@LanguageFrontend).newAssignExpression("+=", listOf(this), listOf(rhs))
val node =
(this@LanguageFrontend).newAssignExpression("+=").withChildren {
it.rhs = listOf(rhs)
it.lhs = listOf(this)
}

if (this@Holder is StatementHolder) {
this@Holder += node
Expand All @@ -1356,7 +1370,11 @@ infix fun Expression.assignPlus(rhs: Expression): AssignExpression {
*/
context(LanguageFrontend<*, *>, Holder<out Node>)
infix fun Expression.assignAsExpr(rhs: Expression): AssignExpression {
val node = (this@LanguageFrontend).newAssignExpression("=", listOf(this), listOf(rhs))
val node =
(this@LanguageFrontend).newAssignExpression("=").withChildren {
it.rhs = listOf(rhs)
it.lhs = listOf(this)
}

node.usedAsExpression = true

Expand Down
Loading
Loading