下面列出了com.intellij.psi.impl.source.tree.TreeUtil#prevLeaf ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static void markToReformatBeforeOrInsertWhitespace(final ASTNode left, @Nonnull final ASTNode right) {
final Language leftLang = left != null ? PsiUtilCore.getNotAnyLanguage(left) : null;
final Language rightLang = PsiUtilCore.getNotAnyLanguage(right);
ASTNode generatedWhitespace = null;
if (leftLang != null && leftLang.isKindOf(rightLang)) {
generatedWhitespace = LanguageTokenSeparatorGenerators.INSTANCE.forLanguage(leftLang).generateWhitespaceBetweenTokens(left, right);
}
else if (rightLang.isKindOf(leftLang)) {
generatedWhitespace = LanguageTokenSeparatorGenerators.INSTANCE.forLanguage(rightLang).generateWhitespaceBetweenTokens(left, right);
}
if (generatedWhitespace != null) {
final TreeUtil.CommonParentState parentState = new TreeUtil.CommonParentState();
TreeUtil.prevLeaf((TreeElement)right, parentState);
parentState.nextLeafBranchStart.getTreeParent().addChild(generatedWhitespace, parentState.nextLeafBranchStart);
}
else {
markToReformatBefore(right, true);
}
}
private static int getMatchingLength(@Nonnull FileElement treeElement, @Nonnull CharSequence text, boolean fromStart) {
int patternIndex = fromStart ? 0 : text.length() - 1;
int finalPatternIndex = fromStart ? text.length() - 1 : 0;
int direction = fromStart ? 1 : -1;
ASTNode leaf = fromStart ? TreeUtil.findFirstLeaf(treeElement, false) : TreeUtil.findLastLeaf(treeElement, false);
int result = 0;
while (leaf != null && (fromStart ? patternIndex <= finalPatternIndex : patternIndex >= finalPatternIndex)) {
if (!(leaf instanceof ForeignLeafPsiElement)) {
CharSequence chars = leaf.getChars();
if (chars.length() > 0) {
int matchingLength = getLeafMatchingLength(chars, text, patternIndex, finalPatternIndex, direction);
result += matchingLength;
if (matchingLength != chars.length()) {
break;
}
patternIndex += fromStart ? matchingLength : -matchingLength;
}
}
leaf = fromStart ? TreeUtil.nextLeaf(leaf, false) : TreeUtil.prevLeaf(leaf, false);
}
return result;
}
public static ASTNode addChildren(ASTNode parent, @Nonnull ASTNode first, @Nonnull ASTNode last, ASTNode anchorBefore) {
ASTNode lastChild = last.getTreeNext();
ASTNode current = first;
while (current != lastChild) {
saveWhitespacesInfo(current);
checkForOuters(current);
current = current.getTreeNext();
}
if (anchorBefore != null && CommentUtilCore.isComment(anchorBefore)) {
final ASTNode anchorPrev = anchorBefore.getTreePrev();
if (anchorPrev != null && anchorPrev.getElementType() == TokenType.WHITE_SPACE) {
anchorBefore = anchorPrev;
}
}
parent.addChildren(first, lastChild, anchorBefore);
ASTNode firstAddedLeaf = findFirstLeaf(first, last);
ASTNode prevLeaf = TreeUtil.prevLeaf(first);
ASTNode result = first;
if (firstAddedLeaf != null) {
ASTNode placeHolderEnd = makePlaceHolderBetweenTokens(prevLeaf, firstAddedLeaf, isFormattingRequired(prevLeaf, first), false);
if (placeHolderEnd != prevLeaf && first == firstAddedLeaf) {
result = placeHolderEnd;
}
ASTNode lastAddedLeaf = findLastLeaf(first, last);
placeHolderEnd = makePlaceHolderBetweenTokens(lastAddedLeaf, TreeUtil.nextLeaf(last), true, false);
if (placeHolderEnd != lastAddedLeaf && lastAddedLeaf == first) {
result = placeHolderEnd;
}
}
else {
makePlaceHolderBetweenTokens(prevLeaf, TreeUtil.nextLeaf(last), isFormattingRequired(prevLeaf, first), false);
}
return result;
}
public static void replaceChild(ASTNode parent, @Nonnull ASTNode oldChild, @Nonnull ASTNode newChild) {
saveWhitespacesInfo(oldChild);
saveWhitespacesInfo(newChild);
checkForOuters(oldChild);
checkForOuters(newChild);
LeafElement oldFirst = TreeUtil.findFirstLeaf(oldChild);
parent.replaceChild(oldChild, newChild);
final LeafElement firstLeaf = TreeUtil.findFirstLeaf(newChild);
final ASTNode prevToken = TreeUtil.prevLeaf(newChild);
if (firstLeaf != null) {
final ASTNode nextLeaf = TreeUtil.nextLeaf(newChild);
makePlaceHolderBetweenTokens(prevToken, firstLeaf, isFormattingRequired(prevToken, newChild), false);
if (nextLeaf != null && !CharArrayUtil.containLineBreaks(nextLeaf.getText())) {
makePlaceHolderBetweenTokens(TreeUtil.prevLeaf(nextLeaf), nextLeaf, false, false);
}
}
else {
if (oldFirst != null && prevToken == null) {
ASTNode whitespaceNode = newChild.getTreeNext();
if (whitespaceNode != null && whitespaceNode.getElementType() == TokenType.WHITE_SPACE) {
// Replacing non-empty prefix to empty shall remove whitespace
parent.removeChild(whitespaceNode);
}
}
makePlaceHolderBetweenTokens(prevToken, TreeUtil.nextLeaf(newChild), isFormattingRequired(prevToken, newChild), false);
}
}
@Nullable
public static PsiElement searchNonSpaceNonCommentBack(PsiElement element, final boolean strict) {
if(element == null || element.getNode() == null) return null;
ASTNode leftNeibour = TreeUtil.prevLeaf(element.getNode());
if (!strict) {
while (leftNeibour != null && (leftNeibour.getElementType() == TokenType.WHITE_SPACE || leftNeibour.getPsi() instanceof PsiComment)){
leftNeibour = TreeUtil.prevLeaf(leftNeibour);
}
}
return leftNeibour != null ? leftNeibour.getPsi() : null;
}
protected ASTNode getPreviousNonWhiteSpaceLeaf(ASTNode originalPrevLeaf) {
ASTNode prevLeaf = originalPrevLeaf;
while ((prevLeaf = TreeUtil.prevLeaf(prevLeaf)) != null && prevLeaf.getElementType() == TokenType.WHITE_SPACE) {
}
return prevLeaf;
}
@Nullable
private static ASTNode makePlaceHolderBetweenTokens(ASTNode left, ASTNode right, boolean forceReformat, boolean normalizeTrailingWS) {
if (right == null) return left;
markToReformatBefore(right, false);
if (left == null) {
markToReformatBefore(right, true);
}
else if (left.getElementType() == TokenType.WHITE_SPACE && left.getTreeNext() == null && normalizeTrailingWS) {
// handle tailing whitespaces if element on the left has been removed
final ASTNode prevLeaf = TreeUtil.prevLeaf(left);
left.getTreeParent().removeChild(left);
markToReformatBeforeOrInsertWhitespace(prevLeaf, right);
left = right;
}
else if (left.getElementType() == TokenType.WHITE_SPACE && right.getElementType() == TokenType.WHITE_SPACE) {
final String text;
final int leftBlankLines = getBlankLines(left.getText());
final int rightBlankLines = getBlankLines(right.getText());
final boolean leaveRightText = leftBlankLines < rightBlankLines;
if (leftBlankLines == 0 && rightBlankLines == 0) {
text = left.getText() + right.getText();
}
else if (leaveRightText) {
text = right.getText();
}
else {
text = left.getText();
}
if (leaveRightText || forceReformat) {
final LeafElement merged = ASTFactory.whitespace(text);
if (!leaveRightText) {
left.getTreeParent().replaceChild(left, merged);
right.getTreeParent().removeChild(right);
}
else {
right.getTreeParent().replaceChild(right, merged);
left.getTreeParent().removeChild(left);
}
left = merged;
}
else {
right.getTreeParent().removeChild(right);
}
}
else if (left.getElementType() != TokenType.WHITE_SPACE || forceReformat) {
if (right.getElementType() == TokenType.WHITE_SPACE) {
markWhitespaceForReformat(right);
}
else if (left.getElementType() == TokenType.WHITE_SPACE) {
markWhitespaceForReformat(left);
}
else {
markToReformatBeforeOrInsertWhitespace(left, right);
}
}
return left;
}