diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt index 0122dad5b85..3ff6474e74e 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt @@ -105,6 +105,7 @@ import org.jetbrains.kotlin.parsing.KotlinParserDefinition import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer import org.jetbrains.kotlin.resolve.ModuleAnnotationsResolver +import org.jetbrains.kotlin.resolve.extensions.ExtraImportsProviderExtension import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension @@ -595,6 +596,7 @@ class KotlinCoreEnvironment private constructor( JsSyntheticTranslateExtension.registerExtensionPoint(project) CompilerConfigurationExtension.registerExtensionPoint(project) CollectAdditionalSourcesExtension.registerExtensionPoint(project) + ExtraImportsProviderExtension.registerExtensionPoint(project) IrGenerationExtension.registerExtensionPoint(project) ScriptEvaluationExtension.registerExtensionPoint(project) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/extensions/ExtraImportsProviderExtension.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/extensions/ExtraImportsProviderExtension.kt new file mode 100644 index 00000000000..242019117fd --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/extensions/ExtraImportsProviderExtension.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. 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.resolve.extensions + +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtImportInfo + +interface ExtraImportsProviderExtension { + companion object : ProjectExtensionDescriptor( + "org.jetbrains.kotlin.extraImportsProviderExtension", ExtraImportsProviderExtension::class.java + ) { + + private class CompoundExtraImportsProviderExtension(val instances: List) : ExtraImportsProviderExtension { + override fun getExtraImports(ktFile: KtFile): Collection = instances.flatMap { + withLinkageErrorLogger(it) { getExtraImports(ktFile) } + } + } + + fun getInstance(project: Project): ExtraImportsProviderExtension { + val instances = getInstances(project) + return instances.singleOrNull() ?: CompoundExtraImportsProviderExtension(instances) + } + } + + fun getExtraImports(ktFile: KtFile): Collection +} \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/extensions/SyntheticResolveExtension.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/extensions/SyntheticResolveExtension.kt index 46f232bcaf8..cf81ccb1a4f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/extensions/SyntheticResolveExtension.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/extensions/SyntheticResolveExtension.kt @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.resolve.extensions -import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.project.Project import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor @@ -39,17 +38,6 @@ interface SyntheticResolveExtension { companion object : ProjectExtensionDescriptor( "org.jetbrains.kotlin.syntheticResolveExtension", SyntheticResolveExtension::class.java ) { - private val logger = Logger.getInstance(this::class.java) - - private inline fun withLinkageErrorLogger(receiver: T, block: T.() -> R): R { - try { - return receiver.block() - } catch (e: LinkageError) { - logger.error("${receiver::class.java.name} caused LinkageError", e) - throw e - } - } - fun getInstance(project: Project): SyntheticResolveExtension { val instances = getInstances(project) if (instances.size == 1) return instances.single() diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/extensions/extensionsUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/extensions/extensionsUtil.kt new file mode 100644 index 00000000000..5d177453b09 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/extensions/extensionsUtil.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. 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.resolve.extensions + +import com.intellij.openapi.diagnostic.Logger + +internal inline fun withLinkageErrorLogger(receiver: T, block: T.() -> R): R { + try { + return receiver.block() + } catch (e: LinkageError) { + val logger = Logger.getInstance(receiver::class.java) + logger.error("${receiver::class.java.name} caused LinkageError", e) + throw e + } +} + diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeFactory.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeFactory.kt index 9c10ac9e0aa..42ad0efd9f0 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeFactory.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeFactory.kt @@ -29,9 +29,9 @@ import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.ImportPath import org.jetbrains.kotlin.resolve.TargetPlatform import org.jetbrains.kotlin.resolve.TemporaryBindingTrace +import org.jetbrains.kotlin.resolve.extensions.ExtraImportsProviderExtension import org.jetbrains.kotlin.resolve.scopes.* import org.jetbrains.kotlin.resolve.source.KotlinSourceElement -import org.jetbrains.kotlin.script.ScriptDependenciesProvider import org.jetbrains.kotlin.storage.getValue import org.jetbrains.kotlin.utils.Printer @@ -66,13 +66,13 @@ class FileScopeFactory( } private data class DefaultImportResolvers( - val explicit: LazyImportResolver, - val allUnder: LazyImportResolver, - val lowPriority: LazyImportResolver + val explicit: LazyImportResolver, + val allUnder: LazyImportResolver, + val lowPriority: LazyImportResolver ) private fun createDefaultImportResolvers( - extraImports: Collection, + extraImports: Collection, aliasImportNames: Collection ): DefaultImportResolvers { val tempTrace = TemporaryBindingTrace.create(bindingTrace, "Transient trace for default imports lazy resolve", false) @@ -114,7 +114,7 @@ class FileScopeFactory( } private fun createDefaultImportResolver( - indexedImports: IndexedImports, + indexedImports: IndexedImports, trace: BindingTrace, aliasImportNames: Collection, packageFragment: PackageFragmentDescriptor?, @@ -178,10 +178,7 @@ class FileScopeFactory( val result = FileScopes(lexicalScope, lazyImportingScope, importResolver) private fun createDefaultImportResolversForFile(): DefaultImportResolvers { - val extraImports = file.takeIf { it.isScript() }?.let { ktFile -> - val scriptDependencies = ScriptDependenciesProvider.getInstance(ktFile.project)?.getScriptDependencies(ktFile.originalFile) - scriptDependencies?.imports?.map { DefaultImportImpl(ImportPath.fromString(it)) } - }.orEmpty() + val extraImports = ExtraImportsProviderExtension.getInstance(file.project).getExtraImports(file) if (extraImports.isEmpty() && aliasImportNames.isEmpty()) { return defaultImportResolvers diff --git a/idea/resources/META-INF/extensions/compiler.xml b/idea/resources/META-INF/extensions/compiler.xml index 2fc1b3f6739..7f36a7ec2de 100644 --- a/idea/resources/META-INF/extensions/compiler.xml +++ b/idea/resources/META-INF/extensions/compiler.xml @@ -40,6 +40,9 @@ + + \ No newline at end of file diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptExtraImportsProviderExtension.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptExtraImportsProviderExtension.kt new file mode 100644 index 00000000000..2b10f28b17f --- /dev/null +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptExtraImportsProviderExtension.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. 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.scripting.compiler.plugin + +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtImportInfo +import org.jetbrains.kotlin.resolve.ImportPath +import org.jetbrains.kotlin.resolve.extensions.ExtraImportsProviderExtension +import org.jetbrains.kotlin.script.ScriptDependenciesProvider + +class ScriptExtraImportsProviderExtension : ExtraImportsProviderExtension { + + // initially copied from org.jetbrains.kotlin.resolve.lazy.FileScopeFactory.DefaultImportImpl, but kept separate to simplify dependencies + // and allow easier extension + private class ScriptExtraImportImpl(private val importPath: ImportPath) : KtImportInfo { + override val isAllUnder: Boolean get() = importPath.isAllUnder + + override val importContent = KtImportInfo.ImportContent.FqNameBased(importPath.fqName) + + override val aliasName: String? get() = importPath.alias?.asString() + + override val importedFqName: FqName? get() = importPath.fqName + } + + override fun getExtraImports(ktFile: KtFile): Collection = + ktFile.takeIf { it.isScript() }?.let { file -> + val scriptDependencies = ScriptDependenciesProvider.getInstance(file.project)?.getScriptDependencies(file.originalFile) + scriptDependencies?.imports?.map { ScriptExtraImportImpl(ImportPath.fromString(it)) } + }.orEmpty() +} \ No newline at end of file diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/pluginRegisrar.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/pluginRegisrar.kt index 1162f58b205..68dc4325fd1 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/pluginRegisrar.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/pluginRegisrar.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.extensions.CollectAdditionalSourcesExtension import org.jetbrains.kotlin.extensions.CompilerConfigurationExtension +import org.jetbrains.kotlin.resolve.extensions.ExtraImportsProviderExtension import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension import org.jetbrains.kotlin.script.ScriptDefinitionProvider import org.jetbrains.kotlin.script.ScriptDependenciesProvider @@ -33,6 +34,7 @@ class ScriptingCompilerConfigurationComponentRegistrar : ComponentRegistrar { CliScriptDependenciesProvider(project) ) SyntheticResolveExtension.registerExtension(project, ScriptingResolveExtension()) + ExtraImportsProviderExtension.registerExtension(project, ScriptExtraImportsProviderExtension()) val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) if (messageCollector != null) {