protected static void clearRelativeOffsets(TreeElement element) { TreeElement cur = element; while (cur != null && cur.myStartOffsetInParent != -1) { cur.myStartOffsetInParent = -1; cur = cur.getTreeNext(); } }
@Override public int getStartOffset() { int result = 0; TreeElement current = this; while (current.myParent != null) { result += current.getStartOffsetInParent(); current = current.myParent; } return result; }
@Override public Object clone() { TreeElement clone = (TreeElement) super.clone(); synchronized (PsiLock.LOCK) { clone.myNextSibling = null; clone.myPrevSibling = null; clone.myParent = null; clone.myStartOffsetInParent = -1; } return clone; }
public void replaceChildInternal(@NotNull ASTNode child, @NotNull TreeElement newElement) { if (newElement.getElementType() == JavaElementType.IMPORT_LIST) { LOG.assertTrue(child.getElementType() == JavaElementType.IMPORT_LIST); if (newElement.getFirstChildNode() == null) { // empty import list ASTNode next = child.getTreeNext(); if (next != null && next.getElementType() == TokenType.WHITE_SPACE) { removeChild(next); } } } super.replaceChildInternal(child, newElement); }
public PsiManagerEx getManager() { TreeElement element; for (element = this; element.getTreeParent() != null; element = element.getTreeParent()) {} if (element instanceof FileElement) { // TODO!! return element.getManager(); } else { if (getTreeParent() != null) { return getTreeParent().getManager(); } return null; } }
@Nullable public static ASTNode findDocComment(@NotNull CompositeElement element) { TreeElement node = element.getFirstChildNode(); while (node != null && (isWhitespaceOrComment(node) && !(node.getPsi() instanceof PsiDocComment))) { node = node.getTreeNext(); } if (node != null && node.getElementType() == JavaDocElementType.DOC_COMMENT) { return node; } else { return null; } }
protected final void rawInsertAfterMeWithoutNotifications(TreeElement firstNew) { firstNew.rawRemoveUpToWithoutNotifications(null, false); final CompositeElement p = getTreeParent(); final TreeElement treeNext = getTreeNext(); firstNew.setTreePrev(this); setTreeNext(firstNew); while (true) { final TreeElement n = firstNew.getTreeNext(); assert n != this : "Attempt to create cycle"; firstNew.setTreeParent(p); if (n == null) break; firstNew = n; } if (treeNext == null) { if (p != null) { firstNew.setTreeParent(p); p.setLastChildNode(firstNew); } } else { firstNew.setTreeNext(treeNext); treeNext.setTreePrev(firstNew); } DebugUtil.checkTreeStructure(this); }
@Override public ASTNode parseContents(ASTNode chameleon) { final CharTable table = SharedImplUtil.findCharTableByTree(chameleon); final FileElement treeElement = new DummyHolder(((TreeElement) chameleon).getManager(), null, table).getTreeElement(); final PsiFile file = (PsiFile) TreeUtil.getFileElement((TreeElement) chameleon).getPsi(); PsiFile originalFile = file.getOriginalFile(); final TemplateLanguageFileViewProvider viewProvider = (TemplateLanguageFileViewProvider) originalFile.getViewProvider(); final Language language = getTemplateFileLanguage(viewProvider); final CharSequence chars = chameleon.getChars(); final PsiFile templateFile = createTemplateFile(file, language, chars, viewProvider); final TreeElement parsed = ((PsiFileImpl) templateFile).calcTreeElement(); Lexer langLexer = LanguageParserDefinitions.INSTANCE.forLanguage(language).createLexer(file.getProject()); final Lexer lexer = new MergingLexerAdapter( new TemplateBlackAndWhiteLexer( createBaseLexer(viewProvider), langLexer, myTemplateElementType, myOuterElementType), TokenSet.create(myTemplateElementType, myOuterElementType)); lexer.start(chars); insertOuters(parsed, lexer, table); if (parsed != null) { final TreeElement element = parsed.getFirstChildNode(); if (element != null) { ((CompositeElement) parsed).rawRemoveAllChildren(); treeElement.rawAddChildren(element); } } treeElement.subtreeChanged(); TreeElement childNode = treeElement.getFirstChildNode(); DebugUtil.checkTreeStructure(parsed); DebugUtil.checkTreeStructure(treeElement); DebugUtil.checkTreeStructure(chameleon); DebugUtil.checkTreeStructure(file.getNode()); DebugUtil.checkTreeStructure(originalFile.getNode()); return childNode; }
@Override public TreeElement addInternal(TreeElement first, ASTNode last, ASTNode anchor, Boolean before) { boolean needToAddNewline = false; if (first == last && first.getElementType() == DOC_TAG) { if (anchor == null) { anchor = getLastChildNode(); // this is a '*/' final ASTNode prevBeforeWS = TreeUtil.skipElementsBack(anchor.getTreePrev(), ElementType.JAVA_WHITESPACE_BIT_SET); if (prevBeforeWS != null) { anchor = prevBeforeWS; before = Boolean.FALSE; } else { before = Boolean.TRUE; } needToAddNewline = true; } if (anchor.getElementType() != DOC_TAG) { final CharTable charTable = SharedImplUtil.findCharTableByTree(this); final TreeElement newLine = Factory.createSingleLeafElement(DOC_COMMENT_DATA, "\n", 0, 1, charTable, getManager()); final TreeElement leadingAsterisk = Factory.createSingleLeafElement( DOC_COMMENT_LEADING_ASTERISKS, "*", 0, 1, charTable, getManager()); final TreeElement commentData = Factory.createSingleLeafElement(DOC_COMMENT_DATA, " ", 0, 1, charTable, getManager()); final TreeElement indentWS = Factory.createSingleLeafElement(DOC_COMMENT_DATA, " ", 0, 1, charTable, getManager()); newLine.getTreeParent().addChild(indentWS); newLine.getTreeParent().addChild(leadingAsterisk); newLine.getTreeParent().addChild(commentData); super.addInternal(newLine, commentData, anchor, Boolean.FALSE); anchor = commentData; before = Boolean.FALSE; } else { needToAddNewline = true; } } if (before) anchor.getTreeParent().addChildren(first, last.getTreeNext(), anchor); else anchor.getTreeParent().addChildren(first, last.getTreeNext(), anchor.getTreeNext()); if (needToAddNewline) { if (first.getTreePrev() != null && first.getTreePrev().getElementType() == DOC_TAG) { addNewLineToTag((CompositeElement) first.getTreePrev(), getProject()); } if (first.getTreeNext() != null && first.getTreeNext().getElementType() == DOC_TAG) { addNewLineToTag((CompositeElement) first, getProject()); } else { removeEndingAsterisksFromTag((CompositeElement) first); } } return first; }
public static boolean containsWhiteSpacesOnly(@Nullable ASTNode node) { if (node == null) return false; final boolean[] spacesOnly = {true}; ((TreeElement) node) .acceptTree( new RecursiveTreeElementWalkingVisitor() { @Override public void visitComposite(CompositeElement composite) { if (!spacesOnly(composite)) { super.visitComposite(composite); } } @Override public void visitLeaf(LeafElement leaf) { if (!spacesOnly(leaf)) { spacesOnly[0] = false; stopWalking(); } } }); return spacesOnly[0]; }
@Override public PsiElement getMirror() { TreeElement mirrorTreeElement = myMirrorFileElement; if (mirrorTreeElement == null) { synchronized (myMirrorLock) { mirrorTreeElement = myMirrorFileElement; if (mirrorTreeElement == null) { VirtualFile file = getVirtualFile(); PsiClass[] classes = getClasses(); String fileName = (classes.length > 0 ? classes[0].getName() : file.getNameWithoutExtension()) + JavaFileType.DOT_DEFAULT_EXTENSION; final Document document = FileDocumentManager.getInstance().getDocument(file); assert document != null : file.getUrl(); CharSequence mirrorText = document.getImmutableCharSequence(); boolean internalDecompiler = StringUtil.startsWith(mirrorText, BANNER); PsiFileFactory factory = PsiFileFactory.getInstance(getManager().getProject()); PsiFile mirror = factory.createFileFromText(fileName, JavaLanguage.INSTANCE, mirrorText, false, false); mirror.putUserData(PsiUtil.FILE_LANGUAGE_LEVEL_KEY, getLanguageLevel()); mirrorTreeElement = SourceTreeToPsiMap.psiToTreeNotNull(mirror); try { final TreeElement finalMirrorTreeElement = mirrorTreeElement; ProgressManager.getInstance() .executeNonCancelableSection( new Runnable() { @Override public void run() { setMirror(finalMirrorTreeElement); putUserData(CLS_DOCUMENT_LINK_KEY, document); } }); } catch (InvalidMirrorException e) { //noinspection ThrowableResultOfMethodCallIgnored LOG.error(file.getUrl(), internalDecompiler ? e : wrapException(e, file)); } ((PsiFileImpl) mirror).setOriginalFile(this); myMirrorFileElement = mirrorTreeElement; } } } return mirrorTreeElement.getPsi(); }
private static void addReferencesInRange( ArrayList<ASTNode> array, TreeElement parent, int startOffset, int endOffset) { if (parent.getElementType() == JavaElementType.JAVA_CODE_REFERENCE || parent.getElementType() == JavaElementType.REFERENCE_EXPRESSION) { array.add(parent); return; } if (parent.getPsi() instanceof PsiFile && JspPsiUtil.isInJspFile(parent.getPsi())) { final JspFile jspFile = JspPsiUtil.getJspFile(parent.getPsi()); JspClass jspClass = (JspClass) jspFile.getJavaClass(); addReferencesInRange(array, (TreeElement) jspClass.getNode(), startOffset, endOffset); return; } addReferencesInRangeForComposite(array, parent, startOffset, endOffset); }
public final int getStartOffsetInParent() { if (myParent == null) return -1; int offsetInParent = myStartOffsetInParent; if (offsetInParent != -1) return offsetInParent; synchronized (START_OFFSET_LOCK) { TreeElement cur = this; offsetInParent = myStartOffsetInParent; if (offsetInParent != -1) return offsetInParent; ApplicationManager.getApplication().assertReadAccessAllowed(); while (true) { TreeElement prev = cur.getTreePrev(); if (prev == null) break; cur = prev; offsetInParent = cur.myStartOffsetInParent; if (offsetInParent != -1) break; } if (offsetInParent == -1) { cur.myStartOffsetInParent = offsetInParent = 0; } while (cur != this) { TreeElement next = cur.getTreeNext(); offsetInParent += cur.getTextLength(); next.myStartOffsetInParent = offsetInParent; cur = next; } return offsetInParent; } }
private static boolean spacesOnly(@Nullable TreeElement node) { if (node == null) return false; if (isWhitespaceOrEmpty(node)) return true; PsiElement psi = node.getPsi(); if (psi == null) { return false; } Language language = psi.getLanguage(); return WhiteSpaceFormattingStrategyFactory.getStrategy(language).containsWhitespacesOnly(node); }
public PomModelEvent runInner() throws IncorrectOperationException { final ASTNode anchor = expandTag(); if (myChild.getElementType() == XmlElementType.XML_TAG) { // compute where to insert tag according to DTD or XSD final XmlElementDescriptor parentDescriptor = getDescriptor(); final XmlTag[] subTags = getSubTags(); final PsiElement declaration = parentDescriptor != null ? parentDescriptor.getDeclaration() : null; // filtring out generated dtds if (declaration != null && declaration.getContainingFile() != null && declaration.getContainingFile().isPhysical() && subTags.length > 0) { final XmlElementDescriptor[] childElementDescriptors = parentDescriptor.getElementsDescriptors(XmlTagImpl.this); int subTagNum = -1; for (final XmlElementDescriptor childElementDescriptor : childElementDescriptors) { final String childElementName = childElementDescriptor.getName(); while (subTagNum < subTags.length - 1 && subTags[subTagNum + 1].getName().equals(childElementName)) { subTagNum++; } if (childElementName.equals( XmlChildRole.START_TAG_NAME_FINDER.findChild(myChild).getText())) { // insert child just after anchor // insert into the position specified by index if (subTagNum >= 0) { final ASTNode subTag = (ASTNode) subTags[subTagNum]; if (subTag.getTreeParent() != XmlTagImpl.this) { // in entity final XmlEntityRef entityRef = PsiTreeUtil.getParentOfType(subTags[subTagNum], XmlEntityRef.class); throw new IncorrectOperationException( "Can't insert subtag to the entity. Entity reference text: " + (entityRef == null ? "" : entityRef.getText())); } myNewElement = XmlTagImpl.super.addInternal(myChild, myChild, subTag, Boolean.FALSE); } else { final ASTNode child = XmlChildRole.START_TAG_END_FINDER.findChild(XmlTagImpl.this); myNewElement = XmlTagImpl.super.addInternal(myChild, myChild, child, Boolean.FALSE); } return null; } } } else { final ASTNode child = XmlChildRole.CLOSING_TAG_START_FINDER.findChild(XmlTagImpl.this); myNewElement = XmlTagImpl.super.addInternal(myChild, myChild, child, Boolean.TRUE); return null; } } myNewElement = XmlTagImpl.super.addInternal(myChild, myChild, anchor, Boolean.TRUE); return null; }
public void rawRemove() { final TreeElement next = getTreeNext(); final CompositeElement parent = getTreeParent(); final TreeElement prev = getTreePrev(); if (prev != null) { prev.setTreeNext(next); } else if (parent != null) { parent.setFirstChildNode(next); } if (next != null) { next.setTreePrev(prev); } else if (parent != null) { parent.setLastChildNode(prev); } DebugUtil.checkTreeStructure(parent); DebugUtil.checkTreeStructure(prev); DebugUtil.checkTreeStructure(next); invalidate(); }
public ASTNode encodeXmlTextContents(String displayText, PsiElement text) { final PsiFile containingFile = text.getContainingFile(); CharTable charTable = SharedImplUtil.findCharTableByTree(text.getNode()); final FileElement dummyParent = DummyHolderFactory.createHolder(text.getManager(), null, charTable).getTreeElement(); final XmlTag rootTag = ((XmlFile) PsiFileFactory.getInstance(containingFile.getProject()) .createFileFromText("a.xml", "<a>" + displayText + "</a>")) .getRootTag(); assert rootTag != null; final XmlTagChild[] tagChildren = rootTag.getValue().getChildren(); final XmlTagChild child = tagChildren.length > 0 ? tagChildren[0] : null; LOG.assertTrue(child != null, "Child is null for tag: " + rootTag.getText()); final TreeElement element = (TreeElement) child.getNode(); ((TreeElement) tagChildren[tagChildren.length - 1].getNode().getTreeNext()).rawRemoveUpToLast(); dummyParent.rawAddChildren(element); TreeUtil.clearCaches(dummyParent); return element.getFirstChildNode(); }
private static void addReferencesInRangeForComposite( final ArrayList<ASTNode> array, final TreeElement parent, final int startOffset, final int endOffset) { int offset = 0; for (TreeElement child = parent.getFirstChildNode(); child != null; child = child.getTreeNext()) { int length = child.getTextLength(); if (startOffset <= offset + length && offset <= endOffset) { final IElementType type = child.getElementType(); if (type == JavaElementType.JAVA_CODE_REFERENCE || type == JavaElementType.REFERENCE_EXPRESSION) { array.add(child); } else { addReferencesInRangeForComposite(array, child, startOffset - offset, endOffset - offset); } } offset += length; } }
@Override public TreeElement addInternal(TreeElement first, ASTNode last, ASTNode anchor, Boolean before) { if (first.getElementType() == NAME_VALUE_PAIR && last.getElementType() == NAME_VALUE_PAIR) { final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this); ASTNode lparenth = findChildByRole(ChildRole.LPARENTH); if (lparenth == null) { LeafElement created = Factory.createSingleLeafElement(LPARENTH, "(", 0, 1, treeCharTab, getManager()); super.addInternal(created, created, getFirstChildNode(), true); } ASTNode rparenth = findChildByRole(ChildRole.RPARENTH); if (rparenth == null) { LeafElement created = Factory.createSingleLeafElement(RPARENTH, ")", 0, 1, treeCharTab, getManager()); super.addInternal(created, created, getLastChildNode(), false); } final ASTNode[] nodes = getChildren(NAME_VALUE_PAIR_BIT_SET); if (nodes.length == 1) { final ASTNode node = nodes[0]; if (node instanceof PsiNameValuePair) { final PsiNameValuePair pair = (PsiNameValuePair) node; if (pair.getName() == null) { final String text = pair.getValue().getText(); try { final PsiAnnotation annotation = JavaPsiFacade.getInstance(getProject()) .getElementFactory() .createAnnotationFromText("@AAA(value = " + text + ")", null); replaceChild(node, annotation.getParameterList().getAttributes()[0].getNode()); } catch (IncorrectOperationException e) { LOG.error(e); } } } } if (anchor == null && before != null) { anchor = findChildByRole(before.booleanValue() ? ChildRole.RPARENTH : ChildRole.LPARENTH); } } return super.addInternal(first, last, anchor, before); }
public TreeElement addInternal(TreeElement first, ASTNode last, ASTNode anchor, Boolean beforeB) { TreeElement firstAppended = null; boolean before = beforeB == null || beforeB.booleanValue(); try { TreeElement next; do { next = first.getTreeNext(); if (firstAppended == null) { firstAppended = addInternal(first, anchor, before); anchor = firstAppended; } else { anchor = addInternal(first, anchor, false); } } while (first != last && (first = next) != null); } catch (IncorrectOperationException ignored) { } finally { clearCaches(); } return firstAppended; }
private void insertOuters(TreeElement root, Lexer lexer, final CharTable table) { TreePatcher patcher = TREE_PATCHER.forLanguage(root.getPsi().getLanguage()); int treeOffset = 0; LeafElement leaf = TreeUtil.findFirstLeaf(root); while (lexer.getTokenType() != null) { IElementType tt = lexer.getTokenType(); if (tt != myTemplateElementType) { while (leaf != null && treeOffset < lexer.getTokenStart()) { treeOffset += leaf.getTextLength(); if (treeOffset > lexer.getTokenStart()) { leaf = patcher.split( leaf, leaf.getTextLength() - (treeOffset - lexer.getTokenStart()), table); treeOffset = lexer.getTokenStart(); } leaf = (LeafElement) TreeUtil.nextLeaf(leaf); } if (leaf == null) break; final OuterLanguageElementImpl newLeaf = createOuterLanguageElement(lexer, table, myOuterElementType); patcher.insert(leaf.getTreeParent(), leaf, newLeaf); leaf.getTreeParent().subtreeChanged(); leaf = newLeaf; } lexer.advance(); } if (lexer.getTokenType() != null) { assert lexer.getTokenType() != myTemplateElementType; final OuterLanguageElementImpl newLeaf = createOuterLanguageElement(lexer, table, myOuterElementType); ((CompositeElement) root).rawAddChildren(newLeaf); ((CompositeElement) root).subtreeChanged(); } }
public void rawInsertBeforeMe(@NotNull TreeElement firstNew) { final TreeElement anchorPrev = getTreePrev(); if (anchorPrev == null) { firstNew.rawRemoveUpToLast(); final CompositeElement p = getTreeParent(); if (p != null) p.setFirstChildNode(firstNew); while (true) { final TreeElement treeNext = firstNew.getTreeNext(); assert treeNext != this : "Attempt to create cycle"; firstNew.setTreeParent(p); if (treeNext == null) break; firstNew = treeNext; } setTreePrev(firstNew); firstNew.setTreeNext(this); if (p != null) { p.subtreeChanged(); } } else anchorPrev.rawInsertAfterMe(firstNew); DebugUtil.checkTreeStructure(this); }
private TreeElement addInternal(TreeElement child, ASTNode anchor, boolean before) throws IncorrectOperationException { final PomModel model = PomManager.getModel(getProject()); if (anchor != null && child.getElementType() == XmlElementType.XML_TEXT) { XmlText psi = null; if (anchor.getPsi() instanceof XmlText) { psi = (XmlText) anchor.getPsi(); } else { final ASTNode other = before ? anchor.getTreePrev() : anchor.getTreeNext(); if (other != null && other.getPsi() instanceof XmlText) { before = !before; psi = (XmlText) other.getPsi(); } } if (psi != null) { if (before) { psi.insertText(((XmlText) child.getPsi()).getValue(), 0); } else { psi.insertText(((XmlText) child.getPsi()).getValue(), psi.getValue().length()); } return (TreeElement) psi.getNode(); } } LOG.assertTrue(child.getPsi() instanceof XmlAttribute || child.getPsi() instanceof XmlTagChild); final InsertTransaction transaction; if (child.getElementType() == XmlElementType.XML_ATTRIBUTE) { transaction = new InsertAttributeTransaction(child, anchor, before, model); } else if (anchor == null) { transaction = getBodyInsertTransaction(child); } else { transaction = new GenericInsertTransaction(child, anchor, before); } model.runTransaction(transaction); return transaction.getFirstInserted(); }
private List<Pair<StubBasedPsiElementBase, CompositeElement>> calcStubAstBindings( final ASTNode root, final Document cachedDocument) { final StubTree stubTree = derefStub(); if (stubTree == null) { return Collections.emptyList(); } final Iterator<StubElement<?>> stubs = stubTree.getPlainList().iterator(); stubs.next(); // Skip file stub; final List<Pair<StubBasedPsiElementBase, CompositeElement>> result = ContainerUtil.newArrayList(); final StubBuilder builder = ((IStubFileElementType) getContentElementType()).getBuilder(); LazyParseableElement.setSuppressEagerPsiCreation(true); try { ((TreeElement) root) .acceptTree( new RecursiveTreeElementWalkingVisitor() { @Override protected void visitNode(TreeElement node) { CompositeElement parent = node.getTreeParent(); if (parent != null && builder.skipChildProcessingWhenBuildingStubs(parent, node)) { return; } IElementType type = node.getElementType(); if (type instanceof IStubElementType && ((IStubElementType) type).shouldCreateStub(node)) { if (!stubs.hasNext()) { reportStubAstMismatch( "Stub list is less than AST, last AST element: " + node.getElementType() + " " + node, stubTree, cachedDocument); } final StubElement stub = stubs.next(); if (stub.getStubType() != node.getElementType()) { reportStubAstMismatch( "Stub and PSI element type mismatch in " + getName() + ": stub " + stub + ", AST " + node.getElementType() + "; " + node, stubTree, cachedDocument); } PsiElement psi = stub.getPsi(); assert psi != null : "Stub " + stub + " (" + stub.getClass() + ") has returned null PSI"; result.add(Pair.create((StubBasedPsiElementBase) psi, (CompositeElement) node)); } super.visitNode(node); } }); } finally { LazyParseableElement.setSuppressEagerPsiCreation(false); } if (stubs.hasNext()) { reportStubAstMismatch( "Stub list in " + getName() + " has more elements than PSI", stubTree, cachedDocument); } return result; }
private static void createActionsMap( @NotNull List<ASTNode> astNodes, @NotNull FileViewProvider provider, @NotNull final TreeSet<PostprocessFormattingTask> rangesToProcess) { final Set<ASTNode> nodesToProcess = new HashSet<ASTNode>(astNodes); final Document document = provider.getDocument(); if (document == null) { return; } for (final ASTNode node : astNodes) { nodesToProcess.remove(node); final FileElement fileElement = TreeUtil.getFileElement((TreeElement) node); if (fileElement == null || ((PsiFile) fileElement.getPsi()).getViewProvider() != provider) continue; final boolean isGenerated = CodeEditUtil.isNodeGenerated(node); ((TreeElement) node) .acceptTree( new RecursiveTreeElementVisitor() { boolean inGeneratedContext = !isGenerated; @Override protected boolean visitNode(TreeElement element) { if (nodesToProcess.contains(element)) return false; final boolean currentNodeGenerated = CodeEditUtil.isNodeGenerated(element); CodeEditUtil.setNodeGenerated(element, false); if (currentNodeGenerated && !inGeneratedContext) { rangesToProcess.add( new ReformatTask(document.createRangeMarker(element.getTextRange()))); inGeneratedContext = true; } if (!currentNodeGenerated && inGeneratedContext) { if (element.getElementType() == TokenType.WHITE_SPACE) return false; final int oldIndent = CodeEditUtil.getOldIndentation(element); CodeEditUtil.setOldIndentation(element, -1); LOG.assertTrue( oldIndent >= 0, "for not generated items old indentation must be defined: element " + element); for (TextRange indentRange : getEnabledRanges(element.getPsi())) { rangesToProcess.add( new ReindentTask(document.createRangeMarker(indentRange), oldIndent)); } inGeneratedContext = false; } return true; } private Iterable<TextRange> getEnabledRanges(@NotNull PsiElement element) { List<TextRange> disabledRanges = new ArrayList<TextRange>(); for (DisabledIndentRangesProvider rangesProvider : DisabledIndentRangesProvider.EP_NAME.getExtensions()) { Collection<TextRange> providedDisabledRanges = rangesProvider.getDisabledIndentRanges(element); if (providedDisabledRanges != null) { disabledRanges.addAll(providedDisabledRanges); } } return TextRangeUtil.excludeRanges(element.getTextRange(), disabledRanges); } @Override public void visitComposite(CompositeElement composite) { boolean oldGeneratedContext = inGeneratedContext; super.visitComposite(composite); inGeneratedContext = oldGeneratedContext; } @Override public void visitLeaf(LeafElement leaf) { boolean oldGeneratedContext = inGeneratedContext; super.visitLeaf(leaf); inGeneratedContext = oldGeneratedContext; } }); } }
// remove nodes from this[including] to end[excluding] from the parent protected final void rawRemoveUpToWithoutNotifications(TreeElement end, boolean invalidate) { if (this == end) return; final CompositeElement parent = getTreeParent(); final TreeElement startPrev = getTreePrev(); final TreeElement endPrev = end != null ? end.getTreePrev() : null; assert end == null || end.getTreeParent() == parent : "Trying to remove non-child"; if (end != null) { TreeElement element; for (element = this; element != end && element != null; element = element.getTreeNext()) ; assert element == end : end + " is not successor of " + this + " in the .getTreeNext() chain"; } if (parent != null) { if (this == parent.getFirstChildNode()) { parent.setFirstChildNode(end); } if (end == null) { parent.setLastChildNode(startPrev); } } if (startPrev != null) { startPrev.setTreeNext(end); } if (end != null) { end.setTreePrev(startPrev); } setTreePrev(null); if (endPrev != null) { endPrev.setTreeNext(null); } if (parent != null) { for (TreeElement element = this; element != null; element = element.getTreeNext()) { element.setTreeParent(null); if (invalidate) { element.onInvalidated(); } } } DebugUtil.checkTreeStructure(parent); DebugUtil.checkTreeStructure(this); }
public TreeElement process(TreeElement element, boolean addImports, boolean uncompleteCode) { IElementType elementType = element.getElementType(); if (elementType == JavaElementType.JAVA_CODE_REFERENCE || elementType == JavaElementType.REFERENCE_EXPRESSION) { final IElementType parentElementType = element.getTreeParent().getElementType(); if (elementType == JavaElementType.JAVA_CODE_REFERENCE || parentElementType == JavaElementType.REFERENCE_EXPRESSION || parentElementType == JavaElementType.METHOD_REF_EXPRESSION || uncompleteCode) { final PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement) SourceTreeToPsiMap.treeElementToPsi(element); final PsiReferenceParameterList parameterList = ref.getParameterList(); if (parameterList != null) { final PsiTypeElement[] typeParameters = parameterList.getTypeParameterElements(); for (PsiTypeElement typeParameter : typeParameters) { process( (TreeElement) SourceTreeToPsiMap.psiElementToTree(typeParameter), addImports, uncompleteCode); } } boolean rightKind = true; if (elementType == JavaElementType.JAVA_CODE_REFERENCE) { int kind = ((PsiJavaCodeReferenceElementImpl) element).getKind(); rightKind = kind == PsiJavaCodeReferenceElementImpl.CLASS_NAME_KIND || kind == PsiJavaCodeReferenceElementImpl.CLASS_OR_PACKAGE_NAME_KIND; } if (rightKind) { boolean isInsideDocComment = TreeUtil.findParent(element, JavaDocElementType.DOC_COMMENT) != null; boolean isShort = !((SourceJavaCodeReference) element).isQualified(); if (!makeFQ(isInsideDocComment)) { if (isShort) return element; // short name already, no need to change } PsiElement refElement; if (!uncompleteCode) { refElement = ref.resolve(); } else { PsiResolveHelper helper = JavaPsiFacade.getInstance(element.getManager().getProject()).getResolveHelper(); refElement = helper.resolveReferencedClass( ((SourceJavaCodeReference) element).getClassNameText(), SourceTreeToPsiMap.treeElementToPsi(element)); } if (refElement instanceof PsiClass) { if (makeFQ(isInsideDocComment)) { String qName = ((PsiClass) refElement).getQualifiedName(); if (qName == null) return element; PsiImportHolder file = (PsiImportHolder) SourceTreeToPsiMap.treeElementToPsi(element).getContainingFile(); if (file instanceof PsiJavaFile && ImportHelper.isImplicitlyImported(qName, (PsiJavaFile) file)) { if (isShort) return element; return (TreeElement) makeShortReference( (CompositeElement) element, (PsiClass) refElement, addImports); } if (file instanceof PsiJavaFile) { String thisPackageName = ((PsiJavaFile) file).getPackageName(); if (ImportHelper.hasPackage(qName, thisPackageName)) { if (!isShort) { return (TreeElement) makeShortReference( (CompositeElement) element, (PsiClass) refElement, addImports); } } } return (TreeElement) replaceReferenceWithFQ(element, (PsiClass) refElement); } else { int oldLength = element.getTextLength(); TreeElement treeElement = (TreeElement) makeShortReference( (CompositeElement) element, (PsiClass) refElement, addImports); if (treeElement.getTextLength() == oldLength && ((PsiClass) refElement).getContainingClass() != null) { PsiElement qualifier = ref.getQualifier(); if (qualifier instanceof PsiJavaCodeReferenceElement && ((PsiJavaCodeReferenceElement) qualifier).resolve() instanceof PsiClass) { process((TreeElement) qualifier.getNode(), addImports, uncompleteCode); } } return treeElement; } } } } } for (TreeElement child = element.getFirstChildNode(); child != null; child = child.getTreeNext()) { child = process(child, addImports, uncompleteCode); } return element; }
private static void createActionsMap( final List<ASTNode> astNodes, final FileViewProvider provider, final TreeSet<PostprocessFormattingTask> rangesToProcess) { final Set<ASTNode> nodesToProcess = new HashSet<ASTNode>(astNodes); final Document document = provider.getDocument(); for (final ASTNode node : astNodes) { nodesToProcess.remove(node); final FileElement fileElement = TreeUtil.getFileElement((TreeElement) node); if (fileElement == null || ((PsiFile) fileElement.getPsi()).getViewProvider() != provider) continue; final boolean isGenerated = CodeEditUtil.isNodeGenerated(node); ((TreeElement) node) .acceptTree( new RecursiveTreeElementVisitor() { boolean inGeneratedContext = !isGenerated; protected boolean visitNode(TreeElement element) { if (nodesToProcess.contains(element)) return false; if (CodeEditUtil.isPostponedFormattingDisabled(element)) return false; final boolean currentNodeGenerated = CodeEditUtil.isNodeGenerated(element); CodeEditUtil.setNodeGenerated(element, false); if (currentNodeGenerated && !inGeneratedContext) { rangesToProcess.add( new ReformatTask(document.createRangeMarker(element.getTextRange()))); inGeneratedContext = true; } if (!currentNodeGenerated && inGeneratedContext) { if (element.getElementType() == TokenType.WHITE_SPACE) return false; final int oldIndent = CodeEditUtil.getOldIndentation(element); LOG.assertTrue( oldIndent >= 0, "for not generated items old indentation must be defined: element " + element); rangesToProcess.add( new ReindentTask( document.createRangeMarker(element.getTextRange()), oldIndent)); inGeneratedContext = false; } return true; } @Override public void visitComposite(CompositeElement composite) { boolean oldGeneratedContext = inGeneratedContext; super.visitComposite(composite); inGeneratedContext = oldGeneratedContext; } @Override public void visitLeaf(LeafElement leaf) { boolean oldGeneratedContext = inGeneratedContext; super.visitLeaf(leaf); inGeneratedContext = oldGeneratedContext; } }); CodeEditUtil.enablePostponedFormattingInTree(node); } }