diff --git a/vscode-extensions/commons/language-server-commons/.settings/org.eclipse.jdt.ui.prefs b/vscode-extensions/commons/language-server-commons/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 000000000..75f829439 --- /dev/null +++ b/vscode-extensions/commons/language-server-commons/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,59 @@ +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=true +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_methods=false +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_missing_override_annotations_interface_methods=true +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_functional_interfaces=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.correct_indentation=false +sp_cleanup.format_source_code=false +sp_cleanup.format_source_code_changes_only=false +sp_cleanup.insert_inferred_type_arguments=false +sp_cleanup.make_local_variable_final=true +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=true +sp_cleanup.make_type_abstract_if_missing_method=false +sp_cleanup.make_variable_declarations_final=false +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.on_save_use_additional_actions=true +sp_cleanup.organize_imports=true +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_redundant_type_arguments=false +sp_cleanup.remove_trailing_whitespaces=true +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_casts=true +sp_cleanup.remove_unnecessary_nls_tags=false +sp_cleanup.remove_unused_imports=false +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.use_anonymous_class_creation=false +sp_cleanup.use_blocks=false +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_lambda=true +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_this_for_non_static_field_access=false +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/vscode-extensions/commons/language-server-commons/pom.xml b/vscode-extensions/commons/language-server-commons/pom.xml index b5caeeef9..900f27817 100644 --- a/vscode-extensions/commons/language-server-commons/pom.xml +++ b/vscode-extensions/commons/language-server-commons/pom.xml @@ -24,18 +24,19 @@ - - 2.5.0 - 2.10 - 0.3.0 - - org.springframework.ide.vscode util-commons ${project.version} + + + org.springframework.ide.vscode + language-server-test-harness + ${project.version} + test + io.typefox.lsapi diff --git a/vscode-extensions/commons/language-server-commons/src/main/java/org/springframework/ide/vscode/commons/completion/DocumentEdits.java b/vscode-extensions/commons/language-server-commons/src/main/java/org/springframework/ide/vscode/commons/completion/DocumentEdits.java index e1fc75d0c..adb277986 100644 --- a/vscode-extensions/commons/language-server-commons/src/main/java/org/springframework/ide/vscode/commons/completion/DocumentEdits.java +++ b/vscode-extensions/commons/language-server-commons/src/main/java/org/springframework/ide/vscode/commons/completion/DocumentEdits.java @@ -95,7 +95,7 @@ public class DocumentEdits implements ProposalApplier { public final int start; public final int end; public final String newText; - + public TextReplace(int start, int end, String newText) { super(); this.start = start; @@ -119,7 +119,7 @@ public class DocumentEdits implements ProposalApplier { */ BEFORE, /** - * + * * Transform positions around inserts to stick to the end of the inserted block. */ AFTER @@ -159,6 +159,7 @@ public class DocumentEdits implements ProposalApplier { public abstract int getStart(); public abstract int getEnd(); abstract void apply(DocumentState doc) throws BadLocationException; + @Override public abstract String toString(); } @@ -228,13 +229,14 @@ public class DocumentEdits implements ProposalApplier { } final OffsetTransformer parent = org2new; org2new = new OffsetTransformer() { + @Override public int transform(int org, Direction dir) { int tOffset = parent.transform(org, dir); if (tOffsettStart) { return tOffset + text.length(); - } else /* tOffset==tStart*/ { + } else /* tOffset==tStart*/ { if (dir==Direction.BEFORE) { return tOffset; } else { @@ -258,6 +260,7 @@ public class DocumentEdits implements ProposalApplier { final OffsetTransformer parent = org2new; org2new = new OffsetTransformer() { + @Override public int transform(int org, Direction dir) { int tOffset = parent.transform(org, dir); if (tOffset<=tStart) { @@ -308,7 +311,7 @@ public class DocumentEdits implements ProposalApplier { } @Override - public IRegion getSelection(IDocument doc) throws Exception { + public IRegion getSelection() throws Exception { DocumentState selectionState = new DocumentState(null); for (Edit edit : edits) { edit.apply(selectionState); @@ -318,12 +321,12 @@ public class DocumentEdits implements ProposalApplier { } return null; } - + public TextReplace asReplacement(IDocument doc) throws BadLocationException { if (!edits.isEmpty()) { int start = edits.stream().mapToInt(Edit::getStart).min().getAsInt(); int end = edits.stream().mapToInt(Edit::getEnd).max().getAsInt(); - + DocumentState state = new DocumentState(doc); for (Edit edit : edits) { edit.apply(state); diff --git a/vscode-extensions/commons/language-server-commons/src/main/java/org/springframework/ide/vscode/commons/completion/ProposalApplier.java b/vscode-extensions/commons/language-server-commons/src/main/java/org/springframework/ide/vscode/commons/completion/ProposalApplier.java index fd1b783d7..9a6b35425 100644 --- a/vscode-extensions/commons/language-server-commons/src/main/java/org/springframework/ide/vscode/commons/completion/ProposalApplier.java +++ b/vscode-extensions/commons/language-server-commons/src/main/java/org/springframework/ide/vscode/commons/completion/ProposalApplier.java @@ -25,12 +25,12 @@ public interface ProposalApplier { * {@link ProposalApplier} that does nothing whatsoever. */ static ProposalApplier NULL = new ProposalApplier() { - @Override public IRegion getSelection(IDocument document) { return null; } + @Override public IRegion getSelection() { return null; } @Override public void apply(IDocument doc) {} @Override public String toString() { return "NULL";}; }; - IRegion getSelection(IDocument document) throws Exception; + IRegion getSelection() throws Exception; void apply(IDocument doc) throws Exception; } diff --git a/vscode-extensions/commons/language-server-commons/src/main/java/org/springframework/ide/vscode/util/TextDocument.java b/vscode-extensions/commons/language-server-commons/src/main/java/org/springframework/ide/vscode/util/TextDocument.java index f1c8b345f..f6c9cc397 100644 --- a/vscode-extensions/commons/language-server-commons/src/main/java/org/springframework/ide/vscode/util/TextDocument.java +++ b/vscode-extensions/commons/language-server-commons/src/main/java/org/springframework/ide/vscode/util/TextDocument.java @@ -12,22 +12,22 @@ import io.typefox.lsapi.impl.PositionImpl; import io.typefox.lsapi.impl.RangeImpl; public class TextDocument implements IDocument { - + //TODO: This representiation of 'document content' is simplistic and inefficient - // for large documents. + // for large documents. // Making any change, such as inserting a character a user typed, works by copying the String that represents the // contents. This could really become problematic for largish-documents when there are frequent changes. - + Pattern NEWLINE = Pattern.compile("\\r|\\n|\\r\\n|\\n\\r"); private int[] _lineStarts; - + private final String uri; private String text = ""; - + public TextDocument(String uri) { this.uri = uri; } - + private TextDocument(TextDocument other) { this.uri = other.uri; this.text = other.text; @@ -37,15 +37,16 @@ public class TextDocument implements IDocument { public String getUri() { return uri; } - + + @Override public String get() { return getText(); } - + public synchronized String getText() { return text; } - + public synchronized void setText(String text) { this.text = text; this._lineStarts = null; @@ -62,7 +63,7 @@ public class TextDocument implements IDocument { } /** - * Convert a simple offset+length pair into a vscode range. This is a method on + * Convert a simple offset+length pair into a vscode range. This is a method on * TextDocument because it requires splitting document into lines to determine * line numbers from offsets. */ @@ -73,7 +74,7 @@ public class TextDocument implements IDocument { range.setEnd(toPosition(end)); return range; } - + /** * Determine the line-number a given offset (i.e. what line is the offset inside of?) */ @@ -200,7 +201,7 @@ public class TextDocument implements IDocument { } } } - + int len = end - start; if (len<0) { len = 0; @@ -222,7 +223,7 @@ public class TextDocument implements IDocument { public int getLineOffset(int line) { return lineStarts()[line]; } - + public int toOffset(Position position) { int line = position.getLine(); int lineStart = lineStarts()[line]; @@ -243,4 +244,9 @@ public class TextDocument implements IDocument { return get(start, end-start); } + @Override + public String toString() { + return "TextDocument(uri="+uri+",\n"+this.text+"\n)"; + } + } diff --git a/vscode-extensions/commons/language-server-commons/src/test/java/org/springframework/ide/vscode/commons/completion/DocumentEditsTest.java b/vscode-extensions/commons/language-server-commons/src/test/java/org/springframework/ide/vscode/commons/completion/DocumentEditsTest.java new file mode 100644 index 000000000..843a9a33a --- /dev/null +++ b/vscode-extensions/commons/language-server-commons/src/test/java/org/springframework/ide/vscode/commons/completion/DocumentEditsTest.java @@ -0,0 +1,192 @@ +/******************************************************************************* + * Copyright (c) 2015 Pivotal, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.completion; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.ide.vscode.testharness.Editor; +import org.springframework.ide.vscode.testharness.LanguageServerHarness; +import org.springframework.ide.vscode.util.IDocument; +import org.springframework.ide.vscode.util.IRegion; +import org.springframework.ide.vscode.util.TextDocument; +/** + * @author Kris De Volder + */ +public class DocumentEditsTest { + + private LanguageServerHarness harness; + + @Before + public void setup() throws Exception { + harness = new LanguageServerHarness(null); + } + + class TestSubject { + private Editor editor; + private DocumentEdits edits; + private String orgText; + + public TestSubject(String contents) throws Exception { + this.orgText = contents; + reset(); + } + + public void reset() throws Exception { + this.editor = harness.newEditor(orgText); + this.edits = new DocumentEdits(getFreshDocument(editor)); + } + + private IDocument getFreshDocument(Editor editor) throws Exception { + TextDocument doc = new TextDocument(null); + doc.setText(editor.getRawText()); + return doc; + } + + public void del(String snippet) { + int start = orgText.indexOf(snippet); + assertTrue(start>=0); + int end = start + snippet.length(); + edits.delete(start, end); + } + + public void expect(String expect) throws Exception { + apply(editor, edits); + assertEquals(expect, editor.getText()); + } + + private void apply(Editor editor, DocumentEdits edit) throws Exception { + IDocument document = getFreshDocument(editor); + edits.apply(document); + editor.setRawText(document.get()); + IRegion sel = edit.getSelection(); + int selectionStart = sel.getOffset(); + int selectionEnd = selectionStart+sel.getLength(); + editor.setSelection(selectionStart, selectionEnd); + } + + public void insBefore(String before, String insert) { + int offset = orgText.indexOf(before); + assertTrue(offset>=0); + edits.insert(offset, insert); + } + + public void delLineAt(String snippet) throws Exception { + int offset = orgText.indexOf(snippet); + assertTrue(offset>=0); + edits.deleteLineBackwardAtOffset(offset); + } + + public void delLine(int i) throws Exception { + edits.deleteLineBackward(0); + } + + } + + @Test public void testDeletes() throws Exception { + TestSubject it; + + it = new TestSubject("0123456789<*>"); + it.del("123"); + it.del("567"); + it.expect("04<*>89"); + + it = new TestSubject("0123456789<*>"); + it.del("567"); + it.del("123"); + it.expect("0<*>489"); + + it = new TestSubject("0123456789<*>"); + it.del("012345"); + it.del("345"); + it.expect("<*>6789"); + + it = new TestSubject("0123456789<*>"); + it.del("345"); + it.del("012345"); + it.expect("<*>6789"); + + it = new TestSubject("0123456789<*>"); + it.del("2345"); + it.del("34567"); + it.expect("01<*>89"); + + it = new TestSubject("0123456789<*>"); + it.del("123"); + it.del("234"); + it.del("7"); + it.expect("056<*>89"); + } + + @Test public void testInserts() throws Exception { + TestSubject it; + + it = new TestSubject("The fox jumps over the dog!"); + it.insBefore("fox", "quick "); + it.insBefore("fox", "brown "); + it.insBefore("dog", "lazy "); + it.expect("The quick brown fox jumps over the lazy <*>dog!"); + } + + @Test public void testInsertAndDelete() throws Exception { + TestSubject it; + + it = new TestSubject("The fox jumps over the dog!"); + + it.insBefore("fox", "quick "); //"The quick fox jumps..." + it.del("The fox"); //" jumps..." + it.insBefore("fox", "A rabbit");//"A rabbit jumps ..." + + it.expect("A rabbit<*> jumps over the dog!"); + } + + @Test public void testDeleteLine() throws Exception { + TestSubject it; + + it = new TestSubject( + "Line 0\n" + + "Line 1\n" + + "Line 2" + ); + + it.delLineAt("0"); + it.expect( + "<*>Line 1\n" + + "Line 2" + ); + + it.reset(); + it.delLineAt("1"); + it.expect( + "Line 0<*>\n" + + "Line 2" + ); + + it.reset(); + it.delLineAt("2"); + it.expect( + "Line 0\n" + + "Line 1<*>" + ); + + it = new TestSubject("Line 0"); //special case: no newlines in document + it.delLineAt("0"); + it.expect("<*>"); + + it = new TestSubject(""); + it.delLine(0); + it.expect("<*>"); + + } + +} diff --git a/vscode-extensions/commons/language-server-test-harness/.settings/org.eclipse.jdt.ui.prefs b/vscode-extensions/commons/language-server-test-harness/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 000000000..68f26e829 --- /dev/null +++ b/vscode-extensions/commons/language-server-test-harness/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,59 @@ +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=true +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_methods=false +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_missing_override_annotations_interface_methods=true +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_functional_interfaces=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.correct_indentation=false +sp_cleanup.format_source_code=false +sp_cleanup.format_source_code_changes_only=false +sp_cleanup.insert_inferred_type_arguments=false +sp_cleanup.make_local_variable_final=true +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=true +sp_cleanup.make_type_abstract_if_missing_method=false +sp_cleanup.make_variable_declarations_final=false +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.on_save_use_additional_actions=true +sp_cleanup.organize_imports=false +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_redundant_type_arguments=false +sp_cleanup.remove_trailing_whitespaces=true +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_casts=true +sp_cleanup.remove_unnecessary_nls_tags=false +sp_cleanup.remove_unused_imports=false +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.use_anonymous_class_creation=false +sp_cleanup.use_blocks=false +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_lambda=true +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_this_for_non_static_field_access=false +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/vscode-extensions/commons/language-server-test-harness/pom.xml b/vscode-extensions/commons/language-server-test-harness/pom.xml index d10989b19..8e33e6f6b 100644 --- a/vscode-extensions/commons/language-server-test-harness/pom.xml +++ b/vscode-extensions/commons/language-server-test-harness/pom.xml @@ -13,10 +13,21 @@ + - org.springframework.ide.vscode - language-server-commons - ${project.version} + io.typefox.lsapi + io.typefox.lsapi + ${lsapi-version} + + + io.typefox.lsapi + io.typefox.lsapi.services + ${lsapi-version} + + + io.typefox.lsapi + io.typefox.lsapi.annotations + ${lsapi-version} junit diff --git a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/Editor.java b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/Editor.java index de5835953..55e030de3 100644 --- a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/Editor.java +++ b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/Editor.java @@ -10,6 +10,8 @@ import java.util.List; import javax.swing.text.BadLocationException; +import org.junit.Assert; + import com.google.common.base.Strings; import io.typefox.lsapi.CompletionItem; @@ -21,12 +23,12 @@ import io.typefox.lsapi.Range; import io.typefox.lsapi.TextEdit; public class Editor { - + static class EditorState { String documentContents; int selectionStart; int selectionEnd; - + public EditorState(String text) { selectionStart = text.indexOf(CURSOR); if (selectionStart>=0) { @@ -45,10 +47,10 @@ public class Editor { this.documentContents = text; } } - + private static final String CURSOR = "<*>"; // used by our test harness private static final String VS_CODE_CURSOR_MARKER = "{{}}"; //vscode uses this in edits to mark cursor position - + private static final Comparator PROBLEM_COMPARATOR = new Comparator() { @Override public int compare(Diagnostic o1, Diagnostic o2) { @@ -123,7 +125,7 @@ public class Editor { } return buf.toString(); } - + /** * Get the editor text, with cursor markers inserted (for easy textual comparison * after applying a proposal) @@ -136,7 +138,7 @@ public class Editor { } return deWindowsify(text); } - + public void setText(String content) throws Exception { EditorState state = new EditorState(content); document = harness.changeDocument(document.getUri(), state.documentContents); @@ -144,6 +146,13 @@ public class Editor { this.selectionEnd = state.selectionEnd; } + /** + * @return The 'raw' text in the editor, i.e. without the cursor markers. + */ + public String getRawText() throws Exception { + return document.getText(); + } + public void setRawText(String newContent) throws Exception { document = harness.changeDocument(document.getUri(), newContent); } @@ -164,7 +173,7 @@ public class Editor { String messageSnippet = parts[1]; boolean spaceSensitive = badSnippet.trim().length()=0); + Assert.assertTrue(end>=start); + Assert.assertTrue(end<=document.getText().length()); + this.selectionStart = start; + this.selectionEnd = end; + } + + @Override + public String toString() { + return "Editor(\n"+getText()+"\n)"; + } + } diff --git a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/LanguageServerHarness.java b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/LanguageServerHarness.java index f5b93f752..39f31ea73 100644 --- a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/LanguageServerHarness.java +++ b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/LanguageServerHarness.java @@ -44,7 +44,7 @@ public class LanguageServerHarness { private LanguageServer server; private InitializeResult initResult; - + private Map documents = new HashMap<>(); private Map diagnostics = new HashMap<>(); @@ -71,7 +71,7 @@ public class LanguageServerHarness { document.setLanguageId(getLanguageId()); return new TextDocumentInfo(document); } - + private synchronized TextDocumentItemImpl setDocumentContent(String uri, String newContent) { TextDocumentInfo o = documents.get(uri); TextDocumentItemImpl n = new TextDocumentItemImpl(); @@ -90,11 +90,11 @@ public class LanguageServerHarness { protected String getLanguageId() { return "plaintext"; } - + protected String getFileExtension() { return ".txt"; } - + private synchronized void receiveDiagnostics(PublishDiagnosticsParams diags) { this.diagnostics.put(diags.getUri(), diags); } @@ -108,7 +108,7 @@ public class LanguageServerHarness { ClientCapabilitiesImpl clientCap = new ClientCapabilitiesImpl(); initParams.setCapabilities(clientCap); initResult = server.initialize(initParams).get(); - + server.getTextDocumentService().onPublishDiagnostics(this::receiveDiagnostics); return initResult; } @@ -118,10 +118,12 @@ public class LanguageServerHarness { didOpen.setTextDocument(documentInfo.getDocument()); didOpen.setText(documentInfo.getText()); didOpen.setUri(documentInfo.getUri()); - server.getTextDocumentService().didOpen(didOpen); + if (server!=null) { + server.getTextDocumentService().didOpen(didOpen); + } return documentInfo; } - + public TextDocumentInfo openDocument(File file) throws Exception { return openDocument(getOrReadFile(file)); } @@ -146,31 +148,38 @@ public class LanguageServerHarness { default: throw new IllegalStateException("Unkown SYNC mode: "+getDocumentSyncMode()); } - server.getTextDocumentService().didChange(didChange); + if (server!=null) { + server.getTextDocumentService().didChange(didChange); + } return documents.get(uri); } private TextDocumentSyncKind getDocumentSyncMode() { - TextDocumentSyncKind mode = initResult.getCapabilities().getTextDocumentSync(); - return mode==null ? TextDocumentSyncKind.None : mode; + if (initResult!=null) { + TextDocumentSyncKind mode = initResult.getCapabilities().getTextDocumentSync(); + if (mode!=null) { + return mode; + } + } + return TextDocumentSyncKind.None; } public PublishDiagnosticsParams getDiagnostics(TextDocumentInfo doc) { return diagnostics.get(doc.getUri()); } - + public static Condition isDiagnosticWithSeverity(DiagnosticSeverity severity) { return new Condition<>( (d) -> d.getSeverity()==severity, "Diagnostic with severity '"+severity+"'" - ); + ); } public static Condition isDiagnosticCovering(TextDocumentInfo doc, String string) { return new Condition<>( (d) -> isDiagnosticCovering(d, doc, string), "Diagnostic covering '"+string+"'" - ); + ); } public static final Condition isWarning = isDiagnosticWithSeverity(DiagnosticSeverity.Warning); @@ -185,7 +194,7 @@ public class LanguageServerHarness { return new Condition<>( (d) -> d.getRange().getStart().getLine()==line, "Diagnostic on line "+line - ); + ); } public CompletionList getCompletions(TextDocumentInfo doc, Position cursor) throws Exception { @@ -213,7 +222,7 @@ public class LanguageServerHarness { throw new RuntimeException(e); } } - + public List resolveCompletions(CompletionList completions) { return completions.getItems().stream() .map(this::resolveCompletionItem) diff --git a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/TextDocumentInfo.java b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/TextDocumentInfo.java index c21aa5e94..3c3b226d2 100644 --- a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/TextDocumentInfo.java +++ b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/TextDocumentInfo.java @@ -11,12 +11,16 @@ import io.typefox.lsapi.impl.PositionImpl; import io.typefox.lsapi.impl.TextDocumentIdentifierImpl; import io.typefox.lsapi.impl.TextDocumentItemImpl; +/** + * Deprecated, we should get rid of this class and use {@link TextDocument}. + */ +@Deprecated public class TextDocumentInfo { Pattern NEWLINE = Pattern.compile("\\r|\\n|\\r\\n|\\n\\r"); - + private final TextDocumentItemImpl document; - + private int[] _lineStarts; public TextDocumentInfo(TextDocumentItemImpl document) { @@ -83,7 +87,7 @@ public class TextDocumentInfo { /** * Find and return the (first) position of a given text snippet in the * document. - * + * * @return The position, or null if the snippet can't be found. */ public Position positionOf(String snippet) { @@ -126,5 +130,5 @@ public class TextDocumentInfo { id.setUri(getUri()); return id; } - + } diff --git a/vscode-extensions/commons/pom.xml b/vscode-extensions/commons/pom.xml index 27739a9be..a332aa641 100644 --- a/vscode-extensions/commons/pom.xml +++ b/vscode-extensions/commons/pom.xml @@ -23,6 +23,9 @@ 3.5.2 1.7.21 19.0 + 2.5.0 + 2.10 + 0.3.0 diff --git a/vscode-extensions/pom.xml b/vscode-extensions/pom.xml new file mode 100644 index 000000000..c71425479 --- /dev/null +++ b/vscode-extensions/pom.xml @@ -0,0 +1,18 @@ + + 4.0.0 + + org.springframework.ide.vscode + aggregator + pom + 0.0.1-SNAPSHOT + aggregator + + + commons + vscode-application-properties + vscode-application-yaml + vscode-manifest-yaml + + diff --git a/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/boot/properties/ApplicationPropertiesLanguageServer.java b/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/boot/properties/ApplicationPropertiesLanguageServer.java index 4dd9c9fae..304e3085a 100644 --- a/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/boot/properties/ApplicationPropertiesLanguageServer.java +++ b/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/boot/properties/ApplicationPropertiesLanguageServer.java @@ -20,9 +20,11 @@ import org.springframework.ide.vscode.util.SimpleTextDocumentService; import org.springframework.ide.vscode.util.TextDocument; import io.typefox.lsapi.Diagnostic; -import io.typefox.lsapi.DiagnosticImpl; +import io.typefox.lsapi.DiagnosticSeverity; import io.typefox.lsapi.ServerCapabilities; -import io.typefox.lsapi.ServerCapabilitiesImpl; +import io.typefox.lsapi.TextDocumentSyncKind; +import io.typefox.lsapi.impl.DiagnosticImpl; +import io.typefox.lsapi.impl.ServerCapabilitiesImpl; /** * Language Server for Spring Boot Application Properties files @@ -57,7 +59,7 @@ public class ApplicationPropertiesLanguageServer extends SimpleLanguageServer { DiagnosticImpl diagnostic = new DiagnosticImpl(); diagnostic.setMessage(createSyntaxErrorMessage(problem.getMessage())); diagnostic.setCode(problem.getCode()); - diagnostic.setSeverity(Diagnostic.SEVERITY_ERROR); + diagnostic.setSeverity(DiagnosticSeverity.Error); diagnostic.setSource("java-properties"); diagnostic.setRange(doc.toRange(problem.getOffset(), problem.getLength())); return diagnostic; @@ -78,7 +80,7 @@ public class ApplicationPropertiesLanguageServer extends SimpleLanguageServer { protected ServerCapabilitiesImpl getServerCapabilities() { ServerCapabilitiesImpl c = new ServerCapabilitiesImpl(); - c.setTextDocumentSync(ServerCapabilities.SYNC_FULL); + c.setTextDocumentSync(TextDocumentSyncKind.Full); return c; } diff --git a/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/boot/properties/Main.java b/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/boot/properties/Main.java index 4662c3d13..4aee322ca 100644 --- a/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/boot/properties/Main.java +++ b/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/boot/properties/Main.java @@ -135,11 +135,6 @@ public class Main { server.onError(message, err); }); - - try { - jsonServer.join(); - } catch (InterruptedException | ExecutionException e) { - throw new RuntimeException(e); - } + jsonServer.join(); } } diff --git a/vscode-extensions/vscode-application-properties/src/test/java/org/springframework/ide/vscode/boot/properties/test/ApplicationPropertiesLanguageServerTest.java b/vscode-extensions/vscode-application-properties/src/test/java/org/springframework/ide/vscode/boot/properties/test/ApplicationPropertiesLanguageServerTest.java index d9dedd35a..3b205f1fa 100644 --- a/vscode-extensions/vscode-application-properties/src/test/java/org/springframework/ide/vscode/boot/properties/test/ApplicationPropertiesLanguageServerTest.java +++ b/vscode-extensions/vscode-application-properties/src/test/java/org/springframework/ide/vscode/boot/properties/test/ApplicationPropertiesLanguageServerTest.java @@ -22,6 +22,7 @@ import org.springframework.ide.vscode.testharness.LanguageServerHarness; import io.typefox.lsapi.InitializeResult; import io.typefox.lsapi.ServerCapabilities; +import io.typefox.lsapi.TextDocumentSyncKind; /** * Boot app properties file language server tests @@ -50,7 +51,7 @@ public class ApplicationPropertiesLanguageServerTest { } private void assertExpectedInitResult(InitializeResult initResult) { - assertThat(initResult.getCapabilities().getTextDocumentSync()).isEqualTo(ServerCapabilities.SYNC_FULL); + assertThat(initResult.getCapabilities().getTextDocumentSync()).isEqualTo(TextDocumentSyncKind.Full); } } diff --git a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/Main.java b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/Main.java index db9b7a4c5..aceccb3ed 100644 --- a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/Main.java +++ b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/Main.java @@ -92,7 +92,7 @@ public class Main { try { jsonServer.join(); - } catch (InterruptedException | ExecutionException e) { + } catch (Exception e) { throw new RuntimeException(e); } } diff --git a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/YamlLanguageServer.java b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/YamlLanguageServer.java index 558b307c0..ff3a06964 100644 --- a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/YamlLanguageServer.java +++ b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/YamlLanguageServer.java @@ -18,16 +18,19 @@ import org.yaml.snakeyaml.nodes.Node; import com.google.common.collect.ImmutableList; import io.typefox.lsapi.CompletionItem; -import io.typefox.lsapi.CompletionItemImpl; +import io.typefox.lsapi.CompletionItemKind; import io.typefox.lsapi.CompletionList; -import io.typefox.lsapi.CompletionListImpl; -import io.typefox.lsapi.CompletionOptionsImpl; import io.typefox.lsapi.Diagnostic; -import io.typefox.lsapi.DiagnosticImpl; -import io.typefox.lsapi.PositionImpl; -import io.typefox.lsapi.RangeImpl; +import io.typefox.lsapi.DiagnosticSeverity; import io.typefox.lsapi.ServerCapabilities; -import io.typefox.lsapi.ServerCapabilitiesImpl; +import io.typefox.lsapi.TextDocumentSyncKind; +import io.typefox.lsapi.impl.CompletionItemImpl; +import io.typefox.lsapi.impl.CompletionListImpl; +import io.typefox.lsapi.impl.CompletionOptionsImpl; +import io.typefox.lsapi.impl.DiagnosticImpl; +import io.typefox.lsapi.impl.PositionImpl; +import io.typefox.lsapi.impl.RangeImpl; +import io.typefox.lsapi.impl.ServerCapabilitiesImpl; public class YamlLanguageServer extends SimpleLanguageServer { @@ -66,7 +69,7 @@ public class YamlLanguageServer extends SimpleLanguageServer { // }, CompletionItemImpl item = new CompletionItemImpl(); item.setLabel("TypeScript"); - item.setKind(CompletionItem.KIND_TEXT); + item.setKind(CompletionItemKind.Text); item.setData(1); items.add(item); } @@ -79,7 +82,7 @@ public class YamlLanguageServer extends SimpleLanguageServer { // } CompletionItemImpl item = new CompletionItemImpl(); item.setLabel("JavaScript"); - item.setKind(CompletionItem.KIND_TEXT); + item.setKind(CompletionItemKind.Text); item.setData(2); items.add(item); } @@ -124,7 +127,7 @@ public class YamlLanguageServer extends SimpleLanguageServer { DiagnosticImpl d = new DiagnosticImpl(); d.setMessage(getMessage(e)); d.setRange(getRange(e)); - d.setSeverity(Diagnostic.SEVERITY_ERROR); + d.setSeverity(DiagnosticSeverity.Error); d.setCode(ErrorCodes.YAML_SYNTAX_ERROR); d.setSource("yaml"); return d; @@ -157,7 +160,7 @@ public class YamlLanguageServer extends SimpleLanguageServer { protected ServerCapabilitiesImpl getServerCapabilities() { ServerCapabilitiesImpl c = new ServerCapabilitiesImpl(); - c.setTextDocumentSync(ServerCapabilities.SYNC_FULL); + c.setTextDocumentSync(TextDocumentSyncKind.Full); CompletionOptionsImpl completionProvider = new CompletionOptionsImpl(); completionProvider.setResolveProvider(true); diff --git a/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/YamlLanguageServerTest.java b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/YamlLanguageServerTest.java index 038ae3fc0..bf65645f9 100644 --- a/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/YamlLanguageServerTest.java +++ b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/YamlLanguageServerTest.java @@ -16,6 +16,7 @@ import io.typefox.lsapi.CompletionItem; import io.typefox.lsapi.CompletionList; import io.typefox.lsapi.InitializeResult; import io.typefox.lsapi.ServerCapabilities; +import io.typefox.lsapi.TextDocumentSyncKind; public class YamlLanguageServerTest { @@ -68,7 +69,7 @@ public class YamlLanguageServerTest { private void assertExpectedInitResult(InitializeResult initResult) { assertThat(initResult.getCapabilities().getCompletionProvider().getResolveProvider()).isTrue(); - assertThat(initResult.getCapabilities().getTextDocumentSync()).isEqualTo(ServerCapabilities.SYNC_FULL); + assertThat(initResult.getCapabilities().getTextDocumentSync()).isEqualTo(TextDocumentSyncKind.Full); } }