From ffc2325d194d2523456484a7dec1f175c729c1b5 Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Sat, 23 Nov 2019 17:06:04 +0300
Subject: [PATCH] Move ModuleSource back to hir

---
 crates/ra_hir/src/code_model.rs      | 65 ++++++++++++++++++++++++++--
 crates/ra_hir/src/code_model/src.rs  |  4 +-
 crates/ra_hir_def/src/lib.rs         | 62 +-------------------------
 crates/ra_hir_def/src/nameres/raw.rs | 18 ++------
 4 files changed, 71 insertions(+), 78 deletions(-)

diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index cd178bf887b..fd7776fb79d 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -18,9 +18,10 @@ use hir_def::{
 use hir_expand::{
     diagnostics::DiagnosticSink,
     name::{self, AsName},
+    AstId,
 };
-use ra_db::{CrateId, Edition};
-use ra_syntax::ast;
+use ra_db::{CrateId, Edition, FileId, FilePosition};
+use ra_syntax::{ast, AstNode, SyntaxNode};
 
 use crate::{
     db::{DefDatabase, HirDatabase},
@@ -78,6 +79,64 @@ impl Crate {
     }
 }
 
+pub enum ModuleSource {
+    SourceFile(ast::SourceFile),
+    Module(ast::Module),
+}
+
+impl ModuleSource {
+    pub fn new(
+        db: &impl DefDatabase,
+        file_id: Option<FileId>,
+        decl_id: Option<AstId<ast::Module>>,
+    ) -> ModuleSource {
+        match (file_id, decl_id) {
+            (Some(file_id), _) => {
+                let source_file = db.parse(file_id).tree();
+                ModuleSource::SourceFile(source_file)
+            }
+            (None, Some(item_id)) => {
+                let module = item_id.to_node(db);
+                assert!(module.item_list().is_some(), "expected inline module");
+                ModuleSource::Module(module)
+            }
+            (None, None) => panic!(),
+        }
+    }
+
+    // FIXME: this methods do not belong here
+    pub fn from_position(db: &impl DefDatabase, position: FilePosition) -> ModuleSource {
+        let parse = db.parse(position.file_id);
+        match &ra_syntax::algo::find_node_at_offset::<ast::Module>(
+            parse.tree().syntax(),
+            position.offset,
+        ) {
+            Some(m) if !m.has_semi() => ModuleSource::Module(m.clone()),
+            _ => {
+                let source_file = parse.tree();
+                ModuleSource::SourceFile(source_file)
+            }
+        }
+    }
+
+    pub fn from_child_node(db: &impl DefDatabase, child: Source<&SyntaxNode>) -> ModuleSource {
+        if let Some(m) =
+            child.value.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi())
+        {
+            ModuleSource::Module(m)
+        } else {
+            let file_id = child.file_id.original_file(db);
+            let source_file = db.parse(file_id).tree();
+            ModuleSource::SourceFile(source_file)
+        }
+    }
+
+    pub fn from_file_id(db: &impl DefDatabase, file_id: FileId) -> ModuleSource {
+        let source_file = db.parse(file_id).tree();
+        ModuleSource::SourceFile(source_file)
+    }
+}
+
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct Module {
     pub(crate) id: ModuleId,
@@ -109,7 +168,7 @@ impl_froms!(
     BuiltinType
 );
 
-pub use hir_def::{attr::Attrs, ModuleSource};
+pub use hir_def::attr::Attrs;
 
 impl Module {
     pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module {
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs
index 402f821bf9f..b7bafe23df7 100644
--- a/crates/ra_hir/src/code_model/src.rs
+++ b/crates/ra_hir/src/code_model/src.rs
@@ -117,7 +117,9 @@ impl HasSource for Import {
     fn source(self, db: &impl DefDatabase) -> Source<Self::Ast> {
         let src = self.parent.definition_source(db);
         let (_, source_map) = db.raw_items_with_source_map(src.file_id);
-        src.with_value(source_map.get(&src.value, self.id))
+        let root = db.parse_or_expand(src.file_id).unwrap();
+        let ptr = source_map.get(self.id);
+        src.with_value(ptr.map(|it| it.to_node(&root), |it| it.to_node(&root)))
     }
 }
 
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index 11ae9cdc0f3..1d195d65d08 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -35,69 +35,11 @@ use std::hash::{Hash, Hasher};
 
 use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, MacroDefId, Source};
 use ra_arena::{impl_arena_id, map::ArenaMap, RawId};
-use ra_db::{salsa, CrateId, FileId};
-use ra_syntax::{ast, AstNode, SyntaxNode};
+use ra_db::{salsa, CrateId};
+use ra_syntax::{ast, AstNode};
 
 use crate::{builtin_type::BuiltinType, db::InternDatabase};
 
-pub enum ModuleSource {
-    SourceFile(ast::SourceFile),
-    Module(ast::Module),
-}
-
-impl ModuleSource {
-    pub fn new(
-        db: &impl db::DefDatabase,
-        file_id: Option<FileId>,
-        decl_id: Option<AstId<ast::Module>>,
-    ) -> ModuleSource {
-        match (file_id, decl_id) {
-            (Some(file_id), _) => {
-                let source_file = db.parse(file_id).tree();
-                ModuleSource::SourceFile(source_file)
-            }
-            (None, Some(item_id)) => {
-                let module = item_id.to_node(db);
-                assert!(module.item_list().is_some(), "expected inline module");
-                ModuleSource::Module(module)
-            }
-            (None, None) => panic!(),
-        }
-    }
-
-    // FIXME: this methods do not belong here
-    pub fn from_position(db: &impl db::DefDatabase, position: ra_db::FilePosition) -> ModuleSource {
-        let parse = db.parse(position.file_id);
-        match &ra_syntax::algo::find_node_at_offset::<ast::Module>(
-            parse.tree().syntax(),
-            position.offset,
-        ) {
-            Some(m) if !m.has_semi() => ModuleSource::Module(m.clone()),
-            _ => {
-                let source_file = parse.tree();
-                ModuleSource::SourceFile(source_file)
-            }
-        }
-    }
-
-    pub fn from_child_node(db: &impl db::DefDatabase, child: Source<&SyntaxNode>) -> ModuleSource {
-        if let Some(m) =
-            child.value.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi())
-        {
-            ModuleSource::Module(m)
-        } else {
-            let file_id = child.file_id.original_file(db);
-            let source_file = db.parse(file_id).tree();
-            ModuleSource::SourceFile(source_file)
-        }
-    }
-
-    pub fn from_file_id(db: &impl db::DefDatabase, file_id: FileId) -> ModuleSource {
-        let source_file = db.parse(file_id).tree();
-        ModuleSource::SourceFile(source_file)
-    }
-}
-
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct LocalImportId(RawId);
 impl_arena_id!(LocalImportId);
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs
index 8ee6f54cdc7..552cbe5448a 100644
--- a/crates/ra_hir_def/src/nameres/raw.rs
+++ b/crates/ra_hir_def/src/nameres/raw.rs
@@ -12,7 +12,7 @@ use hir_expand::{
 use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId};
 use ra_syntax::{
     ast::{self, AttrsOwner, NameOwner},
-    AstNode, AstPtr, SourceFile,
+    AstNode, AstPtr,
 };
 use test_utils::tested_by;
 
@@ -20,7 +20,7 @@ use crate::{
     attr::{Attr, Attrs},
     db::DefDatabase,
     path::Path,
-    FileAstId, HirFileId, LocalImportId, ModuleSource, Source,
+    FileAstId, HirFileId, LocalImportId, Source,
 };
 
 /// `RawItems` is a set of top-level items in a file (except for impls).
@@ -44,24 +44,14 @@ pub struct ImportSourceMap {
 }
 
 type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>;
-type ImportSource = Either<ast::UseTree, ast::ExternCrateItem>;
-
-fn to_node(ptr: ImportSourcePtr, file: &SourceFile) -> ImportSource {
-    ptr.map(|ptr| ptr.to_node(file.syntax()), |ptr| ptr.to_node(file.syntax()))
-}
 
 impl ImportSourceMap {
     fn insert(&mut self, import: LocalImportId, ptr: ImportSourcePtr) {
         self.map.insert(import, ptr)
     }
 
-    pub fn get(&self, source: &ModuleSource, import: LocalImportId) -> ImportSource {
-        let file = match source {
-            ModuleSource::SourceFile(file) => file.clone(),
-            ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(),
-        };
-
-        to_node(self.map[import], &file)
+    pub fn get(&self, import: LocalImportId) -> ImportSourcePtr {
+        self.map[import].clone()
     }
 }