diff options
author | Florian Diebold <[email protected]> | 2018-12-23 11:05:54 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2018-12-23 12:48:04 +0000 |
commit | 7348f7883fa2bd571fff036c82e98c102d05c362 (patch) | |
tree | e7882097498b6d85e631d570dac0d8a89cd24875 /crates/ra_hir | |
parent | 3899898d75176ce3cd87f9e2acecd7e3a987dda5 (diff) |
Add testing infrastructure for type inference
- move dir_tests to test_utils for that.
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/mock.rs | 9 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 30 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 62 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests/data/0001_basics.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests/data/0001_basics.txt | 13 |
5 files changed, 102 insertions, 23 deletions
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index a9fa540d5..3020ee793 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs | |||
@@ -24,6 +24,15 @@ impl MockDatabase { | |||
24 | (db, source_root) | 24 | (db, source_root) |
25 | } | 25 | } |
26 | 26 | ||
27 | pub(crate) fn with_single_file(text: &str) -> (MockDatabase, SourceRoot, FileId) { | ||
28 | let mut db = MockDatabase::default(); | ||
29 | let mut source_root = SourceRoot::default(); | ||
30 | let file_id = db.add_file(&mut source_root, "/main.rs", text); | ||
31 | db.query_mut(ra_db::SourceRootQuery) | ||
32 | .set(WORKSPACE, Arc::new(source_root.clone())); | ||
33 | (db, source_root, file_id) | ||
34 | } | ||
35 | |||
27 | pub(crate) fn with_position(fixture: &str) -> (MockDatabase, FilePosition) { | 36 | pub(crate) fn with_position(fixture: &str) -> (MockDatabase, FilePosition) { |
28 | let (db, _, position) = MockDatabase::from_fixture(fixture); | 37 | let (db, _, position) = MockDatabase::from_fixture(fixture); |
29 | let position = position.expect("expected a marker ( <|> )"); | 38 | let position = position.expect("expected a marker ( <|> )"); |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 087385b98..66b204dcd 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -6,6 +6,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; | |||
6 | 6 | ||
7 | use std::sync::Arc; | 7 | use std::sync::Arc; |
8 | use std::collections::HashMap; | 8 | use std::collections::HashMap; |
9 | use std::fmt; | ||
9 | 10 | ||
10 | use ra_db::LocalSyntaxPtr; | 11 | use ra_db::LocalSyntaxPtr; |
11 | use ra_syntax::{ | 12 | use ra_syntax::{ |
@@ -184,11 +185,40 @@ impl Ty { | |||
184 | } | 185 | } |
185 | } | 186 | } |
186 | 187 | ||
188 | impl fmt::Display for Ty { | ||
189 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
190 | match self { | ||
191 | Ty::Bool => write!(f, "bool"), | ||
192 | Ty::Char => write!(f, "char"), | ||
193 | Ty::Int(t) => write!(f, "{}", t.ty_to_string()), | ||
194 | Ty::Uint(t) => write!(f, "{}", t.ty_to_string()), | ||
195 | Ty::Float(t) => write!(f, "{}", t.ty_to_string()), | ||
196 | Ty::Str => write!(f, "str"), | ||
197 | Ty::Slice(t) => write!(f, "[{}]", t), | ||
198 | Ty::Never => write!(f, "!"), | ||
199 | Ty::Tuple(ts) => { | ||
200 | write!(f, "(")?; | ||
201 | for t in ts { | ||
202 | write!(f, "{},", t)?; | ||
203 | } | ||
204 | write!(f, ")") | ||
205 | } | ||
206 | Ty::Unknown => write!(f, "[unknown]") | ||
207 | } | ||
208 | } | ||
209 | } | ||
210 | |||
187 | #[derive(Clone, PartialEq, Eq, Debug)] | 211 | #[derive(Clone, PartialEq, Eq, Debug)] |
188 | pub struct InferenceResult { | 212 | pub struct InferenceResult { |
189 | type_for: FxHashMap<LocalSyntaxPtr, Ty>, | 213 | type_for: FxHashMap<LocalSyntaxPtr, Ty>, |
190 | } | 214 | } |
191 | 215 | ||
216 | impl InferenceResult { | ||
217 | pub fn type_of_node(&self, node: SyntaxNodeRef) -> Option<Ty> { | ||
218 | self.type_for.get(&LocalSyntaxPtr::new(node)).cloned() | ||
219 | } | ||
220 | } | ||
221 | |||
192 | #[derive(Clone, PartialEq, Eq, Debug)] | 222 | #[derive(Clone, PartialEq, Eq, Debug)] |
193 | pub struct InferenceContext { | 223 | pub struct InferenceContext { |
194 | scopes: Arc<FnScopes>, | 224 | scopes: Arc<FnScopes>, |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index f2466dd51..98eedaa3f 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -1,8 +1,11 @@ | |||
1 | use std::fmt::Write; | ||
1 | use std::sync::Arc; | 2 | use std::sync::Arc; |
3 | use std::path::{Path, PathBuf}; | ||
2 | 4 | ||
3 | use salsa::Database; | 5 | use salsa::Database; |
4 | use ra_db::{FilesDatabase, CrateGraph, SyntaxDatabase}; | 6 | use ra_db::{FilesDatabase, CrateGraph, SyntaxDatabase}; |
5 | use ra_syntax::{SmolStr, algo::visit::{visitor, Visitor}, ast::{self, AstNode}}; | 7 | use ra_syntax::{SmolStr, algo::visit::{visitor, Visitor}, ast::{self, AstNode}}; |
8 | use test_utils::{project_dir, dir_tests}; | ||
6 | use relative_path::RelativePath; | 9 | use relative_path::RelativePath; |
7 | 10 | ||
8 | use crate::{source_binder, mock::WORKSPACE, module::ModuleSourceNode}; | 11 | use crate::{source_binder, mock::WORKSPACE, module::ModuleSourceNode}; |
@@ -13,33 +16,46 @@ use crate::{ | |||
13 | mock::MockDatabase, | 16 | mock::MockDatabase, |
14 | }; | 17 | }; |
15 | 18 | ||
16 | fn infer_all_fns(fixture: &str) -> () { | 19 | fn infer_file(content: &str) -> String { |
17 | let (db, source_root) = MockDatabase::with_files(fixture); | 20 | let (db, source_root, file_id) = MockDatabase::with_single_file(content); |
18 | for &file_id in source_root.files.values() { | 21 | let source_file = db.source_file(file_id); |
19 | let source_file = db.source_file(file_id); | 22 | let mut acc = String::new(); |
20 | for fn_def in source_file.syntax().descendants().filter_map(ast::FnDef::cast) { | 23 | for fn_def in source_file.syntax().descendants().filter_map(ast::FnDef::cast) { |
21 | let func = source_binder::function_from_source(&db, file_id, fn_def).unwrap().unwrap(); | 24 | let func = source_binder::function_from_source(&db, file_id, fn_def).unwrap().unwrap(); |
22 | let inference_result = func.infer(&db); | 25 | let inference_result = func.infer(&db); |
23 | for (syntax_ptr, ty) in &inference_result.type_for { | 26 | for (syntax_ptr, ty) in &inference_result.type_for { |
24 | let node = syntax_ptr.resolve(&source_file); | 27 | let node = syntax_ptr.resolve(&source_file); |
25 | eprintln!("{} '{}': {:?}", syntax_ptr.range(), node.text(), ty); | 28 | write!(acc, "{} '{}': {}\n", syntax_ptr.range(), ellipsize(node.text().to_string().replace("\n", " "), 15), ty); |
26 | } | ||
27 | } | 29 | } |
28 | } | 30 | } |
31 | acc | ||
32 | } | ||
33 | |||
34 | fn ellipsize(mut text: String, max_len: usize) -> String { | ||
35 | if text.len() <= max_len { | ||
36 | return text; | ||
37 | } | ||
38 | let ellipsis = "..."; | ||
39 | let e_len = ellipsis.len(); | ||
40 | let mut prefix_len = (max_len - e_len) / 2; | ||
41 | while !text.is_char_boundary(prefix_len) { | ||
42 | prefix_len += 1; | ||
43 | } | ||
44 | let mut suffix_len = max_len - e_len - prefix_len; | ||
45 | while !text.is_char_boundary(text.len() - suffix_len) { | ||
46 | suffix_len += 1; | ||
47 | } | ||
48 | text.replace_range(prefix_len..text.len() - suffix_len, ellipsis); | ||
49 | text | ||
29 | } | 50 | } |
30 | 51 | ||
31 | #[test] | 52 | #[test] |
32 | fn infer_smoke_test() { | 53 | pub fn infer_tests() { |
33 | let text = " | 54 | dir_tests(&test_data_dir(), &["."], |text, _path| { |
34 | //- /lib.rs | 55 | infer_file(text) |
35 | fn foo(x: u32, y: !) -> i128 { | 56 | }); |
36 | x; | 57 | } |
37 | y; | ||
38 | return 1; | ||
39 | \"hello\"; | ||
40 | 0 | ||
41 | } | ||
42 | "; | ||
43 | 58 | ||
44 | infer_all_fns(text); | 59 | fn test_data_dir() -> PathBuf { |
60 | project_dir().join("crates/ra_hir/src/ty/tests/data") | ||
45 | } | 61 | } |
diff --git a/crates/ra_hir/src/ty/tests/data/0001_basics.rs b/crates/ra_hir/src/ty/tests/data/0001_basics.rs new file mode 100644 index 000000000..59a60d031 --- /dev/null +++ b/crates/ra_hir/src/ty/tests/data/0001_basics.rs | |||
@@ -0,0 +1,11 @@ | |||
1 | |||
2 | fn test(a: u32, b: isize, c: !, d: &str) { | ||
3 | a; | ||
4 | b; | ||
5 | c; | ||
6 | d; | ||
7 | 1usize; | ||
8 | 1isize; | ||
9 | "test"; | ||
10 | 1.0f32; | ||
11 | } | ||
diff --git a/crates/ra_hir/src/ty/tests/data/0001_basics.txt b/crates/ra_hir/src/ty/tests/data/0001_basics.txt new file mode 100644 index 000000000..0c46f243a --- /dev/null +++ b/crates/ra_hir/src/ty/tests/data/0001_basics.txt | |||
@@ -0,0 +1,13 @@ | |||
1 | [33; 34) 'd': [unknown] | ||
2 | [88; 94) '1isize': [unknown] | ||
3 | [48; 49) 'a': u32 | ||
4 | [55; 56) 'b': isize | ||
5 | [112; 118) '1.0f32': [unknown] | ||
6 | [76; 82) '1usize': [unknown] | ||
7 | [9; 10) 'a': u32 | ||
8 | [27; 28) 'c': ! | ||
9 | [62; 63) 'c': ! | ||
10 | [17; 18) 'b': isize | ||
11 | [100; 106) '"test"': [unknown] | ||
12 | [42; 121) '{ ...f32; }': () | ||
13 | [69; 70) 'd': [unknown] | ||