Skip to content

Commit

Permalink
feat(chapi-ast-cpp): add support for importing C++ headers
Browse files Browse the repository at this point in the history
This commit adds support for importing C++ headers in the CPPBasicIdentListener class. The includes are extracted from the code using a regular expression and added to the CodeContainer as CodeImport objects. This allows for better analysis of C++ code that relies on external headers.
  • Loading branch information
phodal committed Feb 14, 2024
1 parent 6f772ae commit 3956222
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ typedef struct {
}

@Test
fun readlWorld() {
fun shouldSuccessHandleDs() {
val code = """
// https://stackoverflow.com/questions/12642830/can-i-define-a-function-inside-a-c-structure
#include <stdio.h>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,16 @@ open class CPPAnalyser: Analyser {
return output
}

private val importRegex = Regex("""#include\s+(<[^>]+>|\"[^\"]+\")""")

override fun analysis(code: String, filePath: String): CodeContainer {
val processedCode = preProcessing(code)
val includesDirective = importRegex.findAll(code).map {
it.groupValues[1]
}.toMutableList()

val context = this.parse(processedCode).translationUnit()
val listener = CPPBasicIdentListener(fileName = filePath)
val listener = CPPBasicIdentListener(fileName = filePath, includesDirective)

ParseTreeWalker().walk(listener, context)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,30 @@ import chapi.ast.antlr.CPP14Parser
import chapi.ast.antlr.CPP14ParserBaseListener
import chapi.domain.core.*

class CPPBasicIdentListener(fileName: String) : CPP14ParserBaseListener() {
class CPPBasicIdentListener(fileName: String, includes: MutableList<String>) : CPP14ParserBaseListener() {
private var codeContainer: CodeContainer = CodeContainer(FullName = fileName)
/// for example, Friend function, global function (`main`), etc.
private var defaultNode = CodeDataStruct()
private var currentFunction: CodeFunction? = null
private var classes = mutableListOf<CodeDataStruct>()
private var currentNode: CodeDataStruct? = null

init {
includes.forEach {
val value = it
.removeSurrounding("\"", "\"")
.removeSurrounding("<", ">")

val imp = CodeImport(
Source = value,
AsName = value
)

codeContainer.Imports += imp
}

}

override fun enterNamespaceDefinition(ctx: CPP14Parser.NamespaceDefinitionContext?) {
ctx?.Identifier()?.let {
codeContainer.PackageName = it.text
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ int main(){}
"""
val container = CPPAnalyser().analysis(code, "helloworld.cpp")
assertEquals(container.DataStructures[0].Functions[0].ReturnType, "int")

// imports
assertEquals(container.Imports.size, 1)
assertEquals(container.Imports[0].Source, "iostream")
}

@Test
Expand Down

0 comments on commit 3956222

Please sign in to comment.