1
1
package cc.unitmesh.devti.language.compiler
2
2
3
3
import cc.unitmesh.devti.language.completion.BuiltinCommand
4
+ import cc.unitmesh.devti.language.parser.CodeBlockElement
5
+ import cc.unitmesh.devti.language.psi.DevInCode
4
6
import cc.unitmesh.devti.language.psi.DevInFile
5
7
import cc.unitmesh.devti.language.psi.DevInTypes
6
8
import cc.unitmesh.devti.language.psi.DevInUsed
7
9
import com.intellij.openapi.diagnostic.logger
8
10
import com.intellij.openapi.editor.Editor
9
11
import com.intellij.openapi.project.Project
12
+ import com.intellij.psi.PsiElement
10
13
import com.intellij.psi.util.elementType
11
14
12
15
data class CompileResult (
@@ -15,17 +18,28 @@ data class CompileResult(
15
18
)
16
19
17
20
class DevInsCompiler (val myProject : Project , val file : DevInFile , val editor : Editor ? = null ) {
21
+ private var skipNextCode: Boolean = false
18
22
private val logger = logger<DevInsCompiler >()
19
23
private val result = CompileResult ()
20
24
private val output: StringBuilder = StringBuilder ()
21
25
26
+ /* *
27
+ * Todo: build AST tree, then compile
28
+ */
22
29
fun compile (): CompileResult {
23
30
file.children.forEach {
24
31
when (it.elementType) {
25
32
DevInTypes .TEXT_SEGMENT -> output.append(it.text)
26
33
DevInTypes .NEWLINE -> output.append(" \n " )
27
- // todo: add lazy to process code
28
- DevInTypes .CODE -> output.append(it.text)
34
+ DevInTypes .CODE -> {
35
+ if (skipNextCode) {
36
+ skipNextCode = false
37
+ return @forEach
38
+ }
39
+
40
+ output.append(it.text)
41
+ }
42
+
29
43
DevInTypes .USED -> processUsed(it as DevInUsed )
30
44
else -> {
31
45
output.append(it.text)
@@ -60,7 +74,7 @@ class DevInsCompiler(val myProject: Project, val file: DevInFile, val editor: Ed
60
74
return
61
75
}
62
76
63
- processingCommand(command, propElement!! .text, fallbackText = used.text)
77
+ processingCommand(command, propElement!! .text, used, fallbackText = used.text)
64
78
}
65
79
66
80
DevInTypes .AGENT_START -> {
@@ -82,7 +96,7 @@ class DevInsCompiler(val myProject: Project, val file: DevInFile, val editor: Ed
82
96
}
83
97
}
84
98
85
- private fun processingCommand (commandNode : BuiltinCommand , prop : String , fallbackText : String ) {
99
+ private fun processingCommand (commandNode : BuiltinCommand , prop : String , used : DevInUsed , fallbackText : String ) {
86
100
val command: AutoCommand = when (commandNode) {
87
101
BuiltinCommand .FILE -> {
88
102
FileAutoCommand (myProject, prop)
@@ -98,7 +112,28 @@ class DevInsCompiler(val myProject: Project, val file: DevInFile, val editor: Ed
98
112
99
113
BuiltinCommand .WRITE -> {
100
114
result.isLocalCommand = true
101
- PrintAutoCommand (" /" + commandNode.agentName + " :" + prop)
115
+ // val devInCode = used.nextSibling.nextSibling as? DevInCode
116
+ // lookup in code
117
+ val devInCode: CodeBlockElement ?
118
+ var next: PsiElement ? = used
119
+ while (true ) {
120
+ next = next?.nextSibling
121
+ if (next == null ) {
122
+ devInCode = null
123
+ break
124
+ }
125
+
126
+ if (next.elementType == DevInTypes .CODE ) {
127
+ devInCode = next as CodeBlockElement
128
+ break
129
+ }
130
+ }
131
+
132
+ if (devInCode == null ) {
133
+ PrintAutoCommand (" /" + commandNode.agentName + " :" + prop)
134
+ } else {
135
+ WriteAutoCommand (myProject, prop, devInCode.text)
136
+ }
102
137
}
103
138
104
139
BuiltinCommand .PATCH -> {
@@ -112,8 +147,17 @@ class DevInsCompiler(val myProject: Project, val file: DevInFile, val editor: Ed
112
147
}
113
148
}
114
149
115
- val result = command.execute() ? : fallbackText
150
+ val execResult = command.execute()
151
+ val result = if (execResult?.contains(" <DevliError>" ) == false ) {
152
+ if (commandNode == BuiltinCommand .WRITE ) {
153
+ skipNextCode = true
154
+ }
155
+
156
+ execResult
157
+ } else {
158
+ execResult ? : fallbackText
159
+ }
160
+
116
161
output.append(result)
117
162
}
118
-
119
- }
163
+ }
0 commit comments