[java-refactoring] MoveInstanceMethodProcessor: extract reference replacing code; cosmetics

GitOrigin-RevId: 767c7e074a41f7e33e67b2103e688feb9331d0d3
This commit is contained in:
Tagir Valeev
2024-05-08 14:03:48 +02:00
committed by intellij-monorepo-bot
parent 375dd52b8e
commit 11a73992ad

View File

@@ -30,6 +30,7 @@ import com.intellij.util.CommonJavaRefactoringUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.VisibilityUtil;
import com.intellij.util.containers.MultiMap;
import com.siyeh.ig.psiutils.ClassUtils;
import com.siyeh.ig.psiutils.ExpressionUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -266,7 +267,7 @@ public class MoveInstanceMethodProcessor extends BaseRefactoringProcessor{
else {
String exprText;
if (myTargetVariable instanceof PsiParameter ||
qualifierExpression instanceof PsiReferenceExpression && ((PsiReferenceExpression)qualifierExpression).resolve() == myMethod.getContainingClass()) {
qualifierExpression instanceof PsiReferenceExpression ref && ref.resolve() == myMethod.getContainingClass()) {
exprText = myTargetVariable.getType().getCanonicalText();
}
else if (qualifierExpression instanceof PsiReferenceExpression) {
@@ -455,110 +456,10 @@ public class MoveInstanceMethodProcessor extends BaseRefactoringProcessor{
private PsiMethod createMethodToAdd () {
ChangeContextUtil.encodeContextInfo(myMethod, true);
try {
final PsiManager manager = myMethod.getManager();
JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject());
final PsiElementFactory factory = facade.getElementFactory();
//correct internal references
final PsiCodeBlock body = myMethod.getBody();
if (body != null) {
final Map<PsiElement, PsiElement> replaceMap = new HashMap<>();
body.accept(new JavaRecursiveElementVisitor() {
@Override public void visitThisExpression(@NotNull PsiThisExpression expression) {
final PsiClass classReferencedByThis = MoveInstanceMembersUtil.getClassReferencedByThis(expression);
if (classReferencedByThis != null && !PsiTreeUtil.isAncestor(myMethod, classReferencedByThis, false)) {
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(myProject);
String paramName = getParameterNameToCreate(classReferencedByThis);
try {
final PsiExpression refExpression = factory.createExpressionFromText(paramName, null);
replaceMap.put(expression, refExpression);
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
}
@Override public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) {
try {
final PsiExpression qualifier = expression.getQualifierExpression();
final PsiElement resolved = expression.resolve();
if (ExpressionUtils.isReferenceTo(qualifier, myTargetVariable)) {
if (resolved instanceof PsiField) {
String fieldName = ((PsiField)resolved).getName();
for (PsiParameter parameter : myMethod.getParameterList().getParameters()) {
if (Comparing.strEqual(parameter.getName(), fieldName) ||
facade.getResolveHelper().resolveReferencedVariable(fieldName, expression) != null) {
qualifier.replace(factory.createExpressionFromText("this", null));
return;
}
}
}
if (expression instanceof PsiMethodReferenceExpression) {
qualifier.replace(factory.createExpressionFromText("this", null));
}
else {
//Target is a field, replace target.m -> m
qualifier.delete();
}
return;
}
if (myTargetVariable.equals(resolved)) {
PsiThisExpression thisExpression = RefactoringChangeUtil.createThisExpression(manager, PsiTreeUtil.isAncestor(myMethod, PsiTreeUtil.getParentOfType(expression, PsiClass.class), true) ? myTargetClass : null);
replaceMap.put(expression, thisExpression);
return;
}
else if (myMethod.equals(resolved)) {
}
else {
PsiClass classReferencedByThis = MoveInstanceMembersUtil.getClassReferencedByThis(expression);
if (classReferencedByThis != null) {
final String paramName = getParameterNameToCreate(classReferencedByThis);
if (paramName != null) {
PsiReferenceExpression newQualifier = (PsiReferenceExpression)factory.createExpressionFromText(paramName, null);
expression.setQualifierExpression(newQualifier);
return;
}
}
}
super.visitReferenceExpression(expression);
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
@Override public void visitNewExpression(@NotNull PsiNewExpression expression) {
try {
final PsiExpression qualifier = expression.getQualifier();
if (ExpressionUtils.isReferenceTo(qualifier, myTargetVariable)) {
//Target is a field, replace target.new A() -> new A()
qualifier.delete();
} else {
final PsiClass classReferencedByThis = MoveInstanceMembersUtil.getClassReferencedByThis(expression);
if (classReferencedByThis != null) {
if (qualifier != null) qualifier.delete();
final String paramName = getParameterNameToCreate(classReferencedByThis);
final PsiExpression newExpression = factory.createExpressionFromText(paramName + "." + expression.getText(), null);
replaceMap.put(expression, newExpression);
}
}
super.visitNewExpression(expression);
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
@Override public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
correctMethodCall(expression, true);
super.visitMethodCallExpression(expression);
}
});
for (PsiElement element : replaceMap.keySet()) {
final PsiElement replacement = replaceMap.get(element);
element.replace(replacement);
}
replaceReferences(body);
}
final PsiMethod methodCopy = getPatternMethod();
@@ -573,6 +474,108 @@ public class MoveInstanceMethodProcessor extends BaseRefactoringProcessor{
}
}
private void replaceReferences(PsiCodeBlock body) {
final PsiManager manager = myMethod.getManager();
JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject());
final PsiElementFactory factory = facade.getElementFactory();
final Map<PsiElement, PsiElement> replaceMap = new HashMap<>();
body.accept(new JavaRecursiveElementVisitor() {
@Override public void visitThisExpression(@NotNull PsiThisExpression expression) {
final PsiClass classReferencedByThis = MoveInstanceMembersUtil.getClassReferencedByThis(expression);
if (classReferencedByThis != null && !PsiTreeUtil.isAncestor(myMethod, classReferencedByThis, false)) {
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(myProject);
String paramName = getParameterNameToCreate(classReferencedByThis);
try {
final PsiExpression refExpression = factory.createExpressionFromText(paramName, null);
replaceMap.put(expression, refExpression);
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
}
@Override public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) {
try {
final PsiExpression qualifier = expression.getQualifierExpression();
final PsiElement resolved = expression.resolve();
if (ExpressionUtils.isReferenceTo(qualifier, myTargetVariable)) {
if (resolved instanceof PsiField) {
String fieldName = ((PsiField)resolved).getName();
for (PsiParameter parameter : myMethod.getParameterList().getParameters()) {
if (Comparing.strEqual(parameter.getName(), fieldName) ||
facade.getResolveHelper().resolveReferencedVariable(fieldName, expression) != null) {
qualifier.replace(factory.createExpressionFromText("this", null));
return;
}
}
}
if (expression instanceof PsiMethodReferenceExpression) {
qualifier.replace(factory.createExpressionFromText("this", null));
}
else {
//Target is a field, replace target.m -> m
qualifier.delete();
}
return;
}
if (myTargetVariable.equals(resolved)) {
PsiThisExpression thisExpression = RefactoringChangeUtil.createThisExpression(
manager, PsiTreeUtil.isAncestor(myMethod, ClassUtils.getContainingClass(expression), true) ? myTargetClass : null);
replaceMap.put(expression, thisExpression);
return;
}
if (!myMethod.equals(resolved)) {
PsiClass classReferencedByThis = MoveInstanceMembersUtil.getClassReferencedByThis(expression);
if (classReferencedByThis != null) {
final String paramName = getParameterNameToCreate(classReferencedByThis);
if (paramName != null) {
PsiReferenceExpression newQualifier = (PsiReferenceExpression)factory.createExpressionFromText(paramName, null);
expression.setQualifierExpression(newQualifier);
return;
}
}
}
super.visitReferenceExpression(expression);
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
@Override public void visitNewExpression(@NotNull PsiNewExpression expression) {
try {
final PsiExpression qualifier = expression.getQualifier();
if (ExpressionUtils.isReferenceTo(qualifier, myTargetVariable)) {
//Target is a field, replace target.new A() -> new A()
qualifier.delete();
} else {
final PsiClass classReferencedByThis = MoveInstanceMembersUtil.getClassReferencedByThis(expression);
if (classReferencedByThis != null) {
if (qualifier != null) qualifier.delete();
final String paramName = getParameterNameToCreate(classReferencedByThis);
final PsiExpression newExpression = factory.createExpressionFromText(paramName + "." + expression.getText(), null);
replaceMap.put(expression, newExpression);
}
}
super.visitNewExpression(expression);
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
@Override public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
correctMethodCall(expression, true);
super.visitMethodCallExpression(expression);
}
});
for (PsiElement element : replaceMap.keySet()) {
final PsiElement replacement = replaceMap.get(element);
element.replace(replacement);
}
}
private PsiMethod getPatternMethod() throws IncorrectOperationException {
final PsiMethod methodCopy = (PsiMethod)myMethod.copy();
String name = myTargetClass.isInterface()