introduce functional parameter from substring

EA-80674 - AIOOBE: IntroduceParameterHandler.introduceStrategy
This commit is contained in:
Anna.Kozlova
2016-03-17 21:25:32 +01:00
parent 5c8090dd02
commit 4ad5c2006c
5 changed files with 59 additions and 26 deletions
@@ -1013,7 +1013,7 @@ public class ExtractMethodProcessor implements MatchProvider {
}
}
myExtractedMethod = (PsiMethod)myTargetClass.addAfter(newMethod, myAnchor);
myExtractedMethod = addExtractedMethod(newMethod);
if (isNeedToChangeCallContext() && myNeedChangeContext) {
ChangeContextUtil.decodeContextInfo(myExtractedMethod, myTargetClass, RefactoringChangeUtil.createThisExpression(myManager, null));
if (myMethodCall.resolveMethod() != myExtractedMethod) {
@@ -1023,6 +1023,10 @@ public class ExtractMethodProcessor implements MatchProvider {
}
}
protected PsiMethod addExtractedMethod(PsiMethod newMethod) {
return (PsiMethod)myTargetClass.addAfter(newMethod, myAnchor);
}
@Nullable
private PsiStatement prepareMethodBody(PsiMethod newMethod, boolean doExtract) {
PsiCodeBlock body = newMethod.getBody();
@@ -549,15 +549,20 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase {
return false;
}
final PsiFile copy = PsiFileFactory.getInstance(project)
.createFileFromText(file.getName(), file.getFileType(), file.getText(), file.getModificationStamp(), false);
final PsiExpression exprInRange = CodeInsightUtil.findExpressionInRange(copy, elements[0].getTextRange().getStartOffset(),
elements[elements.length - 1].getTextRange().getEndOffset());
final PsiElement[] elementsCopy = exprInRange != null
? new PsiElement[] {exprInRange}
: CodeInsightUtil.findStatementsInRange(copy, elements[0].getTextRange().getStartOffset(),
elements[elements.length - 1].getTextRange().getEndOffset());
final PsiElement[] elementsCopy;
if (!elements[0].isPhysical()) {
elementsCopy = elements;
}
else {
final PsiFile copy = PsiFileFactory.getInstance(project)
.createFileFromText(file.getName(), file.getFileType(), file.getText(), file.getModificationStamp(), false);
final TextRange range = new TextRange(elements[0].getTextRange().getStartOffset(),
elements[elements.length - 1].getTextRange().getEndOffset());
final PsiExpression exprInRange = CodeInsightUtil.findExpressionInRange(copy, range.getStartOffset(), range.getEndOffset());
elementsCopy = exprInRange != null
? new PsiElement[]{exprInRange}
: CodeInsightUtil.findStatementsInRange(copy, range.getStartOffset(), range.getEndOffset());
}
final List<PsiMethod> enclosingMethodsInCopy = getEnclosingMethods(Util.getContainingMethod(elementsCopy[0]));
final MyExtractMethodProcessor processor = new MyExtractMethodProcessor(project, editor, elementsCopy,
enclosingMethodsInCopy.get(enclosingMethodsInCopy.size() - 1));
@@ -629,8 +634,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase {
final PsiType selectedType,
final MyExtractMethodProcessor processor,
final PsiElement[] elements) {
final PsiElement commonParent = elements.length > 1 ? PsiTreeUtil.findCommonParent(elements)
: PsiTreeUtil.getParentOfType(elements[0].getParent(), PsiCodeBlock.class, false);
final PsiElement commonParent = findCommonParent(elements);
if (commonParent == null) {
LOG.error("Should have common parent:" + Arrays.toString(elements));
return;
@@ -638,8 +642,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase {
final RangeMarker marker = editor.getDocument().createRangeMarker(commonParent.getTextRange());
final PsiElement[] copyElements = processor.getElements();
final PsiElement containerCopy = copyElements.length > 1 ? PsiTreeUtil.findCommonParent(copyElements)
: PsiTreeUtil.getParentOfType(copyElements[0].getParent(), PsiCodeBlock.class, false);
final PsiElement containerCopy = findCommonParent(copyElements);
if (containerCopy == null) {
LOG.error("Should have common parent:" + Arrays.toString(copyElements));
return;
@@ -661,7 +664,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase {
final String interfaceMethodName = method.getName();
processor.setMethodName(interfaceMethodName);
if (copyElements.length == 1) {
if (copyElements.length == 1 && copyElements[0].getUserData(ElementToWorkOn.PARENT) == null) {
copyElements[0].putUserData(ElementToWorkOn.REPLACE_NON_PHYSICAL, true);
}
@@ -701,6 +704,20 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase {
.introduceParameter(methodToIntroduceParameter, methodToSearchFor);
}
@Nullable
private static PsiElement findCommonParent(PsiElement[] copyElements) {
if (copyElements.length > 1) {
return PsiTreeUtil.findCommonParent(copyElements);
}
else {
PsiElement parent = copyElements[0].getUserData(ElementToWorkOn.PARENT);
if (parent == null) {
parent = copyElements[0].getParent();
}
return PsiTreeUtil.getParentOfType(parent, PsiCodeBlock.class, false);
}
}
private static class MyExtractMethodProcessor extends ExtractMethodProcessor {
private final PsiMethod myTopEnclosingMethod;
@@ -738,6 +755,11 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase {
return false;
}
@Override
protected PsiMethod addExtractedMethod(PsiMethod newMethod) {
return newMethod;
}
@Override
public boolean prepare(@Nullable Pass<ExtractMethodProcessor> pass) throws PrepareFailedException {
final boolean prepare = super.prepare(pass);
@@ -0,0 +1,7 @@
import java.util.function.Supplier;
class Test {
void foo(Supplier<String> anObject) {
System.out.println("a" + anObject.get() + "d");
}
}
@@ -0,0 +1,5 @@
class Test {
void foo() {
System.out.println("a<selection>bc</selection>d");
}
}
@@ -16,12 +16,11 @@
package com.intellij.refactoring;
import com.intellij.JavaTestUtil;
import com.intellij.codeInsight.CodeInsightUtil;
import com.intellij.openapi.editor.SelectionModel;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiExpression;
import com.intellij.refactoring.extractMethod.ExtractMethodHandler;
import com.intellij.refactoring.introduceParameter.IntroduceParameterHandler;
import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.testFramework.TestDataPath;
@@ -69,6 +68,10 @@ public class IntroduceFunctionalParameterTest extends LightRefactoringTestCase
doTest();
}
public void testPartialString() throws Exception {
doTest();
}
@NotNull
@Override
protected String getTestDataPath() {
@@ -97,15 +100,7 @@ public class IntroduceFunctionalParameterTest extends LightRefactoringTestCase
myEditor.getSettings().setVariableInplaceRenameEnabled(false);
final SelectionModel selectionModel = getEditor().getSelectionModel();
if (selectionModel.hasSelection()) {
final int selectionStart = selectionModel.getSelectionStart();
final int selectionEnd = selectionModel.getSelectionEnd();
PsiElement[] elements = CodeInsightUtil.findStatementsInRange(getFile(), selectionStart, selectionEnd);
if (elements.length == 0) {
final PsiExpression expression = CodeInsightUtil.findExpressionInRange(getFile(), selectionStart, selectionEnd);
if (expression != null) {
elements = new PsiElement[] {expression};
}
}
PsiElement[] elements = ExtractMethodHandler.getElements(getProject(), getEditor(), getFile());
new IntroduceParameterHandler().introduceStrategy(getProject(), getEditor(), getFile(), elements);
}
checkResultByFile("/refactoring/introduceFunctionalParameter/after" + getTestName(false) + ".java");