Extract extra imports provision into an extension, implement one ...

for script in the plugin, drop direct dependency on scripts from
FileScopeFactory
This commit is contained in:
Ilya Chernikov
2019-02-20 11:11:50 +01:00
parent 57ac149f5b
commit e99715cf82
9 changed files with 99 additions and 22 deletions
@@ -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)
}
@@ -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<ExtraImportsProviderExtension>(
"org.jetbrains.kotlin.extraImportsProviderExtension", ExtraImportsProviderExtension::class.java
) {
private class CompoundExtraImportsProviderExtension(val instances: List<ExtraImportsProviderExtension>) : ExtraImportsProviderExtension {
override fun getExtraImports(ktFile: KtFile): Collection<KtImportInfo> = 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<KtImportInfo>
}
@@ -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<SyntheticResolveExtension>(
"org.jetbrains.kotlin.syntheticResolveExtension", SyntheticResolveExtension::class.java
) {
private val logger = Logger.getInstance(this::class.java)
private inline fun <T : Any, R> 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()
@@ -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 <T : Any, R> 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
}
}
@@ -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<DefaultImportImpl>,
val allUnder: LazyImportResolver<DefaultImportImpl>,
val lowPriority: LazyImportResolver<DefaultImportImpl>
val explicit: LazyImportResolver<KtImportInfo>,
val allUnder: LazyImportResolver<KtImportInfo>,
val lowPriority: LazyImportResolver<KtImportInfo>
)
private fun createDefaultImportResolvers(
extraImports: Collection<DefaultImportImpl>,
extraImports: Collection<KtImportInfo>,
aliasImportNames: Collection<FqName>
): 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<DefaultImportImpl>,
indexedImports: IndexedImports<KtImportInfo>,
trace: BindingTrace,
aliasImportNames: Collection<FqName>,
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
@@ -40,6 +40,9 @@
<extensionPoint qualifiedName="org.jetbrains.kotlin.scriptTemplatesProvider"
interface="org.jetbrains.kotlin.script.ScriptTemplatesProvider"
area="IDEA_PROJECT"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.extraImportsProviderExtension"
interface="org.jetbrains.kotlin.resolve.extensions.ExtraImportsProviderExtension"
area="IDEA_PROJECT"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.facetConfigurationExtension"
interface="org.jetbrains.kotlin.idea.facet.KotlinFacetConfigurationExtension"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.versionInfoProvider"
@@ -30,5 +30,6 @@
<idePlatformKindTooling implementation="org.jetbrains.kotlin.idea.core.platform.impl.CommonIdePlatformKindTooling"/>
<syntheticResolveExtension implementation="org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingResolveExtension"/>
<extraImportsProviderExtension implementation="org.jetbrains.kotlin.scripting.compiler.plugin.ScriptExtraImportsProviderExtension"/>
</extensions>
</idea-plugin>
@@ -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<KtImportInfo> =
ktFile.takeIf { it.isScript() }?.let { file ->
val scriptDependencies = ScriptDependenciesProvider.getInstance(file.project)?.getScriptDependencies(file.originalFile)
scriptDependencies?.imports?.map { ScriptExtraImportImpl(ImportPath.fromString(it)) }
}.orEmpty()
}
@@ -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) {