diff options
author | Florian Diebold <[email protected]> | 2019-08-30 19:16:28 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-09-02 13:56:38 +0100 |
commit | f92177cfb5088809892455262841e24cf1ecf5b6 (patch) | |
tree | 789f733506520663e6cb5f99eec7d56c1a443831 | |
parent | a7858bb7bf0a784d56b2b9ef97785a4fa78f7853 (diff) |
Add an expr_source method analogous to the source methods in the code model
... and use that instead of exposing the source map.
-rw-r--r-- | crates/ra_cli/src/analysis_stats.rs | 53 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 51 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model/src.rs | 30 | ||||
-rw-r--r-- | crates/ra_hir/src/expr.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/src/ptr.rs | 5 |
8 files changed, 107 insertions, 60 deletions
diff --git a/crates/ra_cli/src/analysis_stats.rs b/crates/ra_cli/src/analysis_stats.rs index 77fa1d26e..d355fa2e8 100644 --- a/crates/ra_cli/src/analysis_stats.rs +++ b/crates/ra_cli/src/analysis_stats.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use std::{collections::HashSet, fmt::Write, path::Path, time::Instant}; | 1 | use std::{collections::HashSet, fmt::Write, path::Path, time::Instant}; |
2 | 2 | ||
3 | use ra_db::SourceDatabase; | 3 | use ra_db::SourceDatabase; |
4 | use ra_hir::{Crate, HasSource, HirDisplay, ImplItem, ModuleDef, Ty}; | 4 | use ra_hir::{Crate, HasBodySource, HasSource, HirDisplay, ImplItem, ModuleDef, Ty}; |
5 | use ra_syntax::AstNode; | 5 | use ra_syntax::AstNode; |
6 | 6 | ||
7 | use crate::Result; | 7 | use crate::Result; |
@@ -104,35 +104,34 @@ pub fn run(verbose: bool, memory_usage: bool, path: &Path, only: Option<&str>) - | |||
104 | if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr_id) { | 104 | if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr_id) { |
105 | num_type_mismatches += 1; | 105 | num_type_mismatches += 1; |
106 | if verbose { | 106 | if verbose { |
107 | let src = f.source(db); | 107 | let src = f.expr_source(db, expr_id); |
108 | let original_file = src.file_id.original_file(db); | 108 | if let Some(src) = src { |
109 | let path = db.file_relative_path(original_file); | 109 | // FIXME: it might be nice to have a function (on Analysis?) that goes from Source<T> -> (LineCol, LineCol) directly |
110 | let line_index = host.analysis().file_line_index(original_file).unwrap(); | 110 | let original_file = src.file_id.original_file(db); |
111 | let body_source_map = f.body_source_map(db); | 111 | let path = db.file_relative_path(original_file); |
112 | let syntax_node = body_source_map.expr_syntax(expr_id); | 112 | let line_index = host.analysis().file_line_index(original_file).unwrap(); |
113 | let line_col = syntax_node.map(|syntax_node| { | 113 | let (start, end) = ( |
114 | ( | 114 | line_index.line_col(src.ast.syntax().text_range().start()), |
115 | line_index.line_col(syntax_node.range().start()), | 115 | line_index.line_col(src.ast.syntax().text_range().end()), |
116 | line_index.line_col(syntax_node.range().end()), | 116 | ); |
117 | ) | 117 | bar.println(format!( |
118 | }); | 118 | "{} {}:{}-{}:{}: Expected {}, got {}", |
119 | let line_col = match line_col { | 119 | path.display(), |
120 | Some((start, end)) => format!( | ||
121 | "{}:{}-{}:{}", | ||
122 | start.line + 1, | 120 | start.line + 1, |
123 | start.col_utf16, | 121 | start.col_utf16, |
124 | end.line + 1, | 122 | end.line + 1, |
125 | end.col_utf16 | 123 | end.col_utf16, |
126 | ), | 124 | mismatch.expected.display(db), |
127 | None => "?:?".to_string(), | 125 | mismatch.actual.display(db) |
128 | }; | 126 | )); |
129 | bar.println(format!( | 127 | } else { |
130 | "{} {}: Expected {}, got {}", | 128 | bar.println(format!( |
131 | path.display(), | 129 | "{}: Expected {}, got {}", |
132 | line_col, | 130 | name, |
133 | mismatch.expected.display(db), | 131 | mismatch.expected.display(db), |
134 | mismatch.actual.display(db) | 132 | mismatch.actual.display(db) |
135 | )); | 133 | )); |
134 | } | ||
136 | } | 135 | } |
137 | } | 136 | } |
138 | } | 137 | } |
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 0f9ff97f1..f7efc1b66 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -510,18 +510,6 @@ pub enum DefWithBody { | |||
510 | impl_froms!(DefWithBody: Function, Const, Static); | 510 | impl_froms!(DefWithBody: Function, Const, Static); |
511 | 511 | ||
512 | impl DefWithBody { | 512 | impl DefWithBody { |
513 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | ||
514 | db.infer(self) | ||
515 | } | ||
516 | |||
517 | pub fn body(self, db: &impl HirDatabase) -> Arc<Body> { | ||
518 | db.body_hir(self) | ||
519 | } | ||
520 | |||
521 | pub fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | ||
522 | db.body_with_source_map(self).1 | ||
523 | } | ||
524 | |||
525 | /// Builds a resolver for code inside this item. | 513 | /// Builds a resolver for code inside this item. |
526 | pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { | 514 | pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { |
527 | match self { | 515 | match self { |
@@ -532,6 +520,43 @@ impl DefWithBody { | |||
532 | } | 520 | } |
533 | } | 521 | } |
534 | 522 | ||
523 | pub trait HasBody: Copy { | ||
524 | fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult>; | ||
525 | fn body(self, db: &impl HirDatabase) -> Arc<Body>; | ||
526 | fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap>; | ||
527 | } | ||
528 | |||
529 | impl<T> HasBody for T | ||
530 | where | ||
531 | T: Into<DefWithBody> + Copy + HasSource, | ||
532 | { | ||
533 | fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | ||
534 | db.infer(self.into()) | ||
535 | } | ||
536 | |||
537 | fn body(self, db: &impl HirDatabase) -> Arc<Body> { | ||
538 | db.body_hir(self.into()) | ||
539 | } | ||
540 | |||
541 | fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | ||
542 | db.body_with_source_map(self.into()).1 | ||
543 | } | ||
544 | } | ||
545 | |||
546 | impl HasBody for DefWithBody { | ||
547 | fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | ||
548 | db.infer(self) | ||
549 | } | ||
550 | |||
551 | fn body(self, db: &impl HirDatabase) -> Arc<Body> { | ||
552 | db.body_hir(self) | ||
553 | } | ||
554 | |||
555 | fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | ||
556 | db.body_with_source_map(self).1 | ||
557 | } | ||
558 | } | ||
559 | |||
535 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 560 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
536 | pub struct Function { | 561 | pub struct Function { |
537 | pub(crate) id: FunctionId, | 562 | pub(crate) id: FunctionId, |
@@ -617,7 +642,7 @@ impl Function { | |||
617 | self.data(db).name.clone() | 642 | self.data(db).name.clone() |
618 | } | 643 | } |
619 | 644 | ||
620 | pub fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | 645 | pub(crate) fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { |
621 | db.body_with_source_map(self.into()).1 | 646 | db.body_with_source_map(self.into()).1 |
622 | } | 647 | } |
623 | 648 | ||
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs index 32bd9c661..e5bae16ab 100644 --- a/crates/ra_hir/src/code_model/src.rs +++ b/crates/ra_hir/src/code_model/src.rs | |||
@@ -1,9 +1,9 @@ | |||
1 | use ra_syntax::ast; | 1 | use ra_syntax::ast::{self, AstNode}; |
2 | 2 | ||
3 | use crate::{ | 3 | use crate::{ |
4 | ids::AstItemDef, AstDatabase, Const, DefDatabase, Enum, EnumVariant, FieldSource, Function, | 4 | ids::AstItemDef, AstDatabase, Const, DefDatabase, Enum, EnumVariant, FieldSource, Function, |
5 | HirFileId, MacroDef, Module, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, | 5 | HasBody, HirDatabase, HirFileId, MacroDef, Module, ModuleSource, Static, Struct, StructField, |
6 | Union, | 6 | Trait, TypeAlias, Union, |
7 | }; | 7 | }; |
8 | 8 | ||
9 | pub struct Source<T> { | 9 | pub struct Source<T> { |
@@ -108,3 +108,27 @@ impl HasSource for MacroDef { | |||
108 | Source { file_id: self.id.0.file_id(), ast: self.id.0.to_node(db) } | 108 | Source { file_id: self.id.0.file_id(), ast: self.id.0.to_node(db) } |
109 | } | 109 | } |
110 | } | 110 | } |
111 | |||
112 | pub trait HasBodySource: HasBody + HasSource | ||
113 | where | ||
114 | Self::Ast: AstNode, | ||
115 | { | ||
116 | fn expr_source( | ||
117 | self, | ||
118 | db: &impl HirDatabase, | ||
119 | expr_id: crate::expr::ExprId, | ||
120 | ) -> Option<Source<ast::Expr>> { | ||
121 | let source_map = self.body_source_map(db); | ||
122 | let expr_syntax = source_map.expr_syntax(expr_id)?; | ||
123 | let source = self.source(db); | ||
124 | let node = expr_syntax.to_node(&source.ast.syntax()); | ||
125 | ast::Expr::cast(node).map(|ast| Source { file_id: source.file_id, ast }) | ||
126 | } | ||
127 | } | ||
128 | |||
129 | impl<T> HasBodySource for T | ||
130 | where | ||
131 | T: HasBody + HasSource, | ||
132 | T::Ast: AstNode, | ||
133 | { | ||
134 | } | ||
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 57225ae91..7cdc7555c 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -128,27 +128,27 @@ impl Index<PatId> for Body { | |||
128 | } | 128 | } |
129 | 129 | ||
130 | impl BodySourceMap { | 130 | impl BodySourceMap { |
131 | pub fn expr_syntax(&self, expr: ExprId) -> Option<SyntaxNodePtr> { | 131 | pub(crate) fn expr_syntax(&self, expr: ExprId) -> Option<SyntaxNodePtr> { |
132 | self.expr_map_back.get(expr).cloned() | 132 | self.expr_map_back.get(expr).cloned() |
133 | } | 133 | } |
134 | 134 | ||
135 | pub fn syntax_expr(&self, ptr: SyntaxNodePtr) -> Option<ExprId> { | 135 | pub(crate) fn syntax_expr(&self, ptr: SyntaxNodePtr) -> Option<ExprId> { |
136 | self.expr_map.get(&ptr).cloned() | 136 | self.expr_map.get(&ptr).cloned() |
137 | } | 137 | } |
138 | 138 | ||
139 | pub fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> { | 139 | pub(crate) fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> { |
140 | self.expr_map.get(&SyntaxNodePtr::new(node.syntax())).cloned() | 140 | self.expr_map.get(&SyntaxNodePtr::new(node.syntax())).cloned() |
141 | } | 141 | } |
142 | 142 | ||
143 | pub fn pat_syntax(&self, pat: PatId) -> Option<PatPtr> { | 143 | pub(crate) fn pat_syntax(&self, pat: PatId) -> Option<PatPtr> { |
144 | self.pat_map_back.get(pat).cloned() | 144 | self.pat_map_back.get(pat).cloned() |
145 | } | 145 | } |
146 | 146 | ||
147 | pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { | 147 | pub(crate) fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { |
148 | self.pat_map.get(&Either::A(AstPtr::new(node))).cloned() | 148 | self.pat_map.get(&Either::A(AstPtr::new(node))).cloned() |
149 | } | 149 | } |
150 | 150 | ||
151 | pub fn field_syntax(&self, expr: ExprId, field: usize) -> AstPtr<ast::RecordField> { | 151 | pub(crate) fn field_syntax(&self, expr: ExprId, field: usize) -> AstPtr<ast::RecordField> { |
152 | self.field_map[&(expr, field)] | 152 | self.field_map[&(expr, field)] |
153 | } | 153 | } |
154 | } | 154 | } |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 018fcd096..752653ad7 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -75,8 +75,8 @@ pub use self::{ | |||
75 | 75 | ||
76 | pub use self::code_model::{ | 76 | pub use self::code_model::{ |
77 | docs::{DocDef, Docs, Documentation}, | 77 | docs::{DocDef, Docs, Documentation}, |
78 | src::{HasSource, Source}, | 78 | src::{HasBodySource, HasSource, Source}, |
79 | BuiltinType, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, | 79 | BuiltinType, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, |
80 | EnumVariant, FieldSource, FnData, Function, MacroDef, Module, ModuleDef, ModuleSource, Static, | 80 | EnumVariant, FieldSource, FnData, Function, HasBody, MacroDef, Module, ModuleDef, ModuleSource, |
81 | Struct, StructField, Trait, TypeAlias, Union, | 81 | Static, Struct, StructField, Trait, TypeAlias, Union, |
82 | }; | 82 | }; |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 56ff7da3a..43aec201a 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -27,9 +27,9 @@ use crate::{ | |||
27 | name, | 27 | name, |
28 | path::{PathKind, PathSegment}, | 28 | path::{PathKind, PathSegment}, |
29 | ty::method_resolution::implements_trait, | 29 | ty::method_resolution::implements_trait, |
30 | AsName, AstId, Const, Crate, DefWithBody, Either, Enum, Function, HirDatabase, HirFileId, | 30 | AsName, AstId, Const, Crate, DefWithBody, Either, Enum, Function, HasBody, HirDatabase, |
31 | MacroDef, Module, ModuleDef, Name, Path, PerNs, Resolution, Resolver, Static, Struct, Trait, | 31 | HirFileId, MacroDef, Module, ModuleDef, Name, Path, PerNs, Resolution, Resolver, Static, |
32 | Ty, | 32 | Struct, Trait, Ty, |
33 | }; | 33 | }; |
34 | 34 | ||
35 | /// Locates the module by `FileId`. Picks topmost module in the file. | 35 | /// Locates the module by `FileId`. Picks topmost module in the file. |
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 812990426..9ba146299 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -50,8 +50,8 @@ use crate::{ | |||
50 | }, | 50 | }, |
51 | ty::infer::diagnostics::InferenceDiagnostic, | 51 | ty::infer::diagnostics::InferenceDiagnostic, |
52 | type_ref::{Mutability, TypeRef}, | 52 | type_ref::{Mutability, TypeRef}, |
53 | AdtDef, ConstData, DefWithBody, FnData, Function, HirDatabase, ImplItem, ModuleDef, Name, Path, | 53 | AdtDef, ConstData, DefWithBody, FnData, Function, HasBody, HirDatabase, ImplItem, ModuleDef, |
54 | StructField, | 54 | Name, Path, StructField, |
55 | }; | 55 | }; |
56 | 56 | ||
57 | mod unify; | 57 | mod unify; |
diff --git a/crates/ra_syntax/src/ptr.rs b/crates/ra_syntax/src/ptr.rs index 992034ef0..80e55d2aa 100644 --- a/crates/ra_syntax/src/ptr.rs +++ b/crates/ra_syntax/src/ptr.rs | |||
@@ -15,9 +15,8 @@ impl SyntaxNodePtr { | |||
15 | SyntaxNodePtr { range: node.text_range(), kind: node.kind() } | 15 | SyntaxNodePtr { range: node.text_range(), kind: node.kind() } |
16 | } | 16 | } |
17 | 17 | ||
18 | pub fn to_node(self, root: &SyntaxNode) -> SyntaxNode { | 18 | pub fn to_node(self, parent: &SyntaxNode) -> SyntaxNode { |
19 | assert!(root.parent().is_none()); | 19 | successors(Some(parent.clone()), |node| { |
20 | successors(Some(root.clone()), |node| { | ||
21 | node.children().find(|it| self.range.is_subrange(&it.text_range())) | 20 | node.children().find(|it| self.range.is_subrange(&it.text_range())) |
22 | }) | 21 | }) |
23 | .find(|it| it.text_range() == self.range && it.kind() == self.kind) | 22 | .find(|it| it.text_range() == self.range && it.kind() == self.kind) |