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:
@@ -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
|
||||
|
||||
+13
-23
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
-5
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user