preserve comments: bring var to scope (IDEA-182644)

This commit is contained in:
Anna.Kozlova
2017-11-24 16:14:28 +01:00
parent 17b49034d6
commit 08530510b2
4 changed files with 33 additions and 50 deletions
@@ -26,6 +26,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.Query;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.CommentTracker;
import com.siyeh.ig.psiutils.HighlightUtils;
import com.siyeh.ig.psiutils.VariableAccessUtils;
import org.jetbrains.annotations.NonNls;
@@ -95,6 +96,7 @@ public class TooBroadScopeInspection extends TooBroadScopeInspectionBase {
return;
}
PsiDeclarationStatement newDeclaration;
CommentTracker tracker = new CommentTracker();
if (commonParent instanceof PsiForStatement) {
final PsiForStatement forStatement = (PsiForStatement)commonParent;
final PsiStatement initialization = forStatement.getInitialization();
@@ -109,14 +111,14 @@ public class TooBroadScopeInspection extends TooBroadScopeInspectionBase {
}
final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)expression;
final PsiExpression rhs = assignmentExpression.getRExpression();
newDeclaration = createNewDeclaration(variable, rhs);
newDeclaration = createNewDeclaration(variable, rhs, tracker);
}
else {
newDeclaration = createNewDeclaration(variable, initializer);
newDeclaration = createNewDeclaration(variable, initializer, tracker);
}
newDeclaration = (PsiDeclarationStatement)initialization.replace(newDeclaration);
} else if (firstReferenceScope.equals(commonParent)) {
newDeclaration = moveDeclarationToLocation(variable, referenceElement);
newDeclaration = moveDeclarationToLocation(variable, referenceElement, tracker);
}
else {
final PsiElement commonParentChild = ScopeUtils.getChildWhichContainsElement(commonParent, referenceElement);
@@ -124,32 +126,35 @@ public class TooBroadScopeInspection extends TooBroadScopeInspectionBase {
return;
}
final PsiElement location = commonParentChild.getPrevSibling();
newDeclaration = createNewDeclaration(variable, initializer);
newDeclaration = createNewDeclaration(variable, initializer, tracker);
newDeclaration = (PsiDeclarationStatement)commonParent.addAfter(newDeclaration, location);
}
final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project);
newDeclaration = (PsiDeclarationStatement)codeStyleManager.reformat(newDeclaration);
removeOldVariable(variable);
removeOldVariable(variable, tracker);
tracker.insertCommentsBefore(newDeclaration);
if (isOnTheFly()) {
HighlightUtils.highlightElement(newDeclaration);
}
}
private void removeOldVariable(@NotNull PsiVariable variable) {
private void removeOldVariable(@NotNull PsiVariable variable, CommentTracker tracker) {
final PsiDeclarationStatement declaration = (PsiDeclarationStatement)variable.getParent();
if (declaration == null) {
return;
}
final PsiElement[] declaredElements = declaration.getDeclaredElements();
if (declaredElements.length == 1) {
declaration.delete();
tracker.delete(declaration);
}
else {
variable.delete();
tracker.delete(variable);
}
}
private PsiDeclarationStatement createNewDeclaration(@NotNull PsiVariable variable, @Nullable PsiExpression initializer) {
private PsiDeclarationStatement createNewDeclaration(@NotNull PsiVariable variable,
@Nullable PsiExpression initializer,
CommentTracker tracker) {
final Project project = variable.getProject();
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
final PsiElementFactory factory = psiFacade.getElementFactory();
@@ -157,22 +162,16 @@ public class TooBroadScopeInspection extends TooBroadScopeInspectionBase {
if (name == null) {
name = "";
}
final String comment;
if (initializer == null || initializer.getParent() == variable) {
comment = getCommentText(variable);
}
else {
comment = getCommentText(variable) + getCommentText(initializer);
}
final PsiType type = variable.getType();
@NonNls final String statementText;
final String typeText = type.getCanonicalText();
if (initializer == null) {
statementText = typeText + ' ' + name + ';' + comment;
statementText = typeText + ' ' + name + ';';
}
else {
final String initializerText = initializer.getText();
statementText = typeText + ' ' + name + '=' + initializerText + ';' + comment;
final String initializerText = tracker.markUnchanged(initializer).getText();
statementText = typeText + ' ' + name + '=' + initializerText + ';';
}
final PsiDeclarationStatement newDeclaration = (PsiDeclarationStatement)factory.createStatementFromText(statementText, variable);
final PsiLocalVariable newVariable = (PsiLocalVariable)newDeclaration.getDeclaredElements()[0];
@@ -186,30 +185,10 @@ public class TooBroadScopeInspection extends TooBroadScopeInspectionBase {
return newDeclaration;
}
private String getCommentText(PsiElement element) {
final PsiElement parent = PsiTreeUtil.getParentOfType(element, PsiStatement.class, true, PsiMember.class);
if (parent == null) {
return "";
}
if (parent instanceof PsiDeclarationStatement) {
final PsiDeclarationStatement parentDeclaration = (PsiDeclarationStatement)parent;
final PsiElement[] declaredElements = parentDeclaration.getDeclaredElements();
if (declaredElements.length != 1) {
return "";
}
}
final PsiElement lastChild = parent.getLastChild();
if (!(lastChild instanceof PsiComment)) {
return "";
}
final PsiElement prevSibling = lastChild.getPrevSibling();
if (prevSibling instanceof PsiWhiteSpace) {
return prevSibling.getText() + lastChild.getText();
}
return lastChild.getText();
}
private PsiDeclarationStatement moveDeclarationToLocation(@NotNull PsiVariable variable, @NotNull PsiElement location) {
private PsiDeclarationStatement moveDeclarationToLocation(@NotNull PsiVariable variable,
@NotNull PsiElement location,
CommentTracker tracker) {
PsiStatement statement = PsiTreeUtil.getParentOfType(location, PsiStatement.class, false);
assert statement != null;
PsiElement statementParent = statement.getParent();
@@ -228,22 +207,22 @@ public class TooBroadScopeInspection extends TooBroadScopeInspectionBase {
final PsiExpression lhs = assignmentExpression.getLExpression();
final IElementType tokenType = assignmentExpression.getOperationTokenType();
if (location.equals(lhs) && JavaTokenType.EQ == tokenType && !VariableAccessUtils.variableIsUsed(variable, rhs)) {
PsiDeclarationStatement newDeclaration = createNewDeclaration(variable, rhs);
PsiDeclarationStatement newDeclaration = createNewDeclaration(variable, rhs, tracker);
newDeclaration = (PsiDeclarationStatement)statementParent.addBefore(newDeclaration, statement);
final PsiElement parent = assignmentExpression.getParent();
assert parent != null;
parent.delete();
tracker.delete(parent);
return newDeclaration;
}
}
}
PsiDeclarationStatement newDeclaration = createNewDeclaration(variable, initializer);
PsiDeclarationStatement newDeclaration = createNewDeclaration(variable, initializer, tracker);
if (statement instanceof PsiForStatement) {
final PsiForStatement forStatement = (PsiForStatement)statement;
final PsiStatement initialization = forStatement.getInitialization();
newDeclaration = (PsiDeclarationStatement)forStatement.addBefore(newDeclaration, initialization);
if (initialization != null) {
initialization.delete();
tracker.delete(initialization);
}
return newDeclaration;
}
@@ -3,7 +3,10 @@ import java.io.*;
public class Comments {
void a() {
try (PrintStream out = System.out) {
int s = out.hashCode(); // a // b
// b
/*some comment inside old declaration*/
// a
int s = out.hashCode(/*inside initializer*/);
out.println(s);
}
}
@@ -2,9 +2,9 @@ import java.io.*;
public class Comments {
void a() {
int <caret>s; // a
int /*some comment inside old declaration*/ <caret>s; // a
try (PrintStream out = System.out) {
s = out.hashCode(); // b
s = out.hashCode(/*inside initializer*/); // b
out.println(s);
}
}
@@ -4,7 +4,8 @@ class Comments2 {
if (data == 0) {
throw new IllegalArgumentException("DATA_CANT_BE_ZERO");
}
int alpha = (data) + 5; // !!!
// !!!
int alpha = (data) + 5;
return process(alpha);
}