Scripting: move gradle specific logic to idea-gradle
This commit is contained in:
committed by
Natalia Selezneva
parent
0fb58ed94c
commit
fc100d13dd
@@ -1,137 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.core.script.configuration
|
|
||||||
|
|
||||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.openapi.util.registry.Registry
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import com.intellij.psi.PsiManager
|
|
||||||
import com.intellij.psi.PsiRecursiveElementVisitor
|
|
||||||
import com.intellij.psi.PsiWhiteSpace
|
|
||||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
|
||||||
import kotlinx.coroutines.GlobalScope
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import org.jetbrains.kotlin.idea.core.script.configuration.cache.CachedConfigurationInputs
|
|
||||||
import org.jetbrains.kotlin.idea.core.script.configuration.listener.DefaultScriptChangeListener
|
|
||||||
import org.jetbrains.kotlin.idea.core.script.configuration.listener.ScriptConfigurationUpdater
|
|
||||||
import org.jetbrains.kotlin.idea.core.script.configuration.loader.DefaultScriptConfigurationLoader
|
|
||||||
import org.jetbrains.kotlin.idea.core.script.configuration.loader.ScriptConfigurationLoadingContext
|
|
||||||
import org.jetbrains.kotlin.idea.core.util.EDT
|
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
|
||||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
|
||||||
import org.jetbrains.kotlin.psi.KtScriptInitializer
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType
|
|
||||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
|
|
||||||
|
|
||||||
class GradleScriptListener : DefaultScriptChangeListener() {
|
|
||||||
private val listenGradleRelatedFiles = false // todo
|
|
||||||
|
|
||||||
override fun editorActivated(file: KtFile, updater: ScriptConfigurationUpdater): Boolean {
|
|
||||||
if (!isGradleKotlinScript(file.virtualFile)) return false
|
|
||||||
if (listenGradleRelatedFiles) {
|
|
||||||
updater.ensureUpToDatedConfigurationSuggested(file)
|
|
||||||
// todo: force reload if related files changed
|
|
||||||
} else {
|
|
||||||
// configuration will be reloaded after editor activation, even it is already up-to-date
|
|
||||||
// this is required for Gradle scripts, since it's classpath may depend on other files (`.properties` for example)
|
|
||||||
updater.forceConfigurationReload(file)
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class GradleScriptConfigurationLoader(project: Project) : DefaultScriptConfigurationLoader(project) {
|
|
||||||
private val useProjectImport: Boolean
|
|
||||||
get() = Registry.`is`("kotlin.gradle.scripts.useIdeaProjectImport", false)
|
|
||||||
|
|
||||||
override fun shouldRunInBackground(scriptDefinition: ScriptDefinition): Boolean {
|
|
||||||
return if (useProjectImport) false else super.shouldRunInBackground(scriptDefinition)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun loadDependencies(
|
|
||||||
isFirstLoad: Boolean,
|
|
||||||
ktFile: KtFile,
|
|
||||||
scriptDefinition: ScriptDefinition,
|
|
||||||
context: ScriptConfigurationLoadingContext
|
|
||||||
): Boolean {
|
|
||||||
if (!isGradleKotlinScript(ktFile.originalFile.virtualFile)) return false
|
|
||||||
|
|
||||||
if (useProjectImport) {
|
|
||||||
// do nothing, project import notification will be already showed
|
|
||||||
// and configuration for gradle build scripts will be saved at the end of import
|
|
||||||
// todo: use default configuration loader for out-of-project scripts?
|
|
||||||
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
// Gradle read files from FS
|
|
||||||
GlobalScope.launch(EDT(project)) {
|
|
||||||
runWriteAction {
|
|
||||||
FileDocumentManager.getInstance().saveAllDocuments()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.loadDependencies(isFirstLoad, ktFile, scriptDefinition, context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getInputsStamp(virtualFile: VirtualFile, file: KtFile): CachedConfigurationInputs {
|
|
||||||
return getGradleScriptInputsStamp(project, virtualFile, file) ?: super.getInputsStamp(virtualFile, file)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class GradleKotlinScriptConfigurationInputs(
|
|
||||||
val buildScriptAndPluginsSections: String
|
|
||||||
) : CachedConfigurationInputs {
|
|
||||||
override fun isUpToDate(project: Project, file: VirtualFile, ktFile: KtFile?): Boolean {
|
|
||||||
val actualStamp = getGradleScriptInputsStamp(project, file, ktFile)
|
|
||||||
return actualStamp == this
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isGradleKotlinScript(virtualFile: VirtualFile) = virtualFile.name.endsWith(".gradle.kts")
|
|
||||||
|
|
||||||
fun getGradleScriptInputsStamp(
|
|
||||||
project: Project,
|
|
||||||
file: VirtualFile,
|
|
||||||
givenKtFile: KtFile? = null
|
|
||||||
): GradleKotlinScriptConfigurationInputs? {
|
|
||||||
if (!isGradleKotlinScript(file)) return null
|
|
||||||
|
|
||||||
return runReadAction {
|
|
||||||
val ktFile = givenKtFile ?: PsiManager.getInstance(project).findFile(file) as? KtFile
|
|
||||||
|
|
||||||
if (ktFile != null) {
|
|
||||||
val result = StringBuilder()
|
|
||||||
ktFile.script?.blockExpression
|
|
||||||
?.getChildrenOfType<KtScriptInitializer>()
|
|
||||||
?.forEach {
|
|
||||||
val call = it.children.singleOrNull() as? KtCallExpression
|
|
||||||
val callRef = call?.firstChild?.text
|
|
||||||
if (callRef == "buildscript" || callRef == "plugins") {
|
|
||||||
result.append(callRef)
|
|
||||||
val lambda = call.lambdaArguments.singleOrNull()
|
|
||||||
lambda?.accept(object : PsiRecursiveElementVisitor(false) {
|
|
||||||
override fun visitElement(element: PsiElement) {
|
|
||||||
super.visitElement(element)
|
|
||||||
when (element) {
|
|
||||||
is PsiWhiteSpace -> if (element.text.contains("\n")) result.append("\n")
|
|
||||||
is LeafPsiElement -> result.append(element.text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
result.append("\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GradleKotlinScriptConfigurationInputs(result.toString())
|
|
||||||
} else null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
-1
@@ -25,7 +25,7 @@ import com.intellij.pom.Navigatable
|
|||||||
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
|
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
|
||||||
import org.jetbrains.kotlin.idea.core.script.configuration.cache.CachedConfigurationInputs
|
import org.jetbrains.kotlin.idea.core.script.configuration.cache.CachedConfigurationInputs
|
||||||
import org.jetbrains.kotlin.idea.core.script.configuration.cache.ScriptConfigurationSnapshot
|
import org.jetbrains.kotlin.idea.core.script.configuration.cache.ScriptConfigurationSnapshot
|
||||||
import org.jetbrains.kotlin.idea.core.script.configuration.getGradleScriptInputsStamp
|
import org.jetbrains.kotlin.idea.script.getGradleScriptInputsStamp
|
||||||
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
|
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
|
||||||
import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper
|
import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper
|
||||||
import org.jetbrains.kotlin.scripting.resolve.VirtualFileScriptSource
|
import org.jetbrains.kotlin.scripting.resolve.VirtualFileScriptSource
|
||||||
|
|||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.script
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import org.jetbrains.kotlin.idea.core.script.configuration.cache.CachedConfigurationInputs
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
|
data class GradleKotlinScriptConfigurationInputs(
|
||||||
|
val buildScriptAndPluginsSections: String
|
||||||
|
) : CachedConfigurationInputs {
|
||||||
|
override fun isUpToDate(project: Project, file: VirtualFile, ktFile: KtFile?): Boolean {
|
||||||
|
val actualStamp = getGradleScriptInputsStamp(project, file, ktFile)
|
||||||
|
return actualStamp == this
|
||||||
|
}
|
||||||
|
}
|
||||||
+60
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.script
|
||||||
|
|
||||||
|
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.util.registry.Registry
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import org.jetbrains.kotlin.idea.core.script.configuration.cache.CachedConfigurationInputs
|
||||||
|
import org.jetbrains.kotlin.idea.core.script.configuration.loader.DefaultScriptConfigurationLoader
|
||||||
|
import org.jetbrains.kotlin.idea.core.script.configuration.loader.ScriptConfigurationLoadingContext
|
||||||
|
import org.jetbrains.kotlin.idea.core.util.EDT
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
|
||||||
|
|
||||||
|
class GradleScriptConfigurationLoader(project: Project) : DefaultScriptConfigurationLoader(project) {
|
||||||
|
private val useProjectImport: Boolean
|
||||||
|
get() = Registry.`is`("kotlin.gradle.scripts.useIdeaProjectImport", false)
|
||||||
|
|
||||||
|
override fun shouldRunInBackground(scriptDefinition: ScriptDefinition): Boolean {
|
||||||
|
return if (useProjectImport) false else super.shouldRunInBackground(scriptDefinition)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun loadDependencies(
|
||||||
|
isFirstLoad: Boolean,
|
||||||
|
virtualFile: VirtualFile,
|
||||||
|
scriptDefinition: ScriptDefinition,
|
||||||
|
context: ScriptConfigurationLoadingContext
|
||||||
|
): Boolean {
|
||||||
|
if (!isGradleKotlinScript(virtualFile)) return false
|
||||||
|
|
||||||
|
if (useProjectImport) {
|
||||||
|
// do nothing, project import notification will be already showed
|
||||||
|
// and configuration for gradle build scripts will be saved at the end of import
|
||||||
|
// todo: use default configuration loader for out-of-project scripts?
|
||||||
|
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
// Gradle read files from FS
|
||||||
|
GlobalScope.launch(EDT(project)) {
|
||||||
|
runWriteAction {
|
||||||
|
FileDocumentManager.getInstance().saveAllDocuments()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.loadDependencies(isFirstLoad, virtualFile, scriptDefinition, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getInputsStamp(virtualFile: VirtualFile, file: KtFile): CachedConfigurationInputs {
|
||||||
|
return getGradleScriptInputsStamp(project, virtualFile, file)
|
||||||
|
?: super.getInputsStamp(virtualFile, file)
|
||||||
|
}
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.script
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.idea.core.script.configuration.listener.DefaultScriptChangeListener
|
||||||
|
import org.jetbrains.kotlin.idea.core.script.configuration.listener.ScriptConfigurationUpdater
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
|
class GradleScriptListener : DefaultScriptChangeListener() {
|
||||||
|
private val listenGradleRelatedFiles = false // todo
|
||||||
|
|
||||||
|
override fun editorActivated(file: KtFile, updater: ScriptConfigurationUpdater): Boolean {
|
||||||
|
if (!isGradleKotlinScript(file.virtualFile)) return false
|
||||||
|
if (listenGradleRelatedFiles) {
|
||||||
|
updater.ensureUpToDatedConfigurationSuggested(file)
|
||||||
|
// todo: force reload if related files changed
|
||||||
|
} else {
|
||||||
|
// configuration will be reloaded after editor activation, even it is already up-to-date
|
||||||
|
// this is required for Gradle scripts, since it's classpath may depend on other files (`.properties` for example)
|
||||||
|
updater.forceConfigurationReload(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.script
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiManager
|
||||||
|
import com.intellij.psi.PsiRecursiveElementVisitor
|
||||||
|
import com.intellij.psi.PsiWhiteSpace
|
||||||
|
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
|
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.psi.KtScriptInitializer
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType
|
||||||
|
|
||||||
|
fun isGradleKotlinScript(virtualFile: VirtualFile) = virtualFile.name.endsWith(".gradle.kts")
|
||||||
|
|
||||||
|
fun getGradleScriptInputsStamp(
|
||||||
|
project: Project,
|
||||||
|
file: VirtualFile,
|
||||||
|
givenKtFile: KtFile? = null
|
||||||
|
): GradleKotlinScriptConfigurationInputs? {
|
||||||
|
if (!isGradleKotlinScript(file)) return null
|
||||||
|
|
||||||
|
return runReadAction {
|
||||||
|
val ktFile = givenKtFile ?: PsiManager.getInstance(project).findFile(file) as? KtFile
|
||||||
|
|
||||||
|
if (ktFile != null) {
|
||||||
|
val result = StringBuilder()
|
||||||
|
ktFile.script?.blockExpression
|
||||||
|
?.getChildrenOfType<KtScriptInitializer>()
|
||||||
|
?.forEach {
|
||||||
|
val call = it.children.singleOrNull() as? KtCallExpression
|
||||||
|
val callRef = call?.firstChild?.text
|
||||||
|
if (callRef == "buildscript" || callRef == "plugins") {
|
||||||
|
result.append(callRef)
|
||||||
|
val lambda = call.lambdaArguments.singleOrNull()
|
||||||
|
lambda?.accept(object : PsiRecursiveElementVisitor(false) {
|
||||||
|
override fun visitElement(element: PsiElement) {
|
||||||
|
super.visitElement(element)
|
||||||
|
when (element) {
|
||||||
|
is PsiWhiteSpace -> if (element.text.contains("\n")) result.append("\n")
|
||||||
|
is LeafPsiElement -> result.append(element.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
result.append("\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GradleKotlinScriptConfigurationInputs(result.toString())
|
||||||
|
} else null
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,11 @@
|
|||||||
<scriptDiagnosticFixProvider implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptDiagnosticFixProvider"/>
|
<scriptDiagnosticFixProvider implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptDiagnosticFixProvider"/>
|
||||||
</extensions>
|
</extensions>
|
||||||
|
|
||||||
|
<extensions defaultExtensionNs="org.jetbrains.kotlin.scripting.idea">
|
||||||
|
<listener implementation="org.jetbrains.kotlin.idea.script.GradleScriptListener"/>
|
||||||
|
<loader implementation="org.jetbrains.kotlin.idea.script.GradleScriptConfigurationLoader"/>
|
||||||
|
</extensions>
|
||||||
|
|
||||||
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
|
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
|
||||||
<orderEnumerationHandlerFactory implementation="org.jetbrains.kotlin.idea.gradle.execution.KotlinGradleOrderEnumerationHandler$Factory" order="first"/>
|
<orderEnumerationHandlerFactory implementation="org.jetbrains.kotlin.idea.gradle.execution.KotlinGradleOrderEnumerationHandler$Factory" order="first"/>
|
||||||
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinMPPGradleProjectResolver"/>
|
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinMPPGradleProjectResolver"/>
|
||||||
|
|||||||
@@ -12,6 +12,11 @@
|
|||||||
<scriptDiagnosticFixProvider implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptDiagnosticFixProvider"/>
|
<scriptDiagnosticFixProvider implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptDiagnosticFixProvider"/>
|
||||||
</extensions>
|
</extensions>
|
||||||
|
|
||||||
|
<extensions defaultExtensionNs="org.jetbrains.kotlin.scripting.idea">
|
||||||
|
<listener implementation="org.jetbrains.kotlin.idea.script.GradleScriptListener"/>
|
||||||
|
<loader implementation="org.jetbrains.kotlin.idea.script.GradleScriptConfigurationLoader"/>
|
||||||
|
</extensions>
|
||||||
|
|
||||||
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
|
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
|
||||||
<orderEnumerationHandlerFactory implementation="org.jetbrains.kotlin.idea.gradle.execution.KotlinGradleOrderEnumerationHandler$Factory" order="first"/>
|
<orderEnumerationHandlerFactory implementation="org.jetbrains.kotlin.idea.gradle.execution.KotlinGradleOrderEnumerationHandler$Factory" order="first"/>
|
||||||
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinMPPGradleProjectResolver"/>
|
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinMPPGradleProjectResolver"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user