diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-03-31 11:43:50 +0100 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-03-31 11:43:50 +0100 |
commit | dec9bde10868b5e459535449476d17a6a0987b3e (patch) | |
tree | 91bb5a70b999474e4d8212245fe265e71c3afde4 /crates/ra_syntax/src | |
parent | 4666138c910a655deb0e8129b0a1dc5974b49bdf (diff) | |
parent | 3f62ab8f510fdac1eeab515c515c437d6dd141e6 (diff) |
Merge #1038
1038: Add WherePred to allow predicate access in WhereClause r=matklad a=vipentti
Lifetime bounds in where predicates are now also parsed into `TYPE_BOUND_LIST` to allow unified access to bounds.
Co-authored-by: Ville Penttinen <[email protected]>
Diffstat (limited to 'crates/ra_syntax/src')
-rw-r--r-- | crates/ra_syntax/src/ast.rs | 67 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated.rs | 43 | ||||
-rw-r--r-- | crates/ra_syntax/src/grammar.ron | 15 |
3 files changed, 123 insertions, 2 deletions
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index 4fddc00ea..fd7e63f84 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs | |||
@@ -799,3 +799,70 @@ fn test_doc_comment_preserves_indents() { | |||
799 | let module = file.syntax().descendants().find_map(Module::cast).unwrap(); | 799 | let module = file.syntax().descendants().find_map(Module::cast).unwrap(); |
800 | assert_eq!("doc1\n```\nfn foo() {\n // ...\n}\n```", module.doc_comment_text().unwrap()); | 800 | assert_eq!("doc1\n```\nfn foo() {\n // ...\n}\n```", module.doc_comment_text().unwrap()); |
801 | } | 801 | } |
802 | |||
803 | #[test] | ||
804 | fn test_where_predicates() { | ||
805 | fn assert_bound(text: &str, bound: Option<&TypeBound>) { | ||
806 | assert_eq!(text, bound.unwrap().syntax().text().to_string()); | ||
807 | } | ||
808 | |||
809 | let file = SourceFile::parse( | ||
810 | r#" | ||
811 | fn foo() | ||
812 | where | ||
813 | T: Clone + Copy + Debug + 'static, | ||
814 | 'a: 'b + 'c, | ||
815 | Iterator::Item: 'a + Debug, | ||
816 | Iterator::Item: Debug + 'a, | ||
817 | <T as Iterator>::Item: Debug + 'a, | ||
818 | for<'a> F: Fn(&'a str) | ||
819 | {} | ||
820 | "#, | ||
821 | ); | ||
822 | let where_clause = file.syntax().descendants().find_map(WhereClause::cast).unwrap(); | ||
823 | |||
824 | let mut predicates = where_clause.predicates(); | ||
825 | |||
826 | let pred = predicates.next().unwrap(); | ||
827 | let mut bounds = pred.type_bound_list().unwrap().bounds(); | ||
828 | |||
829 | assert_eq!("T", pred.type_ref().unwrap().syntax().text().to_string()); | ||
830 | assert_bound("Clone", bounds.next()); | ||
831 | assert_bound("Copy", bounds.next()); | ||
832 | assert_bound("Debug", bounds.next()); | ||
833 | assert_bound("'static", bounds.next()); | ||
834 | |||
835 | let pred = predicates.next().unwrap(); | ||
836 | let mut bounds = pred.type_bound_list().unwrap().bounds(); | ||
837 | |||
838 | assert_eq!("'a", pred.lifetime().unwrap().syntax().text().to_string()); | ||
839 | |||
840 | assert_bound("'b", bounds.next()); | ||
841 | assert_bound("'c", bounds.next()); | ||
842 | |||
843 | let pred = predicates.next().unwrap(); | ||
844 | let mut bounds = pred.type_bound_list().unwrap().bounds(); | ||
845 | |||
846 | assert_eq!("Iterator::Item", pred.type_ref().unwrap().syntax().text().to_string()); | ||
847 | assert_bound("'a", bounds.next()); | ||
848 | |||
849 | let pred = predicates.next().unwrap(); | ||
850 | let mut bounds = pred.type_bound_list().unwrap().bounds(); | ||
851 | |||
852 | assert_eq!("Iterator::Item", pred.type_ref().unwrap().syntax().text().to_string()); | ||
853 | assert_bound("Debug", bounds.next()); | ||
854 | assert_bound("'a", bounds.next()); | ||
855 | |||
856 | let pred = predicates.next().unwrap(); | ||
857 | let mut bounds = pred.type_bound_list().unwrap().bounds(); | ||
858 | |||
859 | assert_eq!("<T as Iterator>::Item", pred.type_ref().unwrap().syntax().text().to_string()); | ||
860 | assert_bound("Debug", bounds.next()); | ||
861 | assert_bound("'a", bounds.next()); | ||
862 | |||
863 | let pred = predicates.next().unwrap(); | ||
864 | let mut bounds = pred.type_bound_list().unwrap().bounds(); | ||
865 | |||
866 | assert_eq!("for<'a> F", pred.type_ref().unwrap().syntax().text().to_string()); | ||
867 | assert_bound("Fn(&'a str)", bounds.next()); | ||
868 | } | ||
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 9ea423b40..c51b4caa4 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -4810,7 +4810,48 @@ impl ToOwned for WhereClause { | |||
4810 | } | 4810 | } |
4811 | 4811 | ||
4812 | 4812 | ||
4813 | impl WhereClause {} | 4813 | impl WhereClause { |
4814 | pub fn predicates(&self) -> impl Iterator<Item = &WherePred> { | ||
4815 | super::children(self) | ||
4816 | } | ||
4817 | } | ||
4818 | |||
4819 | // WherePred | ||
4820 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
4821 | #[repr(transparent)] | ||
4822 | pub struct WherePred { | ||
4823 | pub(crate) syntax: SyntaxNode, | ||
4824 | } | ||
4825 | unsafe impl TransparentNewType for WherePred { | ||
4826 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
4827 | } | ||
4828 | |||
4829 | impl AstNode for WherePred { | ||
4830 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
4831 | match syntax.kind() { | ||
4832 | WHERE_PRED => Some(WherePred::from_repr(syntax.into_repr())), | ||
4833 | _ => None, | ||
4834 | } | ||
4835 | } | ||
4836 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
4837 | } | ||
4838 | |||
4839 | impl ToOwned for WherePred { | ||
4840 | type Owned = TreeArc<WherePred>; | ||
4841 | fn to_owned(&self) -> TreeArc<WherePred> { TreeArc::cast(self.syntax.to_owned()) } | ||
4842 | } | ||
4843 | |||
4844 | |||
4845 | impl ast::TypeBoundsOwner for WherePred {} | ||
4846 | impl WherePred { | ||
4847 | pub fn type_ref(&self) -> Option<&TypeRef> { | ||
4848 | super::child_opt(self) | ||
4849 | } | ||
4850 | |||
4851 | pub fn lifetime(&self) -> Option<&Lifetime> { | ||
4852 | super::child_opt(self) | ||
4853 | } | ||
4854 | } | ||
4814 | 4855 | ||
4815 | // WhileExpr | 4856 | // WhileExpr |
4816 | #[derive(Debug, PartialEq, Eq, Hash)] | 4857 | #[derive(Debug, PartialEq, Eq, Hash)] |
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 18730a894..1123c2e95 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron | |||
@@ -595,7 +595,20 @@ Grammar( | |||
595 | ["bounds", "TypeBound"], | 595 | ["bounds", "TypeBound"], |
596 | ] | 596 | ] |
597 | ), | 597 | ), |
598 | "WhereClause": (), | 598 | "WherePred": ( |
599 | options: [ | ||
600 | "TypeRef", | ||
601 | "Lifetime", | ||
602 | ], | ||
603 | traits: [ | ||
604 | "TypeBoundsOwner", | ||
605 | ], | ||
606 | ), | ||
607 | "WhereClause": ( | ||
608 | collections: [ | ||
609 | ["predicates", "WherePred"], | ||
610 | ], | ||
611 | ), | ||
599 | "ExprStmt": ( | 612 | "ExprStmt": ( |
600 | options: [ ["expr", "Expr"] ] | 613 | options: [ ["expr", "Expr"] ] |
601 | ), | 614 | ), |