From 000aebc5b4ad8b64c607f7063e24b0a29d8667c9 Mon Sep 17 00:00:00 2001 From: azerr Date: Thu, 29 Sep 2022 09:48:01 +0200 Subject: [PATCH] Fix tests on Windows OS Signed-off-by: azerr --- .../org/eclipse/lemminx/dom/DOMElement.java | 40 +++- .../cvc_complex_type_2_4_bCodeAction.java | 32 +-- .../contentmodel/utils/XMLGenerator.java | 35 +++- .../participants/XSIFormatterParticipant.java | 24 ++- .../format/DOMAttributeFormatter.java | 42 ++-- .../services/format/DOMCDATAFormatter.java | 19 +- .../services/format/DOMCommentFormatter.java | 11 +- .../services/format/DOMDocTypeFormatter.java | 108 +++++----- .../services/format/DOMElementFormatter.java | 181 +++++++++++------ .../services/format/TextEditUtils.java | 93 ++++----- .../format/XMLFormatterDocumentNew.java | 188 +++++++++-------- .../contentmodel/XMLExternalTest.java | 2 +- .../XMLSchemaDiagnosticsTest.java | 16 +- .../format/LeftWhitespacesOffsetTest.java | 85 ++++++++ .../services/format/TextEditUtilsTest.java | 6 +- .../XMLFormatterEmptyElementsTest.java | 4 +- .../XMLFormatterExperimentalTest.java | 6 - ...matterPreserveAttributeLineBreaksTest.java | 106 +++++++++- .../XMLFormatterQuoteStyleTest.java | 191 +++++++++++++++--- ...matterSetSpaceBeforeEmptyCloseTagTest.java | 5 - .../XMLFormatterWhitespaceSettingTest.java | 24 +-- .../XMLFormatterWithRangeTest.java | 25 ++- 22 files changed, 802 insertions(+), 441 deletions(-) create mode 100644 org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/LeftWhitespacesOffsetTest.java diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/dom/DOMElement.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/dom/DOMElement.java index d2b7f9250..7b0adf869 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/dom/DOMElement.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/dom/DOMElement.java @@ -388,6 +388,39 @@ public boolean isEndTagClosed() { return getEndTagCloseOffset() != NULL_VALUE; } + /** + * Returns the offset after the start tag name. + * + * + * + * + * + * @return the offset after the start tag name. + */ + public int getOffsetAfterStartTag() { + if (hasTagName()) { + return getStartTagOpenOffset() + getTagName().length() + 1; + } + return getStartTagOpenOffset() + 1; + } + + /** + * Returns the offset before the close of start tag name. + * + * + * + * + * + * + * @return the offset before the close of start tag name. + */ + public int getOffsetBeforeCloseOfStartTag() { + if (isSelfClosed()) { + return getEnd() - 2; + } + return getStartTagCloseOffset(); + } + /** * Returns true if the given element is an orphan end tag (which has no start * tag, eg: ) and false otherwise. @@ -566,11 +599,4 @@ public boolean isEmpty() { return true; } - public int getOffsetAfterStartTag() { - if (hasTagName()) { - return getStartTagOpenOffset() + 1; - } - return getStartTagOpenOffset() + getTagName().length() + 1; - } - } diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/codeactions/cvc_complex_type_2_4_bCodeAction.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/codeactions/cvc_complex_type_2_4_bCodeAction.java index e1fee909c..bee0197ec 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/codeactions/cvc_complex_type_2_4_bCodeAction.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/codeactions/cvc_complex_type_2_4_bCodeAction.java @@ -27,7 +27,6 @@ import org.eclipse.lemminx.extensions.contentmodel.utils.XMLGenerator; import org.eclipse.lemminx.services.extensions.codeaction.ICodeActionParticipant; import org.eclipse.lemminx.services.extensions.codeaction.ICodeActionRequest; -import org.eclipse.lemminx.utils.StringUtils; import org.eclipse.lsp4j.CodeAction; import org.eclipse.lsp4j.Diagnostic; import org.eclipse.lsp4j.Position; @@ -40,16 +39,10 @@ * Given this XML where the expected child elements are not present as defined * in the XSD: * - * - * Error: - * Child elements are missing from element: - * - servlet + * Error: Child elements are missing from element: - servlet * - * The following elements are expected: - * - description - * - display-name - * - icon - * - servlet-name + * The following elements are expected: - description - display-name - icon - + * servlet-name * * To fix the error, the code action will suggest inserting the expected * elements inside the parent tag @@ -104,25 +97,22 @@ public void doCodeAction(ICodeActionRequest request, List codeAction // indent if needed if (document.positionAt(element.getStartTagCloseOffset()).getLine() == document .positionAt(element.getEndTagOpenOffset()).getLine()) { - int lineNum = document.positionAt(element.getStartTagCloseOffset()).getLine(); - insertTextAll.append(document.getLineIndentInfo(lineNum).getLineDelimiter()); - insertTextAll.append(StringUtils.getStartWhitespaces(document.lineText(lineNum))); - insertTextRequired.append(document.getLineIndentInfo(lineNum).getLineDelimiter()); - insertTextRequired.append(StringUtils.getStartWhitespaces(document.lineText(lineNum))); + insertTextAll.append(generator.getLineDelimiter()); + insertTextAll.append(generator.getWhitespacesIndent()); + insertTextRequired.append(generator.getLineDelimiter()); + insertTextRequired.append(generator.getWhitespacesIndent()); } String insertStrAll = insertTextAll.toString(); String insertStrRequired = insertTextRequired.toString(); - CodeAction insertAllExpectedElement = CodeActionFactory.insert( - "Insert all expected elements", childElementPosition, insertStrAll, - document.getTextDocument(), diagnostic); + CodeAction insertAllExpectedElement = CodeActionFactory.insert("Insert all expected elements", + childElementPosition, insertStrAll, document.getTextDocument(), diagnostic); codeActions.add(insertAllExpectedElement); - CodeAction insertRequriedExpectedElement = CodeActionFactory.insert( - "Insert only required elements", childElementPosition, insertStrRequired, - document.getTextDocument(), diagnostic); + CodeAction insertRequriedExpectedElement = CodeActionFactory.insert("Insert only required elements", + childElementPosition, insertStrRequired, document.getTextDocument(), diagnostic); codeActions.add(insertRequriedExpectedElement); diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/utils/XMLGenerator.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/utils/XMLGenerator.java index b10bde9c2..6f7e01071 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/utils/XMLGenerator.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/utils/XMLGenerator.java @@ -68,6 +68,24 @@ public XMLGenerator(SharedSettings sharedSettings, boolean autoCloseTags, String this.maxLevel = maxLevel; } + /** + * Returns the line delimiter. + * + * @return the line delimiter. + */ + public String getLineDelimiter() { + return lineDelimiter; + } + + /** + * Returns the whitespaces indentation. + * + * @return the whitespaces indentation. + */ + public String getWhitespacesIndent() { + return whitespacesIndent; + } + /** * Returns the XML generated from the given element declaration. * @@ -113,16 +131,16 @@ public String generate(CMElementDeclaration elementDeclaration, String prefix, b } private int generate(CMElementDeclaration elementDeclaration, String prefix, boolean generateEndTag, - boolean generateOnlyChildren, int level, - int snippetIndex, XMLBuilder xml, List generatedElements, - Collection existingElementNames, boolean generateOnlyRequired) { + boolean generateOnlyChildren, int level, int snippetIndex, XMLBuilder xml, + List generatedElements, Collection existingElementNames, + boolean generateOnlyRequired) { if (generateOnlyChildren) { Collection childElements = elementDeclaration.getElements(); for (CMElementDeclaration child : childElements) { if (isGenerateChild(elementDeclaration, generateOnlyRequired, child.getName())) { - snippetIndex = generate(child, prefix, true, false, level + 1, snippetIndex, xml, - generatedElements, existingElementNames, generateOnlyRequired); + snippetIndex = generate(child, prefix, true, false, level + 1, snippetIndex, xml, generatedElements, + existingElementNames, generateOnlyRequired); } } return snippetIndex; @@ -149,8 +167,8 @@ private int generate(CMElementDeclaration elementDeclaration, String prefix, boo for (CMElementDeclaration child : children) { if (isGenerateChild(elementDeclaration, generateOnlyRequired, child.getName())) { level++; - snippetIndex = generate(child, prefix, true, false, level, snippetIndex, xml, - generatedElements, existingElementNames, generateOnlyRequired); + snippetIndex = generate(child, prefix, true, false, level, snippetIndex, xml, generatedElements, + existingElementNames, generateOnlyRequired); level--; xml.linefeed(); xml.indent(level); @@ -401,8 +419,7 @@ public static MarkupContent createMarkupContent(CMElementDeclaration cmElement, */ private boolean isGenerateChild(CMElementDeclaration elementDeclaration, boolean generateOnlyRequired, String childName) { - if (!generateOnlyRequired - || (!elementDeclaration.isOptional(childName) && generateOnlyRequired)) { + if (!generateOnlyRequired || (!elementDeclaration.isOptional(childName) && generateOnlyRequired)) { return true; } return false; diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/xsi/participants/XSIFormatterParticipant.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/xsi/participants/XSIFormatterParticipant.java index 6a8fdc84d..1db636902 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/xsi/participants/XSIFormatterParticipant.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/xsi/participants/XSIFormatterParticipant.java @@ -159,22 +159,25 @@ public String getCurrentLineIndent(XMLBuilder xml, XMLFormattingOptions formatti } @Override - public boolean formatAttributeValue(DOMAttr attr, XMLFormatterDocumentNew formatterDocument, - int indentLevel, XMLFormattingOptions formattingOptions, List edits) { + public boolean formatAttributeValue(DOMAttr attr, XMLFormatterDocumentNew formatterDocument, int indentLevel, + XMLFormattingOptions formattingOptions, List edits) { XSISchemaLocationSplit split = XSISchemaLocationSplit.getSplit(formattingOptions); - if (split == XSISchemaLocationSplit.none || !XSISchemaModel.isXSISchemaLocationAttr(attr.getName(), attr) - || getFirstContentOffset(attr.getOriginalValue()) == -1) { + if (split == XSISchemaLocationSplit.none || !XSISchemaModel.isXSISchemaLocationAttr(attr.getName(), attr)) { return false; } + int firstContentOffset = getFirstContentOffset(attr.getOriginalValue()); + if (firstContentOffset == -1) { + return false; + } int attrValueStart = attr.getNodeAttrValue().getStart(); // Remove extra spaces between start of xsi:schemaLocation attribute value quote // and actual value formatterDocument.removeLeftSpaces(attrValueStart + 1, // <... xsi:schemaLocation="| value" // <... xsi:schemaLocation=" |value" - attrValueStart + getFirstContentOffset(attr.getOriginalValue()), edits); + attrValueStart + firstContentOffset, edits); int tabSize = formattingOptions.getTabSize(); int indentSpaceOffset; @@ -184,8 +187,8 @@ public boolean formatAttributeValue(DOMAttr attr, XMLFormatterDocumentNew format indentSpaceOffset = (attrValueStart + 1) - attr.getNodeAttrName().getStart() + formattingOptions.getSplitAttributesIndentSize() * tabSize; } else if (formattingOptions.isPreserveAttributeLineBreaks()) { - indentSpaceOffset = attrValueStart - - formatterDocument.getOffsetWithPreserveLineBreaks(startOfLineOffset, attrValueStart, tabSize, formattingOptions.isInsertSpaces()); + indentSpaceOffset = attrValueStart - formatterDocument.getOffsetWithPreserveLineBreaks(startOfLineOffset, + attrValueStart, tabSize, formattingOptions.isInsertSpaces()); } else { indentSpaceOffset = formatterDocument.getNormalizedLength(startOfLineOffset, attrValueStart + 1) - startOfLineOffset; @@ -195,15 +198,14 @@ public boolean formatAttributeValue(DOMAttr attr, XMLFormatterDocumentNew format int locationNum = 1; String attrValue = attr.getOriginalValue(); - for (int i = 0; i < attrValue.length(); i++) { - int from = formatterDocument.getLeftWhitespacesOffset(attrValueStart, attrValueStart + i + 1); + for (int i = firstContentOffset; i < attrValue.length(); i++) { + int from = formatterDocument.adjustOffsetWithLeftWhitespaces(attrValueStart, attrValueStart + i + 1); if (Character.isWhitespace(attrValue.charAt(i)) && !Character.isWhitespace(attrValue.charAt(i + 1)) && !StringUtils.isQuote(attrValue.charAt(from - attrValueStart))) { // Insert newline and indent where required based on setting if (locationNum % lineFeed == 0) { formatterDocument.replaceLeftSpacesWithIndentationWithOffsetSpaces(indentSpaceOffset, - attrValueStart + i + 1, - true, edits); + attrValueStart, attrValueStart + i + 1, true, edits); } else { formatterDocument.replaceLeftSpacesWithOneSpace(indentSpaceOffset, attrValueStart + i + 1, edits); } diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/DOMAttributeFormatter.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/DOMAttributeFormatter.java index af1865039..21c063e1a 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/DOMAttributeFormatter.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/DOMAttributeFormatter.java @@ -14,10 +14,9 @@ import java.util.List; import org.eclipse.lemminx.dom.DOMAttr; -import org.eclipse.lsp4j.TextEdit; import org.eclipse.lemminx.settings.EnforceQuoteStyle; import org.eclipse.lemminx.utils.StringUtils; -import org.eclipse.lemminx.settings.XMLFormattingOptions; +import org.eclipse.lsp4j.TextEdit; /** * DOM attribute formatter. @@ -42,12 +41,12 @@ public void formatAttribute(DOMAttr attr, int prevOffset, boolean singleAttribut if (useSettings) { int indentLevel = parentConstraints.getIndentLevel(); if (isPreserveAttributeLineBreaks() && hasLineBreak(prevOffset, attr.getStart())) { - replaceLeftSpacesWithIndentation(indentLevel + 1, attr.getStart(), true, edits); + replaceLeftSpacesWithIndentation(indentLevel + 1, prevOffset, attr.getStart(), true, edits); alreadyIndented = true; } else if (isSplitAttributes() && !singleAttribute) { // move the attribute to a new line and indent it. - replaceLeftSpacesWithIndentation(indentLevel + getSplitAttributesIndentSize(), attr.getStart(), true, - edits); + replaceLeftSpacesWithIndentation(indentLevel + getSplitAttributesIndentSize(), prevOffset, + attr.getStart(), true, edits); alreadyIndented = true; } } @@ -79,7 +78,7 @@ public void formatAttribute(DOMAttr attr, int prevOffset, boolean singleAttribut int attrValueStart = attr.getNodeAttrValue().getStart(); // String originalValue = attr.getOriginalValue(); if (getEnforceQuoteStyle() == EnforceQuoteStyle.preferred && originalValue != null) { - if (originalValue.charAt(0) != getQuotationAsChar() - && StringUtils.isQuote(originalValue.charAt(0))) { - formatterDocument.replaceQuoteWithPreferred(attr.getNodeAttrValue().getStart(), - attr.getNodeAttrValue().getStart() + 1, getQuotationAsString(), edits); + if (originalValue.charAt(0) != getQuotationAsChar() && StringUtils.isQuote(originalValue.charAt(0))) { + replaceQuoteWithPreferred(attr.getNodeAttrValue().getStart(), attr.getNodeAttrValue().getStart() + 1, + edits); } if (originalValue.charAt(originalValue.length() - 1) != getQuotationAsChar() && StringUtils.isQuote(originalValue.charAt(originalValue.length() - 1))) { - formatterDocument.replaceQuoteWithPreferred(attr.getNodeAttrValue().getEnd() - 1, - attr.getNodeAttrValue().getEnd(), getQuotationAsString(), edits); + replaceQuoteWithPreferred(attr.getNodeAttrValue().getEnd() - 1, attr.getNodeAttrValue().getEnd(), + edits); } } } + private void formatAttributeValue(DOMAttr attr, int indentLevel, List edits) { + formatterDocument.formatAttributeValue(attr, indentLevel, edits); + } + + private void replaceQuoteWithPreferred(int from, int to, List edits) { + formatterDocument.replaceQuoteWithPreferred(from, to, edits); + } + private void replaceLeftSpacesWithOneSpace(int from, int to, List edits) { formatterDocument.replaceLeftSpacesWithOneSpace(from, to, edits); } - private void replaceLeftSpacesWithIndentation(int indentLevel, int offset, boolean addLineSeparator, + private void replaceLeftSpacesWithIndentation(int indentLevel, int leftLimit, int to, boolean addLineSeparator, List edits) { - formatterDocument.replaceLeftSpacesWithIndentation(indentLevel, offset, addLineSeparator, edits); + formatterDocument.replaceLeftSpacesWithIndentation(indentLevel, leftLimit, to, addLineSeparator, edits); } private void removeLeftSpaces(int from, int to, List edits) { @@ -122,10 +128,6 @@ private int getSplitAttributesIndentSize() { return formatterDocument.getSharedSettings().getFormattingSettings().getSplitAttributesIndentSize(); } - private XMLFormattingOptions getFormattingSettings() { - return formatterDocument.getSharedSettings().getFormattingSettings(); - } - boolean isPreserveAttributeLineBreaks() { return formatterDocument.getSharedSettings().getFormattingSettings().isPreserveAttributeLineBreaks(); } @@ -138,10 +140,6 @@ private char getQuotationAsChar() { return formatterDocument.getSharedSettings().getPreferences().getQuotationAsChar(); } - private String getQuotationAsString() { - return formatterDocument.getSharedSettings().getPreferences().getQuotationAsString(); - } - private EnforceQuoteStyle getEnforceQuoteStyle() { return formatterDocument.getSharedSettings().getFormattingSettings().getEnforceQuoteStyle(); } diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/DOMCDATAFormatter.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/DOMCDATAFormatter.java index 43410522e..0920133b9 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/DOMCDATAFormatter.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/DOMCDATAFormatter.java @@ -63,14 +63,19 @@ public void formatCDATASection(DOMCDATASection cDATANode, XMLFormattingConstrain if (availableLineWidth <= 0) { if (spaceStart != -1) { // Add new line when the comment extends over the maximum line width - replaceLeftSpacesWithIndentation(parentConstraints.getIndentLevel(), contentStart, - true, edits); + replaceLeftSpacesWithIndentation(parentConstraints.getIndentLevel(), spaceStart, + contentStart, true, edits); int indentSpaces = (getTabSize() * parentConstraints.getIndentLevel()); availableLineWidth = getMaxLineWidth() - indentSpaces - (contentEnd + 1 - contentStart); } - } else if (spaceStart == cDATAStartContent || contentEnd == cDATAEndContent) { - // Remove spaces before and after the start and ending bracket of content - removeLeftSpaces(spaceStart + 1, contentStart, edits); + } else if (spaceStart == cDATAStartContent) { + // Remove spaces before the start bracket of content + removeLeftSpaces(spaceStart, contentStart, edits); + spaceStart = -1; + spaceEnd = -1; + } else if (contentEnd == cDATAEndContent) { + // Remove spaces after the ending bracket of content + removeLeftSpaces(spaceStart, contentEnd, edits); spaceStart = -1; spaceEnd = -1; } else { @@ -105,8 +110,8 @@ private void replaceSpacesWithOneSpace(int spaceStart, int spaceEnd, List edits) { - return formatterDocument.replaceLeftSpacesWithIndentation(indentLevel, offset, addLineSeparator, edits); + return formatterDocument.replaceLeftSpacesWithIndentation(indentLevel, from, to, addLineSeparator, edits); } } diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/DOMCommentFormatter.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/DOMCommentFormatter.java index b534dd97c..da5603ba1 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/DOMCommentFormatter.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/DOMCommentFormatter.java @@ -47,8 +47,7 @@ public void formatComment(DOMComment commentNode, XMLFormattingConstraints paren boolean addLineSeparator = formatterDocument.hasLineBreak(leftWhitespaceOffset, start); if (addLineSeparator) { // Indent in case of comment being at the start of line - replaceLeftSpacesWithIndentation(parentConstraints.getIndentLevel(), start, - addLineSeparator, edits); + replaceLeftSpacesWithIndentation(parentConstraints.getIndentLevel(), leftWhitespaceOffset, start, addLineSeparator, edits); } int spaceStart = -1; int spaceEnd = -1; @@ -73,8 +72,8 @@ public void formatComment(DOMComment commentNode, XMLFormattingConstraints paren if (availableLineWidth <= 0) { if (spaceStart != -1) { // Add new line when the comment extends over the maximum line width - replaceLeftSpacesWithIndentation(parentConstraints.getIndentLevel(), contentStart, - true, edits); + replaceLeftSpacesWithIndentation(parentConstraints.getIndentLevel(), spaceStart, contentStart, true, + edits); int indentSpaces = (getTabSize() * parentConstraints.getIndentLevel()); availableLineWidth = getMaxLineWidth() - indentSpaces - (contentEnd + 1 - contentStart); } @@ -106,8 +105,8 @@ private void replaceSpacesWithOneSpace(int spaceStart, int spaceEnd, List edits) { - return formatterDocument.replaceLeftSpacesWithIndentation(indentLevel, offset, addLineSeparator, edits); + return formatterDocument.replaceLeftSpacesWithIndentation(indentLevel, from, to, addLineSeparator, edits); } } diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/DOMDocTypeFormatter.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/DOMDocTypeFormatter.java index 10f746f90..af4891a8f 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/DOMDocTypeFormatter.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/DOMDocTypeFormatter.java @@ -18,10 +18,10 @@ import org.eclipse.lemminx.dom.DTDAttlistDecl; import org.eclipse.lemminx.dom.DTDDeclNode; import org.eclipse.lemminx.dom.DTDDeclParameter; -import org.eclipse.lsp4j.TextEdit; -import org.w3c.dom.Node; import org.eclipse.lemminx.settings.EnforceQuoteStyle; import org.eclipse.lemminx.utils.StringUtils; +import org.eclipse.lsp4j.TextEdit; +import org.w3c.dom.Node; /** * DOM docType formatter. @@ -46,7 +46,7 @@ public void formatDocType(DOMDocumentType docType, XMLFormattingConstraints pare List parameters = docType.getParameters(); if (!parameters.isEmpty()) { for (DTDDeclParameter parameter : parameters) { - replaceLeftSpacesWithOneSpace(parameter.getStart(), edits); + replaceLeftSpacesWithOneSpace(docType.getStart(), parameter.getStart(), edits); if (docType.isInternalSubset(parameter)) { // level + 1 since the 'level' value is the doctype tag's level XMLFormattingConstraints constraints = new XMLFormattingConstraints(); @@ -62,10 +62,8 @@ public void formatDocType(DOMDocumentType docType, XMLFormattingConstraints pare if (quoteStart != -1 && quoteEnd != -1) { // replace current quote with preferred quote in the case: // - formatterDocument.replaceQuoteWithPreferred(quoteStart, - quoteStart + 1, getQuotationAsString(), edits); - formatterDocument.replaceQuoteWithPreferred(quoteEnd - 1, - quoteEnd, getQuotationAsString(), edits); + formatterDocument.replaceQuoteWithPreferred(quoteStart, quoteStart + 1, edits); + formatterDocument.replaceQuoteWithPreferred(quoteEnd - 1, quoteEnd, edits); } } } @@ -75,16 +73,18 @@ public void formatDocType(DOMDocumentType docType, XMLFormattingConstraints pare if (docType.isClosed()) { // Remove space between content and end bracket in case of no internal subset // Example: + int startDocType = docType.getStart(); int endDocType = docType.getEnd() - 1; - removeLeftSpaces(endDocType, edits); + removeLeftSpaces(startDocType, endDocType, edits); } } else { // Add new line at end of internal subset // |]> + int startDocType = internalSubset.getStart(); int endDocType = internalSubset.getEnd() - 1; String lineDelimiter = formatterDocument.getLineDelimiter(); - replaceLeftSpacesWith(endDocType, lineDelimiter, edits); + replaceLeftSpacesWith(startDocType, endDocType, lineDelimiter, edits); } } @@ -94,22 +94,22 @@ private void formatDTD(DOMDocumentType docType, XMLFormattingConstraints parentC for (DOMNode child : docType.getChildren()) { switch (child.getNodeType()) { - case DOMNode.DTD_ELEMENT_DECL_NODE: - case DOMNode.DTD_ATT_LIST_NODE: - case Node.ENTITY_NODE: - case DOMNode.DTD_NOTATION_DECL: - // Format DTD node declaration, for example: - // - DTDDeclNode nodeDecl = (DTDDeclNode) child; - formatDTDNodeDecl(nodeDecl, parentConstraints, addLineSeparator, edits); - addLineSeparator = true; - break; - - default: - // unknown, so just leave alone for now but make sure to update - // available line width - int width = updateLineWidthWithLastLine(child, parentConstraints.getAvailableLineWidth()); - parentConstraints.setAvailableLineWidth(width); + case DOMNode.DTD_ELEMENT_DECL_NODE: + case DOMNode.DTD_ATT_LIST_NODE: + case Node.ENTITY_NODE: + case DOMNode.DTD_NOTATION_DECL: + // Format DTD node declaration, for example: + // + DTDDeclNode nodeDecl = (DTDDeclNode) child; + formatDTDNodeDecl(nodeDecl, parentConstraints, addLineSeparator, edits); + addLineSeparator = true; + break; + + default: + // unknown, so just leave alone for now but make sure to update + // available line width + int width = updateLineWidthWithLastLine(child, parentConstraints.getAvailableLineWidth()); + parentConstraints.setAvailableLineWidth(width); } } } @@ -123,8 +123,8 @@ private void formatDTDNodeDecl(DTDDeclNode nodeDecl, XMLFormattingConstraints pa // 1) indent the DTD element, entity, notation declaration // before formatting : [space][space] // after formatting : - replaceLeftSpacesWithIndentation(parentConstraints.getIndentLevel(), nodeDecl.getStart(), addLineSeparator, - edits); + replaceLeftSpacesWithIndentation(parentConstraints.getIndentLevel(), nodeDecl.getParentNode().getStart(), + nodeDecl.getStart(), addLineSeparator, edits); // 2 separate each parameters with one space // before formatting : @@ -134,82 +134,88 @@ private void formatDTDNodeDecl(DTDDeclNode nodeDecl, XMLFormattingConstraints pa int indentLevel = nodeDecl.getOwnerDocument().isDTD() ? 1 : 2; List internalDecls = attlist.getInternalChildren(); if (internalDecls == null) { + int previousOffset = attlist.getStart(); for (DTDDeclParameter parameter : attlist.getParameters()) { // Normalize space at the start of parameter to a single space for ATTLIST, for // example: // - replaceLeftSpacesWithOneSpace(parameter.getStart(), edits); + replaceLeftSpacesWithOneSpace(previousOffset, parameter.getStart(), edits); // replace current quote with preferred quote in the case: // replaceQuoteWithPreferred(nodeDecl, parameter, edits); + previousOffset = parameter.getEnd(); } } else { boolean multipleInternalAttlistDecls = false; List params = attlist.getParameters(); DTDDeclParameter parameter; + int previousOffset = attlist.getStart(); for (int i = 0; i < params.size(); i++) { parameter = params.get(i); if (attlist.getNameParameter().equals(parameter)) { - replaceLeftSpacesWithOneSpace(parameter.getStart(), edits); + replaceLeftSpacesWithOneSpace(previousOffset, parameter.getStart(), edits); if (attlist.getParameters().size() > 1) { // has parameters after elementName multipleInternalAttlistDecls = true; } } else { if (multipleInternalAttlistDecls && i == 1) { - replaceLeftSpacesWithIndentation(indentLevel, parameter.getStart(), true, edits); + replaceLeftSpacesWithIndentation(indentLevel, previousOffset, parameter.getStart(), true, + edits); } else { - replaceLeftSpacesWithOneSpace(parameter.getStart(), edits); + replaceLeftSpacesWithOneSpace(previousOffset, parameter.getStart(), edits); } } + previousOffset = parameter.getEnd(); } for (DTDAttlistDecl attlistDecl : internalDecls) { params = attlistDecl.getParameters(); + previousOffset = attlistDecl.getStart(); for (int i = 0; i < params.size(); i++) { parameter = params.get(i); if (i == 0) { - replaceLeftSpacesWithIndentation(indentLevel, parameter.getStart(), true, edits); + replaceLeftSpacesWithIndentation(indentLevel, previousOffset, parameter.getStart(), true, + edits); } else { - replaceLeftSpacesWithOneSpace(parameter.getStart(), edits); + replaceLeftSpacesWithOneSpace(previousOffset, parameter.getStart(), edits); } + previousOffset = parameter.getEnd(); } } } } else { List parameters = nodeDecl.getParameters(); if (!parameters.isEmpty()) { + int previousOffset = nodeDecl.getStart(); for (DTDDeclParameter parameter : parameters) { // Normalize space at the start of parameter to a single space for non-ATTLIST, // for example: // - replaceLeftSpacesWithOneSpace(parameter.getStart(), edits); + replaceLeftSpacesWithOneSpace(previousOffset, parameter.getStart(), edits); // replace current quote with preferred quote in the case: // replaceQuoteWithPreferred(nodeDecl, parameter, edits); + previousOffset = parameter.getEnd(); } } } } - private void replaceLeftSpacesWith(int to, String replacement, List edits) { - formatterDocument.replaceLeftSpacesWith(to, replacement, edits); + private void replaceLeftSpacesWith(int from, int to, String replacement, List edits) { + formatterDocument.replaceLeftSpacesWith(from, to, replacement, edits); } - private void replaceLeftSpacesWithOneSpace(int offset, List edits) { - formatterDocument.replaceLeftSpacesWithOneSpace(offset, edits); + private void replaceLeftSpacesWithOneSpace(int from, int to, List edits) { + formatterDocument.replaceLeftSpacesWithOneSpace(from, to, edits); } - private int replaceLeftSpacesWithIndentation(int indentLevel, int offset, boolean addLineSeparator, + private int replaceLeftSpacesWithIndentation(int indentLevel, int from, int to, boolean addLineSeparator, List edits) { - return formatterDocument.replaceLeftSpacesWithIndentation(indentLevel, offset, addLineSeparator, edits); - } - - private void removeLeftSpaces(int to, List edits) { - formatterDocument.removeLeftSpaces(to, edits); + return formatterDocument.replaceLeftSpacesWithIndentation(indentLevel, from, to, addLineSeparator, edits); } - private String getQuotationAsString() { - return formatterDocument.getSharedSettings().getPreferences().getQuotationAsString(); + private void removeLeftSpaces(int from, int to, List edits) { + formatterDocument.removeLeftSpaces(from, to, edits); } private EnforceQuoteStyle getEnforceQuoteStyle() { @@ -237,13 +243,11 @@ private static int getDocTypeIdEnd(DOMDocumentType docType) { private void replaceQuoteWithPreferred(DTDDeclNode nodeDecl, DTDDeclParameter parameter, List edits) { int paramStart = parameter.getStart(); int paramEnd = parameter.getEnd(); - if (StringUtils.isQuote(nodeDecl.getOwnerDocument().getText().charAt(paramStart)) && - StringUtils.isQuote(nodeDecl.getOwnerDocument().getText().charAt(paramEnd - 1))) { + if (StringUtils.isQuote(nodeDecl.getOwnerDocument().getText().charAt(paramStart)) + && StringUtils.isQuote(nodeDecl.getOwnerDocument().getText().charAt(paramEnd - 1))) { if (getEnforceQuoteStyle() == EnforceQuoteStyle.preferred) { - formatterDocument.replaceQuoteWithPreferred(paramStart, - paramStart + 1, getQuotationAsString(), edits); - formatterDocument.replaceQuoteWithPreferred(paramEnd - 1, - paramEnd, getQuotationAsString(), edits); + formatterDocument.replaceQuoteWithPreferred(paramStart, paramStart + 1, edits); + formatterDocument.replaceQuoteWithPreferred(paramEnd - 1, paramEnd, edits); } } diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/DOMElementFormatter.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/DOMElementFormatter.java index 54f53af66..608c45932 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/DOMElementFormatter.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/DOMElementFormatter.java @@ -66,12 +66,15 @@ public void formatElement(DOMElement element, XMLFormattingConstraints parentCon private int formatStartTagElement(DOMElement element, XMLFormattingConstraints parentConstraints, EmptyElements emptyElements, int end, List edits) { + if (!element.hasStartTag()) { + // ex : example text - // after formatting: \n example text + // before formatting: example text + // after formatting: \n example text int parentStartCloseOffset = element.getParentElement().getStartTagCloseOffset() + 1; - if (parentStartCloseOffset != startTagOffset && StringUtils.isWhitespace(formatterDocument.getText(), - parentStartCloseOffset, startTagOffset)) { - int nbSpaces = replaceLeftSpacesWithIndentation(indentLevel, startTagOffset, !addLineSeparator, - edits); + if (parentStartCloseOffset != startTagOffset + && StringUtils.isWhitespace(formatterDocument.getText(), parentStartCloseOffset, startTagOffset)) { + int nbSpaces = replaceLeftSpacesWithIndentation(indentLevel, parentStartCloseOffset, startTagOffset, + !addLineSeparator, edits); width = nbSpaces + element.getStartTagCloseOffset() - startTagOffset; } break; @@ -96,11 +99,11 @@ private int formatStartTagElement(DOMElement element, XMLFormattingConstraints p int currentNewLineCount = getExistingNewLineCount(formatterDocument.getText(), startTagOffset, formatterDocument.getLineDelimiter()); if (currentNewLineCount > preservedNewLines) { - replaceLeftSpacesWithIndentationWithMultiNewLines(indentLevel, startTagOffset, + replaceLeftSpacesWithIndentationWithMultiNewLines(indentLevel, 0, startTagOffset, preservedNewLines + 1, edits); } else { // remove spaces and indent - int nbSpaces = replaceLeftSpacesWithIndentation(indentLevel, startTagOffset, !addLineSeparator, + int nbSpaces = replaceLeftSpacesWithIndentation(indentLevel, 0, startTagOffset, !addLineSeparator, edits); width = nbSpaces + element.getStartTagCloseOffset() - startTagOffset; } @@ -121,7 +124,18 @@ private int formatStartTagElement(DOMElement element, XMLFormattingConstraints p tag.append("'); - createTextEditIfNeeded(element.getEnd() - 3, element.getEnd(), tag.toString(), edits); + // get the from offset: + // - + // - + int from = getOffsetAfterStartTagOrLastAttribute(element); + // get the to offset: + // - | + // - | + int to = element.getEnd(); + // replace with > + // - + // - + createTextEditIfNeeded(from, to, tag.toString(), edits); formatted = true; } break; @@ -135,8 +149,18 @@ private int formatStartTagElement(DOMElement element, XMLFormattingConstraints p tag.append(" "); } tag.append("/>"); - createTextEditIfNeeded(element.getStartTagCloseOffset() - 1, element.getEnd(), tag.toString(), - edits); + // get the from offset: + // - + // - + int from = getOffsetAfterStartTagOrLastAttribute(element); + // get the to offset: + // - | + // - | + int to = element.getEnd(); + // replace with /> + // - + // - + createTextEditIfNeeded(from, to, tag.toString(), edits); formatted = true; } break; @@ -145,36 +169,34 @@ private int formatStartTagElement(DOMElement element, XMLFormattingConstraints p } if (!formatted) { - if (element.isSelfClosed()) { - // --> - int offset = element.getEnd() - 2; - if (shouldFormatClosingBracketNewLine(element)) { - // Add newline with indent before closing bracket. Ex: - // --> add newline here at '|' - replaceLeftSpacesWithIndentation(indentLevel + getSplitAttributesIndentSize(), offset, true, - edits); - } else if (isSpaceBeforeEmptyCloseTag()) { - replaceLeftSpacesWithOneSpace(offset, edits); - } else { - removeLeftSpaces(offset, edits); - } - } else if (element.isStartTagClosed()) { - formatElementStartTagCloseBracket(element, parentConstraints, edits); + if (element.isStartTagClosed() || element.isSelfClosed()) { + formatElementStartTagOrSelfClosed(element, parentConstraints, edits); } } } return width; } + private static int getOffsetAfterStartTagOrLastAttribute(DOMElement element) { + DOMAttr attr = getLastAttribute(element); + if (attr != null) { + return attr.getEnd(); + } + return element.getOffsetAfterStartTag(); + } + private int formatAttributes(DOMElement element, XMLFormattingConstraints parentConstraints, List edits) { if (element.hasAttributes()) { List attributes = element.getAttributeNodes(); + // initialize the previous offset with the start tag: + // . int prevOffset = element.getOffsetAfterStartTag(); boolean singleAttribute = attributes.size() == 1; for (DOMAttr attr : attributes) { + // Format current attribute attributeFormatter.formatAttribute(attr, prevOffset, singleAttribute, true, parentConstraints, edits); + // set the previous offset with end of the current attribute: + // edits) { - int offset = element.getStartTagCloseOffset(); + // + // + int startTagClose = element.getOffsetBeforeCloseOfStartTag(); + // + // + int startTagOpen = element.getOffsetAfterStartTag(); String replace = ""; + boolean spaceBeforeEmptyCloseTag = isSpaceBeforeEmptyCloseTag(); if (isPreserveAttributeLineBreaks() && element.hasAttributes() - && hasLineBreak(getLastAttribute(element).getEnd(), element.getStartTagCloseOffset())) { + && hasLineBreak(getLastAttribute(element).getEnd(), startTagClose)) { + spaceBeforeEmptyCloseTag = false; int indentLevel = parentConstraints.getIndentLevel(); if (indentLevel == 0) { + // + // Add newline when there is no indent replace = formatterDocument.getLineDelimiter(); } else { + // \n + // // Add newline with indent according to indent level - replaceLeftSpacesWithIndentation(indentLevel, offset, true, edits); + replaceLeftSpacesWithIndentation(indentLevel, startTagOpen, startTagClose, true, edits); return; } } else if (shouldFormatClosingBracketNewLine(element)) { int indentLevel = parentConstraints.getIndentLevel(); - replaceLeftSpacesWithIndentation(indentLevel + getSplitAttributesIndentSize(), offset, true, edits); + replaceLeftSpacesWithIndentation(indentLevel + getSplitAttributesIndentSize(), startTagOpen, startTagClose, + true, edits); return; } - replaceLeftSpacesWith(offset, replace, edits); + if (element.isSelfClosed()) { + if (spaceBeforeEmptyCloseTag) { + // --> + replace = replace + " "; + } + } + // remove spaces from the offset of start tag and start tag close + // --> + // --> + replaceLeftSpacesWith(startTagOpen, startTagClose, replace, edits); } private int formatEndTagElement(DOMElement element, XMLFormattingConstraints parentConstraints, @@ -230,11 +275,12 @@ private int formatEndTagElement(DOMElement element, XMLFormattingConstraints par break; case MixedContent: // Remove spaces and indent if the last child is an element, not text - // before formatting: example text + // before formatting: example text // after formatting: example text \n if (element.getLastChild().isElement() && Character.isWhitespace(formatterDocument.getText().charAt(endTagOffset - 1))) { - replaceLeftSpacesWithIndentation(indentLevel, endTagOffset, true, edits); + replaceLeftSpacesWithIndentation(indentLevel, element.getStartTagCloseOffset(), endTagOffset, true, + edits); } break; case IgnoreSpace: @@ -243,11 +289,12 @@ private int formatEndTagElement(DOMElement element, XMLFormattingConstraints par int currentNewLineCount = getExistingNewLineCount(formatterDocument.getText(), endTagOffset, formatterDocument.getLineDelimiter()); if (currentNewLineCount > preservedNewLines) { - replaceLeftSpacesWithIndentationWithMultiNewLines(indentLevel, endTagOffset, preservedNewLines + 1, - edits); + replaceLeftSpacesWithIndentationWithMultiNewLines(indentLevel, element.getStartTagCloseOffset(), + endTagOffset, preservedNewLines + 1, edits); } else { // remove spaces and indent - replaceLeftSpacesWithIndentation(indentLevel, endTagOffset, true, edits); + replaceLeftSpacesWithIndentation(indentLevel, element.getStartTagCloseOffset(), endTagOffset, true, + edits); break; } case NormalizeSpace: @@ -258,7 +305,7 @@ private int formatEndTagElement(DOMElement element, XMLFormattingConstraints par // after formatting : if (element.isEndTagClosed()) { int endTagCloseOffset = element.getEndTagCloseOffset(); - removeLeftSpaces(endTagCloseOffset, edits); + removeLeftSpaces(element.getEndTagOpenOffset(), endTagCloseOffset, edits); } return 0; } @@ -339,52 +386,64 @@ private EmptyElements getEmptyElements(DOMElement element) { * Return true if conditions are met to format according to the * closingBracketNewLine setting. * - * 1. splitAttribute must be set to true - * 2. there must be at least 2 attributes in the element + * 1. splitAttribute must be set to true 2. there must be at least 2 attributes + * in the element * * @param element the DOM element * @return true if should format according to closingBracketNewLine setting. */ private boolean shouldFormatClosingBracketNewLine(DOMElement element) { - boolean isSingleAttribute = element.getAttributeNodes() != null - ? element.getAttributeNodes().size() == 1 + boolean isSingleAttribute = element.getAttributeNodes() != null ? element.getAttributeNodes().size() == 1 : true; return (formatterDocument.getSharedSettings().getFormattingSettings().getClosingBracketNewLine() && isSplitAttributes() && !isSingleAttribute); } - private void replaceLeftSpacesWith(int offset, String replace, List edits) { - formatterDocument.replaceLeftSpacesWith(offset, replace, edits); - } - - private void replaceLeftSpacesWithOneSpace(int offset, List edits) { - formatterDocument.replaceLeftSpacesWithOneSpace(offset, edits); + private void replaceLeftSpacesWith(int from, int to, String replace, List edits) { + formatterDocument.replaceLeftSpacesWith(from, to, replace, edits); } - private int replaceLeftSpacesWithIndentation(int indentLevel, int offset, boolean addLineSeparator, + private int replaceLeftSpacesWithIndentation(int indentLevel, int from, int to, boolean addLineSeparator, List edits) { - return formatterDocument.replaceLeftSpacesWithIndentation(indentLevel, offset, addLineSeparator, edits); + return formatterDocument.replaceLeftSpacesWithIndentation(indentLevel, from, to, addLineSeparator, edits); } - private int replaceLeftSpacesWithIndentationWithMultiNewLines(int indentLevel, int offset, int newLineCount, + private int replaceLeftSpacesWithIndentationWithMultiNewLines(int indentLevel, int from, int to, int newLineCount, List edits) { - return formatterDocument.replaceLeftSpacesWithIndentationWithMultiNewLines(indentLevel, offset, newLineCount, + return formatterDocument.replaceLeftSpacesWithIndentationWithMultiNewLines(indentLevel, from, to, newLineCount, edits); } - private void removeLeftSpaces(int to, List edits) { - formatterDocument.removeLeftSpaces(to, edits); + private void removeLeftSpaces(int from, int to, List edits) { + formatterDocument.removeLeftSpaces(from, to, edits); } private void createTextEditIfNeeded(int from, int to, String expectedContent, List edits) { formatterDocument.createTextEditIfNeeded(from, to, expectedContent, edits); } - private boolean hasLineBreak(int end, int startTagCloseOffset) { - return formatterDocument.hasLineBreak(end, startTagCloseOffset); + /** + * Returns true if the DOM document have some line break in the given range + * [from, to] and false otherwise. + * + * @param from the from offset range. + * @param to the to offset range. + * + * @return true if the DOM document have some line break in the given range + * [from, to] and false otherwise. + */ + private boolean hasLineBreak(int from, int to) { + return formatterDocument.hasLineBreak(from, to); } - private DOMAttr getLastAttribute(DOMElement element) { + /** + * Returns the last attribute of the given DOMelement and null otherwise. + * + * @param element the DOM element. + * + * @return the last attribute of the given DOMelement and null otherwise. + */ + private static DOMAttr getLastAttribute(DOMElement element) { if (!element.hasAttributes()) { return null; } diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/TextEditUtils.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/TextEditUtils.java index de859eee9..35d8f25fe 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/TextEditUtils.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/TextEditUtils.java @@ -20,7 +20,6 @@ import org.eclipse.lemminx.commons.BadLocationException; import org.eclipse.lemminx.commons.TextDocument; -import org.eclipse.lemminx.utils.StringUtils; import org.eclipse.lsp4j.Position; import org.eclipse.lsp4j.Range; import org.eclipse.lsp4j.TextEdit; @@ -51,67 +50,19 @@ public static TextEdit createTextEditIfNeeded(int from, int to, String expectedC String text = textDocument.getText(); // Check if content from the range [from, to] is the same than expected content - if (isMatchExpectedContent(from, to, expectedContent, text) - // The expected content exists, no need to create a TextEdit - && (!expectedContent.equals(System.lineSeparator()))) { - // Line separator may be replacing more white space than specified by from/to, - // therefore may not match expected content. + if (isMatchExpectedContent(from, to, expectedContent, text)) { + // The expected content exists, no need to create a TextEdit return null; } - if (from == to) { - // Insert the expected content. - try { - Position endPos = textDocument.positionAt(to); - Position startPos = endPos; - Range range = new Range(startPos, endPos); - return new TextEdit(range, expectedContent); - } catch (BadLocationException e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - } - } - - int i = expectedContent.length() - 1; - boolean matchExpectedContent = true; - while (from >= 0) { - char c = text.charAt(from); - if (Character.isWhitespace(c)) { - if (matchExpectedContent) { - if (i < 0) { - matchExpectedContent = false; - } else { - if (expectedContent.charAt(i) != c) { - matchExpectedContent = false; - } - i--; - } - } - } else { - break; - } - from--; - } - from++; - if (matchExpectedContent) { - matchExpectedContent = to - from == expectedContent.length(); - } - - // Set parameters to handle case when replacing single quote with double quote - // and vice versa - if (from == to && !expectedContent.isEmpty() && StringUtils.isQuote(expectedContent.toCharArray()[0])) { - from--; - matchExpectedContent = false; - } - - if (!matchExpectedContent) { - try { - Position endPos = textDocument.positionAt(to); - Position startPos = to == from ? endPos : textDocument.positionAt(from); - Range range = new Range(startPos, endPos); - return new TextEdit(range, expectedContent); - } catch (BadLocationException e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - } + // Insert the expected content. + try { + Position endPos = textDocument.positionAt(to); + Position startPos = to == from ? endPos : textDocument.positionAt(from); + Range range = new Range(startPos, endPos); + return new TextEdit(range, expectedContent); + } catch (BadLocationException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); } return null; } @@ -206,4 +157,28 @@ private static List mergeSort(List data, Comparator comparator) { return data; } + /** + * Returns the offset of the first whitespace that's found in the given range + * [leftLimit,to] from the left of the to, and leftLimit otherwise. + * + * @param leftLimit the left limit range. + * @param to the to range. + * + * @return the offset of the first whitespace that's found in the given range + * [leftLimit,to] from the left of the to, and leftLimit otherwise. + */ + public static int adjustOffsetWithLeftWhitespaces(int leftLimit, int to, String text) { + if (to == 0) { + return -1; + } + for (int i = to - 1; i >= leftLimit; i--) { + char c = text.charAt(i); + if (!Character.isWhitespace(c)) { + // The current character is not a whitespace, return the offset of the character + return i + 1; + } + } + return leftLimit; + } + } diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/XMLFormatterDocumentNew.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/XMLFormatterDocumentNew.java index a7815f941..0ebd31d05 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/XMLFormatterDocumentNew.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/format/XMLFormatterDocumentNew.java @@ -21,13 +21,13 @@ import org.eclipse.lemminx.commons.TextDocument; import org.eclipse.lemminx.dom.DOMAttr; import org.eclipse.lemminx.dom.DOMCDATASection; +import org.eclipse.lemminx.dom.DOMComment; import org.eclipse.lemminx.dom.DOMDocument; import org.eclipse.lemminx.dom.DOMDocumentType; import org.eclipse.lemminx.dom.DOMElement; import org.eclipse.lemminx.dom.DOMNode; import org.eclipse.lemminx.dom.DOMProcessingInstruction; import org.eclipse.lemminx.dom.DOMText; -import org.eclipse.lemminx.dom.DOMComment; import org.eclipse.lemminx.services.extensions.format.IFormatterParticipant; import org.eclipse.lemminx.settings.SharedSettings; import org.eclipse.lemminx.settings.XMLFormattingOptions; @@ -274,47 +274,46 @@ private void format(DOMNode child, XMLFormattingConstraints parentConstraints, i switch (child.getNodeType()) { - case Node.DOCUMENT_TYPE_NODE: - DOMDocumentType docType = (DOMDocumentType) child; - docTypeFormatter.formatDocType(docType, parentConstraints, start, end, edits); - break; + case Node.DOCUMENT_TYPE_NODE: + DOMDocumentType docType = (DOMDocumentType) child; + docTypeFormatter.formatDocType(docType, parentConstraints, start, end, edits); + break; - case Node.DOCUMENT_NODE: - DOMDocument document = (DOMDocument) child; - formatChildren(document, parentConstraints, start, end, edits); - break; + case Node.DOCUMENT_NODE: + DOMDocument document = (DOMDocument) child; + formatChildren(document, parentConstraints, start, end, edits); + break; - case DOMNode.PROCESSING_INSTRUCTION_NODE: - DOMProcessingInstruction processingInstruction = (DOMProcessingInstruction) child; - processingInstructionFormatter.formatProcessingInstruction(processingInstruction, parentConstraints, - edits); - break; + case DOMNode.PROCESSING_INSTRUCTION_NODE: + DOMProcessingInstruction processingInstruction = (DOMProcessingInstruction) child; + processingInstructionFormatter.formatProcessingInstruction(processingInstruction, parentConstraints, edits); + break; - case Node.ELEMENT_NODE: - DOMElement element = (DOMElement) child; - elementFormatter.formatElement(element, parentConstraints, start, end, edits); - break; + case Node.ELEMENT_NODE: + DOMElement element = (DOMElement) child; + elementFormatter.formatElement(element, parentConstraints, start, end, edits); + break; - case Node.TEXT_NODE: - DOMText textNode = (DOMText) child; - textFormatter.formatText(textNode, parentConstraints, edits); - break; + case Node.TEXT_NODE: + DOMText textNode = (DOMText) child; + textFormatter.formatText(textNode, parentConstraints, edits); + break; - case Node.COMMENT_NODE: - DOMComment commentNode = (DOMComment) child; - commentFormatter.formatComment(commentNode, parentConstraints, edits); - break; + case Node.COMMENT_NODE: + DOMComment commentNode = (DOMComment) child; + commentFormatter.formatComment(commentNode, parentConstraints, edits); + break; - case Node.CDATA_SECTION_NODE: - DOMCDATASection cDATANode = (DOMCDATASection) child; - cDATAFormatter.formatCDATASection(cDATANode, parentConstraints, edits); - break; + case Node.CDATA_SECTION_NODE: + DOMCDATASection cDATANode = (DOMCDATASection) child; + cDATAFormatter.formatCDATASection(cDATANode, parentConstraints, edits); + break; - default: - // unknown, so just leave alone for now but make sure to update - // available line width - int width = updateLineWidthWithLastLine(child, parentConstraints.getAvailableLineWidth()); - parentConstraints.setAvailableLineWidth(width); + default: + // unknown, so just leave alone for now but make sure to update + // available line width + int width = updateLineWidthWithLastLine(child, parentConstraints.getAvailableLineWidth()); + parentConstraints.setAvailableLineWidth(width); } } @@ -325,103 +324,81 @@ public void formatChildren(DOMNode currentDOMNode, XMLFormattingConstraints pare } } - public void formatAttributeValue(DOMAttr attr, XMLFormatterDocumentNew formatterDocument, int indentLevel, - XMLFormattingOptions formattingOptions, List edits) { + public void formatAttributeValue(DOMAttr attr, int indentLevel, List edits) { if (formatterParticipants != null) { for (IFormatterParticipant formatterParticipant : formatterParticipants) { try { - if (formatterParticipant.formatAttributeValue(attr, formatterDocument, indentLevel, - formattingOptions, edits)) { + if (formatterParticipant.formatAttributeValue(attr, this, indentLevel, getFormattingSettings(), + edits)) { return; } } catch (Exception e) { - LOGGER.log(Level.SEVERE, - "Error while processing format attributes for the participant '" - + formatterParticipant.getClass().getName() + "'.", e); + LOGGER.log(Level.SEVERE, "Error while processing format attributes for the participant '" + + formatterParticipant.getClass().getName() + "'.", e); } } } } - void removeLeftSpaces(int to, List edits) { - replaceLeftSpacesWith(to, "", edits); - } - - public void removeLeftSpaces(int from, int to, List edits) { - replaceLeftSpacesWith(from, to, "", edits); - } - - void replaceLeftSpacesWithOneSpace(int to, List edits) { - replaceLeftSpacesWith(to, " ", edits); - } - - public void replaceLeftSpacesWithOneSpace(int from, int to, List edits) { - replaceLeftSpacesWith(from, to, " ", edits); + public void removeLeftSpaces(int leftLimit, int to, List edits) { + replaceLeftSpacesWith(leftLimit, to, "", edits); } - void replaceLeftSpacesWith(int to, String replacement, List edits) { - replaceLeftSpacesWith(-1, to, replacement, edits); + public void replaceLeftSpacesWithOneSpace(int leftLimit, int to, List edits) { + replaceLeftSpacesWith(leftLimit, to, " ", edits); } void replaceLeftSpacesWith(int leftLimit, int to, String replacement, List edits) { - int from = getLeftWhitespacesOffset(leftLimit, to); - createTextEditIfNeeded(from, to, replacement, edits); + int from = adjustOffsetWithLeftWhitespaces(leftLimit, to); + if (from >= 0) { + createTextEditIfNeeded(from, to, replacement, edits); + } } - void replaceQuoteWithPreferred(int from, int to, String replacement, List edits) { - createTextEditIfNeeded(from, to, replacement, edits); + void replaceQuoteWithPreferred(int from, int to, List edits) { + createTextEditIfNeeded(from, to, getQuotationAsString(), edits); } - public int getLeftWhitespacesOffset(int leftLimit, int to) { - String text = textDocument.getText(); - int from = leftLimit != -1 ? leftLimit : to - 1; - int limit = leftLimit != -1 ? leftLimit : 0; - for (int i = to - 1; i >= limit; i--) { - char c = text.charAt(i); - if (!Character.isWhitespace(c)) { - from = i; - break; - } - } - return from; + public int adjustOffsetWithLeftWhitespaces(int leftLimit, int to) { + return TextEditUtils.adjustOffsetWithLeftWhitespaces(leftLimit, to, textDocument.getText()); } - public int replaceLeftSpacesWithIndentation(int indentLevel, int offset, boolean addLineSeparator, + public int replaceLeftSpacesWithIndentation(int indentLevel, int leftLimit, int to, boolean addLineSeparator, List edits) { - int start = offset - 1; - if (start > 0) { + int from = adjustOffsetWithLeftWhitespaces(leftLimit, to); + if (from >= 0) { String expectedSpaces = getIndentSpaces(indentLevel, addLineSeparator); - createTextEditIfNeeded(start, offset, expectedSpaces, edits); + createTextEditIfNeeded(from, to, expectedSpaces, edits); return expectedSpaces.length(); } return 0; } - public int replaceLeftSpacesWithIndentationWithMultiNewLines(int indentLevel, int offset, + public int replaceLeftSpacesWithIndentationWithMultiNewLines(int indentLevel, int leftLimit, int offset, int newLineCount, List edits) { - int start = getLeftWhitespacesOffset(-1, offset); - if (start > 0) { + int from = adjustOffsetWithLeftWhitespaces(leftLimit, offset); + if (from >= 0) { String expectedSpaces = getIndentSpacesWithMultiNewLines(indentLevel, newLineCount); - createTextEditIfNeeded(start, offset, expectedSpaces, edits); + createTextEditIfNeeded(from, offset, expectedSpaces, edits); return expectedSpaces.length(); } return 0; } - public int replaceLeftSpacesWithIndentationWithOffsetSpaces(int indentSpace, int offset, boolean addLineSeparator, - List edits) { - int start = offset - 1; - if (start > 0) { + public int replaceLeftSpacesWithIndentationWithOffsetSpaces(int indentSpace, int leftLimit, int to, + boolean addLineSeparator, List edits) { + int from = adjustOffsetWithLeftWhitespaces(leftLimit, to); + if (from >= 0) { String expectedSpaces = getIndentSpacesWithOffsetSpaces(indentSpace, addLineSeparator); - createTextEditIfNeeded(start, offset, expectedSpaces, edits); + createTextEditIfNeeded(from, to, expectedSpaces, edits); return expectedSpaces.length(); } return 0; } - boolean hasLineBreak(int startAttr, int start) { + boolean hasLineBreak(int from, int to) { String text = textDocument.getText(); - for (int i = startAttr; i < start; i++) { + for (int i = from; i < to; i++) { char c = text.charAt(i); if (isLineSeparator(c)) { return true; @@ -507,6 +484,17 @@ private static boolean isLineSeparator(char c) { return c == '\r' || c == '\n'; } + public int getLineBreakOffset(int startAttr, int start) { + String text = textDocument.getText(); + for (int i = startAttr; i < start; i++) { + char c = text.charAt(i); + if (isLineSeparator(c)) { + return i; + } + } + return -1; + } + void insertLineBreak(int start, int end, List edits) { createTextEditIfNeeded(start, end, lineDelimiter, edits); } @@ -536,7 +524,7 @@ public FormatElementCategory getFormatElementCategory(DOMElement element, } // Get the category from the settings - FormatElementCategory fromSettings = sharedSettings.getFormattingSettings().getFormatElementCategory(element); + FormatElementCategory fromSettings = getFormattingSettings().getFormatElementCategory(element); if (fromSettings != null) { return fromSettings; } @@ -592,7 +580,7 @@ void createTextEditIfNeeded(int from, int to, String expectedContent, List edits) } int getMaxLineWidth() { - return sharedSettings.getFormattingSettings().getMaxLineWidth(); + return getFormattingSettings().getMaxLineWidth(); } private int getTabSize() { - return sharedSettings.getFormattingSettings().getTabSize(); + return getFormattingSettings().getTabSize(); } private boolean isInsertSpaces() { - return sharedSettings.getFormattingSettings().isInsertSpaces(); + return getFormattingSettings().isInsertSpaces(); } private boolean isTrimFinalNewlines() { - return sharedSettings.getFormattingSettings().isTrimFinalNewlines(); + return getFormattingSettings().isTrimFinalNewlines(); } private boolean isInsertFinalNewline() { - return sharedSettings.getFormattingSettings().isInsertFinalNewline(); + return getFormattingSettings().isInsertFinalNewline(); + } + + private String getQuotationAsString() { + return sharedSettings.getPreferences().getQuotationAsString(); + } + + private XMLFormattingOptions getFormattingSettings() { + return getSharedSettings().getFormattingSettings(); } SharedSettings getSharedSettings() { diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLExternalTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLExternalTest.java index 807e6724e..97aa8d53e 100644 --- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLExternalTest.java +++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLExternalTest.java @@ -152,7 +152,7 @@ public void externalXSDTest() throws InterruptedException, IOException { private TextDocumentItem getXMLTextDocumentItem(String filename, String xmlContents) { String languageId = "xml"; int version = 1; - return new TextDocumentItem(getTempDirPath().toString() + "/" + filename, languageId, version, xmlContents); + return new TextDocumentItem(getTempDirPath().toString().replace('\\', '/') + "/" + filename, languageId, version, xmlContents); } private void clientOpenFile(XMLLanguageServer languageServer, TextDocumentItem textDocumentItem) { diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLSchemaDiagnosticsTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLSchemaDiagnosticsTest.java index f980fc57b..0dbc7ea02 100644 --- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLSchemaDiagnosticsTest.java +++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLSchemaDiagnosticsTest.java @@ -229,12 +229,12 @@ public void cvc_complex_type_2_4_bCodeAction_rootSameLine() throws Exception { "\t\r\n" + // "\t\t\r\n" + // "\t\r\n" + // - "\t\n")), + "\t\r\n")), ca(d, te(1, 79, 1, 79, // "\r\n" + // "\t\r\n" + // "\t\t\r\n" + // - "\t\n"))); + "\t\r\n"))); } @Test @@ -265,12 +265,12 @@ public void cvc_complex_type_2_4_bCodeAction_Only_Required() throws Exception { "\t\r\n" + // "\t\t\r\n" + // "\t\r\n" + // - "\t\n")), + "\t\r\n")), ca(d, te(1, 79, 1, 79, // "\r\n" + // "\t\r\n" + // "\t\t\r\n" + // - "\t\n"))); + "\t\r\n"))); } @Test @@ -287,12 +287,12 @@ public void cvc_complex_type_2_4_bCodeAction_Only_Required_Sequence() throws Exc "\t\r\n" + // "\t\t\r\n" + // "\t\r\n" + // - "\t\n")), + "\t\r\n")), ca(d, te(1, 65, 1, 65, // "\r\n" + // "\t\r\n" + // "\t\r\n" + // - "\t\n"))); + "\t\r\n"))); } @Test @@ -336,7 +336,7 @@ public void cvc_complex_type_2_4_bCodeAction_Complex_Children() throws Exception "\t\t\t\r\n\t\t\r\n" + // "\t\t\t\r\n" + // "\t\t\r\n" + // - "\t\n")), + "\t\r\n")), ca(d, te(1, 82, 1, 82, // "\r\n" + // "\t\r\n" + // @@ -344,7 +344,7 @@ public void cvc_complex_type_2_4_bCodeAction_Complex_Children() throws Exception "\t\t\t\r\n\t\t\r\n" + // "\t\t\t\r\n" + // "\t\t\r\n" + // - "\t\n"))); + "\t\r\n"))); } @Test diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/LeftWhitespacesOffsetTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/LeftWhitespacesOffsetTest.java new file mode 100644 index 000000000..845241518 --- /dev/null +++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/LeftWhitespacesOffsetTest.java @@ -0,0 +1,85 @@ +/******************************************************************************* +* Copyright (c) 2022 Red Hat Inc. and others. +* All rights reserved. This program and the accompanying materials +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v20.html +* +* SPDX-License-Identifier: EPL-2.0 +* +* Contributors: +* Red Hat Inc. - initial API and implementation +*******************************************************************************/ +package org.eclipse.lemminx.services.format; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.eclipse.lemminx.AbstractCacheBasedTest; +import org.junit.jupiter.api.Test; + +/** + * Test for {@link TextEditUtils#adjustOffsetWithLeftWhitespaces(int, int, String)}. + * + * @author Angelo ZERR + * + */ +public class LeftWhitespacesOffsetTest extends AbstractCacheBasedTest { + + @Test + public void spaces() { + assertLeftWhitespacesOffset("", ""); + assertLeftWhitespacesOffset("", ""); + assertLeftWhitespacesOffset("", ""); + assertLeftWhitespacesOffset("|", ""); + } + + @Test + public void lineSeparator() { + assertLeftWhitespacesOffset("", ""); + assertLeftWhitespacesOffset("", ""); + assertLeftWhitespacesOffset("", ""); + assertLeftWhitespacesOffset("|", ""); + } + + @Test + public void nullOffset() { + assertLeftWhitespacesOffset("||", ""); + } + + @Test + public void noSpaces() { + assertLeftWhitespacesOffset("", ""); + } + + @Test + public void getLeftWhitespacesOffsetWithToZero() { + int offset = TextEditUtils.adjustOffsetWithLeftWhitespaces(0, 0, ""); + assertEquals(-1, offset); + offset = TextEditUtils.adjustOffsetWithLeftWhitespaces(1, 0, ""); + assertEquals(-1, offset); + } + + @Test + public void getLeftWhitespacesOffsetWith() { + int offset = TextEditUtils.adjustOffsetWithLeftWhitespaces(0, 0, ""); + assertEquals(-1, offset); + + offset = TextEditUtils.adjustOffsetWithLeftWhitespaces(1, 0, ""); + assertEquals(-1, offset); + } + + private static void assertLeftWhitespacesOffset(String textWithRanges, String expectedWithOffset) { + int leftLimit = textWithRanges.indexOf('|'); + int to = textWithRanges.indexOf('|', leftLimit + 1) - 1; + StringBuilder text = new StringBuilder(); + text.append(textWithRanges.substring(0, leftLimit)); + text.append(textWithRanges.substring(leftLimit + 1, to + 1)); + text.append(textWithRanges.substring(to + 2, textWithRanges.length())); + + int offset = TextEditUtils.adjustOffsetWithLeftWhitespaces(leftLimit, to, text.toString()); + if (offset != -1) { + text.insert(offset, '|'); + } + assertEquals(expectedWithOffset, text.toString()); + } + +} diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/TextEditUtilsTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/TextEditUtilsTest.java index 7d40d5a54..2092c916b 100644 --- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/TextEditUtilsTest.java +++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/TextEditUtilsTest.java @@ -34,13 +34,13 @@ public void textEdit() { TextDocument document = new TextDocument("", "test.xml"); TextEdit edit = TextEditUtils.createTextEditIfNeeded(1, 2, " ", document); assertNotNull(edit); - assertEquals(te(0, 2, 0, 2, " "), edit); + assertEquals(te(0, 1, 0, 2, " "), edit); } @Test public void noTextEdit() { TextDocument document = new TextDocument("", "test.xml"); - TextEdit edit = TextEditUtils.createTextEditIfNeeded(1, 3, " ", document); + TextEdit edit = TextEditUtils.createTextEditIfNeeded(2, 3, " ", document); assertNull(edit); } @@ -49,7 +49,7 @@ public void textEdit2() { TextDocument document = new TextDocument("", "test.xml"); TextEdit edit = TextEditUtils.createTextEditIfNeeded(1, 4, " ", document); assertNotNull(edit); - assertEquals(te(0, 2, 0, 4, " "), edit); + assertEquals(te(0, 1, 0, 4, " "), edit); } @Test diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterEmptyElementsTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterEmptyElementsTest.java index 11965e84c..cfc51a46b 100644 --- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterEmptyElementsTest.java +++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterEmptyElementsTest.java @@ -185,8 +185,7 @@ public void collapseEmptyElementsAndPreserveEmptyContent() throws BadLocationExc " \r\n" + // ""; assertFormat(content, expected, settings, // - te(0, 5, 1, 4, "\r\n "), - te(1, 8, 1, 15, " />")); + te(0, 5, 1, 4, "\r\n "), te(1, 8, 1, 15, " />")); assertFormat(expected, expected, settings); } @@ -208,6 +207,7 @@ public void collapseEmptyElementsInRange() throws BadLocationException { "\r\n" + // ""; assertFormat(content, expected, settings); + // Range covers the b element, collapse is done content = "\r\n" + // "<|b>\r\n" + // diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterExperimentalTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterExperimentalTest.java index fcc53d09b..b15bece34 100644 --- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterExperimentalTest.java +++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterExperimentalTest.java @@ -699,7 +699,6 @@ public void testCommentWithRange() throws BadLocationException { assertFormat(content, expected); } - // ---------- Tests for Text formatting @Disabled @@ -940,11 +939,6 @@ private static void assertFormat(String unformatted, String actual, TextEdit... assertFormat(unformatted, actual, new SharedSettings(), expectedEdits); } - private static void assertFormat(String unformatted, String expected, SharedSettings sharedSettings) - throws BadLocationException { - assertFormat(unformatted, expected, sharedSettings, "test://test.html", (TextEdit[]) null); - } - private static void assertFormat(String unformatted, String expected, SharedSettings sharedSettings, TextEdit... expectedEdits) throws BadLocationException { assertFormat(unformatted, expected, sharedSettings, "test://test.html", expectedEdits); diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterPreserveAttributeLineBreaksTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterPreserveAttributeLineBreaksTest.java index 427b000d6..1f6ce8e4c 100644 --- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterPreserveAttributeLineBreaksTest.java +++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterPreserveAttributeLineBreaksTest.java @@ -160,6 +160,24 @@ public void preserveAttributeLineBreaks5() throws BadLocationException { assertFormat(expected, expected, settings); } + @Test + public void preserveAttributeLineBreaks6() throws BadLocationException { + SharedSettings settings = new SharedSettings(); + settings.getFormattingSettings().setPreserveAttributeLineBreaks(true); + String content = ""; + assertFormat(content, content, settings); + } + + @Test + public void preserveAttributeLineBreaks7() throws BadLocationException { + SharedSettings settings = new SharedSettings(); + settings.getFormattingSettings().setPreserveAttributeLineBreaks(true); + String content = ""; + assertFormat(content, content, settings); + } + @Test public void preserveAttributeLineBreaksMissingValue() throws BadLocationException { SharedSettings settings = new SharedSettings(); @@ -191,10 +209,10 @@ public void preserveAttributeLineBreaksCollapseEmptyElement() throws BadLocation " attr=\"value\" attr=\"value\" />\n" + // ""; assertFormat(content, expected, settings, // - te(0, 3, 1, 0, "\n "), - te(1, 28, 2, 0, "\n "), - te(2, 25, 3, 0, "\n "), - te(3, 25, 4, 4, " />")); + te(0, 3, 1, 0, "\n "), // + te(1, 28, 2, 0, "\n "), // + te(2, 25, 3, 0, "\n "), // + te(3, 25, 4, 4, " />")); assertFormat(expected, expected, settings); } @@ -217,10 +235,10 @@ public void preserveAttributeLineBreaksCollapseEmptyElement2() throws BadLocatio " attr=\"value\" attr=\"value\" />\n" + // ""; assertFormat(content, expected, settings, // - te(0, 3, 1, 0, "\n "), - te(1, 28, 2, 0, "\n "), - te(2, 25, 3, 0, "\n "), - te(3, 25, 5, 4, " />")); + te(0, 3, 1, 0, "\n "), // + te(1, 28, 2, 0, "\n "), // + te(2, 25, 3, 0, "\n "), // + te(3, 25, 5, 4, " />")); assertFormat(expected, expected, settings); } @@ -235,7 +253,7 @@ public void preserveAttributeLineBreaksCollapseEmptyElement3() throws BadLocatio String expected = ""; assertFormat(content, expected, settings, // te(0, 2, 1, 4, " />")); - assertFormat(expected, expected, settings); + assertFormat(expected, expected, settings); } @Test @@ -303,6 +321,76 @@ public void preserveAttributeLineBreaksRangeFormattingWithEndTag3() throws BadLo assertFormat(content, expected, settings); } + @Test + public void preserveAttributeLineBreaksIndentCloseTag() throws BadLocationException { + SharedSettings settings = new SharedSettings(); + settings.getFormattingSettings().setPreserveAttributeLineBreaks(true); + settings.getFormattingSettings().setSpaceBeforeEmptyCloseTag(false); + String content = "\r\n" + // + " \r\n" + // + ""; + String expected = "\r\n" + // + " \r\n" + // + ""; + assertFormat(content, expected, settings, // + te(1, 12, 2, 0, "\r\n ")); + assertFormat(expected, expected, settings); + } + + @Test + public void preserveAttributeLineBreaksIndentCloseTagAndSpaceBeforeEmptyCloseTag() throws BadLocationException { + SharedSettings settings = new SharedSettings(); + settings.getFormattingSettings().setPreserveAttributeLineBreaks(true); + settings.getFormattingSettings().setSpaceBeforeEmptyCloseTag(true); + String content = "\r\n" + // + " \r\n" + // + ""; + String expected = "\r\n" + // + " \r\n" + // + ""; + assertFormat(content, expected, settings, // + te(1, 12, 2, 0, "\r\n ")); + assertFormat(expected, expected, settings); + } + + @Test + public void noPreserveAttributeLineBreaksIndentCloseTag() throws BadLocationException { + SharedSettings settings = new SharedSettings(); + settings.getFormattingSettings().setPreserveAttributeLineBreaks(false); + settings.getFormattingSettings().setSpaceBeforeEmptyCloseTag(false); + String content = "\r\n" + // + " \r\n" + // + ""; + String expected = "\r\n" + // + " \r\n" + // + ""; + assertFormat(content, expected, settings, // + te(1, 12, 2, 0, "")); + assertFormat(expected, expected, settings); + } + + @Test + public void noPreserveAttributeLineBreaksIndentCloseTagAndSpaceBeforeEmptyCloseTag() throws BadLocationException { + SharedSettings settings = new SharedSettings(); + settings.getFormattingSettings().setPreserveAttributeLineBreaks(false); + settings.getFormattingSettings().setSpaceBeforeEmptyCloseTag(true); + String content = "\r\n" + // + " \r\n" + // + ""; + String expected = "\r\n" + // + " \r\n" + // + ""; + assertFormat(content, expected, settings, // + te(1, 12, 2, 0, " ")); + assertFormat(expected, expected, settings); + } + private static void assertFormat(String unformatted, String expected, SharedSettings sharedSettings, TextEdit... expectedEdits) throws BadLocationException { assertFormat(unformatted, expected, sharedSettings, "test://test.html", expectedEdits); diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterQuoteStyleTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterQuoteStyleTest.java index ca32980ce..173d3bc69 100644 --- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterQuoteStyleTest.java +++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterQuoteStyleTest.java @@ -12,6 +12,7 @@ package org.eclipse.lemminx.services.format.experimental; import static java.lang.System.lineSeparator; +import static org.eclipse.lemminx.XMLAssert.te; import org.eclipse.lemminx.XMLAssert; import org.eclipse.lemminx.commons.BadLocationException; @@ -35,7 +36,8 @@ public void testUseDoubleQuotesFromDoubleQuotes() throws BadLocationException { String content = " "; String expected = " "; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 8, 0, 10, "")); assertFormat(expected, expected, settings); } @@ -46,7 +48,8 @@ public void testUseSingleQuotesFromSingleQuotes() throws BadLocationException { settings.getFormattingSettings().setEnforceQuoteStyle(EnforceQuoteStyle.preferred); String content = " "; String expected = " "; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 8, 0, 10, "")); assertFormat(expected, expected, settings); } @@ -58,7 +61,10 @@ public void testUseSingleQuotesFromDoubleQuotes() throws BadLocationException { String content = " "; String expected = " "; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 8, 0, 10, ""), // + te(0, 10, 0, 11, "'"), // + te(0, 18, 0, 19, "'")); assertFormat(expected, expected, settings); } @@ -68,7 +74,10 @@ public void testUseDoubleQuotesFromSingleQuotes() throws BadLocationException { settings.getFormattingSettings().setEnforceQuoteStyle(EnforceQuoteStyle.preferred); String content = " "; String expected = " "; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 8, 0, 10, ""), // + te(0, 10, 0, 11, "\""), // + te(0, 18, 0, 19, "\"")); assertFormat(expected, expected, settings); } @@ -78,7 +87,9 @@ public void testUseDoubleQuotesFromSingleQuotesUnclosedEnd() throws BadLocationE settings.getFormattingSettings().setEnforceQuoteStyle(EnforceQuoteStyle.preferred); String content = " "; String expected = " "; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 8, 0, 10, ""), // + te(0, 10, 0, 11, "\"")); assertFormat(expected, expected, settings); } @@ -88,7 +99,9 @@ public void testUseDoubleQuotesFromSingleQuotesUnclosedStart() throws BadLocatio settings.getFormattingSettings().setEnforceQuoteStyle(EnforceQuoteStyle.preferred); String content = " "; String expected = " "; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 8, 0, 10, " "), // + te(0, 16, 0, 17, "\"")); assertFormat(expected, expected, settings); } @@ -98,7 +111,9 @@ public void testUseDoubleQuotesFromSingleQuotesMisMatchStart() throws BadLocatio settings.getFormattingSettings().setEnforceQuoteStyle(EnforceQuoteStyle.preferred); String content = " "; String expected = " "; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 8, 0, 10, ""), // + te(0, 10, 0, 11, "\"")); assertFormat(expected, expected, settings); } @@ -108,7 +123,8 @@ public void testUseDoubleQuotesFromSingleQuotesMisMatchEnd() throws BadLocationE settings.getFormattingSettings().setEnforceQuoteStyle(EnforceQuoteStyle.preferred); String content = " "; String expected = " "; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 8, 0, 10, "")); assertFormat(expected, expected, settings); } @@ -119,7 +135,8 @@ public void testUseSingleQuotesNoQuotes() throws BadLocationException { settings.getPreferences().setQuoteStyle(QuoteStyle.singleQuotes); String content = " "; String expected = " "; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 7, 0, 8, "")); assertFormat(expected, expected, settings); } @@ -130,7 +147,10 @@ public void testUseSingleQuotesNoQuotesSplit() throws BadLocationException { settings.getFormattingSettings().setSplitAttributes(true); String content = " "; String expected = " "; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 2, 0, 3, lineSeparator() + " "), // + te(0, 7, 0, 8, ""), // + te(0, 9, 0, 10, lineSeparator() + " ")); assertFormat(expected, expected, settings); } @@ -140,7 +160,9 @@ public void testAttValueOnlyStartQuote() throws BadLocationException { settings.getPreferences().setQuoteStyle(QuoteStyle.singleQuotes); String content = " "; String expected = " "; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 7, 0, 8, ""), // + te(0, 9, 0, 10, "")); assertFormat(expected, expected, settings); } @@ -150,7 +172,15 @@ public void testUseDoubleQuotesMultipleAttributes() throws BadLocationException settings.getFormattingSettings().setEnforceQuoteStyle(EnforceQuoteStyle.preferred); String content = " "; String expected = " "; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 9, 0, 11, ""), // + te(0, 21, 0, 23, " "), // + te(0, 29, 0, 30, ""), // + te(0, 40, 0, 43, " "), // + te(0, 49, 0, 50, ""), // + te(0, 50, 0, 51, "\""), // + te(0, 59, 0, 60, "\""), // + te(0, 60, 0, 61, "")); assertFormat(expected, expected, settings); } @@ -161,7 +191,17 @@ public void testUseSingleQuotesMultipleAttributes() throws BadLocationException settings.getFormattingSettings().setEnforceQuoteStyle(EnforceQuoteStyle.preferred); String content = " "; String expected = " "; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 9, 0, 11, ""), // + te(0, 11, 0, 12, "'"), // + te(0, 20, 0, 21, "'"), // + te(0, 21, 0, 23, " "), // + te(0, 29, 0, 30, ""), // + te(0, 30, 0, 31, "'"), // + te(0, 39, 0, 40, "'"), // + te(0, 40, 0, 43, " "), // + te(0, 49, 0, 50, ""), // + te(0, 60, 0, 61, "")); assertFormat(expected, expected, settings); } @@ -174,7 +214,17 @@ public void testUseDoubleQuotesMultipleAttributesSplit() throws BadLocationExcep String content = " \n"; String expected = " "; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 2, 0, 3, "\n "), // + te(0, 9, 0, 11, ""), // + te(0, 21, 0, 23, "\n "), // + te(0, 29, 0, 30, ""), // + te(0, 40, 0, 43, "\n "), // + te(0, 49, 0, 50, ""), // + te(0, 50, 0, 51, "\""), // + te(0, 59, 0, 60, "\""), // + te(0, 60, 0, 61, ""), // + te(0, 67, 1, 0, "")); assertFormat(expected, expected, settings); } @@ -187,7 +237,19 @@ public void testUseSingleQuotesMultipleAttributesSplit() throws BadLocationExcep String content = " \n"; String expected = " "; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 2, 0, 3, "\n "), // + te(0, 9, 0, 11, ""), // + te(0, 11, 0, 12, "'"), // + te(0, 20, 0, 21, "'"), // + te(0, 21, 0, 23, "\n "), // + te(0, 29, 0, 30, ""), // + te(0, 30, 0, 31, "'"), // + te(0, 39, 0, 40, "'"), // + te(0, 40, 0, 43, "\n "), // + te(0, 49, 0, 50, ""), // + te(0, 60, 0, 61, ""), // + te(0, 67, 1, 0, "")); assertFormat(expected, expected, settings); } @@ -198,7 +260,9 @@ public void testUseSingleQuotesLocalDTD() throws BadLocationException { settings.getFormattingSettings().setEnforceQuoteStyle(EnforceQuoteStyle.preferred); String content = ""; String expected = ""; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 22, 0, 23, "'"), // + te(0, 31, 0, 32, "'")); assertFormat(expected, expected, settings); } @@ -246,7 +310,18 @@ public void testUseSingleQuotesLocalDTDWithSubset() throws BadLocationException " \n" + // "]>\n" + // ""; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(1, 18, 1, 19, "'"), // + te(1, 27, 1, 28, "'"), // + te(2, 19, 2, 20, "'"), // + te(2, 40, 2, 41, "'"), // + te(3, 17, 3, 18, "'"), // + te(3, 33, 3, 34, "'"), // + te(5, 26, 5, 27, "'"), // + te(5, 28, 5, 29, "'"), // + te(6, 2, 8, 0, "\n"), // + te(8, 11, 8, 12, "'"), // + te(8, 17, 8, 18, "'")); assertFormat(expected, expected, settings); } @@ -272,7 +347,12 @@ public void testUseSingleQuotesLocalDTDWithSubsetUnclosed() throws BadLocationEx " \n" + // "]>\n" + // ""; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(3, 17, 3, 18, "'"), // + te(3, 33, 3, 34, "'"), // + te(6, 2, 8, 0, "\n"), // + te(8, 11, 8, 12, "'"), // + te(8, 17, 8, 18, "'")); assertFormat(expected, expected, settings); } @@ -291,7 +371,15 @@ public void testUseSingleQuotesDTDFile() throws BadLocationException { "\n" + // "\n" + // ""; - assertFormat(content, expected, settings, "test.dtd"); + assertFormat(content, expected, settings, "test.dtd", // + te(0, 16, 0, 17, "'"), // + te(0, 25, 0, 26, "'"), // + te(1, 17, 1, 18, "'"), // + te(1, 38, 1, 39, "'"), // + te(2, 15, 2, 16, "'"), // + te(2, 31, 2, 32, "'"), // + te(4, 24, 4, 25, "'"), // + te(4, 26, 4, 27, "'")); assertFormat(expected, expected, settings); } @@ -323,7 +411,15 @@ public void testAttributeNameTouchingPreviousValue() throws BadLocationException " tt='aa'\r\n" + // " aa>\r\n" + // ""; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(1, 4, 1, 5, "\r\n "), // + te(1, 8, 1, 9, "\r\n "), // + te(1, 11, 1, 12, ""), // + te(1, 13, 1, 14, ""), // + te(1, 14, 1, 15, "'"), // + te(1, 17, 1, 18, "'"), // + te(1, 18, 1, 18, "\r\n "), // + te(1, 20, 1, 21, "")); assertFormat(expected, expected, settings); } @@ -335,7 +431,12 @@ public void enforceSingleQuoteStyle() throws BadLocationException { String content = ""; String expected = ""; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 2, 0, 4, " "), // + te(0, 8, 0, 11, ""), // + te(0, 12, 0, 17, ""), // + te(0, 17, 0, 18, "'"), // + te(0, 23, 0, 24, "'")); assertFormat(expected, expected, settings); } @@ -347,7 +448,12 @@ public void enforceDoubleQuoteStyle() throws BadLocationException { String content = ""; String expected = ""; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 2, 0, 4, " "), // + te(0, 8, 0, 11, ""), // + te(0, 12, 0, 17, ""), // + te(0, 17, 0, 18, "\""), // + te(0, 23, 0, 24, "\"")); assertFormat(expected, expected, settings); } @@ -359,7 +465,11 @@ public void enforceSingleQuoteStyleProlog() throws BadLocationException { String content = ""; String expected = ""; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 14, 0, 15, "'"), // + te(0, 18, 0, 19, "'"), // + te(0, 29, 0, 30, "'"), // + te(0, 35, 0, 36, "'")); assertFormat(expected, expected, settings); } @@ -371,7 +481,11 @@ public void enforceDoubleQuoteStyleProlog() throws BadLocationException { String content = ""; String expected = ""; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 14, 0, 15, "\""), // + te(0, 18, 0, 19, "\""), // + te(0, 29, 0, 30, "\""), // + te(0, 35, 0, 36, "\"")); assertFormat(expected, expected, settings); } @@ -383,7 +497,10 @@ public void enforceDoubleQuoteStyleProlo() throws BadLocationException { String content = ""; String expected = ""; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 18, 0, 19, "\""), // + te(0, 29, 0, 30, "\""), // + te(0, 30, 0, 30, " ")); assertFormat(expected, expected, settings); } @@ -395,7 +512,11 @@ public void dontEnforceSingleQuoteStyle() throws BadLocationException { String content = ""; String expected = ""; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 7, 0, 9, ""), // + te(0, 10, 0, 13, ""), // + te(0, 22, 0, 25, ""), // + te(0, 26, 0, 31, "")); assertFormat(expected, expected, settings); } @@ -431,18 +552,22 @@ public void dontEnforceDoubleQuoteStyle() throws BadLocationException { String content = ""; String expected = ""; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 7, 0, 9, ""), // + te(0, 10, 0, 13, ""), // + te(0, 22, 0, 25, ""), // + te(0, 26, 0, 31, "")); assertFormat(expected, expected, settings); } - private static void assertFormat(String unformatted, String expected, SharedSettings sharedSettings) - throws BadLocationException { - assertFormat(unformatted, expected, sharedSettings, "test://test.html"); + private static void assertFormat(String unformatted, String expected, SharedSettings sharedSettings, + TextEdit... expectedEdits) throws BadLocationException { + assertFormat(unformatted, expected, sharedSettings, "test://test.html", expectedEdits); } - private static void assertFormat(String unformatted, String expected, SharedSettings sharedSettings, String uri) - throws BadLocationException { - assertFormat(unformatted, expected, sharedSettings, uri, true, (TextEdit[]) null); + private static void assertFormat(String unformatted, String expected, SharedSettings sharedSettings, String uri, + TextEdit... expectedEdits) throws BadLocationException { + assertFormat(unformatted, expected, sharedSettings, uri, true, expectedEdits); } private static void assertFormat(String unformatted, String expected, SharedSettings sharedSettings, String uri, diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterSetSpaceBeforeEmptyCloseTagTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterSetSpaceBeforeEmptyCloseTagTest.java index b9c0d3391..7613fe0a9 100644 --- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterSetSpaceBeforeEmptyCloseTagTest.java +++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterSetSpaceBeforeEmptyCloseTagTest.java @@ -162,11 +162,6 @@ public void testEndTagMissingCloseBracket() throws BadLocationException { assertFormat(expected, expected, settings); } - private static void assertFormat(String unformatted, String actual, TextEdit... expectedEdits) - throws BadLocationException { - assertFormat(unformatted, actual, new SharedSettings(), expectedEdits); - } - private static void assertFormat(String unformatted, String expected, SharedSettings sharedSettings, TextEdit... expectedEdits) throws BadLocationException { assertFormat(unformatted, expected, sharedSettings, "test://test.html", expectedEdits); diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterWhitespaceSettingTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterWhitespaceSettingTest.java index 54206287a..2b6773b8f 100644 --- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterWhitespaceSettingTest.java +++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterWhitespaceSettingTest.java @@ -139,7 +139,6 @@ public void testDontTrimFinalNewLines() throws BadLocationException { assertFormat(expected, expected, settings); } - @Disabled @Test public void testDontTrimFinalNewLines2() throws BadLocationException { SharedSettings settings = new SharedSettings(); @@ -148,10 +147,11 @@ public void testDontTrimFinalNewLines2() throws BadLocationException { " \r\n\r\n"; String expected = "\r\n" + // " \r\n\r\n"; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 2, 0, 4, "")); + assertFormat(expected, expected, settings); } - @Disabled @Test public void testDontTrimFinalNewLines3() throws BadLocationException { SharedSettings settings = new SharedSettings(); @@ -164,7 +164,9 @@ public void testDontTrimFinalNewLines3() throws BadLocationException { " text \r\n" + // " more text \r\n" + // " \r\n"; - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(0, 2, 0, 4, "")); + assertFormat(expected, expected, settings); } @Test @@ -234,8 +236,7 @@ public void testClosingBracketNewLineWithSingleAttribute() throws BadLocationExc settings.getFormattingSettings().setClosingBracketNewLine(true); String content = ""; String expected = ""; - assertFormat(content, expected, settings, - te(0, 7, 0, 7, " ")); + assertFormat(content, expected, settings, te(0, 7, 0, 7, " ")); assertFormat(expected, expected, settings); } @@ -249,9 +250,9 @@ public void testClosingBracketNewLineWithChildElementIndent() throws BadLocation String expected = "" + lineSeparator() + " " + lineSeparator() + ""; assertFormat(content, expected, settings, // - te(1, 4, 1, 5, lineSeparator() + " "), // - te(1, 9, 1, 10, lineSeparator() + " "), // - te(1, 14, 1, 14, lineSeparator() + " ")); + te(1, 4, 1, 5, lineSeparator() + " "), // + te(1, 9, 1, 10, lineSeparator() + " "), // + te(1, 14, 1, 14, lineSeparator() + " ")); assertFormat(expected, expected, settings); } @@ -287,11 +288,6 @@ public void testClosingBracketNewLineWithPreserveEmptyContentSingleAttribute() t assertFormat(expected, expected, settings); } - private static void assertFormat(String unformatted, String actual, TextEdit... expectedEdits) - throws BadLocationException { - assertFormat(unformatted, actual, new SharedSettings(), expectedEdits); - } - private static void assertFormat(String unformatted, String expected, SharedSettings sharedSettings, TextEdit... expectedEdits) throws BadLocationException { assertFormat(unformatted, expected, sharedSettings, "test://test.html", expectedEdits); diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterWithRangeTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterWithRangeTest.java index 6d88e1f3e..d478f7768 100644 --- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterWithRangeTest.java +++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/format/experimental/XMLFormatterWithRangeTest.java @@ -39,7 +39,7 @@ public void range() throws BadLocationException { te(1, 11, 1, 12, ""), // te(1, 13, 1, 14, ""), // te(1, 19, 1, 19, " ")); - + content = "
\n" + // " ||\n" + // "
"; @@ -61,7 +61,7 @@ public void range2() throws BadLocationException { te(1, 11, 1, 12, ""), // te(1, 13, 1, 14, ""), // te(1, 19, 1, 19, " ")); - + content = "
\n" + // " ||\n" + // " \n" + // @@ -287,8 +287,7 @@ public void rangeSelectEntityWithIndent() throws BadLocationException { "]>"; assertFormat(content, expected); } - - @Disabled + @Test public void testSplitAttributesRangeOneLine() throws BadLocationException { String content = "\r\n" + // @@ -305,10 +304,11 @@ public void testSplitAttributesRangeOneLine() throws BadLocationException { SharedSettings settings = new SharedSettings(); settings.getFormattingSettings().setSplitAttributes(true); - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(2, 9, 2, 14, ""), // + te(2, 15, 2, 26, "")); } - @Disabled @Test public void testSplitAttributesRangeMultipleLines() throws BadLocationException { String content = "\r\n" + // @@ -326,14 +326,21 @@ public void testSplitAttributesRangeMultipleLines() throws BadLocationException " abc=\"def\"\r\n" + // " ghi=\"jkl\">sss\r\n" + // ""; - ; SharedSettings settings = new SharedSettings(); settings.getFormattingSettings().setSplitAttributes(true); - assertFormat(content, expected, settings); + assertFormat(content, expected, settings, // + te(1, 7, 2, 8, "\r\n "), // + te(2, 11, 2, 18, ""), // + te(2, 19, 2, 26, ""), // + te(2, 31, 3, 0, "\r\n "), // + te(3, 3, 3, 5, ""), // + te(3, 6, 3, 10, ""), // + te(3, 15, 3, 18, "\r\n "), // + te(3, 21, 3, 23, ""), // + te(3, 24, 4, 4, "")); } - private static void assertFormat(String unformatted, String actual, TextEdit... expectedEdits) throws BadLocationException { assertFormat(unformatted, actual, new SharedSettings(), expectedEdits);