Skip to content

Commit 120a59b

Browse files
committed
feat(pair): improve KotlinWriteTestService and TreeNodeTest
- Improve the `KotlinWriteTestService` class by modifying the `currentClass` variable to use a more concise syntax and handle null values properly. - Add new test cases to the `TreeNodeTest` class to test the `print()` method for different scenarios, including a single node, a tree with children, and a tree with multiple levels.
1 parent d71b8d5 commit 120a59b

File tree

6 files changed

+131
-29
lines changed

6 files changed

+131
-29
lines changed

β€Žjava/src/main/kotlin/cc/unitmesh/idea/provider/JavaLayeredArchProvider.kt

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@ package cc.unitmesh.idea.provider
22

33
import cc.unitmesh.devti.pair.arch.ProjectPackageTree
44
import cc.unitmesh.devti.provider.architecture.LayeredArchProvider
5+
import com.intellij.ide.highlighter.JavaFileType
56
import com.intellij.openapi.project.Project
67
import com.intellij.openapi.projectRoots.JavaSdkType
78
import com.intellij.openapi.roots.ProjectRootManager
8-
import com.intellij.psi.JavaPsiFacade
9+
import com.intellij.psi.PsiJavaFile
10+
import com.intellij.psi.PsiManager
11+
import com.intellij.psi.search.FileTypeIndex
12+
import com.intellij.psi.search.GlobalSearchScope
13+
import com.intellij.psi.search.ProjectScope
914

