Skip to content

Commit 9909f15

Browse files
committed
feat(devin-lang): add support for file path processing in DevInCompiler #101
This commit introduces a new feature to the DevInCompiler class, which allows for the processing of file paths specified in DevInFile commands. It includes the ability to extract a range from a file using a comment-based syntax, and to read the contents of a file from the project directory. Additionally, the compiler now handles various built-in commands more robustly, with logging for missing command properties and proper handling of each command type.
1 parent 81766ff commit 9909f15

File tree

2 files changed

+73
-13
lines changed

2 files changed

+73
-13
lines changed

exts/devin-lang/src/main/kotlin/cc/unitmesh/devti/language/compiler/DevInCompiler.kt

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,14 @@ import cc.unitmesh.devti.language.psi.DevInUsed
77
import com.intellij.openapi.diagnostic.logger
88
import com.intellij.openapi.editor.Editor
99
import com.intellij.openapi.project.Project
10+
import com.intellij.openapi.project.guessProjectDir
11+
import com.intellij.openapi.util.NlsSafe
12+
import com.intellij.openapi.util.TextRange
13+
import com.intellij.openapi.vfs.VirtualFileManager
1014
import com.intellij.psi.util.elementType
15+
import kotlin.io.path.readText
1116

12-
class DevInCompiler(val project: Project, val file: DevInFile, val editor: Editor) {
17+
class DevInCompiler(val myProject: Project, val file: DevInFile, val editor: Editor? = null) {
1318
private val logger = logger<DevInCompiler>()
1419
private val output: StringBuilder = StringBuilder()
1520

@@ -38,27 +43,27 @@ class DevInCompiler(val project: Project, val file: DevInFile, val editor: Edito
3843

3944
private fun processUsed(used: DevInUsed) {
4045
val firstChild = used.firstChild
41-
val id = used.children.getOrNull(1)
46+
val id = firstChild.nextSibling
4247

4348
when (firstChild.elementType) {
4449
DevInTypes.COMMAND_START -> {
45-
/**
46-
*
47-
*/
48-
4950
val command = BuiltinCommand.fromString(id?.text ?: "")
5051
if (command == null) {
5152
output.append(used.text)
5253
logger.warn("Unknown command: ${id?.text}")
5354
return
5455
}
5556

56-
when (command) {
57-
BuiltinCommand.FILE -> TODO()
58-
BuiltinCommand.REV -> TODO()
59-
BuiltinCommand.SYMBOL -> TODO()
60-
BuiltinCommand.WRITE -> TODO()
57+
58+
val propElement = id.nextSibling?.nextSibling
59+
val isProp = (propElement.elementType == DevInTypes.COMMAND_PROP)
60+
if (!isProp) {
61+
output.append(used.text)
62+
logger.warn("No command prop found: ${used.text}")
63+
return
6164
}
65+
66+
processingCommand(command, propElement!!.text)
6267
}
6368

6469
DevInTypes.AGENT_START -> {
@@ -79,4 +84,40 @@ class DevInCompiler(val project: Project, val file: DevInFile, val editor: Edito
7984
}
8085
}
8186
}
87+
88+
private fun processingCommand(command: BuiltinCommand, prop: @NlsSafe String) {
89+
when (command) {
90+
BuiltinCommand.FILE -> {
91+
val range: TextRange? = if (prop.contains("#")) {
92+
val rangeStr = prop.substringAfter("#")
93+
val start = rangeStr.substringBefore("-").toInt()
94+
val end = rangeStr.substringAfter("-").toInt()
95+
TextRange(start, end)
96+
} else {
97+
null
98+
}
99+
100+
val filepath = prop.trim()
101+
val projectPath = myProject.guessProjectDir()?.toNioPath()
102+
val content = projectPath?.resolve(filepath)?.readText()
103+
content?.let {
104+
output.append(content)
105+
}
106+
107+
}
108+
109+
BuiltinCommand.REV -> {
110+
logger.info("handling rev")
111+
output.append(command.agentName)
112+
}
113+
BuiltinCommand.SYMBOL -> {
114+
logger.info("handling symbol")
115+
output.append(command.agentName)
116+
}
117+
BuiltinCommand.WRITE -> {
118+
logger.info("handling write")
119+
output.append(command.agentName)
120+
}
121+
}
122+
}
82123
}

exts/devin-lang/src/main/kotlin/cc/unitmesh/devti/language/run/DevInRunConfigurationProfileState.kt

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package cc.unitmesh.devti.language.run
22

3+
import cc.unitmesh.devti.language.compiler.DevInCompiler
4+
import cc.unitmesh.devti.language.psi.DevInFile
35
import com.intellij.build.process.BuildProcessHandler
46
import com.intellij.execution.DefaultExecutionResult
57
import com.intellij.execution.ExecutionException
@@ -14,6 +16,9 @@ import com.intellij.execution.runners.ProgramRunner
1416
import com.intellij.execution.ui.ConsoleView
1517
import com.intellij.execution.ui.ConsoleViewContentType
1618
import com.intellij.openapi.project.Project
19+
import com.intellij.openapi.vfs.VirtualFile
20+
import com.intellij.openapi.vfs.VirtualFileManager
21+
import com.intellij.psi.PsiManager
1722
import java.io.OutputStream
1823

1924
open class DevInRunConfigurationProfileState(
@@ -25,10 +30,24 @@ open class DevInRunConfigurationProfileState(
2530
ProcessTerminatedListener.attach(processHandler)
2631

2732
val console: ConsoleView = ConsoleViewWrapperBase(ConsoleViewImpl(myProject, true))
28-
2933
console.attachToProcess(processHandler)
3034

31-
console.print("Hello, World!", ConsoleViewContentType.NORMAL_OUTPUT)
35+
val file: DevInFile? = VirtualFileManager.getInstance()
36+
.findFileByUrl("file://${configuration.getScriptPath()}")
37+
?.let {
38+
PsiManager.getInstance(myProject).findFile(it)
39+
} as? DevInFile
40+
41+
if (file == null) {
42+
console.print("File not found: ${configuration.getScriptPath()}", ConsoleViewContentType.ERROR_OUTPUT)
43+
processHandler.destroyProcess()
44+
return DefaultExecutionResult(console, processHandler)
45+
}
46+
47+
val compiler = DevInCompiler(myProject, file)
48+
val output = compiler.compile()
49+
50+
console.print(output, ConsoleViewContentType.NORMAL_OUTPUT)
3251

3352
// done!
3453
processHandler.detachProcess()

0 commit comments

Comments
 (0)