KT-2631 Check multiple assignment - in progress
check multiple declaration without specified type annotation
This commit is contained in:
committed by
Andrey Breslav
parent
68ebdabf8f
commit
a0da232ed3
@@ -24,7 +24,9 @@ import com.intellij.psi.impl.source.tree.LeafPsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.InferenceErrorData;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
@@ -97,6 +99,9 @@ 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<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);
|
||||
|
||||
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);
|
||||
|
||||
+3
@@ -112,6 +112,9 @@ 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(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(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");
|
||||
|
||||
+40
@@ -32,6 +32,7 @@ import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
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.lang.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
@@ -127,6 +128,45 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
return DataFlowUtils.checkStatementType(property, context, context.dataFlowInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetTypeInfo visitMultiDeclaration(JetMultiDeclaration multiDeclaration, final ExpressionTypingContext context) {
|
||||
final JetExpression initializer = multiDeclaration.getInitializer();
|
||||
if (initializer == null) {
|
||||
context.trace.report(INITIALIZER_REQUIRED_FOR_MULTIDECLARATION.on(multiDeclaration));
|
||||
return JetTypeInfo.create(null, context.dataFlowInfo);
|
||||
}
|
||||
final ExpressionReceiver expressionReceiver = ExpressionTypingUtils.getExpressionReceiver(facade, initializer, context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE));
|
||||
if (expressionReceiver == null) {
|
||||
return JetTypeInfo.create(null, context.dataFlowInfo);
|
||||
}
|
||||
int componentIndex = 0;
|
||||
for (JetMultiDeclarationEntry entry : multiDeclaration.getEntries()) {
|
||||
final Name componentName = Name.identifier("component" + componentIndex);
|
||||
componentIndex++;
|
||||
|
||||
JetType componentType = null;
|
||||
OverloadResolutionResults<FunctionDescriptor> results =
|
||||
ExpressionTypingUtils.resolveFakeCall(expressionReceiver, context, componentName);
|
||||
if (results.isSuccess()) {
|
||||
componentType = results.getResultingDescriptor().getReturnType();
|
||||
}
|
||||
else if (results.isAmbiguity()) {
|
||||
context.trace.report(COMPONENT_FUNCTION_AMBIGUITY.on(initializer, componentName, results.getResultingCalls()));
|
||||
}
|
||||
else {
|
||||
context.trace.report(COMPONENT_FUNCTION_MISSING.on(initializer, componentName));
|
||||
}
|
||||
if (componentType == null) {
|
||||
componentType = ErrorUtils.createErrorType(componentName + "() return type");
|
||||
}
|
||||
VariableDescriptor variableDescriptor = context.expressionTypingServices.getDescriptorResolver().
|
||||
resolveLocalVariableDescriptorWithType(scope.getContainingDeclaration(), entry, componentType, context.trace);
|
||||
|
||||
scope.addVariableDescriptor(variableDescriptor);
|
||||
}
|
||||
return DataFlowUtils.checkStatementType(multiDeclaration, context, context.dataFlowInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetTypeInfo visitNamedFunction(JetNamedFunction function, ExpressionTypingContext context) {
|
||||
SimpleFunctionDescriptor functionDescriptor = context.expressionTypingServices.getDescriptorResolver().resolveFunctionDescriptor(scope.getContainingDeclaration(), scope, function, context.trace);
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package a
|
||||
|
||||
class MyClass {
|
||||
fun component0(<!UNUSED_PARAMETER!>i<!>: Int) {}
|
||||
}
|
||||
|
||||
class MyClass2 {}
|
||||
|
||||
<!CONFLICTING_OVERLOADS!>fun MyClass2.component0()<!> = 1.2
|
||||
<!CONFLICTING_OVERLOADS!>fun MyClass2.component0()<!> = 1.3
|
||||
|
||||
fun test(<!UNUSED_PARAMETER!>mc1<!>: MyClass, <!UNUSED_PARAMETER!>mc2<!>: MyClass2) {
|
||||
val (a, b) = <!COMPONENT_FUNCTION_MISSING, COMPONENT_FUNCTION_MISSING!>mc1<!>
|
||||
val (c) = <!COMPONENT_FUNCTION_AMBIGUITY!>mc2<!>
|
||||
|
||||
//a,b,c are error types
|
||||
a : Boolean
|
||||
b : Boolean
|
||||
c : Boolean
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
//KT-2631 Check multiple assignment
|
||||
package a
|
||||
|
||||
class MyClass {
|
||||
fun component0() = 1
|
||||
fun component1() = "a"
|
||||
}
|
||||
|
||||
class MyClass2 {}
|
||||
|
||||
fun MyClass2.component0() = 1.2
|
||||
|
||||
fun test(<!UNUSED_PARAMETER!>mc1<!>: MyClass, <!UNUSED_PARAMETER!>mc2<!>: MyClass2) {
|
||||
val (a, b) = mc1
|
||||
a : Int
|
||||
b : String
|
||||
|
||||
val (c) = mc2
|
||||
c : Double
|
||||
|
||||
//check no error types
|
||||
<!TYPE_MISMATCH!>a<!> : Boolean
|
||||
<!TYPE_MISMATCH!>b<!> : Boolean
|
||||
<!TYPE_MISMATCH!>c<!> : Boolean
|
||||
}
|
||||
@@ -1073,11 +1073,21 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
doTest("compiler/testData/diagnostics/tests/declarationChecks/kt2142.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt2631_MultipleDeclaration.kt")
|
||||
public void testKt2631_MultipleDeclaration() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/declarationChecks/kt2631_MultipleDeclaration.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt559.kt")
|
||||
public void testKt559() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/declarationChecks/kt559.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("MultiDeclarationErrors.kt")
|
||||
public void testMultiDeclarationErrors() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/declarationChecks/MultiDeclarationErrors.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/extensions")
|
||||
|
||||
Reference in New Issue
Block a user