diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-01-20 22:07:38 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2021-01-20 22:07:38 +0000 |
commit | 70f7a10013775c1dce10b0d7a7724a48bb76b065 (patch) | |
tree | 2f3c97e5f45a8579cc860dc9a57123dbb5302b8b | |
parent | 7d5ed18c42c4ee80e776d04254d69750b70e14ba (diff) | |
parent | 82146737acc74b2483f39f1dd0ae4dfffcfda824 (diff) |
Merge #7366
7366: Treat BlockExpr as a potential module origin r=jonas-schievink a=jonas-schievink
A block containing inner items acts like the root module of a crate, so it needs to be representable as a `ModuleSource` and `ModuleOrigin`.
Co-authored-by: Jonas Schievink <[email protected]>
-rw-r--r-- | crates/assists/src/handlers/generate_function.rs | 19 | ||||
-rw-r--r-- | crates/hir_def/src/attr.rs | 1 | ||||
-rw-r--r-- | crates/hir_def/src/nameres.rs | 12 | ||||
-rw-r--r-- | crates/ide/src/display/navigation_target.rs | 1 | ||||
-rw-r--r-- | crates/ide/src/display/short_label.rs | 6 | ||||
-rw-r--r-- | crates/ide/src/hover.rs | 1 | ||||
-rw-r--r-- | crates/ide/src/runnables.rs | 1 | ||||
-rw-r--r-- | crates/ide_db/src/search.rs | 10 |
8 files changed, 44 insertions, 7 deletions
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 { | |||
158 | it.text_range().end() | 158 | it.text_range().end() |
159 | } | 159 | } |
160 | GeneratedFunctionTarget::InEmptyItemList(it) => { | 160 | GeneratedFunctionTarget::InEmptyItemList(it) => { |
161 | let indent = IndentLevel::from_node(it.syntax()); | 161 | let indent = IndentLevel::from_node(&it); |
162 | leading_ws = format!("\n{}", indent + 1); | 162 | leading_ws = format!("\n{}", indent + 1); |
163 | fn_def = fn_def.indent(indent + 1); | 163 | fn_def = fn_def.indent(indent + 1); |
164 | trailing_ws = format!("\n{}", indent); | 164 | trailing_ws = format!("\n{}", indent); |
165 | it.syntax().text_range().start() + TextSize::of('{') | 165 | it.text_range().start() + TextSize::of('{') |
166 | } | 166 | } |
167 | }; | 167 | }; |
168 | 168 | ||
@@ -179,14 +179,14 @@ impl FunctionBuilder { | |||
179 | 179 | ||
180 | enum GeneratedFunctionTarget { | 180 | enum GeneratedFunctionTarget { |
181 | BehindItem(SyntaxNode), | 181 | BehindItem(SyntaxNode), |
182 | InEmptyItemList(ast::ItemList), | 182 | InEmptyItemList(SyntaxNode), |
183 | } | 183 | } |
184 | 184 | ||
185 | impl GeneratedFunctionTarget { | 185 | impl GeneratedFunctionTarget { |
186 | fn syntax(&self) -> &SyntaxNode { | 186 | fn syntax(&self) -> &SyntaxNode { |
187 | match self { | 187 | match self { |
188 | GeneratedFunctionTarget::BehindItem(it) => it, | 188 | GeneratedFunctionTarget::BehindItem(it) => it, |
189 | GeneratedFunctionTarget::InEmptyItemList(it) => it.syntax(), | 189 | GeneratedFunctionTarget::InEmptyItemList(it) => it, |
190 | } | 190 | } |
191 | } | 191 | } |
192 | } | 192 | } |
@@ -323,7 +323,16 @@ fn next_space_for_fn_in_module( | |||
323 | if let Some(last_item) = it.item_list().and_then(|it| it.items().last()) { | 323 | if let Some(last_item) = it.item_list().and_then(|it| it.items().last()) { |
324 | GeneratedFunctionTarget::BehindItem(last_item.syntax().clone()) | 324 | GeneratedFunctionTarget::BehindItem(last_item.syntax().clone()) |
325 | } else { | 325 | } else { |
326 | GeneratedFunctionTarget::InEmptyItemList(it.item_list()?) | 326 | GeneratedFunctionTarget::InEmptyItemList(it.item_list()?.syntax().clone()) |
327 | } | ||
328 | } | ||
329 | hir::ModuleSource::BlockExpr(it) => { | ||
330 | if let Some(last_item) = | ||
331 | it.statements().take_while(|stmt| matches!(stmt, ast::Stmt::Item(_))).last() | ||
332 | { | ||
333 | GeneratedFunctionTarget::BehindItem(last_item.syntax().clone()) | ||
334 | } else { | ||
335 | GeneratedFunctionTarget::InEmptyItemList(it.syntax().clone()) | ||
327 | } | 336 | } |
328 | } | 337 | } |
329 | }; | 338 | }; |
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 { | |||
207 | mod_data.definition_source(db).as_ref().map(|src| match src { | 207 | mod_data.definition_source(db).as_ref().map(|src| match src { |
208 | ModuleSource::SourceFile(file) => file as &dyn AttrsOwner, | 208 | ModuleSource::SourceFile(file) => file as &dyn AttrsOwner, |
209 | ModuleSource::Module(module) => module as &dyn AttrsOwner, | 209 | ModuleSource::Module(module) => module as &dyn AttrsOwner, |
210 | ModuleSource::BlockExpr(block) => block as &dyn AttrsOwner, | ||
210 | }), | 211 | }), |
211 | ), | 212 | ), |
212 | } | 213 | } |
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 { | |||
109 | Inline { | 109 | Inline { |
110 | definition: AstId<ast::Module>, | 110 | definition: AstId<ast::Module>, |
111 | }, | 111 | }, |
112 | /// Pseudo-module introduced by a block scope (contains only inner items). | ||
113 | BlockExpr { | ||
114 | block: AstId<ast::BlockExpr>, | ||
115 | }, | ||
112 | } | 116 | } |
113 | 117 | ||
114 | impl Default for ModuleOrigin { | 118 | impl Default for ModuleOrigin { |
@@ -122,7 +126,7 @@ impl ModuleOrigin { | |||
122 | match self { | 126 | match self { |
123 | ModuleOrigin::File { declaration: module, .. } | 127 | ModuleOrigin::File { declaration: module, .. } |
124 | | ModuleOrigin::Inline { definition: module, .. } => Some(*module), | 128 | | ModuleOrigin::Inline { definition: module, .. } => Some(*module), |
125 | ModuleOrigin::CrateRoot { .. } => None, | 129 | ModuleOrigin::CrateRoot { .. } | ModuleOrigin::BlockExpr { .. } => None, |
126 | } | 130 | } |
127 | } | 131 | } |
128 | 132 | ||
@@ -137,7 +141,7 @@ impl ModuleOrigin { | |||
137 | 141 | ||
138 | pub fn is_inline(&self) -> bool { | 142 | pub fn is_inline(&self) -> bool { |
139 | match self { | 143 | match self { |
140 | ModuleOrigin::Inline { .. } => true, | 144 | ModuleOrigin::Inline { .. } | ModuleOrigin::BlockExpr { .. } => true, |
141 | ModuleOrigin::CrateRoot { .. } | ModuleOrigin::File { .. } => false, | 145 | ModuleOrigin::CrateRoot { .. } | ModuleOrigin::File { .. } => false, |
142 | } | 146 | } |
143 | } | 147 | } |
@@ -155,6 +159,9 @@ impl ModuleOrigin { | |||
155 | definition.file_id, | 159 | definition.file_id, |
156 | ModuleSource::Module(definition.to_node(db.upcast())), | 160 | ModuleSource::Module(definition.to_node(db.upcast())), |
157 | ), | 161 | ), |
162 | ModuleOrigin::BlockExpr { block } => { | ||
163 | InFile::new(block.file_id, ModuleSource::BlockExpr(block.to_node(db.upcast()))) | ||
164 | } | ||
158 | } | 165 | } |
159 | } | 166 | } |
160 | } | 167 | } |
@@ -300,6 +307,7 @@ impl ModuleData { | |||
300 | pub enum ModuleSource { | 307 | pub enum ModuleSource { |
301 | SourceFile(ast::SourceFile), | 308 | SourceFile(ast::SourceFile), |
302 | Module(ast::Module), | 309 | Module(ast::Module), |
310 | BlockExpr(ast::BlockExpr), | ||
303 | } | 311 | } |
304 | 312 | ||
305 | mod diagnostics { | 313 | 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 { | |||
294 | ModuleSource::Module(node) => { | 294 | ModuleSource::Module(node) => { |
295 | (node.syntax(), node.name().map(|it| it.syntax().text_range())) | 295 | (node.syntax(), node.name().map(|it| it.syntax().text_range())) |
296 | } | 296 | } |
297 | ModuleSource::BlockExpr(node) => (node.syntax(), None), | ||
297 | }; | 298 | }; |
298 | let frange = src.with_value(syntax).original_file_range(db); | 299 | let frange = src.with_value(syntax).original_file_range(db); |
299 | NavigationTarget::from_syntax(frange.file_id, name, focus, frange.range, SymbolKind::Module) | 300 | 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 { | |||
53 | } | 53 | } |
54 | } | 54 | } |
55 | 55 | ||
56 | impl ShortLabel for ast::BlockExpr { | ||
57 | fn short_label(&self) -> Option<String> { | ||
58 | None | ||
59 | } | ||
60 | } | ||
61 | |||
56 | impl ShortLabel for ast::TypeAlias { | 62 | impl ShortLabel for ast::TypeAlias { |
57 | fn short_label(&self) -> Option<String> { | 63 | fn short_label(&self) -> Option<String> { |
58 | short_label_from_node(self, "type ") | 64 | 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<Markup> { | |||
321 | match it.definition_source(db).value { | 321 | match it.definition_source(db).value { |
322 | ModuleSource::Module(it) => it.short_label(), | 322 | ModuleSource::Module(it) => it.short_label(), |
323 | ModuleSource::SourceFile(it) => it.short_label(), | 323 | ModuleSource::SourceFile(it) => it.short_label(), |
324 | ModuleSource::BlockExpr(it) => it.short_label(), | ||
324 | }, | 325 | }, |
325 | mod_path, | 326 | mod_path, |
326 | ), | 327 | ), |
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<RootDatabase>, acc: &mut Vec<Runnable>, module | |||
131 | match submodule.definition_source(sema.db).value { | 131 | match submodule.definition_source(sema.db).value { |
132 | hir::ModuleSource::Module(_) => runnables_mod(sema, acc, submodule), | 132 | hir::ModuleSource::Module(_) => runnables_mod(sema, acc, submodule), |
133 | hir::ModuleSource::SourceFile(_) => mark::hit!(dont_recurse_in_outline_submodules), | 133 | hir::ModuleSource::SourceFile(_) => mark::hit!(dont_recurse_in_outline_submodules), |
134 | hir::ModuleSource::BlockExpr(_) => {} // inner items aren't runnable | ||
134 | } | 135 | } |
135 | } | 136 | } |
136 | } | 137 | } |
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 { | |||
228 | // so do nothing. | 228 | // so do nothing. |
229 | } | 229 | } |
230 | } | 230 | } |
231 | ModuleSource::BlockExpr(b) => { | ||
232 | if is_first { | ||
233 | let range = Some(b.syntax().text_range()); | ||
234 | res.insert(file_id, range); | ||
235 | } else { | ||
236 | // We have already added the enclosing file to the search scope, | ||
237 | // so do nothing. | ||
238 | } | ||
239 | } | ||
231 | ModuleSource::SourceFile(_) => { | 240 | ModuleSource::SourceFile(_) => { |
232 | res.insert(file_id, None); | 241 | res.insert(file_id, None); |
233 | } | 242 | } |
@@ -257,6 +266,7 @@ impl Definition { | |||
257 | let mut res = FxHashMap::default(); | 266 | let mut res = FxHashMap::default(); |
258 | let range = match module_src.value { | 267 | let range = match module_src.value { |
259 | ModuleSource::Module(m) => Some(m.syntax().text_range()), | 268 | ModuleSource::Module(m) => Some(m.syntax().text_range()), |
269 | ModuleSource::BlockExpr(b) => Some(b.syntax().text_range()), | ||
260 | ModuleSource::SourceFile(_) => None, | 270 | ModuleSource::SourceFile(_) => None, |
261 | }; | 271 | }; |
262 | res.insert(file_id, range); | 272 | res.insert(file_id, range); |