Refactor and improve code obtaining actual Java annotation parameter values
Extract Java-specific code into module 'frontend.java' and use already existing JavaAnnotationArgument facilities to determine the default parameter value in an actual Java annotation class. Annotation arguments are not yet supported because to create an instance of AnnotationValue, we need a descriptor, which is not available at this point. #KT-22704 In Progress #KT-28077 Open
This commit is contained in:
@@ -65,7 +65,7 @@ private fun StorageComponentContainer.configureJavaTopDownAnalysis(
|
||||
|
||||
useInstance(VirtualFileFinderFactory.getInstance(project).create(moduleContentScope))
|
||||
|
||||
useImpl<JavaPropertyInitializerEvaluatorImpl>()
|
||||
useInstance(JavaPropertyInitializerEvaluatorImpl)
|
||||
useImpl<AnnotationResolverImpl>()
|
||||
useImpl<SignaturePropagatorImpl>()
|
||||
useImpl<TraceBasedErrorReporter>()
|
||||
|
||||
+10
-9
@@ -20,20 +20,21 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaField
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class JavaPropertyInitializerEvaluatorImpl : JavaPropertyInitializerEvaluator {
|
||||
override fun getInitializerConstant(field: JavaField, descriptor: PropertyDescriptor): ConstantValue<*>? {
|
||||
val evaluated = field.initializerValue ?: return null
|
||||
object JavaPropertyInitializerEvaluatorImpl : JavaPropertyInitializerEvaluator {
|
||||
override fun getInitializerConstant(field: JavaField, descriptor: PropertyDescriptor): ConstantValue<*>? =
|
||||
field.initializerValue?.let { value -> convertLiteralValue(value, descriptor.type) }
|
||||
|
||||
return when (evaluated) {
|
||||
//Note: evaluated expression may be of class that does not match field type in some cases
|
||||
// tested for Int, left other checks just in case
|
||||
internal fun convertLiteralValue(value: Any, expectedType: KotlinType): ConstantValue<*>? =
|
||||
when (value) {
|
||||
// Note: `value` expression may be of class that does not match field type in some cases
|
||||
// tested for Int, left other checks just in case
|
||||
is Byte, is Short, is Int, is Long -> {
|
||||
ConstantValueFactory.createIntegerConstantValue((evaluated as Number).toLong(), descriptor.type, false)
|
||||
ConstantValueFactory.createIntegerConstantValue((value as Number).toLong(), expectedType, false)
|
||||
}
|
||||
else -> {
|
||||
ConstantValueFactory.createConstantValue(evaluated)
|
||||
ConstantValueFactory.createConstantValue(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.jvm.multiplatform
|
||||
|
||||
import com.intellij.psi.PsiAnnotationMethod
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.load.java.components.JavaPropertyInitializerEvaluatorImpl
|
||||
import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaAnnotationArgumentImpl
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory
|
||||
import org.jetbrains.kotlin.resolve.constants.EnumValue
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||
|
||||
class JavaActualAnnotationArgumentExtractor : ExpectedActualDeclarationChecker.ActualAnnotationArgumentExtractor {
|
||||
override fun extractActualValue(argument: PsiElement, expectedType: KotlinType): ConstantValue<*>? =
|
||||
(argument as? PsiAnnotationMethod)
|
||||
?.defaultValue
|
||||
?.let { JavaAnnotationArgumentImpl.create(it, null) }
|
||||
?.convert(expectedType)
|
||||
|
||||
// This code is similar to LazyJavaAnnotationDescriptor.resolveAnnotationArgument, but cannot be reused until
|
||||
// KClassValue/AnnotationValue are untied from descriptors/types, because here we do not have an instance of LazyJavaResolverContext.
|
||||
private fun JavaAnnotationArgument.convert(expectedType: KotlinType): ConstantValue<*>? {
|
||||
return when (this) {
|
||||
is JavaLiteralAnnotationArgument -> value?.let {
|
||||
JavaPropertyInitializerEvaluatorImpl.convertLiteralValue(it, expectedType)
|
||||
}
|
||||
is JavaEnumValueAnnotationArgument -> {
|
||||
enumClassId?.let { enumClassId ->
|
||||
entryName?.let { entryName ->
|
||||
EnumValue(enumClassId, entryName)
|
||||
}
|
||||
}
|
||||
}
|
||||
is JavaArrayAnnotationArgument -> {
|
||||
val elementType = expectedType.builtIns.getArrayElementType(expectedType)
|
||||
ConstantValueFactory.createArrayValue(getElements().mapNotNull { it.convert(elementType) }, expectedType)
|
||||
}
|
||||
is JavaAnnotationAsAnnotationArgument -> {
|
||||
// TODO: support annotations as annotation arguments (KT-28077)
|
||||
null
|
||||
}
|
||||
is JavaClassObjectAnnotationArgument -> {
|
||||
// TODO: support class literals as annotation arguments
|
||||
null
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.resolve.checkers.BigFunctionTypeAvailabilityChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.jvm.*
|
||||
import org.jetbrains.kotlin.resolve.jvm.checkers.*
|
||||
import org.jetbrains.kotlin.resolve.jvm.multiplatform.JavaActualAnnotationArgumentExtractor
|
||||
import org.jetbrains.kotlin.synthetic.JavaSyntheticScopes
|
||||
import org.jetbrains.kotlin.types.DynamicTypesSettings
|
||||
import org.jetbrains.kotlin.types.expressions.FunctionWithBigAritySupport
|
||||
@@ -34,7 +35,7 @@ object JvmPlatformConfigurator : PlatformConfigurator(
|
||||
TypeParameterBoundIsNotArrayChecker(),
|
||||
JvmSyntheticApplicabilityChecker(),
|
||||
StrictfpApplicabilityChecker(),
|
||||
ExpectedActualDeclarationChecker,
|
||||
ExpectedActualDeclarationChecker(listOf(JavaActualAnnotationArgumentExtractor())),
|
||||
JvmAnnotationsTargetNonExistentAccessorChecker(),
|
||||
BadInheritedJavaSignaturesChecker
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user