[ULC] Add LanguageVersionSettings to CliLightClassGenerationSupport

+ refactoring
This commit is contained in:
Igor Yakovlev
2020-07-30 17:24:05 +03:00
parent 31b4a021a9
commit 4b8f1bb362
12 changed files with 113 additions and 182 deletions
@@ -24,10 +24,7 @@ import org.jetbrains.kotlin.cli.common.messages.MessageUtil
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser
import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider
@@ -16,8 +16,7 @@
package org.jetbrains.kotlin.cli.jvm.compiler package org.jetbrains.kotlin.cli.jvm.compiler
import com.intellij.psi.PsiManager import com.intellij.openapi.project.Project
import com.intellij.psi.util.CachedValue
import org.jetbrains.kotlin.asJava.LightClassBuilder import org.jetbrains.kotlin.asJava.LightClassBuilder
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.builder.InvalidLightClassDataHolder import org.jetbrains.kotlin.asJava.builder.InvalidLightClassDataHolder
@@ -28,14 +27,9 @@ import org.jetbrains.kotlin.asJava.classes.*
import org.jetbrains.kotlin.codegen.ClassBuilderMode import org.jetbrains.kotlin.codegen.ClassBuilderMode
import org.jetbrains.kotlin.codegen.JvmCodegenUtil import org.jetbrains.kotlin.codegen.JvmCodegenUtil
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.JvmTarget import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.load.java.components.JavaDeprecationSettings import org.jetbrains.kotlin.load.java.components.JavaDeprecationSettings
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
@@ -43,7 +37,6 @@ import org.jetbrains.kotlin.resolve.deprecation.CoroutineCompatibilitySupport
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator as ResolveEvaluator
/** /**
* This class solves the problem of interdependency between analyzing Kotlin code and generating JetLightClasses * This class solves the problem of interdependency between analyzing Kotlin code and generating JetLightClasses
@@ -57,23 +50,25 @@ import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluat
* To mitigate this, CliLightClassGenerationSupport hold a trace that is shared between the analyzer and JetLightClasses * To mitigate this, CliLightClassGenerationSupport hold a trace that is shared between the analyzer and JetLightClasses
*/ */
class CliLightClassGenerationSupport(private val traceHolder: CliTraceHolder) : LightClassGenerationSupport() { class CliLightClassGenerationSupport(
val traceHolder: CliTraceHolder,
private val project: Project
) : LightClassGenerationSupport() {
private val ultraLightSupport = object : KtUltraLightSupport { private class CliLightClassSupport(
private val project: Project,
override val languageVersionSettings: LanguageVersionSettings
) : KtUltraLightSupport {
//TODO: languageVersionSettings is always default // This is the way to untie CliLightClassSupport and CliLightClassGenerationSupport to prevent descriptors leak
private val languageVersionSettings: LanguageVersionSettings private val traceHolder: CliTraceHolder
get() = getContext().languageVersionSettings get() = (getInstance(project) as CliLightClassGenerationSupport).traceHolder
?: LanguageVersionSettingsImpl.DEFAULT
override val isReleasedCoroutine override val isReleasedCoroutine
get() = languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines) get() = languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)
override fun possiblyHasAlias(file: KtFile, shortName: Name): Boolean = true override fun possiblyHasAlias(file: KtFile, shortName: Name): Boolean = true
override fun getConstantEvaluator(expression: KtExpression): org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator =
ResolveEvaluator(moduleDescriptor, languageVersionSettings, expression.project)
override val moduleDescriptor get() = traceHolder.module override val moduleDescriptor get() = traceHolder.module
override val moduleName: String get() = JvmCodegenUtil.getModuleName(moduleDescriptor) override val moduleName: String get() = JvmCodegenUtil.getModuleName(moduleDescriptor)
@@ -99,53 +94,15 @@ class CliLightClassGenerationSupport(private val traceHolder: CliTraceHolder) :
} }
} }
override fun createUltraLightClassForFacade( private val ultraLightSupport: KtUltraLightSupport by lazyPub {
manager: PsiManager, CliLightClassSupport(project, traceHolder.languageVersionSettings)
facadeClassFqName: FqName,
lightClassDataCache: CachedValue<LightClassDataHolder.ForFacade>,
files: Collection<KtFile>
): KtUltraLightClassForFacade? {
if (files.any { it.isScript() }) return null
val filesToSupports: List<Pair<KtFile, KtUltraLightSupport>> = files.map {
it to UltraLightSupportViaService(it)
}
return KtUltraLightClassForFacade(
manager,
facadeClassFqName,
lightClassDataCache,
files,
filesToSupports
)
} }
override fun createUltraLightClass(element: KtClassOrObject): KtUltraLightClass? { override fun getUltraLightClassSupport(element: KtElement): KtUltraLightSupport {
if (element.shouldNotBeVisibleAsLightClass()) { require(element.project == project) { "ULC support created from another project from requested" }
return null return ultraLightSupport
}
return UltraLightSupportViaService(element).let { support ->
when {
element is KtObjectDeclaration && element.isObjectLiteral() ->
KtUltraLightClassForAnonymousDeclaration(element, support)
element.safeIsLocal() ->
KtUltraLightClassForLocalDeclaration(element, support)
(element.hasModifier(KtTokens.INLINE_KEYWORD)) ->
KtUltraLightInlineClass(element, support)
else -> KtUltraLightClass(element, support)
}
}
} }
override fun createUltraLightClassForScript(script: KtScript): KtUltraLightClassForScript? =
KtUltraLightClassForScript(script, support = UltraLightSupportViaService(script))
override fun getUltraLightClassSupport(element: KtElement): KtUltraLightSupport = ultraLightSupport
override fun createDataHolderForClass(classOrObject: KtClassOrObject, builder: LightClassBuilder): LightClassDataHolder.ForClass { override fun createDataHolderForClass(classOrObject: KtClassOrObject, builder: LightClassBuilder): LightClassDataHolder.ForClass {
//force resolve companion for light class generation //force resolve companion for light class generation
traceHolder.bindingContext.get(BindingContext.CLASS, classOrObject)?.companionObjectDescriptor traceHolder.bindingContext.get(BindingContext.CLASS, classOrObject)?.companionObjectDescriptor
@@ -167,7 +124,8 @@ class CliLightClassGenerationSupport(private val traceHolder: CliTraceHolder) :
return LightClassDataHolderImpl(stub, diagnostics) return LightClassDataHolderImpl(stub, diagnostics)
} }
private fun getContext(): LightClassConstructionContext = LightClassConstructionContext(traceHolder.bindingContext, traceHolder.module) private fun getContext(): LightClassConstructionContext =
LightClassConstructionContext(traceHolder.bindingContext, traceHolder.module)
override fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor? { override fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor? {
return traceHolder.bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration) return traceHolder.bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration)
@@ -178,6 +136,4 @@ class CliLightClassGenerationSupport(private val traceHolder: CliTraceHolder) :
override fun analyzeAnnotation(element: KtAnnotationEntry) = traceHolder.bindingContext.get(BindingContext.ANNOTATION, element) override fun analyzeAnnotation(element: KtAnnotationEntry) = traceHolder.bindingContext.get(BindingContext.ANNOTATION, element)
override fun analyzeWithContent(element: KtClassOrObject) = traceHolder.bindingContext override fun analyzeWithContent(element: KtClassOrObject) = traceHolder.bindingContext
} }
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.cli.jvm.compiler package org.jetbrains.kotlin.cli.jvm.compiler
import org.jetbrains.annotations.TestOnly import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtPsiUtil import org.jetbrains.kotlin.psi.KtPsiUtil
@@ -23,11 +24,19 @@ class CliTraceHolder : CodeAnalyzerInitializer {
private set private set
var module: ModuleDescriptor by Delegates.notNull() var module: ModuleDescriptor by Delegates.notNull()
private set private set
var languageVersionSettings: LanguageVersionSettings by Delegates.notNull()
private set
override fun initialize(trace: BindingTrace, module: ModuleDescriptor, codeAnalyzer: KotlinCodeAnalyzer) { override fun initialize(
trace: BindingTrace,
module: ModuleDescriptor,
codeAnalyzer: KotlinCodeAnalyzer,
languageVersionSettings: LanguageVersionSettings
) {
this.bindingContext = trace.bindingContext this.bindingContext = trace.bindingContext
this.module = module this.module = module
this.languageVersionSettings = languageVersionSettings
if (trace !is CliBindingTrace) { if (trace !is CliBindingTrace) {
throw IllegalArgumentException("Shared trace is expected to be subclass of ${CliBindingTrace::class.java.simpleName} class") throw IllegalArgumentException("Shared trace is expected to be subclass of ${CliBindingTrace::class.java.simpleName} class")
@@ -77,10 +77,7 @@ import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem
import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
import org.jetbrains.kotlin.config.APPEND_JAVA_SOURCE_ROOTS_HANDLER_KEY import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.extensions.* import org.jetbrains.kotlin.extensions.*
import org.jetbrains.kotlin.extensions.internal.CandidateInterceptor import org.jetbrains.kotlin.extensions.internal.CandidateInterceptor
import org.jetbrains.kotlin.extensions.internal.TypeResolutionInterceptor import org.jetbrains.kotlin.extensions.internal.TypeResolutionInterceptor
@@ -108,12 +105,13 @@ import java.util.zip.ZipFile
class KotlinCoreEnvironment private constructor( class KotlinCoreEnvironment private constructor(
val projectEnvironment: JavaCoreProjectEnvironment, val projectEnvironment: JavaCoreProjectEnvironment,
initialConfiguration: CompilerConfiguration, private val initialConfiguration: CompilerConfiguration,
configFiles: EnvironmentConfigFiles configFiles: EnvironmentConfigFiles
) { ) {
class ProjectEnvironment( class ProjectEnvironment(
disposable: Disposable, applicationEnvironment: KotlinCoreApplicationEnvironment disposable: Disposable,
applicationEnvironment: KotlinCoreApplicationEnvironment
) : ) :
KotlinCoreProjectEnvironment(disposable, applicationEnvironment) { KotlinCoreProjectEnvironment(disposable, applicationEnvironment) {
@@ -637,7 +635,7 @@ class KotlinCoreEnvironment private constructor(
fun registerKotlinLightClassSupport(project: MockProject) { fun registerKotlinLightClassSupport(project: MockProject) {
with(project) { with(project) {
val traceHolder = CliTraceHolder() val traceHolder = CliTraceHolder()
val cliLightClassGenerationSupport = CliLightClassGenerationSupport(traceHolder) val cliLightClassGenerationSupport = CliLightClassGenerationSupport(traceHolder, project)
val kotlinAsJavaSupport = CliKotlinAsJavaSupport(this, traceHolder) val kotlinAsJavaSupport = CliKotlinAsJavaSupport(this, traceHolder)
registerService(LightClassGenerationSupport::class.java, cliLightClassGenerationSupport) registerService(LightClassGenerationSupport::class.java, cliLightClassGenerationSupport)
registerService(CliLightClassGenerationSupport::class.java, cliLightClassGenerationSupport) registerService(CliLightClassGenerationSupport::class.java, cliLightClassGenerationSupport)
@@ -93,7 +93,7 @@ fun createContainerForLazyResolveWithJava(
} }
fun StorageComponentContainer.initializeJavaSpecificComponents(bindingTrace: BindingTrace) { fun StorageComponentContainer.initializeJavaSpecificComponents(bindingTrace: BindingTrace) {
get<AbstractJavaClassFinder>().initialize(bindingTrace, get<KotlinCodeAnalyzer>()) get<AbstractJavaClassFinder>().initialize(bindingTrace, get<KotlinCodeAnalyzer>(), get<LanguageVersionSettings>())
} }
fun StorageComponentContainer.configureJavaSpecificComponents( fun StorageComponentContainer.configureJavaSpecificComponents(
@@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.search.DelegatingGlobalSearchScope import com.intellij.psi.search.DelegatingGlobalSearchScope
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer
@@ -49,8 +50,8 @@ abstract class AbstractJavaClassFinder : JavaClassFinder {
} }
@PostConstruct @PostConstruct
open fun initialize(trace: BindingTrace, codeAnalyzer: KotlinCodeAnalyzer) { open fun initialize(trace: BindingTrace, codeAnalyzer: KotlinCodeAnalyzer, languageVersionSettings: LanguageVersionSettings) {
CodeAnalyzerInitializer.getInstance(project).initialize(trace, codeAnalyzer.moduleDescriptor, codeAnalyzer) CodeAnalyzerInitializer.getInstance(project).initialize(trace, codeAnalyzer.moduleDescriptor, codeAnalyzer, languageVersionSettings)
} }
inner class FilterOutKotlinSourceFilesScope(baseScope: GlobalSearchScope) : DelegatingGlobalSearchScope(baseScope), inner class FilterOutKotlinSourceFilesScope(baseScope: GlobalSearchScope) : DelegatingGlobalSearchScope(baseScope),
@@ -18,11 +18,18 @@ package org.jetbrains.kotlin.resolve
import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
interface CodeAnalyzerInitializer { interface CodeAnalyzerInitializer {
fun initialize(trace: BindingTrace, module: ModuleDescriptor, codeAnalyzer: KotlinCodeAnalyzer) fun initialize(
trace: BindingTrace,
module: ModuleDescriptor,
codeAnalyzer: KotlinCodeAnalyzer,
languageVersionSettings: LanguageVersionSettings
)
fun createTrace(): BindingTrace fun createTrace(): BindingTrace
companion object { companion object {
@@ -32,7 +39,12 @@ interface CodeAnalyzerInitializer {
} }
class DummyCodeAnalyzerInitializer : CodeAnalyzerInitializer { class DummyCodeAnalyzerInitializer : CodeAnalyzerInitializer {
override fun initialize(trace: BindingTrace, module: ModuleDescriptor, codeAnalyzer: KotlinCodeAnalyzer) { override fun initialize(
trace: BindingTrace,
module: ModuleDescriptor,
codeAnalyzer: KotlinCodeAnalyzer,
languageVersionSettings: LanguageVersionSettings
) {
// Do nothing // Do nothing
} }
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.javac.components package org.jetbrains.kotlin.javac.components
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.javac.JavacWrapper import org.jetbrains.kotlin.javac.JavacWrapper
import org.jetbrains.kotlin.load.java.AbstractJavaClassFinder import org.jetbrains.kotlin.load.java.AbstractJavaClassFinder
import org.jetbrains.kotlin.load.java.JavaClassFinder import org.jetbrains.kotlin.load.java.JavaClassFinder
@@ -27,9 +28,9 @@ class JavacBasedClassFinder : AbstractJavaClassFinder() {
private lateinit var javac: JavacWrapper private lateinit var javac: JavacWrapper
override fun initialize(trace: BindingTrace, codeAnalyzer: KotlinCodeAnalyzer) { override fun initialize(trace: BindingTrace, codeAnalyzer: KotlinCodeAnalyzer, languageVersionSettings: LanguageVersionSettings) {
javac = JavacWrapper.getInstance(project) javac = JavacWrapper.getInstance(project)
super.initialize(trace, codeAnalyzer) super.initialize(trace, codeAnalyzer, languageVersionSettings)
} }
override fun findClass(request: JavaClassFinder.Request) = override fun findClass(request: JavaClassFinder.Request) =
@@ -28,9 +28,11 @@ import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
import org.jetbrains.kotlin.asJava.classes.* import org.jetbrains.kotlin.asJava.classes.*
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
typealias LightClassBuilder = (LightClassConstructionContext) -> LightClassBuilderResult typealias LightClassBuilder = (LightClassConstructionContext) -> LightClassBuilderResult
@@ -49,18 +51,57 @@ abstract class LightClassGenerationSupport {
abstract fun analyzeWithContent(element: KtClassOrObject): BindingContext abstract fun analyzeWithContent(element: KtClassOrObject): BindingContext
abstract fun createUltraLightClass(element: KtClassOrObject): KtUltraLightClass? protected abstract fun getUltraLightClassSupport(element: KtElement): KtUltraLightSupport
abstract fun createUltraLightClassForScript(script: KtScript): KtUltraLightClassForScript? fun createConstantEvaluator(expression: KtExpression): ConstantExpressionEvaluator = getUltraLightClassSupport(expression).run {
ConstantExpressionEvaluator(moduleDescriptor, languageVersionSettings, expression.project)
}
abstract fun getUltraLightClassSupport(element: KtElement): KtUltraLightSupport fun createUltraLightClassForFacade(
abstract fun createUltraLightClassForFacade(
manager: PsiManager, manager: PsiManager,
facadeClassFqName: FqName, facadeClassFqName: FqName,
lightClassDataCache: CachedValue<LightClassDataHolder.ForFacade>, lightClassDataCache: CachedValue<LightClassDataHolder.ForFacade>,
files: Collection<KtFile> files: Collection<KtFile>,
): KtUltraLightClassForFacade? ): KtUltraLightClassForFacade? {
if (files.any { it.isScript() }) return null
val filesToSupports: List<Pair<KtFile, KtUltraLightSupport>> = files.map {
it to getUltraLightClassSupport(it)
}
return KtUltraLightClassForFacade(
manager,
facadeClassFqName,
lightClassDataCache,
files,
filesToSupports
)
}
fun createUltraLightClass(element: KtClassOrObject): KtUltraLightClass? {
if (element.shouldNotBeVisibleAsLightClass()) {
return null
}
return getUltraLightClassSupport(element).let { support ->
when {
element is KtObjectDeclaration && element.isObjectLiteral() ->
KtUltraLightClassForAnonymousDeclaration(element, support)
element.safeIsLocal() ->
KtUltraLightClassForLocalDeclaration(element, support)
(element.hasModifier(KtTokens.INLINE_KEYWORD)) ->
KtUltraLightInlineClass(element, support)
else -> KtUltraLightClass(element, support)
}
}
}
fun createUltraLightClassForScript(script: KtScript): KtUltraLightClassForScript? =
KtUltraLightClassForScript(script, support = getUltraLightClassSupport(script))
companion object { companion object {
@JvmStatic @JvmStatic
@@ -6,12 +6,11 @@
package org.jetbrains.kotlin.asJava.classes package org.jetbrains.kotlin.asJava.classes
import org.jetbrains.annotations.TestOnly import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
interface KtUltraLightSupport { interface KtUltraLightSupport {
@@ -20,9 +19,9 @@ interface KtUltraLightSupport {
val typeMapper: KotlinTypeMapper val typeMapper: KotlinTypeMapper
val moduleDescriptor: ModuleDescriptor val moduleDescriptor: ModuleDescriptor
val isReleasedCoroutine: Boolean val isReleasedCoroutine: Boolean
fun possiblyHasAlias(file: KtFile, shortName: Name): Boolean val languageVersionSettings: LanguageVersionSettings
fun getConstantEvaluator(expression: KtExpression): ConstantExpressionEvaluator fun possiblyHasAlias(file: KtFile, shortName: Name): Boolean
companion object { companion object {
// This property may be removed once IntelliJ versions earlier than 2018.3 become unsupported // This property may be removed once IntelliJ versions earlier than 2018.3 become unsupported
@@ -32,30 +31,3 @@ interface KtUltraLightSupport {
var forceUsingOldLightClasses = false var forceUsingOldLightClasses = false
} }
} }
class UltraLightSupportViaService(private val ktElement: KtElement) : KtUltraLightSupport {
private val serviceProvidedSupport: KtUltraLightSupport
get() = LightClassGenerationSupport.getInstance(ktElement.project).getUltraLightClassSupport(ktElement)
override val moduleName: String
get() = serviceProvidedSupport.moduleName
override val deprecationResolver: DeprecationResolver
get() = serviceProvidedSupport.deprecationResolver
override val typeMapper: KotlinTypeMapper
get() = serviceProvidedSupport.typeMapper
override val moduleDescriptor: ModuleDescriptor
get() = serviceProvidedSupport.moduleDescriptor
override val isReleasedCoroutine: Boolean
get() = serviceProvidedSupport.isReleasedCoroutine
override fun possiblyHasAlias(file: KtFile, shortName: Name): Boolean =
serviceProvidedSupport.possiblyHasAlias(file, shortName)
override fun getConstantEvaluator(expression: KtExpression): ConstantExpressionEvaluator =
serviceProvidedSupport.getConstantEvaluator(expression)
}
@@ -282,9 +282,7 @@ fun computeExpression(expression: PsiElement): Any? {
} }
val generationSupport = LightClassGenerationSupport.getInstance(expressionToCompute.project) val generationSupport = LightClassGenerationSupport.getInstance(expressionToCompute.project)
val evaluator = generationSupport val evaluator = generationSupport.createConstantEvaluator(expressionToCompute)
.getUltraLightClassSupport(expressionToCompute)
.getConstantEvaluator(expressionToCompute)
val constant = runReadAction { val constant = runReadAction {
val evaluatorTrace = DelegatingBindingTrace(generationSupport.analyze(expressionToCompute), "Evaluating annotation argument") val evaluatorTrace = DelegatingBindingTrace(generationSupport.analyze(expressionToCompute), "Evaluating annotation argument")
@@ -7,9 +7,7 @@ package org.jetbrains.kotlin.idea.caches.resolve
import com.intellij.openapi.module.ModuleUtilCore import com.intellij.openapi.module.ModuleUtilCore
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.PsiManager
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.CachedValue
import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager import com.intellij.psi.util.CachedValuesManager
import com.intellij.psi.util.PsiModificationTracker import com.intellij.psi.util.PsiModificationTracker
@@ -25,6 +23,7 @@ import org.jetbrains.kotlin.codegen.JvmCodegenUtil
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.JvmTarget import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.idea.FrontendInternals import org.jetbrains.kotlin.idea.FrontendInternals
@@ -33,33 +32,27 @@ import org.jetbrains.kotlin.idea.caches.lightClasses.LazyLightClassDataHolder
import org.jetbrains.kotlin.idea.project.languageVersionSettings import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.idea.resolve.frontendService import org.jetbrains.kotlin.idea.resolve.frontendService
import org.jetbrains.kotlin.idea.stubindex.KotlinTypeAliasShortNameIndex import org.jetbrains.kotlin.idea.stubindex.KotlinTypeAliasShortNameIndex
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.lazy.NoDescriptorForDeclarationException import org.jetbrains.kotlin.resolve.lazy.NoDescriptorForDeclarationException
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import java.util.concurrent.ConcurrentMap import java.util.concurrent.ConcurrentMap
class IDELightClassGenerationSupport(private val project: Project) : LightClassGenerationSupport() { class IDELightClassGenerationSupport(project: Project) : LightClassGenerationSupport() {
private class KtUltraLightSupportImpl(private val element: KtElement) : KtUltraLightSupport { private class KtUltraLightSupportImpl(private val element: KtElement) : KtUltraLightSupport {
private val module = ModuleUtilCore.findModuleForPsiElement(element) private val module = ModuleUtilCore.findModuleForPsiElement(element)
private val languageVersionSettings override val languageVersionSettings: LanguageVersionSettings
get() = module?.languageVersionSettings ?: KotlinTypeMapper.LANGUAGE_VERSION_SETTINGS_DEFAULT get() = module?.languageVersionSettings ?: KotlinTypeMapper.LANGUAGE_VERSION_SETTINGS_DEFAULT
override val isReleasedCoroutine override val isReleasedCoroutine
get() = languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines) ?: true get() = languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines) ?: true
override fun getConstantEvaluator(expression: KtExpression): ConstantExpressionEvaluator =
ConstantExpressionEvaluator(moduleDescriptor, KotlinTypeMapper.LANGUAGE_VERSION_SETTINGS_DEFAULT, expression.project)
private val resolutionFacade get() = element.getResolutionFacade() private val resolutionFacade get() = element.getResolutionFacade()
override val moduleDescriptor get() = resolutionFacade.moduleDescriptor override val moduleDescriptor get() = resolutionFacade.moduleDescriptor
@@ -94,54 +87,7 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
} }
} }
override fun createUltraLightClassForFacade( override fun getUltraLightClassSupport(element: KtElement): KtUltraLightSupport = KtUltraLightSupportImpl(element)
manager: PsiManager,
facadeClassFqName: FqName,
lightClassDataCache: CachedValue<LightClassDataHolder.ForFacade>,
files: Collection<KtFile>
): KtUltraLightClassForFacade? {
if (files.any { it.isScript() }) return null
val filesToSupports: List<Pair<KtFile, KtUltraLightSupport>> = files.map {
it to KtUltraLightSupportImpl(it)
}
return KtUltraLightClassForFacade(
manager,
facadeClassFqName,
lightClassDataCache,
files,
filesToSupports
)
}
override fun createUltraLightClass(element: KtClassOrObject): KtUltraLightClass? {
if (element.shouldNotBeVisibleAsLightClass()) {
return null
}
return KtUltraLightSupportImpl(element).let { support ->
when {
element is KtObjectDeclaration && element.isObjectLiteral() ->
KtUltraLightClassForAnonymousDeclaration(element, support)
element.safeIsLocal() ->
KtUltraLightClassForLocalDeclaration(element, support)
(element.hasModifier(KtTokens.INLINE_KEYWORD)) ->
KtUltraLightInlineClass(element, support)
else -> KtUltraLightClass(element, support)
}
}
}
override fun createUltraLightClassForScript(script: KtScript): KtUltraLightClassForScript? =
KtUltraLightClassForScript(script, support = KtUltraLightSupportImpl(script))
override fun getUltraLightClassSupport(element: KtElement): KtUltraLightSupport =
KtUltraLightSupportImpl(element)
private val scopeFileComparator = JavaElementFinder.byClasspathComparator(GlobalSearchScope.allScope(project)) private val scopeFileComparator = JavaElementFinder.byClasspathComparator(GlobalSearchScope.allScope(project))