java inline chained constructors: ensure elements are not invalidated during processing (IDEA-255661)

GitOrigin-RevId: e600dbad74bed7eee0e0979bd1e33a2b7e9870bf
This commit is contained in:
Anna Kozlova
2020-11-20 09:33:47 +00:00
committed by intellij-monorepo-bot
parent a51d362cce
commit b5617168c3
4 changed files with 42 additions and 26 deletions
@@ -604,35 +604,30 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
private static void replaceParameterReferences(final PsiElement element,
final PsiMethod oldConstructor,
final PsiExpression[] instanceCreationArguments) {
boolean isParameterReference = false;
if (element instanceof PsiReferenceExpression) {
final PsiReferenceExpression expression = (PsiReferenceExpression)element;
PsiElement resolved = expression.resolve();
if (resolved instanceof PsiParameter &&
element.getManager().areElementsEquivalent(((PsiParameter)resolved).getDeclarationScope(), oldConstructor)) {
isParameterReference = true;
PsiElement declarationScope = ((PsiParameter)resolved).getDeclarationScope();
PsiParameter[] declarationParameters = ((PsiMethod)declarationScope).getParameterList().getParameters();
for (int j = 0; j < declarationParameters.length; j++) {
if (declarationParameters[j] == resolved) {
try {
expression.replace(instanceCreationArguments[j]);
}
catch (IncorrectOperationException e) {
LOG.error(e);
Map<PsiReferenceExpression, PsiExpression> replacement = new LinkedHashMap<>();
element.accept(new JavaRecursiveElementWalkingVisitor() {
@Override
public void visitReferenceExpression(PsiReferenceExpression expression) {
super.visitReferenceExpression(expression);
PsiElement resolved = expression.resolve();
if (resolved instanceof PsiParameter &&
element.getManager().areElementsEquivalent(((PsiParameter)resolved).getDeclarationScope(), oldConstructor)) {
PsiElement declarationScope = ((PsiParameter)resolved).getDeclarationScope();
PsiParameter[] declarationParameters = ((PsiMethod)declarationScope).getParameterList().getParameters();
for (int j = 0; j < declarationParameters.length; j++) {
if (declarationParameters[j] == resolved) {
try {
replacement.put(expression, instanceCreationArguments[j]);
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
}
}
}
}
}
if (!isParameterReference) {
PsiElement child = element.getFirstChild();
while (child != null) {
PsiElement next = child.getNextSibling();
replaceParameterReferences(child, oldConstructor, instanceCreationArguments);
child = next;
}
}
});
replacement.forEach(PsiElement::replace);
}
public void inlineMethodCall(PsiReferenceExpression ref) throws IncorrectOperationException {
@@ -0,0 +1,10 @@
public class Foo {
private Foo(String s, String s2) {
this(s + " " + s2);
}
private Foo(String s) {}
{
Foo foo = new F<caret>oo("a", "b")
}
}
@@ -0,0 +1,7 @@
public class Foo {
private Foo(String s) {}
{
Foo foo = new Foo("a" + " " + "b")
}
}
@@ -221,6 +221,10 @@ public class InlineMethodTest extends LightRefactoringTestCase {
doTestInlineThisOnly();
}
public void testChainedConstructorWithSpacesInvalidation() {
doTest();
}
public void testChainedConstructor1() {
doTest();
}