Skip to content

Commit

Permalink
Trying to implement aliases
Browse files Browse the repository at this point in the history
  • Loading branch information
oxisto committed May 10, 2024
1 parent 8c4c3d0 commit f8058f9
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 18 deletions.
22 changes: 12 additions & 10 deletions cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/ScopeManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ class ScopeManager : ScopeProvider {
*/
private fun newNameScopeIfNecessary(nodeToScope: NamespaceDeclaration): NameScope? {
val existingScope =
currentScope?.children?.firstOrNull { it is NameScope && it.name == nodeToScope.name }
filterScopes { it is NameScope && it.name == nodeToScope.name }.firstOrNull()

return if (existingScope != null) {
// update the AST node to this namespace declaration
Expand Down Expand Up @@ -821,7 +821,7 @@ class ScopeManager : ScopeProvider {
// First, we need to check, whether we have some kind of scoping.
if (n.isQualified()) {
// We need to check, whether we have an alias for the name's parent in this file
n = resolveParentAlias(n, location)
n = resolveParentAlias(n, scope)

// extract the scope name, it is usually a name space, but could probably be something
// else as well in other languages
Expand Down Expand Up @@ -849,17 +849,19 @@ class ScopeManager : ScopeProvider {
* This function resolves a name alias (contained in [aliases]) for the [Name.parent] of the
* given [Name].
*/
fun resolveParentAlias(
name: Name,
location: PhysicalLocation?,
): Name {
fun resolveParentAlias(name: Name, scope: Scope?): Name {
var parentName = name.parent ?: return name

// This is not 100 % ideal, but at least somewhat compatible to the previous approach
var newName = name
val list = aliases[location?.artifactLocation]
val alias = list?.firstOrNull { it.to == name.parent }?.from
if (alias != null) {
val decl =
scope?.lookupSymbol(parentName.localName)?.singleOrNull {
it is NamespaceDeclaration || it is RecordDeclaration
}
if (decl != null) {
// Reconstruct the original name with the alias, so we can resolve declarations with
// the namespace
newName = Name(newName.localName, alias, delimiter = newName.delimiter)
newName = Name(newName.localName, decl.name, delimiter = newName.delimiter)
}

return newName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class ImportResolver(ctx: TranslationContext) : ComponentPass(ctx) {
}
}
} else {
// or a wildcard
// or a symbol directly
val list = scopeManager.findSymbols(node.import, node.location, scope).toMutableList()
node.importedSymbols = mutableMapOf(node.symbol to list)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ open class CXXLanguageFrontend(language: Language<CXXLanguageFrontend>, ctx: Tra
val location = currentTU?.location

// We need to take name(space) aliases into account.
typeName = scopeManager.resolveParentAlias(typeName, location)
typeName = scopeManager.resolveParentAlias(typeName, scopeManager.currentScope)

return objectType(typeName)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,23 @@ class DeclarationHandler(lang: CXXLanguageFrontend) :
* itself for this concept, we just return an empty [DeclarationSequence], which will then be
* ignored in the final graph.
*/
private fun handleNamespaceAlias(ctx: CPPASTNamespaceAlias): DeclarationSequence {
private fun handleNamespaceAlias(ctx: CPPASTNamespaceAlias): ImportDeclaration {
val location = locationOf(ctx)

val from = parseName(ctx.mappingName.toString())
val to = parseName(ctx.alias.toString())

// frontend.scopeManager.currentScope?.addSymbol(ctx.alias.toString(), )

// Currently, we can only scope the alias to the file location, this is a shortcoming of the
// scope manager. In reality, the namespace alias is valid in the current scope block
location?.artifactLocation?.let { frontend.scopeManager.addAlias(it, from, to) }

return DeclarationSequence()
val import = newImportDeclaration(from, false, to, rawNode = ctx)

frontend.scopeManager.addDeclaration(import)

return import
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,6 @@ class GoLanguageFrontend(language: Language<GoLanguageFrontend>, ctx: Translatio
scopeManager.resetToGlobal(tu)
currentTU = tu

val p = newNamespaceDeclaration(f.name.name)
scopeManager.enterScope(p)

// We need to keep imports on a special file scope. We can simulate this by "entering" the
// translation unit
scopeManager.enterScope(tu)
Expand All @@ -184,7 +181,8 @@ class GoLanguageFrontend(language: Language<GoLanguageFrontend>, ctx: Translatio
scopeManager.addDeclaration(import)
}

scopeManager.leaveScope(tu)
val p = newNamespaceDeclaration(f.name.name)
scopeManager.enterScope(p)

try {
// we need to construct the package "path" (e.g. "encoding/json") out of the
Expand Down Expand Up @@ -232,6 +230,9 @@ class GoLanguageFrontend(language: Language<GoLanguageFrontend>, ctx: Translatio
}

scopeManager.leaveScope(p)
scopeManager.leaveScope(tu)

scopeManager.resetToGlobal(tu)

scopeManager.addDeclaration(p)

Expand Down

0 comments on commit f8058f9

Please sign in to comment.