From b970d675f5072e638ea4c2166e82ca5a580f6c50 Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Sat, 8 Aug 2020 19:18:56 +0900 Subject: Reverse document symbols for each scope (#5655) --- crates/rust-analyzer/src/handlers.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'crates') diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index 067259e24..9944757ad 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs @@ -273,19 +273,24 @@ pub(crate) fn handle_document_symbol( parents.push((doc_symbol, symbol.parent)); } let mut document_symbols = Vec::new(); + // Constructs `document_symbols` from `parents`, in order from the end. while let Some((node, parent)) = parents.pop() { match parent { None => document_symbols.push(node), Some(i) => { - let children = &mut parents[i].0.children; - if children.is_none() { - *children = Some(Vec::new()); - } - children.as_mut().unwrap().push(node); + parents[i].0.children.get_or_insert_with(Vec::new).push(node); } } } + fn reverse(symbols: &mut Vec) { + for sym in symbols.iter_mut() { + sym.children.as_mut().map(|c| reverse(c)); + } + symbols.reverse(); + } + reverse(&mut document_symbols); + let res = if snap.config.client_caps.hierarchical_symbols { document_symbols.into() } else { -- cgit v1.2.3 From cd49e41642c1e0bf2d22157914246d181a608c86 Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Sat, 8 Aug 2020 19:34:32 +0900 Subject: Add test for `handle_document_symbol` (#5655) --- crates/rust-analyzer/tests/heavy_tests/main.rs | 321 ++++++++++++++++++++++++- 1 file changed, 317 insertions(+), 4 deletions(-) (limited to 'crates') diff --git a/crates/rust-analyzer/tests/heavy_tests/main.rs b/crates/rust-analyzer/tests/heavy_tests/main.rs index 7370505f8..9a4655e4d 100644 --- a/crates/rust-analyzer/tests/heavy_tests/main.rs +++ b/crates/rust-analyzer/tests/heavy_tests/main.rs @@ -5,11 +5,14 @@ use std::{collections::HashMap, path::PathBuf, time::Instant}; use lsp_types::{ notification::DidOpenTextDocument, - request::{CodeActionRequest, Completion, Formatting, GotoTypeDefinition, HoverRequest}, + request::{ + CodeActionRequest, Completion, DocumentSymbolRequest, Formatting, GotoTypeDefinition, + HoverRequest, + }, CodeActionContext, CodeActionParams, CompletionParams, DidOpenTextDocumentParams, - DocumentFormattingParams, FormattingOptions, GotoDefinitionParams, HoverParams, - PartialResultParams, Position, Range, TextDocumentItem, TextDocumentPositionParams, - WorkDoneProgressParams, + DocumentFormattingParams, DocumentSymbolParams, FormattingOptions, GotoDefinitionParams, + HoverParams, PartialResultParams, Position, Range, TextDocumentItem, + TextDocumentPositionParams, WorkDoneProgressParams, }; use rust_analyzer::lsp_ext::{OnEnter, Runnables, RunnablesParams}; use serde_json::json; @@ -682,3 +685,313 @@ pub fn foo(_input: TokenStream) -> TokenStream { let value = res.get("contents").unwrap().get("value").unwrap().to_string(); assert_eq!(value, r#""```rust\nfoo::Bar\n```\n\n```rust\nfn bar()\n```""#) } + +#[test] +fn test_document_symbol_with_hierarchy() { + if skip_slow_tests() { + return; + } + + let server = Project::with_fixture( + r#" +//- /Cargo.toml +[package] +name = "foo" +version = "0.0.0" + +//- /src/lib.rs +mod a { + mod b { + struct B1; + fn b2() {} + } + struct A1; +} +"#, + ) + .with_config(|config| { + config.client_caps.hierarchical_symbols = true; + }) + .server(); + server.wait_until_workspace_is_loaded(); + + server.request::( + DocumentSymbolParams { + text_document: server.doc_id("src/lib.rs"), + work_done_progress_params: WorkDoneProgressParams::default(), + partial_result_params: PartialResultParams::default(), + }, + json!([ + { + "children": [ + { + "children": [ + { + "deprecated": false, + "kind": 23, + "name": "B1", + "range": { + "end": { + "character": 18, + "line": 2 + }, + "start": { + "character": 8, + "line": 2 + } + }, + "selectionRange": { + "end": { + "character": 17, + "line": 2 + }, + "start": { + "character": 15, + "line": 2 + } + }, + "tags": [] + }, + { + "deprecated": false, + "detail": "fn()", + "kind": 12, + "name": "b2", + "range": { + "end": { + "character": 18, + "line": 3 + }, + "start": { + "character": 8, + "line": 3 + } + }, + "selectionRange": { + "end": { + "character": 13, + "line": 3 + }, + "start": { + "character": 11, + "line": 3 + } + }, + "tags": [] + } + ], + "deprecated": false, + "kind": 2, + "name": "b", + "range": { + "end": { + "character": 5, + "line": 4 + }, + "start": { + "character": 4, + "line": 1 + } + }, + "selectionRange": { + "end": { + "character": 9, + "line": 1 + }, + "start": { + "character": 8, + "line": 1 + } + }, + "tags": [] + }, + { + "deprecated": false, + "kind": 23, + "name": "A1", + "range": { + "end": { + "character": 14, + "line": 5 + }, + "start": { + "character": 4, + "line": 5 + } + }, + "selectionRange": { + "end": { + "character": 13, + "line": 5 + }, + "start": { + "character": 11, + "line": 5 + } + }, + "tags": [] + } + ], + "deprecated": false, + "kind": 2, + "name": "a", + "range": { + "end": { + "character": 1, + "line": 6 + }, + "start": { + "character": 0, + "line": 0 + } + }, + "selectionRange": { + "end": { + "character": 5, + "line": 0 + }, + "start": { + "character": 4, + "line": 0 + } + }, + "tags": [] + } + ]), + ); +} + +#[test] +fn test_document_symbol_without_hierarchy() { + if skip_slow_tests() { + return; + } + + let server = project( + r#" +//- /Cargo.toml +[package] +name = "foo" +version = "0.0.0" + +//- /src/lib.rs +mod a { + mod b { + struct B1; + fn b2() {} + } + struct A1; +} +"#, + ); + server.wait_until_workspace_is_loaded(); + + server.request::( + DocumentSymbolParams { + text_document: server.doc_id("src/lib.rs"), + work_done_progress_params: WorkDoneProgressParams::default(), + partial_result_params: PartialResultParams::default(), + }, + json!([ + { + "deprecated": false, + "kind": 2, + "location": { + "range": { + "end": { + "character": 1, + "line": 6 + }, + "start": { + "character": 0, + "line": 0 + } + }, + "uri": "file:///[..]/src/lib.rs" + }, + "name": "a", + "tags": [] + }, + { + "containerName": "a", + "deprecated": false, + "kind": 2, + "location": { + "range": { + "end": { + "character": 5, + "line": 4 + }, + "start": { + "character": 4, + "line": 1 + } + }, + "uri": "file:///[..]/src/lib.rs" + }, + "name": "b", + "tags": [] + }, + { + "containerName": "b", + "deprecated": false, + "kind": 23, + "location": { + "range": { + "end": { + "character": 18, + "line": 2 + }, + "start": { + "character": 8, + "line": 2 + } + }, + "uri": "file:///[..]/src/lib.rs" + }, + "name": "B1", + "tags": [] + }, + { + "containerName": "b", + "deprecated": false, + "kind": 12, + "location": { + "range": { + "end": { + "character": 18, + "line": 3 + }, + "start": { + "character": 8, + "line": 3 + } + }, + "uri": "file:///[..]/src/lib.rs" + }, + "name": "b2", + "tags": [] + }, + { + "containerName": "a", + "deprecated": false, + "kind": 23, + "location": { + "range": { + "end": { + "character": 14, + "line": 5 + }, + "start": { + "character": 4, + "line": 5 + } + }, + "uri": "file:///[..]/src/lib.rs" + }, + "name": "A1", + "tags": [] + } + ]), + ); +} -- cgit v1.2.3 From e8e1eb4263d5bcf109550432143dd54de9f64946 Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Mon, 17 Aug 2020 00:19:29 +0900 Subject: Remove test for `handle_document_symbol` --- crates/rust-analyzer/tests/heavy_tests/main.rs | 321 +------------------------ 1 file changed, 4 insertions(+), 317 deletions(-) (limited to 'crates') diff --git a/crates/rust-analyzer/tests/heavy_tests/main.rs b/crates/rust-analyzer/tests/heavy_tests/main.rs index 9a4655e4d..7370505f8 100644 --- a/crates/rust-analyzer/tests/heavy_tests/main.rs +++ b/crates/rust-analyzer/tests/heavy_tests/main.rs @@ -5,14 +5,11 @@ use std::{collections::HashMap, path::PathBuf, time::Instant}; use lsp_types::{ notification::DidOpenTextDocument, - request::{ - CodeActionRequest, Completion, DocumentSymbolRequest, Formatting, GotoTypeDefinition, - HoverRequest, - }, + request::{CodeActionRequest, Completion, Formatting, GotoTypeDefinition, HoverRequest}, CodeActionContext, CodeActionParams, CompletionParams, DidOpenTextDocumentParams, - DocumentFormattingParams, DocumentSymbolParams, FormattingOptions, GotoDefinitionParams, - HoverParams, PartialResultParams, Position, Range, TextDocumentItem, - TextDocumentPositionParams, WorkDoneProgressParams, + DocumentFormattingParams, FormattingOptions, GotoDefinitionParams, HoverParams, + PartialResultParams, Position, Range, TextDocumentItem, TextDocumentPositionParams, + WorkDoneProgressParams, }; use rust_analyzer::lsp_ext::{OnEnter, Runnables, RunnablesParams}; use serde_json::json; @@ -685,313 +682,3 @@ pub fn foo(_input: TokenStream) -> TokenStream { let value = res.get("contents").unwrap().get("value").unwrap().to_string(); assert_eq!(value, r#""```rust\nfoo::Bar\n```\n\n```rust\nfn bar()\n```""#) } - -#[test] -fn test_document_symbol_with_hierarchy() { - if skip_slow_tests() { - return; - } - - let server = Project::with_fixture( - r#" -//- /Cargo.toml -[package] -name = "foo" -version = "0.0.0" - -//- /src/lib.rs -mod a { - mod b { - struct B1; - fn b2() {} - } - struct A1; -} -"#, - ) - .with_config(|config| { - config.client_caps.hierarchical_symbols = true; - }) - .server(); - server.wait_until_workspace_is_loaded(); - - server.request::( - DocumentSymbolParams { - text_document: server.doc_id("src/lib.rs"), - work_done_progress_params: WorkDoneProgressParams::default(), - partial_result_params: PartialResultParams::default(), - }, - json!([ - { - "children": [ - { - "children": [ - { - "deprecated": false, - "kind": 23, - "name": "B1", - "range": { - "end": { - "character": 18, - "line": 2 - }, - "start": { - "character": 8, - "line": 2 - } - }, - "selectionRange": { - "end": { - "character": 17, - "line": 2 - }, - "start": { - "character": 15, - "line": 2 - } - }, - "tags": [] - }, - { - "deprecated": false, - "detail": "fn()", - "kind": 12, - "name": "b2", - "range": { - "end": { - "character": 18, - "line": 3 - }, - "start": { - "character": 8, - "line": 3 - } - }, - "selectionRange": { - "end": { - "character": 13, - "line": 3 - }, - "start": { - "character": 11, - "line": 3 - } - }, - "tags": [] - } - ], - "deprecated": false, - "kind": 2, - "name": "b", - "range": { - "end": { - "character": 5, - "line": 4 - }, - "start": { - "character": 4, - "line": 1 - } - }, - "selectionRange": { - "end": { - "character": 9, - "line": 1 - }, - "start": { - "character": 8, - "line": 1 - } - }, - "tags": [] - }, - { - "deprecated": false, - "kind": 23, - "name": "A1", - "range": { - "end": { - "character": 14, - "line": 5 - }, - "start": { - "character": 4, - "line": 5 - } - }, - "selectionRange": { - "end": { - "character": 13, - "line": 5 - }, - "start": { - "character": 11, - "line": 5 - } - }, - "tags": [] - } - ], - "deprecated": false, - "kind": 2, - "name": "a", - "range": { - "end": { - "character": 1, - "line": 6 - }, - "start": { - "character": 0, - "line": 0 - } - }, - "selectionRange": { - "end": { - "character": 5, - "line": 0 - }, - "start": { - "character": 4, - "line": 0 - } - }, - "tags": [] - } - ]), - ); -} - -#[test] -fn test_document_symbol_without_hierarchy() { - if skip_slow_tests() { - return; - } - - let server = project( - r#" -//- /Cargo.toml -[package] -name = "foo" -version = "0.0.0" - -//- /src/lib.rs -mod a { - mod b { - struct B1; - fn b2() {} - } - struct A1; -} -"#, - ); - server.wait_until_workspace_is_loaded(); - - server.request::( - DocumentSymbolParams { - text_document: server.doc_id("src/lib.rs"), - work_done_progress_params: WorkDoneProgressParams::default(), - partial_result_params: PartialResultParams::default(), - }, - json!([ - { - "deprecated": false, - "kind": 2, - "location": { - "range": { - "end": { - "character": 1, - "line": 6 - }, - "start": { - "character": 0, - "line": 0 - } - }, - "uri": "file:///[..]/src/lib.rs" - }, - "name": "a", - "tags": [] - }, - { - "containerName": "a", - "deprecated": false, - "kind": 2, - "location": { - "range": { - "end": { - "character": 5, - "line": 4 - }, - "start": { - "character": 4, - "line": 1 - } - }, - "uri": "file:///[..]/src/lib.rs" - }, - "name": "b", - "tags": [] - }, - { - "containerName": "b", - "deprecated": false, - "kind": 23, - "location": { - "range": { - "end": { - "character": 18, - "line": 2 - }, - "start": { - "character": 8, - "line": 2 - } - }, - "uri": "file:///[..]/src/lib.rs" - }, - "name": "B1", - "tags": [] - }, - { - "containerName": "b", - "deprecated": false, - "kind": 12, - "location": { - "range": { - "end": { - "character": 18, - "line": 3 - }, - "start": { - "character": 8, - "line": 3 - } - }, - "uri": "file:///[..]/src/lib.rs" - }, - "name": "b2", - "tags": [] - }, - { - "containerName": "a", - "deprecated": false, - "kind": 23, - "location": { - "range": { - "end": { - "character": 14, - "line": 5 - }, - "start": { - "character": 4, - "line": 5 - } - }, - "uri": "file:///[..]/src/lib.rs" - }, - "name": "A1", - "tags": [] - } - ]), - ); -} -- cgit v1.2.3