[ULC] Add constant evaluation to light classes service
This commit is contained in:
+10
-3
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
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.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.resolve.lazy.NoDescriptorForDeclarationException
|
||||
@@ -46,12 +47,18 @@ import java.util.concurrent.ConcurrentMap
|
||||
|
||||
class IDELightClassGenerationSupport(private val project: Project) : LightClassGenerationSupport() {
|
||||
|
||||
private inner class KtUltraLightSupportImpl(private val element: KtElement) : KtUltraLightSupport {
|
||||
private class KtUltraLightSupportImpl(private val element: KtElement) : KtUltraLightSupport {
|
||||
|
||||
private val module = ModuleUtilCore.findModuleForPsiElement(element)
|
||||
|
||||
private val languageVersionSettings
|
||||
get() = module?.languageVersionSettings ?: KotlinTypeMapper.LANGUAGE_VERSION_SETTINGS_DEFAULT
|
||||
|
||||
override val isReleasedCoroutine
|
||||
get() = module?.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()
|
||||
|
||||
@@ -68,7 +75,7 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
|
||||
override val typeMapper: KotlinTypeMapper by lazyPub {
|
||||
KotlinTypeMapper(
|
||||
BindingContext.EMPTY, ClassBuilderMode.LIGHT_CLASSES,
|
||||
moduleName, KotlinTypeMapper.LANGUAGE_VERSION_SETTINGS_DEFAULT, // TODO use proper LanguageVersionSettings
|
||||
moduleName, languageVersionSettings,
|
||||
jvmTarget = JvmTarget.JVM_1_8,
|
||||
typePreprocessor = KotlinType::cleanFromAnonymousTypes,
|
||||
namePreprocessor = ::tryGetPredefinedName
|
||||
|
||||
@@ -19,24 +19,10 @@ package org.jetbrains.kotlin.idea
|
||||
import com.intellij.psi.PsiConstantEvaluationHelper
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.impl.ConstantExpressionEvaluator
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightElementBase
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.asJava.computeExpression
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.resolve.DelegatingBindingTrace
|
||||
import org.jetbrains.kotlin.resolve.constants.ArrayValue
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator as FrontendConstantExpressionEvaluator
|
||||
|
||||
class KotlinLightConstantExpressionEvaluator : ConstantExpressionEvaluator {
|
||||
private fun evalConstantValue(constantValue: ConstantValue<*>): Any? {
|
||||
return if (constantValue is ArrayValue) {
|
||||
val items = constantValue.value.map { evalConstantValue(it) }
|
||||
items.singleOrNull() ?: items
|
||||
} else constantValue.value
|
||||
}
|
||||
|
||||
override fun computeConstantExpression(expression: PsiElement, throwExceptionOnOverflow: Boolean): Any? {
|
||||
return computeExpression(expression, throwExceptionOnOverflow, null)
|
||||
@@ -46,23 +32,5 @@ class KotlinLightConstantExpressionEvaluator : ConstantExpressionEvaluator {
|
||||
expression: PsiElement,
|
||||
throwExceptionOnOverflow: Boolean,
|
||||
auxEvaluator: PsiConstantEvaluationHelper.AuxEvaluator?
|
||||
): Any? {
|
||||
val expressionToCompute = when (expression) {
|
||||
is KtLightElementBase -> expression.kotlinOrigin as? KtExpression ?: return null
|
||||
else -> return null
|
||||
}
|
||||
|
||||
val resolutionFacade = expressionToCompute.getResolutionFacade()
|
||||
val evaluator = FrontendConstantExpressionEvaluator(
|
||||
resolutionFacade.moduleDescriptor, expressionToCompute.languageVersionSettings, resolutionFacade.project
|
||||
)
|
||||
|
||||
val constant = runReadAction {
|
||||
val evaluatorTrace = DelegatingBindingTrace(resolutionFacade.analyze(expressionToCompute), "Evaluating annotation argument")
|
||||
evaluator.evaluateExpression(expressionToCompute, evaluatorTrace)
|
||||
} ?: return null
|
||||
|
||||
if (constant.isError) return null
|
||||
return evalConstantValue(constant.toConstantValue(TypeUtils.NO_EXPECTED_TYPE))
|
||||
}
|
||||
): Any? = computeExpression(expression)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user