de.fraunhofer.aisec.cpg.graph.StatementHolder.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cpg-core Show documentation
Show all versions of cpg-core Show documentation
A simple library to extract a code property graph out of source code. It has support for multiple passes that can extend the analysis after the graph is constructed.
/*
* Copyright (c) 2021, Fraunhofer AISEC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $$$$$$\ $$$$$$$\ $$$$$$\
* $$ __$$\ $$ __$$\ $$ __$$\
* $$ / \__|$$ | $$ |$$ / \__|
* $$ | $$$$$$$ |$$ |$$$$\
* $$ | $$ ____/ $$ |\_$$ |
* $$ | $$\ $$ | $$ | $$ |
* \$$$$$ |$$ | \$$$$$ |
* \______/ \__| \______/
*
*/
package de.fraunhofer.aisec.cpg.graph
import de.fraunhofer.aisec.cpg.graph.edge.Properties
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge.Companion.unwrap
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge.Companion.wrap
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdgeDelegate
import de.fraunhofer.aisec.cpg.graph.statements.Statement
/**
* This interface denotes an AST node that can contain code. This code is stored as statements. This
* includes Translation units namespaces and classes as some languages, mainly scripting languages
* allow code placement outside explicit functions.
*
* The reason for not only using a statement property that encapsulates all code in an implicit
* compound statements is that code can be distributed between functions and an encapsulating
* compound statement would imply a block of code with a code region containing only the statements.
*/
interface StatementHolder : Holder {
/** List of statements as property edges. */
var statementEdges: MutableList>
/**
* Virtual property to access [statementEdges] without property edges.
*
* Note: We cannot use [PropertyEdgeDelegate] because delegates are not allowed in interfaces.
*/
var statements: List
get() {
return unwrap(statementEdges)
}
set(value) {
statementEdges = wrap(value, this as Node)
}
/**
* 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
*
* @param s the statement
*/
fun addStatement(s: Statement) {
val propertyEdge = PropertyEdge((this as Node), s)
propertyEdge.addProperty(Properties.INDEX, statementEdges.size)
statementEdges.add(propertyEdge)
}
/** Inserts the statement [s] before the statement specified in [before]. */
fun insertStatementBefore(s: Statement, before: Statement) {
val statements = this.statements
val idx = statements.indexOf(before)
if (idx != -1) {
val before = statements.subList(0, idx)
val after = statements.subList(idx, statements.size)
this.statements = listOf(*before.toTypedArray(), s, *after.toTypedArray())
}
}
override operator fun plusAssign(node: Statement) {
addStatement(node)
}
}