Skip to content

Commit 20025bd

Browse files
committed
feat(compiler): add parallel directory node support #308
Introduce `ParallelDirsNode` to handle directory structures like `component/{col,row,tag}/src`. Add detection logic and processing for parallel directories, improving directory tree representation. Also, add refactoring prompt documentation.
1 parent 84dfba8 commit 20025bd

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
layout: default
3+
title: Refactoring Prompt
4+
nav_order: 13
5+
parent: Development
6+
---
7+
8+
## Refactoring
9+
10+
User: 现在的代码逻辑不够概念化,理解起来有点困难
11+
Assistant:你的问题是当前的 DirInsCommand 类逻辑不够概念化,理解起来比较困难。我将通过重构来提高代码的可读性和概念清晰度。
12+
13+
解决步骤:
14+
- 引入更明确的数据模型来表示目录结构
15+
- 分离展示逻辑和数据收集逻辑
16+
- 简化递归遍历算法
17+
- 提高命名的表达性
18+
- 添加更多注释说明设计思想
19+

exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/compiler/exec/DirInsCommand.kt

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,13 @@ class DirInsCommand(private val myProject: Project, private val dir: String) : I
7171

7272
// 压缩目录节点,用于显示多个同层次目录
7373
data class CompressedNode(override val name: String, val subdirNames: List<String>) : TreeNode()
74+
75+
// 并列简单目录节点,用于像 component/{col,row,tag}/src 这样的结构
76+
data class ParallelDirsNode(
77+
override val name: String,
78+
val dirNames: List<String>,
79+
val commonChildName: String
80+
) : TreeNode()
7481
}
7582

7683
override suspend fun execute(): String? {
@@ -110,6 +117,17 @@ class DirInsCommand(private val myProject: Project, private val dir: String) : I
110117
// 添加目录节点
111118
val subdirectories = directory.subdirectories.filter { !isExcluded(project, it) }
112119

120+
// 检查是否可以应用并列简单目录压缩模式
121+
val parallelDirsNode = detectParallelSimpleDirs(project, subdirectories)
122+
if (parallelDirsNode != null) {
123+
dirNode.addChild(parallelDirsNode)
124+
125+
// 添加那些不符合并列模式的其他子目录
126+
processRemainingDirs(project, subdirectories, parallelDirsNode.dirNames, dirNode, depth)
127+
128+
return dirNode
129+
}
130+
113131
// 检查是否应该压缩显示子目录
114132
if (shouldCompressSubdirectories(project, directory, subdirectories, depth)) {
115133
// 获取可以压缩的子目录列表
@@ -128,6 +146,56 @@ class DirInsCommand(private val myProject: Project, private val dir: String) : I
128146

129147
return dirNode
130148
}
149+
150+
/**
151+
* 处理剩余的不符合并列目录模式的子目录
152+
*/
153+
private fun processRemainingDirs(
154+
project: Project,
155+
allDirs: List<PsiDirectory>,
156+
parallelDirNames: List<String>,
157+
parentNode: TreeNode.DirectoryNode,
158+
depth: Int
159+
) {
160+
val remainingDirs = allDirs.filter { dir -> dir.name !in parallelDirNames }
161+
remainingDirs.forEach { dir ->
162+
buildDirectoryTree(project, dir, depth + 1)?.let { subdirNode ->
163+
parentNode.addChild(subdirNode)
164+
}
165+
}
166+
}
167+
168+
/**
169+
* 检测并列的简单目录模式,如多个组件目录下都只有一个相同名称的子目录
170+
*/
171+
private fun detectParallelSimpleDirs(project: Project, subdirs: List<PsiDirectory>): TreeNode.ParallelDirsNode? {
172+
if (subdirs.size < 2) return null
173+
174+
// 收集有相同子目录结构的目录组
175+
val dirGroups = mutableMapOf<String, MutableList<PsiDirectory>>()
176+
177+
// 对每个目录,检查它是否有单一子目录,如果有,记录子目录名
178+
subdirs.forEach { dir ->
179+
val nonExcludedChildren = dir.subdirectories.filter { !isExcluded(project, it) }
180+
if (nonExcludedChildren.size == 1) {
181+
val childName = nonExcludedChildren.first().name
182+
dirGroups.getOrPut(childName) { mutableListOf() }.add(dir)
183+
}
184+
}
185+
186+
// 找出最大的组(具有相同子目录名的父目录组)
187+
val largestGroup = dirGroups.maxByOrNull { it.value.size }
188+
189+
// 如果最大组至少有2个目录且子目录名不为空,则创建并列目录节点
190+
if (largestGroup != null && largestGroup.value.size >= 2 && largestGroup.key.isNotEmpty()) {
191+
val commonChildName = largestGroup.key
192+
val parentDirNames = largestGroup.value.map { it.name }
193+
194+
return TreeNode.ParallelDirsNode("parallelDirs", parentDirNames, commonChildName)
195+
}
196+
197+
return null
198+
}
131199

132200
/**
133201
* 判断是否应该压缩显示子目录
@@ -178,6 +246,12 @@ class DirInsCommand(private val myProject: Project, private val dir: String) : I
178246
is TreeNode.CompressedNode -> {
179247
output.appendLine("$indent$prefix── {${child.subdirNames.joinToString(",")}}/")
180248
}
249+
250+
is TreeNode.ParallelDirsNode -> {
251+
// 以更紧凑的格式显示并列目录结构
252+
val dirs = child.dirNames.sorted().joinToString(",")
253+
output.appendLine("$indent$prefix── {$dirs}/${child.commonChildName}/")
254+
}
181255
}
182256
}
183257
}

0 commit comments

Comments
 (0)