From 513655239d14c410d49facf207968268a0827f52 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Thu, 20 Apr 2017 14:41:26 +0300 Subject: [PATCH] Introduce initializer-related properties into JavaField It's much more convenient to use and implement these properties instead of manual "pattern matching" in the JavaPropertyInitializerEvaluatorImpl --- .../JavaPropertyInitializerEvaluatorImpl.kt | 20 +------------------ .../java/structure/impl/JavaFieldImpl.java | 15 +++++++++++--- .../java/structure/impl/classFiles/Other.kt | 5 ++++- .../JavaPropertyInitializerEvaluator.kt | 4 ---- .../java/lazy/descriptors/LazyJavaScope.kt | 2 +- .../load/java/structure/javaElements.kt | 2 ++ .../structure/reflect/ReflectJavaField.kt | 3 +++ 7 files changed, 23 insertions(+), 28 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/components/JavaPropertyInitializerEvaluatorImpl.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/components/JavaPropertyInitializerEvaluatorImpl.kt index 04da06839e6..eec889718e2 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/components/JavaPropertyInitializerEvaluatorImpl.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/components/JavaPropertyInitializerEvaluatorImpl.kt @@ -16,23 +16,15 @@ package org.jetbrains.kotlin.load.java.components -import com.intellij.psi.impl.JavaConstantExpressionEvaluator -import com.intellij.psi.util.PsiUtil import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.load.java.structure.JavaField -import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaField -import org.jetbrains.kotlin.load.java.structure.impl.JavaFieldImpl import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns class JavaPropertyInitializerEvaluatorImpl : JavaPropertyInitializerEvaluator { override fun getInitializerConstant(field: JavaField, descriptor: PropertyDescriptor): ConstantValue<*>? { - val evaluated = when (field) { - is JavaFieldImpl -> JavaConstantExpressionEvaluator.computeConstantExpression(field.initializer, false) - is BinaryJavaField -> field.compiledValue - else -> null - } ?: return null + val evaluated = field.initializerValue ?: return null val factory = ConstantValueFactory(descriptor.builtIns) when (evaluated) { @@ -46,14 +38,4 @@ class JavaPropertyInitializerEvaluatorImpl : JavaPropertyInitializerEvaluator { } } } - - override fun isNotNullCompileTimeConstant(field: JavaField): Boolean { - if (field is BinaryJavaField) { - return field.compiledValue != null - } - - // PsiUtil.isCompileTimeConstant returns false for null-initialized fields, - // see com.intellij.psi.util.IsConstantExpressionVisitor.visitLiteralExpression() - return PsiUtil.isCompileTimeConstant((field as JavaFieldImpl).psi) - } } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/JavaFieldImpl.java b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/JavaFieldImpl.java index 595cf24a85a..032303fa730 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/JavaFieldImpl.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/JavaFieldImpl.java @@ -17,8 +17,9 @@ package org.jetbrains.kotlin.load.java.structure.impl; import com.intellij.psi.PsiEnumConstant; -import com.intellij.psi.PsiExpression; import com.intellij.psi.PsiField; +import com.intellij.psi.impl.JavaConstantExpressionEvaluator; +import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.load.java.structure.JavaField; @@ -41,7 +42,15 @@ public class JavaFieldImpl extends JavaMemberImpl implements JavaField } @Nullable - public PsiExpression getInitializer() { - return getPsi().getInitializer(); + @Override + public Object getInitializerValue() { + return JavaConstantExpressionEvaluator.computeConstantExpression(getPsi().getInitializer(), false); + } + + @Override + public boolean getHasConstantNotNullInitializer() { + // PsiUtil.isCompileTimeConstant returns false for null-initialized fields, + // see com.intellij.psi.util.IsConstantExpressionVisitor.visitLiteralExpression() + return PsiUtil.isCompileTimeConstant(getPsi()); } } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/classFiles/Other.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/classFiles/Other.kt index 6e326a8614e..713d630e95b 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/classFiles/Other.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/classFiles/Other.kt @@ -29,10 +29,13 @@ class BinaryJavaField( override val containingClass: JavaClass, override val isEnumEntry: Boolean, override val type: JavaType, - val compiledValue: Any? + override val initializerValue: Any? ) : JavaField, BinaryJavaAnnotationOwner, BinaryJavaModifierListOwner { override val annotations: MutableCollection = ContainerUtil.newSmartList() override val annotationsByFqName by buildLazyValueForMap() + + override val hasConstantNotNullInitializer: Boolean + get() = initializerValue != null } class BinaryJavaTypeParameter( diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/components/JavaPropertyInitializerEvaluator.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/components/JavaPropertyInitializerEvaluator.kt index 8c3511db002..7659487c781 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/components/JavaPropertyInitializerEvaluator.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/components/JavaPropertyInitializerEvaluator.kt @@ -23,11 +23,7 @@ import org.jetbrains.kotlin.resolve.constants.ConstantValue interface JavaPropertyInitializerEvaluator { fun getInitializerConstant(field: JavaField, descriptor: PropertyDescriptor): ConstantValue<*>? - fun isNotNullCompileTimeConstant(field: JavaField): Boolean - object DoNothing : JavaPropertyInitializerEvaluator { override fun getInitializerConstant(field: JavaField, descriptor: PropertyDescriptor) = null - - override fun isNotNullCompileTimeConstant(field: JavaField) = false } } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt index 6eb5ce7673b..595ee5085eb 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt @@ -285,7 +285,7 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS private fun getPropertyType(field: JavaField, annotations: Annotations): KotlinType { // Fields do not have their own generic parameters. // Simple static constants should not have flexible types. - val allowFlexible = !(field.isFinalStatic && c.components.javaPropertyInitializerEvaluator.isNotNullCompileTimeConstant(field)) + val allowFlexible = !(field.isFinalStatic && field.hasConstantNotNullInitializer) val propertyType = c.typeResolver.transformJavaType( field.type, LazyJavaTypeAttributes(TypeUsage.MEMBER_SIGNATURE_INVARIANT, annotations, allowFlexible) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/structure/javaElements.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/structure/javaElements.kt index b5e2e1d96e1..bfd16f90fed 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/structure/javaElements.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/structure/javaElements.kt @@ -97,6 +97,8 @@ interface JavaMethod : JavaMember, JavaTypeParameterListOwner { interface JavaField : JavaMember { val isEnumEntry: Boolean val type: JavaType + val initializerValue: Any? + val hasConstantNotNullInitializer: Boolean } interface JavaConstructor : JavaMember, JavaTypeParameterListOwner { diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaField.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaField.kt index 4bdcf4f139b..91e33efb1cb 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaField.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaField.kt @@ -25,4 +25,7 @@ class ReflectJavaField(override val member: Field) : ReflectJavaMember(), JavaFi override val type: ReflectJavaType get() = ReflectJavaType.create(member.genericType) + + override val initializerValue get() = null + override val hasConstantNotNullInitializer get() = false }