diff --git a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/DocumentHighlightTest.xtend b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/DocumentHighlightTest.xtend index 27ae3e015..d335b5461 100644 --- a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/DocumentHighlightTest.xtend +++ b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/DocumentHighlightTest.xtend @@ -7,139 +7,193 @@ *******************************************************************************/ package org.eclipse.xtext.ide.tests.server -import org.eclipse.lsp4j.DocumentHighlight -import org.eclipse.lsp4j.DocumentHighlightKind import org.eclipse.lsp4j.Position -import org.eclipse.xtext.ide.server.occurrences.IDocumentHighlightService +import org.eclipse.lsp4j.Range +import org.eclipse.lsp4j.TextEdit +import org.eclipse.xtext.ide.server.Document import org.junit.Test +import static org.junit.Assert.* +import org.eclipse.lsp4j.TextDocumentContentChangeEvent +import static extension org.eclipse.xtext.util.Strings.toUnixLineSeparator + /** - * Class for testing the {@link DocumentHighlightService document highlight - * service} behavior through the language server. - * - *

- * The string representation of on single {@link DocumentHighlight highlight} - * instance is represented with the below pattern: - * - *

- * R|W|T [{d}+, {d}+] .. [{d}+, {d}+]
- * 
- * - * where the first character describes the {@link DocumentHighlightKind kind} of - * the document highlight. If missing, then the value is {@code NaN}. The values - * between the first square brackets are the start {@link Position#getLine() - * line} and the (zero-based) {@link Position#getCharacter() character offset} - * in the line. The second square brackets contains the end position of the - * selection and described with the same semantics as the first start range. - * Multiple highlight instances are separated by the {@code |} ("pipe") - * character. - * - * @author akos.kitta - Initial contribution and API - * - * @see DocumentHighlight - * @see IDocumentHighlightService + * @author efftinge - Initial contribution and API */ -class DocumentHighlightTest extends AbstractTestLangLanguageServerTest { +class DocumentTest { + + @Test def void testOffSet() { + new Document(1, ''' + hello world + foo + bar + '''.normalize) => [ + assertEquals(0, getOffSet(position(0,0))) + assertEquals(11, getOffSet(position(0,11))) + try { + getOffSet(position(0, 12)) + fail() + } catch (IndexOutOfBoundsException e) { + //expected + } + assertEquals(12, getOffSet(position(1,0))) + assertEquals(13, getOffSet(position(1,1))) + assertEquals(14, getOffSet(position(1,2))) + assertEquals(16, getOffSet(position(2,0))) + assertEquals(19, getOffSet(position(2,3))) + ] + } + + @Test def void testOffSet_empty() { + new Document(1, "") => [ + assertEquals(0, getOffSet(position(0,0))) + try { + getOffSet(position(0, 12)) + fail() + } catch (IndexOutOfBoundsException e) { + //expected + } + ] + } + + @Test def void testUpdate_01() { + new Document(1, ''' + hello world + foo + bar + '''.normalize) => [ + assertEquals(''' + hello world + bar + '''.normalize, applyTextDocumentChanges(#[ + change(position(1,0), position(2,0), "") + ]).contents) + ] + } + + @Test def void testUpdate_02() { + new Document(1, ''' + hello world + foo + bar + '''.normalize) => [ + assertEquals(''' + hello world + future + bar + '''.normalize, applyTextDocumentChanges(#[ + change(position(1,1), position(1,3), "uture") + ]).contents) + ] + } + + @Test def void testUpdate_03() { + new Document(1, ''' + hello world + foo + bar'''.normalize) => [ + assertEquals('', applyTextDocumentChanges(#[ + change(position(0,0), position(2,3), "") + ]).contents) + ] + } + + @Test def void testApplyTextDocumentChanges_04() { + new Document(1, ''' + foo + bar + '''.normalize).applyTextDocumentChanges(#[ + change(position(0,3), position(0,3), "b"), + change(position(0,4), position(0,4), "a"), + change(position(0,5), position(0,5), "r") + ]) + => [ + assertEquals(''' + foobar + bar + '''.normalize, contents) + assertEquals(2, version) + ] + } + + @Test def void testUpdate_nonIncrementalChange() { + new Document(1, ''' + hello world + foo + bar'''.normalize) => [ + assertEquals(' foo ', applyChanges(#[ + textEdit(null, null, " foo ") + ]).contents) + ] + } + + @Test(expected=IndexOutOfBoundsException) def void testGetLineContent_negative() { + new Document(1, '').getLineContent(-1); + } - @Test - def void singleLineNoOccurrences_SelectionBeforeWriteSiteMethodName() { - testDocumentHighlight[ - model = '''type A { op foo() { } }'''; - column = '''type A { op'''.length; - expectedDocumentHighlight = ''; - ]; - } - - @Test - def void singleLineNoOccurrences_SelectionAfterWriteSiteMethodName() { - testDocumentHighlight[ - model = '''type A { op foo() { } }'''; - column = '''type A { op foo('''.length; - expectedDocumentHighlight = ''; - ]; - } + @Test(expected=IndexOutOfBoundsException) def void testGetLineContent_exceeds() { + new Document(1, ''' + aaa + bbb + ccc''').getLineContent(3); + } - @Test - def void singleLineSingleOccurrence() { - testDocumentHighlight[ - model = '''type A { op foo() { } }'''; - column = '''type A { op fo'''.length; - expectedDocumentHighlight = 'W [[0, 12] .. [0, 15]]'; - ]; - } + @Test def void testGetLineContent_empty() { + assertEquals('', new Document(1, '').getLineContent(0)); + } - @Test - def void singleLineSingleOccurrenceWithVariable() { - testDocumentHighlight[ - model = '''type A { int foo op foo() { } }'''; - column = '''type A { int fo'''.length; - expectedDocumentHighlight = 'W [[0, 13] .. [0, 16]]'; - ]; - } + @Test def void testGetLineContent() { + assertEquals('bbb', new Document(1, ''' + aaa + bbb + ccc'''.toUnixLineSeparator).getLineContent(1)); + } - @Test - def void singleLineSingleOccurrenceWithMultipleTypes() { - testDocumentHighlight[ - model = '''type A { op foo() { } } type B { op foo() { } }'''; - column = '''type A { op fo'''.length; - expectedDocumentHighlight = 'W [[0, 12] .. [0, 15]]'; - ]; - } + @Test def void testGetLineCount_empty() { + assertEquals(1, new Document(1, '').lineCount); + } - @Test - def void singleLineMultipleOccurrences_SelectionOnReadSite() { - testDocumentHighlight[ - model = '''type A { op foo() { } op bar() { foo(10) } }'''; - line = 0; - column = '''type A { op foo() { } op bar() { fo'''.length; - expectedDocumentHighlight = 'W [[0, 12] .. [0, 15]] | R [[0, 33] .. [0, 36]]'; - ]; - } + @Test def void testGetLineCount_single() { + assertEquals(1, new Document(1, 'aaa bbb ccc').lineCount); + } - @Test - def void singleLineMultipleOccurrences_SelectionOnWriteSite() { - testDocumentHighlight[ - model = '''type A { op foo() { } op bar() { foo(10) } }'''; - line = 0; - column = '''type A { op fo'''.length; - expectedDocumentHighlight = 'W [[0, 12] .. [0, 15]] | R [[0, 33] .. [0, 36]]'; - ]; - } + @Test def void testGetLineCount_multi() { + assertEquals(3, new Document(1, ''' + aaa + bbb + ccc''').lineCount); + } - @Test - def void multipleLinesMultipleOccurrences_WithHorizontalTabs() { - testDocumentHighlight[ -// This snippet contains horizontal tabs for code indentation - model = ''' - type A { - op foo() { } - op bar() { - foo(10) - } - }'''; - line = 1; - // Same as above, horizontal tabs for code indentation - column = ''' op fo'''.length; - expectedDocumentHighlight = 'W [[1, 4] .. [1, 7]] | R [[3, 2] .. [3, 5]]'; - ]; - } - - @Test - def void multipleLinesMultipleOccurrences_WithWhitespaces() { - testDocumentHighlight[ -// This snippet contains spaces for code indentation - model = ''' - type A { - op foo() { } - op bar() { - foo(10) - } - }'''; - line = 1; - // Same as above, spaces for code indentation - column = ''' op fo'''.length; - expectedDocumentHighlight = 'W [[1, 7] .. [1, 10]] | R [[3, 8] .. [3, 11]]'; - ]; - } - -} + private def change(Position startPos, Position endPos, String newText) { + new TextDocumentContentChangeEvent => [ + if (startPos !== null) { + range = new Range => [ + start = startPos + end = endPos + ] + } + it.text = newText + ] + } + + private def textEdit(Position startPos, Position endPos, String newText) { + new TextEdit => [ + if (startPos !== null) { + range = new Range => [ + start = startPos + end = endPos + ] + } + it.newText = newText + ] + } + + private def normalize(CharSequence s) { + return s.toString.replaceAll("\r", "") + } + + private def position(int l, int c) { + new Position => [line=l character=c] + } + +} \ No newline at end of file diff --git a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/SemanticHighlightingTest.xtend b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/SemanticHighlightingTest.xtend index 87e9b6e6f..f2fd038c5 100644 --- a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/SemanticHighlightingTest.xtend +++ b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/SemanticHighlightingTest.xtend @@ -11,6 +11,8 @@ import com.google.inject.Inject import java.util.List import org.eclipse.lsp4j.ClientCapabilities import org.eclipse.lsp4j.DidChangeTextDocumentParams +import org.eclipse.lsp4j.Position +import org.eclipse.lsp4j.Range import org.eclipse.lsp4j.SemanticHighlightingCapabilities import org.eclipse.lsp4j.TextDocumentClientCapabilities import org.eclipse.lsp4j.TextDocumentContentChangeEvent @@ -20,8 +22,8 @@ import org.junit.Before import org.junit.Test import static org.junit.Assert.* -import org.eclipse.lsp4j.Range -import org.eclipse.lsp4j.Position + +import static extension org.eclipse.xtext.util.Strings.* class SemanticHighlightingTest extends AbstractTestLangLanguageServerTest { @@ -168,7 +170,7 @@ class SemanticHighlightingTest extends AbstractTestLangLanguageServerTest { val actual = entry.value.sortWith[left, right|left.line - right.line].map[it -> scopes].map [ toExpectation ].join('\n'); - assertEquals(expected, actual); + assertEquals(expected.toUnixLineSeparator, actual); } } diff --git a/org.eclipse.xtext.ide.tests/xtend-gen/org/eclipse/xtext/ide/tests/server/DocumentHighlightTest.java b/org.eclipse.xtext.ide.tests/xtend-gen/org/eclipse/xtext/ide/tests/server/DocumentHighlightTest.java index ad5f41f5c..02dcfb1f6 100644 --- a/org.eclipse.xtext.ide.tests/xtend-gen/org/eclipse/xtext/ide/tests/server/DocumentHighlightTest.java +++ b/org.eclipse.xtext.ide.tests/xtend-gen/org/eclipse/xtext/ide/tests/server/DocumentHighlightTest.java @@ -7,201 +7,285 @@ */ package org.eclipse.xtext.ide.tests.server; -import org.eclipse.lsp4j.DocumentHighlight; -import org.eclipse.lsp4j.DocumentHighlightKind; +import java.util.Collections; import org.eclipse.lsp4j.Position; +import org.eclipse.lsp4j.Range; +import org.eclipse.lsp4j.TextDocumentContentChangeEvent; +import org.eclipse.lsp4j.TextEdit; import org.eclipse.xtend2.lib.StringConcatenation; -import org.eclipse.xtext.ide.server.occurrences.IDocumentHighlightService; -import org.eclipse.xtext.ide.tests.server.AbstractTestLangLanguageServerTest; -import org.eclipse.xtext.testing.DocumentHighlightConfiguration; +import org.eclipse.xtext.ide.server.Document; +import org.eclipse.xtext.util.Strings; +import org.eclipse.xtext.xbase.lib.CollectionLiterals; +import org.eclipse.xtext.xbase.lib.Exceptions; +import org.eclipse.xtext.xbase.lib.ObjectExtensions; import org.eclipse.xtext.xbase.lib.Procedures.Procedure1; +import org.junit.Assert; import org.junit.Test; /** - * Class for testing the {@link DocumentHighlightService document highlight - * service} behavior through the language server. - * - *

- * The string representation of on single {@link DocumentHighlight highlight} - * instance is represented with the below pattern: - * - *

- * R|W|T [{d}+, {d}+] .. [{d}+, {d}+]
- * 
- * - * where the first character describes the {@link DocumentHighlightKind kind} of - * the document highlight. If missing, then the value is {@code NaN}. The values - * between the first square brackets are the start {@link Position#getLine() - * line} and the (zero-based) {@link Position#getCharacter() character offset} - * in the line. The second square brackets contains the end position of the - * selection and described with the same semantics as the first start range. - * Multiple highlight instances are separated by the {@code |} ("pipe") - * character. - * - * @author akos.kitta - Initial contribution and API - * - * @see DocumentHighlight - * @see IDocumentHighlightService + * @author efftinge - Initial contribution and API */ @SuppressWarnings("all") -public class DocumentHighlightTest extends AbstractTestLangLanguageServerTest { +public class DocumentTest { @Test - public void singleLineNoOccurrences_SelectionBeforeWriteSiteMethodName() { - final Procedure1 _function = (DocumentHighlightConfiguration it) -> { - StringConcatenation _builder = new StringConcatenation(); - _builder.append("type A { op foo() { } }"); - it.setModel(_builder.toString()); - StringConcatenation _builder_1 = new StringConcatenation(); - _builder_1.append("type A { op"); - it.setColumn(_builder_1.length()); - it.setExpectedDocumentHighlight(""); + public void testOffSet() { + StringConcatenation _builder = new StringConcatenation(); + _builder.append("hello world"); + _builder.newLine(); + _builder.append("foo"); + _builder.newLine(); + _builder.append("bar"); + _builder.newLine(); + String _normalize = this.normalize(_builder); + Document _document = new Document(Integer.valueOf(1), _normalize); + final Procedure1 _function = (Document it) -> { + Assert.assertEquals(0, it.getOffSet(this.position(0, 0))); + Assert.assertEquals(11, it.getOffSet(this.position(0, 11))); + try { + it.getOffSet(this.position(0, 12)); + Assert.fail(); + } catch (final Throwable _t) { + if (_t instanceof IndexOutOfBoundsException) { + } else { + throw Exceptions.sneakyThrow(_t); + } + } + Assert.assertEquals(12, it.getOffSet(this.position(1, 0))); + Assert.assertEquals(13, it.getOffSet(this.position(1, 1))); + Assert.assertEquals(14, it.getOffSet(this.position(1, 2))); + Assert.assertEquals(16, it.getOffSet(this.position(2, 0))); + Assert.assertEquals(19, it.getOffSet(this.position(2, 3))); }; - this.testDocumentHighlight(_function); + ObjectExtensions.operator_doubleArrow(_document, _function); } @Test - public void singleLineNoOccurrences_SelectionAfterWriteSiteMethodName() { - final Procedure1 _function = (DocumentHighlightConfiguration it) -> { - StringConcatenation _builder = new StringConcatenation(); - _builder.append("type A { op foo() { } }"); - it.setModel(_builder.toString()); - StringConcatenation _builder_1 = new StringConcatenation(); - _builder_1.append("type A { op foo("); - it.setColumn(_builder_1.length()); - it.setExpectedDocumentHighlight(""); + public void testOffSet_empty() { + Document _document = new Document(Integer.valueOf(1), ""); + final Procedure1 _function = (Document it) -> { + Assert.assertEquals(0, it.getOffSet(this.position(0, 0))); + try { + it.getOffSet(this.position(0, 12)); + Assert.fail(); + } catch (final Throwable _t) { + if (_t instanceof IndexOutOfBoundsException) { + } else { + throw Exceptions.sneakyThrow(_t); + } + } }; - this.testDocumentHighlight(_function); + ObjectExtensions.operator_doubleArrow(_document, _function); } @Test - public void singleLineSingleOccurrence() { - final Procedure1 _function = (DocumentHighlightConfiguration it) -> { - StringConcatenation _builder = new StringConcatenation(); - _builder.append("type A { op foo() { } }"); - it.setModel(_builder.toString()); + public void testUpdate_01() { + StringConcatenation _builder = new StringConcatenation(); + _builder.append("hello world"); + _builder.newLine(); + _builder.append("foo"); + _builder.newLine(); + _builder.append("bar"); + _builder.newLine(); + String _normalize = this.normalize(_builder); + Document _document = new Document(Integer.valueOf(1), _normalize); + final Procedure1 _function = (Document it) -> { StringConcatenation _builder_1 = new StringConcatenation(); - _builder_1.append("type A { op fo"); - it.setColumn(_builder_1.length()); - it.setExpectedDocumentHighlight("W [[0, 12] .. [0, 15]]"); + _builder_1.append("hello world"); + _builder_1.newLine(); + _builder_1.append("bar"); + _builder_1.newLine(); + TextDocumentContentChangeEvent _change = this.change(this.position(1, 0), this.position(2, 0), ""); + Assert.assertEquals(this.normalize(_builder_1), it.applyTextDocumentChanges( + Collections.unmodifiableList(CollectionLiterals.newArrayList(_change))).getContents()); }; - this.testDocumentHighlight(_function); + ObjectExtensions.operator_doubleArrow(_document, _function); } @Test - public void singleLineSingleOccurrenceWithVariable() { - final Procedure1 _function = (DocumentHighlightConfiguration it) -> { - StringConcatenation _builder = new StringConcatenation(); - _builder.append("type A { int foo op foo() { } }"); - it.setModel(_builder.toString()); + public void testUpdate_02() { + StringConcatenation _builder = new StringConcatenation(); + _builder.append("hello world"); + _builder.newLine(); + _builder.append("foo"); + _builder.newLine(); + _builder.append("bar"); + _builder.newLine(); + String _normalize = this.normalize(_builder); + Document _document = new Document(Integer.valueOf(1), _normalize); + final Procedure1 _function = (Document it) -> { StringConcatenation _builder_1 = new StringConcatenation(); - _builder_1.append("type A { int fo"); - it.setColumn(_builder_1.length()); - it.setExpectedDocumentHighlight("W [[0, 13] .. [0, 16]]"); + _builder_1.append("hello world"); + _builder_1.newLine(); + _builder_1.append("future"); + _builder_1.newLine(); + _builder_1.append("bar"); + _builder_1.newLine(); + TextDocumentContentChangeEvent _change = this.change(this.position(1, 1), this.position(1, 3), "uture"); + Assert.assertEquals(this.normalize(_builder_1), it.applyTextDocumentChanges( + Collections.unmodifiableList(CollectionLiterals.newArrayList(_change))).getContents()); }; - this.testDocumentHighlight(_function); + ObjectExtensions.operator_doubleArrow(_document, _function); } @Test - public void singleLineSingleOccurrenceWithMultipleTypes() { - final Procedure1 _function = (DocumentHighlightConfiguration it) -> { - StringConcatenation _builder = new StringConcatenation(); - _builder.append("type A { op foo() { } } type B { op foo() { } }"); - it.setModel(_builder.toString()); - StringConcatenation _builder_1 = new StringConcatenation(); - _builder_1.append("type A { op fo"); - it.setColumn(_builder_1.length()); - it.setExpectedDocumentHighlight("W [[0, 12] .. [0, 15]]"); + public void testUpdate_03() { + StringConcatenation _builder = new StringConcatenation(); + _builder.append("hello world"); + _builder.newLine(); + _builder.append("foo"); + _builder.newLine(); + _builder.append("bar"); + String _normalize = this.normalize(_builder); + Document _document = new Document(Integer.valueOf(1), _normalize); + final Procedure1 _function = (Document it) -> { + TextDocumentContentChangeEvent _change = this.change(this.position(0, 0), this.position(2, 3), ""); + Assert.assertEquals("", it.applyTextDocumentChanges( + Collections.unmodifiableList(CollectionLiterals.newArrayList(_change))).getContents()); }; - this.testDocumentHighlight(_function); + ObjectExtensions.operator_doubleArrow(_document, _function); } @Test - public void singleLineMultipleOccurrences_SelectionOnReadSite() { - final Procedure1 _function = (DocumentHighlightConfiguration it) -> { - StringConcatenation _builder = new StringConcatenation(); - _builder.append("type A { op foo() { } op bar() { foo(10) } }"); - it.setModel(_builder.toString()); - it.setLine(0); + public void testApplyTextDocumentChanges_04() { + StringConcatenation _builder = new StringConcatenation(); + _builder.append("foo"); + _builder.newLine(); + _builder.append("bar"); + _builder.newLine(); + String _normalize = this.normalize(_builder); + TextDocumentContentChangeEvent _change = this.change(this.position(0, 3), this.position(0, 3), "b"); + TextDocumentContentChangeEvent _change_1 = this.change(this.position(0, 4), this.position(0, 4), "a"); + TextDocumentContentChangeEvent _change_2 = this.change(this.position(0, 5), this.position(0, 5), "r"); + Document _applyTextDocumentChanges = new Document(Integer.valueOf(1), _normalize).applyTextDocumentChanges( + Collections.unmodifiableList(CollectionLiterals.newArrayList(_change, _change_1, _change_2))); + final Procedure1 _function = (Document it) -> { StringConcatenation _builder_1 = new StringConcatenation(); - _builder_1.append("type A { op foo() { } op bar() { fo"); - it.setColumn(_builder_1.length()); - it.setExpectedDocumentHighlight("W [[0, 12] .. [0, 15]] | R [[0, 33] .. [0, 36]]"); + _builder_1.append("foobar"); + _builder_1.newLine(); + _builder_1.append("bar"); + _builder_1.newLine(); + Assert.assertEquals(this.normalize(_builder_1), it.getContents()); + Assert.assertEquals(2, (it.getVersion()).intValue()); }; - this.testDocumentHighlight(_function); + ObjectExtensions.operator_doubleArrow(_applyTextDocumentChanges, _function); } @Test - public void singleLineMultipleOccurrences_SelectionOnWriteSite() { - final Procedure1 _function = (DocumentHighlightConfiguration it) -> { - StringConcatenation _builder = new StringConcatenation(); - _builder.append("type A { op foo() { } op bar() { foo(10) } }"); - it.setModel(_builder.toString()); - it.setLine(0); - StringConcatenation _builder_1 = new StringConcatenation(); - _builder_1.append("type A { op fo"); - it.setColumn(_builder_1.length()); - it.setExpectedDocumentHighlight("W [[0, 12] .. [0, 15]] | R [[0, 33] .. [0, 36]]"); + public void testUpdate_nonIncrementalChange() { + StringConcatenation _builder = new StringConcatenation(); + _builder.append("hello world"); + _builder.newLine(); + _builder.append("foo"); + _builder.newLine(); + _builder.append("bar"); + String _normalize = this.normalize(_builder); + Document _document = new Document(Integer.valueOf(1), _normalize); + final Procedure1 _function = (Document it) -> { + TextEdit _textEdit = this.textEdit(null, null, " foo "); + Assert.assertEquals(" foo ", it.applyChanges( + Collections.unmodifiableList(CollectionLiterals.newArrayList(_textEdit))).getContents()); }; - this.testDocumentHighlight(_function); + ObjectExtensions.operator_doubleArrow(_document, _function); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void testGetLineContent_negative() { + new Document(Integer.valueOf(1), "").getLineContent((-1)); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void testGetLineContent_exceeds() { + StringConcatenation _builder = new StringConcatenation(); + _builder.append("aaa"); + _builder.newLine(); + _builder.append("bbb"); + _builder.newLine(); + _builder.append("ccc"); + new Document(Integer.valueOf(1), _builder.toString()).getLineContent(3); } @Test - public void multipleLinesMultipleOccurrences_WithHorizontalTabs() { - final Procedure1 _function = (DocumentHighlightConfiguration it) -> { - StringConcatenation _builder = new StringConcatenation(); - _builder.append("type A {"); - _builder.newLine(); - _builder.append("\t"); - _builder.append("op foo() { }"); - _builder.newLine(); - _builder.append("\t"); - _builder.append("op bar() {"); - _builder.newLine(); - _builder.append("\t\t"); - _builder.append("foo(10)"); - _builder.newLine(); - _builder.append("\t"); - _builder.append("}"); - _builder.newLine(); - _builder.append("}"); - it.setModel(_builder.toString()); - it.setLine(1); - StringConcatenation _builder_1 = new StringConcatenation(); - _builder_1.append("\t"); - _builder_1.append("op fo"); - it.setColumn(_builder_1.length()); - it.setExpectedDocumentHighlight("W [[1, 4] .. [1, 7]] | R [[3, 2] .. [3, 5]]"); - }; - this.testDocumentHighlight(_function); + public void testGetLineContent_empty() { + Assert.assertEquals("", new Document(Integer.valueOf(1), "").getLineContent(0)); } @Test - public void multipleLinesMultipleOccurrences_WithWhitespaces() { - final Procedure1 _function = (DocumentHighlightConfiguration it) -> { - StringConcatenation _builder = new StringConcatenation(); - _builder.append("type A {"); - _builder.newLine(); - _builder.append(" "); - _builder.append("op foo() { }"); - _builder.newLine(); - _builder.append(" "); - _builder.append("op bar() {"); - _builder.newLine(); - _builder.append(" "); - _builder.append("foo(10)"); - _builder.newLine(); - _builder.append(" "); - _builder.append("}"); - _builder.newLine(); - _builder.append("}"); - it.setModel(_builder.toString()); - it.setLine(1); - StringConcatenation _builder_1 = new StringConcatenation(); - _builder_1.append(" "); - _builder_1.append("op fo"); - it.setColumn(_builder_1.length()); - it.setExpectedDocumentHighlight("W [[1, 7] .. [1, 10]] | R [[3, 8] .. [3, 11]]"); + public void testGetLineContent() { + StringConcatenation _builder = new StringConcatenation(); + _builder.append("aaa"); + _builder.newLine(); + _builder.append("bbb"); + _builder.newLine(); + _builder.append("ccc"); + String _unixLineSeparator = Strings.toUnixLineSeparator(_builder); + Assert.assertEquals("bbb", new Document(Integer.valueOf(1), _unixLineSeparator).getLineContent(1)); + } + + @Test + public void testGetLineCount_empty() { + Assert.assertEquals(1, new Document(Integer.valueOf(1), "").getLineCount()); + } + + @Test + public void testGetLineCount_single() { + Assert.assertEquals(1, new Document(Integer.valueOf(1), "aaa bbb ccc").getLineCount()); + } + + @Test + public void testGetLineCount_multi() { + StringConcatenation _builder = new StringConcatenation(); + _builder.append("aaa"); + _builder.newLine(); + _builder.append("bbb"); + _builder.newLine(); + _builder.append("ccc"); + Assert.assertEquals(3, new Document(Integer.valueOf(1), _builder.toString()).getLineCount()); + } + + private TextDocumentContentChangeEvent change(final Position startPos, final Position endPos, final String newText) { + TextDocumentContentChangeEvent _textDocumentContentChangeEvent = new TextDocumentContentChangeEvent(); + final Procedure1 _function = (TextDocumentContentChangeEvent it) -> { + if ((startPos != null)) { + Range _range = new Range(); + final Procedure1 _function_1 = (Range it_1) -> { + it_1.setStart(startPos); + it_1.setEnd(endPos); + }; + Range _doubleArrow = ObjectExtensions.operator_doubleArrow(_range, _function_1); + it.setRange(_doubleArrow); + } + it.setText(newText); }; - this.testDocumentHighlight(_function); + return ObjectExtensions.operator_doubleArrow(_textDocumentContentChangeEvent, _function); + } + + private TextEdit textEdit(final Position startPos, final Position endPos, final String newText) { + TextEdit _textEdit = new TextEdit(); + final Procedure1 _function = (TextEdit it) -> { + if ((startPos != null)) { + Range _range = new Range(); + final Procedure1 _function_1 = (Range it_1) -> { + it_1.setStart(startPos); + it_1.setEnd(endPos); + }; + Range _doubleArrow = ObjectExtensions.operator_doubleArrow(_range, _function_1); + it.setRange(_doubleArrow); + } + it.setNewText(newText); + }; + return ObjectExtensions.operator_doubleArrow(_textEdit, _function); + } + + private String normalize(final CharSequence s) { + return s.toString().replaceAll("\r", ""); + } + + private Position position(final int l, final int c) { + Position _position = new Position(); + final Procedure1 _function = (Position it) -> { + it.setLine(l); + it.setCharacter(c); + }; + return ObjectExtensions.operator_doubleArrow(_position, _function); } } diff --git a/org.eclipse.xtext.ide.tests/xtend-gen/org/eclipse/xtext/ide/tests/server/SemanticHighlightingTest.java b/org.eclipse.xtext.ide.tests/xtend-gen/org/eclipse/xtext/ide/tests/server/SemanticHighlightingTest.java index edfdea715..ec6f69093 100644 --- a/org.eclipse.xtext.ide.tests/xtend-gen/org/eclipse/xtext/ide/tests/server/SemanticHighlightingTest.java +++ b/org.eclipse.xtext.ide.tests/xtend-gen/org/eclipse/xtext/ide/tests/server/SemanticHighlightingTest.java @@ -28,6 +28,7 @@ import org.eclipse.lsp4j.VersionedTextDocumentIdentifier; import org.eclipse.xtend2.lib.StringConcatenation; import org.eclipse.xtext.ide.server.UriExtensions; import org.eclipse.xtext.ide.tests.server.AbstractTestLangLanguageServerTest; +import org.eclipse.xtext.util.Strings; import org.eclipse.xtext.xbase.lib.CollectionLiterals; import org.eclipse.xtext.xbase.lib.Extension; import org.eclipse.xtext.xbase.lib.Functions.Function1; @@ -315,6 +316,6 @@ public class SemanticHighlightingTest extends AbstractTestLangLanguageServerTest return this.toExpectation(it); }; final String actual = IterableExtensions.join(ListExtensions.>>, String>map(ListExtensions.>>>map(IterableExtensions.sortWith(entry.getValue(), _function_1), _function_2), _function_3), "\n"); - this.assertEquals(expected, actual); + this.assertEquals(Strings.toUnixLineSeparator(expected), actual); } } diff --git a/org.eclipse.xtext.testing/src/org/eclipse/xtext/testing/AbstractLanguageServerTest.xtend b/org.eclipse.xtext.testing/src/org/eclipse/xtext/testing/AbstractLanguageServerTest.xtend index dfdf0b64a..26a8f0f86 100644 --- a/org.eclipse.xtext.testing/src/org/eclipse/xtext/testing/AbstractLanguageServerTest.xtend +++ b/org.eclipse.xtext.testing/src/org/eclipse/xtext/testing/AbstractLanguageServerTest.xtend @@ -12,12 +12,12 @@ import com.google.inject.Inject import com.google.inject.Module import java.io.File import java.io.FileWriter -import java.net.URI import java.nio.file.Path import java.nio.file.Paths import java.util.List import java.util.Map import java.util.concurrent.CompletableFuture +import org.eclipse.emf.common.util.URI import org.eclipse.lsp4j.CodeAction import org.eclipse.lsp4j.CodeActionContext import org.eclipse.lsp4j.CodeActionParams @@ -65,6 +65,7 @@ import org.eclipse.lsp4j.WorkspaceSymbolParams import org.eclipse.lsp4j.jsonrpc.Endpoint import org.eclipse.lsp4j.jsonrpc.messages.Either import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints +import org.eclipse.lsp4j.services.LanguageClient import org.eclipse.lsp4j.util.SemanticHighlightingTokens import org.eclipse.xtend.lib.annotations.Accessors import org.eclipse.xtend.lib.annotations.Data @@ -84,7 +85,8 @@ import org.junit.Assert import org.junit.Before import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach -import org.eclipse.lsp4j.services.LanguageClient + +import static extension org.eclipse.xtext.util.Strings.* import static extension org.eclipse.lsp4j.util.Ranges.containsRange @@ -174,7 +176,7 @@ abstract class AbstractLanguageServerTest implements Endpoint { } protected def Path relativize(String uri) { - val path = Paths.get(new URI(uri)) + val path = Paths.get(new java.net.URI(uri)) testRootPath.relativize(path) } @@ -210,7 +212,7 @@ abstract class AbstractLanguageServerTest implements Endpoint { uri = fileUri languageId = langaugeId version = 1 - text = model + text = model.toUnixLineSeparator ] ]) } @@ -416,7 +418,7 @@ abstract class AbstractLanguageServerTest implements Endpoint { protected dispatch def String toExpectation(WorkspaceEdit it) ''' changes : «FOR entry : changes.entrySet» - «org.eclipse.emf.common.util.URI.createURI(entry.key).lastSegment» : «entry.value.toExpectation» + «URI.createURI(entry.key).lastSegment» : «entry.value.toExpectation» «ENDFOR» documentChanges : «documentChanges.toExpectation» @@ -435,7 +437,7 @@ abstract class AbstractLanguageServerTest implements Endpoint { ''' protected def dispatch String toExpectation(VersionedTextDocumentIdentifier v) - '''«org.eclipse.emf.common.util.URI.createURI(v.uri).lastSegment» <«v.version»>''' + '''«URI.createURI(v.uri).lastSegment» <«v.version»>''' @@ -782,6 +784,10 @@ class TextDocumentConfiguration { String model String filePath (InitializeParams)=>void initializer + + def void setModel(String model) { + this.model = model.toUnixLineSeparator + } } @Accessors diff --git a/org.eclipse.xtext.testing/xtend-gen/org/eclipse/xtext/testing/AbstractLanguageServerTest.java b/org.eclipse.xtext.testing/xtend-gen/org/eclipse/xtext/testing/AbstractLanguageServerTest.java index 9b65dc8a0..e126a80a7 100644 --- a/org.eclipse.xtext.testing/xtend-gen/org/eclipse/xtext/testing/AbstractLanguageServerTest.java +++ b/org.eclipse.xtext.testing/xtend-gen/org/eclipse/xtext/testing/AbstractLanguageServerTest.java @@ -107,6 +107,7 @@ import org.eclipse.xtext.testing.WorkspaceSymbolConfiguration; import org.eclipse.xtext.util.CancelIndicator; import org.eclipse.xtext.util.Files; import org.eclipse.xtext.util.Modules2; +import org.eclipse.xtext.util.Strings; import org.eclipse.xtext.xbase.lib.CollectionLiterals; import org.eclipse.xtext.xbase.lib.Conversions; import org.eclipse.xtext.xbase.lib.Exceptions; @@ -368,7 +369,7 @@ public abstract class AbstractLanguageServerTest implements Endpoint { it_1.setUri(fileUri); it_1.setLanguageId(langaugeId); it_1.setVersion(1); - it_1.setText(model); + it_1.setText(Strings.toUnixLineSeparator(model)); }; TextDocumentItem _doubleArrow = ObjectExtensions.operator_doubleArrow(_textDocumentItem, _function_1); it.setTextDocument(_doubleArrow);