Minor: refactor DestructuringDeclarationResolver
This commit is contained in:
+34
-19
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.types.expressions
|
package org.jetbrains.kotlin.types.expressions
|
||||||
|
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
|
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry
|
import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
@@ -48,25 +49,7 @@ class DestructuringDeclarationResolver(
|
|||||||
for ((componentIndex, entry) in destructuringDeclaration.entries.withIndex()) {
|
for ((componentIndex, entry) in destructuringDeclaration.entries.withIndex()) {
|
||||||
val componentName = createComponentName(componentIndex + 1)
|
val componentName = createComponentName(componentIndex + 1)
|
||||||
|
|
||||||
val expectedType = getExpectedTypeForComponent(context, entry)
|
val componentType = resolveComponentFunctionAndGetType(componentName, context, entry, receiver, reportErrorsOn)
|
||||||
val results = fakeCallResolver.resolveFakeCall(context.replaceExpectedType(expectedType), receiver, componentName,
|
|
||||||
entry, reportErrorsOn, FakeCallKind.COMPONENT)
|
|
||||||
|
|
||||||
var componentType: KotlinType? = null
|
|
||||||
if (results.isSuccess) {
|
|
||||||
context.trace.record(BindingContext.COMPONENT_RESOLVED_CALL, entry, results.resultingCall)
|
|
||||||
|
|
||||||
val functionDescriptor = results.resultingDescriptor
|
|
||||||
symbolUsageValidator.validateCall(null, functionDescriptor, context.trace, entry)
|
|
||||||
|
|
||||||
componentType = functionDescriptor.returnType
|
|
||||||
if (componentType != null && !TypeUtils.noExpectedType(expectedType) && !KotlinTypeChecker.DEFAULT.isSubtypeOf(componentType, expectedType)) {
|
|
||||||
context.trace.report(Errors.COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH.on(reportErrorsOn, componentName, componentType, expectedType))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (componentType == null) {
|
|
||||||
componentType = ErrorUtils.createErrorType("$componentName() return type")
|
|
||||||
}
|
|
||||||
val variableDescriptor = localVariableResolver.resolveLocalVariableDescriptorWithType(writableScope, entry, componentType, context.trace)
|
val variableDescriptor = localVariableResolver.resolveLocalVariableDescriptorWithType(writableScope, entry, componentType, context.trace)
|
||||||
|
|
||||||
ExpressionTypingUtils.checkVariableShadowing(writableScope, context.trace, variableDescriptor)
|
ExpressionTypingUtils.checkVariableShadowing(writableScope, context.trace, variableDescriptor)
|
||||||
@@ -75,6 +58,38 @@ class DestructuringDeclarationResolver(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun resolveComponentFunctionAndGetType(
|
||||||
|
componentName: Name,
|
||||||
|
context: ExpressionTypingContext,
|
||||||
|
entry: KtDestructuringDeclarationEntry,
|
||||||
|
receiver: ReceiverValue,
|
||||||
|
reportErrorsOn: KtExpression
|
||||||
|
): KotlinType {
|
||||||
|
fun errorType() = ErrorUtils.createErrorType("$componentName() return type")
|
||||||
|
|
||||||
|
val expectedType = getExpectedTypeForComponent(context, entry)
|
||||||
|
val results = fakeCallResolver.resolveFakeCall(
|
||||||
|
context.replaceExpectedType(expectedType), receiver, componentName,
|
||||||
|
entry, reportErrorsOn, FakeCallKind.COMPONENT
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!results.isSuccess) {
|
||||||
|
return errorType()
|
||||||
|
}
|
||||||
|
|
||||||
|
context.trace.record(BindingContext.COMPONENT_RESOLVED_CALL, entry, results.resultingCall)
|
||||||
|
|
||||||
|
val functionDescriptor = results.resultingDescriptor
|
||||||
|
symbolUsageValidator.validateCall(null, functionDescriptor, context.trace, entry)
|
||||||
|
|
||||||
|
val functionReturnType = functionDescriptor.returnType
|
||||||
|
if (functionReturnType != null && !TypeUtils.noExpectedType(expectedType)
|
||||||
|
&& !KotlinTypeChecker.DEFAULT.isSubtypeOf(functionReturnType, expectedType) ) {
|
||||||
|
context.trace.report(Errors.COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH.on(reportErrorsOn, componentName, functionReturnType, expectedType))
|
||||||
|
}
|
||||||
|
return functionReturnType ?: errorType()
|
||||||
|
}
|
||||||
|
|
||||||
private fun getExpectedTypeForComponent(context: ExpressionTypingContext, entry: KtDestructuringDeclarationEntry): KotlinType {
|
private fun getExpectedTypeForComponent(context: ExpressionTypingContext, entry: KtDestructuringDeclarationEntry): KotlinType {
|
||||||
val entryTypeRef = entry.typeReference ?: return TypeUtils.NO_EXPECTED_TYPE
|
val entryTypeRef = entry.typeReference ?: return TypeUtils.NO_EXPECTED_TYPE
|
||||||
return typeResolver.resolveType(context.scope, entryTypeRef, context.trace, true)
|
return typeResolver.resolveType(context.scope, entryTypeRef, context.trace, true)
|
||||||
|
|||||||
Reference in New Issue
Block a user