Add script configuration dependencies to script classpath

It was missing during configuration refinement thought new scripting API and during loading script configuration on Gradle project import

Do not pass additional classpath to configuration classpath: this may only affects Gradle with New scripting API (because it isn't used from other places)
In additional classpath kotlin-compiler and kotlin-stdlib was passed and there is no needs for this during loading Script Definitions through new scripting API

^KT-34626 Fixed
This commit is contained in:
Natalia Selezneva
2019-11-14 13:33:32 +03:00
parent 29ef10a919
commit ca71b2fe90
6 changed files with 58 additions and 53 deletions

View File

@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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
@@ -235,7 +224,7 @@ fun loadDefinitionsFromTemplates(
// as a compatibility measure, the asm based reading of annotations should be implemented to filter classes before classloading
val template = loader.loadClass(templateClassName).kotlin
val hostConfiguration = ScriptingHostConfiguration(baseHostConfiguration) {
configurationDependencies(JvmDependency(classpath))
configurationDependencies(JvmDependency(templateClasspath))
}
when {
template.annotations.firstIsInstanceOrNull<kotlin.script.templates.ScriptTemplateDefinition>() != null -> {

View File

@@ -29,12 +29,16 @@ import org.jetbrains.kotlin.idea.core.script.configuration.getGradleScriptInputs
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper
import org.jetbrains.kotlin.scripting.resolve.VirtualFileScriptSource
import org.jetbrains.kotlin.scripting.resolve.adjustByDefinition
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings
import org.jetbrains.plugins.gradle.util.GradleConstants
import java.io.File
import kotlin.script.experimental.dependencies.ScriptDependencies
import kotlin.script.experimental.api.*
import kotlin.script.experimental.jvm.JvmDependency
import kotlin.script.experimental.jvm.jdkHome
import kotlin.script.experimental.jvm.jvm
class KotlinGradleBuildScriptsDataService : AbstractProjectDataService<GradleSourceSetData, Void>() {
override fun getTargetDataKey(): Key<GradleSourceSetData> = GradleSourceSetData.KEY
@@ -67,21 +71,25 @@ class KotlinGradleBuildScriptsDataService : AbstractProjectDataService<GradleSou
// todo(KT-34440): take inputs snapshot before starting import
val inputs = getGradleScriptInputsStamp(project, virtualFile)
val definition = virtualFile.findScriptDefinition(project) ?: return@forEach
val configuration =
definition.compilationConfiguration.with {
jvm.jdkHome(javaHome)
defaultImports(buildScript.imports)
dependencies(JvmDependency(buildScript.classPath.map { File(it) }))
ide.dependenciesSources(JvmDependency(buildScript.sourcePath.map { File(it) }))
}.adjustByDefinition(definition)
files.add(
Pair(
virtualFile,
ScriptConfigurationSnapshot(
inputs ?: CachedConfigurationInputs.OutOfDate,
listOf(),
ScriptCompilationConfigurationWrapper.FromLegacy(
ScriptCompilationConfigurationWrapper.FromCompilationConfiguration(
VirtualFileScriptSource(virtualFile),
ScriptDependencies(
javaHome = javaHome,
classpath = buildScript.classPath.map { File(it) },
sources = buildScript.sourcePath.map { File(it) },
imports = buildScript.imports
),
virtualFile.findScriptDefinition(project)
configuration
)
)
)

View File

@@ -23,9 +23,6 @@ val ScriptingHostConfigurationKeys.getEnvironment by PropertiesCollection.key<()
@Suppress("UNCHECKED_CAST")
object TemplateDefinition : ScriptCompilationConfiguration(
{
jvm {
dependenciesFromClassContext(TemplateDefinition::class)
}
ide {
acceptedLocations(ScriptAcceptedLocation.Everywhere)
}

View File

@@ -1,23 +1,24 @@
package custom.scriptDefinition
import java.io.File
import kotlin.script.dependencies.*
import kotlin.script.experimental.dependencies.*
import kotlin.script.templates.ScriptTemplateDefinition
import kotlin.script.experimental.location.*
import kotlin.script.experimental.annotations.KotlinScript
import kotlin.script.experimental.api.*
class TestDependenciesResolver : AsyncDependenciesResolver {
override suspend fun resolveAsync(
scriptContents: ScriptContents,
environment: Environment
): DependenciesResolver.ResolveResult {
return ScriptDependencies.Empty.asSuccess()
@KotlinScript(
displayName = "Definition for tests",
fileExtension = "kts",
compilationConfiguration = TemplateDefinition::class
)
open class Template(val args: Array<String>)
@Suppress("UNCHECKED_CAST")
object TemplateDefinition : ScriptCompilationConfiguration(
{
baseClass(Base::class)
ide {
acceptedLocations(ScriptAcceptedLocation.Everywhere)
}
}
}
@ScriptExpectedLocations([ScriptExpectedLocation.Everywhere])
@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts")
open class Template: Base()
)
open class Base {
val i = 3

View File

@@ -12,7 +12,6 @@ import java.io.File
import kotlin.script.dependencies.ScriptContents
import kotlin.script.experimental.dependencies.DependenciesResolver
import kotlin.script.experimental.dependencies.DependenciesResolver.ResolveResult.Failure
import kotlin.script.experimental.dependencies.ScriptDependencies
import kotlin.script.experimental.dependencies.ScriptReport
class ScriptContentLoader(private val project: Project) {
@@ -54,14 +53,6 @@ class ScriptContentLoader(private val project: Project) {
(scriptDef as? KotlinScriptDefinitionFromAnnotatedTemplate)?.environment.orEmpty()
}
fun ScriptDependencies.adjustByDefinition(
scriptDef: KotlinScriptDefinition
): ScriptDependencies {
val additionalClasspath = (scriptDef as? KotlinScriptDefinitionFromAnnotatedTemplate)?.templateClasspath ?: return this
if (additionalClasspath.isEmpty()) return this
return copy(classpath = additionalClasspath + classpath)
}
fun Throwable.asResolveFailure(scriptDef: KotlinScriptDefinition): Failure {
val prefix = "${scriptDef.dependencyResolver::class.simpleName} threw exception ${this::class.simpleName}:\n "
return Failure(ScriptReport(prefix + (message ?: "<no message>"), ScriptReport.Severity.FATAL))

View File

@@ -229,7 +229,10 @@ fun refineScriptCompilationConfiguration(
.onSuccess {
it.refineBeforeCompiling(script, collectedData)
}.onSuccess {
ScriptCompilationConfigurationWrapper.FromCompilationConfiguration(ktFileSource, it).asSuccess()
ScriptCompilationConfigurationWrapper.FromCompilationConfiguration(
ktFileSource,
it.adjustByDefinition(definition)
).asSuccess()
}
} else {
val file = script.getVirtualFile(definition)
@@ -260,12 +263,28 @@ fun refineScriptCompilationConfiguration(
else
ScriptCompilationConfigurationWrapper.FromLegacy(
ktFileSource,
result.dependencies?.adjustByDefinition(definition.legacyDefinition),
result.dependencies?.adjustByDefinition(definition),
definition
).asSuccess(result.reports.mapToDiagnostics())
}
}
fun ScriptDependencies.adjustByDefinition(definition: ScriptDefinition): ScriptDependencies {
val additionalClasspath = additionalClasspath(definition)
if (additionalClasspath.isEmpty()) return this
return copy(classpath = additionalClasspath + classpath)
}
fun ScriptCompilationConfiguration.adjustByDefinition(definition: ScriptDefinition): ScriptCompilationConfiguration {
return this.withUpdatedClasspath(additionalClasspath(definition))
}
private fun additionalClasspath(definition: ScriptDefinition): List<File> {
return (definition.asLegacyOrNull<KotlinScriptDefinitionFromAnnotatedTemplate>()?.templateClasspath
?: definition.hostConfiguration[ScriptingHostConfiguration.configurationDependencies].toClassPathOrEmpty())
}
internal fun makeScriptContents(
file: VirtualFile,
legacyDefinition: KotlinScriptDefinition,