Skip to content

Commit

Permalink
Merge #4611
Browse files Browse the repository at this point in the history
4611: Document `parentModule` experimental LSP request r=matklad a=matklad



bors r+
🤖

Co-authored-by: Aleksey Kladov <[email protected]>
  • Loading branch information
bors[bot] and matklad authored May 25, 2020
2 parents 00172d0 + 50f1652 commit b04951d
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 38 deletions.
1 change: 1 addition & 0 deletions crates/rust-analyzer/src/caps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
"joinLines": true,
"ssr": true,
"onEnter": true,
"parentModule": true,
})),
}
}
Expand Down
6 changes: 3 additions & 3 deletions crates/rust-analyzer/src/lsp_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use std::{collections::HashMap, path::PathBuf};

use lsp_types::request::Request;
use lsp_types::{Location, Position, Range, TextDocumentIdentifier};
use lsp_types::{Position, Range, TextDocumentIdentifier};
use rustc_hash::FxHashMap;
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -79,8 +79,8 @@ pub enum ParentModule {}

impl Request for ParentModule {
type Params = lsp_types::TextDocumentPositionParams;
type Result = Vec<Location>;
const METHOD: &'static str = "rust-analyzer/parentModule";
type Result = Option<lsp_types::GotoDefinitionResponse>;
const METHOD: &'static str = "experimental/parentModule";
}

pub enum JoinLines {}
Expand Down
32 changes: 10 additions & 22 deletions crates/rust-analyzer/src/main_loop/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,11 +344,8 @@ pub fn handle_goto_definition(
None => return Ok(None),
Some(it) => it,
};
let res = to_proto::goto_definition_response(
&world,
FileRange { file_id: position.file_id, range: nav_info.range },
nav_info.info,
)?;
let src = FileRange { file_id: position.file_id, range: nav_info.range };
let res = to_proto::goto_definition_response(&world, Some(src), nav_info.info)?;
Ok(Some(res))
}

Expand All @@ -362,11 +359,8 @@ pub fn handle_goto_implementation(
None => return Ok(None),
Some(it) => it,
};
let res = to_proto::goto_definition_response(
&world,
FileRange { file_id: position.file_id, range: nav_info.range },
nav_info.info,
)?;
let src = FileRange { file_id: position.file_id, range: nav_info.range };
let res = to_proto::goto_definition_response(&world, Some(src), nav_info.info)?;
Ok(Some(res))
}

Expand All @@ -380,26 +374,20 @@ pub fn handle_goto_type_definition(
None => return Ok(None),
Some(it) => it,
};
let res = to_proto::goto_definition_response(
&world,
FileRange { file_id: position.file_id, range: nav_info.range },
nav_info.info,
)?;
let src = FileRange { file_id: position.file_id, range: nav_info.range };
let res = to_proto::goto_definition_response(&world, Some(src), nav_info.info)?;
Ok(Some(res))
}

pub fn handle_parent_module(
world: WorldSnapshot,
params: lsp_types::TextDocumentPositionParams,
) -> Result<Vec<Location>> {
) -> Result<Option<lsp_types::GotoDefinitionResponse>> {
let _p = profile("handle_parent_module");
let position = from_proto::file_position(&world, params)?;
world
.analysis()
.parent_module(position)?
.into_iter()
.map(|it| to_proto::location(&world, it.file_range()))
.collect::<Result<Vec<_>>>()
let navs = world.analysis().parent_module(position)?;
let res = to_proto::goto_definition_response(&world, None, navs)?;
Ok(Some(res))
}

pub fn handle_runnables(
Expand Down
15 changes: 11 additions & 4 deletions crates/rust-analyzer/src/to_proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,13 +403,20 @@ pub(crate) fn location(world: &WorldSnapshot, frange: FileRange) -> Result<lsp_t

pub(crate) fn location_link(
world: &WorldSnapshot,
src: FileRange,
src: Option<FileRange>,
target: NavigationTarget,
) -> Result<lsp_types::LocationLink> {
let src_location = location(world, src)?;
let origin_selection_range = match src {
Some(src) => {
let line_index = world.analysis().file_line_index(src.file_id)?;
let range = range(&line_index, src.range);
Some(range)
}
None => None,
};
let (target_uri, target_range, target_selection_range) = location_info(world, target)?;
let res = lsp_types::LocationLink {
origin_selection_range: Some(src_location.range),
origin_selection_range,
target_uri,
target_range,
target_selection_range,
Expand All @@ -432,7 +439,7 @@ fn location_info(

pub(crate) fn goto_definition_response(
world: &WorldSnapshot,
src: FileRange,
src: Option<FileRange>,
targets: Vec<NavigationTarget>,
) -> Result<lsp_types::GotoDefinitionResponse> {
if world.config.client_caps.location_link {
Expand Down
40 changes: 35 additions & 5 deletions docs/dev/lsp-extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,40 @@ Invoking code action at this position will yield two code actions for importing
* Is a fixed two-level structure enough?
* Should we devise a general way to encode custom interaction protocols for GUI refactorings?

## Parent Module

**Issue:** TBA

**Server Capability:** `{ "parentModule": boolean }`

This request is send from client to server to handle "Goto Parent Module" editor action.

**Method:** `experimental/parentModule`

**Request:** `TextDocumentPositionParams`

**Response:** `Location | Location[] | LocationLink[] | null`


### Example

```rust
// src/main.rs
mod foo;
// src/foo.rs

/* cursor here*/
```

`experimental/parentModule` returns a single `Link` to the `mod foo;` declaration.

### Unresolved Question

* An alternative would be to use a more general "gotoSuper" request, which would work for super methods, super classes and super modules.
This is the approach IntelliJ Rust is takeing.
However, experience shows that super module (which generally has a feeling of navigation between files) should be separate.
If you want super module, but the cursor happens to be inside an overriden function, the behavior with single "gotoSuper" request is surprising.

## Join Lines

**Issue:** https://github.com/microsoft/language-server-protocol/issues/992
Expand All @@ -108,11 +142,7 @@ interface JoinLinesParams {
}
```

**Response:**

```typescript
TextEdit[]
```
**Response:** `TextEdit[]`

### Example

Expand Down
6 changes: 3 additions & 3 deletions editors/code/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,10 @@ export function parentModule(ctx: Ctx): Cmd {
),
});
const loc = response[0];
if (loc == null) return;
if (!loc) return;

const uri = client.protocol2CodeConverter.asUri(loc.uri);
const range = client.protocol2CodeConverter.asRange(loc.range);
const uri = client.protocol2CodeConverter.asUri(loc.targetUri);
const range = client.protocol2CodeConverter.asRange(loc.targetRange);

const doc = await vscode.workspace.openTextDocument(uri);
const e = await vscode.window.showTextDocument(doc);
Expand Down
2 changes: 1 addition & 1 deletion editors/code/src/lsp_ext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export interface MatchingBraceParams {
}
export const matchingBrace = new lc.RequestType<MatchingBraceParams, lc.Position[], void>("experimental/matchingBrace");

export const parentModule = new lc.RequestType<lc.TextDocumentPositionParams, lc.Location[], void>("rust-analyzer/parentModule");
export const parentModule = new lc.RequestType<lc.TextDocumentPositionParams, lc.LocationLink[], void>("experimental/parentModule");

export interface JoinLinesParams {
textDocument: lc.TextDocumentIdentifier;
Expand Down

0 comments on commit b04951d

Please sign in to comment.