summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/lsp/language_server.rs62
-rw-r--r--cli/lsp/tsc.rs5
-rw-r--r--cli/tests/lsp/completion_request_optional.json18
-rw-r--r--cli/tests/lsp/completion_resolve_request_optional.json20
-rw-r--r--cli/tests/lsp/did_open_notification_completion_optional.json12
5 files changed, 115 insertions, 2 deletions
diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs
index 74dcf2136..b55c38189 100644
--- a/cli/lsp/language_server.rs
+++ b/cli/lsp/language_server.rs
@@ -3025,6 +3025,68 @@ mod tests {
harness.run().await;
}
+ #[tokio::test]
+ async fn test_completions_optional() {
+ let mut harness = LspTestHarness::new(vec![
+ ("initialize_request.json", LspResponse::RequestAny),
+ ("initialized_notification.json", LspResponse::None),
+ (
+ "did_open_notification_completion_optional.json",
+ LspResponse::None,
+ ),
+ (
+ "completion_request_optional.json",
+ LspResponse::Request(
+ 2,
+ json!({
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "b?",
+ "kind": 5,
+ "sortText": "1",
+ "filterText": "b",
+ "insertText": "b",
+ "data": {
+ "tsc": {
+ "specifier": "file:///a/file.ts",
+ "position": 79,
+ "name": "b",
+ "useCodeSnippet": false
+ }
+ }
+ }
+ ]
+ }),
+ ),
+ ),
+ (
+ "completion_resolve_request_optional.json",
+ LspResponse::Request(
+ 4,
+ json!({
+ "label": "b?",
+ "kind": 5,
+ "detail": "(property) A.b?: string | undefined",
+ "documentation": {
+ "kind": "markdown",
+ "value": ""
+ },
+ "sortText": "1",
+ "filterText": "b",
+ "insertText": "b"
+ }),
+ ),
+ ),
+ (
+ "shutdown_request.json",
+ LspResponse::Request(3, json!(null)),
+ ),
+ ("exit_notification.json", LspResponse::None),
+ ]);
+ harness.run().await;
+ }
+
#[derive(Deserialize)]
struct PerformanceAverages {
averages: Vec<PerformanceAverage>,
diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs
index 1e7ae6f89..7b7f791d0 100644
--- a/cli/lsp/tsc.rs
+++ b/cli/lsp/tsc.rs
@@ -1188,10 +1188,10 @@ impl CompletionEntry {
}
let text_edit =
- if let (Some(text_span), Some(new_text)) = (range, insert_text) {
+ if let (Some(text_span), Some(new_text)) = (range, &insert_text) {
let range = text_span.to_range(line_index);
let insert_replace_edit = lsp::InsertReplaceEdit {
- new_text,
+ new_text: new_text.clone(),
insert: range,
replace: range,
};
@@ -1216,6 +1216,7 @@ impl CompletionEntry {
preselect,
text_edit,
filter_text,
+ insert_text,
detail,
tags,
data: Some(json!({
diff --git a/cli/tests/lsp/completion_request_optional.json b/cli/tests/lsp/completion_request_optional.json
new file mode 100644
index 000000000..5e86c33ff
--- /dev/null
+++ b/cli/tests/lsp/completion_request_optional.json
@@ -0,0 +1,18 @@
+{
+ "jsonrpc": "2.0",
+ "id": 2,
+ "method": "textDocument/completion",
+ "params": {
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ },
+ "position": {
+ "line": 8,
+ "character": 4
+ },
+ "context": {
+ "triggerKind": 2,
+ "triggerCharacter": "."
+ }
+ }
+}
diff --git a/cli/tests/lsp/completion_resolve_request_optional.json b/cli/tests/lsp/completion_resolve_request_optional.json
new file mode 100644
index 000000000..ffa60b919
--- /dev/null
+++ b/cli/tests/lsp/completion_resolve_request_optional.json
@@ -0,0 +1,20 @@
+{
+ "jsonrpc": "2.0",
+ "id": 4,
+ "method": "completionItem/resolve",
+ "params": {
+ "label": "b?",
+ "kind": 5,
+ "sortText": "1",
+ "filterText": "b",
+ "insertText": "b",
+ "data": {
+ "tsc": {
+ "specifier": "file:///a/file.ts",
+ "position": 79,
+ "name": "b",
+ "useCodeSnippet": false
+ }
+ }
+ }
+}
diff --git a/cli/tests/lsp/did_open_notification_completion_optional.json b/cli/tests/lsp/did_open_notification_completion_optional.json
new file mode 100644
index 000000000..5e919c80a
--- /dev/null
+++ b/cli/tests/lsp/did_open_notification_completion_optional.json
@@ -0,0 +1,12 @@
+{
+ "jsonrpc": "2.0",
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "interface A {\n b?: string;\n}\n\nconst o: A = {};\n\nfunction c(s: string) {}\n\nc(o.)"
+ }
+ }
+}