diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt index 827eed5b274..2b942878cf8 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt @@ -410,6 +410,8 @@ class TypeResolver( override fun getCompileTimeInitializer() = null + override fun cleanCompileTimeInitializerCache() {} + override fun accept(visitor: DeclarationDescriptorVisitor, data: D): R { return visitor.visitVariableDescriptor(this, data) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt index 7562c8c0407..62e4fd8f05b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt @@ -114,9 +114,9 @@ class VariableTypeAndInitializerResolver( trace: BindingTrace ) { if (!variable.hasInitializer() || variable.isVar) return - variableDescriptor.setCompileTimeInitializer( + variableDescriptor.setCompileTimeInitializerFactory { storageManager.createRecursionTolerantNullableLazyValue( - computeInitializer@ { + computeInitializer@{ if (!DescriptorUtils.shouldRecordInitializerForProperty( variableDescriptor, variableType @@ -133,18 +133,17 @@ class VariableTypeAndInitializerResolver( constantExpressionEvaluator.module ) val constant = constantExpressionEvaluator.evaluateExpression(initializer, trace, initializerType) - ?: return@computeInitializer null + ?: return@computeInitializer null if (constant.usesNonConstValAsConstant && variableDescriptor.isConst) { trace.report(Errors.NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION.on(initializer)) } - val qqq = constant.toConstantValue(initializerType) - qqq + constant.toConstantValue(initializerType) }, null ) - ) + } } private fun resolveDelegatedPropertyType( diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt index c9a5d53742d..9bb985d66ec 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt @@ -185,6 +185,7 @@ open class IrBasedValueParameterDescriptor(owner: IrValueParameter) : ValueParam override fun getName() = owner.name override fun declaresDefaultValue() = owner.defaultValue != null override fun getCompileTimeInitializer(): ConstantValue<*>? = null + override fun cleanCompileTimeInitializerCache() {} override fun copy(newOwner: CallableDescriptor, newName: Name, newIndex: Int) = TODO("not implemented") @@ -325,6 +326,8 @@ open class IrBasedVariableDescriptor(owner: IrVariable) : VariableDescriptor, Ir TODO("") } + override fun cleanCompileTimeInitializerCache() {} + override fun getOverriddenDescriptors(): Collection { TODO("Not Implemented") } @@ -359,6 +362,8 @@ open class IrBasedVariableDescriptorWithAccessor(owner: IrLocalDelegatedProperty TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } + override fun cleanCompileTimeInitializerCache() {} + override fun getType(): KotlinType = owner.type.toIrBasedKotlinType() override fun isConst(): Boolean = false @@ -828,6 +833,8 @@ open class IrBasedPropertyDescriptor(owner: IrProperty) : return null } + override fun cleanCompileTimeInitializerCache() {} + override fun isSetterProjectedOut(): Boolean { TODO("not implemented") } @@ -1016,6 +1023,8 @@ open class IrBasedFieldDescriptor(owner: IrField) : PropertyDescriptor, IrBasedD TODO("not implemented") } + override fun cleanCompileTimeInitializerCache() {} + override fun isSetterProjectedOut(): Boolean { TODO("not implemented") } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltinFunctionDescriptor.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltinFunctionDescriptor.kt index 9a8790fd107..b33e91bfd26 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltinFunctionDescriptor.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltinFunctionDescriptor.kt @@ -119,6 +119,7 @@ class IrBuiltinValueParameterDescriptorImpl( override val isNoinline: Boolean get() = false override val varargElementType: KotlinType? get() = null override fun getCompileTimeInitializer(): ConstantValue<*>? = null + override fun cleanCompileTimeInitializerCache() {} override fun isVar(): Boolean = false override fun getVisibility(): DescriptorVisibility = DescriptorVisibilities.LOCAL diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrDelegateDescriptor.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrDelegateDescriptor.kt index ad4958dc9dc..a2dd85e99fb 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrDelegateDescriptor.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrDelegateDescriptor.kt @@ -76,6 +76,8 @@ abstract class IrDelegateDescriptorBase( override fun getCompileTimeInitializer(): ConstantValue<*>? = null + override fun cleanCompileTimeInitializerCache() {} + override fun getVisibility(): DescriptorVisibility = DescriptorVisibilities.PRIVATE override fun substitute(substitutor: TypeSubstitutor): PropertyDescriptor { @@ -131,6 +133,7 @@ class IrLocalDelegatedPropertyDelegateDescriptorImpl( ) { override fun getCompileTimeInitializer(): ConstantValue<*>? = null + override fun cleanCompileTimeInitializerCache() {} override fun isVar(): Boolean = false override fun isLateInit(): Boolean = false override fun substitute(substitutor: TypeSubstitutor): VariableDescriptor? = throw UnsupportedOperationException() diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/FakeCallableDescriptorForObject.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/FakeCallableDescriptorForObject.kt index e4977edef72..c99425330ad 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/FakeCallableDescriptorForObject.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/FakeCallableDescriptorForObject.kt @@ -65,6 +65,8 @@ open class FakeCallableDescriptorForObject( override fun getCompileTimeInitializer() = null + override fun cleanCompileTimeInitializerCache() {} + override fun getSource(): SourceElement = classDescriptor.source override fun isConst(): Boolean = false diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/descriptors/JavaPropertyDescriptor.java b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/descriptors/JavaPropertyDescriptor.java index 1fa6f88446f..e0cd4d36d56 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/descriptors/JavaPropertyDescriptor.java +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/descriptors/JavaPropertyDescriptor.java @@ -148,8 +148,8 @@ public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements Ja enhanced.initialize(newGetter, newSetter, getBackingField(), getDelegateField()); enhanced.setSetterProjectedOut(isSetterProjectedOut()); - if (compileTimeInitializer != null) { - enhanced.setCompileTimeInitializer(compileTimeInitializer); + if (compileTimeInitializerFactory != null) { + enhanced.setCompileTimeInitializer(compileTimeInitializer, compileTimeInitializerFactory); } enhanced.setOverriddenDescriptors(getOverriddenDescriptors()); diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt index 94a15161f1e..232bf763f5c 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt @@ -307,11 +307,11 @@ abstract class LazyJavaScope( ) if (DescriptorUtils.shouldRecordInitializerForProperty(propertyDescriptor, propertyDescriptor.type)) { - propertyDescriptor.setCompileTimeInitializer( + propertyDescriptor.setCompileTimeInitializerFactory { c.storageManager.createNullableLazyValue { c.components.javaPropertyInitializerEvaluator.getInitializerConstant(field, propertyDescriptor) } - ) + } } c.components.javaResolverCache.recordField(field, propertyDescriptor) diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/VariableDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/VariableDescriptor.java index a809993f42b..4f300992550 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/VariableDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/VariableDescriptor.java @@ -31,6 +31,11 @@ public interface VariableDescriptor extends ValueDescriptor { @Nullable ConstantValue getCompileTimeInitializer(); + /** + * ONLY FOR IDE USE! Please don't use the method inside the compiler + */ + void cleanCompileTimeInitializerCache(); + /** * @return true if iff original declaration has appropriate flags and type, e.g. `const` modifier in Kotlin. * It completely does not means that if isConst then `getCompileTimeInitializer` is not null diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java index f14771637a6..927eb40b604 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java @@ -17,7 +17,6 @@ package org.jetbrains.kotlin.descriptors.impl; import kotlin.annotations.jvm.ReadOnly; -import kotlin.collections.CollectionsKt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.descriptors.*; @@ -525,8 +524,8 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp substitutedDescriptor.setOverriddenDescriptors(overridden); } - if (isConst() && compileTimeInitializer != null) { - substitutedDescriptor.setCompileTimeInitializer(compileTimeInitializer); + if (isConst() && compileTimeInitializerFactory != null) { + substitutedDescriptor.setCompileTimeInitializer(compileTimeInitializer, compileTimeInitializerFactory); } return substitutedDescriptor; diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ValueParameterDescriptorImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ValueParameterDescriptorImpl.kt index 2c7b1d9096c..787dbbabec5 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ValueParameterDescriptorImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ValueParameterDescriptorImpl.kt @@ -113,6 +113,9 @@ open class ValueParameterDescriptorImpl( override fun isVar() = false override fun getCompileTimeInitializer() = null + + override fun cleanCompileTimeInitializerCache() {} + override fun copy(newOwner: CallableDescriptor, newName: Name, newIndex: Int): ValueParameterDescriptor { return ValueParameterDescriptorImpl( newOwner, null, newIndex, annotations, newName, type, declaresDefaultValue(), diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/VariableDescriptorWithInitializerImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/VariableDescriptorWithInitializerImpl.java index ee8e31d64b5..d124ee989ab 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/VariableDescriptorWithInitializerImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/VariableDescriptorWithInitializerImpl.java @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.descriptors.impl; +import kotlin.jvm.functions.Function0; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; @@ -30,6 +31,7 @@ public abstract class VariableDescriptorWithInitializerImpl extends VariableDesc private final boolean isVar; protected NullableLazyValue> compileTimeInitializer; + protected Function0>> compileTimeInitializerFactory; public VariableDescriptorWithInitializerImpl( @NotNull DeclarationDescriptor containingDeclaration, @@ -58,8 +60,22 @@ public abstract class VariableDescriptorWithInitializerImpl extends VariableDesc return null; } - public void setCompileTimeInitializer(@NotNull NullableLazyValue> compileTimeInitializer) { + public void setCompileTimeInitializerFactory(@NotNull Function0>> compileTimeInitializerFactory) { assert !isVar() : "Constant value for variable initializer should be recorded only for final variables: " + getName(); - this.compileTimeInitializer = compileTimeInitializer; + setCompileTimeInitializer(null, compileTimeInitializerFactory); + } + + public void setCompileTimeInitializer( + @Nullable NullableLazyValue> compileTimeInitializer, + @NotNull Function0>> compileTimeInitializerFactory + ) { + assert !isVar() : "Constant value for variable initializer should be recorded only for final variables: " + getName(); + this.compileTimeInitializerFactory = compileTimeInitializerFactory; + this.compileTimeInitializer = compileTimeInitializer != null ? compileTimeInitializer : compileTimeInitializerFactory.invoke(); + } + + @Override + public void cleanCompileTimeInitializerCache() { + this.compileTimeInitializer = compileTimeInitializerFactory.invoke(); } } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt index c2e1a0a70fe..64e61f086a6 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt @@ -132,12 +132,12 @@ class MemberDeserializer(private val c: DeserializationContext) { } if (Flags.HAS_CONSTANT.get(flags)) { - property.setCompileTimeInitializer( + property.setCompileTimeInitializerFactory { c.storageManager.createNullableLazyValue { val container = c.containingDeclaration.asProtoContainer()!! c.components.annotationAndConstantLoader.loadPropertyConstant(container, proto, property.returnType) } - ) + } } if ((c.containingDeclaration as? ClassDescriptor)?.kind == ClassKind.ANNOTATION_CLASS) {