diff --git a/compiler/frontend/src/org/jetbrains/kotlin/script/KotlinScriptExternalImportsProvider.kt b/compiler/frontend/src/org/jetbrains/kotlin/script/KotlinScriptExternalImportsProvider.kt index 61477f2c20c..d21946a1f35 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/script/KotlinScriptExternalImportsProvider.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/script/KotlinScriptExternalImportsProvider.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.script import com.intellij.openapi.components.ServiceManager +import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.project.Project import java.io.File import java.util.concurrent.locks.ReentrantReadWriteLock @@ -42,6 +43,7 @@ class KotlinScriptExternalImportsProvider(val project: Project, private val scri else scriptDefinitionProvider.findScriptDefinition(file) ?.let { it.getDependenciesFor(file, project, null) } .apply { + log.info("[kts] new cached deps for $path: ${this?.classpath?.joinToString(File.pathSeparator)}") cacheLock.write { if (this == null) { cacheOfNulls.add(path) @@ -62,6 +64,7 @@ class KotlinScriptExternalImportsProvider(val project: Project, private val scri val scriptDef = scriptDefinitionProvider.findScriptDefinition(file) if (scriptDef != null) { val deps = scriptDef.getDependenciesFor(file, project, null) + log.info("[kts] cached deps for $path: ${deps?.classpath?.joinToString(File.pathSeparator)}") if (deps != null) { cache.put(path, deps) } @@ -88,16 +91,21 @@ class KotlinScriptExternalImportsProvider(val project: Project, private val scri deps != null && (oldDeps == null || !deps.classpath.isSamePathListAs(oldDeps.classpath) || !deps.sources.isSamePathListAs(oldDeps.sources)) -> { // changed or new + log.info("[kts] updated/new cached deps for $path: ${deps.classpath.joinToString(File.pathSeparator)}") cache.put(path, deps) cacheOfNulls.remove(path) file } deps != null -> { // same as before + log.info("[kts] unchanged deps for $path") null } 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 } } @@ -142,12 +150,15 @@ class KotlinScriptExternalImportsProvider(val project: Project, private val scri @JvmStatic fun getInstance(project: Project): KotlinScriptExternalImportsProvider? = ServiceManager.getService(project, KotlinScriptExternalImportsProvider::class.java) + internal val log = Logger.getInstance(KotlinScriptExternalImportsProvider::class.java) } } -internal fun Iterable.isSamePathListAs(other: Iterable): Boolean { - val c1 = asSequence().map { it.canonicalPath } - val c2 = other.asSequence().map { it.canonicalPath } - return c1.zip(c2).all { it.first == it.second } -} +internal fun Iterable.isSamePathListAs(other: Iterable): Boolean = + with (Pair(iterator(), other.iterator())) { + while (first.hasNext() && second.hasNext()) { + if (first.next().canonicalPath != second.next().canonicalPath) return false + } + !(first.hasNext() || second.hasNext()) + } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/script/scriptDefinitionFromTemplate.kt b/compiler/frontend/src/org/jetbrains/kotlin/script/scriptDefinitionFromTemplate.kt index 1db915b5f5c..906d81b3ca3 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/script/scriptDefinitionFromTemplate.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/script/scriptDefinitionFromTemplate.kt @@ -71,7 +71,13 @@ data class KotlinScriptDefinitionFromTemplate(val template: KClass, when { resolver != null -> ScriptTemplateDefinitionData(resolver.javaClass.kotlin, { resolver }, filePattern) // 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) } } @@ -93,7 +99,6 @@ data class KotlinScriptDefinitionFromTemplate(val template: KClass, // 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 getDependenciesFor(file: TF, project: Project, previousDependencies: KotlinScriptExternalDependencies?): KotlinScriptExternalDependencies? { val script = BasicScriptContents(file, getAnnotations = { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/script/scriptTemplateProviderExtensionPoint.kt b/compiler/frontend/src/org/jetbrains/kotlin/script/scriptTemplateProviderExtensionPoint.kt index 524b6db3d33..a1a734e2eae 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/script/scriptTemplateProviderExtensionPoint.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/script/scriptTemplateProviderExtensionPoint.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.script +import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.extensions.ExtensionPointName import com.intellij.openapi.extensions.Extensions import com.intellij.openapi.project.Project @@ -46,7 +47,8 @@ interface ScriptTemplateProvider { } fun makeScriptDefsFromTemplateProviderExtensions(project: Project, - errorsHandler: ((ScriptTemplateProvider, Exception) -> Unit) = { ep, ex -> throw ex }): List = + errorsHandler: ((ScriptTemplateProvider, Exception) -> Unit) = { ep, ex -> throw ex } +): List = makeScriptDefsFromTemplateProviders(Extensions.getArea(project).getExtensionPoint(ScriptTemplateProvider.EP_NAME).extensions.asIterable(), errorsHandler) @@ -57,6 +59,8 @@ fun makeScriptDefsFromTemplateProviders(providers: Iterable try { 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 cl = loader.loadClass(provider.templateClassName) idToVersion.put(provider.id, provider.version) diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/KotlinScriptConfigurationManager.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/KotlinScriptConfigurationManager.kt index e63f76b5a3c..360670e945f 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/KotlinScriptConfigurationManager.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/KotlinScriptConfigurationManager.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.core.script import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.ServiceManager +import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ex.ProjectRootManagerEx import com.intellij.openapi.startup.StartupManager @@ -99,7 +100,7 @@ class KotlinScriptConfigurationManager( fun getAllLibrarySourcesScope() = NonClasspathDirectoriesScope(getAllLibrarySources()) 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 { if (it.isNotEmpty()) { 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" }) return res } + internal val log = Logger.getInstance(KotlinScriptConfigurationManager::class.java) } } diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/gradleScriptTemplateProvider.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/gradleScriptTemplateProvider.kt index 483157b4a3f..2a0a9b978e6 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/gradleScriptTemplateProvider.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/gradleScriptTemplateProvider.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.idea.core.script import com.intellij.execution.configurations.CommandLineTokenizer +import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil import com.intellij.openapi.project.Project import org.gradle.tooling.ProjectConnection @@ -38,10 +39,12 @@ class GradleScriptTemplateProvider(project: Project): ScriptTemplateProvider { org.jetbrains.plugins.gradle.util.GradleConstants.SYSTEM_ID) } 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 } catch (e: ClassNotFoundException) { + Logger.getInstance(GradleScriptTemplateProvider::class.java).error("[kts] Cannot get gradle execution settings", e) null // see todo above } }