Skip to content

Commit a3de41e

Browse files
committed
feat(shire): add post processors && update package structure and imports to align with new namespace #379
1 parent ba0a83e commit a3de41e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1514
-26
lines changed

core/src/main/kotlin/cc/unitmesh/devti/context/builder/CodeModifier.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package cc.unitmesh.devti.context.builder
22

33
import com.intellij.lang.Language
4+
import com.intellij.lang.LanguageExtension
45
import com.intellij.openapi.project.Project
56
import com.intellij.openapi.vfs.VirtualFile
7+
import com.intellij.psi.PsiElement
68

79
/**
810
* The `CodeModifier` interface provides methods for modifying code in a given project.
@@ -43,4 +45,20 @@ interface CodeModifier {
4345
* @return True if the class was successfully inserted, false otherwise.
4446
*/
4547
fun insertClass(sourceFile: VirtualFile, project: Project, code: String): Boolean
48+
49+
/**
50+
* According to the source file, project, and code, it will insert the code in a smart way.
51+
*/
52+
fun smartInsert(sourceFile: VirtualFile, project: Project, code: String): PsiElement? {
53+
return null
54+
}
55+
56+
companion object {
57+
private val languageExtension: LanguageExtension<CodeModifier> =
58+
LanguageExtension("cc.unitmesh.shireCodeModifier")
59+
60+
fun forLanguage(language: Language): CodeModifier? {
61+
return languageExtension.forLanguage(language)
62+
}
63+
}
4664
}

