HeredocLineWhiteSpaceTokenBlock(ASTNode child, int heredocPrefixLength, SpacingBuilder spacingBuilder) { super(child, null, null); assert heredocPrefixLength < child.getTextLength() : "HeredocLineWhiteSpaceTokenBlocks that are shorter than the heredocPrefixLength should not be created"; this.heredocPrefixLength = heredocPrefixLength; this.spacingBuilder = spacingBuilder; }
@NotNull private List<com.intellij.formatting.Block> buildHeredocLineChildren(ASTNode heredocLine, int heredocPrefixLength) { List<com.intellij.formatting.Block> blockList; if (heredocLine.getTextLength() == 1 && heredocLine.getText().equals("\n")) { // prevent insertion of prefix length spaces on blank lines blockList = Collections.emptyList(); } else { blockList = Collections.singletonList( new HeredocLineBlock(heredocLine, heredocPrefixLength, spacingBuilder) ); } return blockList; }
private static boolean shouldBuildBlock(@NotNull ASTNode child) { return shouldBuildBlock(child.getElementType()) && child.getTextLength() > 0; }
@Override public void invoke(@NotNull Project project, @NotNull PsiFile file, @NotNull PsiElement startElement, @NotNull PsiElement endElement) { assert startElement == endElement; com.intellij.lang.ASTNode parentNode = startElement.getNode(); com.intellij.lang.ASTNode whiteSpace = parentNode.findChildByType(TokenType.WHITE_SPACE); BlockSupport blockSupport = BlockSupport.getInstance(project); final int startOffset = whiteSpace.getStartOffset(); final int endOffset = startOffset + whiteSpace.getTextLength(); blockSupport.reparseRange(file, startOffset, endOffset, ""); } }
@NotNull private List<com.intellij.formatting.Block> buildHeredocLinePrefixChildren(ASTNode heredocLinePrefix) { return Block.buildChildren( heredocLinePrefix, (child, childElementType, blockList) -> { if (childElementType == ElixirTypes.HEREDOC_LINE_WHITE_SPACE_TOKEN) { /* It is an error to make an empty block. This can occur if the line's text is indented before the prefix for the terminator like `One` below ``` """ One """ ``` */ if (heredocPrefixLength < child.getTextLength()) { blockList.add( new HeredocLineWhiteSpaceTokenBlock(child, heredocPrefixLength, spacingBuilder) ); } } else { blockList.add(new Block(child, spacingBuilder)); } return blockList; } ); }
@NotNull private List<com.intellij.formatting.Block> buildHeredocChildren(CompositeElement heredoc) { ASTNode heredocPrefix = heredoc.findChildByType(HEREDOC_PREFIX); int heredocPrefixLength = 0; if (heredocPrefix != null) { heredocPrefixLength = heredocPrefix.getTextLength(); } Indent indent = Indent.getNoneIndent(); int finalHeredocPrefixLength = heredocPrefixLength; return buildChildren( heredoc, (child, childElementType, blockList) -> { if (HEREDOC_LINE_TOKEN_SET.contains(childElementType)) { blockList.addAll(buildHeredocLineChildren(child, finalHeredocPrefixLength)); } else if (childElementType != HEREDOC_PREFIX) { /* The heredocPrefix while important for determining the significant white space in each heredoc line, is normal, insignificant whitespace when shifting the lines, so it has no block */ blockList.add(buildChild(child, indent)); } return blockList; } ); }
@Override public int getTextLength() { return getNode().getTextLength(); }
private static boolean isWhitespaceOrEmpty(ASTNode node) { return node.getElementType() == TokenType.WHITE_SPACE || node.getTextLength() == 0; }
@Override public String createEquallyWrappedString(String newContent) { ASTNode node = getNode(); ASTNode firstChild = node.getFirstChildNode(); ASTNode lastChild = node.getLastChildNode(); StringBuilder result = new StringBuilder(firstChild.getTextLength() + newContent.length() + lastChild.getTextLength()); return result.append(firstChild.getText()).append(newContent).append(lastChild.getText()).toString(); }
@Override public int apply() { int delta = 0; if (myElementToChange.isValid() && myElementToChange instanceof LeafPsiElement) { delta = myNewElementContent.length() - myElementToChange.getNode().getTextLength(); ((LeafPsiElement)myElementToChange).replaceWithText(myNewElementContent); } return delta; } }
protected static boolean shouldCreateBlockFor(ASTNode node) { IElementType elementType = PsiUtilCore.getElementType(node); return elementType != TokenType.WHITE_SPACE && !node.getText().isEmpty() && !(HEREDOC_BODIES_TOKENSET.contains(elementType) && node.getTextLength() == 1); } }
@Override public boolean isWrapped() { if (isWrapped == null) { synchronized (stateLock) { if (isWrapped == null) { boolean newIsWrapped = false; if (getTextLength() >= 2) { ASTNode firstChildNode = getNode().getFirstChildNode(); if (firstChildNode != null && firstChildNode.getTextLength() >= 2) { String text = firstChildNode.getText(); newIsWrapped = (text.startsWith("$'") || text.startsWith("'")) && text.endsWith("'"); } } isWrapped = newIsWrapped; } } } return isWrapped; }
public static void foldElement(PsiElement element, List<FoldingDescriptor> myDescriptors, Document myDocument) { PsiElement firstChild = element.getFirstChild(); int leftMargin = firstChild == null || firstChild.getNextSibling() == null ? 0 : firstChild.getNode().getTextLength(); PsiElement lastChild = element.getLastChild(); int rightMargin = lastChild == null || lastChild == firstChild ? 0 : lastChild.getNode().getTextLength(); addDescriptorFor(myDescriptors, myDocument, element, leftMargin, rightMargin, 0); } }
protected int getCloseQuoteOffsetInParent(@NotNull PerlStringMixin element) { PsiElement closingQuote = getClosingQuote(element); ASTNode node = element.getNode(); if (closingQuote == null) // unclosed string { return node.getTextLength(); } return closingQuote.getNode().getStartOffset() - node.getStartOffset(); }
@Override protected List<Block> buildChildren() { List<ASTNode> todoNodes = new ArrayList<>(); List<Block> blocks = new ArrayList<>(); todoNodes.add(getNode().getFirstChildNode()); CsvBlockField currentField = null; while (todoNodes.size() > 0) { ASTNode node = todoNodes.remove(todoNodes.size() - 1); if (node == null) { continue; } IElementType elementType = node.getElementType(); todoNodes.add(node.getTreeNext()); if (elementType == CsvTypes.RECORD) { todoNodes.add(node.getFirstChildNode()); } else if (elementType == CsvTypes.FIELD) { currentField = new CsvBlockField(node, myFormattingInfo); if (currentField.getTextLength() > 0) { blocks.add(currentField); } } else if (elementType == CsvTypes.COMMA || elementType == CsvTypes.CRLF) { blocks.add(new CsvBlockElement(node, myFormattingInfo, currentField)); } else if (elementType != TokenType.WHITE_SPACE && node.getTextLength() > 0) { blocks.add(new CsvDummyBlock(node, myFormattingInfo)); } } validateBlocks(blocks); return blocks; }
@Override public int apply() { int delta = 0; if (getMyModifier().isValid()) { PsiPerlExpr expression = PsiTreeUtil.getChildOfType(getMyModifier(), PsiPerlExpr.class); if (expression != null && expression instanceof PsiPerlParenthesisedExpr) { PsiPerlExpr nestedExpression = ((PsiPerlParenthesisedExpr)expression).getExpr(); if (nestedExpression != null) { delta = nestedExpression.getNode().getTextLength() - expression.getNode().getTextLength(); expression.replace(nestedExpression.copy()); } } } return delta; } }
@Override public int apply() { int delta = 0; if (getMyModifier().isValid()) { PsiPerlExpr expression = PsiTreeUtil.getChildOfType(getMyModifier(), PsiPerlExpr.class); if (expression != null && !(expression instanceof PsiPerlParenthesisedExpr)) { PsiPerlParenthesisedExpr parenthesisedExpression = PerlElementFactory.createParenthesisedExpression(getMyModifier().getProject()); parenthesisedExpression.addAfter(expression.copy(), parenthesisedExpression.getFirstChild()); delta = expression.getNode().getTextLength() - parenthesisedExpression.getNode().getTextLength(); expression.replace(parenthesisedExpression); } } return delta; }
@Override public PsiElement findElementAt(int offset) { ASTNode node = root.getNode(); if (offset >= node.getTextLength()) { return null; } boolean foundChild = true; while (foundChild) { foundChild = false; for (ASTNode child : node.getChildren(null)) { int startOffset = child.getStartOffset(); if (offset >= startOffset && offset < startOffset + child.getTextLength()) { node = child; foundChild = true; break; } } } return node.getPsi(); }
@Override public int apply() { if (!myFromElement.isValid() || !myToElement.isValid()) // seems something happened on the upper level { return 0; } int result = 0; PsiElement currentElement = myFromElement; while (true) { result -= currentElement.getNode().getTextLength(); PsiElement nextElement = currentElement.getNextSibling(); boolean isLast = currentElement == myToElement; currentElement.delete(); if (isLast || nextElement == null) { break; } currentElement = nextElement; assert currentElement.isValid() : "Element become invalid"; } return result; } }
@Override public int apply() { if (!myAnchor.isValid()) // seems something happened on the upper level { return 0; } int result = 0; PsiElement currentElement = myFromElement; PsiElement currentAnchor = getMyAnchor(); PsiElement anchorContainer = currentAnchor.getParent(); assert anchorContainer != null; assert anchorContainer.isValid(); while (true) { result += currentElement.getNode().getTextLength(); currentAnchor = insertElement(currentElement, currentAnchor, anchorContainer); if (currentElement == myToElement || (currentElement = currentElement.getNextSibling()) == null) { break; } assert currentElement.isValid() : "Element become invalid"; } return result; }