Make sure template classpath is always among script dependencies
This commit is contained in:
+3
-1
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.NameUtils
|
||||
import org.jetbrains.kotlin.psi.KtScript
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import java.io.File
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KFunction
|
||||
import kotlin.reflect.KParameter
|
||||
@@ -36,7 +37,8 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
|
||||
template: KClass<out Any>,
|
||||
providedResolver: DependenciesResolver? = null,
|
||||
providedScriptFilePattern: String? = null,
|
||||
val environment: Map<String, Any?>? = null
|
||||
val environment: Map<String, Any?>? = null,
|
||||
val templateClasspath: List<File> = emptyList()
|
||||
) : KotlinScriptDefinition(template) {
|
||||
|
||||
val scriptFilePattern by lazy {
|
||||
|
||||
@@ -67,10 +67,18 @@ class ScriptContentLoader(private val project: Project) {
|
||||
getEnvironment(scriptDef)
|
||||
)
|
||||
ServiceManager.getService(project, ScriptReportSink::class.java)?.attachReports(file, result.reports)
|
||||
return result.dependencies
|
||||
return result.dependencies?.adjustByDefinition(scriptDef)
|
||||
}
|
||||
|
||||
fun getEnvironment(scriptDef: KotlinScriptDefinition) =
|
||||
(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)
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -72,7 +72,10 @@ fun makeScriptDefsFromTemplatesProviders(providers: Iterable<ScriptTemplatesProv
|
||||
try {
|
||||
val loader = createClassLoader(provider)
|
||||
provider.templateClassNames.map {
|
||||
KotlinScriptDefinitionFromAnnotatedTemplate(loader.loadClass(it).kotlin, provider.resolver, provider.filePattern, provider.environment)
|
||||
KotlinScriptDefinitionFromAnnotatedTemplate(
|
||||
loader.loadClass(it).kotlin, provider.resolver,
|
||||
provider.filePattern, provider.environment, provider.templateClasspath
|
||||
)
|
||||
}
|
||||
}
|
||||
catch (ex: Throwable) {
|
||||
|
||||
+15
-15
@@ -139,11 +139,23 @@ internal class ScriptDependenciesUpdater(
|
||||
scriptDef: KotlinScriptDefinition
|
||||
): TimeStampedJob {
|
||||
val currentTimeStamp = TimeStamps.next()
|
||||
|
||||
fun process(result: DependenciesResolver.ResolveResult) {
|
||||
val lastTimeStamp = requests[file.path]?.job?.timeStamp
|
||||
val isLastSentRequest = lastTimeStamp == null || lastTimeStamp == currentTimeStamp
|
||||
if (isLastSentRequest) {
|
||||
ServiceManager.getService(project, ScriptReportSink::class.java)?.attachReports(file, result.reports)
|
||||
val resultingDependencies = (result.dependencies ?: ScriptDependencies.Empty).adjustByDefinition(scriptDef)
|
||||
if (cache(resultingDependencies, file)) {
|
||||
onChange()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val dependenciesResolver = scriptDef.dependencyResolver
|
||||
val newJob = if (dependenciesResolver is AsyncDependenciesResolver) {
|
||||
launch(asyncUpdatesDispatcher) {
|
||||
processResult(
|
||||
file, currentTimeStamp,
|
||||
process(
|
||||
dependenciesResolver.resolveAsync(
|
||||
contentLoader.getScriptContents(scriptDef, file),
|
||||
contentLoader.getEnvironment(scriptDef)
|
||||
@@ -154,8 +166,7 @@ internal class ScriptDependenciesUpdater(
|
||||
else {
|
||||
assert(dependenciesResolver is LegacyResolverWrapper)
|
||||
launch(legacyUpdatesDispatcher) {
|
||||
processResult(
|
||||
file, currentTimeStamp,
|
||||
process(
|
||||
dependenciesResolver.resolve(
|
||||
contentLoader.getScriptContents(scriptDef, file),
|
||||
contentLoader.getEnvironment(scriptDef)
|
||||
@@ -166,17 +177,6 @@ internal class ScriptDependenciesUpdater(
|
||||
return TimeStampedJob(newJob, currentTimeStamp)
|
||||
}
|
||||
|
||||
private fun processResult(file: VirtualFile, currentTimeStamp: TimeStamp, result: DependenciesResolver.ResolveResult) {
|
||||
val lastTimeStamp = requests[file.path]?.job?.timeStamp
|
||||
val isLastSentRequest = lastTimeStamp == null || lastTimeStamp == currentTimeStamp
|
||||
if (isLastSentRequest) {
|
||||
ServiceManager.getService(project, ScriptReportSink::class.java)?.attachReports(file, result.reports)
|
||||
if (cache(result.dependencies ?: ScriptDependencies.Empty, file)) {
|
||||
onChange()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateSync(file: VirtualFile, scriptDef: KotlinScriptDefinition): Boolean {
|
||||
val newDeps = contentLoader.loadContentsAndResolveDependencies(scriptDef, file) ?: ScriptDependencies.Empty
|
||||
return cache(newDeps, file)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
val j: Int = i
|
||||
|
||||
val s: String = str
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package custom.scriptDefinition
|
||||
|
||||
import java.io.File
|
||||
import kotlin.script.dependencies.*
|
||||
import kotlin.script.dependencies.experimental.*
|
||||
import kotlin.script.templates.ScriptTemplateDefinition
|
||||
|
||||
class TestDependenciesResolver : AsyncDependenciesResolver {
|
||||
override suspend fun resolveAsync(
|
||||
scriptContents: ScriptContents,
|
||||
environment: Environment
|
||||
): DependenciesResolver.ResolveResult {
|
||||
return ScriptDependencies.Empty.asSuccess()
|
||||
}
|
||||
}
|
||||
|
||||
@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts")
|
||||
open class Template: Base()
|
||||
|
||||
open class Base {
|
||||
val i = 3
|
||||
val str = ""
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
val j: Int = i
|
||||
|
||||
val s: String = str
|
||||
@@ -0,0 +1,13 @@
|
||||
package custom.scriptDefinition
|
||||
|
||||
import java.io.File
|
||||
import kotlin.script.dependencies.*
|
||||
import kotlin.script.templates.ScriptTemplateDefinition
|
||||
|
||||
@ScriptTemplateDefinition(scriptFilePattern = "script.kts")
|
||||
class Template: Base()
|
||||
|
||||
open class Base {
|
||||
val i = 3
|
||||
val str = ""
|
||||
}
|
||||
+12
@@ -78,6 +78,18 @@ public class ScriptConfigurationHighlightingTestGenerated extends AbstractScript
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("emptyAsyncResolver")
|
||||
public void testEmptyAsyncResolver() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/script/definition/highlighting/emptyAsyncResolver/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("noResolver")
|
||||
public void testNoResolver() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/script/definition/highlighting/noResolver/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("simple")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/script/definition/highlighting/simple/");
|
||||
|
||||
Reference in New Issue
Block a user