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 StorageManager storageManager;
|
||||||
private final KotlinBuiltIns builtIns;
|
private final KotlinBuiltIns builtIns;
|
||||||
private final SupertypeLoopChecker supertypeLoopsResolver;
|
private final SupertypeLoopChecker supertypeLoopsResolver;
|
||||||
private final VariableTypeResolver variableTypeResolver;
|
private final VariableTypeAndInitializerResolver variableTypeAndInitializerResolver;
|
||||||
private final ExpressionTypingServices expressionTypingServices;
|
private final ExpressionTypingServices expressionTypingServices;
|
||||||
private final OverloadChecker overloadChecker;
|
private final OverloadChecker overloadChecker;
|
||||||
private final LanguageVersionSettings languageVersionSettings;
|
private final LanguageVersionSettings languageVersionSettings;
|
||||||
@@ -88,7 +88,7 @@ public class DescriptorResolver {
|
|||||||
@NotNull StorageManager storageManager,
|
@NotNull StorageManager storageManager,
|
||||||
@NotNull TypeResolver typeResolver,
|
@NotNull TypeResolver typeResolver,
|
||||||
@NotNull SupertypeLoopChecker supertypeLoopsResolver,
|
@NotNull SupertypeLoopChecker supertypeLoopsResolver,
|
||||||
@NotNull VariableTypeResolver variableTypeResolver,
|
@NotNull VariableTypeAndInitializerResolver variableTypeAndInitializerResolver,
|
||||||
@NotNull ExpressionTypingServices expressionTypingServices,
|
@NotNull ExpressionTypingServices expressionTypingServices,
|
||||||
@NotNull OverloadChecker overloadChecker,
|
@NotNull OverloadChecker overloadChecker,
|
||||||
@NotNull LanguageVersionSettings languageVersionSettings,
|
@NotNull LanguageVersionSettings languageVersionSettings,
|
||||||
@@ -101,7 +101,7 @@ public class DescriptorResolver {
|
|||||||
this.storageManager = storageManager;
|
this.storageManager = storageManager;
|
||||||
this.typeResolver = typeResolver;
|
this.typeResolver = typeResolver;
|
||||||
this.supertypeLoopsResolver = supertypeLoopsResolver;
|
this.supertypeLoopsResolver = supertypeLoopsResolver;
|
||||||
this.variableTypeResolver = variableTypeResolver;
|
this.variableTypeAndInitializerResolver = variableTypeAndInitializerResolver;
|
||||||
this.expressionTypingServices = expressionTypingServices;
|
this.expressionTypingServices = expressionTypingServices;
|
||||||
this.overloadChecker = overloadChecker;
|
this.overloadChecker = overloadChecker;
|
||||||
this.languageVersionSettings = languageVersionSettings;
|
this.languageVersionSettings = languageVersionSettings;
|
||||||
@@ -813,11 +813,16 @@ public class DescriptorResolver {
|
|||||||
ReceiverParameterDescriptor receiverDescriptor =
|
ReceiverParameterDescriptor receiverDescriptor =
|
||||||
DescriptorFactory.createExtensionReceiverParameterForCallable(propertyDescriptor, receiverType);
|
DescriptorFactory.createExtensionReceiverParameterForCallable(propertyDescriptor, receiverType);
|
||||||
|
|
||||||
KotlinType type = variableTypeResolver.process(
|
LexicalScope scopeForInitializer = ScopeUtils.makeScopeForPropertyInitializer(scopeWithTypeParameters, propertyDescriptor);
|
||||||
propertyDescriptor, ScopeUtils.makeScopeForPropertyInitializer(scopeWithTypeParameters, propertyDescriptor),
|
KotlinType type = variableTypeAndInitializerResolver.resolveType(
|
||||||
|
propertyDescriptor, scopeForInitializer,
|
||||||
property, dataFlowInfo, true, trace
|
property, dataFlowInfo, true, trace
|
||||||
);
|
);
|
||||||
|
|
||||||
|
variableTypeAndInitializerResolver.setConstantForVariableIfNeeded(
|
||||||
|
propertyDescriptor, scopeForInitializer, property, dataFlowInfo, type, trace
|
||||||
|
);
|
||||||
|
|
||||||
propertyDescriptor.setType(type, typeParameterDescriptors, getDispatchReceiverParameterIfNeeded(containingDeclaration),
|
propertyDescriptor.setType(type, typeParameterDescriptors, getDispatchReceiverParameterIfNeeded(containingDeclaration),
|
||||||
receiverDescriptor);
|
receiverDescriptor);
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.*
|
|||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.VariableDescriptorWithInitializerImpl
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors.*
|
import org.jetbrains.kotlin.diagnostics.Errors.*
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtProperty
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
@@ -43,7 +44,7 @@ class LocalVariableResolver(
|
|||||||
private val identifierChecker: IdentifierChecker,
|
private val identifierChecker: IdentifierChecker,
|
||||||
private val dataFlowAnalyzer: DataFlowAnalyzer,
|
private val dataFlowAnalyzer: DataFlowAnalyzer,
|
||||||
private val annotationResolver: AnnotationResolver,
|
private val annotationResolver: AnnotationResolver,
|
||||||
private val variableTypeResolver: VariableTypeResolver,
|
private val variableTypeAndInitializerResolver: VariableTypeAndInitializerResolver,
|
||||||
private val delegatedPropertyResolver: DelegatedPropertyResolver,
|
private val delegatedPropertyResolver: DelegatedPropertyResolver,
|
||||||
private val languageVersionSettings: LanguageVersionSettings
|
private val languageVersionSettings: LanguageVersionSettings
|
||||||
) {
|
) {
|
||||||
@@ -132,7 +133,7 @@ class LocalVariableResolver(
|
|||||||
trace: BindingTrace
|
trace: BindingTrace
|
||||||
): VariableDescriptor {
|
): VariableDescriptor {
|
||||||
val containingDeclaration = scope.ownerDescriptor
|
val containingDeclaration = scope.ownerDescriptor
|
||||||
val result: VariableDescriptor
|
val result: VariableDescriptorWithInitializerImpl
|
||||||
val type: KotlinType
|
val type: KotlinType
|
||||||
if (KtPsiUtil.isScriptDeclaration(variable)) {
|
if (KtPsiUtil.isScriptDeclaration(variable)) {
|
||||||
val propertyDescriptor = PropertyDescriptorImpl.create(
|
val propertyDescriptor = PropertyDescriptorImpl.create(
|
||||||
@@ -148,7 +149,7 @@ class LocalVariableResolver(
|
|||||||
/* isConst = */ false
|
/* isConst = */ false
|
||||||
)
|
)
|
||||||
// For a local variable the type must not be deferred
|
// 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
|
val receiverParameter = (containingDeclaration as ScriptDescriptor).thisAsReceiverParameter
|
||||||
propertyDescriptor.setType(type, emptyList<TypeParameterDescriptor>(), receiverParameter, null as? KotlinType)
|
propertyDescriptor.setType(type, emptyList<TypeParameterDescriptor>(), receiverParameter, null as? KotlinType)
|
||||||
@@ -159,10 +160,11 @@ class LocalVariableResolver(
|
|||||||
else {
|
else {
|
||||||
val variableDescriptor = resolveLocalVariableDescriptorWithType(scope, variable, null, trace)
|
val variableDescriptor = resolveLocalVariableDescriptorWithType(scope, variable, null, trace)
|
||||||
// For a local variable the type must not be deferred
|
// 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)
|
variableDescriptor.setOutType(type)
|
||||||
result = variableDescriptor
|
result = variableDescriptor
|
||||||
}
|
}
|
||||||
|
variableTypeAndInitializerResolver.setConstantForVariableIfNeeded(result, scope, variable, dataFlowInfo, type, trace)
|
||||||
// Type annotations also should be resolved
|
// Type annotations also should be resolved
|
||||||
ForceResolveUtil.forceResolveAllContents(type.annotations)
|
ForceResolveUtil.forceResolveAllContents(type.annotations)
|
||||||
return result
|
return result
|
||||||
|
|||||||
+12
-22
@@ -36,7 +36,7 @@ import org.jetbrains.kotlin.types.TypeUtils
|
|||||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
|
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
|
||||||
import org.jetbrains.kotlin.types.expressions.PreliminaryDeclarationVisitor
|
import org.jetbrains.kotlin.types.expressions.PreliminaryDeclarationVisitor
|
||||||
|
|
||||||
class VariableTypeResolver(
|
class VariableTypeAndInitializerResolver(
|
||||||
private val storageManager: StorageManager,
|
private val storageManager: StorageManager,
|
||||||
private val expressionTypingServices: ExpressionTypingServices,
|
private val expressionTypingServices: ExpressionTypingServices,
|
||||||
private val typeResolver: TypeResolver,
|
private val typeResolver: TypeResolver,
|
||||||
@@ -44,7 +44,7 @@ class VariableTypeResolver(
|
|||||||
private val delegatedPropertyResolver: DelegatedPropertyResolver
|
private val delegatedPropertyResolver: DelegatedPropertyResolver
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun process(
|
fun resolveType(
|
||||||
variableDescriptor: VariableDescriptorWithInitializerImpl,
|
variableDescriptor: VariableDescriptorWithInitializerImpl,
|
||||||
scopeForInitializer: LexicalScope,
|
scopeForInitializer: LexicalScope,
|
||||||
variable: KtVariableDeclaration,
|
variable: KtVariableDeclaration,
|
||||||
@@ -55,12 +55,8 @@ class VariableTypeResolver(
|
|||||||
val propertyTypeRef = variable.typeReference
|
val propertyTypeRef = variable.typeReference
|
||||||
|
|
||||||
val hasDelegate = variable is KtProperty && variable.hasDelegateExpression()
|
val hasDelegate = variable is KtProperty && variable.hasDelegateExpression()
|
||||||
when {
|
return when {
|
||||||
propertyTypeRef != null -> {
|
propertyTypeRef != null -> typeResolver.resolveType(scopeForInitializer, propertyTypeRef, trace, true)
|
||||||
val type = typeResolver.resolveType(scopeForInitializer, propertyTypeRef, trace, true)
|
|
||||||
setConstantForVariableIfNeeded(variableDescriptor, scopeForInitializer, variable, dataFlowInfo, type, trace)
|
|
||||||
return type
|
|
||||||
}
|
|
||||||
!variable.hasInitializer() -> {
|
!variable.hasInitializer() -> {
|
||||||
if (hasDelegate && variableDescriptor is VariableDescriptorWithAccessors) {
|
if (hasDelegate && variableDescriptor is VariableDescriptorWithAccessors) {
|
||||||
val property = variable as KtProperty
|
val property = variable as KtProperty
|
||||||
@@ -80,25 +76,20 @@ class VariableTypeResolver(
|
|||||||
return ErrorUtils.createErrorType("No type, no body")
|
return ErrorUtils.createErrorType("No type, no body")
|
||||||
}
|
}
|
||||||
notLocal -> {
|
notLocal -> {
|
||||||
return DeferredType.createRecursionIntolerant(
|
DeferredType.createRecursionIntolerant(
|
||||||
storageManager,
|
storageManager,
|
||||||
trace
|
trace
|
||||||
) {
|
) {
|
||||||
PreliminaryDeclarationVisitor.createForDeclaration(variable, trace)
|
PreliminaryDeclarationVisitor.createForDeclaration(variable, trace)
|
||||||
val initializerType = resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace)
|
val initializerType = resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace)
|
||||||
setConstantForVariableIfNeeded(variableDescriptor, scopeForInitializer, variable, dataFlowInfo, initializerType, trace)
|
|
||||||
transformAnonymousTypeIfNeeded(variableDescriptor, variable, initializerType, trace)
|
transformAnonymousTypeIfNeeded(variableDescriptor, variable, initializerType, trace)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace)
|
||||||
val initializerType = resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace)
|
|
||||||
setConstantForVariableIfNeeded(variableDescriptor, scopeForInitializer, variable, dataFlowInfo, initializerType, trace)
|
|
||||||
return initializerType
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setConstantForVariableIfNeeded(
|
fun setConstantForVariableIfNeeded(
|
||||||
variableDescriptor: VariableDescriptorWithInitializerImpl,
|
variableDescriptor: VariableDescriptorWithInitializerImpl,
|
||||||
scope: LexicalScope,
|
scope: LexicalScope,
|
||||||
variable: KtVariableDeclaration,
|
variable: KtVariableDeclaration,
|
||||||
@@ -106,17 +97,16 @@ class VariableTypeResolver(
|
|||||||
variableType: KotlinType,
|
variableType: KotlinType,
|
||||||
trace: BindingTrace
|
trace: BindingTrace
|
||||||
) {
|
) {
|
||||||
if (!DescriptorUtils.shouldRecordInitializerForProperty(variableDescriptor, variableType)) return
|
if (!variable.hasInitializer() || variable.isVar) return
|
||||||
|
|
||||||
if (!variable.hasInitializer()) return
|
|
||||||
|
|
||||||
variableDescriptor.setCompileTimeInitializer(
|
variableDescriptor.setCompileTimeInitializer(
|
||||||
storageManager.createRecursionTolerantNullableLazyValue(
|
storageManager.createRecursionTolerantNullableLazyValue(
|
||||||
{
|
computeInitializer@{
|
||||||
|
if (!DescriptorUtils.shouldRecordInitializerForProperty(variableDescriptor, variableType)) return@computeInitializer null
|
||||||
|
|
||||||
val initializer = variable.initializer
|
val initializer = variable.initializer
|
||||||
val initializerType = expressionTypingServices.safeGetType(scope, initializer!!, variableType, dataFlowInfo, trace)
|
val initializerType = expressionTypingServices.safeGetType(scope, initializer!!, variableType, dataFlowInfo, trace)
|
||||||
val constant = constantExpressionEvaluator.evaluateExpression(initializer, trace, initializerType)
|
val constant = constantExpressionEvaluator.evaluateExpression(initializer, trace, initializerType)
|
||||||
?: return@createRecursionTolerantNullableLazyValue null
|
?: return@computeInitializer null
|
||||||
|
|
||||||
if (constant.usesNonConstValAsConstant && variableDescriptor.isConst) {
|
if (constant.usesNonConstValAsConstant && variableDescriptor.isConst) {
|
||||||
trace.report(Errors.NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION.on(initializer))
|
trace.report(Errors.NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION.on(initializer))
|
||||||
-5
@@ -52,11 +52,6 @@ public abstract class VariableDescriptorWithInitializerImpl extends VariableDesc
|
|||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public ConstantValue<?> getCompileTimeInitializer() {
|
public ConstantValue<?> getCompileTimeInitializer() {
|
||||||
// Force computation and setting of compileTimeInitializer, if needed
|
|
||||||
if (compileTimeInitializer == null) {
|
|
||||||
outType.getConstructor();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (compileTimeInitializer != null) {
|
if (compileTimeInitializer != null) {
|
||||||
return compileTimeInitializer.invoke();
|
return compileTimeInitializer.invoke();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user