aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src')
-rw-r--r--crates/ra_syntax/src/ast/extensions.rs3
-rw-r--r--crates/ra_syntax/src/ast/generated.rs42
-rw-r--r--crates/ra_syntax/src/ast/make.rs28
-rw-r--r--crates/ra_syntax/src/tests.rs14
-rw-r--r--crates/ra_syntax/src/validation.rs12
5 files changed, 84 insertions, 15 deletions
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs
index 392731dac..bf7d137be 100644
--- a/crates/ra_syntax/src/ast/extensions.rs
+++ b/crates/ra_syntax/src/ast/extensions.rs
@@ -325,6 +325,9 @@ impl ast::BindPat {
325 pub fn is_ref(&self) -> bool { 325 pub fn is_ref(&self) -> bool {
326 self.syntax().children_with_tokens().any(|n| n.kind() == T![ref]) 326 self.syntax().children_with_tokens().any(|n| n.kind() == T![ref])
327 } 327 }
328 pub fn has_at(&self) -> bool {
329 self.syntax().children_with_tokens().any(|it| it.kind() == T![@])
330 }
328} 331}
329 332
330pub struct SlicePatComponents { 333pub struct SlicePatComponents {
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index 7204ca5b1..0c339b987 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -2563,6 +2563,38 @@ impl LiteralPat {
2563 } 2563 }
2564} 2564}
2565#[derive(Debug, Clone, PartialEq, Eq, Hash)] 2565#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2566pub struct MacroPat {
2567 pub(crate) syntax: SyntaxNode,
2568}
2569impl std::fmt::Display for MacroPat {
2570 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
2571 std::fmt::Display::fmt(self.syntax(), f)
2572 }
2573}
2574impl AstNode for MacroPat {
2575 fn can_cast(kind: SyntaxKind) -> bool {
2576 match kind {
2577 MACRO_PAT => true,
2578 _ => false,
2579 }
2580 }
2581 fn cast(syntax: SyntaxNode) -> Option<Self> {
2582 if Self::can_cast(syntax.kind()) {
2583 Some(Self { syntax })
2584 } else {
2585 None
2586 }
2587 }
2588 fn syntax(&self) -> &SyntaxNode {
2589 &self.syntax
2590 }
2591}
2592impl MacroPat {
2593 pub fn macro_call(&self) -> Option<MacroCall> {
2594 AstChildren::new(&self.syntax).next()
2595 }
2596}
2597#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2566pub struct RecordPat { 2598pub struct RecordPat {
2567 pub(crate) syntax: SyntaxNode, 2599 pub(crate) syntax: SyntaxNode,
2568} 2600}
@@ -4600,6 +4632,7 @@ pub enum Pat {
4600 SlicePat(SlicePat), 4632 SlicePat(SlicePat),
4601 RangePat(RangePat), 4633 RangePat(RangePat),
4602 LiteralPat(LiteralPat), 4634 LiteralPat(LiteralPat),
4635 MacroPat(MacroPat),
4603} 4636}
4604impl From<OrPat> for Pat { 4637impl From<OrPat> for Pat {
4605 fn from(node: OrPat) -> Pat { 4638 fn from(node: OrPat) -> Pat {
@@ -4671,6 +4704,11 @@ impl From<LiteralPat> for Pat {
4671 Pat::LiteralPat(node) 4704 Pat::LiteralPat(node)
4672 } 4705 }
4673} 4706}
4707impl From<MacroPat> for Pat {
4708 fn from(node: MacroPat) -> Pat {
4709 Pat::MacroPat(node)
4710 }
4711}
4674impl std::fmt::Display for Pat { 4712impl std::fmt::Display for Pat {
4675 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 4713 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
4676 std::fmt::Display::fmt(self.syntax(), f) 4714 std::fmt::Display::fmt(self.syntax(), f)
@@ -4681,7 +4719,7 @@ impl AstNode for Pat {
4681 match kind { 4719 match kind {
4682 OR_PAT | PAREN_PAT | REF_PAT | BOX_PAT | BIND_PAT | PLACEHOLDER_PAT | DOT_DOT_PAT 4720 OR_PAT | PAREN_PAT | REF_PAT | BOX_PAT | BIND_PAT | PLACEHOLDER_PAT | DOT_DOT_PAT
4683 | PATH_PAT | RECORD_PAT | TUPLE_STRUCT_PAT | TUPLE_PAT | SLICE_PAT | RANGE_PAT 4721 | PATH_PAT | RECORD_PAT | TUPLE_STRUCT_PAT | TUPLE_PAT | SLICE_PAT | RANGE_PAT
4684 | LITERAL_PAT => true, 4722 | LITERAL_PAT | MACRO_PAT => true,
4685 _ => false, 4723 _ => false,
4686 } 4724 }
4687 } 4725 }
@@ -4701,6 +4739,7 @@ impl AstNode for Pat {
4701 SLICE_PAT => Pat::SlicePat(SlicePat { syntax }), 4739 SLICE_PAT => Pat::SlicePat(SlicePat { syntax }),
4702 RANGE_PAT => Pat::RangePat(RangePat { syntax }), 4740 RANGE_PAT => Pat::RangePat(RangePat { syntax }),
4703 LITERAL_PAT => Pat::LiteralPat(LiteralPat { syntax }), 4741 LITERAL_PAT => Pat::LiteralPat(LiteralPat { syntax }),
4742 MACRO_PAT => Pat::MacroPat(MacroPat { syntax }),
4704 _ => return None, 4743 _ => return None,
4705 }; 4744 };
4706 Some(res) 4745 Some(res)
@@ -4721,6 +4760,7 @@ impl AstNode for Pat {
4721 Pat::SlicePat(it) => &it.syntax, 4760 Pat::SlicePat(it) => &it.syntax,
4722 Pat::RangePat(it) => &it.syntax, 4761 Pat::RangePat(it) => &it.syntax,
4723 Pat::LiteralPat(it) => &it.syntax, 4762 Pat::LiteralPat(it) => &it.syntax,
4763 Pat::MacroPat(it) => &it.syntax,
4724 } 4764 }
4725 } 4765 }
4726} 4766}
diff --git a/crates/ra_syntax/src/ast/make.rs b/crates/ra_syntax/src/ast/make.rs
index 0c908573d..f39559e9e 100644
--- a/crates/ra_syntax/src/ast/make.rs
+++ b/crates/ra_syntax/src/ast/make.rs
@@ -22,7 +22,8 @@ pub fn path_unqualified(segment: ast::PathSegment) -> ast::Path {
22pub fn path_qualified(qual: ast::Path, segment: ast::PathSegment) -> ast::Path { 22pub fn path_qualified(qual: ast::Path, segment: ast::PathSegment) -> ast::Path {
23 path_from_text(&format!("{}::{}", qual, segment)) 23 path_from_text(&format!("{}::{}", qual, segment))
24} 24}
25fn path_from_text(text: &str) -> ast::Path { 25
26pub fn path_from_text(text: &str) -> ast::Path {
26 ast_from_text(text) 27 ast_from_text(text)
27} 28}
28 29
@@ -269,6 +270,31 @@ pub fn unreachable_macro_call() -> ast::MacroCall {
269 ast_from_text(&format!("unreachable!()")) 270 ast_from_text(&format!("unreachable!()"))
270} 271}
271 272
273pub fn param(name: String, ty: String) -> ast::Param {
274 ast_from_text(&format!("fn f({}: {}) {{ }}", name, ty))
275}
276
277pub fn param_list(pats: impl IntoIterator<Item = ast::Param>) -> ast::ParamList {
278 let args = pats.into_iter().join(", ");
279 ast_from_text(&format!("fn f({}) {{ }}", args))
280}
281
282pub fn fn_def(
283 fn_name: ast::Name,
284 type_params: Option<ast::TypeParamList>,
285 params: ast::ParamList,
286 body: ast::BlockExpr,
287) -> ast::FnDef {
288 let type_params =
289 if let Some(type_params) = type_params { format!("<{}>", type_params) } else { "".into() };
290 ast_from_text(&format!("fn {}{}{} {}", fn_name, type_params, params, body))
291}
292
293pub fn add_newlines(amount_of_newlines: usize, t: impl AstNode) -> ast::SourceFile {
294 let newlines = "\n".repeat(amount_of_newlines);
295 ast_from_text(&format!("{}{}", newlines, t.syntax()))
296}
297
272fn ast_from_text<N: AstNode>(text: &str) -> N { 298fn ast_from_text<N: AstNode>(text: &str) -> N {
273 let parse = SourceFile::parse(text); 299 let parse = SourceFile::parse(text);
274 let node = parse.tree().syntax().descendants().find_map(N::cast).unwrap(); 300 let node = parse.tree().syntax().descendants().find_map(N::cast).unwrap();
diff --git a/crates/ra_syntax/src/tests.rs b/crates/ra_syntax/src/tests.rs
index 6a8cb6bb5..355843b94 100644
--- a/crates/ra_syntax/src/tests.rs
+++ b/crates/ra_syntax/src/tests.rs
@@ -3,7 +3,7 @@ use std::{
3 path::{Component, Path, PathBuf}, 3 path::{Component, Path, PathBuf},
4}; 4};
5 5
6use test_utils::{collect_tests, dir_tests, project_dir, read_text}; 6use test_utils::{collect_rust_files, dir_tests, project_dir, read_text};
7 7
8use crate::{fuzz, tokenize, SourceFile, SyntaxError, TextRange, TextUnit, Token}; 8use crate::{fuzz, tokenize, SourceFile, SyntaxError, TextRange, TextUnit, Token};
9 9
@@ -13,12 +13,12 @@ fn lexer_tests() {
13 // * Add tests for unicode escapes in byte-character and [raw]-byte-string literals 13 // * Add tests for unicode escapes in byte-character and [raw]-byte-string literals
14 // * Add tests for unescape errors 14 // * Add tests for unescape errors
15 15
16 dir_tests(&test_data_dir(), &["lexer/ok"], |text, path| { 16 dir_tests(&test_data_dir(), &["lexer/ok"], "txt", |text, path| {
17 let (tokens, errors) = tokenize(text); 17 let (tokens, errors) = tokenize(text);
18 assert_errors_are_absent(&errors, path); 18 assert_errors_are_absent(&errors, path);
19 dump_tokens_and_errors(&tokens, &errors, text) 19 dump_tokens_and_errors(&tokens, &errors, text)
20 }); 20 });
21 dir_tests(&test_data_dir(), &["lexer/err"], |text, path| { 21 dir_tests(&test_data_dir(), &["lexer/err"], "txt", |text, path| {
22 let (tokens, errors) = tokenize(text); 22 let (tokens, errors) = tokenize(text);
23 assert_errors_are_present(&errors, path); 23 assert_errors_are_present(&errors, path);
24 dump_tokens_and_errors(&tokens, &errors, text) 24 dump_tokens_and_errors(&tokens, &errors, text)
@@ -40,13 +40,13 @@ fn main() {
40 40
41#[test] 41#[test]
42fn parser_tests() { 42fn parser_tests() {
43 dir_tests(&test_data_dir(), &["parser/inline/ok", "parser/ok"], |text, path| { 43 dir_tests(&test_data_dir(), &["parser/inline/ok", "parser/ok"], "rast", |text, path| {
44 let parse = SourceFile::parse(text); 44 let parse = SourceFile::parse(text);
45 let errors = parse.errors(); 45 let errors = parse.errors();
46 assert_errors_are_absent(&errors, path); 46 assert_errors_are_absent(&errors, path);
47 parse.debug_dump() 47 parse.debug_dump()
48 }); 48 });
49 dir_tests(&test_data_dir(), &["parser/err", "parser/inline/err"], |text, path| { 49 dir_tests(&test_data_dir(), &["parser/err", "parser/inline/err"], "rast", |text, path| {
50 let parse = SourceFile::parse(text); 50 let parse = SourceFile::parse(text);
51 let errors = parse.errors(); 51 let errors = parse.errors();
52 assert_errors_are_present(&errors, path); 52 assert_errors_are_present(&errors, path);
@@ -56,14 +56,14 @@ fn parser_tests() {
56 56
57#[test] 57#[test]
58fn parser_fuzz_tests() { 58fn parser_fuzz_tests() {
59 for (_, text) in collect_tests(&test_data_dir(), &["parser/fuzz-failures"]) { 59 for (_, text) in collect_rust_files(&test_data_dir(), &["parser/fuzz-failures"]) {
60 fuzz::check_parser(&text) 60 fuzz::check_parser(&text)
61 } 61 }
62} 62}
63 63
64#[test] 64#[test]
65fn reparse_fuzz_tests() { 65fn reparse_fuzz_tests() {
66 for (_, text) in collect_tests(&test_data_dir(), &["reparse/fuzz-failures"]) { 66 for (_, text) in collect_rust_files(&test_data_dir(), &["reparse/fuzz-failures"]) {
67 let check = fuzz::CheckReparse::from_data(text.as_bytes()).unwrap(); 67 let check = fuzz::CheckReparse::from_data(text.as_bytes()).unwrap();
68 println!("{:?}", check); 68 println!("{:?}", check);
69 check.run(); 69 check.run();
diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs
index 7915cf8cb..f85b3e61b 100644
--- a/crates/ra_syntax/src/validation.rs
+++ b/crates/ra_syntax/src/validation.rs
@@ -88,12 +88,12 @@ pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> {
88 for node in root.descendants() { 88 for node in root.descendants() {
89 match_ast! { 89 match_ast! {
90 match node { 90 match node {
91 ast::Literal(it) => { validate_literal(it, &mut errors) }, 91 ast::Literal(it) => validate_literal(it, &mut errors),
92 ast::BlockExpr(it) => { block::validate_block_expr(it, &mut errors) }, 92 ast::BlockExpr(it) => block::validate_block_expr(it, &mut errors),
93 ast::FieldExpr(it) => { validate_numeric_name(it.name_ref(), &mut errors) }, 93 ast::FieldExpr(it) => validate_numeric_name(it.name_ref(), &mut errors),
94 ast::RecordField(it) => { validate_numeric_name(it.name_ref(), &mut errors) }, 94 ast::RecordField(it) => validate_numeric_name(it.name_ref(), &mut errors),
95 ast::Visibility(it) => { validate_visibility(it, &mut errors) }, 95 ast::Visibility(it) => validate_visibility(it, &mut errors),
96 ast::RangeExpr(it) => { validate_range_expr(it, &mut errors) }, 96 ast::RangeExpr(it) => validate_range_expr(it, &mut errors),
97 _ => (), 97 _ => (),
98 } 98 }
99 } 99 }