mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
inline parameter: allow to inline as local for methods with usages (IDEA-65536) ; respect write access for parameters with constant values ( IDEA-65535)
This commit is contained in:
+20
-1
@@ -251,7 +251,8 @@ public class InlineParameterExpressionProcessor extends BaseRefactoringProcessor
|
||||
initializer.replace(localVarInitializer);
|
||||
final PsiCodeBlock body = myMethod.getBody();
|
||||
if (body != null) {
|
||||
body.addAfter(localDeclaration, body.getLBrace());
|
||||
PsiElement anchor = findAnchorForLocalVariableDeclaration(body);
|
||||
body.addAfter(localDeclaration, anchor);
|
||||
}
|
||||
} else {
|
||||
for (PsiJavaCodeReferenceElement paramRef : paramRefsToInline) {
|
||||
@@ -280,6 +281,24 @@ public class InlineParameterExpressionProcessor extends BaseRefactoringProcessor
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiElement findAnchorForLocalVariableDeclaration(PsiCodeBlock body) {
|
||||
PsiElement anchor = body.getLBrace();
|
||||
if (myMethod.isConstructor()) {
|
||||
final PsiStatement[] statements = body.getStatements();
|
||||
if (statements.length > 0 && statements[0] instanceof PsiExpressionStatement) {
|
||||
final PsiExpression expression = ((PsiExpressionStatement)statements[0]).getExpression();
|
||||
if (expression instanceof PsiMethodCallExpression) {
|
||||
final String referenceName = ((PsiMethodCallExpression)expression).getMethodExpression().getReferenceName();
|
||||
if (PsiKeyword.SUPER.equals(referenceName) || PsiKeyword.THIS.equals(referenceName)) {
|
||||
anchor = statements[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return anchor;
|
||||
}
|
||||
|
||||
private static class LocalReplacementUsageInfo extends UsageInfo {
|
||||
private final PsiElement myReplacement;
|
||||
private final PsiVariable myVariable;
|
||||
|
||||
@@ -108,35 +108,35 @@ public class InlineParameterHandler extends JavaInlineActionHandler {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (occurrences.isEmpty()) {
|
||||
final int offset = editor.getCaretModel().getOffset();
|
||||
final PsiElement refExpr = psiElement.getContainingFile().findElementAt(offset);
|
||||
final PsiCodeBlock codeBlock = PsiTreeUtil.getParentOfType(refExpr, PsiCodeBlock.class);
|
||||
if (codeBlock != null) {
|
||||
final PsiElement[] defs = DefUseUtil.getDefs(codeBlock, psiParameter, refExpr);
|
||||
if (defs.length == 1) {
|
||||
final PsiElement def = defs[0];
|
||||
if (def instanceof PsiReferenceExpression && PsiUtil.isOnAssignmentLeftHand((PsiExpression)def)) {
|
||||
final PsiExpression rExpr = ((PsiAssignmentExpression)def.getParent()).getRExpression();
|
||||
if (rExpr != null) {
|
||||
final PsiElement[] refs = DefUseUtil.getRefs(codeBlock, psiParameter, refExpr);
|
||||
final int offset = editor.getCaretModel().getOffset();
|
||||
final PsiElement refExpr = psiElement.getContainingFile().findElementAt(offset);
|
||||
final PsiCodeBlock codeBlock = PsiTreeUtil.getParentOfType(refExpr, PsiCodeBlock.class);
|
||||
if (codeBlock != null) {
|
||||
final PsiElement[] defs = DefUseUtil.getDefs(codeBlock, psiParameter, refExpr);
|
||||
if (defs.length == 1) {
|
||||
final PsiElement def = defs[0];
|
||||
if (def instanceof PsiReferenceExpression && PsiUtil.isOnAssignmentLeftHand((PsiExpression)def)) {
|
||||
final PsiExpression rExpr = ((PsiAssignmentExpression)def.getParent()).getRExpression();
|
||||
if (rExpr != null) {
|
||||
final PsiElement[] refs = DefUseUtil.getRefs(codeBlock, psiParameter, refExpr);
|
||||
|
||||
if (InlineLocalHandler.checkRefsInAugmentedAssignmentOrUnaryModified(refs) == null) {
|
||||
new WriteCommandAction(project) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
for (final PsiElement ref : refs) {
|
||||
InlineUtil.inlineVariable(psiParameter, rExpr, (PsiJavaCodeReferenceElement)ref);
|
||||
}
|
||||
def.getParent().delete();
|
||||
if (InlineLocalHandler.checkRefsInAugmentedAssignmentOrUnaryModified(refs) == null) {
|
||||
new WriteCommandAction(project) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
for (final PsiElement ref : refs) {
|
||||
InlineUtil.inlineVariable(psiParameter, rExpr, (PsiJavaCodeReferenceElement)ref);
|
||||
}
|
||||
}.execute();
|
||||
return;
|
||||
}
|
||||
def.getParent().delete();
|
||||
}
|
||||
}.execute();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (occurrences.isEmpty()) {
|
||||
CommonRefactoringUtil
|
||||
.showErrorHint(project, editor, "Method has no usages", RefactoringBundle.message("inline.parameter.refactoring"), null);
|
||||
return;
|
||||
@@ -182,6 +182,14 @@ public class InlineParameterHandler extends JavaInlineActionHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
for (PsiReference psiReference : ReferencesSearch.search(psiParameter)) {
|
||||
final PsiElement element = psiReference.getElement();
|
||||
if (element instanceof PsiExpression && PsiUtil.isAccessedForWriting((PsiExpression)element)) {
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, "Inline parameter which has write usages is not supported", RefactoringBundle.message("inline.parameter.refactoring"), null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
String occurencesString = RefactoringBundle.message("occurences.string", occurrences.size());
|
||||
String question = RefactoringBundle.message("inline.parameter.confirmation", psiParameter.getName(),
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
class Base {
|
||||
public Base() {
|
||||
}
|
||||
}
|
||||
|
||||
class Inheritor extends Base {
|
||||
public Inheritor(String b<caret>ar) {
|
||||
super();
|
||||
System.out.println(bar);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new Inheritor("bar".toString());
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
class Base {
|
||||
public Base() {
|
||||
}
|
||||
}
|
||||
|
||||
class Inheritor extends Base {
|
||||
public Inheritor() {
|
||||
super();
|
||||
String bar = "bar".toString();
|
||||
System.out.println(bar);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new Inheritor();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
class Clazz {
|
||||
public Clazz(String b<caret>ar) {
|
||||
bar = bar + bar;
|
||||
System.out.println(bar);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new Clazz("bar");
|
||||
}
|
||||
}
|
||||
@@ -135,6 +135,19 @@ public class InlineParameterTest extends LightCodeInsightTestCase {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
public void testLocalVarDeclarationInConstructor() throws Exception {
|
||||
doTest(true);
|
||||
}
|
||||
|
||||
public void testParameterWithWriteAccess() throws Exception {
|
||||
try {
|
||||
doTest(false);
|
||||
}
|
||||
catch (CommonRefactoringUtil.RefactoringErrorHintException e) {
|
||||
assertEquals("Inline parameter which has write usages is not supported", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testRefNewInnerFromMethod() throws Exception {
|
||||
try {
|
||||
doTest(false);
|
||||
|
||||
Reference in New Issue
Block a user