Split CompileTimeConstant into two entities
1. ConstantValue * just holds some value and its type * implementations for concrete constants 2. CompileTimeConstant * is only produced by ConstantExpressionEvaluator * has additional flags (canBeUsedInAnnotation etc) * has two implementations TypedCompileTimeConstant containing a constant value and IntegerValueConstant which does not have exact type * can be converted to ConstantValue Adjustt usages to use ConstantValue if flags are not needed Add tests for some uncovered cases
This commit is contained in:
+10
-9
@@ -30,7 +30,8 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.resolve.constants.*
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass
|
||||
import org.jetbrains.kotlin.resolve.jvm.PLATFORM_TYPES
|
||||
import org.jetbrains.kotlin.types.*
|
||||
@@ -64,7 +65,7 @@ class LazyJavaAnnotationDescriptor(
|
||||
annotationClass?.getDefaultType() ?: ErrorUtils.createErrorType(fqName.asString())
|
||||
}
|
||||
|
||||
private val factory = CompileTimeConstantFactory(CompileTimeConstant.Parameters.Impl(true, false, false), c.module.builtIns)
|
||||
private val factory = ConstantValueFactory(c.module.builtIns)
|
||||
|
||||
override fun getType(): JetType = type()
|
||||
|
||||
@@ -74,7 +75,7 @@ class LazyJavaAnnotationDescriptor(
|
||||
|
||||
override fun getAllValueArguments() = allValueArguments()
|
||||
|
||||
private fun computeValueArguments(): Map<ValueParameterDescriptor, CompileTimeConstant<*>> {
|
||||
private fun computeValueArguments(): Map<ValueParameterDescriptor, ConstantValue<*>> {
|
||||
val constructors = getAnnotationClass().getConstructors()
|
||||
if (constructors.isEmpty()) return mapOf()
|
||||
|
||||
@@ -100,9 +101,9 @@ class LazyJavaAnnotationDescriptor(
|
||||
|
||||
private fun getAnnotationClass() = getType().getConstructor().getDeclarationDescriptor() as ClassDescriptor
|
||||
|
||||
private fun resolveAnnotationArgument(argument: JavaAnnotationArgument?): CompileTimeConstant<*>? {
|
||||
private fun resolveAnnotationArgument(argument: JavaAnnotationArgument?): ConstantValue<*>? {
|
||||
return when (argument) {
|
||||
is JavaLiteralAnnotationArgument -> factory.createCompileTimeConstant(argument.value)
|
||||
is JavaLiteralAnnotationArgument -> factory.createConstantValue(argument.value)
|
||||
is JavaEnumValueAnnotationArgument -> resolveFromEnumValue(argument.resolve())
|
||||
is JavaArrayAnnotationArgument -> resolveFromArray(argument.name ?: DEFAULT_ANNOTATION_MEMBER_NAME, argument.getElements())
|
||||
is JavaAnnotationAsAnnotationArgument -> resolveFromAnnotation(argument.getAnnotation())
|
||||
@@ -111,13 +112,13 @@ class LazyJavaAnnotationDescriptor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveFromAnnotation(javaAnnotation: JavaAnnotation): CompileTimeConstant<*>? {
|
||||
private fun resolveFromAnnotation(javaAnnotation: JavaAnnotation): ConstantValue<*>? {
|
||||
val descriptor = c.resolveAnnotation(javaAnnotation) ?: return null
|
||||
|
||||
return factory.createAnnotationValue(descriptor)
|
||||
}
|
||||
|
||||
private fun resolveFromArray(argumentName: Name, elements: List<JavaAnnotationArgument>): CompileTimeConstant<*>? {
|
||||
private fun resolveFromArray(argumentName: Name, elements: List<JavaAnnotationArgument>): ConstantValue<*>? {
|
||||
if (getType().isError()) return null
|
||||
|
||||
val valueParameter = DescriptorResolverUtils.getAnnotationParameterByName(argumentName, getAnnotationClass()) ?: return null
|
||||
@@ -128,7 +129,7 @@ class LazyJavaAnnotationDescriptor(
|
||||
return factory.createArrayValue(values, valueParameter.getType())
|
||||
}
|
||||
|
||||
private fun resolveFromEnumValue(element: JavaField?): CompileTimeConstant<*>? {
|
||||
private fun resolveFromEnumValue(element: JavaField?): ConstantValue<*>? {
|
||||
if (element == null || !element.isEnumEntry()) return null
|
||||
|
||||
val containingJavaClass = element.getContainingClass()
|
||||
@@ -142,7 +143,7 @@ class LazyJavaAnnotationDescriptor(
|
||||
return factory.createEnumValue(classifier)
|
||||
}
|
||||
|
||||
private fun resolveFromJavaClassObjectType(javaType: JavaType): CompileTimeConstant<*>? {
|
||||
private fun resolveFromJavaClassObjectType(javaType: JavaType): ConstantValue<*>? {
|
||||
// Class type is never nullable in 'Foo.class' in Java
|
||||
val type = TypeUtils.makeNotNullable(c.typeResolver.transformJavaType(
|
||||
javaType,
|
||||
|
||||
+1
-1
@@ -181,7 +181,7 @@ class LazyJavaClassDescriptor(
|
||||
getAnnotations().
|
||||
findAnnotation(JvmAnnotationNames.PURELY_IMPLEMENTS_ANNOTATION) ?: return null
|
||||
|
||||
val fqNameString = (annotation.getAllValueArguments().values().singleOrNull() as? StringValue)?.getValue() ?: return null
|
||||
val fqNameString = (annotation.getAllValueArguments().values().singleOrNull() as? StringValue)?.value ?: return null
|
||||
if (!isValidJavaFqName(fqNameString)) return null
|
||||
|
||||
return FqName(fqNameString)
|
||||
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.load.java.structure;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
|
||||
public interface JavaPropertyInitializerEvaluator {
|
||||
JavaPropertyInitializerEvaluator DO_NOTHING = new JavaPropertyInitializerEvaluator() {
|
||||
@Nullable
|
||||
@Override
|
||||
public CompileTimeConstant<?> getInitializerConstant(@NotNull JavaField field, @NotNull PropertyDescriptor descriptor) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNotNullCompileTimeConstant(@NotNull JavaField field) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@Nullable
|
||||
CompileTimeConstant<?> getInitializerConstant(@NotNull JavaField field, @NotNull PropertyDescriptor descriptor);
|
||||
|
||||
boolean isNotNullCompileTimeConstant(@NotNull JavaField field);
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.load.java.structure
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||
|
||||
public interface JavaPropertyInitializerEvaluator {
|
||||
public fun getInitializerConstant(field: JavaField, descriptor: PropertyDescriptor): ConstantValue<*>?
|
||||
|
||||
public fun isNotNullCompileTimeConstant(field: JavaField): Boolean
|
||||
|
||||
public object DoNothing : JavaPropertyInitializerEvaluator {
|
||||
override fun getInitializerConstant(field: JavaField, descriptor: PropertyDescriptor) = null
|
||||
|
||||
override fun isNotNullCompileTimeConstant(field: JavaField) = false
|
||||
}
|
||||
}
|
||||
+13
-11
@@ -26,7 +26,9 @@ import org.jetbrains.kotlin.load.java.components.DescriptorResolverUtils
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.constants.*
|
||||
import org.jetbrains.kotlin.resolve.constants.AnnotationValue
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.AnnotationDeserializer
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
|
||||
@@ -42,16 +44,16 @@ public class BinaryClassAnnotationAndConstantLoaderImpl(
|
||||
storageManager: StorageManager,
|
||||
kotlinClassFinder: KotlinClassFinder,
|
||||
errorReporter: ErrorReporter
|
||||
) : AbstractBinaryClassAnnotationAndConstantLoader<AnnotationDescriptor, CompileTimeConstant<*>>(
|
||||
) : AbstractBinaryClassAnnotationAndConstantLoader<AnnotationDescriptor, ConstantValue<*>>(
|
||||
storageManager, kotlinClassFinder, errorReporter
|
||||
) {
|
||||
private val annotationDeserializer = AnnotationDeserializer(module)
|
||||
private val factory = CompileTimeConstantFactory(CompileTimeConstant.Parameters.ThrowException, module.builtIns)
|
||||
private val factory = ConstantValueFactory(module.builtIns)
|
||||
|
||||
override fun loadTypeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): AnnotationDescriptor =
|
||||
annotationDeserializer.deserializeAnnotation(proto, nameResolver)
|
||||
|
||||
override fun loadConstant(desc: String, initializer: Any): CompileTimeConstant<*>? {
|
||||
override fun loadConstant(desc: String, initializer: Any): ConstantValue<*>? {
|
||||
val normalizedValue: Any = if (desc in "ZBCS") {
|
||||
val intValue = initializer as Int
|
||||
when (desc) {
|
||||
@@ -66,7 +68,7 @@ public class BinaryClassAnnotationAndConstantLoaderImpl(
|
||||
initializer
|
||||
}
|
||||
|
||||
return factory.createCompileTimeConstant(normalizedValue)
|
||||
return factory.createConstantValue(normalizedValue)
|
||||
}
|
||||
|
||||
override fun loadAnnotation(
|
||||
@@ -76,7 +78,7 @@ public class BinaryClassAnnotationAndConstantLoaderImpl(
|
||||
val annotationClass = resolveClass(annotationClassId)
|
||||
|
||||
return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor {
|
||||
private val arguments = HashMap<ValueParameterDescriptor, CompileTimeConstant<*>>()
|
||||
private val arguments = HashMap<ValueParameterDescriptor, ConstantValue<*>>()
|
||||
|
||||
override fun visit(name: Name?, value: Any?) {
|
||||
if (name != null) {
|
||||
@@ -90,7 +92,7 @@ public class BinaryClassAnnotationAndConstantLoaderImpl(
|
||||
|
||||
override fun visitArray(name: Name): AnnotationArrayArgumentVisitor? {
|
||||
return object : KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor {
|
||||
private val elements = ArrayList<CompileTimeConstant<*>>()
|
||||
private val elements = ArrayList<ConstantValue<*>>()
|
||||
|
||||
override fun visit(value: Any?) {
|
||||
elements.add(createConstant(name, value))
|
||||
@@ -122,7 +124,7 @@ public class BinaryClassAnnotationAndConstantLoaderImpl(
|
||||
}
|
||||
|
||||
// NOTE: see analogous code in AnnotationDeserializer
|
||||
private fun enumEntryValue(enumClassId: ClassId, name: Name): CompileTimeConstant<*> {
|
||||
private fun enumEntryValue(enumClassId: ClassId, name: Name): ConstantValue<*> {
|
||||
val enumClass = resolveClass(enumClassId)
|
||||
if (enumClass.getKind() == ClassKind.ENUM_CLASS) {
|
||||
val classifier = enumClass.getUnsubstitutedInnerClassesScope().getClassifier(name)
|
||||
@@ -137,12 +139,12 @@ public class BinaryClassAnnotationAndConstantLoaderImpl(
|
||||
result.add(AnnotationDescriptorImpl(annotationClass.getDefaultType(), arguments))
|
||||
}
|
||||
|
||||
private fun createConstant(name: Name?, value: Any?): CompileTimeConstant<*> {
|
||||
return factory.createCompileTimeConstant(value) ?:
|
||||
private fun createConstant(name: Name?, value: Any?): ConstantValue<*> {
|
||||
return factory.createConstantValue(value) ?:
|
||||
factory.createErrorValue("Unsupported annotation argument: $name")
|
||||
}
|
||||
|
||||
private fun setArgumentValueByName(name: Name, argumentValue: CompileTimeConstant<*>) {
|
||||
private fun setArgumentValueByName(name: Name, argumentValue: ConstantValue<*>) {
|
||||
val parameter = DescriptorResolverUtils.getAnnotationParameterByName(name, annotationClass)
|
||||
if (parameter != null) {
|
||||
arguments[parameter] = argumentValue
|
||||
|
||||
Reference in New Issue
Block a user