Fix typechecker when initializer of destructuring declaration is unresolved or missing
This commit is contained in:
+9
-7
@@ -42,14 +42,14 @@ class DestructuringDeclarationResolver(
|
||||
fun defineLocalVariablesFromMultiDeclaration(
|
||||
writableScope: LexicalWritableScope,
|
||||
destructuringDeclaration: KtDestructuringDeclaration,
|
||||
receiver: ReceiverValue,
|
||||
reportErrorsOn: KtExpression,
|
||||
receiver: ReceiverValue?,
|
||||
initializer: KtExpression?,
|
||||
context: ExpressionTypingContext
|
||||
) {
|
||||
for ((componentIndex, entry) in destructuringDeclaration.entries.withIndex()) {
|
||||
val componentName = createComponentName(componentIndex + 1)
|
||||
|
||||
val componentType = resolveComponentFunctionAndGetType(componentName, context, entry, receiver, reportErrorsOn)
|
||||
val componentType = resolveComponentFunctionAndGetType(componentName, context, entry, receiver, initializer)
|
||||
val variableDescriptor = localVariableResolver.resolveLocalVariableDescriptorWithType(writableScope, entry, componentType, context.trace)
|
||||
|
||||
ExpressionTypingUtils.checkVariableShadowing(writableScope, context.trace, variableDescriptor)
|
||||
@@ -62,15 +62,17 @@ class DestructuringDeclarationResolver(
|
||||
componentName: Name,
|
||||
context: ExpressionTypingContext,
|
||||
entry: KtDestructuringDeclarationEntry,
|
||||
receiver: ReceiverValue,
|
||||
reportErrorsOn: KtExpression
|
||||
receiver: ReceiverValue?,
|
||||
initializer: KtExpression?
|
||||
): KotlinType {
|
||||
fun errorType() = ErrorUtils.createErrorType("$componentName() return type")
|
||||
|
||||
if (receiver == null || initializer == null) return errorType()
|
||||
|
||||
val expectedType = getExpectedTypeForComponent(context, entry)
|
||||
val results = fakeCallResolver.resolveFakeCall(
|
||||
context.replaceExpectedType(expectedType), receiver, componentName,
|
||||
entry, reportErrorsOn, FakeCallKind.COMPONENT
|
||||
entry, initializer, FakeCallKind.COMPONENT
|
||||
)
|
||||
|
||||
if (!results.isSuccess) {
|
||||
@@ -85,7 +87,7 @@ class DestructuringDeclarationResolver(
|
||||
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))
|
||||
context.trace.report(Errors.COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH.on(initializer, componentName, functionReturnType, expectedType))
|
||||
}
|
||||
return functionReturnType ?: errorType()
|
||||
}
|
||||
|
||||
+12
-8
@@ -117,19 +117,23 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
KtExpression initializer = multiDeclaration.getInitializer();
|
||||
if (initializer == null) {
|
||||
context.trace.report(INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION.on(multiDeclaration));
|
||||
return TypeInfoFactoryKt.noTypeInfo(context);
|
||||
}
|
||||
ExpressionReceiver expressionReceiver = ExpressionTypingUtils.getExpressionReceiver(
|
||||
facade, initializer, context.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT));
|
||||
KotlinTypeInfo typeInfo = facade.getTypeInfo(initializer, context);
|
||||
if (expressionReceiver == null) {
|
||||
return TypeInfoFactoryKt.noTypeInfo(context);
|
||||
}
|
||||
|
||||
ExpressionReceiver expressionReceiver = initializer != null ? ExpressionTypingUtils.getExpressionReceiver(
|
||||
facade, initializer, context.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT)) : null;
|
||||
|
||||
components.destructuringDeclarationResolver
|
||||
.defineLocalVariablesFromMultiDeclaration(scope, multiDeclaration, expressionReceiver, initializer, context);
|
||||
components.modifiersChecker.withTrace(context.trace).checkModifiersForDestructuringDeclaration(multiDeclaration);
|
||||
components.identifierChecker.checkDeclaration(multiDeclaration, context.trace);
|
||||
return typeInfo.replaceType(components.dataFlowAnalyzer.checkStatementType(multiDeclaration, context));
|
||||
|
||||
if (expressionReceiver == null) {
|
||||
return TypeInfoFactoryKt.noTypeInfo(context);
|
||||
}
|
||||
else {
|
||||
return facade.getTypeInfo(initializer, context)
|
||||
.replaceType(components.dataFlowAnalyzer.checkStatementType(multiDeclaration, context));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fun useDeclaredVariables() {
|
||||
val (a, b) = <!UNRESOLVED_REFERENCE!>unresolved<!>
|
||||
<!UNUSED_EXPRESSION, DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>a<!>
|
||||
<!UNUSED_EXPRESSION, DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>b<!>
|
||||
}
|
||||
|
||||
fun checkersShouldRun() {
|
||||
val (@A <!UNUSED_VARIABLE!>a<!>, <!UNDERSCORE_IS_RESERVED, UNUSED_VARIABLE!>_<!>) = <!UNRESOLVED_REFERENCE!>unresolved<!>
|
||||
}
|
||||
|
||||
annotation class A
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package
|
||||
|
||||
public fun checkersShouldRun(): kotlin.Unit
|
||||
public fun useDeclaredVariables(): kotlin.Unit
|
||||
|
||||
public final annotation class A : kotlin.Annotation {
|
||||
public constructor A()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fun useDeclaredVariables() {
|
||||
<!INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION!>val (a, b)<!>
|
||||
<!UNUSED_EXPRESSION, DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>a<!>
|
||||
<!UNUSED_EXPRESSION, DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>b<!>
|
||||
}
|
||||
|
||||
fun checkersShouldRun() {
|
||||
<!INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION!>val (@A <!UNUSED_VARIABLE!>a<!>, <!UNDERSCORE_IS_RESERVED, UNUSED_VARIABLE!>_<!>)<!>
|
||||
}
|
||||
|
||||
annotation class A
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package
|
||||
|
||||
public fun checkersShouldRun(): kotlin.Unit
|
||||
public fun useDeclaredVariables(): kotlin.Unit
|
||||
|
||||
public final annotation class A : kotlin.Annotation {
|
||||
public constructor A()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -4463,6 +4463,18 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("multiDeclarationAssignedUnresolved.kt")
|
||||
public void testMultiDeclarationAssignedUnresolved() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/declarationChecks/multiDeclarations/multiDeclarationAssignedUnresolved.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("multiDeclarationMissingInitializer.kt")
|
||||
public void testMultiDeclarationMissingInitializer() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/declarationChecks/multiDeclarations/multiDeclarationMissingInitializer.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("RedeclarationInForLoop.kt")
|
||||
public void testRedeclarationInForLoop() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/declarationChecks/multiDeclarations/RedeclarationInForLoop.kt");
|
||||
|
||||
Reference in New Issue
Block a user