aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/code_model_api.rs10
-rw-r--r--crates/ra_hir/src/code_model_impl/module.rs4
-rw-r--r--crates/ra_hir/src/db.rs14
-rw-r--r--crates/ra_hir/src/ids.rs7
-rw-r--r--crates/ra_hir/src/impl_block.rs5
-rw-r--r--crates/ra_hir/src/nameres/crate_def_map/collector.rs9
-rw-r--r--crates/ra_hir/src/nameres/crate_def_map/raw.rs16
-rw-r--r--crates/ra_hir/src/nameres/lower.rs190
-rw-r--r--crates/ra_hir/src/source_binder.rs42
9 files changed, 43 insertions, 254 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs
index 86c26f1d8..c918ec9f6 100644
--- a/crates/ra_hir/src/code_model_api.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -186,11 +186,11 @@ impl Module {
186 } 186 }
187 187
188 pub fn declarations(self, db: &impl HirDatabase) -> Vec<ModuleDef> { 188 pub fn declarations(self, db: &impl HirDatabase) -> Vec<ModuleDef> {
189 let lowered_module = db.lower_module(self); 189 let def_map = db.crate_def_map(self.krate);
190 lowered_module 190 def_map[self.module_id]
191 .declarations 191 .scope
192 .values() 192 .entries()
193 .cloned() 193 .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None })
194 .flat_map(|per_ns| { 194 .flat_map(|per_ns| {
195 per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter()) 195 per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter())
196 }) 196 })
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs
index 5d8f738b5..aa4e62518 100644
--- a/crates/ra_hir/src/code_model_impl/module.rs
+++ b/crates/ra_hir/src/code_model_impl/module.rs
@@ -76,8 +76,8 @@ impl Module {
76 db: &impl HirDatabase, 76 db: &impl HirDatabase,
77 import: ImportId, 77 import: ImportId,
78 ) -> TreeArc<ast::PathSegment> { 78 ) -> TreeArc<ast::PathSegment> {
79 let (_, source_map) = db.lower_module_with_source_map(*self); 79 let (file_id, source) = self.definition_source(db);
80 let (_, source) = self.definition_source(db); 80 let (_, source_map) = db.raw_items_with_source_map(file_id.original_file(db));
81 source_map.get(&source, import) 81 source_map.get(&source, import)
82 } 82 }
83 83
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index 0190f4987..b8c0a68a6 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -10,7 +10,7 @@ use crate::{
10 Struct, Enum, StructField, 10 Struct, Enum, StructField,
11 Const, ConstSignature, Static, 11 Const, ConstSignature, Static,
12 macros::MacroExpansion, 12 macros::MacroExpansion,
13 nameres::{Namespace, lower::{LoweredModule, ImportSourceMap}, crate_def_map::{RawItems, CrateDefMap}}, 13 nameres::{Namespace, lower::{ImportSourceMap}, crate_def_map::{RawItems, CrateDefMap}},
14 ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef, CallableDef, FnSig}, 14 ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef, CallableDef, FnSig},
15 adt::{StructData, EnumData}, 15 adt::{StructData, EnumData},
16 impl_block::{ModuleImplBlocks, ImplSourceMap}, 16 impl_block::{ModuleImplBlocks, ImplSourceMap},
@@ -38,18 +38,12 @@ pub trait PersistentHirDatabase: SourceDatabase + AsRef<HirInterner> {
38 #[salsa::invoke(crate::ids::SourceFileItems::file_item_query)] 38 #[salsa::invoke(crate::ids::SourceFileItems::file_item_query)]
39 fn file_item(&self, source_item_id: SourceItemId) -> TreeArc<SyntaxNode>; 39 fn file_item(&self, source_item_id: SourceItemId) -> TreeArc<SyntaxNode>;
40 40
41 #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_with_source_map_query)]
42 fn lower_module_with_source_map(
43 &self,
44 module: Module,
45 ) -> (Arc<LoweredModule>, Arc<ImportSourceMap>);
46
47 #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_query)]
48 fn lower_module(&self, module: Module) -> Arc<LoweredModule>;
49
50 #[salsa::invoke(RawItems::raw_items_query)] 41 #[salsa::invoke(RawItems::raw_items_query)]
51 fn raw_items(&self, file_id: FileId) -> Arc<RawItems>; 42 fn raw_items(&self, file_id: FileId) -> Arc<RawItems>;
52 43
44 #[salsa::invoke(RawItems::raw_items_with_source_map_query)]
45 fn raw_items_with_source_map(&self, file_id: FileId) -> (Arc<RawItems>, Arc<ImportSourceMap>);
46
53 #[salsa::invoke(CrateDefMap::crate_def_map_query)] 47 #[salsa::invoke(CrateDefMap::crate_def_map_query)]
54 fn crate_def_map(&self, krate: Crate) -> Arc<CrateDefMap>; 48 fn crate_def_map(&self, krate: Crate) -> Arc<CrateDefMap>;
55 49
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index 6ce00a372..2bd617436 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -83,13 +83,6 @@ impl HirFileId {
83 } 83 }
84 } 84 }
85 85
86 pub(crate) fn as_macro_call_id(self) -> Option<MacroCallId> {
87 match self.0 {
88 HirFileIdRepr::Macro(it) => Some(it),
89 _ => None,
90 }
91 }
92
93 pub(crate) fn hir_parse( 86 pub(crate) fn hir_parse(
94 db: &impl PersistentHirDatabase, 87 db: &impl PersistentHirDatabase,
95 file_id: HirFileId, 88 file_id: HirFileId,
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
index eb2d4ed8d..8807a4b56 100644
--- a/crates/ra_hir/src/impl_block.rs
+++ b/crates/ra_hir/src/impl_block.rs
@@ -4,7 +4,8 @@ use rustc_hash::FxHashMap;
4use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; 4use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
5use ra_syntax::{ 5use ra_syntax::{
6 AstPtr, SourceFile, TreeArc, 6 AstPtr, SourceFile, TreeArc,
7ast::{self, AstNode}}; 7 ast::{self, AstNode}
8};
8 9
9use crate::{ 10use crate::{
10 Const, TypeAlias, Function, HirFileId, 11 Const, TypeAlias, Function, HirFileId,
@@ -13,7 +14,7 @@ use crate::{
13 type_ref::TypeRef, 14 type_ref::TypeRef,
14 ids::LocationCtx, 15 ids::LocationCtx,
15 resolve::Resolver, 16 resolve::Resolver,
16 ty::Ty, generics::GenericParams 17 ty::Ty, generics::GenericParams,
17}; 18};
18 19
19use crate::code_model_api::{Module, ModuleSource}; 20use crate::code_model_api::{Module, ModuleSource};
diff --git a/crates/ra_hir/src/nameres/crate_def_map/collector.rs b/crates/ra_hir/src/nameres/crate_def_map/collector.rs
index 8b727e2c9..0f500ce42 100644
--- a/crates/ra_hir/src/nameres/crate_def_map/collector.rs
+++ b/crates/ra_hir/src/nameres/crate_def_map/collector.rs
@@ -224,7 +224,7 @@ where
224 } 224 }
225 } 225 }
226 let resolution = Resolution { def, import: Some(import_id) }; 226 let resolution = Resolution { def, import: Some(import_id) };
227 self.update(module_id, None, &[(name, resolution)]); 227 self.update(module_id, Some(import_id), &[(name, resolution)]);
228 } 228 }
229 } 229 }
230 230
@@ -262,6 +262,13 @@ where
262 existing.import = import.or(res.import); 262 existing.import = import.or(res.import);
263 changed = true; 263 changed = true;
264 } 264 }
265 if existing.def.is_none()
266 && res.def.is_none()
267 && existing.import.is_none()
268 && res.import.is_some()
269 {
270 existing.import = res.import;
271 }
265 } 272 }
266 if !changed { 273 if !changed {
267 return; 274 return;
diff --git a/crates/ra_hir/src/nameres/crate_def_map/raw.rs b/crates/ra_hir/src/nameres/crate_def_map/raw.rs
index f064f722c..dca86e394 100644
--- a/crates/ra_hir/src/nameres/crate_def_map/raw.rs
+++ b/crates/ra_hir/src/nameres/crate_def_map/raw.rs
@@ -14,6 +14,7 @@ use ra_syntax::{
14use crate::{ 14use crate::{
15 PersistentHirDatabase, Name, AsName, Path, HirFileId, 15 PersistentHirDatabase, Name, AsName, Path, HirFileId,
16 ids::{SourceFileItemId, SourceFileItems}, 16 ids::{SourceFileItemId, SourceFileItems},
17 nameres::lower::ImportSourceMap,
17}; 18};
18 19
19#[derive(Debug, Default, PartialEq, Eq)] 20#[derive(Debug, Default, PartialEq, Eq)]
@@ -31,13 +32,21 @@ impl RawItems {
31 db: &impl PersistentHirDatabase, 32 db: &impl PersistentHirDatabase,
32 file_id: FileId, 33 file_id: FileId,
33 ) -> Arc<RawItems> { 34 ) -> Arc<RawItems> {
35 db.raw_items_with_source_map(file_id).0
36 }
37
38 pub(crate) fn raw_items_with_source_map_query(
39 db: &impl PersistentHirDatabase,
40 file_id: FileId,
41 ) -> (Arc<RawItems>, Arc<ImportSourceMap>) {
34 let mut collector = RawItemsCollector { 42 let mut collector = RawItemsCollector {
35 raw_items: RawItems::default(), 43 raw_items: RawItems::default(),
36 source_file_items: db.file_items(file_id.into()), 44 source_file_items: db.file_items(file_id.into()),
45 source_map: ImportSourceMap::default(),
37 }; 46 };
38 let source_file = db.parse(file_id); 47 let source_file = db.parse(file_id);
39 collector.process_module(None, &*source_file); 48 collector.process_module(None, &*source_file);
40 Arc::new(collector.raw_items) 49 (Arc::new(collector.raw_items), Arc::new(collector.source_map))
41 } 50 }
42 51
43 pub(crate) fn items(&self) -> &[RawItem] { 52 pub(crate) fn items(&self) -> &[RawItem] {
@@ -51,6 +60,7 @@ impl RawItems {
51 let mut collector = RawItemsCollector { 60 let mut collector = RawItemsCollector {
52 raw_items: RawItems::default(), 61 raw_items: RawItems::default(),
53 source_file_items: Arc::new(source_file_items), 62 source_file_items: Arc::new(source_file_items),
63 source_map: ImportSourceMap::default(),
54 }; 64 };
55 collector.process_module(None, &*source_file); 65 collector.process_module(None, &*source_file);
56 collector.raw_items 66 collector.raw_items
@@ -144,6 +154,7 @@ pub(crate) struct MacroData {
144struct RawItemsCollector { 154struct RawItemsCollector {
145 raw_items: RawItems, 155 raw_items: RawItems,
146 source_file_items: Arc<SourceFileItems>, 156 source_file_items: Arc<SourceFileItems>,
157 source_map: ImportSourceMap,
147} 158}
148 159
149impl RawItemsCollector { 160impl RawItemsCollector {
@@ -227,6 +238,9 @@ impl RawItemsCollector {
227 is_prelude, 238 is_prelude,
228 is_extern_crate: false, 239 is_extern_crate: false,
229 }); 240 });
241 if let Some(segment) = segment {
242 self.source_map.insert(import, segment)
243 }
230 self.push_item(current_module, RawItem::Import(import)) 244 self.push_item(current_module, RawItem::Import(import))
231 }) 245 })
232 } 246 }
diff --git a/crates/ra_hir/src/nameres/lower.rs b/crates/ra_hir/src/nameres/lower.rs
index 24707aed1..d4c7f2481 100644
--- a/crates/ra_hir/src/nameres/lower.rs
+++ b/crates/ra_hir/src/nameres/lower.rs
@@ -1,18 +1,10 @@
1use std::sync::Arc;
2
3use ra_syntax::{ 1use ra_syntax::{
4 AstNode, SourceFile, TreeArc, AstPtr, 2 AstNode, SourceFile, TreeArc, AstPtr,
5 ast::{self, ModuleItemOwner, NameOwner, AttrsOwner}, 3 ast,
6}; 4};
7use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; 5use ra_arena::{RawId, impl_arena_id, map::ArenaMap};
8use rustc_hash::FxHashMap;
9 6
10use crate::{ 7use crate::{Path, ModuleSource, Name};
11 SourceItemId, Path, ModuleSource, Name,
12 HirFileId, MacroCallLoc, AsName, PerNs, Function,
13 ModuleDef, Module, Struct, Enum, Const, Static, Trait, TypeAlias,
14 ids::LocationCtx, PersistentHirDatabase,
15};
16 8
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18pub struct ImportId(RawId); 10pub struct ImportId(RawId);
@@ -27,25 +19,13 @@ pub struct ImportData {
27 pub(super) is_extern_crate: bool, 19 pub(super) is_extern_crate: bool,
28} 20}
29 21
30/// A set of items and imports declared inside a module, without relation to
31/// other modules.
32///
33/// This sits in-between raw syntax and name resolution and allows us to avoid
34/// recomputing name res: if two instance of `InputModuleItems` are the same, we
35/// can avoid redoing name resolution.
36#[derive(Debug, Default, PartialEq, Eq)]
37pub struct LoweredModule {
38 pub(crate) declarations: FxHashMap<Name, PerNs<ModuleDef>>,
39 pub(super) imports: Arena<ImportId, ImportData>,
40}
41
42#[derive(Debug, Default, PartialEq, Eq)] 22#[derive(Debug, Default, PartialEq, Eq)]
43pub struct ImportSourceMap { 23pub struct ImportSourceMap {
44 map: ArenaMap<ImportId, AstPtr<ast::PathSegment>>, 24 map: ArenaMap<ImportId, AstPtr<ast::PathSegment>>,
45} 25}
46 26
47impl ImportSourceMap { 27impl ImportSourceMap {
48 fn insert(&mut self, import: ImportId, segment: &ast::PathSegment) { 28 pub(crate) fn insert(&mut self, import: ImportId, segment: &ast::PathSegment) {
49 self.map.insert(import, AstPtr::new(segment)) 29 self.map.insert(import, AstPtr::new(segment))
50 } 30 }
51 31
@@ -58,165 +38,3 @@ impl ImportSourceMap {
58 self.map[import].to_node(file).to_owned() 38 self.map[import].to_node(file).to_owned()
59 } 39 }
60} 40}
61
62impl LoweredModule {
63 pub(crate) fn lower_module_query(
64 db: &impl PersistentHirDatabase,
65 module: Module,
66 ) -> Arc<LoweredModule> {
67 db.lower_module_with_source_map(module).0
68 }
69
70 pub(crate) fn lower_module_with_source_map_query(
71 db: &impl PersistentHirDatabase,
72 module: Module,
73 ) -> (Arc<LoweredModule>, Arc<ImportSourceMap>) {
74 let (file_id, source) = module.definition_source(db);
75 let file_id: HirFileId = file_id.into();
76 let mut source_map = ImportSourceMap::default();
77 let mut res = LoweredModule::default();
78 match source {
79 ModuleSource::SourceFile(it) => {
80 res.fill(&mut source_map, db, module, file_id, &mut it.items_with_macros())
81 }
82 ModuleSource::Module(it) => {
83 if let Some(item_list) = it.item_list() {
84 res.fill(
85 &mut source_map,
86 db,
87 module,
88 file_id,
89 &mut item_list.items_with_macros(),
90 )
91 }
92 }
93 };
94 (Arc::new(res), Arc::new(source_map))
95 }
96
97 fn fill(
98 &mut self,
99 source_map: &mut ImportSourceMap,
100 db: &impl PersistentHirDatabase,
101 module: Module,
102 file_id: HirFileId,
103 items: &mut Iterator<Item = ast::ItemOrMacro>,
104 ) {
105 let file_items = db.file_items(file_id);
106
107 for item in items {
108 match item {
109 ast::ItemOrMacro::Item(it) => {
110 self.add_def_id(source_map, db, module, file_id, it);
111 }
112 ast::ItemOrMacro::Macro(macro_call) => {
113 let item_id = file_items.id_of_unchecked(macro_call.syntax());
114 let loc =
115 MacroCallLoc { module, source_item_id: SourceItemId { file_id, item_id } };
116 let id = loc.id(db);
117 let file_id = HirFileId::from(id);
118 //FIXME: expand recursively
119 for item in db.hir_parse(file_id).items() {
120 self.add_def_id(source_map, db, module, file_id, item);
121 }
122 }
123 }
124 }
125 }
126
127 fn add_def_id(
128 &mut self,
129 source_map: &mut ImportSourceMap,
130 db: &impl PersistentHirDatabase,
131 module: Module,
132 file_id: HirFileId,
133 item: &ast::ModuleItem,
134 ) {
135 let ctx = LocationCtx::new(db, module, file_id);
136 match item.kind() {
137 ast::ModuleItemKind::StructDef(it) => {
138 if let Some(name) = it.name() {
139 let s = Struct { id: ctx.to_def(it) };
140 let s: ModuleDef = s.into();
141 self.declarations.insert(name.as_name(), PerNs::both(s, s));
142 }
143 }
144 ast::ModuleItemKind::EnumDef(it) => {
145 if let Some(name) = it.name() {
146 let e = Enum { id: ctx.to_def(it) };
147 let e: ModuleDef = e.into();
148 self.declarations.insert(name.as_name(), PerNs::types(e));
149 }
150 }
151 ast::ModuleItemKind::FnDef(it) => {
152 if let Some(name) = it.name() {
153 let func = Function { id: ctx.to_def(it) };
154 self.declarations.insert(name.as_name(), PerNs::values(func.into()));
155 }
156 }
157 ast::ModuleItemKind::TraitDef(it) => {
158 if let Some(name) = it.name() {
159 let t = Trait { id: ctx.to_def(it) };
160 self.declarations.insert(name.as_name(), PerNs::types(t.into()));
161 }
162 }
163 ast::ModuleItemKind::TypeAliasDef(it) => {
164 if let Some(name) = it.name() {
165 let t = TypeAlias { id: ctx.to_def(it) };
166 self.declarations.insert(name.as_name(), PerNs::types(t.into()));
167 }
168 }
169 ast::ModuleItemKind::ImplBlock(_) => {
170 // impls don't define items
171 }
172 ast::ModuleItemKind::UseItem(it) => {
173 self.add_use_item(source_map, it);
174 }
175 ast::ModuleItemKind::ExternCrateItem(it) => {
176 if let Some(name_ref) = it.name_ref() {
177 let path = Path::from_name_ref(name_ref);
178 let alias = it.alias().and_then(|a| a.name()).map(AsName::as_name);
179 self.imports.alloc(ImportData {
180 path,
181 alias,
182 is_glob: false,
183 is_prelude: false,
184 is_extern_crate: true,
185 });
186 }
187 }
188 ast::ModuleItemKind::ConstDef(it) => {
189 if let Some(name) = it.name() {
190 let c = Const { id: ctx.to_def(it) };
191 self.declarations.insert(name.as_name(), PerNs::values(c.into()));
192 }
193 }
194 ast::ModuleItemKind::StaticDef(it) => {
195 if let Some(name) = it.name() {
196 let s = Static { id: ctx.to_def(it) };
197 self.declarations.insert(name.as_name(), PerNs::values(s.into()));
198 }
199 }
200 ast::ModuleItemKind::Module(_) => {
201 // modules are handled separately directly by name res
202 }
203 };
204 }
205
206 fn add_use_item(&mut self, source_map: &mut ImportSourceMap, item: &ast::UseItem) {
207 let is_prelude =
208 item.attrs().any(|attr| attr.as_atom().map(|s| s == "prelude_import").unwrap_or(false));
209 Path::expand_use_item(item, |path, segment, alias| {
210 let import = self.imports.alloc(ImportData {
211 path,
212 alias,
213 is_glob: segment.is_none(),
214 is_prelude,
215 is_extern_crate: false,
216 });
217 if let Some(segment) = segment {
218 source_map.insert(import, segment)
219 }
220 })
221 }
222}
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 62b699a64..902110913 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -7,13 +7,13 @@
7/// purely for "IDE needs". 7/// purely for "IDE needs".
8use ra_db::{FileId, FilePosition}; 8use ra_db::{FileId, FilePosition};
9use ra_syntax::{ 9use ra_syntax::{
10 SmolStr, TextRange, SyntaxNode, 10 SyntaxNode,
11 ast::{self, AstNode, NameOwner}, 11 ast::{self, AstNode, NameOwner},
12 algo::{find_node_at_offset, find_leaf_at_offset}, 12 algo::{find_node_at_offset, find_leaf_at_offset},
13}; 13};
14 14
15use crate::{ 15use crate::{
16 HirDatabase, Function, ModuleDef, Struct, Enum, 16 HirDatabase, Function, Struct, Enum,
17 AsName, Module, HirFileId, Crate, Trait, Resolver, 17 AsName, Module, HirFileId, Crate, Trait, Resolver,
18 ids::{LocationCtx, SourceFileItemId}, 18 ids::{LocationCtx, SourceFileItemId},
19 expr 19 expr
@@ -152,44 +152,6 @@ pub fn trait_from_module(
152 Trait { id: ctx.to_def(trait_def) } 152 Trait { id: ctx.to_def(trait_def) }
153} 153}
154 154
155pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, TextRange)> {
156 let module = match module_from_file_id(db, file_id) {
157 Some(it) => it,
158 None => return Vec::new(),
159 };
160 let items = db.lower_module(module);
161 let mut res = Vec::new();
162
163 for macro_call_id in items
164 .declarations
165 .iter()
166 .filter_map(|(_, it)| it.clone().take_types())
167 .filter_map(|it| match it {
168 ModuleDef::Trait(it) => Some(it),
169 _ => None,
170 })
171 .filter_map(|it| it.source(db).0.as_macro_call_id())
172 {
173 if let Some(exp) = db.expand_macro_invocation(macro_call_id) {
174 let loc = macro_call_id.loc(db);
175 let syntax = db.file_item(loc.source_item_id);
176 let macro_call = ast::MacroCall::cast(&syntax).unwrap();
177 let off = macro_call.token_tree().unwrap().syntax().range().start();
178 let file = exp.file();
179 for trait_def in file.syntax().descendants().filter_map(ast::TraitDef::cast) {
180 if let Some(name) = trait_def.name() {
181 let dst_range = name.syntax().range();
182 if let Some(src_range) = exp.map_range_back(dst_range) {
183 res.push((name.text().clone(), src_range + off))
184 }
185 }
186 }
187 }
188 }
189
190 res
191}
192
193pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> Resolver { 155pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> Resolver {
194 let file_id = position.file_id; 156 let file_id = position.file_id;
195 let file = db.parse(file_id); 157 let file = db.parse(file_id);