From ae1f77e5e9aef59aed9cd5a146114e37a74e3316 Mon Sep 17 00:00:00 2001 From: kjeremy Date: Fri, 24 Apr 2020 10:08:45 -0400 Subject: Add hierarchical symbols client capability --- crates/rust-analyzer/src/config.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 715eddadb..74a63e32a 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -69,6 +69,7 @@ pub enum RustfmtConfig { pub struct ClientCapsConfig { pub location_link: bool, pub line_folding_only: bool, + pub hierarchical_symbols: bool, } impl Default for Config { @@ -215,6 +216,11 @@ impl Config { if let Some(value) = caps.folding_range.as_ref().and_then(|it| it.line_folding_only) { self.client_caps.line_folding_only = value } + if let Some(value) = + caps.document_symbol.as_ref().and_then(|it| it.hierarchical_document_symbol_support) + { + self.client_caps.hierarchical_symbols = value + } self.completion.allow_snippets(false); if let Some(completion) = &caps.completion { if let Some(completion_item) = &completion.completion_item { -- cgit v1.2.3 From 0619c67ac6b2f503750058437ce0af08d17d1018 Mon Sep 17 00:00:00 2001 From: kjeremy Date: Fri, 24 Apr 2020 10:11:57 -0400 Subject: Support returning non-hierarchical symbols If `hierarchicalDocumentSymbolSupport` is not true in the client capabilites then it does not support the `DocumentSymbol[]` return type from the `textDocument/documentSymbol` request and we must fall back to `SymbolInformation[]`. This is one of the few requests that use the client capabilities to differentiate between return types and could cause problems for clients. See https://github.com/microsoft/language-server-protocol/pull/538#issuecomment-442510767 for more context. Found while looking at #144 --- crates/rust-analyzer/src/main_loop/handlers.rs | 37 +++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index 41d9fe344..246085005 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs @@ -16,7 +16,7 @@ use lsp_types::{ Hover, HoverContents, Location, MarkupContent, MarkupKind, Position, PrepareRenameResponse, Range, RenameParams, SemanticTokensParams, SemanticTokensRangeParams, SemanticTokensRangeResult, SemanticTokensResult, SymbolInformation, TextDocumentIdentifier, - TextEdit, WorkspaceEdit, + TextEdit, Url, WorkspaceEdit, }; use ra_ide::{ Assist, AssistId, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind, @@ -219,6 +219,7 @@ pub fn handle_document_symbol( let _p = profile("handle_document_symbol"); let file_id = params.text_document.try_conv_with(&world)?; let line_index = world.analysis().file_line_index(file_id)?; + let url = file_id.try_conv_with(&world)?; let mut parents: Vec<(DocumentSymbol, Option)> = Vec::new(); @@ -234,10 +235,10 @@ pub fn handle_document_symbol( }; parents.push((doc_symbol, symbol.parent)); } - let mut res = Vec::new(); + let mut document_symbols = Vec::new(); while let Some((node, parent)) = parents.pop() { match parent { - None => res.push(node), + None => document_symbols.push(node), Some(i) => { let children = &mut parents[i].0.children; if children.is_none() { @@ -248,7 +249,35 @@ pub fn handle_document_symbol( } } - Ok(Some(res.into())) + if world.config.client_caps.hierarchical_symbols { + Ok(Some(document_symbols.into())) + } else { + let mut symbol_information = Vec::::new(); + for symbol in document_symbols { + flatten_document_symbol(&symbol, None, &url, &mut symbol_information); + } + + Ok(Some(symbol_information.into())) + } +} + +fn flatten_document_symbol( + symbol: &DocumentSymbol, + container_name: Option, + url: &Url, + res: &mut Vec, +) { + res.push(SymbolInformation { + name: symbol.name.clone(), + kind: symbol.kind, + deprecated: symbol.deprecated, + location: Location::new(url.clone(), symbol.range), + container_name: container_name, + }); + + for child in symbol.children.iter().flatten() { + flatten_document_symbol(child, Some(symbol.name.clone()), url, res); + } } pub fn handle_workspace_symbol( -- cgit v1.2.3 From b87b335e6859ead3baa7fde20e3ea2ac69f63d85 Mon Sep 17 00:00:00 2001 From: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com> Date: Sat, 25 Apr 2020 15:48:04 +0200 Subject: add support for cfg feature attributes on expression #4063 Signed-off-by: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com> --- crates/ra_hir_def/src/body/lower.rs | 4 ++++ crates/ra_hir_ty/src/tests.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 0caedd8d8..571603854 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -141,6 +141,10 @@ impl ExprCollector<'_> { fn collect_expr(&mut self, expr: ast::Expr) -> ExprId { let syntax_ptr = AstPtr::new(&expr); + let attrs = self.expander.parse_attrs(&expr); + if !self.expander.is_cfg_enabled(&attrs) { + return self.missing_expr(); + } match expr { ast::Expr::IfExpr(e) => { let then_branch = self.collect_block_opt(e.then_branch()); diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs index b6a96bb5c..588d81282 100644 --- a/crates/ra_hir_ty/src/tests.rs +++ b/crates/ra_hir_ty/src/tests.rs @@ -390,6 +390,38 @@ fn no_such_field_with_feature_flag_diagnostics_on_struct_lit() { assert_snapshot!(diagnostics, @r###""###); } +#[test] +fn no_such_field_with_feature_flag_diagnostics_on_block_expr() { + let diagnostics = TestDB::with_files( + r#" + //- /lib.rs crate:foo cfg:feature=foo + struct S { + #[cfg(feature = "foo")] + foo: u32, + #[cfg(not(feature = "foo"))] + bar: u32, + } + + impl S { + fn new(bar: u32) -> Self { + #[cfg(feature = "foo")] + { + Self { foo: bar } + } + #[cfg(not(feature = "foo"))] + { + Self { bar } + } + } + } + "#, + ) + .diagnostics() + .0; + + assert_snapshot!(diagnostics, @r###""###); +} + #[test] fn no_such_field_with_feature_flag_diagnostics_on_struct_fields() { let diagnostics = TestDB::with_files( -- cgit v1.2.3 From f52e2f6840280ef1302604d90cd3b338a2e488cc Mon Sep 17 00:00:00 2001 From: veetaha Date: Sat, 25 Apr 2020 20:49:51 +0300 Subject: Fix typo --- crates/ra_hir_def/src/body.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 3b169440a..890cefcaf 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -27,7 +27,7 @@ use crate::{ AsMacroCall, DefWithBodyId, HasModule, Lookup, ModuleId, }; -/// A subser of Exander that only deals with cfg attributes. We only need it to +/// A subset of Exander that only deals with cfg attributes. We only need it to /// avoid cyclic queries in crate def map during enum processing. pub(crate) struct CfgExpander { cfg_options: CfgOptions, -- cgit v1.2.3 From 5f88df82a67d3d17bbead1179f82ad7261f68692 Mon Sep 17 00:00:00 2001 From: veetaha Date: Sat, 25 Apr 2020 20:52:50 +0300 Subject: Remove unnecessary async from vscode language client creation --- editors/code/src/client.ts | 2 +- editors/code/src/ctx.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index 0ad4b63ae..97e794091 100644 --- a/editors/code/src/client.ts +++ b/editors/code/src/client.ts @@ -4,7 +4,7 @@ import * as vscode from 'vscode'; import { CallHierarchyFeature } from 'vscode-languageclient/lib/callHierarchy.proposed'; import { SemanticTokensFeature, DocumentSemanticsTokensSignature } from 'vscode-languageclient/lib/semanticTokens.proposed'; -export async function createClient(serverPath: string, cwd: string): Promise { +export function createClient(serverPath: string, cwd: string): lc.LanguageClient { // '.' Is the fallback if no folder is open // TODO?: Workspace folders support Uri's (eg: file://test.txt). // It might be a good idea to test if the uri points to a file. diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index f7ed62d03..41df11991 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -21,7 +21,7 @@ export class Ctx { serverPath: string, cwd: string, ): Promise { - const client = await createClient(serverPath, cwd); + const client = createClient(serverPath, cwd); const res = new Ctx(config, extCtx, client, serverPath); res.pushCleanup(client.start()); await client.onReady(); -- cgit v1.2.3