Skip to content

Commit 5527d13

Browse files
committed
feat(javascript): add ReactUIComponentProvider for UI component collection #319
Introduce `ReactUIComponentProvider` to collect UI components from JavaScript and TypeScript files. This includes updating configuration files and refactoring existing code to use the new provider.
1 parent 732fd56 commit 5527d13

File tree

7 files changed

+110
-28
lines changed

7 files changed

+110
-28
lines changed

core/src/223/main/resources/META-INF/autodev-core.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,11 @@
217217
interface="cc.unitmesh.devti.provider.RevisionProvider"
218218
dynamic="true">
219219
</extensionPoint>
220+
221+
<!-- Bridge -->
222+
<extensionPoint qualifiedName="cc.unitmesh.uiComponentProvider"
223+
interface="cc.unitmesh.devti.bridge.provider.UiComponentProvider"
224+
dynamic="true"/>
220225
</extensionPoints>
221226

222227
<applicationListeners>

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,10 @@
193193
<!-- Lang Sketch Provider -->
194194
<extensionPoint qualifiedName="cc.unitmesh.langSketchProvider"
195195
interface="cc.unitmesh.devti.sketch.ui.LanguageSketchProvider"
196-
dynamic="true" />
196+
dynamic="true"/>
197197
<extensionPoint qualifiedName="cc.unitmesh.sketchToolchainProvider"
198198
interface="cc.unitmesh.devti.sketch.SketchToolchainProvider"
199-
dynamic="true" />
199+
dynamic="true"/>
200200

201201
<extensionPoint qualifiedName="cc.unitmesh.relatedClassProvider"
202202
beanClass="com.intellij.lang.LanguageExtensionPoint" dynamic="true">
@@ -217,6 +217,11 @@
217217
interface="cc.unitmesh.devti.provider.RevisionProvider"
218218
dynamic="true">
219219
</extensionPoint>
220+
221+
<!-- Bridge -->
222+
<extensionPoint qualifiedName="cc.unitmesh.uiComponentProvider"
223+
interface="cc.unitmesh.devti.bridge.provider.UiComponentProvider"
224+
dynamic="true"/>
220225
</extensionPoints>
221226

222227
<applicationListeners>
@@ -262,14 +267,14 @@
262267
<action id="cc.unitmesh.devti.inlayCompleteCode"
263268
class="cc.unitmesh.devti.actions.completion.InlayCompleteCodeAction"
264269
text="Inlay Complete Code (AutoDev)"
265-
description="Inlay complete code!" >
270+
description="Inlay complete code!">
266271
<keyboard-shortcut keymap="$default" first-keystroke="alt PERIOD"/>
267272
<add-to-group group-id="ShowIntentionsGroup" relative-to-action="ShowIntentionActions" anchor="after"/>
268273
</action>
269274
<action id="cc.unitmesh.devti.disposeInlayCompleteCode"
270275
class="cc.unitmesh.devti.actions.completion.InlayCompleteCodeDisposedAction"
271276
text="Disposed Inlay Complete Code"
272-
description="Disposed Inlay complete code!" >
277+
description="Disposed Inlay complete code!">
273278
<keyboard-shortcut keymap="$default" first-keystroke="ESCAPE"/>
274279
</action>
275280

@@ -358,7 +363,7 @@
358363

359364
<group id="AutoDev.ToolWindow.Chat.TitleActions">
360365
<action id="AutoDev.ToolWindow.NewChatAction" class="cc.unitmesh.devti.gui.toolbar.NewChatAction"/>
361-
<!-- <action id="AutoDev.ToolWindow.NewSketchAction" class="cc.unitmesh.devti.gui.toolbar.NewSketchAction"/>-->
366+
<!-- <action id="AutoDev.ToolWindow.NewSketchAction" class="cc.unitmesh.devti.gui.toolbar.NewSketchAction"/>-->
362367
</group>
363368

