Minor. Split method VariableTypeResolver.process

It looks much natural to differ type resolution and setting
compile time initializer to descriptor
This commit is contained in:
Denis Zharkov
2016-11-10 13:42:46 +03:00
parent bce023c8ad
commit e21ecbe702
4 changed files with 29 additions and 37 deletions
@@ -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);
@@ -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<TypeParameterDescriptor>(), 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
@@ -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)
}
}
}
@@ -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();
}