Spacing (@Nullable Block child1, @NotNull Block child2) { if (child1 instanceof ReadOnlyBlock || child2 instanceof ReadOnlyBlock) { return Spacing.getReadOnlySpacing(); } if (!(child1 instanceof AbstractXmlBlock) || !(child2 instanceof AbstractXmlBlock)) { return null; } ASTNode node1 = ((AbstractBlock)child1).getNode(); ASTNode node2 = ((AbstractBlock)child2).getNode(); IElementType type1 = node1.getElementType(); IElementType type2 = node2.getElementType(); if (type2 == XmlElementType.XML_COMMENT) { // Do not remove any spaces except extra blank lines return Spacing.createSpacing(0, Integer.MAX_VALUE, 0, true, myXmlFormattingPolicy.getKeepBlankLines()); } if (type1 == XmlElementType.XML_COMMENT) { ASTNode prev = node1.getTreePrev(); if (prev != null) { node1 = prev; type1 = prev.getElementType(); } } boolean firstIsText = isTextFragment(node1); boolean secondIsText = isTextFragment(node2); if (((AbstractXmlBlock)child1).isPreserveSpace() && ((AbstractXmlBlock)child2).isPreserveSpace()) { ASTNode parent = node1.getTreeParent(); boolean inText = parent != null && parent.getTreePrev().getElementType() == XmlTokenType.XML_TAG_END; if (inText) return Spacing.getReadOnlySpacing(); } if (type1 == XmlTokenType.XML_CDATA_START || type2 == XmlTokenType.XML_CDATA_END) { if (myXmlFormattingPolicy.getKeepWhiteSpacesInsideCDATA()) { return Spacing.getReadOnlySpacing(); } if (type1 == XmlTokenType.XML_CDATA_START && type2 == XmlTokenType.XML_CDATA_END) { return Spacing.createSpacing(0, 0, 0, myXmlFormattingPolicy.getShouldKeepLineBreaks(), myXmlFormattingPolicy.getKeepBlankLines()); } if (type1 == XmlTokenType.XML_CDATA_START && child2 instanceof AnotherLanguageBlockWrapper || type2 == XmlTokenType.XML_CDATA_END && child1 instanceof AnotherLanguageBlockWrapper) { return Spacing.createSpacing(0, 0, 1, myXmlFormattingPolicy.getShouldKeepLineBreaks(), 0); } } boolean firstIsTag = node1.getPsi() instanceof XmlTag && !firstIsText; boolean secondIsTag = node2.getPsi() instanceof XmlTag && !secondIsText; boolean firstIsEntityRef = isEntityRef(node1); boolean secondIsEntityRef = isEntityRef(node2); if ((secondIsText && isInlineTag(node1) || firstIsText && isInlineTag(node2)) && myXmlFormattingPolicy.isKeepSpacesAroundInlineTags()) { return Spacing.getReadOnlySpacing(); } if (isSpaceInText(firstIsTag, secondIsTag, firstIsText, secondIsText) && keepWhiteSpaces()) { return Spacing.getReadOnlySpacing(); } if (firstIsEntityRef || secondIsEntityRef) { return Spacing.createSafeSpacing(myXmlFormattingPolicy.getShouldKeepLineBreaks(), myXmlFormattingPolicy.getKeepBlankLines()); } if (isAttributeElementType(type1) && (type2 == XmlTokenType.XML_TAG_END || type2 == XmlTokenType.XML_EMPTY_ELEMENT_END)) { Spacing spacing = myXmlFormattingPolicy.getSpacingAfterLastAttribute((XmlAttribute)node1.getPsi()); if (spacing != null) { return spacing; } } if (type2 == XmlTokenType.XML_EMPTY_ELEMENT_END && myXmlFormattingPolicy.addSpaceIntoEmptyTag()) { return Spacing.createSpacing(1, 1, 0, myXmlFormattingPolicy.getShouldKeepLineBreaks(), myXmlFormattingPolicy.getKeepBlankLines()); } if (isXmlTagName(type1, type2)) { final int spaces = shouldAddSpaceAroundTagName(node1, node2) ? 1 : 0; return Spacing.createSpacing(spaces, spaces, 0, myXmlFormattingPolicy.getShouldKeepLineBreaks(), myXmlFormattingPolicy.getKeepBlankLines()); } if (isAttributeElementType(type2)) { if (type1 == XmlTokenType.XML_NAME || type1 == XmlTokenType.XML_TAG_NAME) { Spacing spacing = myXmlFormattingPolicy.getSpacingBeforeFirstAttribute((XmlAttribute)node2.getPsi()); if (spacing != null) { return spacing; } } return Spacing.createSpacing(1, 1, 0, myXmlFormattingPolicy.getShouldKeepLineBreaks(), myXmlFormattingPolicy.getKeepBlankLines()); } if (type1 == XmlTokenType.XML_DATA_CHARACTERS && type2 == XmlTokenType.XML_DATA_CHARACTERS) { return Spacing.createSpacing(1, 1, 0, myXmlFormattingPolicy.getShouldKeepLineBreaksInText(), myXmlFormattingPolicy.getKeepBlankLines()); } if (((AbstractXmlBlock)child1).isTextElement() && ((AbstractXmlBlock)child2).isTextElement()) { return Spacing.createSafeSpacing(myXmlFormattingPolicy.getShouldKeepLineBreaksInText(), myXmlFormattingPolicy.getKeepBlankLines()); } if (firstIsTag && insertLineFeedAfter((XmlTag)node1.getPsi())) { return Spacing.createSpacing(0, 0, 1, true, myXmlFormattingPolicy.getKeepBlankLines()); } if ((firstIsText || firstIsTag) && secondIsTag) { //<tag/>text <tag/></tag> if (((AbstractXmlBlock)child2).insertLineBreakBeforeTag()) { return Spacing.createSpacing(0, Integer.MAX_VALUE, ((AbstractXmlBlock)child2).getBlankLinesBeforeTag() + 1, myXmlFormattingPolicy.getShouldKeepLineBreaks(), myXmlFormattingPolicy.getKeepBlankLines()); } else if (((AbstractXmlBlock)child2).removeLineBreakBeforeTag()) { return Spacing.createSpacing(0, Integer.MAX_VALUE, 0, myXmlFormattingPolicy.getShouldKeepLineBreaks(), myXmlFormattingPolicy.getKeepBlankLines()); } } final boolean saveSpacesBetweenTagAndText = myXmlFormattingPolicy.shouldSaveSpacesBetweenTagAndText() && child1.getTextRange().getEndOffset() < child2.getTextRange().getStartOffset(); if (firstIsTag && secondIsText) { //<tag/>-text if (((AbstractXmlBlock)child1).isTextElement() || saveSpacesBetweenTagAndText) { return Spacing.createSafeSpacing(true, myXmlFormattingPolicy.getKeepBlankLines()); } else { return Spacing.createSpacing(0, 0, 0, true, myXmlFormattingPolicy.getKeepBlankLines()); } } if (firstIsText && secondIsTag) { //text-<tag/> if (((AbstractXmlBlock)child2).isTextElement() || saveSpacesBetweenTagAndText) { return Spacing.createSafeSpacing(true, myXmlFormattingPolicy.getKeepBlankLines()); } else { return Spacing.createSpacing(0, 0, 0, true, myXmlFormattingPolicy.getKeepBlankLines()); } } if (firstIsTag && secondIsTag) {//<tag/><tag/> return Spacing.createSpacing(0, Integer.MAX_VALUE, 0, true, myXmlFormattingPolicy.getKeepBlankLines()); } return Spacing.createSpacing(0, Integer.MAX_VALUE, 0, myXmlFormattingPolicy.getShouldKeepLineBreaksInText(), myXmlFormattingPolicy.getKeepBlankLines()); }