364369
<group id="AutoDev.ToolWindow.Message.Toolbar.Assistant">
@@ -388,7 +393,8 @@
388393
icon="cc.unitmesh.devti.AutoDevIcons.AI_COPILOT"
389394
class="cc.unitmesh.devti.actions.chat.AutoTestInMenuAction">
390395

391-
<add-to-group group-id="ProjectViewPopupMenu" anchor="after" relative-to-action="ProjectViewPopupMenuRefactoringGroup" />
396+
<add-to-group group-id="ProjectViewPopupMenu" anchor="after"
397+
relative-to-action="ProjectViewPopupMenuRefactoringGroup"/>
392398
<add-to-group group-id="RefactoringMenu" anchor="last"/>
393399
<add-to-group group-id="EditorTabPopupMenu" anchor="last"/>
394400
</action>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package cc.unitmesh.devti.bridge.provider
2+
3+
import cc.unitmesh.devti.bridge.tools.UiComponent
4+
import com.intellij.openapi.extensions.ExtensionPointName
5+
import com.intellij.openapi.project.Project
6+
import com.intellij.serviceContainer.LazyExtensionInstance
7+
import com.intellij.util.xmlb.annotations.Attribute
8+
9+
abstract class UiComponentProvider : LazyExtensionInstance<UiComponentProvider>() {
10+
@Attribute("implementationClass")
11+
var implementationClass: String? = null
12+
13+
override fun getImplementationClassName(): String? = implementationClass
14+
15+
open fun collect(project: Project): List<UiComponent> {
16+
return emptyList()
17+
}
18+
19+
companion object {
20+
val EP_NAME: ExtensionPointName<UiComponentProvider> =
21+
ExtensionPointName.create("cc.unitmesh.uiComponentProvider")
22+
}
23+
24+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package cc.unitmesh.ide.javascript.bridge
2+
3+
import cc.unitmesh.devti.bridge.provider.UiComponentProvider
4+
import cc.unitmesh.devti.bridge.tools.UiComponent
5+
import cc.unitmesh.ide.javascript.flow.ReactAutoPage
6+
import cc.unitmesh.ide.javascript.util.ReactPsiUtil
7+
import com.intellij.lang.javascript.JavaScriptFileType
8+
import com.intellij.lang.javascript.TypeScriptJSXFileType
9+
import com.intellij.lang.javascript.dialects.ECMA6LanguageDialect
10+
import com.intellij.lang.javascript.dialects.TypeScriptJSXLanguageDialect
11+
import com.intellij.lang.javascript.psi.JSFile
12+
import com.intellij.openapi.diagnostic.logger
13+
import com.intellij.openapi.project.Project
14+
import com.intellij.psi.PsiManager
15+
import com.intellij.psi.search.FileTypeIndex
16+
import com.intellij.psi.search.GlobalSearchScope
17+
import com.intellij.psi.search.ProjectScope
18+
import kotlin.collections.plusAssign
19+
20+
class ReactUIComponentProvider : UiComponentProvider() {
21+
override fun collect(project: Project): List<UiComponent> {
22+
val searchScope: GlobalSearchScope = ProjectScope.getContentScope(project)
23+
val psiManager = PsiManager.getInstance(project)
24+
25+
val virtualFiles =
26+
FileTypeIndex.getFiles(JavaScriptFileType.INSTANCE, searchScope) +
27+
FileTypeIndex.getFiles(TypeScriptJSXFileType.INSTANCE, searchScope)
28+
29+
val components = mutableListOf<UiComponent>()
30+
virtualFiles.forEach { file ->
31+
val jsFile = (psiManager.findFile(file) ?: return@forEach) as? JSFile ?: return@forEach
32+
if (jsFile.isTestFile) return@forEach
33+
34+
components += buildComponent(jsFile) ?: return@forEach
35+
}
36+
37+
return components
38+
}
39+
40+
companion object {
41+
fun buildComponent(jsFile: JSFile): List<UiComponent>? {
42+
return when (jsFile.language) {
43+
is TypeScriptJSXLanguageDialect,
44+
is ECMA6LanguageDialect
45+
-> {
46+
val dsComponents = ReactPsiUtil.tsxComponentToComponent(jsFile)
47+
if (dsComponents.isEmpty()) {
48+
logger<ReactAutoPage>().warn("no component found in ${jsFile.name}")
49+
}
50+
dsComponents
51+
}
52+
53+
else -> {
54+
logger<ReactAutoPage>().warn("unknown language: ${jsFile.language}")
55+
null
56+
}
57+
}
58+
}
59+
60+
}
61+
}

javascript/src/main/kotlin/cc/unitmesh/ide/javascript/flow/ReactAutoPage.kt

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cc.unitmesh.ide.javascript.flow
22

33
import cc.unitmesh.devti.bridge.tools.UiComponent
4+
import cc.unitmesh.ide.javascript.bridge.ReactUIComponentProvider
45
import cc.unitmesh.ide.javascript.util.ReactPsiUtil
56
import com.intellij.lang.javascript.JavaScriptFileType
67
import com.intellij.lang.javascript.TypeScriptJSXFileType
@@ -53,15 +54,15 @@ class ReactAutoPage(
5354
if (jsFile.isTestFile) return@forEach
5455

5556
when {
56-
path.contains("views") -> buildComponent(jsFile)?.let {
57+
path.contains("views") -> ReactUIComponentProvider.buildComponent(jsFile)?.let {
5758
pages += it
5859
}
5960

60-
path.contains("pages") -> buildComponent(jsFile)?.let {
61+
path.contains("pages") -> ReactUIComponentProvider.buildComponent(jsFile)?.let {
6162
pages += it
6263
}
6364

64-
path.contains("components") -> buildComponent(jsFile)?.let {
65+
path.contains("components") -> ReactUIComponentProvider.buildComponent(jsFile)?.let {
6566
components += it
6667
}
6768

@@ -82,25 +83,6 @@ class ReactAutoPage(
8283

8384
override fun getComponents(): List<UiComponent> = components
8485

85-
private fun buildComponent(jsFile: JSFile): List<UiComponent>? {
86-
return when (jsFile.language) {
87-
is TypeScriptJSXLanguageDialect,
88-
is ECMA6LanguageDialect
89-
-> {
90-
val dsComponents = ReactPsiUtil.tsxComponentToComponent(jsFile)
91-
if (dsComponents.isEmpty()) {
92-
logger<ReactAutoPage>().warn("no component found in ${jsFile.name}")
93-
}
94-
dsComponents
95-
}
96-
97-
else -> {
98-
logger<ReactAutoPage>().warn("unknown language: ${jsFile.language}")
99-
null
100-
}
101-
}
102-
}
103-
10486
override fun getRoutes(): Map<String, String> {
10587
return this.routes.map {
10688
when (it.key) {

javascript/src/main/resources/cc.unitmesh.javascript.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,7 @@
4444
implementationClass="cc.unitmesh.ide.javascript.provider.JavaScriptLivingDocumentation"/>
4545

4646
<buildSystemProvider implementation="cc.unitmesh.ide.javascript.provider.JavaScriptBuildSystemProvider" />
47+
48+
<uiComponentProvider implementation="cc.unitmesh.ide.javascript.bridge.ReactUIComponentProvider"/>
4749
</extensions>
4850
</idea-plugin>

javascript/src/test/kotlin/cc/unitmesh/ide/javascript/util/ReactPsiUtilTest.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import com.intellij.lang.javascript.JavascriptLanguage
44
import com.intellij.lang.javascript.psi.JSFile
55
import com.intellij.psi.PsiFileFactory
66
import com.intellij.testFramework.LightPlatformTestCase
7+
import org.intellij.lang.annotations.Language
78

89
class ReactPsiUtilTest : LightPlatformTestCase() {
910
fun testShouldHandleExportReactComponent() {
11+
@Language("TypeScript JSX")
1012
val code = """
1113
interface AppProps {
1214
Component: any;

0 commit comments

Comments
 (0)