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<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<JetMultiDeclaration> INITIALIZER_REQUIRED_FOR_MULTIDECLARATION = SimpleDiagnosticFactory.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);
|
||||
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<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(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(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_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_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.types.ErrorUtils;
|
||||
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.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||
@@ -144,11 +145,20 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
final Name componentName = Name.identifier("component" + componentIndex);
|
||||
componentIndex++;
|
||||
|
||||
JetType componentType = null;
|
||||
JetType expectedType = getExpectedTypeForComponent(context, entry);
|
||||
OverloadResolutionResults<FunctionDescriptor> results =
|
||||
ExpressionTypingUtils.resolveFakeCall(expressionReceiver, context, componentName);
|
||||
ExpressionTypingUtils.resolveFakeCall(expressionReceiver, context.replaceExpectedType(expectedType), componentName);
|
||||
|
||||
JetType componentType = null;
|
||||
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()) {
|
||||
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);
|
||||
}
|
||||
|
||||
@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
|
||||
public JetTypeInfo visitNamedFunction(JetNamedFunction function, ExpressionTypingContext context) {
|
||||
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);
|
||||
}
|
||||
|
||||
@TestMetadata("ComponentFunctionReturnTypeMismatch.kt")
|
||||
public void testComponentFunctionReturnTypeMismatch() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/declarationChecks/ComponentFunctionReturnTypeMismatch.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DataFlowInfoInMultiDecl.kt")
|
||||
public void testDataFlowInfoInMultiDecl() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/declarationChecks/DataFlowInfoInMultiDecl.kt");
|
||||
|
||||
Reference in New Issue
Block a user