Open alexheretic opened 6 years ago
This one blocks https://github.com/eclipse/corrosion/issues/268
Are there any plans to implement children
in documentSymbol
, in this fashion? https://github.com/palantir/python-language-server/pull/537
https://microsoft.github.io/language-server-protocol/specification#textDocument_documentSymbol
/**
* Children of this symbol, e.g. properties of a class.
*/
children?: DocumentSymbol[];
/**
* The name of the symbol containing this symbol. This information is for
* user interface purposes (e.g. to render a qualifier in the user interface
* if necessary). It can't be used to re-infer a hierarchy for the document
* symbols.
*/
containerName?: string;
Yes, we definitely plan to implement that! Last time I looked into this it was (somewhat) blocked on https://github.com/rust-lang/rls/issues/1377
We should provide textDocument/documentSymbol outlines that allow showing the symbols in a tree.
Pulled out my comment from #86 into it's own issue as I guess its a larger thing.
Current Status
textDocument/documentSymbol response
```json [{ "name": "", "kind": 2, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 1, "character": 0 }, "end": { "line": 58, "character": 1 } } }, "containerName": null }, { "name": "stuff", "kind": 2, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 7, "character": 4 }, "end": { "line": 7, "character": 9 } } }, "containerName": "" }, { "name": "speaks", "kind": 2, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 8, "character": 8 }, "end": { "line": 8, "character": 14 } } }, "containerName": "stuff" }, { "name": "Speaks", "kind": 11, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 9, "character": 18 }, "end": { "line": 9, "character": 24 } } }, "containerName": "speaks" }, { "name": "speak", "kind": 6, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 10, "character": 15 }, "end": { "line": 10, "character": 20 } } }, "containerName": "Speaks" }, { "name": "NUM_A", "kind": 14, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 14, "character": 10 }, "end": { "line": 14, "character": 15 } } }, "containerName": "stuff" }, { "name": "Temp", "kind": 5, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 18, "character": 11 }, "end": { "line": 18, "character": 15 } } }, "containerName": "stuff" }, { "name": "field", "kind": 8, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 19, "character": 8 }, "end": { "line": 19, "character": 13 } } }, "containerName": "Temp" }, { "name": "Another", "kind": 5, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 21, "character": 11 }, "end": { "line": 21, "character": 18 } } }, "containerName": "stuff" }, { "name": "AnEnum", "kind": 10, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 23, "character": 20 }, "end": { "line": 23, "character": 26 } } }, "containerName": "stuff" }, { "name": "One", "kind": 8, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 24, "character": 8 }, "end": { "line": 24, "character": 11 } } }, "containerName": "AnEnum" }, { "name": "Two", "kind": 8, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 25, "character": 8 }, "end": { "line": 25, "character": 11 } } }, "containerName": "AnEnum" }, { "name": "name", "kind": 8, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 25, "character": 14 }, "end": { "line": 25, "character": 18 } } }, "containerName": "Two" }, { "name": "Three", "kind": 8, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 26, "character": 8 }, "end": { "line": 26, "character": 13 } } }, "containerName": "AnEnum" }, { "name": "something", "kind": 6, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 29, "character": 11 }, "end": { "line": 29, "character": 20 } } }, "containerName": null }, { "name": "speak", "kind": 6, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 34, "character": 11 }, "end": { "line": 34, "character": 16 } } }, "containerName": "Speaks" }, { "name": "self", "kind": 13, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 34, "character": 18 }, "end": { "line": 34, "character": 22 } } }, "containerName": null }, { "name": "speak", "kind": 6, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 39, "character": 11 }, "end": { "line": 39, "character": 16 } } }, "containerName": "Speaks" }, { "name": "self", "kind": 13, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 39, "character": 18 }, "end": { "line": 39, "character": 22 } } }, "containerName": null }, { "name": "fun1", "kind": 12, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 43, "character": 7 }, "end": { "line": 43, "character": 11 } } }, "containerName": "stuff" }, { "name": "fun2", "kind": 12, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 44, "character": 11 }, "end": { "line": 44, "character": 15 } } }, "containerName": null }, { "name": "m", "kind": 13, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 50, "character": 16 }, "end": { "line": 50, "character": 17 } } }, "containerName": null }, { "name": "main", "kind": 12, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 56, "character": 3 }, "end": { "line": 56, "character": 7 } } }, "containerName": "" }, { "name": "a", "kind": 13, "location": { "uri": "file:///home/alex/project/rusttmp/src/main.rs", "range": { "start": { "line": 57, "character": 8 }, "end": { "line": 57, "character": 9 } } }, "containerName": null }] ```So we can see that we _do_ already set `containerName` in a few cases. However, without nested location ranges atom can't construct the proper syntax tree outline & can't connect the `containerName` with the actual symbol `name`, so both appear separately. So it looks like we should make the following improvements, that may need enhancements to `rls-analysis`: - [ ] Construct test case using above example. - [ ] Extend all location end positions to the end of the owning scope _if applicable_. _So for example the `mod stuff` location should change from [7:4, 7:9] -> [7:4, **56:1**]_ - [ ] Add missing symbols, _ie `impl Temp`_ _(probably just use `Unknown` to describe this symbol kind)_ - [ ] Add missing `containerName`s, _ie `fn fun1() { fn fun2() {} }`_ - [ ] Once we have the symbol, rename `impl Speaks for Temp` _"Speaks"_ -> _"Speaks for Temp"_ (remove generics if they exist though?) - [ ] Make use of newer LSP symbol kinds _struct, etc_ - [ ] Minor: Remove empty string name symbols & `containerName`s Later enhancements: - [ ] Outlines for common macro declarations _`lazy_static!`, `thread_local!`, etc_
Test/example code
```rust #![allow(unused)] #[macro_use] extern crate lazy_static; use std::collections::HashMap; use std::sync::Arc; mod stuff { mod speaks { pub trait Speaks { fn speak(&self); } } use self::speaks::Speaks; const NUM_A: usize = 234; struct Temp { field: i32, } struct Another; pub(crate) enum AnEnum { One(u32, u32), Two { name: &'static str }, Three, } impl Temp { fn something() -> i32 { 1 } } impl Speaks for Temp { fn speak(&self) { eprintln!("hello"); } } impl Speaks for AnEnum { fn speak(&self) { eprintln!("hmmmm"); } } fn fun1() { fn fun2() {} } } lazy_static! { pub static ref MAP: HashMap