Use WorkspaceEdit for ssr

This commit is contained in:
Aleksey Kladov 2020-05-22 00:28:49 +02:00
parent 59732df8d4
commit 5ef4ebff20
6 changed files with 43 additions and 9 deletions

View file

@ -94,6 +94,7 @@ pub fn server_capabilities() -> ServerCapabilities {
), ),
experimental: Some(json!({ experimental: Some(json!({
"joinLines": true, "joinLines": true,
"ssr": true,
})), })),
} }
} }

View file

@ -173,8 +173,8 @@ pub enum Ssr {}
impl Request for Ssr { impl Request for Ssr {
type Params = SsrParams; type Params = SsrParams;
type Result = SourceChange; type Result = lsp_types::WorkspaceEdit;
const METHOD: &'static str = "rust-analyzer/ssr"; const METHOD: &'static str = "experimental/ssr";
} }
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize)]

View file

@ -986,11 +986,11 @@ pub fn handle_document_highlight(
pub fn handle_ssr( pub fn handle_ssr(
world: WorldSnapshot, world: WorldSnapshot,
params: lsp_ext::SsrParams, params: lsp_ext::SsrParams,
) -> Result<lsp_ext::SourceChange> { ) -> Result<lsp_types::WorkspaceEdit> {
let _p = profile("handle_ssr"); let _p = profile("handle_ssr");
let source_change = let source_change =
world.analysis().structural_search_replace(&params.query, params.parse_only)??; world.analysis().structural_search_replace(&params.query, params.parse_only)??;
to_proto::source_change(&world, source_change) to_proto::workspace_edit(&world, source_change)
} }
pub fn publish_diagnostics(world: &WorldSnapshot, file_id: FileId) -> Result<DiagnosticTask> { pub fn publish_diagnostics(world: &WorldSnapshot, file_id: FileId) -> Result<DiagnosticTask> {

View file

@ -84,3 +84,38 @@ fn main() {
* What is the position of the cursor after `joinLines`? * What is the position of the cursor after `joinLines`?
Currently this is left to editor's discretion, but it might be useful to specify on the server via snippets. Currently this is left to editor's discretion, but it might be useful to specify on the server via snippets.
However, it then becomes unclear how it works with multi cursor. However, it then becomes unclear how it works with multi cursor.
## Structural Search Replace (SSR)
**Server Capability:** `{ "ssr": boolean }`
This request is send from client to server to handle structural search replace -- automated syntax tree based transformation of the source.
**Method:** `experimental/ssr`
**Request:**
```typescript
interface SsrParams {
/// Search query.
/// The specific syntax is specified outside of the protocol.
query: string,
/// If true, only check the syntax of the query and don't compute the actual edit.
parseOnly: bool,
}
```
**Response:**
```typescript
WorkspaceEdit
```
### Example
SSR with query `foo($a:expr, $b:expr) ==>> ($a).foo($b)` will transform, eg `foo(y + 5, z)` into `(y + 5).foo(z)`.
### Unresolved Question
* Probably needs search without replace mode
* Needs a way to limit the scope to certain files.

View file

@ -2,7 +2,6 @@ import * as vscode from 'vscode';
import * as ra from "../rust-analyzer-api"; import * as ra from "../rust-analyzer-api";
import { Ctx, Cmd } from '../ctx'; import { Ctx, Cmd } from '../ctx';
import { applySourceChange } from '../source_change';
export function ssr(ctx: Ctx): Cmd { export function ssr(ctx: Ctx): Cmd {
return async () => { return async () => {
@ -22,11 +21,10 @@ export function ssr(ctx: Ctx): Cmd {
} }
}; };
const request = await vscode.window.showInputBox(options); const request = await vscode.window.showInputBox(options);
if (!request) return; if (!request) return;
const change = await client.sendRequest(ra.ssr, { query: request, parseOnly: false }); const edit = await client.sendRequest(ra.ssr, { query: request, parseOnly: false });
await applySourceChange(ctx, change); await vscode.workspace.applyEdit(client.protocol2CodeConverter.asWorkspaceEdit(edit));
}; };
} }

View file

@ -112,7 +112,7 @@ export interface SsrParams {
query: string; query: string;
parseOnly: boolean; parseOnly: boolean;
} }
export const ssr = request<SsrParams, SourceChange>("ssr"); export const ssr = new lc.RequestType<SsrParams, lc.WorkspaceEdit, unknown>('experimental/ssr');
export const publishDecorations = notification<PublishDecorationsParams>("publishDecorations"); export const publishDecorations = notification<PublishDecorationsParams>("publishDecorations");