Skip to content

Commit

Permalink
feat(cpp): add CppContextPrettify utility class and test case
Browse files Browse the repository at this point in the history
This commit adds the `CppContextPrettify` utility class, which provides a method `extractStructureText` to extract the structure text from a given `OCStruct` object. It also includes a test case `CppContextPrettifyTest` to verify the functionality of the utility class.
  • Loading branch information
phodal committed Jan 17, 2024
1 parent f98ee90 commit b3d9dd6
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 0 deletions.
59 changes: 59 additions & 0 deletions cpp/src/main/kotlin/cc/unitmesh/cpp/util/CppContextPrettify.kt
@@ -0,0 +1,59 @@
package cc.unitmesh.cpp.util

import com.intellij.psi.PsiComment
import com.intellij.psi.PsiElement
import com.intellij.psi.util.PsiTreeUtil
import com.jetbrains.cidr.lang.psi.*

object CppContextPrettify {
fun extractStructureText(struct: OCStruct): String {
val builder = StringBuilder()
findDeclAndExtractCommentWithTemplateLists(struct, builder)
builder.append("struct").append(' ').append(struct.name).append(" {\n")

struct.members.forEach { member ->
val declaration = member as? OCFunctionDeclaration ?: member
if (declaration is OCFunctionDeclaration) {
extractDeclCommentAndTemplateLists(declaration, builder)
val signature = declaration.symbol?.getSignature(struct.project)
builder.append("$signature;\n")
} else if (declaration != null) {
builder.append(declaration.text).append("\n")
}
}

builder.append("}")
return builder.toString()
}

private fun findDeclAndExtractCommentWithTemplateLists(
struct: OCStruct,
structTextBuilder: java.lang.StringBuilder
) {
val parentPsiDecl = findParentOCDeclaration(struct as PsiElement)
if (parentPsiDecl != null) {
extractDeclCommentAndTemplateLists(parentPsiDecl, structTextBuilder)
}
}

private fun findParentOCDeclaration(globalContextElement: PsiElement): OCDeclaration? {
return PsiTreeUtil.findFirstParent(globalContextElement) { parentElement ->
parentElement is OCDeclaration
} as? OCDeclaration
}

private fun extractDeclCommentAndTemplateLists(parentPsiDecl: OCDeclaration, builder: StringBuilder) {
if (parentPsiDecl.firstChild is PsiComment) {
builder.append(parentPsiDecl.firstChild.text).append("\n")
}

parentPsiDecl.children.filterIsInstance<OCTemplateParameterList>().firstOrNull()?.let {
builder.append(it.text).append("\n")
}

parentPsiDecl.children.filterIsInstance<OCTemplateArgumentList>().firstOrNull()?.let {
builder.append(it.text).append("\n")
}
}

}
52 changes: 52 additions & 0 deletions cpp/src/test/kotlin/cc/unitmesh/cpp/util/CppContextPrettifyTest.kt
@@ -0,0 +1,52 @@
package cc.unitmesh.cpp.util;

import com.intellij.psi.PsiComment
import com.intellij.psi.PsiElement
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.testFramework.fixtures.BasePlatformTestCase
import com.jetbrains.cidr.lang.psi.*
import org.junit.Assert.assertEquals
import org.junit.Test

class CppContextPrettifyTest : BasePlatformTestCase() {

fun testShouldExtractStructureText() {
// given
val psiElement = myFixture.configureByText(
"car.cpp", """
#include <iostream>
class Car {
public:
// class data
std::string brand, model;
int mileage = 0;
// class function
void drive(int distance) {
mileage += distance;
}
};
""".trimIndent()
)

val decl = PsiTreeUtil.getChildrenOfTypeAsList(psiElement, OCDeclaration::class.java).first()
val type = PsiTreeUtil.getChildrenOfTypeAsList(decl, OCTypeElement::class.java).first()
val struct = PsiTreeUtil.getChildrenOfTypeAsList(type, OCStructLike::class.java).first()

// when
val result = CppContextPrettify.extractStructureText(struct as OCStruct)

// then
val expected = """
struct Car {
// class data
std::string brand, model;
int mileage = 0;
// class function
void drive(int distance);
}
""".trimIndent()
assertEquals(expected, result)
}
}

0 comments on commit b3d9dd6

Please sign in to comment.