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

Implementing AST properties using singleton edge lists #1646

Merged
merged 5 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -32,16 +32,10 @@ import de.fraunhofer.aisec.cpg.graph.invoke
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

/**
* This [ValueEvaluator] can resolve multiple possible values of a node.
*
* It requires running the [EdgeCachePass] after the translation to add all necessary edges.
*/
/** This [ValueEvaluator] can resolve multiple possible values of a node. */
class MultiValueEvaluator : ValueEvaluator() {
companion object {
const val MAX_DEPTH: Int = 20
Expand Down Expand Up @@ -268,7 +262,8 @@ class MultiValueEvaluator : ValueEvaluator() {
forStatement.initializerStatement == node || // The node is the initialization
(initializerDecl != null &&
initializerDecl ==
node.astParent) || // The parent of the node is the initializer of the loop
node.astParent) || // The parent of the node is the initializer of the
// loop
// variable
forStatement.iterationStatement ==
node || // The node or its parent are the iteration statement of the loop
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,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 @@ -33,7 +33,6 @@ import de.fraunhofer.aisec.cpg.frontends.TestLanguage
import de.fraunhofer.aisec.cpg.frontends.TestLanguageFrontend
import de.fraunhofer.aisec.cpg.graph.array
import de.fraunhofer.aisec.cpg.graph.builder.*
import de.fraunhofer.aisec.cpg.passes.EdgeCachePass
import de.fraunhofer.aisec.cpg.passes.UnreachableEOGPass

class GraphExamples {
Expand All @@ -45,7 +44,6 @@ class GraphExamples {
.defaultPasses()
.registerLanguage(TestLanguage("."))
.registerPass<UnreachableEOGPass>()
.registerPass<EdgeCachePass>()
.build()
) =
testFrontend(config).build {
Expand Down Expand Up @@ -244,7 +242,6 @@ class GraphExamples {
.defaultPasses()
.registerLanguage(TestLanguage("."))
.registerPass<UnreachableEOGPass>()
.registerPass<EdgeCachePass>()
.build()
) =
testFrontend(config).build {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import de.fraunhofer.aisec.cpg.graph.array
import de.fraunhofer.aisec.cpg.graph.builder.*
import de.fraunhofer.aisec.cpg.graph.newNewArrayExpression
import de.fraunhofer.aisec.cpg.graph.pointer
import de.fraunhofer.aisec.cpg.passes.EdgeCachePass

class Query {
companion object {
Expand Down Expand Up @@ -99,7 +98,6 @@ class Query {
TranslationConfiguration.builder()
.defaultPasses()
.registerLanguage(TestLanguage("."))
.registerPass<EdgeCachePass>()
.inferenceConfiguration(InferenceConfiguration.builder().enabled(false).build())
.build()
) =
Expand Down Expand Up @@ -176,7 +174,6 @@ class Query {
TranslationConfiguration.builder()
.defaultPasses()
.registerLanguage(TestLanguage("."))
.registerPass<EdgeCachePass>()
.inferenceConfiguration(
InferenceConfiguration.builder().inferFunctions(false).build()
)
Expand Down Expand Up @@ -255,7 +252,6 @@ class Query {
TranslationConfiguration.builder()
.defaultPasses()
.registerLanguage(TestLanguage("."))
.registerPass<EdgeCachePass>()
.build()
) =
testFrontend(config).build {
Expand Down Expand Up @@ -392,7 +388,6 @@ class Query {
config: TranslationConfiguration =
TranslationConfiguration.builder()
.defaultPasses()
.registerPass<EdgeCachePass>()
.registerLanguage(TestLanguage("."))
.build()
) =
Expand Down Expand Up @@ -438,7 +433,6 @@ class Query {
config: TranslationConfiguration =
TranslationConfiguration.builder()
.defaultPasses()
.registerPass<EdgeCachePass>()
.registerLanguage(TestLanguage("."))
.build()
) =
Expand Down Expand Up @@ -498,7 +492,6 @@ class Query {
config: TranslationConfiguration =
TranslationConfiguration.builder()
.defaultPasses()
.registerPass<EdgeCachePass>()
.registerLanguage(TestLanguage("."))
.build()
) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import de.fraunhofer.aisec.cpg.TranslationConfiguration
import de.fraunhofer.aisec.cpg.frontends.TestLanguage
import de.fraunhofer.aisec.cpg.graph.*
import de.fraunhofer.aisec.cpg.graph.builder.*
import de.fraunhofer.aisec.cpg.passes.EdgeCachePass
import de.fraunhofer.aisec.cpg.passes.UnreachableEOGPass

class ValueEvaluationTests {
Expand All @@ -40,7 +39,6 @@ class ValueEvaluationTests {
.defaultPasses()
.registerLanguage(TestLanguage("."))
.registerPass<UnreachableEOGPass>()
.registerPass<EdgeCachePass>()
.build()
) =
testFrontend(config).build {
Expand Down Expand Up @@ -100,7 +98,6 @@ class ValueEvaluationTests {
.defaultPasses()
.registerLanguage(TestLanguage("."))
.registerPass<UnreachableEOGPass>()
.registerPass<EdgeCachePass>()
.build()
) =
testFrontend(config).build {
Expand Down Expand Up @@ -143,7 +140,6 @@ class ValueEvaluationTests {
.defaultPasses()
.registerLanguage(TestLanguage("."))
.registerPass<UnreachableEOGPass>()
.registerPass<EdgeCachePass>()
.build()
) =
testFrontend(config).build {
Expand Down Expand Up @@ -249,7 +245,6 @@ class ValueEvaluationTests {
.defaultPasses()
.registerLanguage(TestLanguage("."))
.registerPass<UnreachableEOGPass>()
.registerPass<EdgeCachePass>()
.build()
) =
testFrontend(config).build {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,18 @@
package de.fraunhofer.aisec.cpg

import de.fraunhofer.aisec.cpg.frontends.LanguageFrontend
import de.fraunhofer.aisec.cpg.graph.AST
import de.fraunhofer.aisec.cpg.graph.Component
import de.fraunhofer.aisec.cpg.graph.Name
import de.fraunhofer.aisec.cpg.graph.Node
import de.fraunhofer.aisec.cpg.graph.declarations.TranslationUnitDeclaration
import de.fraunhofer.aisec.cpg.graph.edges.ast.astEdgesOf
import de.fraunhofer.aisec.cpg.graph.edges.unwrapping
import de.fraunhofer.aisec.cpg.helpers.MeasurementHolder
import de.fraunhofer.aisec.cpg.helpers.StatisticsHolder
import de.fraunhofer.aisec.cpg.passes.Pass
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import org.neo4j.ogm.annotation.Relationship

/**
* The global (intermediate) result of the translation. A [LanguageFrontend] will initially populate
Expand All @@ -52,11 +54,12 @@ class TranslationResult(
var finalCtx: TranslationContext,
) : Node(), StatisticsHolder {

@Relationship("COMPONENTS") val componentEdges = astEdgesOf<Component>()
/**
* Entry points to the CPG: "SoftwareComponent" refer to programs, application, other "bundles"
* of software.
*/
@AST val components = mutableListOf<Component>()
val components by unwrapping(TranslationResult::componentEdges)

/**
* Scratch storage that can be used by passes to store additional information in this result.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,13 @@ class FrontendUtils {
val smallestEnclosingNode =
enclosingNodes.sortedWith(compareBy { it.code?.length ?: 10000 }).first()

val children = SubgraphWalker.getAstChildren(smallestEnclosingNode).toMutableList()
val children = smallestEnclosingNode.astChildren.toMutableList()

// Because in GO we wrap all elements into a NamespaceDeclaration we have to extract the
// natural children
children.addAll(
children.filterIsInstance<NamespaceDeclaration>().flatMap { namespace ->
SubgraphWalker.getAstChildren(namespace).filter { it !in children }
namespace.astChildren.filter { it !in children }
}
)

Expand Down
35 changes: 0 additions & 35 deletions cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/AST.kt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
package de.fraunhofer.aisec.cpg.graph

import de.fraunhofer.aisec.cpg.graph.declarations.TranslationUnitDeclaration
import de.fraunhofer.aisec.cpg.graph.edges.ast.astEdgesOf
import de.fraunhofer.aisec.cpg.graph.edges.unwrapping
import org.neo4j.ogm.annotation.Relationship

/**
* A node which presents some kind of complete piece of software, e.g., an application, a library,
Expand All @@ -35,8 +38,10 @@ import de.fraunhofer.aisec.cpg.graph.declarations.TranslationUnitDeclaration
* entry points or interactions with other software.
*/
open class Component : Node() {
@Relationship("TRANSLATION_UNITS")
val translationUnitEdges = astEdgesOf<TranslationUnitDeclaration>()
/** All translation units belonging to this application. */
@AST val translationUnits: MutableList<TranslationUnitDeclaration> = mutableListOf()
val translationUnits by unwrapping(Component::translationUnitEdges)

@Synchronized
fun addTranslationUnit(tu: TranslationUnitDeclaration) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ fun LanguageProvider.newTupleDeclaration(

// Also all our elements need to have an auto-type
elements.forEach { it.type = autoType() }
node.elements = elements
node.elements = elements.toMutableList()

node.initializer = initializer

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ fun MetadataProvider.newAssignExpression(
val node = AssignExpression()
node.applyMetadata(this, operatorCode, rawNode, true)
node.operatorCode = operatorCode
node.lhs = lhs
node.rhs = rhs
node.lhs = lhs.toMutableList()
KuechA marked this conversation as resolved.
Show resolved Hide resolved
node.rhs = rhs.toMutableList()

log(node)

Expand Down Expand Up @@ -207,8 +207,8 @@ fun MetadataProvider.newConditionalExpression(
*/
@JvmOverloads
fun MetadataProvider.newKeyValueExpression(
key: Expression? = null,
value: Expression? = null,
key: Expression,
value: Expression,
rawNode: Any? = null
): KeyValueExpression {
val node = KeyValueExpression()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,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 @@ -34,6 +34,7 @@ import de.fraunhofer.aisec.cpg.frontends.Handler
import de.fraunhofer.aisec.cpg.frontends.Language
import de.fraunhofer.aisec.cpg.graph.declarations.*
import de.fraunhofer.aisec.cpg.graph.edges.*
import de.fraunhofer.aisec.cpg.graph.edges.ast.astEdgesOf
import de.fraunhofer.aisec.cpg.graph.edges.flows.ControlDependences
import de.fraunhofer.aisec.cpg.graph.edges.flows.Dataflows
import de.fraunhofer.aisec.cpg.graph.edges.flows.EvaluationOrders
Expand Down Expand Up @@ -165,6 +166,8 @@ abstract class Node :
var astChildren: List<Node> = listOf()
get() = SubgraphWalker.getAstChildren(this)

@Transient var astParent: Node? = null

/** Virtual property for accessing [prevEOGEdges] without property edges. */
@PopulatedByPass(EvaluationOrderGraphPass::class) var prevEOG by unwrapping(Node::prevEOGEdges)

Expand Down Expand Up @@ -251,7 +254,8 @@ abstract class Node :
var argumentIndex = 0

/** List of annotations associated with that node. */
@AST var annotations: MutableList<Annotation> = ArrayList()
@Relationship("ANNOTATIONS") var annotationEdges = astEdgesOf<Annotation>()
var annotations by unwrapping(Node::annotationEdges)

/**
* If a node should be removed from the graph, just removing it from the AST is not enough (see
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,6 @@ interface StatementHolder : Holder<Statement> {
*/
var statements: MutableList<Statement>

/**
* Adds the specified statement to this statement holder. The statements have to be stored as a
* list of statements as we try to avoid adding new AST-nodes that do not exist, e.g. a code
* body to hold statements
*
* This only exists because of
* [de.fraunhofer.aisec.cpg.graph.statements.ForEachStatement.addStatement] which is needed
* until we re-design the Fluent DSL.
*
* @param s the statement
*/
@Deprecated(message = "This should be replaced by a direct call to statementEdges.add.")
fun addStatement(s: Statement) {
statementEdges.add(s)
}

override operator fun plusAssign(node: Statement) {
statementEdges += node
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1310,7 +1310,7 @@ fun Expression.conditional(
context(LanguageFrontend<*, *>, StatementHolder)
infix fun Expression.assign(init: AssignExpression.() -> Expression): AssignExpression {
val node = (this@LanguageFrontend).newAssignExpression("=")
node.lhs = listOf(this)
node.lhs = mutableListOf(this)
init(node)
// node.rhs = listOf(init(node))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,17 @@
*/
package de.fraunhofer.aisec.cpg.graph.declarations

import de.fraunhofer.aisec.cpg.graph.AST
import de.fraunhofer.aisec.cpg.graph.HasInitializer
import de.fraunhofer.aisec.cpg.graph.edges.ast.astOptionalEdgeOf
import de.fraunhofer.aisec.cpg.graph.edges.unwrapping
import de.fraunhofer.aisec.cpg.graph.statements.expressions.Expression
import org.neo4j.ogm.annotation.Relationship

/**
* Represents a constant within an [EnumDeclaration]. Depending on the language, this might have an
* explicit initializer value.
*/
class EnumConstantDeclaration : ValueDeclaration(), HasInitializer {
@AST override var initializer: Expression? = null
@Relationship("INITIALIZER") var initializerEdge = astOptionalEdgeOf<Expression>()
override var initializer by unwrapping(EnumConstantDeclaration::initializerEdge)
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,14 @@
*/
package de.fraunhofer.aisec.cpg.graph.declarations

import de.fraunhofer.aisec.cpg.graph.AST
import de.fraunhofer.aisec.cpg.graph.edges.ast.astEdgesOf
import de.fraunhofer.aisec.cpg.graph.edges.unwrapping
import org.apache.commons.lang3.builder.ToStringBuilder
import org.neo4j.ogm.annotation.Relationship

class EnumDeclaration : RecordDeclaration() {
@Relationship(value = "ENTRIES", direction = Relationship.Direction.OUTGOING)
@AST
var entryEdges = astEdgesOf<EnumConstantDeclaration>()

var entries by unwrapping(EnumDeclaration::entryEdges)

override fun toString(): String {
Expand Down
Loading
Loading