mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
SSR: keep unmatched resource lists and finally blocks when replacing try/catch statements
This commit is contained in:
+24
-7
@@ -5,7 +5,8 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.structuralsearch.impl.matcher.JavaMatchingVisitor;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.structuralsearch.impl.matcher.GlobalMatchingVisitor;
|
||||
import com.intellij.structuralsearch.impl.matcher.MatcherImplUtil;
|
||||
import com.intellij.structuralsearch.impl.matcher.PatternTreeContext;
|
||||
import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
|
||||
@@ -282,14 +283,24 @@ public class JavaReplaceHandler extends StructuralReplaceHandler {
|
||||
replacement = handleSymbolReplacement(replacement, el);
|
||||
|
||||
if (replacement instanceof PsiTryStatement) {
|
||||
final List<PsiCatchSection> unmatchedCatchSections = el.getUserData(JavaMatchingVisitor.UNMATCHED_CATCH_SECTION_CONTENT_VAR_KEY);
|
||||
if (unmatchedCatchSections != null) {
|
||||
final PsiTryStatement tryStatement = (PsiTryStatement)replacement;
|
||||
final PsiTryStatement tryStatement = (PsiTryStatement)replacement;
|
||||
final List<PsiElement> unmatchedElements = el.getUserData(GlobalMatchingVisitor.UNMATCHED_ELEMENTS_KEY);
|
||||
if (unmatchedElements != null) {
|
||||
final PsiElement firstElement = unmatchedElements.get(0);
|
||||
if (firstElement instanceof PsiResourceList) addElementAfterAnchor(tryStatement, firstElement, tryStatement.getFirstChild());
|
||||
final PsiCatchSection[] catches = tryStatement.getCatchSections();
|
||||
final PsiElement anchor = catches.length == 0 ? tryStatement.getTryBlock() : catches[catches.length - 1];
|
||||
for (int i = unmatchedCatchSections.size() - 1; i >= 0; --i) {
|
||||
replacement.addAfter(unmatchedCatchSections.get(i), anchor);
|
||||
replacement.addAfter(createWhiteSpace(replacement), anchor);
|
||||
for (int i = unmatchedElements.size() - 1; i >= 0; i--) {
|
||||
final PsiElement element = unmatchedElements.get(i);
|
||||
if ((element instanceof PsiCatchSection)) addElementAfterAnchor(tryStatement, element, anchor);
|
||||
}
|
||||
final PsiElement lastElement = unmatchedElements.get(unmatchedElements.size() - 1);
|
||||
if (lastElement instanceof PsiCodeBlock) {
|
||||
final PsiElement finallyKeyword = PsiTreeUtil.skipSiblingsBackward(lastElement, PsiWhiteSpace.class);
|
||||
assert finallyKeyword != null;
|
||||
final PsiElement finallyAnchor = tryStatement.getLastChild();
|
||||
addElementAfterAnchor(tryStatement, lastElement, finallyAnchor);
|
||||
addElementAfterAnchor(tryStatement, finallyKeyword, finallyAnchor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -436,6 +447,12 @@ public class JavaReplaceHandler extends StructuralReplaceHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private static void addElementAfterAnchor(PsiElement parentElement, PsiElement element, PsiElement anchor) {
|
||||
parentElement.addAfter(element, anchor);
|
||||
final PsiElement sibling = element.getPrevSibling();
|
||||
if (sibling instanceof PsiWhiteSpace) parentElement.addAfter(sibling, anchor); // recycle whitespace
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcess(PsiElement affectedElement, ReplaceOptions options) {
|
||||
if (!affectedElement.isValid()) {
|
||||
|
||||
+16
-15
@@ -2,7 +2,6 @@ package com.intellij.structuralsearch.impl.matcher;
|
||||
|
||||
import com.intellij.dupLocator.iterators.ArrayBackedNodeIterator;
|
||||
import com.intellij.dupLocator.iterators.NodeIterator;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
@@ -34,7 +33,6 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
PsiModifier.PUBLIC, PsiModifier.PROTECTED, PsiModifier.PRIVATE, PsiModifier.STATIC, PsiModifier.ABSTRACT, PsiModifier.FINAL,
|
||||
PsiModifier.NATIVE, PsiModifier.SYNCHRONIZED, PsiModifier.STRICTFP, PsiModifier.TRANSIENT, PsiModifier.VOLATILE, PsiModifier.DEFAULT
|
||||
};
|
||||
public static final Key<List<PsiCatchSection>> UNMATCHED_CATCH_SECTION_CONTENT_VAR_KEY = Key.create("UnmatchedCatchSection");
|
||||
private final GlobalMatchingVisitor myMatchingVisitor;
|
||||
private PsiClass myClazz;
|
||||
|
||||
@@ -1334,7 +1332,6 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
final PsiTryStatement try2 = (PsiTryStatement)myMatchingVisitor.getElement();
|
||||
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.matchSons(try1.getTryBlock(), try2.getTryBlock()));
|
||||
|
||||
if (!myMatchingVisitor.getResult()) return;
|
||||
|
||||
final PsiResourceList resourceList1 = try1.getResourceList();
|
||||
@@ -1354,6 +1351,8 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
myMatchingVisitor.setResult(false);
|
||||
}
|
||||
else {
|
||||
final List<PsiElement> unmatchedElements = new ArrayList<PsiElement>();
|
||||
|
||||
if (resourceList1 != null) {
|
||||
if (resourceList2 == null) {
|
||||
myMatchingVisitor.setResult(false);
|
||||
@@ -1366,11 +1365,11 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
resourceVariables2.toArray(new PsiResourceVariable[resourceVariables2.size()])));
|
||||
if (!myMatchingVisitor.getResult()) return;
|
||||
}
|
||||
else if (resourceList2 != null){
|
||||
unmatchedElements.add(resourceList2);
|
||||
}
|
||||
|
||||
final List<PsiCatchSection> unmatchedCatchSections = new ArrayList<PsiCatchSection>();
|
||||
|
||||
ContainerUtil.addAll(unmatchedCatchSections, catches2);
|
||||
|
||||
ContainerUtil.addAll(unmatchedElements, catches2);
|
||||
for (PsiCatchSection catchSection : catches1) {
|
||||
final MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(catchSection);
|
||||
final PsiElement pinnedNode = handler.getPinnedNode(null);
|
||||
@@ -1380,15 +1379,15 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
if (!myMatchingVisitor.getResult()) return;
|
||||
}
|
||||
else {
|
||||
int j;
|
||||
for (j = 0; j < unmatchedCatchSections.size(); ++j) {
|
||||
if (handler.match(catchSection, unmatchedCatchSections.get(j), myMatchingVisitor.getMatchContext())) {
|
||||
unmatchedCatchSections.remove(j);
|
||||
boolean matched = false;
|
||||
for (int j = 0; j < unmatchedElements.size(); ++j) {
|
||||
if (handler.match(catchSection, unmatchedElements.get(j), myMatchingVisitor.getMatchContext())) {
|
||||
unmatchedElements.remove(j);
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == catches2.length) {
|
||||
if (!matched) {
|
||||
myMatchingVisitor.setResult(false);
|
||||
return;
|
||||
}
|
||||
@@ -1397,10 +1396,12 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
|
||||
if (finally1 != null) {
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.matchSons(finally1, finally2));
|
||||
} else if (finally2 != null) {
|
||||
unmatchedElements.add(finally2);
|
||||
}
|
||||
|
||||
if (myMatchingVisitor.getResult() && unmatchedCatchSections.size() > 0) {
|
||||
try2.putUserData(UNMATCHED_CATCH_SECTION_CONTENT_VAR_KEY, unmatchedCatchSections);
|
||||
if (myMatchingVisitor.getResult() && unmatchedElements.size() > 0) {
|
||||
try2.putUserData(GlobalMatchingVisitor.UNMATCHED_ELEMENTS_KEY, unmatchedElements);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user