diff --git a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/serializer/ChangeSerializerTest.xtend b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/serializer/ChangeSerializerTest.xtend index c96945665..d2f1d6805 100644 --- a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/serializer/ChangeSerializerTest.xtend +++ b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/serializer/ChangeSerializerTest.xtend @@ -96,6 +96,31 @@ class ChangeSerializerTest { 24 1 " " -> " bazz; " ''' } + + @Test + def void testInsertBeforeComment() { + val fs = new InMemoryURIHandler() + fs += "inmemory:/file1.pstl" -> ''' + #1 root { + /**/ + child1; + } + ''' + + val rs = fs.createResourceSet + val model = rs.contents("inmemory:/file1.pstl", Node) + + val serializer = newChangeSerializer() + serializer.beginRecordChanges(model.eResource) + model.children.add(0, createNode => [name = "bazz"]) + serializer.endRecordChangesToTextDocuments === ''' + ----------------- inmemory:/file1.pstl (syntax: ) ----------------- + #1 root {<9:9| bazz; /**/ >child1; + } + -------------------------------------------------------------------------------- + 9 9 "\n /**/ \n " -> " bazz; /**/ " + ''' + } @Test def void testInsertTwoChild() { diff --git a/org.eclipse.xtext.ide.tests/xtend-gen/org/eclipse/xtext/ide/tests/serializer/ChangeSerializerTest.java b/org.eclipse.xtext.ide.tests/xtend-gen/org/eclipse/xtext/ide/tests/serializer/ChangeSerializerTest.java index ea8033832..b420efb24 100644 --- a/org.eclipse.xtext.ide.tests/xtend-gen/org/eclipse/xtext/ide/tests/serializer/ChangeSerializerTest.java +++ b/org.eclipse.xtext.ide.tests/xtend-gen/org/eclipse/xtext/ide/tests/serializer/ChangeSerializerTest.java @@ -140,6 +140,48 @@ public class ChangeSerializerTest { this._changeSerializerTestHelper.operator_tripleEquals(_endRecordChangesToTextDocuments, _builder_1); } + @Test + public void testInsertBeforeComment() { + final InMemoryURIHandler fs = new InMemoryURIHandler(); + StringConcatenation _builder = new StringConcatenation(); + _builder.append("#1 root {"); + _builder.newLine(); + _builder.append("\t"); + _builder.append("/**/ "); + _builder.newLine(); + _builder.append("\t"); + _builder.append("child1;"); + _builder.newLine(); + _builder.append("}"); + _builder.newLine(); + Pair _mappedTo = Pair.of("inmemory:/file1.pstl", _builder.toString()); + this._changeSerializerTestHelper.operator_add(fs, _mappedTo); + final ResourceSet rs = this._changeSerializerTestHelper.createResourceSet(fs); + final Node model = this._changeSerializerTestHelper.contents(rs, "inmemory:/file1.pstl", Node.class); + final IChangeSerializer serializer = this._changeSerializerTestHelper.newChangeSerializer(); + serializer.beginRecordChanges(model.eResource()); + EList _children = model.getChildren(); + Node _createNode = this.fac.createNode(); + final Procedure1 _function = (Node it) -> { + it.setName("bazz"); + }; + Node _doubleArrow = ObjectExtensions.operator_doubleArrow(_createNode, _function); + _children.add(0, _doubleArrow); + Collection _endRecordChangesToTextDocuments = this._changeSerializerTestHelper.endRecordChangesToTextDocuments(serializer); + StringConcatenation _builder_1 = new StringConcatenation(); + _builder_1.append("----------------- inmemory:/file1.pstl (syntax: ) -----------------"); + _builder_1.newLine(); + _builder_1.append("#1 root {<9:9| bazz; /**/ >child1;"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append("--------------------------------------------------------------------------------"); + _builder_1.newLine(); + _builder_1.append("9 9 \"\\n\t/**/ \\n\t\" -> \" bazz; /**/ \""); + _builder_1.newLine(); + this._changeSerializerTestHelper.operator_tripleEquals(_endRecordChangesToTextDocuments, _builder_1); + } + @Test public void testInsertTwoChild() { final InMemoryURIHandler fs = new InMemoryURIHandler(); diff --git a/org.eclipse.xtext.tests/src/org/eclipse/xtext/formatting2/regionaccess/internal/RegionAccessDiffTest.xtend b/org.eclipse.xtext.tests/src/org/eclipse/xtext/formatting2/regionaccess/internal/RegionAccessDiffTest.xtend index 81c386d78..eb59b02fc 100644 --- a/org.eclipse.xtext.tests/src/org/eclipse/xtext/formatting2/regionaccess/internal/RegionAccessDiffTest.xtend +++ b/org.eclipse.xtext.tests/src/org/eclipse/xtext/formatting2/regionaccess/internal/RegionAccessDiffTest.xtend @@ -235,5 +235,37 @@ class RegionAccessDiffTest { 2 1 S "a" ValueList:name+=ID ''' } + + @Test def void testInsertBeforeComment() { + val access = ''' + 8 + /**/ + a b + '''.toTextRegionAccess + access.modify [ + val extension ext = access.extensions + val rootObj = access.regionForRootEObject.semanticElement as ValueList + val a = rootObj.regionFor.keyword("8").nextSemanticRegion + val b = a.nextSemanticRegion + replace(a.previousHiddenRegion, a.previousHiddenRegion, b.previousHiddenRegion, b.nextHiddenRegion) + ] === ''' + 0 0 H + B ValueList'[a, b]' Root + 0 1 S "8" Root:'8' + 1 1 1 H "\n" Whitespace:TerminalRule'WS' + 2 1 1 S "b" ValueList:name+=ID + 3 1 H "/**/" Comment:TerminalRule'ML_COMMENT' + 5 "\n" Whitespace:TerminalRule'WS' + 8 1 S "a" ValueList:name+=ID + 9 1 H " " Whitespace:TerminalRule'WS' + 10 1 S "b" ValueList:name+=ID + E ValueList'[a, b]' Root + 11 0 H + ------------ diff 1 ------------ + 1 H "\n" Whitespace:TerminalRule'WS' + "/**/" Comment:TerminalRule'ML_COMMENT' + 6 "\n" Whitespace:TerminalRule'WS' + ''' + } } diff --git a/org.eclipse.xtext.tests/xtend-gen/org/eclipse/xtext/formatting2/regionaccess/internal/RegionAccessDiffTest.java b/org.eclipse.xtext.tests/xtend-gen/org/eclipse/xtext/formatting2/regionaccess/internal/RegionAccessDiffTest.java index 2fd250133..76439b593 100644 --- a/org.eclipse.xtext.tests/xtend-gen/org/eclipse/xtext/formatting2/regionaccess/internal/RegionAccessDiffTest.java +++ b/org.eclipse.xtext.tests/xtend-gen/org/eclipse/xtext/formatting2/regionaccess/internal/RegionAccessDiffTest.java @@ -426,4 +426,73 @@ public class RegionAccessDiffTest { _builder_1.newLine(); this._regionAccessTestHelper.operator_tripleEquals(_modify, _builder_1); } + + @Test + public void testInsertBeforeComment() { + StringConcatenation _builder = new StringConcatenation(); + _builder.append("8"); + _builder.newLine(); + _builder.append("/**/"); + _builder.newLine(); + _builder.append("a b"); + _builder.newLine(); + final ITextRegionAccess access = this._regionAccessTestHelper.toTextRegionAccess(_builder); + final Procedure1 _function = (ITextRegionDiffBuilder it) -> { + @Extension + final ITextRegionExtensions ext = access.getExtensions(); + EObject _semanticElement = access.regionForRootEObject().getSemanticElement(); + final ValueList rootObj = ((ValueList) _semanticElement); + final ISemanticRegion a = ext.regionFor(rootObj).keyword("8").getNextSemanticRegion(); + final ISemanticRegion b = a.getNextSemanticRegion(); + it.replace(a.getPreviousHiddenRegion(), a.getPreviousHiddenRegion(), b.getPreviousHiddenRegion(), b.getNextHiddenRegion()); + }; + ITextRegionAccess _modify = this._regionAccessTestHelper.modify(access, _function); + StringConcatenation _builder_1 = new StringConcatenation(); + _builder_1.append(" "); + _builder_1.append("0 0 H"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("B ValueList\'[a, b]\' Root"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("0 1 S \"8\" Root:\'8\'"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("1 1 1 H \"\\n\" Whitespace:TerminalRule\'WS\'"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("2 1 1 S \"b\" ValueList:name+=ID"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("3 1 H \"/**/\" Comment:TerminalRule\'ML_COMMENT\'"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("5 \"\\n\" Whitespace:TerminalRule\'WS\'"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("8 1 S \"a\" ValueList:name+=ID"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("9 1 H \" \" Whitespace:TerminalRule\'WS\'"); + _builder_1.newLine(); + _builder_1.append("10 1 S \"b\" ValueList:name+=ID"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("E ValueList\'[a, b]\' Root"); + _builder_1.newLine(); + _builder_1.append("11 0 H"); + _builder_1.newLine(); + _builder_1.append("------------ diff 1 ------------"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("1 H \"\\n\" Whitespace:TerminalRule\'WS\'"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("\"/**/\" Comment:TerminalRule\'ML_COMMENT\'"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("6 \"\\n\" Whitespace:TerminalRule\'WS\'"); + _builder_1.newLine(); + this._regionAccessTestHelper.operator_tripleEquals(_modify, _builder_1); + } } diff --git a/org.eclipse.xtext/src/org/eclipse/xtext/formatting2/regionaccess/internal/AbstractHiddenRegion.java b/org.eclipse.xtext/src/org/eclipse/xtext/formatting2/regionaccess/internal/AbstractHiddenRegion.java index 2a8831aa9..406c65c30 100644 --- a/org.eclipse.xtext/src/org/eclipse/xtext/formatting2/regionaccess/internal/AbstractHiddenRegion.java +++ b/org.eclipse.xtext/src/org/eclipse/xtext/formatting2/regionaccess/internal/AbstractHiddenRegion.java @@ -45,30 +45,33 @@ public abstract class AbstractHiddenRegion extends AbstractTextSegment implement protected List collectAlternatingSpaceAndComments(boolean includeComments) { List parts = getParts(); if (parts.isEmpty()) { - return Collections. singletonList(this); + return Collections.singletonList(this); } else { - ITextSegment last = null; + ITextSegment lastWhitespace = null; List result = Lists.newArrayList(); for (IHiddenRegionPart part : parts) { if (part instanceof IWhitespace) { - if (last == null || last instanceof IComment) { + if (lastWhitespace == null) { result.add(part); + lastWhitespace = part; } else { - int mergedLength = last.getLength() + part.getLength(); - result.set(result.size() - 1, new TextSegment(access, last.getOffset(), mergedLength)); + int mergedLength = lastWhitespace.getLength() + part.getLength(); + lastWhitespace = new TextSegment(access, lastWhitespace.getOffset(), mergedLength); + result.set(result.size() - 1, lastWhitespace); } } else if (part instanceof IComment) { - if (last == null || last instanceof IComment) { + if (lastWhitespace == null) { result.add(new TextSegment(access, part.getOffset(), 0)); + } else { + lastWhitespace = null; } - if (includeComments) + if (includeComments) { result.add(part); + } } - if (!result.isEmpty()) - last = result.get(result.size() - 1); } - if (last instanceof IComment) { - result.add(new TextSegment(access, last.getOffset() + last.getLength(), 0)); + if (lastWhitespace == null) { + result.add(new TextSegment(access, getEndOffset(), 0)); } return ImmutableList.copyOf(result); }