Fix after review, add logging for scripting-specific behavior
This commit is contained in:
+17
-6
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.script
|
package org.jetbrains.kotlin.script
|
||||||
|
|
||||||
import com.intellij.openapi.components.ServiceManager
|
import com.intellij.openapi.components.ServiceManager
|
||||||
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||||
@@ -42,6 +43,7 @@ class KotlinScriptExternalImportsProvider(val project: Project, private val scri
|
|||||||
else scriptDefinitionProvider.findScriptDefinition(file)
|
else scriptDefinitionProvider.findScriptDefinition(file)
|
||||||
?.let { it.getDependenciesFor(file, project, null) }
|
?.let { it.getDependenciesFor(file, project, null) }
|
||||||
.apply {
|
.apply {
|
||||||
|
log.info("[kts] new cached deps for $path: ${this?.classpath?.joinToString(File.pathSeparator)}")
|
||||||
cacheLock.write {
|
cacheLock.write {
|
||||||
if (this == null) {
|
if (this == null) {
|
||||||
cacheOfNulls.add(path)
|
cacheOfNulls.add(path)
|
||||||
@@ -62,6 +64,7 @@ class KotlinScriptExternalImportsProvider(val project: Project, private val scri
|
|||||||
val scriptDef = scriptDefinitionProvider.findScriptDefinition(file)
|
val scriptDef = scriptDefinitionProvider.findScriptDefinition(file)
|
||||||
if (scriptDef != null) {
|
if (scriptDef != null) {
|
||||||
val deps = scriptDef.getDependenciesFor(file, project, null)
|
val deps = scriptDef.getDependenciesFor(file, project, null)
|
||||||
|
log.info("[kts] cached deps for $path: ${deps?.classpath?.joinToString(File.pathSeparator)}")
|
||||||
if (deps != null) {
|
if (deps != null) {
|
||||||
cache.put(path, deps)
|
cache.put(path, deps)
|
||||||
}
|
}
|
||||||
@@ -88,16 +91,21 @@ class KotlinScriptExternalImportsProvider(val project: Project, private val scri
|
|||||||
deps != null && (oldDeps == null ||
|
deps != null && (oldDeps == null ||
|
||||||
!deps.classpath.isSamePathListAs(oldDeps.classpath) || !deps.sources.isSamePathListAs(oldDeps.sources)) -> {
|
!deps.classpath.isSamePathListAs(oldDeps.classpath) || !deps.sources.isSamePathListAs(oldDeps.sources)) -> {
|
||||||
// changed or new
|
// changed or new
|
||||||
|
log.info("[kts] updated/new cached deps for $path: ${deps.classpath.joinToString(File.pathSeparator)}")
|
||||||
cache.put(path, deps)
|
cache.put(path, deps)
|
||||||
cacheOfNulls.remove(path)
|
cacheOfNulls.remove(path)
|
||||||
file
|
file
|
||||||
}
|
}
|
||||||
deps != null -> {
|
deps != null -> {
|
||||||
// same as before
|
// same as before
|
||||||
|
log.info("[kts] unchanged deps for $path")
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
if (cache.remove(path) != null || cacheOfNulls.remove(path)) file // cleared
|
if (cache.remove(path) != null || cacheOfNulls.remove(path)) {
|
||||||
|
log.info("[kts] removed deps for $path")
|
||||||
|
file
|
||||||
|
} // cleared
|
||||||
else null // same as before
|
else null // same as before
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,12 +150,15 @@ class KotlinScriptExternalImportsProvider(val project: Project, private val scri
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getInstance(project: Project): KotlinScriptExternalImportsProvider? =
|
fun getInstance(project: Project): KotlinScriptExternalImportsProvider? =
|
||||||
ServiceManager.getService(project, KotlinScriptExternalImportsProvider::class.java)
|
ServiceManager.getService(project, KotlinScriptExternalImportsProvider::class.java)
|
||||||
|
internal val log = Logger.getInstance(KotlinScriptExternalImportsProvider::class.java)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Iterable<File>.isSamePathListAs(other: Iterable<File>): Boolean {
|
internal fun Iterable<File>.isSamePathListAs(other: Iterable<File>): Boolean =
|
||||||
val c1 = asSequence().map { it.canonicalPath }
|
with (Pair(iterator(), other.iterator())) {
|
||||||
val c2 = other.asSequence().map { it.canonicalPath }
|
while (first.hasNext() && second.hasNext()) {
|
||||||
return c1.zip(c2).all { it.first == it.second }
|
if (first.next().canonicalPath != second.next().canonicalPath) return false
|
||||||
}
|
}
|
||||||
|
!(first.hasNext() || second.hasNext())
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,13 @@ data class KotlinScriptDefinitionFromTemplate(val template: KClass<out Any>,
|
|||||||
when {
|
when {
|
||||||
resolver != null -> ScriptTemplateDefinitionData(resolver.javaClass.kotlin, { resolver }, filePattern)
|
resolver != null -> ScriptTemplateDefinitionData(resolver.javaClass.kotlin, { resolver }, filePattern)
|
||||||
// TODO: logScriptDefMessage missing or invalid constructor
|
// TODO: logScriptDefMessage missing or invalid constructor
|
||||||
defAnn != null -> ScriptTemplateDefinitionData(defAnn.resolver, { defAnn.resolver.primaryConstructor?.call() }, filePattern)
|
defAnn != null -> ScriptTemplateDefinitionData(defAnn.resolver,
|
||||||
|
{
|
||||||
|
defAnn.resolver.primaryConstructor?.call() ?: null.apply {
|
||||||
|
log.error("[kts] No default constructor found for ${defAnn.resolver.qualifiedName}")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
filePattern)
|
||||||
else -> ScriptTemplateDefinitionData(BasicScriptDependenciesResolver::class, ::BasicScriptDependenciesResolver, filePattern)
|
else -> ScriptTemplateDefinitionData(BasicScriptDependenciesResolver::class, ::BasicScriptDependenciesResolver, filePattern)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,7 +99,6 @@ data class KotlinScriptDefinitionFromTemplate(val template: KClass<out Any>,
|
|||||||
// TODO: implement other strategy - e.g. try to extract something from match with ScriptFilePattern
|
// TODO: implement other strategy - e.g. try to extract something from match with ScriptFilePattern
|
||||||
override fun getScriptName(script: KtScript): Name = ScriptNameUtil.fileNameWithExtensionStripped(script, KotlinParserDefinition.STD_SCRIPT_EXT)
|
override fun getScriptName(script: KtScript): Name = ScriptNameUtil.fileNameWithExtensionStripped(script, KotlinParserDefinition.STD_SCRIPT_EXT)
|
||||||
|
|
||||||
|
|
||||||
override fun <TF> getDependenciesFor(file: TF, project: Project, previousDependencies: KotlinScriptExternalDependencies?): KotlinScriptExternalDependencies? {
|
override fun <TF> getDependenciesFor(file: TF, project: Project, previousDependencies: KotlinScriptExternalDependencies?): KotlinScriptExternalDependencies? {
|
||||||
|
|
||||||
val script = BasicScriptContents(file, getAnnotations = {
|
val script = BasicScriptContents(file, getAnnotations = {
|
||||||
|
|||||||
+5
-1
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.script
|
package org.jetbrains.kotlin.script
|
||||||
|
|
||||||
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
import com.intellij.openapi.extensions.ExtensionPointName
|
import com.intellij.openapi.extensions.ExtensionPointName
|
||||||
import com.intellij.openapi.extensions.Extensions
|
import com.intellij.openapi.extensions.Extensions
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
@@ -46,7 +47,8 @@ interface ScriptTemplateProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun makeScriptDefsFromTemplateProviderExtensions(project: Project,
|
fun makeScriptDefsFromTemplateProviderExtensions(project: Project,
|
||||||
errorsHandler: ((ScriptTemplateProvider, Exception) -> Unit) = { ep, ex -> throw ex }): List<KotlinScriptDefinitionFromTemplate> =
|
errorsHandler: ((ScriptTemplateProvider, Exception) -> Unit) = { ep, ex -> throw ex }
|
||||||
|
): List<KotlinScriptDefinitionFromTemplate> =
|
||||||
makeScriptDefsFromTemplateProviders(Extensions.getArea(project).getExtensionPoint(ScriptTemplateProvider.EP_NAME).extensions.asIterable(),
|
makeScriptDefsFromTemplateProviders(Extensions.getArea(project).getExtensionPoint(ScriptTemplateProvider.EP_NAME).extensions.asIterable(),
|
||||||
errorsHandler)
|
errorsHandler)
|
||||||
|
|
||||||
@@ -57,6 +59,8 @@ fun makeScriptDefsFromTemplateProviders(providers: Iterable<ScriptTemplateProvid
|
|||||||
return providers.filter { it.isValid }.sortedByDescending { it.version }.mapNotNull { provider ->
|
return providers.filter { it.isValid }.sortedByDescending { it.version }.mapNotNull { provider ->
|
||||||
try {
|
try {
|
||||||
idToVersion.get(provider.id)?.let { ver -> errorsHandler(provider, RuntimeException("Conflicting scriptTemplateProvider ${provider.id}, using one with version $ver")) }
|
idToVersion.get(provider.id)?.let { ver -> errorsHandler(provider, RuntimeException("Conflicting scriptTemplateProvider ${provider.id}, using one with version $ver")) }
|
||||||
|
Logger.getInstance("makeScriptDefsFromTemplateProviders")
|
||||||
|
.info("[kts] loading script definition ${provider.templateClassName} using cp: ${provider.dependenciesClasspath.joinToString(File.pathSeparator)}")
|
||||||
val loader = URLClassLoader(provider.dependenciesClasspath.map { File(it).toURI().toURL() }.toTypedArray(), ScriptTemplateProvider::class.java.classLoader)
|
val loader = URLClassLoader(provider.dependenciesClasspath.map { File(it).toURI().toURL() }.toTypedArray(), ScriptTemplateProvider::class.java.classLoader)
|
||||||
val cl = loader.loadClass(provider.templateClassName)
|
val cl = loader.loadClass(provider.templateClassName)
|
||||||
idToVersion.put(provider.id, provider.version)
|
idToVersion.put(provider.id, provider.version)
|
||||||
|
|||||||
+3
-1
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.core.script
|
|||||||
|
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
import com.intellij.openapi.components.ServiceManager
|
import com.intellij.openapi.components.ServiceManager
|
||||||
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.roots.ex.ProjectRootManagerEx
|
import com.intellij.openapi.roots.ex.ProjectRootManagerEx
|
||||||
import com.intellij.openapi.startup.StartupManager
|
import com.intellij.openapi.startup.StartupManager
|
||||||
@@ -99,7 +100,7 @@ class KotlinScriptConfigurationManager(
|
|||||||
fun getAllLibrarySourcesScope() = NonClasspathDirectoriesScope(getAllLibrarySources())
|
fun getAllLibrarySourcesScope() = NonClasspathDirectoriesScope(getAllLibrarySources())
|
||||||
|
|
||||||
private fun reloadScriptDefinitions() {
|
private fun reloadScriptDefinitions() {
|
||||||
(makeScriptDefsFromTemplateProviderExtensions(project, { ep, ex -> /* TODO: add logging here */ }) +
|
(makeScriptDefsFromTemplateProviderExtensions(project, { ep, ex -> log.error("[kts] Error loading definition from ${ep.id}", ex) }) +
|
||||||
loadScriptConfigsFromProjectRoot(File(project.basePath ?: "")).map { KotlinConfigurableScriptDefinition(it, kotlinEnvVars) }).let {
|
loadScriptConfigsFromProjectRoot(File(project.basePath ?: "")).map { KotlinConfigurableScriptDefinition(it, kotlinEnvVars) }).let {
|
||||||
if (it.isNotEmpty()) {
|
if (it.isNotEmpty()) {
|
||||||
scriptDefinitionProvider.setScriptDefinitions(it + StandardScriptDefinition)
|
scriptDefinitionProvider.setScriptDefinitions(it + StandardScriptDefinition)
|
||||||
@@ -150,6 +151,7 @@ class KotlinScriptConfigurationManager(
|
|||||||
// TODO: report this somewhere, but do not throw: assert(res != null, { "Invalid classpath entry '$this': exists: ${exists()}, is directory: $isDirectory, is file: $isFile" })
|
// TODO: report this somewhere, but do not throw: assert(res != null, { "Invalid classpath entry '$this': exists: ${exists()}, is directory: $isDirectory, is file: $isFile" })
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
internal val log = Logger.getInstance(KotlinScriptConfigurationManager::class.java)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.idea.core.script
|
package org.jetbrains.kotlin.idea.core.script
|
||||||
|
|
||||||
import com.intellij.execution.configurations.CommandLineTokenizer
|
import com.intellij.execution.configurations.CommandLineTokenizer
|
||||||
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import org.gradle.tooling.ProjectConnection
|
import org.gradle.tooling.ProjectConnection
|
||||||
@@ -38,10 +39,12 @@ class GradleScriptTemplateProvider(project: Project): ScriptTemplateProvider {
|
|||||||
org.jetbrains.plugins.gradle.util.GradleConstants.SYSTEM_ID)
|
org.jetbrains.plugins.gradle.util.GradleConstants.SYSTEM_ID)
|
||||||
}
|
}
|
||||||
catch (e: NoClassDefFoundError) {
|
catch (e: NoClassDefFoundError) {
|
||||||
// TODO: log warning and consider displaying it to user
|
// TODO: consider displaying the warning to the user
|
||||||
|
Logger.getInstance(GradleScriptTemplateProvider::class.java).error("[kts] Cannot get gradle execution settings", e)
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
catch (e: ClassNotFoundException) {
|
catch (e: ClassNotFoundException) {
|
||||||
|
Logger.getInstance(GradleScriptTemplateProvider::class.java).error("[kts] Cannot get gradle execution settings", e)
|
||||||
null // see todo above
|
null // see todo above
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user