From 15c8f0e14da40cf2268cc57600278a0320471375 Mon Sep 17 00:00:00 2001 From: Phodal Huang Date: Tue, 30 Jan 2024 12:12:50 +0800 Subject: [PATCH] feat(cpp): add support for identifying C++ structures #24 This commit adds support for identifying C++ structures in the `CPPBasicIdentListener` class. It includes a new test case that analyzes a C++ code snippet and verifies the identification of a structure. The identified structure is then added to the `CodeContainer` object. Additionally, the `CodeDataStruct` class is updated to include a new `DataStructType` enum value for C++ unions. --- .../chapi/ast/cppast/CPPBasicIdentListener.kt | 12 ++++++++++++ .../ast/cppast/CPPBasicIdentListenerTest.kt | 17 +++++++++++++++++ .../kotlin/chapi/domain/core/CodeDataStruct.kt | 2 ++ .../main/kotlin/chapi/domain/core/CodeField.kt | 7 ++++--- 4 files changed, 35 insertions(+), 3 deletions(-) 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 ee5ce843..ec186bcc 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 @@ -60,6 +60,16 @@ class CPPBasicIdentListener(fileName: String) : CPP14ParserBaseListener() { override fun enterClassSpecifier(ctx: CPP14Parser.ClassSpecifierContext?) { ctx?.classHead()?.let { currentNode = CodeDataStruct() + + it.classKey()?.let { keyContext -> + currentNode?.Type = when (keyContext.text) { + "class" -> DataStructType.CLASS + "struct" -> DataStructType.STRUCT + "union" -> DataStructType.UNION + else -> DataStructType.CLASS + } + } + currentNode?.NodeName = it.classHeadName()?.className()?.text ?: "" val extends = it.baseClause()?.baseSpecifierList()?.baseSpecifier()?.map { baseSpecifier -> @@ -88,6 +98,8 @@ class CPPBasicIdentListener(fileName: String) : CPP14ParserBaseListener() { } } + + fun getNodeInfo(): CodeContainer { if (defaultNode.Functions.isNotEmpty()) { codeContainer.DataStructures += defaultNode 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 d5f2b3e6..009b88fd 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 @@ -1,5 +1,6 @@ package chapi.ast.cppast +import chapi.domain.core.DataStructType import org.junit.jupiter.api.Test import kotlin.test.assertEquals @@ -150,4 +151,20 @@ void display(char c, int n) { assertEquals(container.DataStructures[0].Fields[1].TypeType, "int") assertEquals(container.DataStructures[0].Fields[1].TypeKey, "No") } + + @Test + internal fun shouldIdentifyCppStructure() { + val code = """ + struct Person + { + char name[50]; + int age; + float salary; + }; + """.trimIndent() + + val container = CPPAnalyser().analysis(code, "helloworld.cpp") + assertEquals(container.DataStructures.size, 1) + assertEquals(container.DataStructures[0].Type, DataStructType.STRUCT) + } } diff --git a/chapi-domain/src/main/kotlin/chapi/domain/core/CodeDataStruct.kt b/chapi-domain/src/main/kotlin/chapi/domain/core/CodeDataStruct.kt index 1c09c5a8..e4c3d5a3 100644 --- a/chapi-domain/src/main/kotlin/chapi/domain/core/CodeDataStruct.kt +++ b/chapi-domain/src/main/kotlin/chapi/domain/core/CodeDataStruct.kt @@ -15,6 +15,8 @@ enum class DataStructType(val structType: String) { INNER_STRUCTURES("InnerStructures"), CREATOR_CLASS("CreatorClass"), ABSTRACT_CLASS("AbstractClass"), + /// add 2.2.6 for cpp + UNION("Union"), // for scala, Rust TRAIT("Trait"), diff --git a/chapi-domain/src/main/kotlin/chapi/domain/core/CodeField.kt b/chapi-domain/src/main/kotlin/chapi/domain/core/CodeField.kt index 19faa003..86594bc7 100644 --- a/chapi-domain/src/main/kotlin/chapi/domain/core/CodeField.kt +++ b/chapi-domain/src/main/kotlin/chapi/domain/core/CodeField.kt @@ -3,14 +3,15 @@ package chapi.domain.core import kotlinx.serialization.Serializable /** + * Represents a field in a Java class. + * + * In Java, a field is defined as follows: * - * for Java, it will be the field * ```java * private String helloText = "hello, world"; * // || || || * // * ``` - * */ @Serializable data class CodeField( @@ -19,7 +20,7 @@ data class CodeField( var TypeKey: String = "", var Annotations: List = listOf(), var Modifiers: List = listOf(), - // for TypeScript and JavaScript only, examples: `export default sample = createHello() ` + /// for TypeScript and JavaScript only, examples: `export default sample = createHello() ` var Calls: List = listOf(), /// import 2.2.3 for Toml @Since("2.2.3")