Update gradle script resolver environment:

- JVM options from IDEA config to connect/run daemon with appropriate options (need to be tested)
- A lexing function to allow gradle plugin to check whether dependency-defining part of the script is actually changed
This commit is contained in:
Ilya Chernikov
2016-07-28 17:14:18 +02:00
parent 3b1e7494b8
commit 80f7dda6c7
@@ -16,13 +16,17 @@
package org.jetbrains.kotlin.idea.core.script
import com.intellij.execution.configurations.CommandLineTokenizer
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.project.Project
import org.gradle.tooling.ProjectConnection
import org.jetbrains.kotlin.lexer.KotlinLexer
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.script.ScriptTemplateProvider
import org.jetbrains.plugins.gradle.service.execution.GradleExecutionHelper
import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings
import java.io.File
import java.util.*
class GradleScriptTemplateProvider(project: Project): ScriptTemplateProvider {
@@ -42,6 +46,15 @@ class GradleScriptTemplateProvider(project: Project): ScriptTemplateProvider {
}
}
private val gradleJvmOptions: List<String> by lazy {
gradleExeSettings?.let { settings ->
CommandLineTokenizer(settings.daemonVmOptions).toList()
.mapNotNull { it?.let { it as? String } }
.filterNot { it.isBlank() }
.distinct()
} ?: emptyList()
}
override val id: String = "Gradle"
override val version: Int = 1
override val isValid: Boolean get() = gradleExeSettings?.gradleHome != null
@@ -54,12 +67,16 @@ class GradleScriptTemplateProvider(project: Project): ScriptTemplateProvider {
?.map { it.canonicalPath }
?: emptyList()
}
override val environment: Map<String, Any?>? by lazy { mapOf(
override val environment: Map<String, Any?>? by lazy {
mapOf(
"gradleHome" to gradleExeSettings?.gradleHome?.let { File(it) },
"projectRoot" to (project.basePath ?: project.baseDir.canonicalPath)?.let { File(it) },
"projectActionExecutor" to { action: (ProjectConnection) -> Unit ->
"gradleWithConnection" to { action: (ProjectConnection) -> Unit ->
GradleExecutionHelper().execute(project.basePath!!, null) { action(it) } },
"gradleJavaHome" to gradleExeSettings?.javaHome)
"gradleJavaHome" to gradleExeSettings?.javaHome,
"gradleJvmOptions" to gradleJvmOptions,
"getScriptSectionTokens" to ::topLevelSectionCodeTextTokens)
}
companion object {
@@ -67,3 +84,53 @@ class GradleScriptTemplateProvider(project: Project): ScriptTemplateProvider {
}
}
class TopLevelSectionTokensEnumerator(script: CharSequence, identifier: String) : Enumeration<KotlinLexer> {
private val lexer = KotlinLexer().apply {
start(script)
var depth = 0
loop@ while (tokenType != null) {
when (tokenType) {
KtTokens.IDENTIFIER -> if (depth == 0 && tokenText == identifier) {
advance()
skipWhiteSpaceAndComments()
if (tokenType == KtTokens.LBRACE)
break@loop
}
KtTokens.LBRACE -> depth += 1
KtTokens.RBRACE -> depth -= 1
}
advance()
}
}
private var depth = 1
private var finished = false
override fun hasMoreElements(): Boolean = !finished && lexer.tokenType != null
override fun nextElement(): KotlinLexer = lexer.apply {
advance()
when (tokenType) {
KtTokens.LBRACE -> depth += 1
KtTokens.RBRACE -> {
if (depth == 1) {
finished = true
}
depth -= 1
}
}
}
private fun KotlinLexer.skipWhiteSpaceAndComments() {
while (tokenType in KtTokens.WHITE_SPACE_OR_COMMENT_BIT_SET) {
advance()
}
}
}
fun topLevelSectionCodeTextTokens(script: CharSequence, sectionIdentifier: String): Sequence<CharSequence> =
TopLevelSectionTokensEnumerator(script, sectionIdentifier).asSequence()
.filter { it.tokenType !in KtTokens.WHITE_SPACE_OR_COMMENT_BIT_SET }
.map { it.tokenSequence }