1015
class JavaLayeredArchProvider : LayeredArchProvider {
1116
private val layeredArch = ProjectPackageTree()
@@ -16,16 +21,15 @@ class JavaLayeredArchProvider : LayeredArchProvider {
1621
}
1722

1823
override fun getLayeredArch(project: Project): ProjectPackageTree {
19-
val psiFacade = JavaPsiFacade.getInstance(project)
24+
val searchScope: GlobalSearchScope = ProjectScope.getContentScope(project)
25+
val javaFiles = FileTypeIndex.getFiles(JavaFileType.INSTANCE, searchScope)
26+
val psiManager = PsiManager.getInstance(project)
2027

21-
val projectRootManager = ProjectRootManager.getInstance(project)
22-
val contentRoots = projectRootManager.contentRoots
23-
for (contentRoot in contentRoots) {
24-
// todo implement this
25-
val psiPackage = psiFacade.findPackage(contentRoot.url)
26-
if (psiPackage != null) {
27-
layeredArch.addPackage(psiPackage.qualifiedName)
28-
}
28+
javaFiles.forEach { javaFile ->
29+
val psiFile = psiManager.findFile(javaFile) ?: return@forEach
30+
val psiJavaFile = psiFile as? PsiJavaFile ?: return@forEach
31+
32+
layeredArch.addPackage(psiJavaFile.packageName)
2933
}
3034

3135
return layeredArch

β€Žkotlin/src/main/kotlin/cc/unitmesh/kotlin/provider/KotlinWriteTestService.kt

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,18 +90,20 @@ class KotlinWriteTestService : WriteTestService() {
9090

9191
project.guessProjectDir()?.refresh(true, true)
9292

93-
val currentClass = runReadAction {
94-
when (element) {
93+
val currentClass: String = runReadAction {
94+
val classContext = when (element) {
9595
is KtClassOrObject -> ClassContextProvider(false).from(element)
9696
is KtNamedFunction -> {
9797
PsiTreeUtil.getParentOfType(element, KtClassOrObject::class.java)?.let {
98-
return@runReadAction ClassContextProvider(false).from(it)
99-
} ?: return@runReadAction null
98+
ClassContextProvider(false).from(it)
99+
}
100100
}
101101

102102
else -> null
103103
}
104-
}?.format()
104+
105+
return@runReadAction classContext?.format() ?: ""
106+
}
105107

106108
val imports: List<String> = runReadAction {
107109
(sourceFile as KtFile).importList?.imports?.map { it.text } ?: emptyList()

β€Žsrc/233/main/resources/META-INF/autodev-core.xml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,13 @@
5050
icon="cc.unitmesh.devti.AutoDevIcons.AI_COPILOT"
5151
factoryClass="cc.unitmesh.devti.gui.AutoDevToolWindowFactory"/>
5252

53-
<toolWindow id="AutoDev Pair"
54-
doNotActivateOnStart="true"
55-
anchor="left"
56-
secondary="true"
57-
canCloseContents="false"
58-
icon="cc.unitmesh.devti.AutoDevIcons.AI_PAIR"
59-
factoryClass="cc.unitmesh.devti.gui.AutoDevPairToolWindowFactory"/>
53+
<!-- <toolWindow id="AutoDev Pair"-->
54+
<!-- doNotActivateOnStart="true"-->
55+
<!-- anchor="left"-->
56+
<!-- secondary="true"-->
57+
<!-- canCloseContents="false"-->
58+
<!-- icon="cc.unitmesh.devti.AutoDevIcons.AI_PAIR"-->
59+
<!-- factoryClass="cc.unitmesh.devti.gui.AutoDevPairToolWindowFactory"/>-->
6060

6161
<notificationGroup id="AI notification group" displayType="STICKY_BALLOON" bundle="messages.AutoDevBundle"
6262
key="name"/>

β€Žsrc/main/kotlin/cc/unitmesh/devti/gui/AutoDevPairToolWindowFactory.kt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
package cc.unitmesh.devti.gui
22

3+
import cc.unitmesh.devti.fullWidthCell
4+
import cc.unitmesh.devti.gui.chat.ChatRole
35
import cc.unitmesh.devti.provider.architecture.LayeredArchProvider
6+
import cc.unitmesh.devti.util.parser.Code
47
import com.intellij.openapi.Disposable
8+
import com.intellij.openapi.fileTypes.PlainTextLanguage
59
import com.intellij.openapi.project.Project
610
import com.intellij.openapi.ui.NullableComponent
711
import com.intellij.openapi.ui.SimpleToolWindowPanel
812
import com.intellij.openapi.wm.ToolWindow
913
import com.intellij.openapi.wm.ToolWindowFactory
14+
import com.intellij.temporary.gui.block.*
1015
import com.intellij.ui.dsl.builder.panel
1116

1217
class AutoDevPairToolWindowFactory : ToolWindowFactory {
@@ -27,11 +32,15 @@ class AutoDevPairToolWindow(val project: Project, val disposable: Disposable) :
2732
val layeredArch = LayeredArchProvider.find(project)?.getLayeredArch(project)
2833
val panel = panel {
2934
row {
30-
label("Hello World")
35+
label("Layered Architecture")
3136
}
3237
row {
33-
// show a tree in a table
34-
label(layeredArch.toString())
38+
val text = layeredArch?.print() ?: "No Layered Arch"
39+
val block = CodeBlock(SimpleMessage(text, text, ChatRole.User))
40+
block.code = Code(PlainTextLanguage.INSTANCE, text, true)
41+
42+
val codeBlockView = CodeBlockView(block, project, disposable)
43+
fullWidthCell(codeBlockView.getComponent())
3544
}
3645
}
3746

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,29 @@
11
package cc.unitmesh.devti.pair.arch
22

3+
/**
4+
* Represents a node in a tree structure.
5+
*
6+
* @property name the name of the node
7+
* @property children the list of child nodes
8+
*/
39
class TreeNode(val name: String, val children: MutableList<TreeNode> = mutableListOf()) {
410
fun addChild(child: TreeNode) {
511
children.add(child)
612
}
713

8-
fun print(): String {
14+
fun print(indent: String = "", isLast: Boolean = false): String {
915
val sb = StringBuilder()
16+
sb.append(indent)
17+
sb.append(if (isLast) "└── " else "β”œβ”€β”€ ")
1018
sb.append(name)
1119
sb.append("\n")
12-
for (child in children) {
13-
sb.append(child.print())
20+
21+
val childIndent = "$indent${if (isLast) " " else "β”‚ "}"
22+
for ((index, child) in children.withIndex()) {
23+
val childIsLast = index == children.size - 1
24+
sb.append(child.print(childIndent, childIsLast))
1425
}
26+
1527
return sb.toString()
1628
}
17-
}
29+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package cc.unitmesh.devti.pair.arch;
2+
3+
import org.junit.Assert.assertEquals
4+
import org.junit.Test
5+
6+
class TreeNodeTest {
7+
8+
@Test
9+
fun shouldPrintSingleNode() {
10+
// given
11+
val node = TreeNode("A")
12+
13+
// when
14+
val result = node.print()
15+
16+
// then
17+
assertEquals("β”œβ”€β”€ A\n", result)
18+
}
19+
20+
@Test
21+
fun shouldPrintTreeWithChildren() {
22+
// given
23+
val nodeA = TreeNode("A")
24+
val nodeB = TreeNode("B")
25+
val nodeC = TreeNode("C")
26+
val nodeD = TreeNode("D")
27+
nodeA.addChild(nodeB)
28+
nodeA.addChild(nodeC)
29+
nodeC.addChild(nodeD)
30+
31+
// when
32+
val result = nodeA.print()
33+
34+
// then
35+
val expected = """
36+
β”œβ”€β”€ A
37+
β”‚ β”œβ”€β”€ B
38+
β”‚ └── C
39+
β”‚ └── D
40+
41+
""".trimIndent()
42+
assertEquals(expected, result)
43+
}
44+
45+
@Test
46+
fun shouldPrintTreeWithMultipleLevels() {
47+
// given
48+
val nodeA = TreeNode("A")
49+
val nodeB = TreeNode("B")
50+
val nodeC = TreeNode("C")
51+
val nodeD = TreeNode("D")
52+
val nodeE = TreeNode("E")
53+
val nodeF = TreeNode("F")
54+
nodeA.addChild(nodeB)
55+
nodeA.addChild(nodeC)
56+
nodeB.addChild(nodeD)
57+
nodeB.addChild(nodeE)
58+
nodeC.addChild(nodeF)
59+
60+
// when
61+
val result = nodeA.print()
62+
63+
// then
64+
val expected = """
65+
β”œβ”€β”€ A
66+
β”‚ β”œβ”€β”€ B
67+
β”‚ β”‚ β”œβ”€β”€ D
68+
β”‚ β”‚ └── E
69+
β”‚ └── C
70+
β”‚ └── F
71+
72+
""".trimIndent()
73+
assertEquals(expected, result)
74+
}
75+
}

0 commit comments

Comments
Β (0)