16
16
17
17
package org.jetbrains.kotlin.idea.core.script
18
18
19
+ import com.intellij.execution.configurations.CommandLineTokenizer
19
20
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
20
21
import com.intellij.openapi.project.Project
21
22
import org.gradle.tooling.ProjectConnection
23
+ import org.jetbrains.kotlin.lexer.KotlinLexer
24
+ import org.jetbrains.kotlin.lexer.KtTokens
22
25
import org.jetbrains.kotlin.script.ScriptTemplateProvider
23
26
import org.jetbrains.plugins.gradle.service.execution.GradleExecutionHelper
24
27
import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings
25
28
import java.io.File
29
+ import java.util.*
26
30
27
31
class GradleScriptTemplateProvider (project : Project ): ScriptTemplateProvider {
28
32
@@ -42,6 +46,15 @@ class GradleScriptTemplateProvider(project: Project): ScriptTemplateProvider {
42
46
}
43
47
}
44
48
49
+ private val gradleJvmOptions: List <String > by lazy {
50
+ gradleExeSettings?.let { settings ->
51
+ CommandLineTokenizer (settings.daemonVmOptions).toList()
52
+ .mapNotNull { it?.let { it as ? String } }
53
+ .filterNot { it.isBlank() }
54
+ .distinct()
55
+ } ? : emptyList()
56
+ }
57
+
45
58
override val id: String = " Gradle"
46
59
override val version: Int = 1
47
60
override val isValid: Boolean get() = gradleExeSettings?.gradleHome != null
@@ -54,16 +67,70 @@ class GradleScriptTemplateProvider(project: Project): ScriptTemplateProvider {
54
67
?.map { it.canonicalPath }
55
68
? : emptyList()
56
69
}
57
- override val environment: Map <String , Any ?>? by lazy { mapOf (
70
+ override val environment: Map <String , Any ?>? by lazy {
71
+
72
+ mapOf (
58
73
" gradleHome" to gradleExeSettings?.gradleHome?.let { File (it) },
59
74
" projectRoot" to (project.basePath ? : project.baseDir.canonicalPath)?.let { File (it) },
60
- " projectActionExecutor " to { action: (ProjectConnection ) -> Unit ->
75
+ " gradleWithConnection " to { action: (ProjectConnection ) -> Unit ->
61
76
GradleExecutionHelper ().execute(project.basePath!! , null ) { action(it) } },
62
- " gradleJavaHome" to gradleExeSettings?.javaHome)
77
+ " gradleJavaHome" to gradleExeSettings?.javaHome,
78
+ " gradleJvmOptions" to gradleJvmOptions,
79
+ " getScriptSectionTokens" to ::topLevelSectionCodeTextTokens)
63
80
}
64
81
65
82
companion object {
66
83
private val depLibsPrefixes = listOf (" gradle-script-kotlin" , " gradle-core" )
67
84
}
68
85
}
69
86
87
+ class TopLevelSectionTokensEnumerator (script : CharSequence , identifier : String ) : Enumeration<KotlinLexer> {
88
+
89
+ private val lexer = KotlinLexer ().apply {
90
+ start(script)
91
+ var depth = 0
92
+
93
+ loop@ while (tokenType != null ) {
94
+ when (tokenType) {
95
+ KtTokens .IDENTIFIER -> if (depth == 0 && tokenText == identifier) {
96
+ advance()
97
+ skipWhiteSpaceAndComments()
98
+ if (tokenType == KtTokens .LBRACE )
99
+ break @loop
100
+ }
101
+ KtTokens .LBRACE -> depth + = 1
102
+ KtTokens .RBRACE -> depth - = 1
103
+ }
104
+ advance()
105
+ }
106
+ }
107
+
108
+ private var depth = 1
109
+ private var finished = false
110
+
111
+ override fun hasMoreElements (): Boolean = ! finished && lexer.tokenType != null
112
+
113
+ override fun nextElement (): KotlinLexer = lexer.apply {
114
+ advance()
115
+ when (tokenType) {
116
+ KtTokens .LBRACE -> depth + = 1
117
+ KtTokens .RBRACE -> {
118
+ if (depth == 1 ) {
119
+ finished = true
120
+ }
121
+ depth - = 1
122
+ }
123
+ }
124
+ }
125
+
126
+ private fun KotlinLexer.skipWhiteSpaceAndComments () {
127
+ while (tokenType in KtTokens .WHITE_SPACE_OR_COMMENT_BIT_SET ) {
128
+ advance()
129
+ }
130
+ }
131
+ }
132
+
133
+ fun topLevelSectionCodeTextTokens (script : CharSequence , sectionIdentifier : String ): Sequence <CharSequence > =
134
+ TopLevelSectionTokensEnumerator (script, sectionIdentifier).asSequence()
135
+ .filter { it.tokenType !in KtTokens .WHITE_SPACE_OR_COMMENT_BIT_SET }
136
+ .map { it.tokenSequence }
0 commit comments