From 82146737acc74b2483f39f1dd0ae4dfffcfda824 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Wed, 20 Jan 2021 20:05:48 +0100 Subject: Treat BlockExpr as a potential module origin --- crates/assists/src/handlers/generate_function.rs | 19 ++++++++++++++----- crates/hir_def/src/attr.rs | 1 + crates/hir_def/src/nameres.rs | 12 ++++++++++-- crates/ide/src/display/navigation_target.rs | 1 + crates/ide/src/display/short_label.rs | 6 ++++++ crates/ide/src/hover.rs | 1 + crates/ide/src/runnables.rs | 1 + crates/ide_db/src/search.rs | 10 ++++++++++ 8 files changed, 44 insertions(+), 7 deletions(-) (limited to 'crates') diff --git a/crates/assists/src/handlers/generate_function.rs b/crates/assists/src/handlers/generate_function.rs index 06ac85f67..1805c1dfd 100644 --- a/crates/assists/src/handlers/generate_function.rs +++ b/crates/assists/src/handlers/generate_function.rs @@ -158,11 +158,11 @@ impl FunctionBuilder { it.text_range().end() } GeneratedFunctionTarget::InEmptyItemList(it) => { - let indent = IndentLevel::from_node(it.syntax()); + let indent = IndentLevel::from_node(&it); leading_ws = format!("\n{}", indent + 1); fn_def = fn_def.indent(indent + 1); trailing_ws = format!("\n{}", indent); - it.syntax().text_range().start() + TextSize::of('{') + it.text_range().start() + TextSize::of('{') } }; @@ -179,14 +179,14 @@ impl FunctionBuilder { enum GeneratedFunctionTarget { BehindItem(SyntaxNode), - InEmptyItemList(ast::ItemList), + InEmptyItemList(SyntaxNode), } impl GeneratedFunctionTarget { fn syntax(&self) -> &SyntaxNode { match self { GeneratedFunctionTarget::BehindItem(it) => it, - GeneratedFunctionTarget::InEmptyItemList(it) => it.syntax(), + GeneratedFunctionTarget::InEmptyItemList(it) => it, } } } @@ -323,7 +323,16 @@ fn next_space_for_fn_in_module( if let Some(last_item) = it.item_list().and_then(|it| it.items().last()) { GeneratedFunctionTarget::BehindItem(last_item.syntax().clone()) } else { - GeneratedFunctionTarget::InEmptyItemList(it.item_list()?) + GeneratedFunctionTarget::InEmptyItemList(it.item_list()?.syntax().clone()) + } + } + hir::ModuleSource::BlockExpr(it) => { + if let Some(last_item) = + it.statements().take_while(|stmt| matches!(stmt, ast::Stmt::Item(_))).last() + { + GeneratedFunctionTarget::BehindItem(last_item.syntax().clone()) + } else { + GeneratedFunctionTarget::InEmptyItemList(it.syntax().clone()) } } }; diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index 1b09ff816..c72649c41 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs @@ -207,6 +207,7 @@ impl Attrs { mod_data.definition_source(db).as_ref().map(|src| match src { ModuleSource::SourceFile(file) => file as &dyn AttrsOwner, ModuleSource::Module(module) => module as &dyn AttrsOwner, + ModuleSource::BlockExpr(block) => block as &dyn AttrsOwner, }), ), } diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs index 23f960ad4..a3200c710 100644 --- a/crates/hir_def/src/nameres.rs +++ b/crates/hir_def/src/nameres.rs @@ -109,6 +109,10 @@ pub enum ModuleOrigin { Inline { definition: AstId, }, + /// Pseudo-module introduced by a block scope (contains only inner items). + BlockExpr { + block: AstId, + }, } impl Default for ModuleOrigin { @@ -122,7 +126,7 @@ impl ModuleOrigin { match self { ModuleOrigin::File { declaration: module, .. } | ModuleOrigin::Inline { definition: module, .. } => Some(*module), - ModuleOrigin::CrateRoot { .. } => None, + ModuleOrigin::CrateRoot { .. } | ModuleOrigin::BlockExpr { .. } => None, } } @@ -137,7 +141,7 @@ impl ModuleOrigin { pub fn is_inline(&self) -> bool { match self { - ModuleOrigin::Inline { .. } => true, + ModuleOrigin::Inline { .. } | ModuleOrigin::BlockExpr { .. } => true, ModuleOrigin::CrateRoot { .. } | ModuleOrigin::File { .. } => false, } } @@ -155,6 +159,9 @@ impl ModuleOrigin { definition.file_id, ModuleSource::Module(definition.to_node(db.upcast())), ), + ModuleOrigin::BlockExpr { block } => { + InFile::new(block.file_id, ModuleSource::BlockExpr(block.to_node(db.upcast()))) + } } } } @@ -300,6 +307,7 @@ impl ModuleData { pub enum ModuleSource { SourceFile(ast::SourceFile), Module(ast::Module), + BlockExpr(ast::BlockExpr), } mod diagnostics { diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs index 671aa1373..9c568c90c 100644 --- a/crates/ide/src/display/navigation_target.rs +++ b/crates/ide/src/display/navigation_target.rs @@ -294,6 +294,7 @@ impl ToNav for hir::Module { ModuleSource::Module(node) => { (node.syntax(), node.name().map(|it| it.syntax().text_range())) } + ModuleSource::BlockExpr(node) => (node.syntax(), None), }; let frange = src.with_value(syntax).original_file_range(db); NavigationTarget::from_syntax(frange.file_id, name, focus, frange.range, SymbolKind::Module) diff --git a/crates/ide/src/display/short_label.rs b/crates/ide/src/display/short_label.rs index b8e4cc181..7ac050473 100644 --- a/crates/ide/src/display/short_label.rs +++ b/crates/ide/src/display/short_label.rs @@ -53,6 +53,12 @@ impl ShortLabel for ast::SourceFile { } } +impl ShortLabel for ast::BlockExpr { + fn short_label(&self) -> Option { + None + } +} + impl ShortLabel for ast::TypeAlias { fn short_label(&self) -> Option { short_label_from_node(self, "type ") diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 44ebdbd35..ec1631486 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -321,6 +321,7 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option { match it.definition_source(db).value { ModuleSource::Module(it) => it.short_label(), ModuleSource::SourceFile(it) => it.short_label(), + ModuleSource::BlockExpr(it) => it.short_label(), }, mod_path, ), diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index 47a85dc45..975abf47f 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs @@ -131,6 +131,7 @@ fn runnables_mod(sema: &Semantics, acc: &mut Vec, module match submodule.definition_source(sema.db).value { hir::ModuleSource::Module(_) => runnables_mod(sema, acc, submodule), hir::ModuleSource::SourceFile(_) => mark::hit!(dont_recurse_in_outline_submodules), + hir::ModuleSource::BlockExpr(_) => {} // inner items aren't runnable } } } diff --git a/crates/ide_db/src/search.rs b/crates/ide_db/src/search.rs index 0ecb13a64..b9ba0aed5 100644 --- a/crates/ide_db/src/search.rs +++ b/crates/ide_db/src/search.rs @@ -228,6 +228,15 @@ impl Definition { // so do nothing. } } + ModuleSource::BlockExpr(b) => { + if is_first { + let range = Some(b.syntax().text_range()); + res.insert(file_id, range); + } else { + // We have already added the enclosing file to the search scope, + // so do nothing. + } + } ModuleSource::SourceFile(_) => { res.insert(file_id, None); } @@ -257,6 +266,7 @@ impl Definition { let mut res = FxHashMap::default(); let range = match module_src.value { ModuleSource::Module(m) => Some(m.syntax().text_range()), + ModuleSource::BlockExpr(b) => Some(b.syntax().text_range()), ModuleSource::SourceFile(_) => None, }; res.insert(file_id, range); -- cgit v1.2.3