mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
introduce field: resolve conflicts with constructor params (IDEA-91633)
This commit is contained in:
@@ -175,7 +175,7 @@ public abstract class LocalToFieldHandler {
|
||||
private static PsiExpressionStatement createAssignment(PsiLocalVariable local, String fieldname, PsiElementFactory factory) {
|
||||
try {
|
||||
String pattern = fieldname + "=0;";
|
||||
PsiExpressionStatement statement = (PsiExpressionStatement)factory.createStatementFromText(pattern, null);
|
||||
PsiExpressionStatement statement = (PsiExpressionStatement)factory.createStatementFromText(pattern, local);
|
||||
statement = (PsiExpressionStatement)CodeStyleManager.getInstance(local.getProject()).reformat(statement);
|
||||
|
||||
PsiAssignmentExpression expr = (PsiAssignmentExpression)statement.getExpression();
|
||||
@@ -212,6 +212,7 @@ public abstract class LocalToFieldHandler {
|
||||
PsiClass aClass = field.getContainingClass();
|
||||
PsiMethod[] constructors = aClass.getConstructors();
|
||||
PsiStatement assignment = createAssignment(local, field.getName(), factory);
|
||||
PsiExpression thisAccessExpr = factory.createExpressionFromText("this", null);
|
||||
boolean added = false;
|
||||
for (PsiMethod constructor : constructors) {
|
||||
if (constructor == enclosingConstructor) continue;
|
||||
@@ -228,7 +229,9 @@ public abstract class LocalToFieldHandler {
|
||||
continue;
|
||||
}
|
||||
if ("super".equals(text) && enclosingConstructor == null && PsiTreeUtil.isAncestor(constructor, local, false)) {
|
||||
ChangeContextUtil.encodeContextInfo(assignment, false);
|
||||
final PsiStatement statement = (PsiStatement)body.addAfter(assignment, first);
|
||||
ChangeContextUtil.decodeContextInfo(statement, field.getContainingClass(), thisAccessExpr);
|
||||
appendComments(local, statement);
|
||||
local.delete();
|
||||
return statement;
|
||||
@@ -236,14 +239,18 @@ public abstract class LocalToFieldHandler {
|
||||
}
|
||||
}
|
||||
if (enclosingConstructor == null && PsiTreeUtil.isAncestor(constructor, local, false)) {
|
||||
ChangeContextUtil.encodeContextInfo(assignment, false);
|
||||
final PsiStatement statement = (PsiStatement)body.addBefore(assignment, first);
|
||||
ChangeContextUtil.decodeContextInfo(statement, field.getContainingClass(), thisAccessExpr);
|
||||
appendComments(local, statement);
|
||||
local.delete();
|
||||
return statement;
|
||||
}
|
||||
}
|
||||
|
||||
ChangeContextUtil.encodeContextInfo(assignment, false);
|
||||
assignment = (PsiStatement)body.add(assignment);
|
||||
ChangeContextUtil.decodeContextInfo(assignment, field.getContainingClass(), thisAccessExpr);
|
||||
added = true;
|
||||
}
|
||||
if (!added && enclosingConstructor == null) {
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
class Foo {
|
||||
String foo = "foo";
|
||||
public final String fooBar;
|
||||
|
||||
public Foo(int foo) {
|
||||
fooBar = this.foo.subString(1);
|
||||
}
|
||||
|
||||
void bar() {
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
class Foo {
|
||||
String foo = "foo";
|
||||
public Foo(int foo) {
|
||||
}
|
||||
|
||||
void bar() {
|
||||
String fo<caret>oBar = foo.subString(1);
|
||||
}
|
||||
}
|
||||
+44
-38
@@ -34,28 +34,28 @@ public class IntroduceFieldInSameClassTest extends LightCodeInsightTestCase {
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return JavaTestUtil.getJavaTestDataPath();
|
||||
return JavaTestUtil.getJavaTestDataPath() + "/refactoring/introduceField/";
|
||||
}
|
||||
|
||||
public void testInClassInitializer() {
|
||||
configureByFile("/refactoring/introduceField/before1.java");
|
||||
configureByFile("before1.java");
|
||||
performRefactoring(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION, true);
|
||||
checkResultByFile("/refactoring/introduceField/after1.java");
|
||||
checkResultByFile("after1.java");
|
||||
}
|
||||
|
||||
public void testConflictingFieldInContainingClass() {
|
||||
configureByFile("/refactoring/introduceField/beforeConflictingFieldInContainingClass.java");
|
||||
configureByFile("beforeConflictingFieldInContainingClass.java");
|
||||
new MockIntroduceFieldHandler(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION, false) {
|
||||
@Override
|
||||
protected String getNewName(Project project, PsiExpression expr, PsiType type) {
|
||||
return "aField";
|
||||
}
|
||||
}.invoke(getProject(), myEditor, myFile, null);
|
||||
checkResultByFile("/refactoring/introduceField/afterConflictingFieldInContainingClass.java");
|
||||
checkResultByFile("afterConflictingFieldInContainingClass.java");
|
||||
}
|
||||
|
||||
public void testConflictingFieldInContainingClassLocal() {
|
||||
configureByFile("/refactoring/introduceField/beforeConflictingFieldInContainingClassLocal.java");
|
||||
configureByFile("beforeConflictingFieldInContainingClassLocal.java");
|
||||
new MockIntroduceFieldHandler(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION, false) {
|
||||
@Override
|
||||
protected String getNewName(Project project, PsiExpression expr, PsiType type) {
|
||||
@@ -67,78 +67,84 @@ public class IntroduceFieldInSameClassTest extends LightCodeInsightTestCase {
|
||||
return 0;
|
||||
}
|
||||
}.invoke(getProject(), myEditor, myFile, null);
|
||||
checkResultByFile("/refactoring/introduceField/afterConflictingFieldInContainingClassLocal.java");
|
||||
checkResultByFile("afterConflictingFieldInContainingClassLocal.java");
|
||||
}
|
||||
|
||||
public void testInElseClause() {
|
||||
configureByFile("/refactoring/introduceField/beforeElseClause.java");
|
||||
configureByFile("beforeElseClause.java");
|
||||
performRefactoring(BaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD, true);
|
||||
checkResultByFile("/refactoring/introduceField/afterElseClause.java");
|
||||
checkResultByFile("afterElseClause.java");
|
||||
}
|
||||
|
||||
public void testOuterClass() {
|
||||
configureByFile("/refactoring/introduceField/beforeOuterClass.java");
|
||||
configureByFile("beforeOuterClass.java");
|
||||
performRefactoring(BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR, false);
|
||||
checkResultByFile("/refactoring/introduceField/afterOuterClass.java");
|
||||
checkResultByFile("afterOuterClass.java");
|
||||
}
|
||||
|
||||
public void testConflictingConstructorParameter() {
|
||||
configureByFile("beforeConflictingConstructorParameter.java");
|
||||
performRefactoring(BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR, false);
|
||||
checkResultByFile("afterConflictingConstructorParameter.java");
|
||||
}
|
||||
|
||||
public void testOnClassLevelNoDuplicates() {
|
||||
configureByFile("/refactoring/introduceField/beforeOnClassLevelNoDuplicates.java");
|
||||
configureByFile("beforeOnClassLevelNoDuplicates.java");
|
||||
performRefactoring(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION, false);
|
||||
checkResultByFile("/refactoring/introduceField/afterOnClassLevelNoDuplicates.java");
|
||||
checkResultByFile("afterOnClassLevelNoDuplicates.java");
|
||||
}
|
||||
|
||||
public void testOnClassLevelDuplicates() {
|
||||
configureByFile("/refactoring/introduceField/beforeOnClassLevelDuplicates.java");
|
||||
configureByFile("beforeOnClassLevelDuplicates.java");
|
||||
performRefactoring(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION, false);
|
||||
checkResultByFile("/refactoring/introduceField/afterOnClassLevelDuplicates.java");
|
||||
checkResultByFile("afterOnClassLevelDuplicates.java");
|
||||
}
|
||||
|
||||
public void testOnClassLevelDuplicates1() {
|
||||
configureByFile("/refactoring/introduceField/beforeOnClassLevelDuplicates1.java");
|
||||
configureByFile("beforeOnClassLevelDuplicates1.java");
|
||||
performRefactoring(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION, false);
|
||||
checkResultByFile("/refactoring/introduceField/afterOnClassLevelDuplicates1.java");
|
||||
checkResultByFile("afterOnClassLevelDuplicates1.java");
|
||||
}
|
||||
|
||||
public void testOnClassLevelBinary() {
|
||||
configureByFile("/refactoring/introduceField/beforeOnClassLevelBinary.java");
|
||||
configureByFile("beforeOnClassLevelBinary.java");
|
||||
performRefactoring(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION, false);
|
||||
checkResultByFile("/refactoring/introduceField/afterOnClassLevelBinary.java");
|
||||
checkResultByFile("afterOnClassLevelBinary.java");
|
||||
}
|
||||
|
||||
//multiple error elements on class level corresponding to the extracted fragment ------------------
|
||||
public void testOnClassLevelNewExpression() {
|
||||
configureByFile("/refactoring/introduceField/beforeOnClassLevelNewExpression.java");
|
||||
configureByFile("beforeOnClassLevelNewExpression.java");
|
||||
performRefactoring(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION, false);
|
||||
checkResultByFile("/refactoring/introduceField/afterOnClassLevelNewExpression.java");
|
||||
checkResultByFile("afterOnClassLevelNewExpression.java");
|
||||
}
|
||||
|
||||
public void testOnClassLevelClassForName() {
|
||||
configureByFile("/refactoring/introduceField/beforeOnClassLevelClassForName.java");
|
||||
configureByFile("beforeOnClassLevelClassForName.java");
|
||||
performRefactoring(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION, false);
|
||||
checkResultByFile("/refactoring/introduceField/afterOnClassLevelClassForName.java");
|
||||
checkResultByFile("afterOnClassLevelClassForName.java");
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
public void testUnresolvedReferenceToLocalVar() {
|
||||
configureByFile("/refactoring/introduceField/beforeUnresolvedReferenceToLocalVar.java");
|
||||
configureByFile("beforeUnresolvedReferenceToLocalVar.java");
|
||||
performRefactoring(BaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD, false);
|
||||
checkResultByFile("/refactoring/introduceField/afterUnresolvedReferenceToLocalVar.java");
|
||||
checkResultByFile("afterUnresolvedReferenceToLocalVar.java");
|
||||
}
|
||||
|
||||
public void testForcedFieldType() {
|
||||
configureByFile("/refactoring/introduceField/beforeForcedFieldType.java");
|
||||
configureByFile("beforeForcedFieldType.java");
|
||||
new MockIntroduceFieldHandler(BaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD, false) {
|
||||
@Override
|
||||
protected PsiType getFieldType(PsiType type) {
|
||||
return PsiType.INT;
|
||||
}
|
||||
}.invoke(getProject(), myEditor, myFile, null);
|
||||
checkResultByFile("/refactoring/introduceField/afterForcedFieldType.java");
|
||||
checkResultByFile("afterForcedFieldType.java");
|
||||
}
|
||||
|
||||
public void testRejectIntroduceFieldFromExprInThisCall() {
|
||||
configureByFile("/refactoring/introduceField/beforeRejectIntroduceFieldFromExprInThisCall.java");
|
||||
configureByFile("beforeRejectIntroduceFieldFromExprInThisCall.java");
|
||||
try {
|
||||
performRefactoring(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION, false);
|
||||
fail("Should not proceed");
|
||||
@@ -149,38 +155,38 @@ public class IntroduceFieldInSameClassTest extends LightCodeInsightTestCase {
|
||||
}
|
||||
|
||||
public void testInConstructorEnclosingAnonymous() {
|
||||
configureByFile("/refactoring/introduceField/beforeEnclosingAnonymous.java");
|
||||
configureByFile("beforeEnclosingAnonymous.java");
|
||||
performRefactoring(BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR, false);
|
||||
checkResultByFile("/refactoring/introduceField/afterEnclosingAnonymous.java");
|
||||
checkResultByFile("afterEnclosingAnonymous.java");
|
||||
}
|
||||
|
||||
public void testLocalVarAnnotations() {
|
||||
configureByFile("/refactoring/introduceField/beforeLocalVarAnnotations.java");
|
||||
configureByFile("beforeLocalVarAnnotations.java");
|
||||
performRefactoring(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION, false);
|
||||
checkResultByFile("/refactoring/introduceField/afterLocalVarAnnotations.java");
|
||||
checkResultByFile("afterLocalVarAnnotations.java");
|
||||
}
|
||||
|
||||
public void testFromLambdaExpr() {
|
||||
configureByFile("/refactoring/introduceField/beforeFromLambdaExpr.java");
|
||||
configureByFile("beforeFromLambdaExpr.java");
|
||||
performRefactoring(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION, false);
|
||||
checkResultByFile("/refactoring/introduceField/afterFromLambdaExpr.java");
|
||||
checkResultByFile("afterFromLambdaExpr.java");
|
||||
}
|
||||
|
||||
public void testSimplifyDiamond() {
|
||||
configureByFile("/refactoring/introduceField/beforeSimplifiedDiamond.java");
|
||||
configureByFile("beforeSimplifiedDiamond.java");
|
||||
performRefactoring(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION, false);
|
||||
checkResultByFile("/refactoring/introduceField/afterSimplifiedDiamond.java");
|
||||
checkResultByFile("afterSimplifiedDiamond.java");
|
||||
}
|
||||
|
||||
public void testStaticFieldInInnerClass() {
|
||||
configureByFile("/refactoring/introduceField/beforeStaticFieldInInnerClass.java");
|
||||
configureByFile("beforeStaticFieldInInnerClass.java");
|
||||
new MockIntroduceFieldHandler(BaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD, false) {
|
||||
@Override
|
||||
protected int getChosenClassIndex(List<PsiClass> classes) {
|
||||
return 0;
|
||||
}
|
||||
}.invoke(getProject(), myEditor, myFile, null);
|
||||
checkResultByFile("/refactoring/introduceField/afterStaticFieldInInnerClass.java");
|
||||
checkResultByFile("afterStaticFieldInInnerClass.java");
|
||||
}
|
||||
|
||||
private static void performRefactoring(BaseExpressionToFieldHandler.InitializationPlace initializationPlace, boolean declareStatic) {
|
||||
|
||||
Reference in New Issue
Block a user