private static void addFoldingDescriptors( final List<FoldingDescriptor> descriptors, final PsiElement tag, @NotNull Document document) { TextRange elementRange = tag.getTextRange(); final int start = elementRange.getStartOffset(); final int end = elementRange.getEndOffset(); if (start + 1 < end) { TextRange range = null; ASTNode astNode = tag.getNode(); IElementType astType = astNode.getElementType(); if (tag instanceof CfmlTag) { // if (tag instanceof CfmlTagFunctionImpl || tag instanceof CfmlTagComponentImpl || tag // instanceof CfmlTagScriptImpl) { range = buildRangeForBraces( range, astNode, CfmlTokenTypes.R_ANGLEBRACKET, CfmlTokenTypes.LSLASH_ANGLEBRACKET); // } } else if (astType == CfmlElementTypes.FUNCTIONBODY || astType == CfmlElementTypes.BLOCK_OF_STATEMENTS) { range = buildRange(range, start, end); } else if (astType == CfmlElementTypes.SWITCHEXPRESSION) { ASTNode lparen = astNode.findChildByType(CfscriptTokenTypes.L_CURLYBRACKET); ASTNode rparen = astNode.findChildByType(CfscriptTokenTypes.R_CURLYBRACKET); if (lparen != null && rparen != null) { range = buildRange(range, lparen.getStartOffset(), rparen.getTextRange().getEndOffset()); } } else if (tag instanceof PsiComment) { boolean isColdFusionComment = astNode.getElementType() == CfmlTokenTypes.COMMENT; int endIndex = astNode.getText().lastIndexOf(isColdFusionComment ? "--->" : "*/"); if (endIndex != -1) { String commentText = astNode.getText().substring(0, endIndex); if (commentText.contains("\n")) { int startOffset = tag.getTextRange().getStartOffset(); range = buildRange( range, startOffset + (isColdFusionComment ? "<!---" : "/*").length(), startOffset + commentText.length()); } } } if (range != null) { descriptors.add(new FoldingDescriptor(astNode, range)); } // TODO: insert condition addFoldingDescriptorsFromChildren(descriptors, tag, document); } }
@Override public void visitPyStringLiteralExpression(PyStringLiteralExpression node) { final Pair<PsiElement, TextRange> data = node.getUserData(PyReplaceExpressionUtil.SELECTION_BREAKS_AST_NODE); if (data != null) { final PsiElement parent = data.getFirst(); final String text = parent.getText(); final Pair<String, String> detectedQuotes = PythonStringUtil.getQuotes(text); final Pair<String, String> quotes = detectedQuotes != null ? detectedQuotes : Pair.create("'", "'"); final TextRange range = data.getSecond(); final String substring = range.substring(text); myResult.append(quotes.getFirst() + substring + quotes.getSecond()); } else { ASTNode child = node.getNode().getFirstChildNode(); while (child != null) { String text = child.getText(); if (child.getElementType() == TokenType.WHITE_SPACE) { if (text.contains("\n")) { if (!text.contains("\\")) { myResult.append("\\"); } myResult.append(text); } } else { myResult.append(text); } child = child.getTreeNext(); } } }
private static void reportInconsistentLength( PsiFile file, CharSequence newFileText, ASTNode node, int start, int end) { String message = "Index out of bounds: type=" + node.getElementType() + "; file=" + file + "; file.class=" + file.getClass() + "; start=" + start + "; end=" + end + "; length=" + node.getTextLength(); String newTextBefore = newFileText.subSequence(0, start).toString(); String oldTextBefore = file.getText().subSequence(0, start).toString(); if (oldTextBefore.equals(newTextBefore)) { message += "; oldTextBefore==newTextBefore"; } LOG.error( message, new Attachment(file.getName() + "_oldNodeText.txt", node.getText()), new Attachment(file.getName() + "_oldFileText.txt", file.getText()), new Attachment(file.getName() + "_newFileText.txt", newFileText.toString())); }
@NotNull public PsiReference[] getReferences() { ProgressManager.checkCanceled(); final ASTNode startTagName = XmlChildRole.START_TAG_NAME_FINDER.findChild(this); if (startTagName == null) return PsiReference.EMPTY_ARRAY; final ASTNode endTagName = XmlChildRole.CLOSING_TAG_NAME_FINDER.findChild(this); List<PsiReference> refs = new ArrayList<PsiReference>(); String prefix = getNamespacePrefix(); TagNameReference startTagRef = TagNameReference.createTagNameReference(this, startTagName, true); refs.add(startTagRef); if (prefix.length() > 0) { refs.add(createPrefixReference(startTagName, prefix, startTagRef)); } if (endTagName != null) { TagNameReference endTagRef = TagNameReference.createTagNameReference(this, endTagName, false); refs.add(endTagRef); prefix = XmlUtil.findPrefixByQualifiedName(endTagName.getText()); if (StringUtil.isNotEmpty(prefix)) { refs.add(createPrefixReference(endTagName, prefix, endTagRef)); } } // ArrayList.addAll() makes a clone of the collection //noinspection ManualArrayToCollectionCopy for (PsiReference ref : ReferenceProvidersRegistry.getReferencesFromProviders(this, XmlTag.class)) { refs.add(ref); } return ContainerUtil.toArray(refs, new PsiReference[refs.size()]); }
public static String getName(X816SymbolAffectation element) { ASTNode symbol = element.getNode().findChildByType(X816Types.SYMBOL); if (symbol != null) { return symbol.getText(); } return null; }
@Nullable public String getActualStepPrefix() { ASTNode keyword = getKeyword(); if (keyword == null) { // that's weird! return null; } return keyword.getText(); }
@Override protected String replaceWithPsiInLeaf( final TextRange textRange, String whiteSpace, ASTNode leafElement) { if (!myCanModifyAllWhiteSpaces) { if (leafElement.getElementType() == TokenType.WHITE_SPACE) return null; LOG.assertTrue(leafElement.getPsi().isValid()); ASTNode prevNode = TreeUtil.prevLeaf(leafElement); if (prevNode != null) { IElementType type = prevNode.getElementType(); if (type == TokenType.WHITE_SPACE) { final String text = prevNode.getText(); final @NonNls String cdataStartMarker = "<![CDATA["; final int cdataPos = text.indexOf(cdataStartMarker); if (cdataPos != -1 && whiteSpace.indexOf(cdataStartMarker) == -1) { whiteSpace = mergeWsWithCdataMarker(whiteSpace, text, cdataPos); if (whiteSpace == null) return null; } prevNode = TreeUtil.prevLeaf(prevNode); type = prevNode != null ? prevNode.getElementType() : null; } final @NonNls String cdataEndMarker = "]]>"; if (type == XmlTokenType.XML_CDATA_END && whiteSpace.indexOf(cdataEndMarker) == -1) { final ASTNode at = findElementAt(prevNode.getStartOffset()); if (at != null && at.getPsi() instanceof PsiWhiteSpace) { final String s = at.getText(); final int cdataEndPos = s.indexOf(cdataEndMarker); whiteSpace = mergeWsWithCdataMarker(whiteSpace, s, cdataEndPos); leafElement = at; } else { whiteSpace = null; } if (whiteSpace == null) return null; } } } FormatterUtil.replaceWhiteSpace(whiteSpace, leafElement, TokenType.WHITE_SPACE, textRange); return whiteSpace; }
@Override public String getIncludeText() { final JSIncludeDirectiveStub stub = getStub(); if (stub != null) { return stub.getIncludeText(); } final ASTNode astNode = getIncludedFileNode(); return astNode != null ? StringUtil.stripQuotesAroundValue(astNode.getText()) : null; }
@Nullable @Override public String getName() { final PyFunctionStub stub = getStub(); if (stub != null) { return stub.getName(); } ASTNode node = getNameNode(); return node != null ? node.getText() : null; }
public boolean isOperator(String chars) { ASTNode child = getNode().getFirstChildNode(); StringBuilder buf = new StringBuilder(); while (child != null) { IElementType elType = child.getElementType(); if (elType instanceof PyElementType && PyElementTypes.BINARY_OPS.contains(elType)) { buf.append(child.getText()); } child = child.getTreeNext(); } return buf.toString().equals(chars); }
@NotNull public String getName() { String name = myName; if (name == null) { final ASTNode nameElement = XmlChildRole.START_TAG_NAME_FINDER.findChild(this); if (nameElement != null) { name = nameElement.getText(); } else { name = ""; } myName = name; } return name; }
private static HashSet<String> findAllVariables( ASTNode[] children, HashSet<String> resultSet, IElementType type, boolean limitResults) { int amount = (false) ? Math.min(AUTO_POPUP_VARS_ITEMS_LIMIT, children.length) : children.length; // get all results only if users press ctrl+space for (int i = 0; i < amount; i++) { ASTNode astNode = children[i].findChildByType(type); if (astNode != null) { resultSet.add(astNode.getText()); } else if (children[i].getChildren(null) != null) { findAllVariables(children[i].getChildren(null), resultSet, type, false); } } return resultSet; }
@Override @NotNull public PsiReference[] getReferences() { ASTNode node = getIncludedFileNode(); if (node != null) { return new FileReferenceSet( StringUtil.stripQuotesAroundValue(node.getText()), this, node.getPsi().getStartOffsetInParent() + 1, null, SystemInfo.isFileSystemCaseSensitive) .getAllReferences(); } return PsiReference.EMPTY_ARRAY; }
protected void applyFix( final Project project, final PsiElement psiElement, final PsiFile file, final Editor editor) { final ASTNode oldValueNode = ((JSAttributeNameValuePair) psiElement).getValueNode(); final String oldText = oldValueNode.getText(); char quoteChar = oldText.length() > 0 ? oldText.charAt(0) : '"'; if (quoteChar != '\'' && quoteChar != '"') { quoteChar = '"'; } final String newText = quoteChar + "/" + StringUtil.stripQuotesAroundValue(oldText) + quoteChar; final ASTNode newNode = JSChangeUtil.createExpressionFromText(project, newText); psiElement.getNode().replaceChild(oldValueNode, newNode.getFirstChildNode()); }
private void postponeFormatting(final FileViewProvider viewProvider, final ASTNode child) { if (!CodeEditUtil.isNodeGenerated(child) && child.getElementType() != TokenType.WHITE_SPACE) { final int oldIndent = CodeEditUtil.getOldIndentation(child); LOG.assertTrue( oldIndent >= 0, "for not generated items old indentation must be defined: element=" + child + ", text=" + child.getText()); } List<ASTNode> list = myReformatElements.get(viewProvider); if (list == null) { list = new ArrayList<ASTNode>(); myReformatElements.put(viewProvider, list); } list.add(child); }
private void postponeFormatting(@NotNull FileViewProvider viewProvider, @NotNull ASTNode child) { if (!CodeEditUtil.isNodeGenerated(child) && child.getElementType() != TokenType.WHITE_SPACE) { final int oldIndent = CodeEditUtil.getOldIndentation(child); LOG.assertTrue( oldIndent >= 0, "for not generated items old indentation must be defined: element=" + child + ", text=" + child.getText()); } List<ASTNode> list = myReformatElements.get(viewProvider); if (list == null) { list = new ArrayList<ASTNode>(); myReformatElements.put(viewProvider, list); if (STORE_REFORMAT_ORIGINATOR_STACKTRACE) { viewProvider.putUserData(REFORMAT_ORIGINATOR, new Throwable()); } } list.add(child); }
private static StringBuilder createNewLeafChars( final ASTNode leafElement, final TextRange textRange, final String whiteSpace) { final TextRange elementRange = leafElement.getTextRange(); final String elementText = leafElement.getText(); final StringBuilder result = new StringBuilder(); if (elementRange.getStartOffset() < textRange.getStartOffset()) { result.append( elementText.substring(0, textRange.getStartOffset() - elementRange.getStartOffset())); } result.append(whiteSpace); if (elementRange.getEndOffset() > textRange.getEndOffset()) { result.append( elementText.substring(textRange.getEndOffset() - elementRange.getStartOffset())); } return result; }
@Override protected List<Block> buildChildren() { final ArrayList<Block> result = new ArrayList<Block>(); ASTNode child = getNode().getFirstChildNode(); while (child != null) { IElementType childType = child.getElementType(); if (childType != TokenType.WHITE_SPACE && !FormatterUtil.containsWhiteSpacesOnly(child) && !child.getText().trim().isEmpty()) { result.add( createBlock( child, calcIndent(child), null, AlignmentStrategy.getNullStrategy(), settings, spacingBuilder)); } child = child.getTreeNext(); } return result; }
/** * @param node Tree node * @return true, if the current node can be myBlock node, else otherwise */ private static boolean canBeCorrectBlock(final ASTNode node) { return (node.getText().trim().length() > 0); }
public Result beforeCharTyped( final char c, final Project project, final Editor editor, final PsiFile editedFile, final FileType fileType) { final XmlEditorOptions xmlEditorOptions = XmlEditorOptions.getInstance(); if (c == '>' && xmlEditorOptions != null && xmlEditorOptions.isAutomaticallyInsertClosingTag() && (editedFile.getLanguage() instanceof XMLLanguage || editedFile.getViewProvider().getBaseLanguage() instanceof XMLLanguage)) { PsiDocumentManager.getInstance(project).commitAllDocuments(); PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); FileViewProvider provider = editedFile.getViewProvider(); int offset = editor.getCaretModel().getOffset(); PsiElement element, elementAtCaret = null; if (offset < editor.getDocument().getTextLength()) { elementAtCaret = element = provider.findElementAt(offset, XMLLanguage.class); if (!(element instanceof PsiWhiteSpace)) { boolean nonAcceptableDelimiter = true; if (element instanceof XmlToken) { IElementType tokenType = ((XmlToken) element).getTokenType(); if (tokenType == XmlTokenType.XML_START_TAG_START || tokenType == XmlTokenType.XML_END_TAG_START) { if (offset > 0) { PsiElement previousElement = provider.findElementAt(offset - 1, XMLLanguage.class); if (previousElement instanceof XmlToken) { tokenType = ((XmlToken) previousElement).getTokenType(); element = previousElement; nonAcceptableDelimiter = false; } } } else if (tokenType == XmlTokenType.XML_NAME) { if (element.getNextSibling() instanceof PsiErrorElement) { nonAcceptableDelimiter = false; } } if (tokenType == XmlTokenType.XML_TAG_END || tokenType == XmlTokenType.XML_EMPTY_ELEMENT_END && element.getTextOffset() == offset - 1) { editor.getCaretModel().moveToOffset(offset + 1); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); return Result.STOP; } } if (nonAcceptableDelimiter) return Result.CONTINUE; } else { // check if right after empty end PsiElement previousElement = provider.findElementAt(offset - 1, XMLLanguage.class); if (previousElement instanceof XmlToken) { final IElementType tokenType = ((XmlToken) previousElement).getTokenType(); if (tokenType == XmlTokenType.XML_EMPTY_ELEMENT_END) { return Result.STOP; } } } PsiElement parent = element.getParent(); if (parent instanceof XmlText) { final String text = parent.getText(); // check / final int index = offset - parent.getTextOffset() - 1; if (index >= 0 && text.charAt(index) == '/') { return Result.CONTINUE; // already seen / } element = parent.getPrevSibling(); } else if (parent instanceof XmlTag && !(element.getPrevSibling() instanceof XmlTag)) { element = parent; } else if (parent instanceof XmlAttributeValue) { element = parent; } } else { element = provider.findElementAt(editor.getDocument().getTextLength() - 1, XMLLanguage.class); if (element == null) return Result.CONTINUE; element = element.getParent(); } if (offset > 0 && offset <= editor.getDocument().getTextLength()) { if (editor.getDocument().getCharsSequence().charAt(offset - 1) == '/') { // Some languages (e.g. GSP) allow character '/' in tag name. return Result.CONTINUE; } } if (element instanceof XmlAttributeValue) { element = element.getParent().getParent(); } while (element instanceof PsiWhiteSpace) element = element.getPrevSibling(); if (element instanceof XmlDocument) { // hack for closing tags in RHTML element = element.getLastChild(); } if (element == null) return Result.CONTINUE; if (!(element instanceof XmlTag)) { if (element instanceof XmlTokenImpl && element.getPrevSibling() != null && element.getPrevSibling().getText().equals("<")) { // tag is started and there is another text in the end editor.getDocument().insertString(offset, "</" + element.getText() + ">"); } return Result.CONTINUE; } XmlTag tag = (XmlTag) element; if (XmlUtil.getTokenOfType(tag, XmlTokenType.XML_TAG_END) != null) return Result.CONTINUE; if (XmlUtil.getTokenOfType(tag, XmlTokenType.XML_EMPTY_ELEMENT_END) != null) return Result.CONTINUE; final XmlToken startToken = XmlUtil.getTokenOfType(tag, XmlTokenType.XML_START_TAG_START); if (startToken == null || !startToken.getText().equals("<")) return Result.CONTINUE; String name = tag.getName(); if (elementAtCaret instanceof XmlToken && ((XmlToken) elementAtCaret).getTokenType() == XmlTokenType.XML_NAME) { name = name.substring(0, offset - elementAtCaret.getTextOffset()); } if (tag instanceof HtmlTag && HtmlUtil.isSingleHtmlTag(name)) return Result.CONTINUE; if ("".equals(name)) return Result.CONTINUE; int tagOffset = tag.getTextRange().getStartOffset(); final XmlToken nameToken = XmlUtil.getTokenOfType(tag, XmlTokenType.XML_NAME); if (nameToken != null && nameToken.getTextRange().getStartOffset() > offset) return Result.CONTINUE; HighlighterIterator iterator = ((EditorEx) editor).getHighlighter().createIterator(tagOffset); if (BraceMatchingUtil.matchBrace( editor.getDocument().getCharsSequence(), editedFile.getFileType(), iterator, true, true)) { PsiElement parent = tag.getParent(); boolean hasBalance = true; while (parent instanceof XmlTag && name.equals(((XmlTag) parent).getName())) { ASTNode astNode = XmlChildRole.CLOSING_TAG_NAME_FINDER.findChild(parent.getNode()); if (astNode == null) { hasBalance = false; break; } parent = parent.getParent(); } if (hasBalance) { hasBalance = false; for (ASTNode node = parent.getNode().getLastChildNode(); node != null; node = node.getTreePrev()) { ASTNode leaf = node; if (leaf.getElementType() == TokenType.ERROR_ELEMENT) { ASTNode firstChild = leaf.getFirstChildNode(); if (firstChild != null) leaf = firstChild; else { PsiElement psiElement = PsiTreeUtil.nextLeaf(leaf.getPsi()); leaf = psiElement != null ? psiElement.getNode() : null; } if (leaf != null && leaf.getElementType() == TokenType.WHITE_SPACE) { PsiElement psiElement = PsiTreeUtil.nextLeaf(leaf.getPsi()); if (psiElement != null) leaf = psiElement.getNode(); } } if (leaf != null && leaf.getElementType() == XmlTokenType.XML_END_TAG_START) { ASTNode treeNext = leaf.getTreeNext(); IElementType treeNextType; if (treeNext != null && ((treeNextType = treeNext.getElementType()) == XmlTokenType.XML_NAME || treeNextType == XmlTokenType.XML_TAG_NAME)) { if (name.equals(treeNext.getText())) { ASTNode parentEndName = parent instanceof XmlTag ? XmlChildRole.CLOSING_TAG_NAME_FINDER.findChild(parent.getNode()) : null; hasBalance = !(parent instanceof XmlTag) || parentEndName != null && !parentEndName.getText().equals(name); break; } } } } } if (hasBalance) return Result.CONTINUE; } TextRange cdataReformatRange = null; final XmlElementDescriptor descriptor = tag.getDescriptor(); if (descriptor instanceof XmlElementDescriptorWithCDataContent) { final XmlElementDescriptorWithCDataContent cDataContainer = (XmlElementDescriptorWithCDataContent) descriptor; if (cDataContainer.requiresCdataBracesInContext(tag)) { int rangeStart = offset; @NonNls final String cDataStart = "><![CDATA["; final String inserted = cDataStart + "\n]]>"; editor.getDocument().insertString(offset, inserted); final int newoffset = offset + cDataStart.length(); editor.getCaretModel().moveToOffset(newoffset); offset += inserted.length(); cdataReformatRange = new TextRange(rangeStart, offset + 1); } } editor.getDocument().insertString(offset, "</" + name + ">"); if (cdataReformatRange != null) { PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument()); try { CodeStyleManager.getInstance(project) .reformatText( file, cdataReformatRange.getStartOffset(), cdataReformatRange.getEndOffset()); } catch (IncorrectOperationException e) { LOG.error(e); } } return cdataReformatRange != null ? Result.STOP : Result.CONTINUE; } return Result.CONTINUE; }
private static boolean isWhitespaceCommentData(ASTNode docCommentData) { return WS_PATTERN.matcher(docCommentData.getText()).matches(); }
public static Spacing getSpacing( GroovyBlock child1, GroovyBlock child2, CommonCodeStyleSettings settings) { ASTNode leftNode = child1.getNode(); ASTNode rightNode = child2.getNode(); final PsiElement left = leftNode.getPsi(); final PsiElement right = rightNode.getPsi(); IElementType leftType = leftNode.getElementType(); IElementType rightType = rightNode.getElementType(); // Braces Placement // For multi-line strings if (!mirrorsAst(child1) || !mirrorsAst(child2)) { return NO_SPACING; } if (leftType == mGDOC_COMMENT_START && rightType == mGDOC_COMMENT_DATA || leftType == mGDOC_COMMENT_DATA && rightType == mGDOC_COMMENT_END) { return LAZY_SPACING; } // For type parameters if (mLT == leftType && rightNode.getPsi() instanceof GrTypeParameter || mGT == rightType && leftNode.getPsi() instanceof GrTypeParameter || mIDENT == leftType && rightNode.getPsi() instanceof GrTypeParameterList) { return NO_SPACING; } // For left parentheses in method declarations or calls if (mLPAREN.equals(rightType) && rightNode.getPsi().getParent().getNode() != null && METHOD_DEFS.contains(rightNode.getPsi().getParent().getNode().getElementType())) { return NO_SPACING; } if (ARGUMENTS.equals(rightType)) { return NO_SPACING; } // For left square bracket in array declarations and selections by index if ((mLBRACK.equals(rightType) && rightNode.getPsi().getParent().getNode() != null && INDEX_OR_ARRAY.contains(rightNode.getPsi().getParent().getNode().getElementType())) || ARRAY_DECLARATOR.equals(rightType)) { return NO_SPACING; } if (METHOD_DEFS.contains(leftType)) { if (rightType == mSEMI) { return NO_SPACING; } return Spacing.createSpacing( 0, 0, settings.BLANK_LINES_AROUND_METHOD + 1, settings.KEEP_LINE_BREAKS, 100); } if (METHOD_DEFS.contains(rightType)) { if (leftNode.getElementType() == GROOVY_DOC_COMMENT) { return Spacing.createSpacing( 0, 0, settings.BLANK_LINES_AROUND_METHOD, settings.KEEP_LINE_BREAKS, 0); } return Spacing.createSpacing( 0, 0, settings.BLANK_LINES_AROUND_METHOD + 1, settings.KEEP_LINE_BREAKS, 100); } if (leftType == mLCURLY && rightType == PARAMETERS_LIST) { // closure return LAZY_SPACING; } // For parentheses in arguments and typecasts if (LEFT_BRACES.contains(leftType) || RIGHT_BRACES.contains(rightType)) { PsiElement parent = (LEFT_BRACES.contains(leftType) ? left : right).getParent(); boolean shouldHaveSpace = parent instanceof GrTypeCastExpression && settings.SPACE_WITHIN_CAST_PARENTHESES; return shouldHaveSpace ? COMMON_SPACING : NO_SPACING_WITH_NEWLINE; } // For type parameters if ((mLT.equals(leftType) || mGT.equals(rightType)) && leftNode.getPsi().getParent() != null && leftNode.getPsi().getParent() instanceof GrTypeArgumentList) { return NO_SPACING_WITH_NEWLINE; } if (rightNode.getPsi() != null && rightNode.getPsi() instanceof GrTypeArgumentList) { return NO_SPACING_WITH_NEWLINE; } if (rightType == mCOLON && left instanceof GrParameter && left.getParent() instanceof GrForInClause) { return COMMON_SPACING; } /** ******** punctuation marks *********** */ // For dots, commas etc. if ((PUNCTUATION_SIGNS.contains(rightType)) || (mCOLON.equals(rightType) && !(rightNode.getPsi().getParent() instanceof GrConditionalExpression))) { return NO_SPACING_WITH_NEWLINE; } if (DOTS.contains(leftType)) { return NO_SPACING_WITH_NEWLINE; } /** ******** imports *********** */ if (IMPORT_STATEMENT.equals(leftType) && IMPORT_STATEMENT.equals(rightType)) { return IMPORT_BETWEEN_SPACING; } if ((IMPORT_STATEMENT.equals(leftType) && (!IMPORT_STATEMENT.equals(rightType) && !mSEMI.equals(rightType))) || ((!IMPORT_STATEMENT.equals(leftType) && !mSEMI.equals(leftType)) && IMPORT_STATEMENT.equals(rightType))) { return IMPORT_OTHER_SPACING; } // todo:check it for multiple assignments if ((VARIABLE_DEFINITION.equals(leftType) || VARIABLE_DEFINITION.equals(rightType)) && !(leftNode.getTreeNext() instanceof PsiErrorElement)) { return Spacing.createSpacing(0, 0, 1, false, 100); } /** ******** exclusions *********** */ // For << and >> ... if ((mLT.equals(leftType) && mLT.equals(rightType)) || (mGT.equals(leftType) && mGT.equals(rightType))) { return NO_SPACING_WITH_NEWLINE; } // Unary and postfix expressions if (PREFIXES.contains(leftType) || POSTFIXES.contains(rightType) || (PREFIXES_OPTIONAL.contains(leftType) && leftNode.getPsi().getParent() instanceof GrUnaryExpression)) { return NO_SPACING_WITH_NEWLINE; } if (RANGES.contains(leftType) || RANGES.contains(rightType)) { return NO_SPACING_WITH_NEWLINE; } // For Gstrings and regexes if (left.getParent() != null && left.getParent().equals(right.getParent()) && (left.getParent() instanceof GrString || leftNode.getTreeParent().getElementType() == mREGEX_LITERAL || leftNode.getTreeParent().getElementType() == mDOLLAR_SLASH_REGEX_LITERAL)) { return NO_SPACING; } if (isDollarInGStringInjection(leftNode) || isDollarInGStringInjection(rightNode)) { return NO_SPACING; } if (leftNode.getPsi().getParent() instanceof GrStringInjection && rightNode.getPsi().getParent() instanceof GrString && rightNode.getPsi().getParent().equals(leftNode.getPsi().getParent().getParent())) { return NO_SPACING; } if (mGDOC_ASTERISKS == leftType && mGDOC_COMMENT_DATA == rightType) { String text = rightNode.getText(); if (text.length() > 0 && !text.startsWith(" ")) { return COMMON_SPACING; } return NO_SPACING; } if (leftType == mGDOC_TAG_VALUE_TOKEN && rightType == mGDOC_COMMENT_DATA) { return LAZY_SPACING; } if (left instanceof GrStatement && right instanceof GrStatement && left.getParent() instanceof GrStatementOwner && right.getParent() instanceof GrStatementOwner) { return COMMON_SPACING_WITH_NL; } if (rightType == mGDOC_INLINE_TAG_END || leftType == mGDOC_INLINE_TAG_START || rightType == mGDOC_INLINE_TAG_START || leftType == mGDOC_INLINE_TAG_END) { return NO_SPACING; } if ((leftType == GDOC_INLINED_TAG && rightType == mGDOC_COMMENT_DATA) || (leftType == mGDOC_COMMENT_DATA && rightType == GDOC_INLINED_TAG)) { // Keep formatting between groovy doc text and groovy doc reference tag as is. return NO_SPACING; } if (leftType == CLASS_TYPE_ELEMENT && rightType == mTRIPLE_DOT) { return NO_SPACING; } // diamonds if (rightType == mLT || rightType == mGT) { if (right.getParent() instanceof GrCodeReferenceElement) { PsiElement p = right.getParent().getParent(); if (p instanceof GrNewExpression || p instanceof GrAnonymousClassDefinition) { return NO_SPACING; } } } if (leftType == mRPAREN && left.getParent() instanceof GrTypeCastExpression) { return settings.SPACE_AFTER_TYPE_CAST ? COMMON_SPACING : NO_SPACING; } return COMMON_SPACING; }
public String getDeclName() { ASTNode node = getNode().findChildByType(PLSqlTypesAdopted.TYPE_NAME); return node.getText(); }
@Override public PsiReference getReference() { final PsiDocComment comment = PsiTreeUtil.getParentOfType(this, PsiDocComment.class); if (comment == null) return null; final PsiDocCommentOwner owner = comment.getOwner(); if (!(owner instanceof PsiMethod) && !(owner instanceof PsiClass)) return null; final ASTNode valueToken = findChildByType(JavaDocTokenType.DOC_TAG_VALUE_TOKEN); if (valueToken == null) return null; final String name = valueToken.getText(); PsiElement reference = null; final PsiElement firstChild = getFirstChild(); if (firstChild instanceof PsiDocToken && ((PsiDocToken) firstChild).getTokenType().equals(JavaDocTokenType.DOC_TAG_VALUE_LT)) { final PsiTypeParameter[] typeParameters = ((PsiTypeParameterListOwner) owner).getTypeParameters(); for (PsiTypeParameter typeParameter : typeParameters) { if (typeParameter.getName().equals(name)) { reference = typeParameter; } } } else if (owner instanceof PsiMethod) { final PsiParameter[] parameters = ((PsiMethod) owner).getParameterList().getParameters(); for (PsiParameter parameter : parameters) { if (parameter.getName().equals(name)) { reference = parameter; } } } final PsiElement resultReference = reference; return new PsiJavaReference() { @Override public PsiElement resolve() { return resultReference; } @Override @NotNull public String getCanonicalText() { return valueToken.getText(); } @Override public PsiElement handleElementRename(String newElementName) { final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(getNode()); LeafElement newElement = Factory.createSingleLeafElement( JavaDocTokenType.DOC_TAG_VALUE_TOKEN, newElementName, charTableByTree, getManager()); replaceChild(valueToken, newElement); return PsiDocParamRef.this; } @Override public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { if (isReferenceTo(element)) return PsiDocParamRef.this; if (!(element instanceof PsiParameter)) { throw new IncorrectOperationException("Unsupported operation"); } return handleElementRename(((PsiParameter) element).getName()); } @Override public boolean isReferenceTo(PsiElement element) { if (!(element instanceof PsiNamedElement)) return false; PsiNamedElement namedElement = (PsiNamedElement) element; if (!getCanonicalText().equals(namedElement.getName())) return false; return getManager().areElementsEquivalent(resolve(), element); } @Override @NotNull public PsiElement[] getVariants() { final PsiElement firstChild = getFirstChild(); Set<String> usedNames = new HashSet<String>(); for (PsiDocTag tag : comment.getTags()) { if (tag.getName().equals("param")) { PsiDocTagValue valueElement = tag.getValueElement(); if (valueElement != null) { usedNames.add(valueElement.getText()); } } } PsiNamedElement[] result = PsiNamedElement.EMPTY_ARRAY; if (firstChild instanceof PsiDocToken && ((PsiDocToken) firstChild) .getTokenType() .equals(JavaDocTokenType.DOC_TAG_VALUE_LT)) { result = ((PsiTypeParameterListOwner) owner).getTypeParameters(); } else if (owner instanceof PsiMethod) { result = ((PsiMethod) owner).getParameterList().getParameters(); } List<PsiElement> filtered = new ArrayList<PsiElement>(); for (PsiNamedElement namedElement : result) { if (!usedNames.contains(namedElement.getName())) { filtered.add(namedElement); } } return filtered.toArray(new PsiElement[filtered.size()]); } @Override public boolean isSoft() { return false; } @Override public TextRange getRangeInElement() { final int startOffsetInParent = valueToken.getPsi().getStartOffsetInParent(); return new TextRange(startOffsetInParent, startOffsetInParent + valueToken.getTextLength()); } @Override public PsiElement getElement() { return PsiDocParamRef.this; } @Override public void processVariants(PsiScopeProcessor processor) { for (final PsiElement element : getVariants()) { if (!processor.execute(element, ResolveState.initial())) { return; } } } @Override @NotNull public JavaResolveResult advancedResolve(boolean incompleteCode) { return resultReference == null ? JavaResolveResult.EMPTY : new CandidateInfo(resultReference, PsiSubstitutor.EMPTY); } @Override @NotNull public JavaResolveResult[] multiResolve(boolean incompleteCode) { return resultReference == null ? JavaResolveResult.EMPTY_ARRAY : new JavaResolveResult[] {new CandidateInfo(resultReference, PsiSubstitutor.EMPTY)}; } }; }
public Indent getChildIndent(final ASTNode node) { final IElementType elementType = node.getElementType(); final ASTNode prevSibling = UsefulPsiTreeUtil.getPrevSiblingSkipWhiteSpacesAndComments(node); final IElementType prevSiblingType = prevSibling == null ? null : prevSibling.getElementType(); final ASTNode parent = node.getTreeParent(); final IElementType parentType = parent != null ? parent.getElementType() : null; final ASTNode superParent = parent == null ? null : parent.getTreeParent(); final IElementType superParentType = superParent == null ? null : superParent.getElementType(); final int braceStyle = superParentType == FUNCTION_BODY ? settings.METHOD_BRACE_STYLE : settings.BRACE_STYLE; if (parent == null || parent.getTreeParent() == null || parentType == EMBEDDED_CONTENT) { return Indent.getNoneIndent(); } if (elementType == MULTI_LINE_COMMENT_BODY) { return Indent.getContinuationIndent(); } if (elementType == DOC_COMMENT_LEADING_ASTERISK || elementType == MULTI_LINE_COMMENT_END) { return Indent.getSpaceIndent(1, true); } if (settings.KEEP_FIRST_COLUMN_COMMENT && (elementType == SINGLE_LINE_COMMENT || elementType == MULTI_LINE_COMMENT)) { final ASTNode previousNode = node.getTreePrev(); if (previousNode != null && previousNode.getElementType() == WHITE_SPACE && previousNode.getText().endsWith("\n")) { return Indent.getAbsoluteNoneIndent(); } } if (COMMENTS.contains(elementType) && prevSiblingType == LBRACE && parentType == CLASS_BODY) { return Indent.getNormalIndent(); } if (parentType == ENUM_DEFINITION && isBetweenBraces(node)) { // instead of isBetweenBraces(node) we can parse enum block as a separate ASTNode, or build // formatter blocks not tied to AST. return Indent.getNormalIndent(); } if (parentType == MAP_LITERAL_EXPRESSION || parentType == LIST_LITERAL_EXPRESSION) { if (elementType == LBRACE || elementType == RBRACE || elementType == LBRACKET || elementType == RBRACKET) { return Indent.getNoneIndent(); } if (elementType == TYPE_ARGUMENTS) { return Indent.getNoneIndent(); } // Be careful to preserve typing behavior. if (elementType == MAP_LITERAL_ENTRY || elementType == EXPRESSION_LIST || elementType == COMMA) { return Indent.getNormalIndent(); } if (COMMENTS.contains(elementType)) { return Indent.getNormalIndent(); } return Indent.getNoneIndent(); } if (elementType == LBRACE || elementType == RBRACE) { switch (braceStyle) { case CommonCodeStyleSettings.END_OF_LINE: if (elementType == LBRACE && FormatterUtil.isPrecededBy(parent, SINGLE_LINE_COMMENT, WHITE_SPACE)) { // Use Nystrom style rather than Allman. return Indent.getContinuationIndent(); } // FALL THROUGH case CommonCodeStyleSettings.NEXT_LINE: case CommonCodeStyleSettings.NEXT_LINE_IF_WRAPPED: return Indent.getNoneIndent(); case CommonCodeStyleSettings.NEXT_LINE_SHIFTED: case CommonCodeStyleSettings.NEXT_LINE_SHIFTED2: return Indent.getNormalIndent(); default: return Indent.getNoneIndent(); } } if (parentType == PARENTHESIZED_EXPRESSION) { if (elementType == LPAREN || elementType == RPAREN) { return Indent.getNoneIndent(); } return Indent.getContinuationIndent(); } if (elementType == CLASS_MEMBERS) { return Indent.getNormalIndent(); } if (parentType == BLOCK) { final PsiElement psi = node.getPsi(); if (psi.getParent() instanceof PsiFile) { return Indent.getNoneIndent(); } return Indent.getNormalIndent(); } if (parentType == ARGUMENT_LIST) { // TODO In order to handle some dart_style examples we need to set indent for each arg. // The formatter does not appear to honor indent on individual argument expressions // when KEEP_LINE_BREAKS==true. That means two DartFormatterTest tests fail. Those tests // have been changed since the recommended setting for Dart programming is // KEEP_LINE_BREAKS==false. The two tests are testAlignment() and testWrappingMeth(). if (EXPRESSIONS.contains(elementType) && elementType != FUNCTION_EXPRESSION) { return Indent.getContinuationIndent(); } } if (parentType == FORMAL_PARAMETER_LIST) { return Indent.getContinuationIndent(); } if (parentType == FOR_STATEMENT && prevSiblingType == FOR_LOOP_PARTS_IN_BRACES && elementType != BLOCK) { return Indent.getNormalIndent(); } if (parentType == SWITCH_STATEMENT && (elementType == SWITCH_CASE || elementType == DEFAULT_CASE)) { return Indent.getNormalIndent(); } if ((parentType == SWITCH_CASE || parentType == DEFAULT_CASE) && elementType == STATEMENTS) { return Indent.getNormalIndent(); } if (parentType == WHILE_STATEMENT && prevSiblingType == RPAREN && elementType != BLOCK) { return Indent.getNormalIndent(); } if (parentType == DO_WHILE_STATEMENT && prevSiblingType == DO && elementType != BLOCK) { return Indent.getNormalIndent(); } if ((parentType == RETURN_STATEMENT) && prevSiblingType == RETURN && elementType != BLOCK) { return Indent.getNormalIndent(); } if (parentType == IF_STATEMENT && elementType != BLOCK && (prevSiblingType == RPAREN || (prevSiblingType == ELSE && elementType != IF_STATEMENT))) { return Indent.getNormalIndent(); } if (elementType == CASCADE_REFERENCE_EXPRESSION) { return Indent.getNormalIndent(); } if (elementType == OPEN_QUOTE && prevSiblingType == CLOSING_QUOTE && parentType == STRING_LITERAL_EXPRESSION) { return Indent.getContinuationIndent(); } if (BINARY_EXPRESSIONS.contains(parentType) && prevSibling != null) { return Indent.getContinuationIndent(); } if (elementType == COLON || parentType == TERNARY_EXPRESSION && elementType == QUEST) { return Indent.getContinuationIndent(); } if (elementType == NAMED_ARGUMENT) { return Indent.getContinuationIndent(); } if (elementType == HIDE_COMBINATOR || elementType == SHOW_COMBINATOR) { return Indent.getContinuationIndent(); } if (parentType == FUNCTION_BODY) { if (FormatterUtil.isPrecededBy(node, EXPRESSION_BODY_DEF)) { return Indent.getContinuationIndent(); } } if (elementType == CALL_EXPRESSION) { if (FormatterUtil.isPrecededBy(node, EXPRESSION_BODY_DEF)) { return Indent.getContinuationIndent(); } if (FormatterUtil.isPrecededBy(node, ASSIGNMENT_OPERATOR)) { return Indent.getContinuationIndent(); } } if ((elementType == REFERENCE_EXPRESSION || BINARY_EXPRESSIONS.contains(elementType)) && FormatterUtil.isPrecededBy(node, ASSIGNMENT_OPERATOR)) { return Indent.getContinuationIndent(); } if (elementType == VAR_DECLARATION_LIST_PART) { return Indent.getContinuationIndent(); } if (elementType == SUPER_CALL_OR_FIELD_INITIALIZER) { return Indent.getContinuationIndent(); } if (parentType == SUPER_CALL_OR_FIELD_INITIALIZER && elementType != COLON) { return Indent.getNormalIndent(); } if (parentType == CLASS_DEFINITION) { if (elementType == SUPERCLASS || elementType == INTERFACES || elementType == MIXINS) { return Indent.getContinuationIndent(); } } if (parentType == MIXIN_APPLICATION && elementType == MIXINS) { return Indent.getContinuationIndent(); } if (parentType == LIBRARY_NAME_ELEMENT) { return Indent.getContinuationIndent(); } if (elementType == SEMICOLON && FormatterUtil.isPrecededBy(node, SINGLE_LINE_COMMENT, WHITE_SPACE)) { return Indent.getContinuationIndent(); } if (elementType == DOT || elementType == QUEST_DOT) { return Indent.getContinuationIndent(); } if (parentType == TYPE_LIST && elementType == TYPE) { return Indent.getContinuationIndent(); } if (elementType == OPEN_QUOTE && parentType == STRING_LITERAL_EXPRESSION && superParentType == VAR_INIT) { if (node.getText().length() < 3) { return Indent.getContinuationIndent(); } } if (elementType == RAW_SINGLE_QUOTED_STRING && parentType == STRING_LITERAL_EXPRESSION && superParentType == VAR_INIT) { return Indent.getContinuationIndent(); } if (parentType == LONG_TEMPLATE_ENTRY && EXPRESSIONS.contains(elementType)) { return Indent.getContinuationIndent(); } return Indent.getNoneIndent(); }
public List<Block> generateSubBlocks() { // For binary expressions PsiElement blockPsi = myNode.getPsi(); if (blockPsi instanceof GrBinaryExpression && !(blockPsi.getParent() instanceof GrBinaryExpression)) { return generateForBinaryExpr(); } // For multiline strings if ((myNode.getElementType() == mSTRING_LITERAL || myNode.getElementType() == mGSTRING_LITERAL) && myBlock.getTextRange().equals(myNode.getTextRange())) { String text = myNode.getText(); if (text.length() > 6) { if (text.substring(0, 3).equals("'''") && text.substring(text.length() - 3).equals("'''") || text.substring(0, 3).equals("\"\"\"") & text.substring(text.length() - 3).equals("\"\"\"")) { return generateForMultiLineString(); } } } if (myNode.getElementType() == mGSTRING_BEGIN && myBlock.getTextRange().equals(myNode.getTextRange())) { String text = myNode.getText(); if (text.length() > 3) { if (text.substring(0, 3).equals("\"\"\"")) { return generateForMultiLineGStringBegin(); } } } // for gstrings if (myNode.getElementType() == GSTRING) { final ArrayList<Block> subBlocks = new ArrayList<Block>(); ASTNode[] children = getGroovyChildren(myNode); for (ASTNode childNode : children) { if (childNode.getTextRange().getLength() > 0) { final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); subBlocks.add( new GroovyBlock( childNode, myAlignment, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } } return subBlocks; } // chained properties, calls, indexing, etc if (NESTED.contains(myNode.getElementType()) && blockPsi.getParent() != null && !NESTED.contains(blockPsi.getParent().getNode().getElementType())) { final List<Block> subBlocks = new ArrayList<Block>(); Alignment dotsAlignment = mySettings.ALIGN_MULTILINE_CHAINED_METHODS ? Alignment.createAlignment() : null; addNestedChildren(myNode.getPsi(), subBlocks, dotsAlignment, true); return subBlocks; } // For Parameter lists if (isListLikeClause(blockPsi)) { final ArrayList<Block> subBlocks = new ArrayList<Block>(); List<ASTNode> astNodes = visibleChildren(myNode); final Alignment newAlignment = mustAlign(blockPsi, astNodes) ? Alignment.createAlignment() : null; for (ASTNode childNode : astNodes) { final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); subBlocks.add( new GroovyBlock( childNode, isKeyword(childNode) ? null : newAlignment, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } return subBlocks; } boolean classLevel = blockPsi instanceof GrTypeDefinitionBody; if (blockPsi instanceof GrCodeBlock || blockPsi instanceof GroovyFile || classLevel) { List<ASTNode> children = visibleChildren(myNode); calculateAlignments(children, classLevel); final ArrayList<Block> subBlocks = new ArrayList<Block>(); for (ASTNode childNode : children) { final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); Alignment alignmentToUse = classLevel ? myAlignment : myInnerAlignments.get(childNode.getPsi()); subBlocks.add( new GroovyBlock( childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } return subBlocks; } // For other cases final ArrayList<Block> subBlocks = new ArrayList<Block>(); for (ASTNode childNode : visibleChildren(myNode)) { final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); subBlocks.add( new GroovyBlock( childNode, myInnerAlignments.get(childNode.getPsi()), indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } return subBlocks; }
@Nullable public String getReferencedName() { final ASTNode nameElement = getNameElement(); return nameElement != null ? nameElement.getText() : null; }
@NotNull @Override public Runnable processFile(final PsiFile file) { VirtualFile vFile = file.getVirtualFile(); if (vFile instanceof VirtualFileWindow) vFile = ((VirtualFileWindow) vFile).getDelegate(); final Project project = file.getProject(); if (vFile == null || !ProjectRootManager.getInstance(project).getFileIndex().isInSourceContent(vFile)) { return EmptyRunnable.INSTANCE; } final List<Pair<String, Boolean>> names = new ArrayList<Pair<String, Boolean>>(); final Set<String> demandedForNested = new HashSet<>(); collectNamesToImport(names, demandedForNested, (XmlFile) file); Collections.sort(names, (o1, o2) -> StringUtil.compare(o1.first, o2.first, true)); final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(project); final List<Pair<String, Boolean>> sortedNames = ImportHelper.sortItemsAccordingToSettings(names, settings); final HashSet<String> onDemand = new HashSet<String>(); ImportHelper.collectOnDemandImports(sortedNames, onDemand, settings); onDemand.addAll(demandedForNested); final Set<String> imported = new HashSet<String>(); final List<String> imports = new ArrayList<String>(); for (Pair<String, Boolean> pair : sortedNames) { final String qName = pair.first; final String packageName = StringUtil.getPackageName(qName); if (imported.contains(packageName) || imported.contains(qName)) { continue; } if (onDemand.contains(packageName)) { imported.add(packageName); imports.add("<?import " + packageName + ".*?>"); } else { imported.add(qName); imports.add("<?import " + qName + "?>"); } } final PsiFileFactory factory = PsiFileFactory.getInstance(file.getProject()); final XmlFile dummyFile = (XmlFile) factory.createFileFromText( "_Dummy_.fxml", StdFileTypes.XML, StringUtil.join(imports, "\n")); final XmlDocument document = dummyFile.getDocument(); final XmlProlog newImportList = document != null ? document.getProlog() : null; if (newImportList == null) return EmptyRunnable.getInstance(); return () -> { final XmlDocument xmlDocument = ((XmlFile) file).getDocument(); final XmlProlog prolog = xmlDocument != null ? xmlDocument.getProlog() : null; if (prolog != null) { final Collection<XmlProcessingInstruction> instructions = PsiTreeUtil.findChildrenOfType(prolog, XmlProcessingInstruction.class); for (final XmlProcessingInstruction instruction : instructions) { final ASTNode node = instruction.getNode(); final ASTNode nameNode = node.findChildByType(XmlTokenType.XML_NAME); if (nameNode != null && nameNode.getText().equals("import")) { instruction.delete(); } } prolog.add(newImportList); } else { document.addBefore(newImportList, document.getRootTag()); } }; }
public static void replaceWhiteSpace( final String whiteSpace, final ASTNode leafElement, final IElementType whiteSpaceToken, @Nullable final TextRange textRange) { final CharTable charTable = SharedImplUtil.findCharTableByTree(leafElement); ASTNode treePrev = findPreviousWhiteSpace(leafElement, whiteSpaceToken); if (treePrev == null) { treePrev = getWsCandidate(leafElement); } if (treePrev != null && treePrev.getText().trim().isEmpty() && treePrev.getElementType() != whiteSpaceToken && treePrev.getTextLength() > 0 && !whiteSpace.isEmpty()) { LeafElement whiteSpaceElement = Factory.createSingleLeafElement( treePrev.getElementType(), whiteSpace, charTable, SharedImplUtil.getManagerByTree(leafElement)); ASTNode treeParent = treePrev.getTreeParent(); treeParent.replaceChild(treePrev, whiteSpaceElement); } else { LeafElement whiteSpaceElement = Factory.createSingleLeafElement( whiteSpaceToken, whiteSpace, charTable, SharedImplUtil.getManagerByTree(leafElement)); if (treePrev == null) { if (!whiteSpace.isEmpty()) { addWhiteSpace(leafElement, whiteSpaceElement); } } else { if (!(treePrev.getElementType() == whiteSpaceToken)) { if (!whiteSpace.isEmpty()) { addWhiteSpace(treePrev, whiteSpaceElement); } } else { if (treePrev.getElementType() == whiteSpaceToken) { final CompositeElement treeParent = (CompositeElement) treePrev.getTreeParent(); if (!whiteSpace.isEmpty()) { // LOG.assertTrue(textRange == null || // treeParent.getTextRange().equals(textRange)); treeParent.replaceChild(treePrev, whiteSpaceElement); } else { treeParent.removeChild(treePrev); } // There is a possible case that more than one PSI element is matched by the target text // range. // That is the case, for example, for Python's multi-line expression. It may looks like // below: // import contextlib,\ // math, decimal // Here single range contains two blocks: '\' & '\n '. So, we may want to replace that // range to another text, hence, // we replace last element located there with it ('\n ') and want to remove any // remaining elements ('\'). ASTNode removeCandidate = findPreviousWhiteSpace(whiteSpaceElement, whiteSpaceToken); while (textRange != null && removeCandidate != null && removeCandidate.getStartOffset() >= textRange.getStartOffset()) { treePrev = findPreviousWhiteSpace(removeCandidate, whiteSpaceToken); removeCandidate.getTreeParent().removeChild(removeCandidate); removeCandidate = treePrev; } // treeParent.subtreeChanged(); } } } } }
public List<Block> generateSubBlocks() { // For binary expressions PsiElement blockPsi = myNode.getPsi(); if (blockPsi instanceof GrBinaryExpression && !(blockPsi.getParent() instanceof GrBinaryExpression)) { return generateForBinaryExpr(); } // For multiline strings if ((myNode.getElementType() == mSTRING_LITERAL || myNode.getElementType() == mGSTRING_LITERAL) && myBlock.getTextRange().equals(myNode.getTextRange())) { String text = myNode.getText(); if (text.length() > 6) { if (text.substring(0, 3).equals("'''") && text.substring(text.length() - 3).equals("'''") || text.substring(0, 3).equals("\"\"\"") & text.substring(text.length() - 3).equals("\"\"\"")) { return generateForMultiLineString(); } } } if (myNode.getElementType() == mGSTRING_BEGIN && myBlock.getTextRange().equals(myNode.getTextRange())) { String text = myNode.getText(); if (text.length() > 3) { if (text.substring(0, 3).equals("\"\"\"")) { return generateForMultiLineGStringBegin(); } } } // for gstrings if (myNode.getElementType() == GSTRING) { final ArrayList<Block> subBlocks = new ArrayList<Block>(); ASTNode[] children = getGroovyChildren(myNode); for (ASTNode childNode : children) { if (childNode.getTextRange().getLength() > 0) { final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); subBlocks.add( new GroovyBlock( childNode, indent, myWrap, mySettings, myGroovySettings, myAlignmentProvider)); } } return subBlocks; } // chained properties, calls, indexing, etc if (NESTED.contains(myNode.getElementType()) && blockPsi.getParent() != null && !NESTED.contains(blockPsi.getParent().getNode().getElementType())) { final List<Block> subBlocks = new ArrayList<Block>(); AlignmentProvider.Aligner dotsAligner = mySettings.ALIGN_MULTILINE_CHAINED_METHODS ? myAlignmentProvider.createAligner(true) : null; addNestedChildren(myNode.getPsi(), subBlocks, dotsAligner, true); return subBlocks; } if (blockPsi instanceof GrListOrMap && ((GrListOrMap) blockPsi).isMap() && myGroovySettings.ALIGN_NAMED_ARGS_IN_MAP) { AlignmentProvider.Aligner labels = myAlignmentProvider.createAligner(false); AlignmentProvider.Aligner exprs = myAlignmentProvider.createAligner(true); GrNamedArgument[] namedArgs = ((GrListOrMap) blockPsi).getNamedArguments(); for (GrNamedArgument arg : namedArgs) { GrArgumentLabel label = arg.getLabel(); if (label != null) labels.append(label); PsiElement colon = arg.getColon(); if (colon == null) colon = arg.getExpression(); if (colon != null) exprs.append(colon); } } // For Parameter lists if (isListLikeClause(blockPsi)) { final ArrayList<Block> subBlocks = new ArrayList<Block>(); List<ASTNode> astNodes = visibleChildren(myNode); if (mustAlign(blockPsi, astNodes)) { final AlignmentProvider.Aligner aligner = myAlignmentProvider.createAligner(false); for (ASTNode node : astNodes) { if (!isKeyword(node)) aligner.append(node.getPsi()); } } for (ASTNode childNode : astNodes) { final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); subBlocks.add( new GroovyBlock( childNode, indent, myWrap, mySettings, myGroovySettings, myAlignmentProvider)); } return subBlocks; } boolean classLevel = blockPsi instanceof GrTypeDefinitionBody; if (blockPsi instanceof GrCodeBlock || blockPsi instanceof GroovyFile || classLevel) { List<ASTNode> children = visibleChildren(myNode); calculateAlignments(children, classLevel); final ArrayList<Block> subBlocks = new ArrayList<Block>(); if (classLevel && myAlignment != null) { final AlignmentProvider.Aligner aligner = myAlignmentProvider.createAligner(true); for (ASTNode child : children) { aligner.append(child.getPsi()); } } for (ASTNode childNode : children) { final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); subBlocks.add( new GroovyBlock( childNode, indent, myWrap, mySettings, myGroovySettings, myAlignmentProvider)); } return subBlocks; } // For other cases final ArrayList<Block> subBlocks = new ArrayList<Block>(); for (ASTNode childNode : visibleChildren(myNode)) { final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); subBlocks.add( new GroovyBlock( childNode, indent, myWrap, mySettings, myGroovySettings, myAlignmentProvider)); } return subBlocks; }