about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/ide_ssr/src/fragments.rs21
-rw-r--r--crates/ide_ssr/src/lib.rs1
-rw-r--r--crates/ide_ssr/src/parsing.rs24
-rw-r--r--crates/parser/src/lib.rs2
-rw-r--r--crates/syntax/src/lib.rs7
-rw-r--r--crates/syntax/src/tests.rs9
-rw-r--r--crates/syntax/test_data/parser/fragments/type/err/0000_missing_close.rast1
-rw-r--r--crates/syntax/test_data/parser/fragments/type/err/0000_missing_close.rs1
-rw-r--r--crates/syntax/test_data/parser/fragments/type/ok/0000_result.rast22
-rw-r--r--crates/syntax/test_data/parser/fragments/type/ok/0000_result.rs1
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>