@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; }
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); }
protected static void clearRelativeOffsets(TreeElement element) { TreeElement cur = element; while (cur != null && cur.myStartOffsetInParent != -1) { cur.myStartOffsetInParent = -1; cur = cur.getTreeNext(); } }
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; } }
// 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); }
@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; } }
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; }
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 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; } }
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; }