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('{')
}
};
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,
}
}
}
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())
}
}
};
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,
}),
),
}
Inline {
definition: AstId<ast::Module>,
},
+ /// Pseudo-module introduced by a block scope (contains only inner items).
+ BlockExpr {
+ block: AstId<ast::BlockExpr>,
+ },
}
impl Default for ModuleOrigin {
match self {
ModuleOrigin::File { declaration: module, .. }
| ModuleOrigin::Inline { definition: module, .. } => Some(*module),
- ModuleOrigin::CrateRoot { .. } => None,
+ ModuleOrigin::CrateRoot { .. } | ModuleOrigin::BlockExpr { .. } => None,
}
}
pub fn is_inline(&self) -> bool {
match self {
- ModuleOrigin::Inline { .. } => true,
+ ModuleOrigin::Inline { .. } | ModuleOrigin::BlockExpr { .. } => true,
ModuleOrigin::CrateRoot { .. } | ModuleOrigin::File { .. } => false,
}
}
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())))
+ }
}
}
}
pub enum ModuleSource {
SourceFile(ast::SourceFile),
Module(ast::Module),
+ BlockExpr(ast::BlockExpr),
}
mod diagnostics {
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)
}
}
+impl ShortLabel for ast::BlockExpr {
+ fn short_label(&self) -> Option<String> {
+ None
+ }
+}
+
impl ShortLabel for ast::TypeAlias {
fn short_label(&self) -> Option<String> {
short_label_from_node(self, "type ")
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,
),
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
}
}
}
// 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);
}
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);