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(
|
fun defineLocalVariablesFromMultiDeclaration(
|
||||||
writableScope: LexicalWritableScope,
|
writableScope: LexicalWritableScope,
|
||||||
destructuringDeclaration: KtDestructuringDeclaration,
|
destructuringDeclaration: KtDestructuringDeclaration,
|
||||||
receiver: ReceiverValue,
|
receiver: ReceiverValue?,
|
||||||
reportErrorsOn: KtExpression,
|
initializer: KtExpression?,
|
||||||
context: ExpressionTypingContext
|
context: ExpressionTypingContext
|
||||||
) {
|
) {
|
||||||
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 componentType = resolveComponentFunctionAndGetType(componentName, context, entry, receiver, reportErrorsOn)
|
val componentType = resolveComponentFunctionAndGetType(componentName, context, entry, receiver, initializer)
|
||||||
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)
|
||||||
@@ -62,15 +62,17 @@ class DestructuringDeclarationResolver(
|
|||||||
componentName: Name,
|
componentName: Name,
|
||||||
context: ExpressionTypingContext,
|
context: ExpressionTypingContext,
|
||||||
entry: KtDestructuringDeclarationEntry,
|
entry: KtDestructuringDeclarationEntry,
|
||||||
receiver: ReceiverValue,
|
receiver: ReceiverValue?,
|
||||||
reportErrorsOn: KtExpression
|
initializer: KtExpression?
|
||||||
): KotlinType {
|
): KotlinType {
|
||||||
fun errorType() = ErrorUtils.createErrorType("$componentName() return type")
|
fun errorType() = ErrorUtils.createErrorType("$componentName() return type")
|
||||||
|
|
||||||
|
if (receiver == null || initializer == null) return errorType()
|
||||||
|
|
||||||
val expectedType = getExpectedTypeForComponent(context, entry)
|
val expectedType = getExpectedTypeForComponent(context, entry)
|
||||||
val results = fakeCallResolver.resolveFakeCall(
|
val results = fakeCallResolver.resolveFakeCall(
|
||||||
context.replaceExpectedType(expectedType), receiver, componentName,
|
context.replaceExpectedType(expectedType), receiver, componentName,
|
||||||
entry, reportErrorsOn, FakeCallKind.COMPONENT
|
entry, initializer, FakeCallKind.COMPONENT
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!results.isSuccess) {
|
if (!results.isSuccess) {
|
||||||
@@ -85,7 +87,7 @@ class DestructuringDeclarationResolver(
|
|||||||
val functionReturnType = functionDescriptor.returnType
|
val functionReturnType = functionDescriptor.returnType
|
||||||
if (functionReturnType != null && !TypeUtils.noExpectedType(expectedType)
|
if (functionReturnType != null && !TypeUtils.noExpectedType(expectedType)
|
||||||
&& !KotlinTypeChecker.DEFAULT.isSubtypeOf(functionReturnType, 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()
|
return functionReturnType ?: errorType()
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-8
@@ -117,19 +117,23 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
|||||||
KtExpression initializer = multiDeclaration.getInitializer();
|
KtExpression initializer = multiDeclaration.getInitializer();
|
||||||
if (initializer == null) {
|
if (initializer == null) {
|
||||||
context.trace.report(INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION.on(multiDeclaration));
|
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
|
components.destructuringDeclarationResolver
|
||||||
.defineLocalVariablesFromMultiDeclaration(scope, multiDeclaration, expressionReceiver, initializer, context);
|
.defineLocalVariablesFromMultiDeclaration(scope, multiDeclaration, expressionReceiver, initializer, context);
|
||||||
components.modifiersChecker.withTrace(context.trace).checkModifiersForDestructuringDeclaration(multiDeclaration);
|
components.modifiersChecker.withTrace(context.trace).checkModifiersForDestructuringDeclaration(multiDeclaration);
|
||||||
components.identifierChecker.checkDeclaration(multiDeclaration, context.trace);
|
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
|
@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);
|
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")
|
@TestMetadata("RedeclarationInForLoop.kt")
|
||||||
public void testRedeclarationInForLoop() throws Exception {
|
public void testRedeclarationInForLoop() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/declarationChecks/multiDeclarations/RedeclarationInForLoop.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/declarationChecks/multiDeclarations/RedeclarationInForLoop.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user