Report type mismatch for component functions
This commit is contained in:
@@ -100,9 +100,11 @@ public interface Errors {
|
|||||||
SimpleDiagnosticFactory<JetExpression> MANY_FUNCTION_LITERAL_ARGUMENTS = SimpleDiagnosticFactory.create(ERROR);
|
SimpleDiagnosticFactory<JetExpression> MANY_FUNCTION_LITERAL_ARGUMENTS = SimpleDiagnosticFactory.create(ERROR);
|
||||||
SimpleDiagnosticFactory<JetProperty> PROPERTY_WITH_NO_TYPE_NO_INITIALIZER = SimpleDiagnosticFactory.create(ERROR, NAMED_ELEMENT);
|
SimpleDiagnosticFactory<JetProperty> PROPERTY_WITH_NO_TYPE_NO_INITIALIZER = SimpleDiagnosticFactory.create(ERROR, NAMED_ELEMENT);
|
||||||
SimpleDiagnosticFactory<JetVariableDeclaration> VARIABLE_WITH_NO_TYPE_NO_INITIALIZER = SimpleDiagnosticFactory.create(ERROR, NAME_IDENTIFIER);
|
SimpleDiagnosticFactory<JetVariableDeclaration> VARIABLE_WITH_NO_TYPE_NO_INITIALIZER = SimpleDiagnosticFactory.create(ERROR, NAME_IDENTIFIER);
|
||||||
|
|
||||||
SimpleDiagnosticFactory<JetMultiDeclaration> INITIALIZER_REQUIRED_FOR_MULTIDECLARATION = SimpleDiagnosticFactory.create(ERROR, DEFAULT);
|
SimpleDiagnosticFactory<JetMultiDeclaration> INITIALIZER_REQUIRED_FOR_MULTIDECLARATION = SimpleDiagnosticFactory.create(ERROR, DEFAULT);
|
||||||
DiagnosticFactory1<JetExpression, Name> COMPONENT_FUNCTION_MISSING = DiagnosticFactory1.create(ERROR, DEFAULT);
|
DiagnosticFactory1<JetExpression, Name> COMPONENT_FUNCTION_MISSING = DiagnosticFactory1.create(ERROR, DEFAULT);
|
||||||
DiagnosticFactory2<JetExpression, Name, Collection<? extends ResolvedCall<? extends CallableDescriptor>>> COMPONENT_FUNCTION_AMBIGUITY = DiagnosticFactory2.create(ERROR, DEFAULT);
|
DiagnosticFactory2<JetExpression, Name, Collection<? extends ResolvedCall<? extends CallableDescriptor>>> COMPONENT_FUNCTION_AMBIGUITY = DiagnosticFactory2.create(ERROR, DEFAULT);
|
||||||
|
DiagnosticFactory3<JetExpression, Name, JetType, JetType> COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH = DiagnosticFactory3.create(ERROR, DEFAULT);
|
||||||
|
|
||||||
SimpleDiagnosticFactory<JetModifierListOwner> ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS = SimpleDiagnosticFactory.create(ERROR, ABSTRACT_MODIFIER);
|
SimpleDiagnosticFactory<JetModifierListOwner> ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS = SimpleDiagnosticFactory.create(ERROR, ABSTRACT_MODIFIER);
|
||||||
SimpleDiagnosticFactory<JetProperty> ABSTRACT_PROPERTY_NOT_IN_CLASS = SimpleDiagnosticFactory.create(ERROR, ABSTRACT_MODIFIER);
|
SimpleDiagnosticFactory<JetProperty> ABSTRACT_PROPERTY_NOT_IN_CLASS = SimpleDiagnosticFactory.create(ERROR, ABSTRACT_MODIFIER);
|
||||||
|
|||||||
+4
-1
@@ -113,9 +113,12 @@ public class DefaultErrorMessages {
|
|||||||
MAP.put(MANY_FUNCTION_LITERAL_ARGUMENTS, "Only one function literal is allowed outside a parenthesized argument list");
|
MAP.put(MANY_FUNCTION_LITERAL_ARGUMENTS, "Only one function literal is allowed outside a parenthesized argument list");
|
||||||
MAP.put(PROPERTY_WITH_NO_TYPE_NO_INITIALIZER, "This property must either have a type annotation or be initialized");
|
MAP.put(PROPERTY_WITH_NO_TYPE_NO_INITIALIZER, "This property must either have a type annotation or be initialized");
|
||||||
MAP.put(VARIABLE_WITH_NO_TYPE_NO_INITIALIZER, "This variable must either have a type annotation or be initialized");
|
MAP.put(VARIABLE_WITH_NO_TYPE_NO_INITIALIZER, "This variable must either have a type annotation or be initialized");
|
||||||
|
|
||||||
MAP.put(INITIALIZER_REQUIRED_FOR_MULTIDECLARATION, "Initializer required for multi-declaration");
|
MAP.put(INITIALIZER_REQUIRED_FOR_MULTIDECLARATION, "Initializer required for multi-declaration");
|
||||||
MAP.put(COMPONENT_FUNCTION_MISSING, "Multi-declaration initializer must have a ''{0}()'' function", TO_STRING);
|
MAP.put(COMPONENT_FUNCTION_MISSING, "Multi-declaration initializer must have a ''{0}()'' function", TO_STRING);
|
||||||
MAP.put(COMPONENT_FUNCTION_AMBIGUITY, "Method ''{0}'' is ambiguous for this expression: {1}", TO_STRING, AMBIGUOUS_CALLS);
|
MAP.put(COMPONENT_FUNCTION_AMBIGUITY, "Function ''{0}()'' is ambiguous for this expression: {1}", TO_STRING, AMBIGUOUS_CALLS);
|
||||||
|
MAP.put(COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH, "''{0}()'' function returns ''{1}'', but ''{2}'' is expected",
|
||||||
|
TO_STRING, RENDER_TYPE, RENDER_TYPE);
|
||||||
|
|
||||||
MAP.put(ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS, "This property cannot be declared abstract");
|
MAP.put(ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS, "This property cannot be declared abstract");
|
||||||
MAP.put(ABSTRACT_PROPERTY_NOT_IN_CLASS, "A property may be abstract only when defined in a class or trait");
|
MAP.put(ABSTRACT_PROPERTY_NOT_IN_CLASS, "A property may be abstract only when defined in a class or trait");
|
||||||
|
|||||||
+24
-3
@@ -34,6 +34,7 @@ import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
|||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||||
import org.jetbrains.jet.lang.types.JetTypeInfo;
|
import org.jetbrains.jet.lang.types.JetTypeInfo;
|
||||||
|
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||||
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||||
@@ -144,11 +145,20 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
|||||||
final Name componentName = Name.identifier("component" + componentIndex);
|
final Name componentName = Name.identifier("component" + componentIndex);
|
||||||
componentIndex++;
|
componentIndex++;
|
||||||
|
|
||||||
JetType componentType = null;
|
JetType expectedType = getExpectedTypeForComponent(context, entry);
|
||||||
OverloadResolutionResults<FunctionDescriptor> results =
|
OverloadResolutionResults<FunctionDescriptor> results =
|
||||||
ExpressionTypingUtils.resolveFakeCall(expressionReceiver, context, componentName);
|
ExpressionTypingUtils.resolveFakeCall(expressionReceiver, context.replaceExpectedType(expectedType), componentName);
|
||||||
|
|
||||||
|
JetType componentType = null;
|
||||||
if (results.isSuccess()) {
|
if (results.isSuccess()) {
|
||||||
componentType = results.getResultingDescriptor().getReturnType();
|
FunctionDescriptor resultingDescriptor = results.getResultingDescriptor();
|
||||||
|
componentType = resultingDescriptor.getReturnType();
|
||||||
|
if (componentType != null && expectedType != TypeUtils.NO_EXPECTED_TYPE
|
||||||
|
&& !JetTypeChecker.INSTANCE.isSubtypeOf(componentType, expectedType)) {
|
||||||
|
|
||||||
|
context.trace.report(
|
||||||
|
COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH.on(initializer, componentName, componentType, expectedType));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (results.isAmbiguity()) {
|
else if (results.isAmbiguity()) {
|
||||||
context.trace.report(COMPONENT_FUNCTION_AMBIGUITY.on(initializer, componentName, results.getResultingCalls()));
|
context.trace.report(COMPONENT_FUNCTION_AMBIGUITY.on(initializer, componentName, results.getResultingCalls()));
|
||||||
@@ -167,6 +177,17 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
|||||||
return DataFlowUtils.checkStatementType(multiDeclaration, context, context.dataFlowInfo);
|
return DataFlowUtils.checkStatementType(multiDeclaration, context, context.dataFlowInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static JetType getExpectedTypeForComponent(ExpressionTypingContext context, JetMultiDeclarationEntry entry) {
|
||||||
|
JetTypeReference entryTypeRef = entry.getTypeRef();
|
||||||
|
if (entryTypeRef != null) {
|
||||||
|
return context.expressionTypingServices.getTypeResolver().resolveType(context.scope, entryTypeRef, context.trace, true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return TypeUtils.NO_EXPECTED_TYPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetTypeInfo visitNamedFunction(JetNamedFunction function, ExpressionTypingContext context) {
|
public JetTypeInfo visitNamedFunction(JetNamedFunction function, ExpressionTypingContext context) {
|
||||||
SimpleFunctionDescriptor functionDescriptor = context.expressionTypingServices.getDescriptorResolver().resolveFunctionDescriptor(scope.getContainingDeclaration(), scope, function, context.trace);
|
SimpleFunctionDescriptor functionDescriptor = context.expressionTypingServices.getDescriptorResolver().resolveFunctionDescriptor(scope.getContainingDeclaration(), scope, function, context.trace);
|
||||||
|
|||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
class A {
|
||||||
|
fun component1() : Int = 1
|
||||||
|
fun component2() : Int = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
fun a(<!UNUSED_PARAMETER!>aa<!> : A) {
|
||||||
|
val (a: String, b1: String) = <!COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH, COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH!>aa<!>
|
||||||
|
}
|
||||||
@@ -1053,6 +1053,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.checkers.AbstractDiagnosticsTestWithEagerResolve", new File("compiler/testData/diagnostics/tests/declarationChecks"), "kt", false);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.checkers.AbstractDiagnosticsTestWithEagerResolve", new File("compiler/testData/diagnostics/tests/declarationChecks"), "kt", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ComponentFunctionReturnTypeMismatch.kt")
|
||||||
|
public void testComponentFunctionReturnTypeMismatch() throws Exception {
|
||||||
|
doTest("compiler/testData/diagnostics/tests/declarationChecks/ComponentFunctionReturnTypeMismatch.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("DataFlowInfoInMultiDecl.kt")
|
@TestMetadata("DataFlowInfoInMultiDecl.kt")
|
||||||
public void testDataFlowInfoInMultiDecl() throws Exception {
|
public void testDataFlowInfoInMultiDecl() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/tests/declarationChecks/DataFlowInfoInMultiDecl.kt");
|
doTest("compiler/testData/diagnostics/tests/declarationChecks/DataFlowInfoInMultiDecl.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user