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:
Pavel V. Talanov
2015-07-07 14:56:19 +03:00
parent 155f00578d
commit c313887641
134 changed files with 791 additions and 907 deletions
@@ -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,
@@ -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)
@@ -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);
}
@@ -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
}
}
@@ -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