From d382bdd287356dfeb137a0c9a92dcf7b646e8c18 Mon Sep 17 00:00:00 2001 From: Phodal Huang Date: Tue, 30 Jan 2024 11:03:51 +0800 Subject: [PATCH] feat(cppast): add support for identifying namespaces This commit adds support for identifying namespaces in the CPPBasicIdentListenerTest. A new test case `shouldIdentifyNameSpace` is added to test the identification of namespaces. The `CPPBasicIdentListener` is modified to handle the `enterNamespaceDefinition` event and extract the namespace name from the context. The extracted namespace name is then assigned to the `PackageName` property of the `CodeContainer` class. --- .../chapi/ast/cppast/CPPBasicIdentListener.kt | 6 ++++++ .../ast/cppast/CPPBasicIdentListenerTest.kt | 21 ++++++++++++++++++- .../kotlin/chapi/domain/core/CodeContainer.kt | 2 ++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/chapi-ast-cpp/src/main/kotlin/chapi/ast/cppast/CPPBasicIdentListener.kt b/chapi-ast-cpp/src/main/kotlin/chapi/ast/cppast/CPPBasicIdentListener.kt index b8bcd720..909eaea3 100644 --- a/chapi-ast-cpp/src/main/kotlin/chapi/ast/cppast/CPPBasicIdentListener.kt +++ b/chapi-ast-cpp/src/main/kotlin/chapi/ast/cppast/CPPBasicIdentListener.kt @@ -15,6 +15,12 @@ class CPPBasicIdentListener(fileName: String) : CPP14ParserBaseListener() { private var classes = mutableListOf() private var currentNode: CodeDataStruct? = null + override fun enterNamespaceDefinition(ctx: CPP14Parser.NamespaceDefinitionContext?) { + ctx?.Identifier()?.let { + codeContainer.PackageName = it.text + } + } + override fun enterFunctionDefinition(ctx: CPP14Parser.FunctionDefinitionContext?) { val method = CodeFunction() diff --git a/chapi-ast-cpp/src/test/kotlin/chapi/ast/cppast/CPPBasicIdentListenerTest.kt b/chapi-ast-cpp/src/test/kotlin/chapi/ast/cppast/CPPBasicIdentListenerTest.kt index 3d3b97a6..ff0a4532 100644 --- a/chapi-ast-cpp/src/test/kotlin/chapi/ast/cppast/CPPBasicIdentListenerTest.kt +++ b/chapi-ast-cpp/src/test/kotlin/chapi/ast/cppast/CPPBasicIdentListenerTest.kt @@ -92,7 +92,7 @@ void display(char c, int n) { } @Test - internal fun shouldIdentifyFunction() { + internal fun shouldIdentifyClassFunction() { val code = """ class EntityB: public Entity { @@ -112,4 +112,23 @@ void display(char c, int n) { assertEquals(container.DataStructures[0].NodeName, "EntityB") assertEquals(container.DataStructures[0].Functions[0].Name, "init") } + + @Test + internal fun shouldIdentifyNameSpace() { + val code = """ + namespace NS + { + class M + { + friend class F; // Introduces F but doesn't define it + }; + } + """.trimIndent() + + val container = CPPAnalyser().analysis(code, "helloworld.cpp") + assertEquals(container.PackageName, "NS") + assertEquals(container.DataStructures.size, 1) + assertEquals(container.DataStructures[0].NodeName, "M") + } + } diff --git a/chapi-domain/src/main/kotlin/chapi/domain/core/CodeContainer.kt b/chapi-domain/src/main/kotlin/chapi/domain/core/CodeContainer.kt index 05ee1129..98101ac3 100644 --- a/chapi-domain/src/main/kotlin/chapi/domain/core/CodeContainer.kt +++ b/chapi-domain/src/main/kotlin/chapi/domain/core/CodeContainer.kt @@ -7,6 +7,8 @@ import kotlinx.serialization.Serializable data class CodeContainer( var FullName: String = "", /** + * In Rust, the package name is the module name. + * In C++, C#, the namespace is the package name. * In toml, the package name is the table name. */ var PackageName: String = "",