From bd068778e503a6c92506c6b143b70911bfbef746 Mon Sep 17 00:00:00 2001 From: Amirali Esmaeili Date: Sat, 8 May 2021 05:21:45 +0430 Subject: [PATCH 1/2] Add rename provider --- server/src/server.ts | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/server/src/server.ts b/server/src/server.ts index db44c7309..5f3a79e02 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -20,7 +20,8 @@ import { assert } from "console"; import { fileURLToPath } from "url"; import { ChildProcess } from "child_process"; import { Location } from "vscode-languageserver"; -import { SymbolInformation } from "vscode-languageserver"; +import { SymbolInformation, WorkspaceEdit } from "vscode-languageserver"; +import { TextEdit } from "vscode-languageserver-types"; // https://microsoft.github.io/language-server-protocol/specification#initialize // According to the spec, there could be requests before the 'initialize' request. Link in comment tells how to handle them. @@ -307,6 +308,7 @@ function onMessage(msg: m.Message) { hoverProvider: true, definitionProvider: true, referencesProvider: true, + renameProvider: true, documentSymbolProvider: false, completionProvider: { triggerCharacters: [".", ">", "@", "~"] }, }, @@ -386,6 +388,44 @@ function onMessage(msg: m.Message) { // error: code and message set in case an exception happens during the definition request. }; send(definitionResponse); + } else if (msg.method === p.RenameRequest.method) { + // https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_rename + let params = msg.params as p.RenameParams; + let filePath = fileURLToPath(params.textDocument.uri); + let locations: Location[] | null = utils.runAnalysisAfterSanityCheck( + filePath, + [ + "references", + filePath, + params.position.line, + params.position.character, + ] + ); + + let result: WorkspaceEdit | null; + if (locations === null) { + result = null; + } else { + let changes: { [uri: string]: TextEdit[] } = {}; + locations.forEach(({ uri, range }) => { + let textEdit: TextEdit = {range, newText: params.newName}; + if (uri in changes) { + changes[uri].push(textEdit); + } else { + changes[uri] = [textEdit] + } + }); + + result = {changes}; + } + + let renameResponse: m.ResponseMessage = { + jsonrpc: c.jsonrpcVersion, + id: msg.id, + result, + }; + + send(renameResponse); } else if (msg.method === p.ReferencesRequest.method) { // https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references let params = msg.params as p.ReferenceParams; From 026d9a1342ddc8745693dc800ae86244adfa993b Mon Sep 17 00:00:00 2001 From: Amirali Esmaeili Date: Sat, 8 May 2021 14:36:09 +0430 Subject: [PATCH 2/2] Extract get references to a separate function --- server/src/server.ts | 24 +++--------------------- server/src/utils.ts | 3 +++ 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/server/src/server.ts b/server/src/server.ts index 5f3a79e02..c339e1d86 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -19,8 +19,7 @@ import * as chokidar from "chokidar"; import { assert } from "console"; import { fileURLToPath } from "url"; import { ChildProcess } from "child_process"; -import { Location } from "vscode-languageserver"; -import { SymbolInformation, WorkspaceEdit } from "vscode-languageserver"; +import { WorkspaceEdit } from "vscode-languageserver"; import { TextEdit } from "vscode-languageserver-types"; // https://microsoft.github.io/language-server-protocol/specification#initialize @@ -392,16 +391,7 @@ function onMessage(msg: m.Message) { // https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_rename let params = msg.params as p.RenameParams; let filePath = fileURLToPath(params.textDocument.uri); - let locations: Location[] | null = utils.runAnalysisAfterSanityCheck( - filePath, - [ - "references", - filePath, - params.position.line, - params.position.character, - ] - ); - + let locations: p.Location[] | null = utils.getReferencesForPosition(filePath, params.position); let result: WorkspaceEdit | null; if (locations === null) { result = null; @@ -430,15 +420,7 @@ function onMessage(msg: m.Message) { // https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references let params = msg.params as p.ReferenceParams; let filePath = fileURLToPath(params.textDocument.uri); - let result: typeof p.ReferencesRequest.type = utils.runAnalysisAfterSanityCheck( - filePath, - [ - "references", - filePath, - params.position.line, - params.position.character, - ] - ); + let result: typeof p.ReferencesRequest.type = utils.getReferencesForPosition(filePath, params.position); let definitionResponse: m.ResponseMessage = { jsonrpc: c.jsonrpcVersion, id: msg.id, diff --git a/server/src/utils.ts b/server/src/utils.ts index c657b1cb4..f1b59f353 100644 --- a/server/src/utils.ts +++ b/server/src/utils.ts @@ -144,6 +144,9 @@ export let runAnalysisAfterSanityCheck = ( return JSON.parse(stdout.toString()); }; +export let getReferencesForPosition = (filePath: p.DocumentUri, position: p.Position) => + runAnalysisAfterSanityCheck(filePath, ['references', filePath, position.line, position.character]); + export let replaceFileExtension = (filePath: string, ext: string): string => { let name = path.basename(filePath, path.extname(filePath)); return path.format({ dir: path.dirname(filePath), name, ext })