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

Merging PythonAddDeclarationPass into SymbolResovler using HasDynamicDeclarations trait #2006

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
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 @@ -31,6 +31,7 @@ import de.fraunhofer.aisec.cpg.graph.HasOperatorCode
import de.fraunhofer.aisec.cpg.graph.HasOverloadedOperation
import de.fraunhofer.aisec.cpg.graph.LanguageProvider
import de.fraunhofer.aisec.cpg.graph.Name
import de.fraunhofer.aisec.cpg.graph.declarations.Declaration
import de.fraunhofer.aisec.cpg.graph.declarations.FunctionDeclaration
import de.fraunhofer.aisec.cpg.graph.declarations.RecordDeclaration
import de.fraunhofer.aisec.cpg.graph.declarations.TranslationUnitDeclaration
Expand Down Expand Up @@ -298,6 +299,16 @@ inline infix fun <reified T : HasOverloadedOperation> KClass<T>.of(
return Pair(T::class, operatorCode)
}

/**
* A language trait that specifies that this language has dynamic declarations, meaning that
* declarations can be added to the symbol table at runtime. Since we are a static analysis tools,
* we can only deliver an approximation to the actual behaviour.
*/
interface HasDynamicDeclarations : LanguageTrait {

fun SymbolResolver.provideDeclaration(ref: Reference): Declaration?
}

/** Checks whether the name for a function (as [CharSequence]) is a known operator name. */
context(LanguageProvider)
val CharSequence.isKnownOperatorName: Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import de.fraunhofer.aisec.cpg.graph.statements.expressions.*
import de.fraunhofer.aisec.cpg.graph.types.Type
import de.fraunhofer.aisec.cpg.helpers.IdentitySet
import de.fraunhofer.aisec.cpg.helpers.SubgraphWalker
import de.fraunhofer.aisec.cpg.helpers.identitySetOf
import de.fraunhofer.aisec.cpg.tryCast
import java.util.*
import org.slf4j.LoggerFactory
Expand Down Expand Up @@ -120,6 +121,8 @@ open class EvaluationOrderGraphPass(ctx: TranslationContext) : TranslationUnitPa
*/
protected val intermediateNodes = mutableListOf<Node>()

val alreadySeen = identitySetOf<Node>()

protected fun doNothing() {
// Nothing to do for this node type
}
Expand Down Expand Up @@ -344,6 +347,9 @@ open class EvaluationOrderGraphPass(ctx: TranslationContext) : TranslationUnitPa
if (node == null) {
return
}

alreadySeen.add(node)

intermediateNodes.add(node)

when (node) {
Expand Down Expand Up @@ -537,8 +543,7 @@ open class EvaluationOrderGraphPass(ctx: TranslationContext) : TranslationUnitPa
} else if (declaration is FunctionDeclaration) {
// save the current EOG stack, because we can have a function declaration within an
// existing function and the EOG handler for handling function declarations will
// reset the
// stack
// reset the stack
val oldEOG = currentPredecessors.toMutableList()

// analyze the defaults
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,13 @@ open class SymbolResolver(ctx: TranslationContext) : ComponentPass(ctx) {
val language = ref.language
val helperType = ref.resolutionHelper?.type

// Before we resolve anything, we give languages with dynamic declarations a chance to
// declare any variables they need. This is most likely only needed for WRITE references,
// but we let the language decide that
if (language is HasDynamicDeclarations) {
with(language) { provideDeclaration(ref) }
}

// Ignore references to anonymous identifiers, if the language supports it (e.g., the _
// identifier in Go)
if (
Expand Down Expand Up @@ -312,6 +319,13 @@ open class SymbolResolver(ctx: TranslationContext) : ComponentPass(ctx) {
val base = current.base
val language = current.language

// Before we resolve anything, we give languages with dynamic declarations a chance to
// declare any variables they need. This is most likely only needed for WRITE references,
// but we let the language decide that
if (language is HasDynamicDeclarations) {
with(language) { provideDeclaration(current) }
}

// We need to adjust certain types of the base in case of a "super" expression, and we
// delegate this to the language. If that is successful, we can continue with regular
// resolving.
Expand Down
Loading
Loading