Create from usage: Fixed case for multi-declaration in a for-loop.
This commit is contained in:
@@ -358,7 +358,7 @@ public interface Errors {
|
|||||||
// Multi-declarations
|
// Multi-declarations
|
||||||
|
|
||||||
DiagnosticFactory0<JetMultiDeclaration> INITIALIZER_REQUIRED_FOR_MULTIDECLARATION = DiagnosticFactory0.create(ERROR, DEFAULT);
|
DiagnosticFactory0<JetMultiDeclaration> INITIALIZER_REQUIRED_FOR_MULTIDECLARATION = DiagnosticFactory0.create(ERROR, DEFAULT);
|
||||||
DiagnosticFactory1<JetExpression, Name> COMPONENT_FUNCTION_MISSING = DiagnosticFactory1.create(ERROR, DEFAULT);
|
DiagnosticFactory2<JetExpression, Name, JetType> COMPONENT_FUNCTION_MISSING = DiagnosticFactory2.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);
|
DiagnosticFactory3<JetExpression, Name, JetType, JetType> COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH = DiagnosticFactory3.create(ERROR, DEFAULT);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -113,7 +113,7 @@ public class DefaultErrorMessages {
|
|||||||
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 of type {1} must have a ''{0}()'' function", TO_STRING, RENDER_TYPE);
|
||||||
MAP.put(COMPONENT_FUNCTION_AMBIGUITY, "Function ''{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",
|
MAP.put(COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH, "''{0}()'' function returns ''{1}'', but ''{2}'' is expected",
|
||||||
TO_STRING, RENDER_TYPE, RENDER_TYPE);
|
TO_STRING, RENDER_TYPE, RENDER_TYPE);
|
||||||
|
|||||||
+1
-1
@@ -417,7 +417,7 @@ public class ExpressionTypingUtils {
|
|||||||
context.trace.report(COMPONENT_FUNCTION_AMBIGUITY.on(reportErrorsOn, componentName, results.getResultingCalls()));
|
context.trace.report(COMPONENT_FUNCTION_AMBIGUITY.on(reportErrorsOn, componentName, results.getResultingCalls()));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
context.trace.report(COMPONENT_FUNCTION_MISSING.on(reportErrorsOn, componentName));
|
context.trace.report(COMPONENT_FUNCTION_MISSING.on(reportErrorsOn, componentName, receiver.getType()));
|
||||||
}
|
}
|
||||||
if (componentType == null) {
|
if (componentType == null) {
|
||||||
componentType = ErrorUtils.createErrorType(componentName + "() return type");
|
componentType = ErrorUtils.createErrorType(componentName + "() return type");
|
||||||
|
|||||||
@@ -51,9 +51,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
import org.jetbrains.jet.lang.diagnostics.*;
|
||||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1;
|
|
||||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||||
@@ -1313,7 +1311,10 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase {
|
|||||||
JetForExpression forExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetForExpression.class);
|
JetForExpression forExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetForExpression.class);
|
||||||
if (forExpr == null) return null;
|
if (forExpr == null) return null;
|
||||||
JetExpression variableExpr = forExpr.getLoopParameter();
|
JetExpression variableExpr = forExpr.getLoopParameter();
|
||||||
if (variableExpr == null) return null;
|
if (variableExpr == null) {
|
||||||
|
variableExpr = forExpr.getMultiParameter();
|
||||||
|
if (variableExpr == null) return null;
|
||||||
|
}
|
||||||
TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(variableExpr, Variance.OUT_VARIANCE);
|
TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(variableExpr, Variance.OUT_VARIANCE);
|
||||||
return new CreateFunctionFromUsageFix(forExpr, ownerType, "next", returnType, new ArrayList<Parameter>());
|
return new CreateFunctionFromUsageFix(forExpr, ownerType, "next", returnType, new ArrayList<Parameter>());
|
||||||
}
|
}
|
||||||
@@ -1335,7 +1336,10 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase {
|
|||||||
JetExpression iterableExpr = forExpr.getLoopRange();
|
JetExpression iterableExpr = forExpr.getLoopRange();
|
||||||
if (iterableExpr == null) return null;
|
if (iterableExpr == null) return null;
|
||||||
JetExpression variableExpr = forExpr.getLoopParameter();
|
JetExpression variableExpr = forExpr.getLoopParameter();
|
||||||
if (variableExpr == null) return null;
|
if (variableExpr == null) {
|
||||||
|
variableExpr = forExpr.getMultiParameter();
|
||||||
|
if (variableExpr == null) return null;
|
||||||
|
}
|
||||||
TypeOrExpressionThereof iterableType = new TypeOrExpressionThereof(iterableExpr, Variance.IN_VARIANCE);
|
TypeOrExpressionThereof iterableType = new TypeOrExpressionThereof(iterableExpr, Variance.IN_VARIANCE);
|
||||||
JetType returnJetType = KotlinBuiltIns.getInstance().getIterator().getDefaultType();
|
JetType returnJetType = KotlinBuiltIns.getInstance().getIterator().getDefaultType();
|
||||||
|
|
||||||
@@ -1359,25 +1363,33 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase {
|
|||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public IntentionAction createAction(Diagnostic diagnostic) {
|
public IntentionAction createAction(Diagnostic diagnostic) {
|
||||||
JetMultiDeclaration multiDeclaration = QuickFixUtil.getParentElementOfType(diagnostic, JetMultiDeclaration.class);
|
|
||||||
if (multiDeclaration == null) return null;
|
|
||||||
List<JetMultiDeclarationEntry> entries = multiDeclaration.getEntries();
|
|
||||||
|
|
||||||
assert diagnostic.getFactory() == Errors.COMPONENT_FUNCTION_MISSING;
|
assert diagnostic.getFactory() == Errors.COMPONENT_FUNCTION_MISSING;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
DiagnosticWithParameters1<JetExpression, Name> diagnosticWithParameters =
|
DiagnosticWithParameters2<JetExpression, Name, JetType> diagnosticWithParameters =
|
||||||
(DiagnosticWithParameters1<JetExpression, Name>) diagnostic;
|
(DiagnosticWithParameters2<JetExpression, Name, JetType>) diagnostic;
|
||||||
Name name = diagnosticWithParameters.getA();
|
Name name = diagnosticWithParameters.getA();
|
||||||
Matcher componentNumberMatcher = COMPONENT_FUNCTION_PATTERN.matcher(name.getIdentifier());
|
Matcher componentNumberMatcher = COMPONENT_FUNCTION_PATTERN.matcher(name.getIdentifier());
|
||||||
if (!componentNumberMatcher.matches()) return null;
|
if (!componentNumberMatcher.matches()) return null;
|
||||||
String componentNumberString = componentNumberMatcher.group(1);
|
String componentNumberString = componentNumberMatcher.group(1);
|
||||||
int componentNumber = Integer.decode(componentNumberString) - 1;
|
int componentNumber = Integer.decode(componentNumberString) - 1;
|
||||||
|
|
||||||
|
JetMultiDeclaration multiDeclaration = QuickFixUtil.getParentElementOfType(diagnostic, JetMultiDeclaration.class);
|
||||||
|
TypeOrExpressionThereof ownerType;
|
||||||
|
if (multiDeclaration == null) { // if it's not a multi-declaration, must be a multi parameter in a for-loop
|
||||||
|
JetForExpression forExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetForExpression.class);
|
||||||
|
if (forExpr == null) return null;
|
||||||
|
multiDeclaration = forExpr.getMultiParameter();
|
||||||
|
if (multiDeclaration == null) return null;
|
||||||
|
ownerType = new TypeOrExpressionThereof(diagnosticWithParameters.getB(), Variance.IN_VARIANCE);
|
||||||
|
} else {
|
||||||
|
JetExpression rhs = multiDeclaration.getInitializer();
|
||||||
|
if (rhs == null) return null;
|
||||||
|
ownerType = new TypeOrExpressionThereof(rhs, Variance.IN_VARIANCE);
|
||||||
|
}
|
||||||
|
List<JetMultiDeclarationEntry> entries = multiDeclaration.getEntries();
|
||||||
|
|
||||||
JetMultiDeclarationEntry entry = entries.get(componentNumber);
|
JetMultiDeclarationEntry entry = entries.get(componentNumber);
|
||||||
TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(entry, Variance.OUT_VARIANCE);
|
TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(entry, Variance.OUT_VARIANCE);
|
||||||
JetExpression rhs = multiDeclaration.getInitializer();
|
|
||||||
if (rhs == null) return null;
|
|
||||||
TypeOrExpressionThereof ownerType = new TypeOrExpressionThereof(rhs, Variance.IN_VARIANCE);
|
|
||||||
|
|
||||||
return new CreateFunctionFromUsageFix(multiDeclaration, ownerType, name.getIdentifier(), returnType, new ArrayList<Parameter>());
|
return new CreateFunctionFromUsageFix(multiDeclaration, ownerType, name.getIdentifier(), returnType, new ArrayList<Parameter>());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// "Create function 'component2' from usage" "true"
|
||||||
|
class FooIterator<T> {
|
||||||
|
fun hasNext(): Boolean { return false }
|
||||||
|
fun next(): Any {
|
||||||
|
throw UnsupportedOperationException("not implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Foo<T> {
|
||||||
|
fun iterator(): FooIterator<String> {
|
||||||
|
throw UnsupportedOperationException("not implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun Any.component1(): Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
fun foo() {
|
||||||
|
for ((i: Int, j: Int) in Foo<Int>()) { }
|
||||||
|
}
|
||||||
|
fun Any.component2(): Int {
|
||||||
|
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
// "Create function 'component2' from usage" "true"
|
||||||
|
class FooIterator<T> {
|
||||||
|
fun hasNext(): Boolean { return false }
|
||||||
|
fun next(): Any {
|
||||||
|
throw UnsupportedOperationException("not implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Foo<T> {
|
||||||
|
fun iterator(): FooIterator<String> {
|
||||||
|
throw UnsupportedOperationException("not implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun Any.component1(): Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
fun foo() {
|
||||||
|
for ((i: Int, j: Int) in Foo<caret><Int>()) { }
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// "Create function 'next' from usage" "true"
|
||||||
|
class FooIterator<T> {
|
||||||
|
fun hasNext(): Boolean { return false }
|
||||||
|
fun next(): Any {
|
||||||
|
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Foo<T> {
|
||||||
|
fun iterator(): FooIterator<String> {
|
||||||
|
throw UnsupportedOperationException("not implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun Any.component1(): Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
fun Any.component2(): Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
fun foo() {
|
||||||
|
for ((i: Int, j: Int) in Foo<Int>()) { }
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
// "Create function 'next' from usage" "true"
|
||||||
|
class FooIterator<T> {
|
||||||
|
fun hasNext(): Boolean { return false }
|
||||||
|
}
|
||||||
|
class Foo<T> {
|
||||||
|
fun iterator(): FooIterator<String> {
|
||||||
|
throw UnsupportedOperationException("not implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun Any.component1(): Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
fun Any.component2(): Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
fun foo() {
|
||||||
|
for ((i: Int, j: Int) in Foo<caret><Int>()) { }
|
||||||
|
}
|
||||||
@@ -452,6 +452,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
doTest("idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage2.kt");
|
doTest("idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("beforeCreateComponentFromUsage3.kt")
|
||||||
|
public void testCreateComponentFromUsage3() throws Exception {
|
||||||
|
doTest("idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage3.kt");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/quickfix/createFromUsage/get")
|
@TestMetadata("idea/testData/quickfix/createFromUsage/get")
|
||||||
@@ -561,6 +566,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
doTest("idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage2.kt");
|
doTest("idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("beforeCreateIteratorFromUsage3.kt")
|
||||||
|
public void testCreateIteratorFromUsage3() throws Exception {
|
||||||
|
doTest("idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage3.kt");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/quickfix/createFromUsage/next")
|
@TestMetadata("idea/testData/quickfix/createFromUsage/next")
|
||||||
|
|||||||
Reference in New Issue
Block a user