Fixed KT-2071: Cannot Introduce Variable from function literal.
This commit is contained in:
@@ -50,6 +50,13 @@ public class JetPsiFactory {
|
||||
return property.getInitializer();
|
||||
}
|
||||
|
||||
public static JetValueArgumentList createCallArguments(Project project, String text) {
|
||||
JetProperty property = createProperty(project, "val x = foo" + text);
|
||||
JetExpression initializer = property.getInitializer();
|
||||
JetCallExpression callExpression = (JetCallExpression) initializer;
|
||||
return callExpression.getValueArgumentList();
|
||||
}
|
||||
|
||||
public static JetTypeReference createType(Project project, String type) {
|
||||
JetProperty property = createProperty(project, "val x : " + type);
|
||||
return property.getPropertyTypeRef();
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
cannot.refactor.not.expression=Cannot find an expression to introduce
|
||||
cannot.refactor.not.expression.to.extract=Cannot find an expression to extract
|
||||
expressions.title=Expressions
|
||||
introduce.variable=Introduce Variable
|
||||
cannot.refactor.no.container=Cannot refactor in this place
|
||||
cannot.refactor.no.expression=Cannot perform refactoring without an expression
|
||||
cannot.refactor.expression.has.unit.type=Cannot introduce expression of unit type
|
||||
cannot.refactor.namespace.expression=Cannot intoduce namespace reference
|
||||
cannot.refactor.namespace.expression=Cannot intoduce namespace reference
|
||||
cannot.extract.method=Cannot find statements to extract
|
||||
cannot.find.class.to.extract=Cannot find class to extract method
|
||||
cannot.refactor.expression.should.have.inferred.type=Expression should have inferred type
|
||||
|
||||
+4
-2
@@ -61,6 +61,7 @@ public class JetInplaceVariableIntroducer extends InplaceVariableIntroducer<JetE
|
||||
private final boolean isVar;
|
||||
private final boolean myDoNotChangeVar;
|
||||
@Nullable private final JetType myExprType;
|
||||
private final boolean noTypeInference;
|
||||
private JCheckBox myVarCheckbox;
|
||||
private JCheckBox myExprTypeCheckbox;
|
||||
|
||||
@@ -68,13 +69,14 @@ public class JetInplaceVariableIntroducer extends InplaceVariableIntroducer<JetE
|
||||
String title, JetExpression[] occurrences,
|
||||
@Nullable JetExpression expr, boolean replaceOccurrence,
|
||||
JetProperty property, boolean isVar, boolean doNotChangeVar,
|
||||
@Nullable JetType exprType) {
|
||||
@Nullable JetType exprType, boolean noTypeInference) {
|
||||
super(elementToRename, editor, project, title, occurrences, expr);
|
||||
this.myReplaceOccurrence = replaceOccurrence;
|
||||
myProperty = property;
|
||||
this.isVar = isVar;
|
||||
myDoNotChangeVar = doNotChangeVar;
|
||||
myExprType = exprType;
|
||||
this.noTypeInference = noTypeInference;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,7 +101,7 @@ public class JetInplaceVariableIntroducer extends InplaceVariableIntroducer<JetE
|
||||
});
|
||||
}
|
||||
|
||||
if (myExprType != null) {
|
||||
if (myExprType != null && !noTypeInference) {
|
||||
myExprTypeCheckbox = new NonFocusableCheckBox("Specify type explicitly");
|
||||
myExprTypeCheckbox.setSelected(false);
|
||||
myExprTypeCheckbox.setMnemonic('t');
|
||||
|
||||
+58
-12
@@ -43,8 +43,10 @@ import org.jetbrains.jet.lang.types.NamespaceType;
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening;
|
||||
import org.jetbrains.jet.plugin.project.AnalyzeSingleFileUtil;
|
||||
import org.jetbrains.jet.plugin.refactoring.*;
|
||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -81,6 +83,8 @@ public class JetIntroduceVariableHandler extends JetIntroduceHandlerBase {
|
||||
_expression = (JetExpression)_expression.getParent();
|
||||
}
|
||||
final JetExpression expression = _expression;
|
||||
boolean noTypeInference = false;
|
||||
boolean needParentheses = false;
|
||||
if (expression.getParent() instanceof JetQualifiedExpression) {
|
||||
JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression)expression.getParent();
|
||||
if (qualifiedExpression.getReceiverExpression() != expression) {
|
||||
@@ -88,9 +92,17 @@ public class JetIntroduceVariableHandler extends JetIntroduceHandlerBase {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (expression.getParent() instanceof JetCallElement || expression instanceof JetStatementExpression) {
|
||||
else if (expression instanceof JetStatementExpression) {
|
||||
showErrorHint(project, editor, JetRefactoringBundle.message("cannot.refactor.no.expression"));
|
||||
return;
|
||||
} else if (expression.getParent() instanceof JetCallElement) {
|
||||
if (expression instanceof JetFunctionLiteralExpression) {
|
||||
noTypeInference = true;
|
||||
needParentheses = true;
|
||||
} else {
|
||||
showErrorHint(project, editor, JetRefactoringBundle.message("cannot.refactor.no.expression"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (expression.getParent() instanceof JetOperationExpression) {
|
||||
JetOperationExpression operationExpression = (JetOperationExpression)expression.getParent();
|
||||
@@ -110,6 +122,10 @@ public class JetIntroduceVariableHandler extends JetIntroduceHandlerBase {
|
||||
showErrorHint(project, editor, JetRefactoringBundle.message("cannot.refactor.expression.has.unit.type"));
|
||||
return;
|
||||
}
|
||||
if (expressionType == null && noTypeInference) {
|
||||
showErrorHint(project, editor, JetRefactoringBundle.message("cannot.refactor.expression.should.have.inferred.type"));
|
||||
return;
|
||||
}
|
||||
final PsiElement container = getContainer(expression);
|
||||
final PsiElement occurrenceContainer = getOccurrenceContainer(expression);
|
||||
if (container == null) {
|
||||
@@ -119,7 +135,9 @@ public class JetIntroduceVariableHandler extends JetIntroduceHandlerBase {
|
||||
final boolean isInplaceAvailableOnDataContext =
|
||||
editor.getSettings().isVariableInplaceRenameEnabled() &&
|
||||
!ApplicationManager.getApplication().isUnitTestMode();
|
||||
final ArrayList<JetExpression> allOccurrences = findOccurrences(occurrenceContainer, expression);
|
||||
final List<JetExpression> allOccurrences = findOccurrences(occurrenceContainer, expression);
|
||||
final boolean finalNoTypeInference = noTypeInference;
|
||||
final boolean finalNeedParentheses = needParentheses;
|
||||
Pass<OccurrencesChooser.ReplaceChoice> callback = new Pass<OccurrencesChooser.ReplaceChoice>() {
|
||||
@Override
|
||||
public void pass(OccurrencesChooser.ReplaceChoice replaceChoice) {
|
||||
@@ -147,7 +165,7 @@ public class JetIntroduceVariableHandler extends JetIntroduceHandlerBase {
|
||||
final Ref<JetExpression> reference = new Ref<JetExpression>();
|
||||
final Runnable introduceRunnable = introduceVariable(project, expression, suggestedNames, allReplaces, commonContainer,
|
||||
commonParent, replaceOccurrence, propertyRef, references,
|
||||
reference);
|
||||
reference, finalNoTypeInference, finalNeedParentheses, expressionType);
|
||||
final boolean finalReplaceOccurrence = replaceOccurrence;
|
||||
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
|
||||
@Override
|
||||
@@ -166,7 +184,7 @@ public class JetIntroduceVariableHandler extends JetIntroduceHandlerBase {
|
||||
references.toArray(new JetExpression[references.size()]),
|
||||
reference.get(), finalReplaceOccurrence,
|
||||
property, /*todo*/false, /*todo*/false,
|
||||
expressionType);
|
||||
expressionType, finalNoTypeInference);
|
||||
variableIntroducer.performInplaceRefactoring(suggestedNamesSet);
|
||||
}
|
||||
}
|
||||
@@ -189,11 +207,18 @@ public class JetIntroduceVariableHandler extends JetIntroduceHandlerBase {
|
||||
final PsiElement commonParent, final boolean replaceOccurrence,
|
||||
final Ref<JetProperty> propertyRef,
|
||||
final ArrayList<JetExpression> references,
|
||||
final Ref<JetExpression> reference) {
|
||||
final Ref<JetExpression> reference,
|
||||
final boolean noTypeInference,
|
||||
final boolean needParentheses,
|
||||
final JetType expressionType) {
|
||||
return new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String variableText = "val " + suggestedNames[0] + " = ";
|
||||
String variableText = "val " + suggestedNames[0];
|
||||
if (noTypeInference) {
|
||||
variableText += ": " + DescriptorRenderer.TEXT.renderType(expressionType);
|
||||
}
|
||||
variableText += " = ";
|
||||
if (expression instanceof JetParenthesizedExpression) {
|
||||
JetParenthesizedExpression parenthesizedExpression = (JetParenthesizedExpression)expression;
|
||||
JetExpression innerExpression = parenthesizedExpression.getExpression();
|
||||
@@ -225,9 +250,15 @@ public class JetIntroduceVariableHandler extends JetIntroduceHandlerBase {
|
||||
if (replaceOccurrence && commonContainer != null) {
|
||||
for (JetExpression replace : allReplaces) {
|
||||
boolean isActualExpression = expression == replace;
|
||||
JetExpression element =
|
||||
(JetExpression)replace.replace(JetPsiFactory.createExpression(project, suggestedNames[0]));
|
||||
if (isActualExpression) reference.set(element);
|
||||
if (!needParentheses && !(replace.getParent() instanceof JetCallExpression)) {
|
||||
JetExpression element =
|
||||
(JetExpression)replace.replace(JetPsiFactory.createExpression(project, suggestedNames[0]));
|
||||
if (isActualExpression) reference.set(element);
|
||||
} else {
|
||||
JetValueArgumentList argumentList = JetPsiFactory.createCallArguments(project, "(" + suggestedNames[0] + ")");
|
||||
JetValueArgumentList element = (JetValueArgumentList) replace.replace(argumentList);
|
||||
if (isActualExpression) reference.set(element.getArguments().get(0).getArgumentExpression());
|
||||
}
|
||||
}
|
||||
PsiElement oldElement = commonContainer;
|
||||
if (commonContainer instanceof JetWhenEntry) {
|
||||
@@ -322,15 +353,30 @@ public class JetIntroduceVariableHandler extends JetIntroduceHandlerBase {
|
||||
for (JetExpression replace : allReplaces) {
|
||||
if (replaceOccurrence && !needBraces) {
|
||||
boolean isActualExpression = expression == replace;
|
||||
JetExpression element = (JetExpression)replace.replace(JetPsiFactory.createExpression(project, suggestedNames[0]));
|
||||
references.add(element);
|
||||
if (isActualExpression) reference.set(element);
|
||||
|
||||
if (!needParentheses && !(replace.getParent() instanceof JetCallExpression)) {
|
||||
JetExpression element =
|
||||
(JetExpression)replace.replace(JetPsiFactory.createExpression(project, suggestedNames[0]));
|
||||
references.add(element);
|
||||
if (isActualExpression) reference.set(element);
|
||||
} else {
|
||||
JetValueArgumentList argumentList = JetPsiFactory.createCallArguments(project, "(" + suggestedNames[0] + ")");
|
||||
JetValueArgumentList element = (JetValueArgumentList) replace.replace(argumentList);
|
||||
JetExpression argumentExpression = element.getArguments().get(0).getArgumentExpression();
|
||||
references.add(argumentExpression);
|
||||
if (isActualExpression) {
|
||||
reference.set(argumentExpression);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!needBraces) {
|
||||
replace.delete();
|
||||
}
|
||||
}
|
||||
propertyRef.set(property);
|
||||
if (noTypeInference) {
|
||||
ReferenceToClassesShortening.compactReferenceToClasses(Collections.singletonList(property));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
fun foo(c : Collection<String>){
|
||||
c.filter<selection>{it; false}</selection>
|
||||
}
|
||||
/*
|
||||
fun foo(c : Collection<String>){
|
||||
val function: () -> Boolean = {it; false}
|
||||
c.filter(function)
|
||||
}
|
||||
*/
|
||||
+4
@@ -53,6 +53,10 @@ public class JetIntroduceVariableTest extends LightCodeInsightFixtureTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testFunctionLiteral() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIfCondition() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user