Skip to content

Commit b3d9dd6

Browse files
committed
feat(cpp): add CppContextPrettify utility class and test case
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.
1 parent f98ee90 commit b3d9dd6

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package cc.unitmesh.cpp.util
2+
3+
import com.intellij.psi.PsiComment
4+
import com.intellij.psi.PsiElement
5+
import com.intellij.psi.util.PsiTreeUtil
6+
import com.jetbrains.cidr.lang.psi.*
7+
8+
object CppContextPrettify {
9+
fun extractStructureText(struct: OCStruct): String {
10+
val builder = StringBuilder()
11+
findDeclAndExtractCommentWithTemplateLists(struct, builder)
12+
builder.append("struct").append(' ').append(struct.name).append(" {\n")
13+
14+
struct.members.forEach { member ->
15+
val declaration = member as? OCFunctionDeclaration ?: member
16+
if (declaration is OCFunctionDeclaration) {
17+
extractDeclCommentAndTemplateLists(declaration, builder)
18+
val signature = declaration.symbol?.getSignature(struct.project)
19+
builder.append("$signature;\n")
20+
} else if (declaration != null) {
21+
builder.append(declaration.text).append("\n")
22+
}
23+
}
24+
25+
builder.append("}")
26+
return builder.toString()
27+
}
28+
29+
private fun findDeclAndExtractCommentWithTemplateLists(
30+
struct: OCStruct,
31+
structTextBuilder: java.lang.StringBuilder
32+
) {
33+
val parentPsiDecl = findParentOCDeclaration(struct as PsiElement)
34+
if (parentPsiDecl != null) {
35+
extractDeclCommentAndTemplateLists(parentPsiDecl, structTextBuilder)
36+
}
37+
}
38+
39+
private fun findParentOCDeclaration(globalContextElement: PsiElement): OCDeclaration? {
40+
return PsiTreeUtil.findFirstParent(globalContextElement) { parentElement ->
41+
parentElement is OCDeclaration
42+
} as? OCDeclaration
43+
}
44+
45+
private fun extractDeclCommentAndTemplateLists(parentPsiDecl: OCDeclaration, builder: StringBuilder) {
46+
if (parentPsiDecl.firstChild is PsiComment) {
47+
builder.append(parentPsiDecl.firstChild.text).append("\n")
48+
}
49+
50+
parentPsiDecl.children.filterIsInstance<OCTemplateParameterList>().firstOrNull()?.let {
51+
builder.append(it.text).append("\n")
52+
}
53+
54+
parentPsiDecl.children.filterIsInstance<OCTemplateArgumentList>().firstOrNull()?.let {
55+
builder.append(it.text).append("\n")
56+
}
57+
}
58+
59+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package cc.unitmesh.cpp.util;
2+
3+
import com.intellij.psi.PsiComment
4+
import com.intellij.psi.PsiElement
5+
import com.intellij.psi.util.PsiTreeUtil
6+
import com.intellij.testFramework.fixtures.BasePlatformTestCase
7+
import com.jetbrains.cidr.lang.psi.*
8+
import org.junit.Assert.assertEquals
9+
import org.junit.Test
10+
11+
class CppContextPrettifyTest : BasePlatformTestCase() {
12+
13+
fun testShouldExtractStructureText() {
14+
// given
15+
val psiElement = myFixture.configureByText(
16+
"car.cpp", """
17+
#include <iostream>
18+
19+
class Car {
20+
public:
21+
// class data
22+
std::string brand, model;
23+
int mileage = 0;
24+
25+
// class function
26+
void drive(int distance) {
27+
mileage += distance;
28+
}
29+
};
30+
""".trimIndent()
31+
)
32+
33+
val decl = PsiTreeUtil.getChildrenOfTypeAsList(psiElement, OCDeclaration::class.java).first()
34+
val type = PsiTreeUtil.getChildrenOfTypeAsList(decl, OCTypeElement::class.java).first()
35+
val struct = PsiTreeUtil.getChildrenOfTypeAsList(type, OCStructLike::class.java).first()
36+
37+
// when
38+
val result = CppContextPrettify.extractStructureText(struct as OCStruct)
39+
40+
// then
41+
val expected = """
42+
struct Car {
43+
// class data
44+
std::string brand, model;
45+
int mileage = 0;
46+
// class function
47+
void drive(int distance);
48+
}
49+
""".trimIndent()
50+
assertEquals(expected, result)
51+
}
52+
}

0 commit comments

Comments
 (0)