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
|
||||
|
||||
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);
|
||||
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(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_RETURN_TYPE_MISMATCH, "''{0}()'' function returns ''{1}'', but ''{2}'' is expected",
|
||||
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()));
|
||||
}
|
||||
else {
|
||||
context.trace.report(COMPONENT_FUNCTION_MISSING.on(reportErrorsOn, componentName));
|
||||
context.trace.report(COMPONENT_FUNCTION_MISSING.on(reportErrorsOn, componentName, receiver.getType()));
|
||||
}
|
||||
if (componentType == null) {
|
||||
componentType = ErrorUtils.createErrorType(componentName + "() return type");
|
||||
|
||||
@@ -51,9 +51,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1;
|
||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||
import org.jetbrains.jet.lang.diagnostics.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
@@ -1313,7 +1311,10 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase {
|
||||
JetForExpression forExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetForExpression.class);
|
||||
if (forExpr == null) return null;
|
||||
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);
|
||||
return new CreateFunctionFromUsageFix(forExpr, ownerType, "next", returnType, new ArrayList<Parameter>());
|
||||
}
|
||||
@@ -1335,7 +1336,10 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase {
|
||||
JetExpression iterableExpr = forExpr.getLoopRange();
|
||||
if (iterableExpr == null) return null;
|
||||
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);
|
||||
JetType returnJetType = KotlinBuiltIns.getInstance().getIterator().getDefaultType();
|
||||
|
||||
@@ -1359,25 +1363,33 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase {
|
||||
@Nullable
|
||||
@Override
|
||||
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;
|
||||
@SuppressWarnings("unchecked")
|
||||
DiagnosticWithParameters1<JetExpression, Name> diagnosticWithParameters =
|
||||
(DiagnosticWithParameters1<JetExpression, Name>) diagnostic;
|
||||
DiagnosticWithParameters2<JetExpression, Name, JetType> diagnosticWithParameters =
|
||||
(DiagnosticWithParameters2<JetExpression, Name, JetType>) diagnostic;
|
||||
Name name = diagnosticWithParameters.getA();
|
||||
Matcher componentNumberMatcher = COMPONENT_FUNCTION_PATTERN.matcher(name.getIdentifier());
|
||||
if (!componentNumberMatcher.matches()) return null;
|
||||
String componentNumberString = componentNumberMatcher.group(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);
|
||||
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>());
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@TestMetadata("beforeCreateComponentFromUsage3.kt")
|
||||
public void testCreateComponentFromUsage3() throws Exception {
|
||||
doTest("idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage3.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/createFromUsage/get")
|
||||
@@ -561,6 +566,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
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")
|
||||
|
||||
Reference in New Issue
Block a user