diff options
| -rw-r--r-- | crates/ide_ssr/src/fragments.rs | 21 | ||||
| -rw-r--r-- | crates/ide_ssr/src/lib.rs | 1 | ||||
| -rw-r--r-- | crates/ide_ssr/src/parsing.rs | 24 | ||||
| -rw-r--r-- | crates/parser/src/lib.rs | 2 | ||||
| -rw-r--r-- | crates/syntax/src/lib.rs | 7 | ||||
| -rw-r--r-- | crates/syntax/src/tests.rs | 9 | ||||
| -rw-r--r-- | crates/syntax/test_data/parser/fragments/type/err/0000_missing_close.rast | 1 | ||||
| -rw-r--r-- | crates/syntax/test_data/parser/fragments/type/err/0000_missing_close.rs | 1 | ||||
| -rw-r--r-- | crates/syntax/test_data/parser/fragments/type/ok/0000_result.rast | 22 | ||||
| -rw-r--r-- | crates/syntax/test_data/parser/fragments/type/ok/0000_result.rs | 1 |
10 files changed, 44 insertions, 45 deletions
diff --git a/crates/ide_ssr/src/fragments.rs b/crates/ide_ssr/src/fragments.rs new file mode 100644 index 00000000000..0abf9e4d98c --- /dev/null +++ b/crates/ide_ssr/src/fragments.rs @@ -0,0 +1,21 @@ +//! When specifying SSR rule, you generally want to map one *kind* of thing to +//! the same kind of thing: path to path, expression to expression, type to +//! type. +//! +//! The problem is, while this *kind* is generally obvious to the human, the ide +//! needs to determine it somehow. We do this in a stupid way -- by pasting SSR +//! rule into different contexts and checking what works. + +use parser::SyntaxKind; +use syntax::{ast, AstNode, SyntaxNode}; + +pub(crate) fn ty(s: &str) -> Result<SyntaxNode, ()> { + let template = "type T = {};"; + let input = template.replace("{}", s); + let parse = syntax::SourceFile::parse(&input); + if !parse.errors().is_empty() { + return Err(()); + } + let node = parse.tree().syntax().descendants().find_map(ast::Type::cast).ok_or(())?; + Ok(node.syntax().clone()) +} diff --git a/crates/ide_ssr/src/lib.rs b/crates/ide_ssr/src/lib.rs index 2fe1f5b616e..d56bc12b680 100644 --- a/crates/ide_ssr/src/lib.rs +++ b/crates/ide_ssr/src/lib.rs @@ -71,6 +71,7 @@ mod from_comment; mod matching; mod nester; mod parsing; +mod fragments; mod replacing; mod resolving; mod search; diff --git a/crates/ide_ssr/src/parsing.rs b/crates/ide_ssr/src/parsing.rs index ae7d5b4bf15..b32efe879a4 100644 --- a/crates/ide_ssr/src/parsing.rs +++ b/crates/ide_ssr/src/parsing.rs @@ -6,7 +6,7 @@ //! e.g. expressions, type references etc. use crate::errors::bail; -use crate::{SsrError, SsrPattern, SsrRule}; +use crate::{fragments, SsrError, SsrPattern, SsrRule}; use rustc_hash::{FxHashMap, FxHashSet}; use std::{fmt::Display, str::FromStr}; use syntax::{ast, AstNode, SmolStr, SyntaxKind, SyntaxNode, T}; @@ -79,7 +79,7 @@ impl ParsedRule { } else { builder.try_add(ast::Expr::parse(&raw_pattern), raw_template_stmt.clone()); } - builder.try_add(ast::Type::parse(&raw_pattern), raw_template.map(ast::Type::parse)); + builder.try_add2(fragments::ty(&raw_pattern), raw_template.map(fragments::ty)); builder.try_add(ast::Item::parse(&raw_pattern), raw_template.map(ast::Item::parse)); builder.try_add(ast::Path::parse(&raw_pattern), raw_template.map(ast::Path::parse)); builder.try_add(ast::Pat::parse(&raw_pattern), raw_template.map(ast::Pat::parse)); @@ -114,6 +114,26 @@ impl RuleBuilder { } } + fn try_add2( + &mut self, + pattern: Result<SyntaxNode, ()>, + template: Option<Result<SyntaxNode, ()>>, + ) { + match (pattern, template) { + (Ok(pattern), Some(Ok(template))) => self.rules.push(ParsedRule { + placeholders_by_stand_in: self.placeholders_by_stand_in.clone(), + pattern, + template: Some(template), + }), + (Ok(pattern), None) => self.rules.push(ParsedRule { + placeholders_by_stand_in: self.placeholders_by_stand_in.clone(), + pattern, + template: None, + }), + _ => {} + } + } + fn build(mut self) -> Result<Vec<ParsedRule>, SsrError> { if self.rules.is_empty() { bail!("Not a valid Rust expression, type, item, path or pattern"); diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index 6827cf8bf1a..fb5280d1977 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -141,7 +141,6 @@ pub enum ParserEntryPoint { Path, Expr, StatementOptionalSemi, - Type, Pattern, Item, Attr, @@ -164,7 +163,6 @@ pub fn parse(inp: &Input, entry_point: ParserEntryPoint) -> Output { let entry_point: fn(&'_ mut parser::Parser) = match entry_point { ParserEntryPoint::Path => grammar::entry::prefix::path, ParserEntryPoint::Expr => grammar::entry::prefix::expr, - ParserEntryPoint::Type => grammar::entry::prefix::ty, ParserEntryPoint::Pattern => grammar::entry::prefix::pat, ParserEntryPoint::Item => grammar::entry::prefix::item, ParserEntryPoint::StatementOptionalSemi => grammar::entry_points::stmt_optional_semi, diff --git a/crates/syntax/src/lib.rs b/crates/syntax/src/lib.rs index 65a6b7ac4e4..b82df661624 100644 --- a/crates/syntax/src/lib.rs +++ b/crates/syntax/src/lib.rs @@ -201,13 +201,6 @@ impl ast::Item { } } -impl ast::Type { - /// Returns `text`, parsed as an type reference, but only if it has no errors. - pub fn parse(text: &str) -> Result<Self, ()> { - parsing::parse_text_as(text, parser::ParserEntryPoint::Type) - } -} - impl ast::Attr { /// Returns `text`, parsed as an attribute, but only if it has no errors. pub fn parse(text: &str) -> Result<Self, ()> { diff --git a/crates/syntax/src/tests.rs b/crates/syntax/src/tests.rs index 04105dedc9e..a632d0e6309 100644 --- a/crates/syntax/src/tests.rs +++ b/crates/syntax/src/tests.rs @@ -96,15 +96,6 @@ fn item_parser_tests() { } #[test] -fn type_parser_tests() { - fragment_parser_dir_test( - &["parser/fragments/type/ok"], - &["parser/fragments/type/err"], - crate::ast::Type::parse, - ); -} - -#[test] fn stmt_parser_tests() { fragment_parser_dir_test( &["parser/fragments/stmt/ok"], diff --git a/crates/syntax/test_data/parser/fragments/type/err/0000_missing_close.rast b/crates/syntax/test_data/parser/fragments/type/err/0000_missing_close.rast deleted file mode 100644 index 5df7507e2de..00000000000 --- a/crates/syntax/test_data/parser/fragments/type/err/0000_missing_close.rast +++ /dev/null @@ -1 +0,0 @@ -ERROR diff --git a/crates/syntax/test_data/parser/fragments/type/err/0000_missing_close.rs b/crates/syntax/test_data/parser/fragments/type/err/0000_missing_close.rs deleted file mode 100644 index caa4d7c0927..00000000000 --- a/crates/syntax/test_data/parser/fragments/type/err/0000_missing_close.rs +++ /dev/null @@ -1 +0,0 @@ -Result<Foo, Bar diff --git a/crates/syntax/test_data/parser/fragments/type/ok/0000_result.rast b/crates/syntax/test_data/parser/fragments/type/ok/0000_result.rast deleted file mode 100644 index 38c15b5815e..00000000000 --- a/crates/syntax/test_data/parser/fragments/type/ok/0000_result.rast +++ /dev/null @@ -1,22 +0,0 @@ -PATH_TYPE@0..16 - PATH@0..16 - PATH_SEGMENT@0..16 - NAME_REF@0..6 - IDENT@0..6 "Result" - GENERIC_ARG_LIST@6..16 - L_ANGLE@6..7 "<" - TYPE_ARG@7..10 - PATH_TYPE@7..10 - PATH@7..10 - PATH_SEGMENT@7..10 - NAME_REF@7..10 - IDENT@7..10 "Foo" - COMMA@10..11 "," - WHITESPACE@11..12 " " - TYPE_ARG@12..15 - PATH_TYPE@12..15 - PATH@12..15 - PATH_SEGMENT@12..15 - NAME_REF@12..15 - IDENT@12..15 "Bar" - R_ANGLE@15..16 ">" diff --git a/crates/syntax/test_data/parser/fragments/type/ok/0000_result.rs b/crates/syntax/test_data/parser/fragments/type/ok/0000_result.rs deleted file mode 100644 index b50b3bb3bfd..00000000000 --- a/crates/syntax/test_data/parser/fragments/type/ok/0000_result.rs +++ /dev/null @@ -1 +0,0 @@ -Result<Foo, Bar> |
