aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-03-31 11:43:50 +0100
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-03-31 11:43:50 +0100
commitdec9bde10868b5e459535449476d17a6a0987b3e (patch)
tree91bb5a70b999474e4d8212245fe265e71c3afde4 /crates/ra_syntax/src
parent4666138c910a655deb0e8129b0a1dc5974b49bdf (diff)
parent3f62ab8f510fdac1eeab515c515c437d6dd141e6 (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.rs67
-rw-r--r--crates/ra_syntax/src/ast/generated.rs43
-rw-r--r--crates/ra_syntax/src/grammar.ron15
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]
804fn 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#"
811fn foo()
812where
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
4813impl WhereClause {} 4813impl 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)]
4822pub struct WherePred {
4823 pub(crate) syntax: SyntaxNode,
4824}
4825unsafe impl TransparentNewType for WherePred {
4826 type Repr = rowan::SyntaxNode<RaTypes>;
4827}
4828
4829impl 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
4839impl ToOwned for WherePred {
4840 type Owned = TreeArc<WherePred>;
4841 fn to_owned(&self) -> TreeArc<WherePred> { TreeArc::cast(self.syntax.to_owned()) }
4842}
4843
4844
4845impl ast::TypeBoundsOwner for WherePred {}
4846impl 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 ),