mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-refactoring] Rename conflicting local class
IDEA-332489 Inlining refactoring operation leads to naming conflicts GitOrigin-RevId: 4e239def02419e7a0a30097d3b3ec8cdb69911fd
This commit is contained in:
committed by
intellij-monorepo-bot
parent
4228eb556f
commit
21617c8137
+1
-1
@@ -655,7 +655,7 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
|
||||
BlockData blockData = prepareBlock(ref, helper);
|
||||
ChangeContextUtil.encodeContextInfo(blockData.block, false);
|
||||
helper.substituteTypes(blockData.parmVars);
|
||||
InlineUtil.solveVariableNameConflicts(blockData.block, ref, myMethodCopy.getBody());
|
||||
InlineUtil.solveLocalNameConflicts(blockData.block, ref, myMethodCopy.getBody());
|
||||
helper.initializeParameters(blockData.parmVars);
|
||||
addThisInitializer(methodCall, blockData.thisVar);
|
||||
|
||||
|
||||
+3
-3
@@ -101,7 +101,7 @@ public final class InlineObjectProcessor extends BaseRefactoringProcessor {
|
||||
InlineTransformer ctorTransformer = InlineTransformer.getSuitableTransformer(myMethod).apply(myReference);
|
||||
ctorTransformer.transformBody(ctorCopy, myReference, PsiTypes.voidType());
|
||||
PsiCodeBlock ctorBody = Objects.requireNonNull(ctorCopy.getBody());
|
||||
InlineUtil.solveVariableNameConflicts(ctorBody, target, ctorBody);
|
||||
InlineUtil.solveLocalNameConflicts(ctorBody, target, ctorBody);
|
||||
updateFieldRefs(ctorCopy, aClass);
|
||||
ctorParameters = addRange(target, ctorBody, ctorParameters);
|
||||
|
||||
@@ -110,7 +110,7 @@ public final class InlineObjectProcessor extends BaseRefactoringProcessor {
|
||||
InlineTransformer nextTransformer = InlineTransformer.getSuitableTransformer(myNextMethod).apply(myNextCall.getMethodExpression());
|
||||
PsiLocalVariable result = nextTransformer.transformBody(nextCopy, myNextCall.getMethodExpression(), myNextCall.getType());
|
||||
PsiCodeBlock nextBody = Objects.requireNonNull(nextCopy.getBody());
|
||||
InlineUtil.solveVariableNameConflicts(nextBody, target, nextBody);
|
||||
InlineUtil.solveLocalNameConflicts(nextBody, target, nextBody);
|
||||
updateFieldRefs(nextCopy, aClass);
|
||||
if (result != null) {
|
||||
PsiLocalVariable[] resultAndParameters = ArrayUtil.prepend(result, nextParameters);
|
||||
@@ -122,7 +122,7 @@ public final class InlineObjectProcessor extends BaseRefactoringProcessor {
|
||||
nextParameters = addRange(target, nextBody, nextParameters);
|
||||
}
|
||||
|
||||
InlineUtil.solveVariableNameConflicts(target, myReference.getElement(), target);
|
||||
InlineUtil.solveLocalNameConflicts(target, myReference.getElement(), target);
|
||||
ctorHelper.initializeParameters(ctorParameters);
|
||||
nextHelper.initializeParameters(nextParameters);
|
||||
|
||||
|
||||
@@ -30,11 +30,13 @@ import com.intellij.util.CommonJavaRefactoringUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.text.NameUtilCore;
|
||||
import com.siyeh.ig.psiutils.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.tryCast;
|
||||
|
||||
@@ -78,7 +80,7 @@ public final class InlineUtil implements CommonJavaInlineUtil {
|
||||
}
|
||||
}
|
||||
}
|
||||
solveVariableNameConflicts(initializer, ref, initializer);
|
||||
solveLocalNameConflicts(initializer, ref, initializer);
|
||||
|
||||
ChangeContextUtil.encodeContextInfo(initializer, false);
|
||||
PsiExpression expr = (PsiExpression)replaceDiamondWithInferredTypesIfNeeded(initializer, ref);
|
||||
@@ -299,33 +301,62 @@ public final class InlineUtil implements CommonJavaInlineUtil {
|
||||
return ref != initializer ? ref.replace(initializer) : initializer;
|
||||
}
|
||||
|
||||
public static void solveVariableNameConflicts(final PsiElement scope,
|
||||
final PsiElement placeToInsert,
|
||||
final PsiElement renameScope) throws IncorrectOperationException {
|
||||
if (scope instanceof PsiVariable var) {
|
||||
String name = var.getName();
|
||||
String oldName = name;
|
||||
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(scope.getProject());
|
||||
while (true) {
|
||||
String newName = codeStyleManager.suggestUniqueVariableName(name, placeToInsert, true);
|
||||
if (newName.equals(name)) break;
|
||||
name = newName;
|
||||
newName = codeStyleManager.suggestUniqueVariableName(name, var, true);
|
||||
if (newName.equals(name)) break;
|
||||
name = newName;
|
||||
}
|
||||
if (!name.equals(oldName)) {
|
||||
RefactoringUtil.renameVariableReferences(var, name, new LocalSearchScope(renameScope), true);
|
||||
var.getNameIdentifier().replace(JavaPsiFacade.getElementFactory(scope.getProject()).createIdentifier(name));
|
||||
public static void solveLocalNameConflicts(final PsiElement scope,
|
||||
final PsiElement placeToInsert,
|
||||
final PsiElement renameScope) {
|
||||
if (scope instanceof PsiVariable || scope instanceof PsiClass) {
|
||||
PsiNameIdentifierOwner named = (PsiNameIdentifierOwner)scope;
|
||||
String name = named.getName();
|
||||
PsiElement identifier = named.getNameIdentifier();
|
||||
if (name != null && identifier != null) {
|
||||
String oldName = name;
|
||||
Project project = scope.getProject();
|
||||
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
|
||||
BiFunction<PsiElement, String, String> suggester =
|
||||
scope instanceof PsiVariable ?
|
||||
(place, curName) -> codeStyleManager.suggestUniqueVariableName(curName, place, true) :
|
||||
(place, curName) -> suggestClassName(place, curName);
|
||||
while (true) {
|
||||
String newName = suggester.apply(placeToInsert, name);
|
||||
if (newName.equals(name)) break;
|
||||
name = newName;
|
||||
newName = suggester.apply(named, name);
|
||||
if (newName.equals(name)) break;
|
||||
name = newName;
|
||||
}
|
||||
if (!name.equals(oldName)) {
|
||||
for (PsiReference reference : ReferencesSearch.search(named, new LocalSearchScope(renameScope), true)) {
|
||||
reference.handleElementRename(name);
|
||||
}
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(scope.getProject());
|
||||
if (named instanceof PsiClass cls) {
|
||||
for (PsiMethod constructor : cls.getConstructors()) {
|
||||
if (!(constructor instanceof SyntheticElement) && constructor.getName().equals(oldName)) {
|
||||
Objects.requireNonNull(constructor.getNameIdentifier()).replace(factory.createIdentifier(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
Objects.requireNonNull(named.getNameIdentifier()).replace(factory.createIdentifier(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PsiElement[] children = scope.getChildren();
|
||||
for (PsiElement child : children) {
|
||||
solveVariableNameConflicts(child, placeToInsert, renameScope);
|
||||
solveLocalNameConflicts(child, placeToInsert, renameScope);
|
||||
}
|
||||
}
|
||||
|
||||
private static @NotNull String suggestClassName(@NotNull PsiElement place, @NotNull String name) {
|
||||
PsiResolveHelper helper = PsiResolveHelper.getInstance(place.getProject());
|
||||
return NameUtilCore.uniqName(
|
||||
name,
|
||||
n -> helper.resolveReferencedClass(n, place) != null ||
|
||||
place instanceof PsiClass && place.getParent() instanceof PsiDeclarationStatement decl &&
|
||||
decl.getParent() instanceof PsiCodeBlock block &&
|
||||
SyntaxTraverser.psiTraverser(block).filter(PsiClass.class).find(cls -> n.equals(cls.getName())) != null);
|
||||
}
|
||||
|
||||
public static boolean isChainingConstructor(PsiMethod constructor) {
|
||||
return CommonJavaRefactoringUtil.getChainedConstructor(constructor) != null;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
class TestCase{
|
||||
public void main() {
|
||||
class T {
|
||||
public T() {}
|
||||
}
|
||||
/*]*/fo<caret>o();/*[*/
|
||||
}
|
||||
|
||||
public void foo() {
|
||||
class T {
|
||||
T t;
|
||||
public T() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
class TestCase{
|
||||
public void main() {
|
||||
class T {
|
||||
public T() {}
|
||||
}
|
||||
/*]*//*[*/
|
||||
class T1 {
|
||||
T1 t;
|
||||
public T1() {}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
class TestCase{
|
||||
public void main() {
|
||||
class T1 {
|
||||
public T1() {}
|
||||
}
|
||||
fo<caret>o();
|
||||
}
|
||||
|
||||
public void foo() {
|
||||
class T1 {
|
||||
T1 t;
|
||||
public T1() {}
|
||||
}
|
||||
class T2 {
|
||||
T2 t;
|
||||
public T2() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
class TestCase{
|
||||
public void main() {
|
||||
class T1 {
|
||||
public T1() {}
|
||||
}
|
||||
class T3 {
|
||||
T3 t;
|
||||
public T3() {}
|
||||
}
|
||||
class T2 {
|
||||
T2 t;
|
||||
public T2() {}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -579,6 +579,10 @@ public class InlineMethodTest extends LightRefactoringTestCase {
|
||||
public void testSplitIfAndCollapseBack() { doTest(); }
|
||||
|
||||
public void testThisVariableName() { doTest(); }
|
||||
|
||||
public void testRenameLocalClass() { doTest(); }
|
||||
|
||||
public void testRenameLocalClassDoubleConflict() { doTest(); }
|
||||
|
||||
@Override
|
||||
protected Sdk getProjectJDK() {
|
||||
|
||||
Reference in New Issue
Block a user