core/src/main/kotlin/cc/unitmesh/devti/provider/PsiElementDataBuilder.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ interface PsiElementDataBuilder {
4343

4444
fun lookupElement(project: Project, canonicalName: String): ClassContext? = null
4545

46+
fun parseComment(project: Project, code: String): String? = null
47+
4648
companion object {
4749
private val languageExtension: LanguageExtension<PsiElementDataBuilder> =
4850
LanguageExtension("cc.unitmesh.testDataBuilder")

exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/ast/FunctionStatementProcessor.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ import com.intellij.openapi.diagnostic.logger
1111
import com.intellij.openapi.project.Project
1212
import com.intellij.psi.PsiElement
1313
import com.jayway.jsonpath.JsonPath
14-
import com.phodal.shirelang.compiler.ast.*
15-
import com.phodal.shirelang.compiler.execute.shireql.ShireDateSchema
14+
import cc.unitmesh.shirelang.compiler.execute.shireql.ShireDateSchema
1615
import kotlinx.coroutines.runBlocking
1716

1817
/**

exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/ast/action/PatternActionFuncDef.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ enum class PatternActionFuncDef(val funcName: String, val description: String, v
335335
| ---
336336
| ```
337337
|
338-
| Output Example: 1: package com.phodal.devinlang.controller; 2: import org.springframework.web.bind.annotation.GetMapping; 3: import org.springframework.web.bind.annotation.RestController; 4: import org.springframework.web.bind.annotation.RequestMapping; 5: import org.springframework.web.bind.annotation.RequestParam;
338+
| Output Example: 1: package cc.unitmesh.devinlang.controller; 2: import org.springframework.web.bind.annotation.GetMapping; 3: import org.springframework.web.bind.annotation.RestController; 4: import org.springframework.web.bind.annotation.RequestMapping; 5: import org.springframework.web.bind.annotation.RequestParam;
339339
|
340340
""".trimMargin()
341341
)

exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/ast/action/PatternFuncProcessor.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import com.intellij.openapi.vfs.LocalFileSystem
2121
import com.intellij.openapi.vfs.VirtualFile
2222
import com.intellij.openapi.vfs.findFile
2323
import com.intellij.openapi.vfs.readText
24-
import com.phodal.shirelang.compiler.execute.processor.CaptureProcessor
24+
import cc.unitmesh.shirelang.compiler.execute.processor.CaptureProcessor
2525
import cc.unitmesh.devti.language.processor.ForeignFunctionProcessor
2626
import kotlinx.coroutines.CoroutineScope
2727
import kotlinx.coroutines.launch

exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/ast/shireql/ShireDateSchema.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.phodal.shirelang.compiler.execute.shireql
1+
package cc.unitmesh.shirelang.compiler.execute.shireql
22

33
import cc.unitmesh.devti.language.ast.shireql.ShireQLSchema
44
import kotlinx.datetime.*

exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/ast/shireql/ShireQLInterpreter.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import com.intellij.openapi.project.Project
66
import com.intellij.psi.PsiElement
77

88
/**
9-
* For [com.phodal.shirelang.compiler.hobbit.execute.PsiQueryStatementProcessor]
9+
* For [cc.unitmesh.shirelang.compiler.hobbit.execute.PsiQueryStatementProcessor]
1010
*/
1111
interface ShireQLInterpreter {
1212
fun supportsMethod(language: Language, methodName: String): List<String>
@@ -23,7 +23,7 @@ interface ShireQLInterpreter {
2323

2424
companion object {
2525
private val languageExtension: LanguageExtension<ShireQLInterpreter> =
26-
LanguageExtension("com.phodal.shirePsiQLInterpreter")
26+
LanguageExtension("cc.unitmesh.shirePsiQLInterpreter")
2727

2828
fun provide(language: Language): ShireQLInterpreter? {
2929
return languageExtension.forLanguage(language)

exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/ast/shireql/ShireQLVariableBuilder.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import com.intellij.psi.PsiElement
88
import cc.unitmesh.devti.language.ast.shireql.variable.vcs.ShireGitCommit
99
import cc.unitmesh.devti.language.provider.ShireQLDataProvider
1010
import cc.unitmesh.devti.language.provider.ShireSymbolProvider
11-
import com.phodal.shirelang.compiler.execute.shireql.ShireDateSchema
11+
import cc.unitmesh.shirelang.compiler.execute.shireql.ShireDateSchema
1212

1313
class ShireQLVariableBuilder(val myProject: Project, hole: HobbitHole) {
1414
fun buildVariables(fromStmt: PatternActionFunc.From): Map<String, List<Any>> {

exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/ast/shireql/variable/frontend/ComponentProvider.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.phodal.shirecore.variable.frontend
1+
package cc.unitmesh.shirecore.variable.frontend
22

33
import cc.unitmesh.devti.language.ast.shireql.variable.frontend.Component
44

exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/ast/variable/PsiContextVariableProvider.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ interface PsiContextVariableProvider : VariableProvider<PsiContextVariable> {
5858

5959
companion object {
6060
private val languageExtension: LanguageExtension<PsiContextVariableProvider> =
61-
LanguageExtension("com.phodal.shirePsiVariableProvider")
61+
LanguageExtension("cc.unitmesh.shirePsiVariableProvider")
6262

6363
fun provide(language: Language): PsiContextVariableProvider {
6464
return languageExtension.forLanguage(language) ?: DefaultPsiContextVariableProvider()

exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/compiler/streaming/StreamingServiceProvider.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ interface StreamingServiceProvider : Disposable {
4747

4848
companion object {
4949
val EP_NAME =
50-
ExtensionPointName.create<StreamingServiceProvider>("com.phodal.shireStreamingService")
50+
ExtensionPointName.create<StreamingServiceProvider>("cc.unitmesh.shireStreamingService")
5151

5252
fun getStreamingService(name: String): StreamingServiceProvider? {
5353
return EP_NAME.extensions.firstOrNull { it.name == name }
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package cc.unitmesh.devti.language.middleware.builtin
2+
3+
import com.intellij.execution.ui.ConsoleView
4+
import com.intellij.openapi.project.Project
5+
import cc.unitmesh.devti.language.middleware.post.PostProcessorType
6+
import cc.unitmesh.devti.language.middleware.post.PostProcessorContext
7+
import cc.unitmesh.devti.language.middleware.post.PostProcessor
8+
import kotlin.text.get
9+
10+
class AppendProcessor : PostProcessor {
11+
override val processorName: String = PostProcessorType.Append.handleName
12+
override val description: String = "`append` will append the text to the generated text"
13+
14+
override fun isApplicable(context: PostProcessorContext): Boolean = true
15+
16+
override fun execute(
17+
project: Project,
18+
context: PostProcessorContext,
19+
console: ConsoleView?,
20+
args: List<Any>,
21+
): Any {
22+
23+
context.genText += args.map {
24+
if (it.toString().startsWith("$")) {
25+
context.compiledVariables[it.toString().substring(1)] ?: ""
26+
} else {
27+
it
28+
}
29+
}.joinToString(" ")
30+
31+
return context.genText ?: ""
32+
}
33+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package cc.unitmesh.devti.language.middleware.builtin
2+
3+
import com.intellij.diff.DiffContentFactoryEx
4+
import com.intellij.diff.DiffDialogHints
5+
import com.intellij.diff.DiffManager
6+
import com.intellij.diff.chains.SimpleDiffRequestChain
7+
import com.intellij.diff.chains.SimpleDiffRequestProducer
8+
import com.intellij.diff.requests.SimpleDiffRequest
9+
import com.intellij.execution.ui.ConsoleView
10+
import com.intellij.execution.ui.ConsoleViewContentType
11+
import com.intellij.openapi.application.runInEdt
12+
import com.intellij.openapi.application.runReadAction
13+
import com.intellij.openapi.project.Project
14+
import cc.unitmesh.devti.language.middleware.post.PostProcessor
15+
import cc.unitmesh.devti.language.middleware.post.PostProcessorContext
16+
import cc.unitmesh.devti.language.middleware.post.PostProcessorType
17+
import cc.unitmesh.devti.language.utils.findFile
18+
19+
class DiffProcessor : PostProcessor {
20+
override val processorName: String = PostProcessorType.Diff.handleName
21+
override val description: String =
22+
"`diff` will show the diff of two texts, default is current code and llm response"
23+
24+
private val diffFactory = DiffContentFactoryEx.getInstanceEx()
25+
26+
override fun isApplicable(context: PostProcessorContext): Boolean {
27+
return true
28+
}
29+
30+
override fun execute(project: Project, context: PostProcessorContext, console: ConsoleView?, args: List<Any>): Any {
31+
if (args.size < 2) {
32+
console?.print("DiffProcessor: not enough arguments", ConsoleViewContentType.ERROR_OUTPUT)
33+
return ""
34+
}
35+
36+
val firstArg = args[0].toString()
37+
val virtualFile = runReadAction { project.findFile(firstArg) } ?: let {
38+
console?.print("DiffProcessor: file not found", ConsoleViewContentType.ERROR_OUTPUT)
39+
return ""
40+
}
41+
42+
val currentDocContent = diffFactory.create(project, virtualFile)
43+
val newDocContent = diffFactory.create(args[1].toString())
44+
45+
val diffRequest =
46+
SimpleDiffRequest("Shire Diff Viewer", currentDocContent, newDocContent, "Current code", "AI generated")
47+
val producer = SimpleDiffRequestProducer.create(virtualFile.path) {
48+
diffRequest
49+
}
50+
51+
val chain = SimpleDiffRequestChain.fromProducer(producer)
52+
runInEdt {
53+
DiffManager.getInstance().showDiff(project, chain, DiffDialogHints.FRAME)
54+
}
55+
56+
return ""
57+
}
58+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package cc.unitmesh.devti.language.middleware.builtin
2+
3+
import com.intellij.execution.ui.ConsoleView
4+
import com.intellij.openapi.command.WriteCommandAction
5+
import com.intellij.openapi.project.Project
6+
import com.intellij.psi.PsiDocumentManager
7+
import com.intellij.psi.codeStyle.CodeStyleManager
8+
import cc.unitmesh.devti.language.middleware.post.PostProcessorType
9+
import cc.unitmesh.devti.language.middleware.post.PostProcessorContext
10+
import cc.unitmesh.devti.language.middleware.post.PostProcessor
11+
import cc.unitmesh.devti.util.workerThread
12+
import kotlinx.coroutines.CoroutineScope
13+
import kotlinx.coroutines.launch
14+
15+
class FormatCodeProcessor : PostProcessor {
16+
override val processorName: String = PostProcessorType.FormatCode.handleName
17+
override val description: String = "`formatCode` will format the code of the current file"
18+
19+
override fun isApplicable(context: PostProcessorContext): Boolean = true
20+
21+
override fun execute(project: Project, context: PostProcessorContext, console: ConsoleView?, args: List<Any>): Any {
22+
val file = context.currentFile ?: return ""
23+
val document = PsiDocumentManager.getInstance(project).getDocument(file) ?: return ""
24+
25+
CoroutineScope(workerThread).launch {
26+
WriteCommandAction.runWriteCommandAction(project) {
27+
val codeStyleManager = CodeStyleManager.getInstance(project)
28+
if (context.modifiedTextRange != null) {
29+
codeStyleManager.reformatText(file, listOf(context.modifiedTextRange))
30+
} else if (context.genPsiElement != null) {
31+
codeStyleManager.reformat(context.genPsiElement!!)
32+
} else {
33+
codeStyleManager.reformatText(file, 0, document.textLength)
34+
}
35+
}
36+
}
37+
38+
return context.genText ?: ""
39+
}
40+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package cc.unitmesh.devti.language.middleware.builtin
2+
3+
import cc.unitmesh.devti.context.builder.CodeModifier
4+
import com.intellij.execution.ui.ConsoleView
5+
import com.intellij.execution.ui.ConsoleViewContentType
6+
import com.intellij.openapi.command.WriteCommandAction
7+
import com.intellij.openapi.project.Project
8+
import cc.unitmesh.devti.language.middleware.post.PostProcessorType
9+
import cc.unitmesh.devti.language.middleware.post.PostProcessorContext
10+
import cc.unitmesh.devti.language.middleware.post.PostProcessor
11+
12+
class InsertCodeProcessor : PostProcessor {
13+
override val processorName: String = PostProcessorType.InsertCode.handleName
14+
override val description: String = "`insertCode` will insert the code to the current file"
15+
16+
override fun isApplicable(context: PostProcessorContext): Boolean = true
17+
18+
override fun execute(project: Project, context: PostProcessorContext, console: ConsoleView?, args: List<Any>): String {
19+
if (context.currentLanguage == null || context.currentFile == null) {
20+
console?.print("No found current language\n", ConsoleViewContentType.ERROR_OUTPUT)
21+
return ""
22+
}
23+
24+
25+
val codeModifier = CodeModifier.forLanguage(context.currentLanguage!!)
26+
if (codeModifier == null) {
27+
console?.print("No code modifier found\n", ConsoleViewContentType.NORMAL_OUTPUT)
28+
// insert to the end of the file
29+
val editor = context.editor ?: return ""
30+
WriteCommandAction.runWriteCommandAction(project) {
31+
editor.document.insertString(editor.caretModel.offset, context.genText ?: "")
32+
}
33+
return ""
34+
}
35+
36+
context.genPsiElement = codeModifier.smartInsert(context.currentFile!!.virtualFile!!, project, context.genText ?: "")
37+
return ""
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package cc.unitmesh.devti.language.middleware.builtin
2+
3+
import com.intellij.execution.ui.ConsoleView
4+
import com.intellij.openapi.command.WriteCommandAction
5+
import com.intellij.openapi.project.Project
6+
import cc.unitmesh.devti.language.middleware.post.PostProcessorType
7+
import cc.unitmesh.devti.language.middleware.post.PostProcessorContext
8+
import cc.unitmesh.devti.language.middleware.post.PostProcessor
9+
import cc.unitmesh.devti.util.workerThread
10+
import kotlinx.coroutines.CoroutineScope
11+
import kotlinx.coroutines.launch
12+
13+
class InsertNewlineProcessor : PostProcessor {
14+
override val processorName: String = PostProcessorType.InsertNewline.handleName
15+
override val description: String = "`insertNewline` will insert a newline at the cursor position"
16+
17+
override fun isApplicable(context: PostProcessorContext): Boolean = true
18+
19+
override fun execute(project: Project, context: PostProcessorContext, console: ConsoleView?, args: List<Any>): Any {
20+
val editor = context.editor ?: return ""
21+
22+
CoroutineScope(workerThread).launch {
23+
WriteCommandAction.runWriteCommandAction(project) {
24+
editor.document.insertString(editor.caretModel.offset, "\n")
25+
}
26+
}
27+
28+
return editor.document.text
29+
}
30+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package cc.unitmesh.devti.language.middleware.builtin
2+
3+
import com.intellij.execution.filters.OpenFileHyperlinkInfo
4+
import com.intellij.execution.ui.ConsoleView
5+
import com.intellij.openapi.application.runInEdt
6+
import com.intellij.openapi.fileEditor.FileEditorManager
7+
import com.intellij.openapi.project.Project
8+
import com.intellij.openapi.vfs.VirtualFile
9+
import cc.unitmesh.devti.language.middleware.post.PostProcessorType
10+
import cc.unitmesh.devti.language.middleware.post.PostProcessorContext
11+
import cc.unitmesh.devti.language.middleware.post.PostProcessor
12+
import cc.unitmesh.devti.language.utils.findFile
13+
import com.intellij.execution.ui.ConsoleViewContentType
14+
15+
16+
class OpenFileProcessor : PostProcessor {
17+
override val processorName: String = PostProcessorType.OpenFile.handleName
18+
override val description: String = "`openFile` will open the file in the editor"
19+
20+
override fun isApplicable(context: PostProcessorContext): Boolean = true
21+
22+
override fun execute(project: Project, context: PostProcessorContext, console: ConsoleView?, args: List<Any>): String {
23+
val firstArg = args.firstOrNull()
24+
val file = firstArg ?: context.pipeData["output"] ?: context.genText
25+
if (file !is VirtualFile) {
26+
if (file is String) {
27+
// check has multiple files
28+
val files = file.split("\n")
29+
runInEdt {
30+
val findFiles = files.mapNotNull { project.findFile(it) }
31+
findFiles.map {
32+
console?.printHyperlink("$it", OpenFileHyperlinkInfo(project, it, -1, -1))
33+
// new line
34+
console?.print("\n", ConsoleViewContentType.NORMAL_OUTPUT)
35+
}
36+
37+
findFiles.mapIndexed { index, it ->
38+
val isFocus = index == findFiles.size - 1
39+
FileEditorManager.getInstance(project).openFile(it, isFocus)
40+
}
41+
}
42+
43+
return ""
44+
} else {
45+
console?.print("No file to open\n", ConsoleViewContentType.ERROR_OUTPUT)
46+
}
47+
48+
return ""
49+
}
50+
51+
runInEdt {
52+
FileEditorManager.getInstance(project).openFile(file, true)
53+
}
54+
55+
return ""
56+
}
57+
}
58+

0 commit comments

Comments
 (0)