diff options
Diffstat (limited to 'java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSourceUtil.java')
-rw-r--r-- | java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSourceUtil.java | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSourceUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSourceUtil.java index 8cf5b5bfbdd2..e2af7b08df0d 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSourceUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSourceUtil.java @@ -15,13 +15,28 @@ */ package com.intellij.psi.impl.source.tree; +import com.intellij.lang.ASTFactory; import com.intellij.lang.ASTNode; +import com.intellij.lang.LighterAST; +import com.intellij.lang.LighterASTNode; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.impl.source.DummyHolder; import com.intellij.psi.impl.source.SourceJavaCodeReference; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; import com.intellij.util.CharTable; +import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; public class JavaSourceUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.JavaSourceUtil"); + + private static final TokenSet REF_FILTER = TokenSet.orSet( + ElementType.JAVA_COMMENT_OR_WHITESPACE_BIT_SET, TokenSet.create(JavaElementType.ANNOTATION)); + private JavaSourceUtil() { } public static void fullyQualifyReference(@NotNull CompositeElement reference, @NotNull PsiClass targetClass) { @@ -61,4 +76,70 @@ public class JavaSourceUtil { } } } + + @NotNull + public static String getReferenceText(@NotNull PsiJavaCodeReferenceElement ref) { + final StringBuilder buffer = new StringBuilder(); + + ((TreeElement)ref.getNode()).acceptTree(new RecursiveTreeElementWalkingVisitor() { + @Override + public void visitLeaf(LeafElement leaf) { + if (!REF_FILTER.contains(leaf.getElementType())) { + String leafText = leaf.getText(); + if (buffer.length() > 0 && !leafText.isEmpty() && Character.isJavaIdentifierPart(leafText.charAt(0))) { + char lastInBuffer = buffer.charAt(buffer.length() - 1); + if (lastInBuffer == '?' || Character.isJavaIdentifierPart(lastInBuffer)) { + buffer.append(" "); + } + } + + buffer.append(leafText); + } + } + + @Override + public void visitComposite(CompositeElement composite) { + if (!REF_FILTER.contains(composite.getElementType())) { + super.visitComposite(composite); + } + } + }); + + return buffer.toString(); + } + + @NotNull + public static String getReferenceText(@NotNull LighterAST tree, @NotNull LighterASTNode node) { + return LightTreeUtil.toFilteredString(tree, node, REF_FILTER); + } + + public static TreeElement addParenthToReplacedChild(@NotNull IElementType parenthType, + @NotNull TreeElement newChild, + @NotNull PsiManager manager) { + CompositeElement parenthExpr = ASTFactory.composite(parenthType); + + TreeElement dummyExpr = (TreeElement)newChild.clone(); + final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(newChild); + new DummyHolder(manager, parenthExpr, null, charTableByTree); + parenthExpr.putUserData(CharTable.CHAR_TABLE_KEY, charTableByTree); + parenthExpr.rawAddChildren(ASTFactory.leaf(JavaTokenType.LPARENTH, "(")); + parenthExpr.rawAddChildren(dummyExpr); + parenthExpr.rawAddChildren(ASTFactory.leaf(JavaTokenType.RPARENTH, ")")); + + try { + CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(manager.getProject()); + PsiElement formatted = codeStyleManager.reformat(SourceTreeToPsiMap.treeToPsiNotNull(parenthExpr)); + parenthExpr = (CompositeElement)SourceTreeToPsiMap.psiToTreeNotNull(formatted); + } + catch (IncorrectOperationException e) { + LOG.error(e); // should not happen + } + + newChild.putUserData(CharTable.CHAR_TABLE_KEY, SharedImplUtil.findCharTableByTree(newChild)); + dummyExpr.getTreeParent().replaceChild(dummyExpr, newChild); + + // TODO remove explicit caches drop since this should be ok if we will use ChangeUtil for the modification + TreeUtil.clearCaches(TreeUtil.getFileElement(parenthExpr)); + return parenthExpr; + } } |