From e21ecbe702f343fb9d1ca8fb094f68620062ba0b Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Thu, 10 Nov 2016 13:42:46 +0300 Subject: [PATCH] Minor. Split method VariableTypeResolver.process It looks much natural to differ type resolution and setting compile time initializer to descriptor --- .../kotlin/resolve/DescriptorResolver.java | 15 +++++--- .../kotlin/resolve/LocalVariableResolver.kt | 10 +++--- ... => VariableTypeAndInitializerResolver.kt} | 36 +++++++------------ ...VariableDescriptorWithInitializerImpl.java | 5 --- 4 files changed, 29 insertions(+), 37 deletions(-) rename compiler/frontend/src/org/jetbrains/kotlin/resolve/{VariableTypeResolver.kt => VariableTypeAndInitializerResolver.kt} (83%) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java index 983d446a9fa..a141ba180fc 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java @@ -74,7 +74,7 @@ public class DescriptorResolver { private final StorageManager storageManager; private final KotlinBuiltIns builtIns; private final SupertypeLoopChecker supertypeLoopsResolver; - private final VariableTypeResolver variableTypeResolver; + private final VariableTypeAndInitializerResolver variableTypeAndInitializerResolver; private final ExpressionTypingServices expressionTypingServices; private final OverloadChecker overloadChecker; private final LanguageVersionSettings languageVersionSettings; @@ -88,7 +88,7 @@ public class DescriptorResolver { @NotNull StorageManager storageManager, @NotNull TypeResolver typeResolver, @NotNull SupertypeLoopChecker supertypeLoopsResolver, - @NotNull VariableTypeResolver variableTypeResolver, + @NotNull VariableTypeAndInitializerResolver variableTypeAndInitializerResolver, @NotNull ExpressionTypingServices expressionTypingServices, @NotNull OverloadChecker overloadChecker, @NotNull LanguageVersionSettings languageVersionSettings, @@ -101,7 +101,7 @@ public class DescriptorResolver { this.storageManager = storageManager; this.typeResolver = typeResolver; this.supertypeLoopsResolver = supertypeLoopsResolver; - this.variableTypeResolver = variableTypeResolver; + this.variableTypeAndInitializerResolver = variableTypeAndInitializerResolver; this.expressionTypingServices = expressionTypingServices; this.overloadChecker = overloadChecker; this.languageVersionSettings = languageVersionSettings; @@ -813,11 +813,16 @@ public class DescriptorResolver { ReceiverParameterDescriptor receiverDescriptor = DescriptorFactory.createExtensionReceiverParameterForCallable(propertyDescriptor, receiverType); - KotlinType type = variableTypeResolver.process( - propertyDescriptor, ScopeUtils.makeScopeForPropertyInitializer(scopeWithTypeParameters, propertyDescriptor), + LexicalScope scopeForInitializer = ScopeUtils.makeScopeForPropertyInitializer(scopeWithTypeParameters, propertyDescriptor); + KotlinType type = variableTypeAndInitializerResolver.resolveType( + propertyDescriptor, scopeForInitializer, property, dataFlowInfo, true, trace ); + variableTypeAndInitializerResolver.setConstantForVariableIfNeeded( + propertyDescriptor, scopeForInitializer, property, dataFlowInfo, type, trace + ); + propertyDescriptor.setType(type, typeParameterDescriptors, getDispatchReceiverParameterIfNeeded(containingDeclaration), receiverDescriptor); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/LocalVariableResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/LocalVariableResolver.kt index 2e5896e80c5..0ee67c8aa8b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/LocalVariableResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/LocalVariableResolver.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl +import org.jetbrains.kotlin.descriptors.impl.VariableDescriptorWithInitializerImpl import org.jetbrains.kotlin.diagnostics.Errors.* import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtProperty @@ -43,7 +44,7 @@ class LocalVariableResolver( private val identifierChecker: IdentifierChecker, private val dataFlowAnalyzer: DataFlowAnalyzer, private val annotationResolver: AnnotationResolver, - private val variableTypeResolver: VariableTypeResolver, + private val variableTypeAndInitializerResolver: VariableTypeAndInitializerResolver, private val delegatedPropertyResolver: DelegatedPropertyResolver, private val languageVersionSettings: LanguageVersionSettings ) { @@ -132,7 +133,7 @@ class LocalVariableResolver( trace: BindingTrace ): VariableDescriptor { val containingDeclaration = scope.ownerDescriptor - val result: VariableDescriptor + val result: VariableDescriptorWithInitializerImpl val type: KotlinType if (KtPsiUtil.isScriptDeclaration(variable)) { val propertyDescriptor = PropertyDescriptorImpl.create( @@ -148,7 +149,7 @@ class LocalVariableResolver( /* isConst = */ false ) // For a local variable the type must not be deferred - type = variableTypeResolver.process(propertyDescriptor, scope, variable, dataFlowInfo, false, trace) + type = variableTypeAndInitializerResolver.resolveType(propertyDescriptor, scope, variable, dataFlowInfo, false, trace) val receiverParameter = (containingDeclaration as ScriptDescriptor).thisAsReceiverParameter propertyDescriptor.setType(type, emptyList(), receiverParameter, null as? KotlinType) @@ -159,10 +160,11 @@ class LocalVariableResolver( else { val variableDescriptor = resolveLocalVariableDescriptorWithType(scope, variable, null, trace) // For a local variable the type must not be deferred - type = variableTypeResolver.process(variableDescriptor, scope, variable, dataFlowInfo, false, trace) + type = variableTypeAndInitializerResolver.resolveType(variableDescriptor, scope, variable, dataFlowInfo, false, trace) variableDescriptor.setOutType(type) result = variableDescriptor } + variableTypeAndInitializerResolver.setConstantForVariableIfNeeded(result, scope, variable, dataFlowInfo, type, trace) // Type annotations also should be resolved ForceResolveUtil.forceResolveAllContents(type.annotations) return result diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt similarity index 83% rename from compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeResolver.kt rename to compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt index ff9ef83c0f0..6c5f4a82a23 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt @@ -36,7 +36,7 @@ import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices import org.jetbrains.kotlin.types.expressions.PreliminaryDeclarationVisitor -class VariableTypeResolver( +class VariableTypeAndInitializerResolver( private val storageManager: StorageManager, private val expressionTypingServices: ExpressionTypingServices, private val typeResolver: TypeResolver, @@ -44,7 +44,7 @@ class VariableTypeResolver( private val delegatedPropertyResolver: DelegatedPropertyResolver ) { - fun process( + fun resolveType( variableDescriptor: VariableDescriptorWithInitializerImpl, scopeForInitializer: LexicalScope, variable: KtVariableDeclaration, @@ -55,12 +55,8 @@ class VariableTypeResolver( val propertyTypeRef = variable.typeReference val hasDelegate = variable is KtProperty && variable.hasDelegateExpression() - when { - propertyTypeRef != null -> { - val type = typeResolver.resolveType(scopeForInitializer, propertyTypeRef, trace, true) - setConstantForVariableIfNeeded(variableDescriptor, scopeForInitializer, variable, dataFlowInfo, type, trace) - return type - } + return when { + propertyTypeRef != null -> typeResolver.resolveType(scopeForInitializer, propertyTypeRef, trace, true) !variable.hasInitializer() -> { if (hasDelegate && variableDescriptor is VariableDescriptorWithAccessors) { val property = variable as KtProperty @@ -80,25 +76,20 @@ class VariableTypeResolver( return ErrorUtils.createErrorType("No type, no body") } notLocal -> { - return DeferredType.createRecursionIntolerant( + DeferredType.createRecursionIntolerant( storageManager, trace ) { PreliminaryDeclarationVisitor.createForDeclaration(variable, trace) val initializerType = resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace) - setConstantForVariableIfNeeded(variableDescriptor, scopeForInitializer, variable, dataFlowInfo, initializerType, trace) transformAnonymousTypeIfNeeded(variableDescriptor, variable, initializerType, trace) } } - else -> { - val initializerType = resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace) - setConstantForVariableIfNeeded(variableDescriptor, scopeForInitializer, variable, dataFlowInfo, initializerType, trace) - return initializerType - } + else -> resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace) } } - private fun setConstantForVariableIfNeeded( + fun setConstantForVariableIfNeeded( variableDescriptor: VariableDescriptorWithInitializerImpl, scope: LexicalScope, variable: KtVariableDeclaration, @@ -106,17 +97,16 @@ class VariableTypeResolver( variableType: KotlinType, trace: BindingTrace ) { - if (!DescriptorUtils.shouldRecordInitializerForProperty(variableDescriptor, variableType)) return - - if (!variable.hasInitializer()) return - + if (!variable.hasInitializer() || variable.isVar) return variableDescriptor.setCompileTimeInitializer( storageManager.createRecursionTolerantNullableLazyValue( - { + computeInitializer@{ + if (!DescriptorUtils.shouldRecordInitializerForProperty(variableDescriptor, variableType)) return@computeInitializer null + val initializer = variable.initializer val initializerType = expressionTypingServices.safeGetType(scope, initializer!!, variableType, dataFlowInfo, trace) val constant = constantExpressionEvaluator.evaluateExpression(initializer, trace, initializerType) - ?: return@createRecursionTolerantNullableLazyValue null + ?: return@computeInitializer null if (constant.usesNonConstValAsConstant && variableDescriptor.isConst) { trace.report(Errors.NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION.on(initializer)) @@ -158,4 +148,4 @@ class VariableTypeResolver( ): KotlinType { return expressionTypingServices.safeGetType(scope, initializer, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo, trace) } -} \ No newline at end of file +} 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 bcb5cdfb52d..ee8e31d64b5 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/VariableDescriptorWithInitializerImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/VariableDescriptorWithInitializerImpl.java @@ -52,11 +52,6 @@ public abstract class VariableDescriptorWithInitializerImpl extends VariableDesc @Nullable @Override public ConstantValue getCompileTimeInitializer() { - // Force computation and setting of compileTimeInitializer, if needed - if (compileTimeInitializer == null) { - outType.getConstructor(); - } - if (compileTimeInitializer != null) { return compileTimeInitializer.invoke(); }