summaryrefslogtreecommitdiff
path: root/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/JavaReplaceHandler.java
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/JavaReplaceHandler.java')
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/JavaReplaceHandler.java500
1 files changed, 0 insertions, 500 deletions
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/JavaReplaceHandler.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/JavaReplaceHandler.java
deleted file mode 100644
index 36b8fff26afb..000000000000
--- a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/JavaReplaceHandler.java
+++ /dev/null
@@ -1,500 +0,0 @@
-package com.intellij.structuralsearch;
-
-import com.intellij.openapi.fileTypes.StdFileTypes;
-import com.intellij.openapi.project.Project;
-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.psi.xml.XmlText;
-import com.intellij.structuralsearch.impl.matcher.JavaMatchingVisitor;
-import com.intellij.structuralsearch.impl.matcher.MatcherImplUtil;
-import com.intellij.structuralsearch.impl.matcher.PatternTreeContext;
-import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
-import com.intellij.structuralsearch.plugin.replace.ReplacementInfo;
-import com.intellij.structuralsearch.plugin.replace.impl.ReplacementContext;
-import com.intellij.structuralsearch.plugin.replace.impl.Replacer;
-import com.intellij.structuralsearch.plugin.replace.impl.ReplacerUtil;
-import com.intellij.util.IncorrectOperationException;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author Eugene.Kudelevsky
- */
-public class JavaReplaceHandler extends StructuralReplaceHandler {
- private final ReplacementContext myContext;
- private PsiCodeBlock codeBlock;
-
- public JavaReplaceHandler(ReplacementContext context) {
- this.myContext = context;
- }
-
- private PsiCodeBlock getCodeBlock() throws IncorrectOperationException {
- if (codeBlock == null) {
- PsiCodeBlock search;
- search = (PsiCodeBlock)MatcherImplUtil.createTreeFromText(
- myContext.getOptions().getMatchOptions().getSearchPattern(),
- PatternTreeContext.Block,
- myContext.getOptions().getMatchOptions().getFileType(),
- myContext.getProject()
- )[0].getParent();
-
- codeBlock = search;
- }
- return codeBlock;
- }
-
- private static PsiElement findRealSubstitutionElement(PsiElement el) {
- if (el instanceof PsiIdentifier) {
- // matches are tokens, identifiers, etc
- el = el.getParent();
- }
-
- if (el instanceof PsiReferenceExpression &&
- el.getParent() instanceof PsiMethodCallExpression
- ) {
- // method
- el = el.getParent();
- }
-
- if (el instanceof PsiDeclarationStatement && ((PsiDeclarationStatement)el).getDeclaredElements()[0] instanceof PsiClass) {
- el = ((PsiDeclarationStatement)el).getDeclaredElements()[0];
- }
- return el;
- }
-
- private static boolean isListContext(PsiElement el) {
- boolean listContext = false;
- final PsiElement parent = el.getParent();
-
- if (parent instanceof PsiParameterList ||
- parent instanceof PsiExpressionList ||
- parent instanceof PsiCodeBlock ||
- parent instanceof PsiClass ||
- parent instanceof XmlText ||
- (parent instanceof PsiIfStatement &&
- (((PsiIfStatement)parent).getThenBranch() == el ||
- ((PsiIfStatement)parent).getElseBranch() == el
- )
- ) ||
- (parent instanceof PsiLoopStatement &&
- ((PsiLoopStatement)parent).getBody() == el
- )
- ) {
- listContext = true;
- }
-
- return listContext;
- }
-
- @Nullable
- private PsiNamedElement getSymbolReplacementTarget(final PsiElement el)
- throws IncorrectOperationException {
- if (myContext.getOptions().getMatchOptions().getFileType() != StdFileTypes.JAVA) return null; //?
- final PsiStatement[] searchStatements = getCodeBlock().getStatements();
- if (searchStatements.length > 0 &&
- searchStatements[0] instanceof PsiExpressionStatement) {
- final PsiExpression expression = ((PsiExpressionStatement)searchStatements[0]).getExpression();
-
- if (expression instanceof PsiReferenceExpression &&
- ((PsiReferenceExpression)expression).getQualifierExpression() == null
- ) {
- // looks like symbol replacements, namely replace AAA by BBB, so lets do the best
- if (el instanceof PsiNamedElement) {
- return (PsiNamedElement)el;
- }
- }
- }
-
- return null;
- }
-
- private static PsiElement getMatchExpr(PsiElement replacement, PsiElement elementToReplace) {
- if (replacement instanceof PsiExpressionStatement &&
- !(replacement.getLastChild() instanceof PsiJavaToken) &&
- !(replacement.getLastChild() instanceof PsiComment)
- ) {
- // replacement is expression (and pattern should be so)
- // assert ...
- replacement = ((PsiExpressionStatement)replacement).getExpression();
- }
- else if (replacement instanceof PsiDeclarationStatement &&
- ((PsiDeclarationStatement)replacement).getDeclaredElements().length == 1
- ) {
- return ((PsiDeclarationStatement)replacement).getDeclaredElements()[0];
- }
- else if (replacement instanceof PsiBlockStatement &&
- elementToReplace instanceof PsiCodeBlock
- ) {
- return ((PsiBlockStatement)replacement).getCodeBlock();
- }
-
- return replacement;
- }
-
- private boolean isSymbolReplacement(final PsiElement el) throws IncorrectOperationException {
- return getSymbolReplacementTarget(el) != null;
- }
-
- @SuppressWarnings({"unchecked", "ConstantConditions"})
- private void handleModifierList(final PsiElement el, final PsiElement replacement) throws IncorrectOperationException {
- // We want to copy all comments, including doc comments and modifier lists
- // that are present in matched nodes but not present in search/replace
-
- Map<String, String> newNameToSearchPatternNameMap = myContext.getNewName2PatternNameMap();
-
- ModifierListOwnerCollector collector = new ModifierListOwnerCollector();
- el.accept(collector);
- Map<String, PsiNamedElement> originalNamedElements = (Map<String, PsiNamedElement>)collector.namedElements.clone();
- collector.namedElements.clear();
-
- replacement.accept(collector);
- Map<String, PsiNamedElement> replacedNamedElements = (Map<String, PsiNamedElement>)collector.namedElements.clone();
- collector.namedElements.clear();
-
- if (originalNamedElements.size() == 0 && replacedNamedElements.size() == 0) {
- Replacer.handleComments(el, replacement, myContext);
- return;
- }
-
- final PsiStatement[] statements = getCodeBlock().getStatements();
- if (statements.length > 0) {
- statements[0].getParent().accept(collector);
- }
-
- Map<String, PsiNamedElement> searchedNamedElements = (Map<String, PsiNamedElement>)collector.namedElements.clone();
- collector.namedElements.clear();
-
- for (String name : originalNamedElements.keySet()) {
- PsiNamedElement originalNamedElement = originalNamedElements.get(name);
- PsiNamedElement replacementNamedElement = replacedNamedElements.get(name);
- String key = newNameToSearchPatternNameMap.get(name);
- if (key == null) key = name;
- PsiNamedElement searchNamedElement = searchedNamedElements.get(key);
-
- if (replacementNamedElement == null && originalNamedElements.size() == 1 && replacedNamedElements.size() == 1) {
- replacementNamedElement = replacedNamedElements.entrySet().iterator().next().getValue();
- }
-
- PsiElement comment = null;
-
- if (originalNamedElement instanceof PsiDocCommentOwner) {
- comment = ((PsiDocCommentOwner)originalNamedElement).getDocComment();
- if (comment == null) {
- PsiElement prevElement = originalNamedElement.getPrevSibling();
- if (prevElement instanceof PsiWhiteSpace) {
- prevElement = prevElement.getPrevSibling();
- }
- if (prevElement instanceof PsiComment) {
- comment = prevElement;
- }
- }
- }
-
- if (replacementNamedElement != null && searchNamedElement != null) {
- Replacer.handleComments(originalNamedElement, replacementNamedElement, myContext);
- }
-
- if (comment != null && replacementNamedElement instanceof PsiDocCommentOwner &&
- !(replacementNamedElement.getFirstChild() instanceof PsiDocComment)
- ) {
- final PsiElement nextSibling = comment.getNextSibling();
- PsiElement prevSibling = comment.getPrevSibling();
- replacementNamedElement.addRangeBefore(
- prevSibling instanceof PsiWhiteSpace ? prevSibling : comment,
- nextSibling instanceof PsiWhiteSpace ? nextSibling : comment,
- replacementNamedElement.getFirstChild()
- );
- }
-
- if (originalNamedElement instanceof PsiModifierListOwner &&
- replacementNamedElement instanceof PsiModifierListOwner
- ) {
- PsiModifierList modifierList = ((PsiModifierListOwner)originalNamedElements.get(name)).getModifierList();
-
- if (searchNamedElement instanceof PsiModifierListOwner) {
- PsiModifierList modifierListOfSearchedElement = ((PsiModifierListOwner)searchNamedElement).getModifierList();
- final PsiModifierListOwner modifierListOwner = ((PsiModifierListOwner)replacementNamedElement);
- PsiModifierList modifierListOfReplacement = modifierListOwner.getModifierList();
-
- if (modifierListOfSearchedElement.getTextLength() == 0 &&
- modifierListOfReplacement.getTextLength() == 0 &&
- modifierList.getTextLength() > 0
- ) {
- PsiElement space = modifierList.getNextSibling();
- if (!(space instanceof PsiWhiteSpace)) {
- space = createWhiteSpace(space);
- }
-
- modifierListOfReplacement.replace(modifierList);
- // copy space after modifier list
- if (space instanceof PsiWhiteSpace) {
- modifierListOwner.addRangeAfter(space, space, modifierListOwner.getModifierList());
- }
- } else if (modifierListOfSearchedElement.getTextLength() == 0 && modifierList.getTextLength() > 0) {
- modifierListOfReplacement.addRange(modifierList.getFirstChild(), modifierList.getLastChild());
- }
- }
- }
- }
- }
-
- private PsiElement handleSymbolReplacemenent(PsiElement replacement, final PsiElement el) throws IncorrectOperationException {
- PsiNamedElement nameElement = getSymbolReplacementTarget(el);
- if (nameElement != null) {
- PsiElement oldReplacement = replacement;
- replacement = el.copy();
- ((PsiNamedElement)replacement).setName(oldReplacement.getText());
- }
-
- return replacement;
- }
-
- public void replace(final ReplacementInfo info, ReplaceOptions options) {
- PsiElement elementToReplace = info.getMatch(0);
- PsiElement elementParent = elementToReplace.getParent();
- String replacementToMake = info.getReplacement();
- Project project = myContext.getProject();
- PsiElement el = findRealSubstitutionElement(elementToReplace);
- boolean listContext = isListContext(el);
-
- if (el instanceof PsiAnnotation && !StringUtil.startsWithChar(replacementToMake, '@')) {
- replacementToMake = "@" + replacementToMake;
- }
-
- PsiElement[] statements = ReplacerUtil
- .createTreeForReplacement(replacementToMake, el instanceof PsiMember && !isSymbolReplacement(el) ?
- PatternTreeContext.Class :
- PatternTreeContext.Block, myContext);
-
- if (listContext) {
- if (statements.length > 1) {
- elementParent.addRangeBefore(statements[0], statements[statements.length - 1], elementToReplace);
- }
- else if (statements.length == 1) {
- PsiElement replacement = getMatchExpr(statements[0], elementToReplace);
-
- handleModifierList(el, replacement);
- replacement = handleSymbolReplacemenent(replacement, el);
-
- if (replacement instanceof PsiTryStatement) {
- final List<PsiCatchSection> unmatchedCatchSections = el.getUserData(JavaMatchingVisitor.UNMATCHED_CATCH_SECTION_CONTENT_VAR_KEY);
- final PsiCatchSection[] catches = ((PsiTryStatement)replacement).getCatchSections();
-
- if (unmatchedCatchSections != null) {
- for (int i = unmatchedCatchSections.size() - 1; i >= 0; --i) {
- final PsiParameter parameter = unmatchedCatchSections.get(i).getParameter();
- final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory();
- final PsiCatchSection catchSection = elementFactory.createCatchSection(parameter.getType(), parameter.getName(), null);
-
- catchSection.getCatchBlock().replace(
- unmatchedCatchSections.get(i).getCatchBlock()
- );
- replacement.addAfter(
- catchSection, catches[catches.length - 1]
- );
- replacement.addBefore(createWhiteSpace(replacement), replacement.getLastChild());
- }
- }
- }
-
- try {
- final PsiElement inserted = elementParent.addBefore(replacement, elementToReplace);
-
- if (replacement instanceof PsiComment &&
- (elementParent instanceof PsiIfStatement ||
- elementParent instanceof PsiLoopStatement
- )
- ) {
- elementParent.addAfter(createSemicolon(replacement), inserted);
- }
- }
- catch (IncorrectOperationException e) {
- elementToReplace.replace(replacement);
- }
- }
- }
- else if (statements.length > 0) {
- PsiElement replacement = ReplacerUtil.copySpacesAndCommentsBefore(elementToReplace, statements, replacementToMake, elementParent);
-
- replacement = getMatchExpr(replacement, elementToReplace);
-
- if (replacement instanceof PsiStatement &&
- !(replacement.getLastChild() instanceof PsiJavaToken) &&
- !(replacement.getLastChild() instanceof PsiComment)
- ) {
- // assert w/o ;
- final PsiElement prevLastChildInParent = replacement.getLastChild().getPrevSibling();
-
- if (prevLastChildInParent != null) {
- elementParent.addRangeBefore(replacement.getFirstChild(), prevLastChildInParent, el);
- }
- else {
- elementParent.addBefore(replacement.getFirstChild(), el);
- }
-
- el.getNode().getTreeParent().removeChild(el.getNode());
- }
- else {
- // preserve comments
- handleModifierList(el, replacement);
-
- if (replacement instanceof PsiClass) {
- // modifier list
- final PsiStatement[] searchStatements = getCodeBlock().getStatements();
- if (searchStatements.length > 0 &&
- searchStatements[0] instanceof PsiDeclarationStatement &&
- ((PsiDeclarationStatement)searchStatements[0]).getDeclaredElements()[0] instanceof PsiClass
- ) {
- final PsiClass replaceClazz = (PsiClass)replacement;
- final PsiClass queryClazz = (PsiClass)((PsiDeclarationStatement)searchStatements[0]).getDeclaredElements()[0];
- final PsiClass clazz = (PsiClass)el;
-
- if (replaceClazz.getExtendsList().getTextLength() == 0 &&
- queryClazz.getExtendsList().getTextLength() == 0 &&
- clazz.getExtendsList().getTextLength() != 0
- ) {
- replaceClazz.addBefore(clazz.getExtendsList().getPrevSibling(), replaceClazz.getExtendsList()); // whitespace
- replaceClazz.getExtendsList().addRange(
- clazz.getExtendsList().getFirstChild(), clazz.getExtendsList().getLastChild()
- );
- }
-
- if (replaceClazz.getImplementsList().getTextLength() == 0 &&
- queryClazz.getImplementsList().getTextLength() == 0 &&
- clazz.getImplementsList().getTextLength() != 0
- ) {
- replaceClazz.addBefore(clazz.getImplementsList().getPrevSibling(), replaceClazz.getImplementsList()); // whitespace
- replaceClazz.getImplementsList().addRange(
- clazz.getImplementsList().getFirstChild(),
- clazz.getImplementsList().getLastChild()
- );
- }
-
- if (replaceClazz.getTypeParameterList().getTextLength() == 0 &&
- queryClazz.getTypeParameterList().getTextLength() == 0 &&
- clazz.getTypeParameterList().getTextLength() != 0
- ) {
- // skip < and >
- replaceClazz.getTypeParameterList().replace(
- clazz.getTypeParameterList()
- );
- }
- }
- }
-
- replacement = handleSymbolReplacemenent(replacement, el);
-
- el.replace(replacement);
- }
- }
- else {
- final PsiElement nextSibling = el.getNextSibling();
- el.delete();
- if (nextSibling instanceof PsiWhiteSpace && nextSibling.isValid()) {
- nextSibling.delete();
- }
- }
-
- if (listContext) {
- final int matchSize = info.getMatchesCount();
-
- for (int i = 0; i < matchSize; ++i) {
- PsiElement matchElement = info.getMatch(i);
- PsiElement element = findRealSubstitutionElement(matchElement);
-
- if (element == null) continue;
- PsiElement firstToDelete = element;
- PsiElement lastToDelete = element;
- PsiElement prevSibling = element.getPrevSibling();
- PsiElement nextSibling = element.getNextSibling();
-
- if (prevSibling instanceof PsiWhiteSpace) {
- firstToDelete = prevSibling;
- prevSibling = prevSibling != null ? prevSibling.getPrevSibling() : null;
- }
- else if (prevSibling == null && nextSibling instanceof PsiWhiteSpace) {
- lastToDelete = nextSibling;
- }
-
- if (nextSibling instanceof XmlText && i + 1 < matchSize) {
- final PsiElement next = info.getMatch(i + 1);
- if (next != null && next == nextSibling.getNextSibling()) {
- lastToDelete = nextSibling;
- }
- }
-
- if (element instanceof PsiExpression) {
- final PsiElement parent = element.getParent().getParent();
- if ((parent instanceof PsiCall ||
- parent instanceof PsiAnonymousClass
- ) &&
- prevSibling instanceof PsiJavaToken &&
- ((PsiJavaToken)prevSibling).getTokenType() == JavaTokenType.COMMA
- ) {
- firstToDelete = prevSibling;
- }
- }
- else if (element instanceof PsiParameter &&
- prevSibling instanceof PsiJavaToken &&
- ((PsiJavaToken)prevSibling).getTokenType() == JavaTokenType.COMMA
- ) {
- firstToDelete = prevSibling;
- }
-
- element.getParent().deleteChildRange(firstToDelete, lastToDelete);
- }
- }
-
- if (options.isToShortenFQN() && elementParent.isValid()) {
- JavaCodeStyleManager.getInstance(project).shortenClassReferences(elementParent, 0, elementParent.getTextLength());
- }
- }
-
- @Nullable
- private static PsiElement createSemicolon(final PsiElement space) throws IncorrectOperationException {
- final PsiStatement text = JavaPsiFacade.getInstance(space.getProject()).getElementFactory().createStatementFromText(";", null);
- return text.getFirstChild();
- }
-
- private static PsiElement createWhiteSpace(final PsiElement space) throws IncorrectOperationException {
- return PsiParserFacade.SERVICE.getInstance(space.getProject()).createWhiteSpaceFromText(" ");
- }
-
- private static class ModifierListOwnerCollector extends JavaRecursiveElementWalkingVisitor {
- HashMap<String, PsiNamedElement> namedElements = new HashMap<String, PsiNamedElement>(1);
-
- @Override
- public void visitClass(PsiClass aClass) {
- if (aClass instanceof PsiAnonymousClass) return;
- handleNamedElement(aClass);
- }
-
- private void handleNamedElement(final PsiNamedElement named) {
- String name = named.getName();
-
- assert name != null;
-
- if (StructuralSearchUtil.isTypedVariable(name)) {
- name = name.substring(1, name.length() - 1);
- }
-
- if (!namedElements.containsKey(name)) namedElements.put(name, named);
- named.acceptChildren(this);
- }
-
- @Override
- public void visitVariable(PsiVariable var) {
- handleNamedElement(var);
- }
-
- @Override
- public void visitMethod(PsiMethod method) {
- handleNamedElement(method);
- }
- }
-}