mirror of
https://github.com/denoland/deno.git
synced 2025-07-24 05:35:33 +00:00
feat(lsp): Implement textDocument/documentSymbol (#9981)
Co-authored-by: Kitson Kelly <me@kitsonkelly.com>
This commit is contained in:
parent
6d404ec54b
commit
2079da0f1c
5 changed files with 563 additions and 2 deletions
|
@ -718,6 +718,49 @@ impl Inner {
|
|||
self.performance.measure(mark);
|
||||
}
|
||||
|
||||
async fn document_symbol(
|
||||
&self,
|
||||
params: DocumentSymbolParams,
|
||||
) -> LspResult<Option<DocumentSymbolResponse>> {
|
||||
if !self.enabled() {
|
||||
return Ok(None);
|
||||
}
|
||||
let mark = self.performance.mark("selection_range");
|
||||
let specifier = self.url_map.normalize_url(¶ms.text_document.uri);
|
||||
|
||||
let line_index =
|
||||
if let Some(line_index) = self.get_line_index_sync(&specifier) {
|
||||
line_index
|
||||
} else {
|
||||
return Err(LspError::invalid_params(format!(
|
||||
"An unexpected specifier ({}) was provided.",
|
||||
specifier
|
||||
)));
|
||||
};
|
||||
|
||||
let req = tsc::RequestMethod::GetNavigationTree(specifier);
|
||||
let navigation_tree: tsc::NavigationTree = self
|
||||
.ts_server
|
||||
.request(self.snapshot(), req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Failed to request to tsserver {}", err);
|
||||
LspError::invalid_request()
|
||||
})?;
|
||||
|
||||
let response = if let Some(child_items) = navigation_tree.child_items {
|
||||
let mut document_symbols = Vec::<DocumentSymbol>::new();
|
||||
for item in child_items {
|
||||
item.collect_document_symbols(&line_index, &mut document_symbols);
|
||||
}
|
||||
Some(DocumentSymbolResponse::Nested(document_symbols))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.performance.measure(mark);
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
async fn formatting(
|
||||
&self,
|
||||
params: DocumentFormattingParams,
|
||||
|
@ -2165,6 +2208,13 @@ impl lspower::LanguageServer for LanguageServer {
|
|||
self.0.lock().await.did_change_watched_files(params).await
|
||||
}
|
||||
|
||||
async fn document_symbol(
|
||||
&self,
|
||||
params: DocumentSymbolParams,
|
||||
) -> LspResult<Option<DocumentSymbolResponse>> {
|
||||
self.0.lock().await.document_symbol(params).await
|
||||
}
|
||||
|
||||
async fn formatting(
|
||||
&self,
|
||||
params: DocumentFormattingParams,
|
||||
|
@ -3406,6 +3456,410 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_document_symbol() {
|
||||
let mut harness = LspTestHarness::new(vec![
|
||||
(
|
||||
LspFixture::Path("initialize_request.json"),
|
||||
LspResponse::RequestAny,
|
||||
),
|
||||
(
|
||||
LspFixture::Path("initialized_notification.json"),
|
||||
LspResponse::None,
|
||||
),
|
||||
(
|
||||
LspFixture::Path("document_symbol_did_open_notification.json"),
|
||||
LspResponse::None,
|
||||
),
|
||||
(
|
||||
LspFixture::Path("document_symbol_request.json"),
|
||||
LspResponse::Request(
|
||||
2,
|
||||
json!([
|
||||
{
|
||||
"name": "bar",
|
||||
"kind": 13,
|
||||
"range": {
|
||||
"start": {
|
||||
"line": 17,
|
||||
"character": 4
|
||||
},
|
||||
"end": {
|
||||
"line": 17,
|
||||
"character": 26
|
||||
}
|
||||
},
|
||||
"selectionRange": {
|
||||
"start": {
|
||||
"line": 17,
|
||||
"character": 4
|
||||
},
|
||||
"end": {
|
||||
"line": 17,
|
||||
"character": 7
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Bar",
|
||||
"kind": 5,
|
||||
"range": {
|
||||
"start": {
|
||||
"line": 4,
|
||||
"character": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 13,
|
||||
"character": 1
|
||||
}
|
||||
},
|
||||
"selectionRange": {
|
||||
"start": {
|
||||
"line": 4,
|
||||
"character": 6
|
||||
},
|
||||
"end": {
|
||||
"line": 4,
|
||||
"character": 9
|
||||
}
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"name": "constructor",
|
||||
"kind": 9,
|
||||
"range": {
|
||||
"start": {
|
||||
"line": 5,
|
||||
"character": 2
|
||||
},
|
||||
"end": {
|
||||
"line": 5,
|
||||
"character": 35
|
||||
}
|
||||
},
|
||||
"selectionRange": {
|
||||
"start": {
|
||||
"line": 5,
|
||||
"character": 2
|
||||
},
|
||||
"end": {
|
||||
"line": 5,
|
||||
"character": 35
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "baz",
|
||||
"kind": 6,
|
||||
"tags": [
|
||||
1
|
||||
],
|
||||
"range": {
|
||||
"start": {
|
||||
"line": 8,
|
||||
"character": 2
|
||||
},
|
||||
"end": {
|
||||
"line": 8,
|
||||
"character": 25
|
||||
}
|
||||
},
|
||||
"selectionRange": {
|
||||
"start": {
|
||||
"line": 8,
|
||||
"character": 2
|
||||
},
|
||||
"end": {
|
||||
"line": 8,
|
||||
"character": 5
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "foo",
|
||||
"kind": 6,
|
||||
"range": {
|
||||
"start": {
|
||||
"line": 6,
|
||||
"character": 2
|
||||
},
|
||||
"end": {
|
||||
"line": 6,
|
||||
"character": 24
|
||||
}
|
||||
},
|
||||
"selectionRange": {
|
||||
"start": {
|
||||
"line": 6,
|
||||
"character": 2
|
||||
},
|
||||
"end": {
|
||||
"line": 6,
|
||||
"character": 5
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "getStaticBar",
|
||||
"kind": 6,
|
||||
"range": {
|
||||
"start": {
|
||||
"line": 12,
|
||||
"character": 2
|
||||
},
|
||||
"end": {
|
||||
"line": 12,
|
||||
"character": 57
|
||||
}
|
||||
},
|
||||
"selectionRange": {
|
||||
"start": {
|
||||
"line": 12,
|
||||
"character": 17
|
||||
},
|
||||
"end": {
|
||||
"line": 12,
|
||||
"character": 29
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "staticBar",
|
||||
"kind": 7,
|
||||
"range": {
|
||||
"start": {
|
||||
"line": 11,
|
||||
"character": 2
|
||||
},
|
||||
"end": {
|
||||
"line": 11,
|
||||
"character": 32
|
||||
}
|
||||
},
|
||||
"selectionRange": {
|
||||
"start": {
|
||||
"line": 11,
|
||||
"character": 9
|
||||
},
|
||||
"end": {
|
||||
"line": 11,
|
||||
"character": 18
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"kind": 7,
|
||||
"range": {
|
||||
"start": {
|
||||
"line": 9,
|
||||
"character": 2
|
||||
},
|
||||
"end": {
|
||||
"line": 9,
|
||||
"character": 35
|
||||
}
|
||||
},
|
||||
"selectionRange": {
|
||||
"start": {
|
||||
"line": 9,
|
||||
"character": 6
|
||||
},
|
||||
"end": {
|
||||
"line": 9,
|
||||
"character": 11
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"kind": 7,
|
||||
"range": {
|
||||
"start": {
|
||||
"line": 10,
|
||||
"character": 2
|
||||
},
|
||||
"end": {
|
||||
"line": 10,
|
||||
"character": 42
|
||||
}
|
||||
},
|
||||
"selectionRange": {
|
||||
"start": {
|
||||
"line": 10,
|
||||
"character": 6
|
||||
},
|
||||
"end": {
|
||||
"line": 10,
|
||||
"character": 11
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "x",
|
||||
"kind": 7,
|
||||
"range": {
|
||||
"start": {
|
||||
"line": 5,
|
||||
"character": 14
|
||||
},
|
||||
"end": {
|
||||
"line": 5,
|
||||
"character": 30
|
||||
}
|
||||
},
|
||||
"selectionRange": {
|
||||
"start": {
|
||||
"line": 5,
|
||||
"character": 21
|
||||
},
|
||||
"end": {
|
||||
"line": 5,
|
||||
"character": 22
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "IFoo",
|
||||
"kind": 11,
|
||||
"range": {
|
||||
"start": {
|
||||
"line": 0,
|
||||
"character": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 2,
|
||||
"character": 1
|
||||
}
|
||||
},
|
||||
"selectionRange": {
|
||||
"start": {
|
||||
"line": 0,
|
||||
"character": 10
|
||||
},
|
||||
"end": {
|
||||
"line": 0,
|
||||
"character": 14
|
||||
}
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"name": "foo",
|
||||
"kind": 6,
|
||||
"range": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"character": 2
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"character": 17
|
||||
}
|
||||
},
|
||||
"selectionRange": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"character": 2
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"character": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Values",
|
||||
"kind": 10,
|
||||
"range": {
|
||||
"start": {
|
||||
"line": 15,
|
||||
"character": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 15,
|
||||
"character": 30
|
||||
}
|
||||
},
|
||||
"selectionRange": {
|
||||
"start": {
|
||||
"line": 15,
|
||||
"character": 5
|
||||
},
|
||||
"end": {
|
||||
"line": 15,
|
||||
"character": 11
|
||||
}
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"name": "value1",
|
||||
"kind": 13,
|
||||
"range": {
|
||||
"start": {
|
||||
"line": 15,
|
||||
"character": 14
|
||||
},
|
||||
"end": {
|
||||
"line": 15,
|
||||
"character": 20
|
||||
}
|
||||
},
|
||||
"selectionRange": {
|
||||
"start": {
|
||||
"line": 15,
|
||||
"character": 14
|
||||
},
|
||||
"end": {
|
||||
"line": 15,
|
||||
"character": 20
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "value2",
|
||||
"kind": 13,
|
||||
"range": {
|
||||
"start": {
|
||||
"line": 15,
|
||||
"character": 22
|
||||
},
|
||||
"end": {
|
||||
"line": 15,
|
||||
"character": 28
|
||||
}
|
||||
},
|
||||
"selectionRange": {
|
||||
"start": {
|
||||
"line": 15,
|
||||
"character": 22
|
||||
},
|
||||
"end": {
|
||||
"line": 15,
|
||||
"character": 28
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]),
|
||||
),
|
||||
),
|
||||
(
|
||||
LspFixture::Path("shutdown_request.json"),
|
||||
LspResponse::Request(3, json!(null)),
|
||||
),
|
||||
(
|
||||
LspFixture::Path("exit_notification.json"),
|
||||
LspResponse::None,
|
||||
),
|
||||
]);
|
||||
harness.run().await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_folding_range() {
|
||||
let mut harness = LspTestHarness::new(vec![
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue