From dc61aef9eea1567f6e4e71faa1b7424d663a6cb9 Mon Sep 17 00:00:00 2001 From: Nicolay Mitropolsky Date: Fri, 7 May 2021 15:53:18 +0300 Subject: [PATCH] Yaml: `YamlScalarTextEvaluator` extracted to implement old `getTextValue` behavior GitOrigin-RevId: 0dfa545f3b9d3c8a46452a7dd3a657e618d3b1f6 --- .../jetbrains/yaml/psi/YAMLBlockScalar.java | 5 - .../yaml/psi/impl/YAMLBlockScalarImpl.java | 228 ------------------ .../yaml/psi/impl/YAMLBlockScalarImpl.kt | 151 ++++++++++++ .../impl/YAMLBlockScalarTextEvaluator.java | 147 +++++++++++ .../yaml/psi/impl/YAMLPlainTextImpl.java | 94 ++++---- .../yaml/psi/impl/YAMLQuotedTextImpl.java | 16 +- .../psi/impl/YAMLQuotedTextTextEvaluator.java | 80 ++++++ .../yaml/psi/impl/YAMLScalarImpl.java | 38 +-- .../yaml/psi/impl/YAMLScalarListImpl.java | 103 +++----- .../yaml/psi/impl/YAMLScalarTextImpl.java | 102 ++++---- .../psi/impl/YamlScalarTextEvaluator.java | 49 ++++ .../psi/YAMLScalarLiteralEscaperTest.java | 25 +- .../yaml/psi/data/doubleQuote1.positions.txt | 16 +- .../yaml/psi/data/doubleQuote2.positions.txt | 10 +- .../psi/data/doubleQuoteTag.positions.txt | 6 +- .../yaml/psi/data/foldedStyle1.positions.txt | 7 +- .../yaml/psi/data/foldedStyle2.positions.txt | 15 +- .../yaml/psi/data/foldedStyle3.positions.txt | 12 +- .../yaml/psi/data/foldedStyle4.positions.txt | 48 ++-- .../psi/data/foldedStyle4Tag.positions.txt | 48 ++-- .../foldedStyleCommentInHeader.positions.txt | 8 +- .../psi/data/foldedStyleKeep.positions.txt | 18 +- .../psi/data/foldedStyleStrip.positions.txt | 7 +- .../yaml/psi/data/literalStyle1.positions.txt | 8 +- .../yaml/psi/data/literalStyle2.positions.txt | 11 +- .../yaml/psi/data/literalStyle3.positions.txt | 25 +- .../literalStyleCommentInHeader.positions.txt | 8 +- .../psi/data/literalStyleKeep.positions.txt | 19 +- .../psi/data/literalStyleStrip.positions.txt | 8 +- .../yaml/psi/data/plainScalar1.positions.txt | 6 +- .../yaml/psi/data/plainScalar2.positions.txt | 25 +- .../yaml/psi/data/plainScalar3.positions.txt | 20 +- .../psi/data/plainScalar3Tag.positions.txt | 20 +- ...ainScalarBigFirstLineIndent1.positions.txt | 6 +- ...ainScalarBigFirstLineIndent2.positions.txt | 6 +- .../yaml/psi/data/singleQuote2.positions.txt | 10 +- .../YAMLScalarConversionTest.java | 4 +- 37 files changed, 727 insertions(+), 682 deletions(-) delete mode 100644 plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLBlockScalarImpl.java create mode 100644 plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLBlockScalarImpl.kt create mode 100644 plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLBlockScalarTextEvaluator.java create mode 100644 plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLQuotedTextTextEvaluator.java create mode 100644 plugins/yaml/src/org/jetbrains/yaml/psi/impl/YamlScalarTextEvaluator.java diff --git a/plugins/yaml/src/org/jetbrains/yaml/psi/YAMLBlockScalar.java b/plugins/yaml/src/org/jetbrains/yaml/psi/YAMLBlockScalar.java index 845ac4f810ae3..50683622b7b31 100644 --- a/plugins/yaml/src/org/jetbrains/yaml/psi/YAMLBlockScalar.java +++ b/plugins/yaml/src/org/jetbrains/yaml/psi/YAMLBlockScalar.java @@ -6,9 +6,4 @@ /** See 8.1. Block Scalar Styles */ public interface YAMLBlockScalar extends YAMLScalar { - /** It is temporary solution. Please Do not use it in production! */ - @ApiStatus.Internal - Key FORCE_KEEP_CHOMPING = new Key<>("Force keep chomping indicator"); - - boolean hasExplicitIndent(); } diff --git a/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLBlockScalarImpl.java b/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLBlockScalarImpl.java deleted file mode 100644 index b08d37b917ec9..0000000000000 --- a/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLBlockScalarImpl.java +++ /dev/null @@ -1,228 +0,0 @@ -package org.jetbrains.yaml.psi.impl; - -import com.intellij.codeInsight.intention.impl.QuickEditHandler; -import com.intellij.lang.ASTNode; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.TextRange; -import com.intellij.psi.impl.source.tree.TreeUtil; -import com.intellij.psi.tree.IElementType; -import com.intellij.util.SmartList; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.UtilKt; -import kotlin.collections.CollectionsKt; -import one.util.streamex.StreamEx; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.yaml.YAMLElementTypes; -import org.jetbrains.yaml.YAMLTokenTypes; -import org.jetbrains.yaml.YAMLUtil; -import org.jetbrains.yaml.psi.YAMLBlockScalar; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Set; - -public abstract class YAMLBlockScalarImpl extends YAMLScalarImpl implements YAMLBlockScalar { - protected static final int DEFAULT_CONTENT_INDENT = 2; - private static final int IMPLICIT_INDENT = -1; - - public YAMLBlockScalarImpl(@NotNull ASTNode node) { - super(node); - } - - @NotNull - protected abstract IElementType getContentType(); - - @Override - public boolean isMultiline() { - return true; - } - - protected boolean shouldIncludeEolInRange(ASTNode child) { - if (isEol(child) && child.getTreeNext() == null && getChompingIndicator() == ChompingIndicator.KEEP) { - return true; - } - return false; - } - - protected boolean isEnding(@Nullable TextRange rangeInHost) { - if (rangeInHost == null) return true; - TextRange lastItem = ContainerUtil.getLastItem(getContentRanges()); - if (lastItem == null) return false; - return rangeInHost.getEndOffset() == lastItem.getEndOffset(); - } - - @NotNull - @Override - public List getContentRanges() { - int myStart = getTextRange().getStartOffset(); - int indent = locateIndent(); - - List contentRanges = StreamEx.of(getLinesNodes()).map((line) -> { - var first = line.get(0); - return TextRange.create(first.getTextRange().getStartOffset() - myStart - + ((first.getElementType() == YAMLTokenTypes.INDENT) ? indent : 0), - ContainerUtil.getLastItem(line).getTextRange().getEndOffset() - myStart); - }).toList(); - - if (contentRanges.size() == 1) { - return List.of(TextRange.create(contentRanges.get(0).getEndOffset(), contentRanges.get(0).getEndOffset())); - } - else if (contentRanges.isEmpty()) { - return List.of(); - } - else { - return UtilKt.tailOrEmpty(contentRanges); - } - } - - protected int getFragmentEndOfLines(Set fragmentEditors) { - if (fragmentEditors.isEmpty()) return -1; - QuickEditHandler fe = ContainerUtil.getFirstItem(fragmentEditors); - - CharSequence cs = fe.getFragmentDocument().getImmutableCharSequence(); - int i = 0; - for (; i < cs.length(); i++) { - if (cs.charAt(cs.length() - i - 1) != '\n') break; - } - return i; - } - - - @Override - public boolean hasExplicitIndent() { - return getExplicitIndent() != IMPLICIT_INDENT; - } - - /** - * @return Nth child of this scalar block item type ({@link YAMLElementTypes#BLOCK_SCALAR_ITEMS}). - * Child with number 0 is a header. Content children have numbers more than 0. - */ - @Nullable - public ASTNode getNthContentTypeChild(int nth) { - int number = 0; - for (ASTNode child = getNode().getFirstChildNode(); child != null; child = child.getTreeNext()) { - if (child.getElementType() == getContentType()) { - if (number == nth) { - return child; - } - number++; - } - } - return null; - } - - /** See 8.1.1.1. Block Indentation Indicator*/ - public final int locateIndent() { - int indent = getExplicitIndent(); - if (indent != IMPLICIT_INDENT) { - return indent; - } - - ASTNode firstLine = getNthContentTypeChild(1); - if (firstLine != null) { - return YAMLUtil.getIndentInThisLine(firstLine.getPsi()); - } - else { - List line = CollectionsKt.getOrNull(getLinesNodes(), 1); - if (line != null) { - ASTNode lineIndentElement = ContainerUtil.find(line, l -> l.getElementType().equals(YAMLTokenTypes.INDENT)); - if (lineIndentElement != null) { - return lineIndentElement.getTextLength(); - } - } - } - return 0; - } - - protected @NotNull List> getLinesNodes() { - List> result = new SmartList<>(); - List currentLine = new SmartList<>(); - for (ASTNode child = getNode().getFirstChildNode(); child != null; child = child.getTreeNext()) { - currentLine.add(child); - if (isEol(child)) { - result.add(currentLine); - currentLine = new SmartList<>(); - } - } - if (!currentLine.isEmpty()) { - result.add(currentLine); - } - return result; - } - - /** - * See 8.1.1.2. Block Chomping Indicator - */ - @NotNull - protected final ChompingIndicator getChompingIndicator() { - Boolean forceKeepChomping = getContainingFile().getOriginalFile().getUserData(FORCE_KEEP_CHOMPING); - if (forceKeepChomping != null && forceKeepChomping) { - return ChompingIndicator.KEEP; - } - ASTNode headerNode = getNthContentTypeChild(0); - assert headerNode != null; - - String header = headerNode.getText(); - - if (header.contains("+")) { - return ChompingIndicator.KEEP; - } - if (header.contains("-")) { - return ChompingIndicator.STRIP; - } - - return ChompingIndicator.CLIP; - } - - private int getExplicitIndent() { - ASTNode headerNode = getNthContentTypeChild(0); - assert headerNode != null; - - String header = headerNode.getText(); - - for (int i = 0; i < header.length(); i++) { - if (Character.isDigit(header.charAt(i))) { - int k = i + 1; - // YAML 1.2 standard does not allow more then 1 symbol in indentation number - if (k < header.length() && Character.isDigit(header.charAt(k))) { - return IMPLICIT_INDENT; - } - int res = Integer.parseInt(header.substring(i, k)); - if (res == 0) { - // zero is not allowed as c-indentation-indicator - return IMPLICIT_INDENT; - } - return res; - } - } - return IMPLICIT_INDENT; - } - - @Contract("null -> false") - public static boolean isEol(@Nullable ASTNode node) { - if (node == null) { - return false; - } - return YAMLElementTypes.EOL_ELEMENTS.contains(node.getElementType()); - } - - @Contract("null -> true") - public static boolean isEolOrNull(@Nullable ASTNode node) { - if (node == null) { - return true; - } - return YAMLElementTypes.EOL_ELEMENTS.contains(node.getElementType()); - } - - /** - * See 8.1.1.2. Block Chomping Indicator - */ - protected enum ChompingIndicator { - CLIP, - STRIP, - KEEP - } -} diff --git a/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLBlockScalarImpl.kt b/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLBlockScalarImpl.kt new file mode 100644 index 0000000000000..93258adc2f935 --- /dev/null +++ b/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLBlockScalarImpl.kt @@ -0,0 +1,151 @@ +package org.jetbrains.yaml.psi.impl + +import com.intellij.lang.ASTNode +import com.intellij.openapi.util.Pair +import com.intellij.openapi.util.TextRange +import com.intellij.openapi.util.text.StringUtil +import com.intellij.psi.tree.IElementType +import com.intellij.psi.util.CachedValueProvider +import com.intellij.psi.util.CachedValuesManager +import com.intellij.psi.util.PsiModificationTracker +import com.intellij.util.SmartList +import com.intellij.util.containers.ContainerUtil +import com.intellij.util.containers.tailOrEmpty +import com.intellij.util.text.splitLineRanges +import org.jetbrains.yaml.YAMLElementTypes +import org.jetbrains.yaml.YAMLTokenTypes +import org.jetbrains.yaml.YAMLUtil +import org.jetbrains.yaml.psi.YAMLBlockScalar + +abstract class YAMLBlockScalarImpl(node: ASTNode) : YAMLScalarImpl(node), YAMLBlockScalar { + protected abstract val contentType: IElementType + + override fun isMultiline(): Boolean = true + + override fun getContentRanges(): List { + + return CachedValuesManager.getCachedValue(this, CachedValueProvider { + val myStart = textRange.startOffset + val indent = locateIndent() + + val contentRanges = linesNodes.mapNotNull { line -> + val first = line.first() + TextRange.create(first.textRange.startOffset - myStart + + (if (first.elementType == YAMLTokenTypes.INDENT) indent else 0), + line.last().textRange.endOffset - myStart) + } + + CachedValueProvider.Result.create((if (contentRanges.size == 1) + listOf(contentRanges.single().let { TextRange.create(it.endOffset, it.endOffset) }) + else if (contentRanges.isEmpty()) + emptyList() + else + contentRanges.tailOrEmpty()), PsiModificationTracker.MODIFICATION_COUNT) + }) + } + + fun hasExplicitIndent(): Boolean = explicitIndent != IMPLICIT_INDENT + + /** + * @return Nth child of this scalar block item type ([YAMLElementTypes.BLOCK_SCALAR_ITEMS]). + * Child with number 0 is a header. Content children have numbers more than 0. + */ + fun getNthContentTypeChild(nth: Int): ASTNode? { + var number = 0 + var child = node.firstChildNode + while (child != null) { + if (child.elementType === contentType) { + if (number == nth) { + return child + } + number++ + } + child = child.treeNext + } + return null + } + + /** See [8.1.1.1. Block Indentation Indicator](http://www.yaml.org/spec/1.2/spec.html#id2793979) */ + fun locateIndent(): Int { + val indent = explicitIndent + if (indent != IMPLICIT_INDENT) { + return indent + } + val firstLine = getNthContentTypeChild(1) + if (firstLine != null) { + return YAMLUtil.getIndentInThisLine(firstLine.psi) + } + else { + val line = linesNodes.getOrNull(1) + if (line != null) { + val lineIndentElement = ContainerUtil.find(line) { l: ASTNode -> l.elementType == YAMLTokenTypes.INDENT } + if (lineIndentElement != null) { + return lineIndentElement.textLength + } + } + } + return 0 + } + + @Throws(IllegalArgumentException::class) + override fun getEncodeReplacements(input: CharSequence): List> { + var indent = locateIndent() + if (indent == 0) { + indent = YAMLUtil.getIndentToThisElement(this) + DEFAULT_CONTENT_INDENT + } + val indentString = StringUtil.repeatSymbol(' ', indent) + + return splitLineRanges(input).zipWithNext { a, b -> Pair.create(TextRange.create(a.endOffset, b.startOffset), indentString) }.toList() + } + + protected val linesNodes: List> + get() { + val result: MutableList> = SmartList() + var currentLine: MutableList = SmartList() + var child = node.firstChildNode + while (child != null) { + currentLine.add(child) + if (isEol(child)) { + result.add(currentLine) + currentLine = SmartList() + } + child = child.treeNext + } + if (!currentLine.isEmpty()) { + result.add(currentLine) + } + return result + } + + // YAML 1.2 standard does not allow more then 1 symbol in indentation number + private val explicitIndent: Int + get() { + val headerNode = getNthContentTypeChild(0)!! + val header = headerNode.text + for (i in 0 until header.length) { + if (Character.isDigit(header[i])) { + val k = i + 1 + // YAML 1.2 standard does not allow more then 1 symbol in indentation number + if (k < header.length && Character.isDigit(header[k])) { + return IMPLICIT_INDENT + } + val res = header.substring(i, k).toInt() + return if (res == 0) { + // zero is not allowed as c-indentation-indicator + IMPLICIT_INDENT + } + else res + } + } + return IMPLICIT_INDENT + } + +} + +const val DEFAULT_CONTENT_INDENT = 2 +private const val IMPLICIT_INDENT = -1 + +fun isEol(node: ASTNode?): Boolean = when (node) { + null -> false + else -> YAMLElementTypes.EOL_ELEMENTS.contains(node.elementType) +} diff --git a/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLBlockScalarTextEvaluator.java b/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLBlockScalarTextEvaluator.java new file mode 100644 index 0000000000000..7644dff10457f --- /dev/null +++ b/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLBlockScalarTextEvaluator.java @@ -0,0 +1,147 @@ +package org.jetbrains.yaml.psi.impl; + +import com.intellij.lang.ASTNode; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.impl.source.tree.TreeUtil; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.yaml.YAMLElementTypes; +import org.jetbrains.yaml.YAMLTokenTypes; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static org.jetbrains.yaml.psi.impl.YAMLBlockScalarImplKt.isEol; + +public abstract class YAMLBlockScalarTextEvaluator extends YamlScalarTextEvaluator { + + public YAMLBlockScalarTextEvaluator(@NotNull T host) { + super(host); + } + + protected boolean shouldIncludeEolInRange(ASTNode child) { + if (isEol(child) && child.getTreeNext() == null && getChompingIndicator() == ChompingIndicator.KEEP) { + return true; + } + return false; + } + + protected boolean isEnding(@Nullable TextRange rangeInHost) { + if (rangeInHost == null) return true; + TextRange lastItem = ContainerUtil.getLastItem(getContentRanges()); + if (lastItem == null) return false; + return rangeInHost.getEndOffset() == lastItem.getEndOffset(); + } + + @NotNull + @Override + public List getContentRanges() { + final ASTNode firstContentChild = myHost.getFirstContentNode(); + if (firstContentChild == null) { + return Collections.emptyList(); + } + + final int myStart = myHost.getTextRange().getStartOffset(); + final List result = new ArrayList<>(); + + final int indent = myHost.locateIndent(); + + final ASTNode firstEol = TreeUtil.findSibling(firstContentChild, YAMLElementTypes.EOL_ELEMENTS); + if (firstEol == null) { + return Collections.emptyList(); + } + + int thisLineStart = firstEol.getStartOffset() + 1; + for (ASTNode child = firstEol.getTreeNext(); child != null; child = child.getTreeNext()) { + final IElementType childType = child.getElementType(); + final TextRange childRange = child.getTextRange(); + + if (childType == YAMLTokenTypes.INDENT && isEol(child.getTreePrev())) { + thisLineStart = child.getStartOffset() + Math.min(indent, child.getTextLength()); + } + else if (childType == YAMLTokenTypes.SCALAR_EOL) { + if (thisLineStart != -1) { + int endOffset = shouldIncludeEolInRange(child) ? child.getTextRange().getEndOffset() : child.getStartOffset(); + result.add(TextRange.create(thisLineStart, endOffset).shiftRight(-myStart)); + } + thisLineStart = child.getStartOffset() + 1; + } + else { + if (isEol(child.getTreeNext())) { + if (thisLineStart == -1) { + Logger.getInstance(YAMLBlockScalarTextEvaluator.class).warn("thisLineStart == -1: '" + myHost.getText() + "'", new Throwable()); + continue; + } + int endOffset = shouldIncludeEolInRange(child) ? child.getTreeNext().getTextRange().getEndOffset() : childRange.getEndOffset(); + result.add(TextRange.create(thisLineStart, endOffset).shiftRight(-myStart)); + thisLineStart = -1; + } + } + } + if (thisLineStart != -1) { + result.add(TextRange.create(thisLineStart, myHost.getTextRange().getEndOffset()).shiftRight(-myStart)); + } + + ChompingIndicator chomping = getChompingIndicator(); + + if (chomping == ChompingIndicator.KEEP) { + return result; + } + + final int lastNonEmpty = ContainerUtil.lastIndexOf(result, range -> range.getLength() != 0); + + return lastNonEmpty == -1 ? Collections.emptyList() : result.subList(0, lastNonEmpty + 1); + } + + /** + * See 8.1.1.2. Block Chomping Indicator + */ + @NotNull + protected final ChompingIndicator getChompingIndicator() { + Boolean forceKeepChomping = myHost.getContainingFile().getOriginalFile().getUserData(FORCE_KEEP_CHOMPING); + if (forceKeepChomping != null && forceKeepChomping) { + return ChompingIndicator.KEEP; + } + ASTNode headerNode = myHost.getNthContentTypeChild(0); + assert headerNode != null; + + String header = headerNode.getText(); + + if (header.contains("+")) { + return ChompingIndicator.KEEP; + } + if (header.contains("-")) { + return ChompingIndicator.STRIP; + } + + return ChompingIndicator.CLIP; + } + + @Contract("null -> true") + public static boolean isEolOrNull(@Nullable ASTNode node) { + if (node == null) { + return true; + } + return YAMLElementTypes.EOL_ELEMENTS.contains(node.getElementType()); + } + + /** + * See 8.1.1.2. Block Chomping Indicator + */ + protected enum ChompingIndicator { + CLIP, + STRIP, + KEEP + } + + /** It is temporary solution. Please Do not use it in production! */ + @ApiStatus.Internal + public static final Key FORCE_KEEP_CHOMPING = new Key<>("Force keep chomping indicator"); +} diff --git a/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLPlainTextImpl.java b/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLPlainTextImpl.java index e461a2d5b0ab9..4f47f3f805274 100644 --- a/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLPlainTextImpl.java +++ b/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLPlainTextImpl.java @@ -24,65 +24,77 @@ public List getContentRanges() { final int myStart = getTextRange().getStartOffset(); final List result = new ArrayList<>(); - boolean seenText = false; + TextRange textRange = null; for (ASTNode child = getFirstContentNode(); child != null; child = child.getTreeNext()) { + TextRange childRange = child.getTextRange().shiftRight(-myStart); if (child.getElementType() == YAMLTokenTypes.TEXT) { - seenText = true; - result.add(child.getTextRange().shiftRight(-myStart)); + if (textRange != null) result.add(textRange); + textRange = childRange; } else if (child.getElementType() == YAMLTokenTypes.EOL) { - if (!seenText) { - result.add(child.getTextRange().shiftRight(-myStart)); + if (textRange == null) { + result.add(childRange); + } + else { + result.add(textRange.union(childRange)); + textRange = null; } - seenText = false; } } + if (textRange != null) result.add(textRange); return result; } - @NotNull @Override - protected String getRangesJoiner(@NotNull CharSequence text, @NotNull List contentRanges, int indexBefore) { - if (isNewline(text, contentRanges.get(indexBefore)) || isNewline(text, contentRanges.get(indexBefore + 1))) { - return ""; - } - else { - return " "; - } - } - - private static boolean isNewline(@NotNull CharSequence text, @NotNull TextRange range) { - return range.getLength() == 1 && text.charAt(range.getStartOffset()) == '\n'; - } - - @Override - protected List> getEncodeReplacements(@NotNull CharSequence input) throws IllegalArgumentException { - checkForConsistency(input); - - final int indent = YAMLUtil.getIndentToThisElement(this); - final String indentString = StringUtil.repeatSymbol(' ', indent); + public @NotNull YamlScalarTextEvaluator getTextEvaluator() { + return new YamlScalarTextEvaluator<>(this) { + + @NotNull + @Override + public List getContentRanges() { + final int myStart = getTextRange().getStartOffset(); + final List result = new ArrayList<>(); + + boolean seenText = false; + for (ASTNode child = getFirstContentNode(); child != null; child = child.getTreeNext()) { + if (child.getElementType() == YAMLTokenTypes.TEXT) { + seenText = true; + result.add(child.getTextRange().shiftRight(-myStart)); + } + else if (child.getElementType() == YAMLTokenTypes.EOL) { + if (!seenText) { + result.add(child.getTextRange().shiftRight(-myStart)); + } + seenText = false; + } + } - final List> result = new ArrayList<>(); - int currentLength = 0; - for (int i = 0; i < input.length(); ++i) { - if (input.charAt(i) == '\n') { - result.add(Pair.create(TextRange.from(i, 1), "\n\n" + indentString)); - currentLength = 0; - continue; + return result; } - if (currentLength > MAX_SCALAR_LENGTH_PREDEFINED && - input.charAt(i) == ' ' && isSurroundedByNoSpace(input, i)) { - result.add(Pair.create(TextRange.from(i, 1), "\n" + indentString)); - currentLength = 0; - continue; + @NotNull + @Override + protected String getRangesJoiner(@NotNull CharSequence text, @NotNull List contentRanges, int indexBefore) { + if (isNewline(text, contentRanges.get(indexBefore)) || isNewline(text, contentRanges.get(indexBefore + 1))) { + return ""; + } + else { + return " "; + } } - currentLength++; - } + private boolean isNewline(@NotNull CharSequence text, @NotNull TextRange range) { + return range.getLength() == 1 && text.charAt(range.getStartOffset()) == '\n'; + } + }; + } - return result; + @Override + protected List> getEncodeReplacements(@NotNull CharSequence input) throws IllegalArgumentException { + // doesn't replace anything, just checks that input is supported + checkForConsistency(input); + return super.getDecodeReplacements(input); } private static void checkForConsistency(@NotNull CharSequence input) throws IllegalArgumentException { diff --git a/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLQuotedTextImpl.java b/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLQuotedTextImpl.java index cdb351f89c2fa..d041cc0a11363 100644 --- a/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLQuotedTextImpl.java +++ b/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLQuotedTextImpl.java @@ -75,19 +75,9 @@ public List getContentRanges() { return result; } - @NotNull @Override - protected String getRangesJoiner(@NotNull CharSequence text, @NotNull List contentRanges, int indexBefore) { - final TextRange leftRange = contentRanges.get(indexBefore); - if (leftRange.isEmpty() || !isSingleQuote() && text.charAt(leftRange.getEndOffset() - 1) == '\\') { - return "\n"; - } - else if (contentRanges.get(indexBefore + 1).isEmpty()) { - return ""; - } - else { - return " "; - } + public @NotNull YamlScalarTextEvaluator getTextEvaluator() { + return new YAMLQuotedTextTextEvaluator(this); } @SuppressWarnings("AssignmentToForLoopParameter") @@ -143,7 +133,7 @@ else if (!isSingleQuote() && i + 1 < input.length() && input.charAt(i + 1) == '\ result.add(Pair.create(TextRange.from(i, 1), "\\\n" + indentString + "\\n")); } else { - result.add(Pair.create(TextRange.from(i, 1), "\n\n" + indentString)); + result.add(Pair.create(TextRange.from(i, 1), "\n" + indentString)); } currentLength = 0; continue; diff --git a/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLQuotedTextTextEvaluator.java b/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLQuotedTextTextEvaluator.java new file mode 100644 index 0000000000000..00c223ed92b74 --- /dev/null +++ b/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLQuotedTextTextEvaluator.java @@ -0,0 +1,80 @@ +// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package org.jetbrains.yaml.psi.impl; + +import com.intellij.lang.ASTNode; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.yaml.lexer.YAMLGrammarCharUtil; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +class YAMLQuotedTextTextEvaluator extends YamlScalarTextEvaluator { + + YAMLQuotedTextTextEvaluator(YAMLQuotedTextImpl text) { + super(text); + } + + @NotNull + @Override + public List getContentRanges() { + final ASTNode firstContentNode = myHost.getFirstContentNode(); + if (firstContentNode == null) { + return Collections.emptyList(); + } + + List result = new ArrayList<>(); + TextRange contentRange = TextRange.create(firstContentNode.getStartOffset(), myHost.getTextRange().getEndOffset()) + .shiftRight(-myHost.getTextRange().getStartOffset()); + + final List lines = StringUtil.split(contentRange.substring(myHost.getText()), "\n", true, false); + // First line has opening quote + int cumulativeOffset = contentRange.getStartOffset(); + for (int i = 0; i < lines.size(); ++i) { + final String line = lines.get(i); + + int lineStart = 0; + int lineEnd = line.length(); + if (i == 0) { + lineStart++; + } + else { + while (lineStart < line.length() && YAMLGrammarCharUtil.isSpaceLike(line.charAt(lineStart))) { + lineStart++; + } + } + if (i == lines.size() - 1) { + // Last line has closing quote + lineEnd--; + } + else { + while (lineEnd > lineStart && YAMLGrammarCharUtil.isSpaceLike(line.charAt(lineEnd - 1))) { + lineEnd--; + } + } + + result.add(TextRange.create(lineStart, lineEnd).shiftRight(cumulativeOffset)); + cumulativeOffset += line.length() + 1; + } + + return result; + } + + @NotNull + @Override + protected String getRangesJoiner(@NotNull CharSequence text, @NotNull List contentRanges, int indexBefore) { + final TextRange leftRange = contentRanges.get(indexBefore); + if (leftRange.isEmpty() || !myHost.isSingleQuote() && text.charAt(leftRange.getEndOffset() - 1) == '\\') { + return "\n"; + } + else if (contentRanges.get(indexBefore + 1).isEmpty()) { + return ""; + } + else { + return " "; + } + } + +} diff --git a/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLScalarImpl.java b/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLScalarImpl.java index 925671da84465..a6769e0e9d5d4 100644 --- a/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLScalarImpl.java +++ b/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLScalarImpl.java @@ -26,46 +26,28 @@ public YAMLScalarImpl(@NotNull ASTNode node) { @NotNull public abstract List getContentRanges(); - - @NotNull - protected abstract String getRangesJoiner(@NotNull CharSequence text, @NotNull List contentRanges, int indexBefore); + + public abstract @NotNull YamlScalarTextEvaluator getTextEvaluator(); protected List> getDecodeReplacements(@NotNull CharSequence input) { return Collections.emptyList(); } protected List> getEncodeReplacements(@NotNull CharSequence input) throws IllegalArgumentException { - throw new IllegalArgumentException("Not implemented"); + return Collections.emptyList(); } @NotNull @Override public final String getTextValue() { - return getTextValue(null); + return getTextEvaluator().getTextValue(null); } @NotNull - public String getTextValue(@Nullable TextRange rangeInHost) { - final String text = getText(); - final List contentRanges = getContentRanges(); - - final StringBuilder builder = new StringBuilder(); - - for (int i = 0; i < contentRanges.size(); i++) { - final TextRange range = rangeInHost != null ? rangeInHost.intersection(contentRanges.get(i)) : contentRanges.get(i); - if (range == null) continue; - - final CharSequence curString = range.subSequence(text); - builder.append(curString); - - if (range.getEndOffset() == contentRanges.get(i).getEndOffset() && i + 1 != contentRanges.size()) { - builder.append(getRangesJoiner(text, contentRanges, i)); - } - } - return processReplacements(builder, getDecodeReplacements(builder)); + public final String getTextValue(@Nullable TextRange rangeInHost) { + return getTextEvaluator().getTextValue(rangeInHost); } - @Override public PsiReference getReference() { final PsiReference[] references = getReferences(); @@ -134,7 +116,8 @@ public boolean decode(@NotNull TextRange rangeInsideHost, @NotNull StringBuilder for (TextRange range : ranges) { TextRange intersection = range.intersection(rangeInsideHost); if (intersection == null) continue; - outChars.append(intersection.substring(text)); + String substring = intersection.substring(text); + outChars.append(processReplacements(substring, myHost.getDecodeReplacements(substring))); } return true; } @@ -154,11 +137,6 @@ public int getOffsetInHost(int offsetInDecoded, @NotNull TextRange rangeInsideHo String curString = range.subSequence(text).toString(); - if (range.getEndOffset() == contentRanges.get(i).getEndOffset() && i + 1 != contentRanges.size()) { - final String joiner = myHost.getRangesJoiner(text, contentRanges, i); - curString += joiner; - } - final List> replacementsForThisLine = myHost.getDecodeReplacements(curString); int encodedOffsetInCurrentLine = 0; for (Pair replacement : replacementsForThisLine) { diff --git a/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLScalarListImpl.java b/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLScalarListImpl.java index 1cd7084818aee..de38a8f7fac27 100644 --- a/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLScalarListImpl.java +++ b/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLScalarListImpl.java @@ -1,8 +1,6 @@ package org.jetbrains.yaml.psi.impl; -import com.intellij.codeInsight.intention.impl.QuickEditHandler; import com.intellij.lang.ASTNode; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElementVisitor; @@ -11,18 +9,16 @@ import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; import com.intellij.util.ObjectUtils; -import one.util.streamex.StreamEx; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.yaml.YAMLElementTypes; import org.jetbrains.yaml.YAMLTokenTypes; -import org.jetbrains.yaml.YAMLUtil; import org.jetbrains.yaml.psi.YAMLScalarList; import org.jetbrains.yaml.psi.YamlPsiElementVisitor; -import java.util.ArrayList; import java.util.List; -import java.util.Objects; + +import static org.jetbrains.yaml.psi.impl.YAMLBlockScalarImplKt.isEol; /** * @author oleg @@ -39,70 +35,51 @@ protected IElementType getContentType() { return YAMLTokenTypes.SCALAR_LIST; } - @NotNull - @Override - protected String getRangesJoiner(@NotNull CharSequence text, @NotNull List contentRanges, int indexBefore) { - return ""; - } - - @NotNull @Override - public String getTextValue(@Nullable TextRange rangeInHost) { - String value = super.getTextValue(rangeInHost); - if (!StringUtil.isEmptyOrSpaces(value) && getChompingIndicator() == ChompingIndicator.KEEP && isEnding(rangeInHost)) { - value += "\n"; - } - return value; - } - - @Override - protected boolean shouldIncludeEolInRange(ASTNode child) { - if (getChompingIndicator() == ChompingIndicator.KEEP) return true; - - int feen = getFragmentEndOfLines(QuickEditHandler.getFragmentEditors(this)); - - long endingEndls = StreamEx.iterate(child.getTreeNext(), it -> it.getTreeNext()) - .takeWhile(Objects::nonNull) - .takeWhile(it -> isEolOrNull(it)).count(); - - if (feen == -1 && - isEol(child) && - isEolOrNull(child.getTreeNext()) && - !(YAMLTokenTypes.INDENT.equals(ObjectUtils.doIfNotNull(child.getTreePrev(), ASTNode::getElementType)) && - getLinesNodes().size() <= 2)) { - return false; - } - if (feen != -1 && endingEndls < feen) return true; + public @NotNull YamlScalarTextEvaluator getTextEvaluator() { + return new YAMLBlockScalarTextEvaluator<>(this) { - ASTNode next = TreeUtil.findSibling(child.getTreeNext(), NON_SPACE_VALUES); - if (isEol(next) && - isEolOrNull(TreeUtil.findSibling(next.getTreeNext(), NON_SPACE_VALUES)) && - getChompingIndicator() == ChompingIndicator.STRIP) { - return false; - } - - return true; - } - - private static final TokenSet NON_SPACE_VALUES = TokenSet.orSet(YAMLElementTypes.SCALAR_VALUES, YAMLElementTypes.EOL_ELEMENTS); + @NotNull + @Override + protected String getRangesJoiner(@NotNull CharSequence text, @NotNull List contentRanges, int indexBefore) { + return ""; + } - @Override - protected List> getEncodeReplacements(@NotNull CharSequence input) throws IllegalArgumentException { - int indent = locateIndent(); - if (indent == 0) { - indent = YAMLUtil.getIndentToThisElement(this) + DEFAULT_CONTENT_INDENT; - } - final String indentString = StringUtil.repeatSymbol(' ', indent); + @NotNull + @Override + public String getTextValue(@Nullable TextRange rangeInHost) { + String value = super.getTextValue(rangeInHost); + if (!StringUtil.isEmptyOrSpaces(value) && getChompingIndicator() == ChompingIndicator.KEEP && isEnding(rangeInHost)) { + value += "\n"; + } + return value; + } - final List> result = new ArrayList<>(); - for (int i = 0; i < input.length(); ++i) { - if (input.charAt(i) == '\n') { - result.add(Pair.create(TextRange.from(i, 1), "\n" + indentString)); + @Override + protected boolean shouldIncludeEolInRange(ASTNode child) { + if (getChompingIndicator() == ChompingIndicator.KEEP) return true; + + if (isEol(child) && + isEolOrNull(child.getTreeNext()) && + !(YAMLTokenTypes.INDENT.equals(ObjectUtils.doIfNotNull(child.getTreePrev(), ASTNode::getElementType)) && + myHost.getLinesNodes().size() <= 2)) { + return false; + } + + ASTNode next = TreeUtil.findSibling(child.getTreeNext(), NON_SPACE_VALUES); + if (isEol(next) && + isEolOrNull(TreeUtil.findSibling(next.getTreeNext(), NON_SPACE_VALUES)) && + getChompingIndicator() == ChompingIndicator.STRIP) { + return false; + } + + return true; } - } - return result; + private final TokenSet NON_SPACE_VALUES = TokenSet.orSet(YAMLElementTypes.SCALAR_VALUES, YAMLElementTypes.EOL_ELEMENTS); + }; } + @Override public PsiLanguageInjectionHost updateText(@NotNull String text) { diff --git a/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLScalarTextImpl.java b/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLScalarTextImpl.java index 72ccb585e95d9..2a68df0500ee6 100644 --- a/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLScalarTextImpl.java +++ b/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YAMLScalarTextImpl.java @@ -7,7 +7,6 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElementVisitor; import com.intellij.psi.tree.IElementType; -import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.yaml.YAMLTokenTypes; @@ -19,6 +18,7 @@ import java.util.ArrayList; import java.util.List; + public class YAMLScalarTextImpl extends YAMLBlockScalarImpl implements YAMLScalarText { public YAMLScalarTextImpl(@NotNull final ASTNode node) { super(node); @@ -30,56 +30,64 @@ protected IElementType getContentType() { return YAMLTokenTypes.SCALAR_TEXT; } - @NotNull @Override - protected String getRangesJoiner(@NotNull CharSequence text, @NotNull List contentRanges, int indexBefore) { - final TextRange leftRange = contentRanges.get(indexBefore); - final TextRange rightRange = contentRanges.get(indexBefore + 1); - if (leftRange.isEmpty()) { - if (rightRange.getLength() == 1 && text.charAt(rightRange.getStartOffset()) == '\n' && getChompingIndicator() != ChompingIndicator.KEEP) - return ""; - return "\n"; - } - if (startsWithWhitespace(text, leftRange) || startsWithWhitespace(text, rightRange)) { - return "\n"; - } - if (rightRange.isEmpty()) { - int i = indexBefore + 2; - // Unfortunately we need to scan to the nearest non-empty line to understand - // whether we should add a line here - while (i < contentRanges.size() && contentRanges.get(i).isEmpty()) { - i++; - } - if (i >= contentRanges.size()) { - // empty lines until the end - if (getChompingIndicator() == ChompingIndicator.KEEP) { + public @NotNull YamlScalarTextEvaluator getTextEvaluator() { + return new YAMLBlockScalarTextEvaluator<>(this) { + + @NotNull + @Override + protected String getRangesJoiner(@NotNull CharSequence text, @NotNull List contentRanges, int indexBefore) { + final TextRange leftRange = contentRanges.get(indexBefore); + final TextRange rightRange = contentRanges.get(indexBefore + 1); + if (leftRange.isEmpty()) { + if (rightRange.getLength() == 1 && + text.charAt(rightRange.getStartOffset()) == '\n' && + getChompingIndicator() != ChompingIndicator.KEEP) + return ""; return "\n"; } + if (startsWithWhitespace(text, leftRange) || startsWithWhitespace(text, rightRange)) { + return "\n"; + } + if (rightRange.isEmpty()) { + int i = indexBefore + 2; + // Unfortunately we need to scan to the nearest non-empty line to understand + // whether we should add a line here + while (i < contentRanges.size() && contentRanges.get(i).isEmpty()) { + i++; + } + if (i >= contentRanges.size()) { + // empty lines until the end + if (getChompingIndicator() == ChompingIndicator.KEEP) { + return "\n"; + } + } + else if (startsWithWhitespace(text, contentRanges.get(i))) { + return "\n"; + } + return ""; + } + return " "; } - else if (startsWithWhitespace(text, contentRanges.get(i))) { - return "\n"; - } - return ""; - } - return " "; - } - @NotNull - @Override - public String getTextValue(@Nullable TextRange rangeInHost) { - String value = super.getTextValue(rangeInHost); - if (!StringUtil.isEmptyOrSpaces(value) && getChompingIndicator() != ChompingIndicator.STRIP && isEnding(rangeInHost)) { - value += "\n"; - } - return value; - } + @NotNull + @Override + public String getTextValue(@Nullable TextRange rangeInHost) { + String value = super.getTextValue(rangeInHost); + if (!StringUtil.isEmptyOrSpaces(value) && getChompingIndicator() != ChompingIndicator.STRIP && isEnding(rangeInHost)) { + value += "\n"; + } + return value; + } - private static boolean startsWithWhitespace(@NotNull CharSequence text, @NotNull TextRange range) { - if (range.isEmpty()) { - return false; - } - final char c = text.charAt(range.getStartOffset()); - return c == ' ' || c == '\t'; + private boolean startsWithWhitespace(@NotNull CharSequence text, @NotNull TextRange range) { + if (range.isEmpty()) { + return false; + } + final char c = text.charAt(range.getStartOffset()); + return c == ' ' || c == '\t'; + } + }; } @Override @@ -90,7 +98,7 @@ protected List> getEncodeReplacements(@NotNull CharSeque int indent = locateIndent(); if (indent == 0) { - indent = YAMLUtil.getIndentToThisElement(this) + DEFAULT_CONTENT_INDENT; + indent = YAMLUtil.getIndentToThisElement(this) + YAMLBlockScalarImplKt.DEFAULT_CONTENT_INDENT; } final String indentString = StringUtil.repeatSymbol(' ', indent); @@ -108,7 +116,7 @@ protected List> getEncodeReplacements(@NotNull CharSeque replacement = "\n" + indentString; } else { - replacement = "\n\n" + indentString; + replacement = "\n" + indentString; } result.add(Pair.create(TextRange.from(i, 1), replacement)); diff --git a/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YamlScalarTextEvaluator.java b/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YamlScalarTextEvaluator.java new file mode 100644 index 0000000000000..0793264f8a8fc --- /dev/null +++ b/plugins/yaml/src/org/jetbrains/yaml/psi/impl/YamlScalarTextEvaluator.java @@ -0,0 +1,49 @@ +package org.jetbrains.yaml.psi.impl; + +import com.intellij.openapi.util.TextRange; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +import static org.jetbrains.yaml.psi.impl.YAMLScalarImpl.processReplacements; + +/** + * Yaml text value evaluator according to the YAML Literal values specification https://yaml.org/spec/1.2/spec.html#Block + */ +public abstract class YamlScalarTextEvaluator { + + protected final @NotNull T myHost; + + public YamlScalarTextEvaluator(@NotNull T host) { + myHost = host; + } + + @NotNull + public abstract List getContentRanges(); + + @NotNull + protected abstract String getRangesJoiner(@NotNull CharSequence text, @NotNull List contentRanges, int indexBefore); + + @NotNull + public String getTextValue(@Nullable TextRange rangeInHost) { + final String text = myHost.getText(); + final List contentRanges = getContentRanges(); + + final StringBuilder builder = new StringBuilder(); + + for (int i = 0; i < contentRanges.size(); i++) { + final TextRange range = rangeInHost != null ? rangeInHost.intersection(contentRanges.get(i)) : contentRanges.get(i); + if (range == null) continue; + + final CharSequence curString = range.subSequence(text); + builder.append(curString); + + if (range.getEndOffset() == contentRanges.get(i).getEndOffset() && i + 1 != contentRanges.size()) { + builder.append(getRangesJoiner(text, contentRanges, i)); + } + } + return processReplacements(builder, myHost.getDecodeReplacements(builder)); + } + +} \ No newline at end of file diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/YAMLScalarLiteralEscaperTest.java b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/YAMLScalarLiteralEscaperTest.java index ad1cc2b8a3405..55916c4367726 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/YAMLScalarLiteralEscaperTest.java +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/YAMLScalarLiteralEscaperTest.java @@ -1,12 +1,18 @@ // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package org.jetbrains.yaml.psi; +import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.application.ex.PathManagerEx; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.ThrowableComputable; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.ElementManipulators; import com.intellij.psi.LiteralTextEscaper; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiLanguageInjectionHost; +import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.testFramework.fixtures.BasePlatformTestCase; import org.jetbrains.yaml.YAMLParserDefinition; @@ -152,7 +158,6 @@ private void doTest() { final StringBuilder builder = new StringBuilder(); assertTrue(elementLiteralEscaper.decode(ElementManipulators.getValueTextRange(scalarElement), builder)); - assertEquals(scalarElement.getTextValue(), builder.toString()); int[] offsets = new int[builder.length() + 1]; for (int i = 0; i < builder.length() + 1; ++i) { @@ -162,13 +167,27 @@ private void doTest() { final String elementText = scalarElement.getText(); StringBuilder description = new StringBuilder(); for (int i = 0; i < builder.length(); ++i) { - description.append(builder.charAt(i)) + description.append(StringUtil.escapeLineBreak(Character.toString(builder.charAt(i)))) .append("->") - .append(elementText.subSequence(offsets[i], offsets[i + 1])) + .append(StringUtil.escapeLineBreak(elementText.subSequence(offsets[i], offsets[i + 1]).toString())) .append('\n'); } assertSameLinesWithFile(getTestDataPath() + getTestName(true) + ".positions.txt", Arrays.toString(offsets) + "\n" + description, false); + + String decodedText = builder.toString(); + YAMLScalar scalar = WriteCommandAction.runWriteCommandAction( + getProject(), + (Computable)() -> CodeStyleManager.getInstance(getProject()) + .performActionWithFormatterDisabled(() -> + ElementManipulators.handleContentChange(scalarElement, decodedText)) + ); + //assertEquals("element text should be the same after re-decoding", elementText, scalar.getText()); + final StringBuilder decodedOnceAgain = new StringBuilder(); + assertTrue(scalar.createLiteralTextEscaper().decode(ElementManipulators.getValueTextRange(scalar), decodedOnceAgain)); + assertEquals("should decode to the same content after content change with previously decoded content", + decodedText, + decodedOnceAgain.toString()); } } diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/doubleQuote1.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/doubleQuote1.positions.txt index 41c81955046df..b3b293506468a 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/doubleQuote1.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/doubleQuote1.positions.txt @@ -1,4 +1,4 @@ -[1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61] +[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61] f->f o->o l->l @@ -6,7 +6,7 @@ d->d e->e d->d -> - +\n->\n t->t o->o -> @@ -17,11 +17,10 @@ p->p a->a c->c e->e -,->, - - --> - +,->, + -> +\n->\n +\n->\n t->t o->o -> @@ -42,8 +41,7 @@ o->o r->r -> -> - ->\ - \ + ->\\n \ -> n->n o->o diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/doubleQuote2.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/doubleQuote2.positions.txt index 8ab0719e4ffb3..b2c198a37c16d 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/doubleQuote2.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/doubleQuote2.positions.txt @@ -1,4 +1,4 @@ -[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48] +[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48] -> 1->1 s->s @@ -13,10 +13,8 @@ m->m p->p t->t y->y - - --> - +\n->\n +\n->\n 2->2 n->n d->d @@ -31,7 +29,7 @@ p->p t->t y->y -> - +\n->\n 3->3 r->r d->d diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/doubleQuoteTag.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/doubleQuoteTag.positions.txt index 7e482f3b63410..fa15e1e64b3ab 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/doubleQuoteTag.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/doubleQuoteTag.positions.txt @@ -1,8 +1,6 @@ [6, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] - -->\n - -->\n +\n->\n +\n->\n '->' '->' c->c diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyle1.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyle1.positions.txt index 681b27e05ecfb..0aa4bd3555a4e 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyle1.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyle1.positions.txt @@ -1,11 +1,8 @@ -[3, 4, 5, 6, 8, 9, 10, 11, 11] +[3, 4, 5, 6, 8, 9, 10, 11] f->f o->o o->o - -> - +\n->\n b->b a->a r->r - --> diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyle2.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyle2.positions.txt index 8b574943caa2c..466102e39121e 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyle2.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyle2.positions.txt @@ -1,16 +1,11 @@ -[2, 4, 5, 6, 8, 10, 11, 12, 13, 13] - --> - +[2, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14] +\n->\n f->f o->o o->o - - --> - +\n->\n +\n->\n b->b a->a r->r - --> +\n->\n diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyle3.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyle3.positions.txt index d5f61189860e6..c6fbd90123f44 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyle3.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyle3.positions.txt @@ -1,19 +1,13 @@ -[4, 5, 6, 7, 10, 11, 12, 13, 14, 17, 18, 19, 20, 20] +[4, 5, 6, 7, 10, 11, 12, 13, 14, 17, 18, 19, 20] f->f o->o o->o - --> - +\n->\n -> b->b a->a r->r - --> - +\n->\n b->b a->a z->z - --> diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyle4.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyle4.positions.txt index 67392d8ba2386..0984f0c8fe260 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyle4.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyle4.positions.txt @@ -1,36 +1,28 @@ -[2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 17, 19, 20, 21, 22, 23, 25, 26, 27, 28, 29, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 50, 51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 65, 66, 67, 68, 69, 71, 72, 73, 74, 75, 75] - --> - +[2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 25, 26, 27, 28, 29, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 50, 51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 65, 66, 67, 68, 69, 71, 72, 73, 74, 75, 76] +\n->\n f->f o->o l->l d->d e->e d->d - -> - +\n->\n l->l i->i n->n e->e - - --> - +\n->\n +\n->\n n->n e->e x->x t->t - -> - +\n->\n l->l i->i n->n e->e - --> - +\n->\n -> -> *->* @@ -41,12 +33,8 @@ l->l l->l e->e t->t - --> - - --> - +\n->\n +\n->\n -> -> *->* @@ -55,9 +43,7 @@ l->l i->i s->s t->t - --> - +\n->\n -> -> *->* @@ -66,21 +52,15 @@ l->l i->i n->n e->e - --> - - --> - +\n->\n +\n->\n l->l a->a s->s t->t - -> - +\n->\n l->l i->i n->n e->e - --> +\n->\n diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyle4Tag.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyle4Tag.positions.txt index 91cf1f06bd876..7aa3b2f46996a 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyle4Tag.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyle4Tag.positions.txt @@ -1,36 +1,28 @@ -[7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 22, 24, 25, 26, 27, 28, 30, 31, 32, 33, 34, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 49, 50, 51, 52, 53, 54, 55, 56, 57, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 70, 71, 72, 73, 74, 76, 77, 78, 79, 80, 80] - --> - +[7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 30, 31, 32, 33, 34, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 49, 50, 51, 52, 53, 54, 55, 56, 57, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 70, 71, 72, 73, 74, 76, 77, 78, 79, 80, 81] +\n->\n f->f o->o l->l d->d e->e d->d - -> - +\n->\n l->l i->i n->n e->e - - --> - +\n->\n +\n->\n n->n e->e x->x t->t - -> - +\n->\n l->l i->i n->n e->e - --> - +\n->\n -> -> *->* @@ -41,12 +33,8 @@ l->l l->l e->e t->t - --> - - --> - +\n->\n +\n->\n -> -> *->* @@ -55,9 +43,7 @@ l->l i->i s->s t->t - --> - +\n->\n -> -> *->* @@ -66,21 +52,15 @@ l->l i->i n->n e->e - --> - - --> - +\n->\n +\n->\n l->l a->a s->s t->t - -> - +\n->\n l->l i->i n->n e->e - --> +\n->\n diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyleCommentInHeader.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyleCommentInHeader.positions.txt index f38a917171a8c..452b5e83a9471 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyleCommentInHeader.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyleCommentInHeader.positions.txt @@ -1,15 +1,13 @@ -[21, 22, 23, 24, 25, 26, 30, 31, 32, 33, 34, 35, 35] +[21, 22, 23, 24, 25, 26, 30, 31, 32, 33, 34, 35, 36] h->h e->e l->l l->l o->o - -> - +\n->\n w->w o->o r->r l->l d->d - --> +\n->\n diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyleKeep.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyleKeep.positions.txt index 6d25f739e10fd..710ed7636822d 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyleKeep.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyleKeep.positions.txt @@ -1,24 +1,14 @@ -[5, 6, 7, 8, 9, 10, 13, 14, 15, 16, 17, 19, 21, 22, 22, 22] +[5, 6, 7, 8, 9, 10, 13, 14, 15, 16, 17, 18, 19, 22] h->h e->e l->l l->l o->o - -> - +\n->\n w->w o->o r->r l->l d->d - - --> - - --> - - --> - --> +\n->\n +\n->\n \n diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyleStrip.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyleStrip.positions.txt index db9344f2e421f..710ed7636822d 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyleStrip.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/foldedStyleStrip.positions.txt @@ -1,13 +1,14 @@ -[5, 6, 7, 8, 9, 10, 13, 14, 15, 16, 17, 18] +[5, 6, 7, 8, 9, 10, 13, 14, 15, 16, 17, 18, 19, 22] h->h e->e l->l l->l o->o - -> - +\n->\n w->w o->o r->r l->l d->d +\n->\n +\n->\n \n diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyle1.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyle1.positions.txt index 91dc86fda4ff1..bfd8820f3708f 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyle1.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyle1.positions.txt @@ -6,13 +6,9 @@ e->e r->r a->a l->l - --> - +\n->\n t->t e->e x->x t->t - --> - +\n->\n diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyle2.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyle2.positions.txt index 6a32c66b8039e..54f9fac5ad4ad 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyle2.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyle2.positions.txt @@ -1,4 +1,4 @@ -[3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18] +[3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19] l->l i->i t->t @@ -6,14 +6,11 @@ e->e r->r a->a l->l - --> - +\n->\n -> t->t e->e x->x t->t - --> - +\n->\n +\n->\n diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyle3.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyle3.positions.txt index eb415b79cab98..95856e87de1cc 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyle3.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyle3.positions.txt @@ -1,10 +1,5 @@ -[3, 6, 9, 10, 11, 12, 13, 14, 15, 16, 19, 20, 23, 26, 27, 28, 29, 30, 31] - --> - - --> - +[6, 9, 10, 11, 12, 13, 14, 15, 16, 19, 20, 23, 26, 27, 28, 29, 30, 31] +\n->\n l->l i->i t->t @@ -12,20 +7,12 @@ e->e r->r a->a l->l - --> - +\n->\n -> - --> - - --> - +\n->\n +\n->\n t->t e->e x->x t->t - --> - +\n->\n diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyleCommentInHeader.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyleCommentInHeader.positions.txt index 57610ec3f736a..1b93248dbe08d 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyleCommentInHeader.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyleCommentInHeader.positions.txt @@ -4,15 +4,11 @@ e->e l->l l->l o->o - --> - +\n->\n -> w->w o->o r->r l->l d->d - --> - +\n->\n diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyleKeep.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyleKeep.positions.txt index eeb56c997ca07..710ed7636822d 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyleKeep.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyleKeep.positions.txt @@ -1,25 +1,14 @@ -[5, 6, 7, 8, 9, 10, 13, 14, 15, 16, 17, 18, 19, 21, 22, 22] +[5, 6, 7, 8, 9, 10, 13, 14, 15, 16, 17, 18, 19, 22] h->h e->e l->l l->l o->o - --> - +\n->\n w->w o->o r->r l->l d->d - --> - - --> - - --> - - --> +\n->\n +\n->\n \n diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyleStrip.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyleStrip.positions.txt index fe325bfdbaaf0..710ed7636822d 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyleStrip.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/literalStyleStrip.positions.txt @@ -1,14 +1,14 @@ -[5, 6, 7, 8, 9, 10, 13, 14, 15, 16, 17, 18] +[5, 6, 7, 8, 9, 10, 13, 14, 15, 16, 17, 18, 19, 22] h->h e->e l->l l->l o->o - --> - +\n->\n w->w o->o r->r l->l d->d +\n->\n +\n->\n \n diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalar1.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalar1.positions.txt index bb366ccfdef4c..6b908f2a5140b 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalar1.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalar1.positions.txt @@ -2,13 +2,11 @@ f->f o->o o->o - -> - +\n->\n b->b a->a r->r - -> - +\n->\n b->b a->a z->z diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalar2.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalar2.positions.txt index 36b082e81633c..caed132deffac 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalar2.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalar2.positions.txt @@ -1,29 +1,20 @@ -[0, 1, 2, 3, 6, 7, 8, 10, 11, 12, 13, 14, 16, 17, 20, 21, 22, 23, 24] +[0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, 22, 23, 24] f->f o->o o->o - -> - +\n->\n b->b a->a r->r - - --> - - --> - +\n->\n +\n->\n +\n->\n b->b a->a z->z - - --> - - --> - +\n->\n +\n->\n +\n->\n f->f o->o f->f diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalar3.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalar3.positions.txt index 413e778e0dac8..896269c43e53f 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalar3.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalar3.positions.txt @@ -1,28 +1,22 @@ -[0, 1, 2, 3, 8, 9, 10, 11, 14, 15, 16, 18, 21, 22, 23, 25, 28, 29, 30, 31, 32, 33] +[0, 1, 2, 3, 8, 9, 10, 11, 14, 15, 16, 17, 18, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33] f->f o->o o->o - -> - +\n->\n b->b a->a r->r - -> - +\n->\n f->f a->a r->r - - --> - +\n->\n +\n->\n b->b a->a z->z - - --> - +\n->\n +\n->\n b->b a->a a->a diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalar3Tag.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalar3Tag.positions.txt index eae97a24cb185..557bc9dc07c56 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalar3Tag.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalar3Tag.positions.txt @@ -1,28 +1,22 @@ -[5, 6, 7, 8, 13, 14, 15, 16, 19, 20, 21, 23, 26, 27, 28, 30, 33, 34, 35, 36, 37, 38] +[5, 6, 7, 8, 13, 14, 15, 16, 19, 20, 21, 22, 23, 26, 27, 28, 29, 30, 33, 34, 35, 36, 37, 38] f->f o->o o->o - -> - +\n->\n b->b a->a r->r - -> - +\n->\n f->f a->a r->r - - --> - +\n->\n +\n->\n b->b a->a z->z - - --> - +\n->\n +\n->\n b->b a->a a->a diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalarBigFirstLineIndent1.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalarBigFirstLineIndent1.positions.txt index 64f9763af521c..917ad5e5dd3ce 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalarBigFirstLineIndent1.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalarBigFirstLineIndent1.positions.txt @@ -25,8 +25,7 @@ g->g o->o n->n e->e - -> - +\n->\n s->s e->e c->c @@ -71,8 +70,7 @@ t->t o->o n->n e->e - -> - +\n->\n t->t h->h i->i diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalarBigFirstLineIndent2.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalarBigFirstLineIndent2.positions.txt index 64f9763af521c..917ad5e5dd3ce 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalarBigFirstLineIndent2.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/plainScalarBigFirstLineIndent2.positions.txt @@ -25,8 +25,7 @@ g->g o->o n->n e->e - -> - +\n->\n s->s e->e c->c @@ -71,8 +70,7 @@ t->t o->o n->n e->e - -> - +\n->\n t->t h->h i->i diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/singleQuote2.positions.txt b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/singleQuote2.positions.txt index d97b4bd8f9e2f..538602e3ee4f8 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/singleQuote2.positions.txt +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/psi/data/singleQuote2.positions.txt @@ -1,4 +1,4 @@ -[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49] +[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49] -> 1->1 s->s @@ -13,10 +13,8 @@ m->m p->p t->t y->y - - --> - +\n->\n +\n->\n 2->2 n->n d->d @@ -31,7 +29,7 @@ p->p t->t y->y -> - +\n->\n 3->3 r->r d->d diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/scalarConversion/YAMLScalarConversionTest.java b/plugins/yaml/testSrc/org/jetbrains/yaml/scalarConversion/YAMLScalarConversionTest.java index 1b278a9cda0ac..eb5fcad16c321 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/scalarConversion/YAMLScalarConversionTest.java +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/scalarConversion/YAMLScalarConversionTest.java @@ -75,7 +75,9 @@ private void doTest(Class ...unsupportedClasses) { final YAMLScalar newElement = manipulator.handleContentChange(scalar, text); assertEquals(isUnsupported + ";" + newElement.getClass() + ";" + scalar.getClass(), isUnsupported, newElement.getClass() != scalar.getClass()); - assertEquals("Failed at " + scalar.getClass() + " (became " + newElement.getClass() + "): ", text, newElement.getTextValue()); + StringBuilder stringBuilder = new StringBuilder(); + assertTrue(newElement.createLiteralTextEscaper().decode(ElementManipulators.getValueTextRange(newElement), stringBuilder)); + assertEquals("Failed at " + scalar.getClass() + " (became " + newElement.getClass() + "): ", text, stringBuilder.toString()); }); } }