diff --git a/cpg-language-go/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/golang/DeclarationHandler.kt b/cpg-language-go/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/golang/DeclarationHandler.kt index a25beee957..5123ec3d58 100644 --- a/cpg-language-go/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/golang/DeclarationHandler.kt +++ b/cpg-language-go/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/golang/DeclarationHandler.kt @@ -61,10 +61,15 @@ class DeclarationHandler(frontend: GoLanguageFrontend) : val recv = funcDecl.recv val func = if (recv != null) { - val method = newMethodDeclaration(funcDecl.name.name, rawNode = funcDecl) val recvField = recv.list.firstOrNull() val recordType = recvField?.type?.let { frontend.typeOf(it) } ?: unknownType() + val method = + newMethodDeclaration( + Name(funcDecl.name.name, recordType.name), + rawNode = funcDecl + ) + // The name of the Go receiver is optional. In fact, if the name is not // specified we probably do not need any receiver variable at all, // because the syntax is only there to ensure that this method is part @@ -95,7 +100,13 @@ class DeclarationHandler(frontend: GoLanguageFrontend) : // associated members of the class and the pure AST nodes declared in the // struct // itself - record?.addMethod(method) + if (record != null) { + method.recordDeclaration = record + record.addMethod(method) + + // Enter scope of record + frontend.scopeManager.enterScope(record) + } } method } else { @@ -186,6 +197,11 @@ class DeclarationHandler(frontend: GoLanguageFrontend) : frontend.scopeManager.leaveScope(func) + // Leave scope of record, if applicable + (func as? MethodDeclaration)?.recordDeclaration?.let { + frontend.scopeManager.leaveScope(it) + } + return func } diff --git a/cpg-language-go/src/test/kotlin/de/fraunhofer/aisec/cpg/frontends/golang/DeclarationTest.kt b/cpg-language-go/src/test/kotlin/de/fraunhofer/aisec/cpg/frontends/golang/DeclarationTest.kt index b9ce305d42..1624bf0298 100644 --- a/cpg-language-go/src/test/kotlin/de/fraunhofer/aisec/cpg/frontends/golang/DeclarationTest.kt +++ b/cpg-language-go/src/test/kotlin/de/fraunhofer/aisec/cpg/frontends/golang/DeclarationTest.kt @@ -105,14 +105,12 @@ class DeclarationTest { ) { it.registerLanguage() } - assertNotNull(tu) - val p = tu.getDeclarationsByName("p", NamespaceDeclaration::class.java).iterator().next() - - val myStruct = - p.getDeclarationsByName("p.MyStruct", RecordDeclaration::class.java).iterator().next() + val p = tu.namespaces["p"] + assertNotNull(p) + val myStruct = p.records["MyStruct"] assertNotNull(myStruct) assertEquals("struct", myStruct.kind) @@ -126,8 +124,7 @@ class DeclarationTest { var myFunc = methods.firstOrNull() assertNotNull(myFunc) - - assertLocalName("MyFunc", myFunc) + assertFullName("p.MyStruct.MyFunc", myFunc) val myField = fields.firstOrNull() assertNotNull(myField)