diff options
Diffstat (limited to 'crates/ra_syntax/src/ast')
-rw-r--r-- | crates/ra_syntax/src/ast/extensions.rs | 54 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated.rs | 87 |
2 files changed, 134 insertions, 7 deletions
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs index cb0aee422..44de4af89 100644 --- a/crates/ra_syntax/src/ast/extensions.rs +++ b/crates/ra_syntax/src/ast/extensions.rs | |||
@@ -1,6 +1,8 @@ | |||
1 | //! Various extension methods to ast Nodes, which are hard to code-generate. | 1 | //! Various extension methods to ast Nodes, which are hard to code-generate. |
2 | //! Extensions for various expressions live in a sibling `expr_extensions` module. | 2 | //! Extensions for various expressions live in a sibling `expr_extensions` module. |
3 | 3 | ||
4 | use itertools::Itertools; | ||
5 | |||
4 | use crate::{ | 6 | use crate::{ |
5 | ast::{self, child_opt, children, AstNode, AttrInput, SyntaxNode}, | 7 | ast::{self, child_opt, children, AstNode, AttrInput, SyntaxNode}, |
6 | SmolStr, SyntaxElement, | 8 | SmolStr, SyntaxElement, |
@@ -35,6 +37,12 @@ fn text_of_first_token(node: &SyntaxNode) -> &SmolStr { | |||
35 | node.green().children().next().and_then(|it| it.into_token()).unwrap().text() | 37 | node.green().children().next().and_then(|it| it.into_token()).unwrap().text() |
36 | } | 38 | } |
37 | 39 | ||
40 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
41 | pub enum AttrKind { | ||
42 | Inner, | ||
43 | Outer, | ||
44 | } | ||
45 | |||
38 | impl ast::Attr { | 46 | impl ast::Attr { |
39 | pub fn as_simple_atom(&self) -> Option<SmolStr> { | 47 | pub fn as_simple_atom(&self) -> Option<SmolStr> { |
40 | match self.input() { | 48 | match self.input() { |
@@ -69,6 +77,18 @@ impl ast::Attr { | |||
69 | _ => None, | 77 | _ => None, |
70 | } | 78 | } |
71 | } | 79 | } |
80 | |||
81 | pub fn kind(&self) -> AttrKind { | ||
82 | let first_token = self.syntax().first_token(); | ||
83 | let first_token_kind = first_token.as_ref().map(SyntaxToken::kind); | ||
84 | let second_token_kind = | ||
85 | first_token.and_then(|token| token.next_token()).as_ref().map(SyntaxToken::kind); | ||
86 | |||
87 | match (first_token_kind, second_token_kind) { | ||
88 | (Some(SyntaxKind::POUND), Some(SyntaxKind::EXCL)) => AttrKind::Inner, | ||
89 | _ => AttrKind::Outer, | ||
90 | } | ||
91 | } | ||
72 | } | 92 | } |
73 | 93 | ||
74 | #[derive(Debug, Clone, PartialEq, Eq)] | 94 | #[derive(Debug, Clone, PartialEq, Eq)] |
@@ -293,6 +313,40 @@ impl ast::BindPat { | |||
293 | } | 313 | } |
294 | } | 314 | } |
295 | 315 | ||
316 | pub struct SlicePatComponents { | ||
317 | pub prefix: Vec<ast::Pat>, | ||
318 | pub slice: Option<ast::Pat>, | ||
319 | pub suffix: Vec<ast::Pat>, | ||
320 | } | ||
321 | |||
322 | impl ast::SlicePat { | ||
323 | pub fn components(&self) -> SlicePatComponents { | ||
324 | let mut args = self.args().peekable(); | ||
325 | let prefix = args | ||
326 | .peeking_take_while(|p| match p { | ||
327 | ast::Pat::DotDotPat(_) => false, | ||
328 | ast::Pat::BindPat(bp) => match bp.pat() { | ||
329 | Some(ast::Pat::DotDotPat(_)) => false, | ||
330 | _ => true, | ||
331 | }, | ||
332 | ast::Pat::RefPat(rp) => match rp.pat() { | ||
333 | Some(ast::Pat::DotDotPat(_)) => false, | ||
334 | Some(ast::Pat::BindPat(bp)) => match bp.pat() { | ||
335 | Some(ast::Pat::DotDotPat(_)) => false, | ||
336 | _ => true, | ||
337 | }, | ||
338 | _ => true, | ||
339 | }, | ||
340 | _ => true, | ||
341 | }) | ||
342 | .collect(); | ||
343 | let slice = args.next(); | ||
344 | let suffix = args.collect(); | ||
345 | |||
346 | SlicePatComponents { prefix, slice, suffix } | ||
347 | } | ||
348 | } | ||
349 | |||
296 | impl ast::PointerType { | 350 | impl ast::PointerType { |
297 | pub fn is_mut(&self) -> bool { | 351 | pub fn is_mut(&self) -> bool { |
298 | self.syntax().children_with_tokens().any(|n| n.kind() == T![mut]) | 352 | self.syntax().children_with_tokens().any(|n| n.kind() == T![mut]) |
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 435135f92..8eb240801 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -1759,8 +1759,8 @@ impl AstNode for MatchArm { | |||
1759 | } | 1759 | } |
1760 | impl ast::AttrsOwner for MatchArm {} | 1760 | impl ast::AttrsOwner for MatchArm {} |
1761 | impl MatchArm { | 1761 | impl MatchArm { |
1762 | pub fn pats(&self) -> AstChildren<Pat> { | 1762 | pub fn pat(&self) -> Option<Pat> { |
1763 | AstChildren::new(&self.syntax) | 1763 | AstChildren::new(&self.syntax).next() |
1764 | } | 1764 | } |
1765 | pub fn guard(&self) -> Option<MatchGuard> { | 1765 | pub fn guard(&self) -> Option<MatchGuard> { |
1766 | AstChildren::new(&self.syntax).next() | 1766 | AstChildren::new(&self.syntax).next() |
@@ -1887,6 +1887,60 @@ impl RecordField { | |||
1887 | } | 1887 | } |
1888 | } | 1888 | } |
1889 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 1889 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
1890 | pub struct OrPat { | ||
1891 | pub(crate) syntax: SyntaxNode, | ||
1892 | } | ||
1893 | impl AstNode for OrPat { | ||
1894 | fn can_cast(kind: SyntaxKind) -> bool { | ||
1895 | match kind { | ||
1896 | OR_PAT => true, | ||
1897 | _ => false, | ||
1898 | } | ||
1899 | } | ||
1900 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
1901 | if Self::can_cast(syntax.kind()) { | ||
1902 | Some(Self { syntax }) | ||
1903 | } else { | ||
1904 | None | ||
1905 | } | ||
1906 | } | ||
1907 | fn syntax(&self) -> &SyntaxNode { | ||
1908 | &self.syntax | ||
1909 | } | ||
1910 | } | ||
1911 | impl OrPat { | ||
1912 | pub fn pats(&self) -> AstChildren<Pat> { | ||
1913 | AstChildren::new(&self.syntax) | ||
1914 | } | ||
1915 | } | ||
1916 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
1917 | pub struct ParenPat { | ||
1918 | pub(crate) syntax: SyntaxNode, | ||
1919 | } | ||
1920 | impl AstNode for ParenPat { | ||
1921 | fn can_cast(kind: SyntaxKind) -> bool { | ||
1922 | match kind { | ||
1923 | PAREN_PAT => true, | ||
1924 | _ => false, | ||
1925 | } | ||
1926 | } | ||
1927 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
1928 | if Self::can_cast(syntax.kind()) { | ||
1929 | Some(Self { syntax }) | ||
1930 | } else { | ||
1931 | None | ||
1932 | } | ||
1933 | } | ||
1934 | fn syntax(&self) -> &SyntaxNode { | ||
1935 | &self.syntax | ||
1936 | } | ||
1937 | } | ||
1938 | impl ParenPat { | ||
1939 | pub fn pat(&self) -> Option<Pat> { | ||
1940 | AstChildren::new(&self.syntax).next() | ||
1941 | } | ||
1942 | } | ||
1943 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
1890 | pub struct RefPat { | 1944 | pub struct RefPat { |
1891 | pub(crate) syntax: SyntaxNode, | 1945 | pub(crate) syntax: SyntaxNode, |
1892 | } | 1946 | } |
@@ -2063,7 +2117,11 @@ impl AstNode for SlicePat { | |||
2063 | &self.syntax | 2117 | &self.syntax |
2064 | } | 2118 | } |
2065 | } | 2119 | } |
2066 | impl SlicePat {} | 2120 | impl SlicePat { |
2121 | pub fn args(&self) -> AstChildren<Pat> { | ||
2122 | AstChildren::new(&self.syntax) | ||
2123 | } | ||
2124 | } | ||
2067 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 2125 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
2068 | pub struct RangePat { | 2126 | pub struct RangePat { |
2069 | pub(crate) syntax: SyntaxNode, | 2127 | pub(crate) syntax: SyntaxNode, |
@@ -3900,6 +3958,8 @@ impl AstNode for Expr { | |||
3900 | } | 3958 | } |
3901 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 3959 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
3902 | pub enum Pat { | 3960 | pub enum Pat { |
3961 | OrPat(OrPat), | ||
3962 | ParenPat(ParenPat), | ||
3903 | RefPat(RefPat), | 3963 | RefPat(RefPat), |
3904 | BoxPat(BoxPat), | 3964 | BoxPat(BoxPat), |
3905 | BindPat(BindPat), | 3965 | BindPat(BindPat), |
@@ -3913,6 +3973,16 @@ pub enum Pat { | |||
3913 | RangePat(RangePat), | 3973 | RangePat(RangePat), |
3914 | LiteralPat(LiteralPat), | 3974 | LiteralPat(LiteralPat), |
3915 | } | 3975 | } |
3976 | impl From<OrPat> for Pat { | ||
3977 | fn from(node: OrPat) -> Pat { | ||
3978 | Pat::OrPat(node) | ||
3979 | } | ||
3980 | } | ||
3981 | impl From<ParenPat> for Pat { | ||
3982 | fn from(node: ParenPat) -> Pat { | ||
3983 | Pat::ParenPat(node) | ||
3984 | } | ||
3985 | } | ||
3916 | impl From<RefPat> for Pat { | 3986 | impl From<RefPat> for Pat { |
3917 | fn from(node: RefPat) -> Pat { | 3987 | fn from(node: RefPat) -> Pat { |
3918 | Pat::RefPat(node) | 3988 | Pat::RefPat(node) |
@@ -3976,15 +4046,16 @@ impl From<LiteralPat> for Pat { | |||
3976 | impl AstNode for Pat { | 4046 | impl AstNode for Pat { |
3977 | fn can_cast(kind: SyntaxKind) -> bool { | 4047 | fn can_cast(kind: SyntaxKind) -> bool { |
3978 | match kind { | 4048 | match kind { |
3979 | REF_PAT | BOX_PAT | BIND_PAT | PLACEHOLDER_PAT | DOT_DOT_PAT | PATH_PAT | 4049 | OR_PAT | PAREN_PAT | REF_PAT | BOX_PAT | BIND_PAT | PLACEHOLDER_PAT | DOT_DOT_PAT |
3980 | | RECORD_PAT | TUPLE_STRUCT_PAT | TUPLE_PAT | SLICE_PAT | RANGE_PAT | LITERAL_PAT => { | 4050 | | PATH_PAT | RECORD_PAT | TUPLE_STRUCT_PAT | TUPLE_PAT | SLICE_PAT | RANGE_PAT |
3981 | true | 4051 | | LITERAL_PAT => true, |
3982 | } | ||
3983 | _ => false, | 4052 | _ => false, |
3984 | } | 4053 | } |
3985 | } | 4054 | } |
3986 | fn cast(syntax: SyntaxNode) -> Option<Self> { | 4055 | fn cast(syntax: SyntaxNode) -> Option<Self> { |
3987 | let res = match syntax.kind() { | 4056 | let res = match syntax.kind() { |
4057 | OR_PAT => Pat::OrPat(OrPat { syntax }), | ||
4058 | PAREN_PAT => Pat::ParenPat(ParenPat { syntax }), | ||
3988 | REF_PAT => Pat::RefPat(RefPat { syntax }), | 4059 | REF_PAT => Pat::RefPat(RefPat { syntax }), |
3989 | BOX_PAT => Pat::BoxPat(BoxPat { syntax }), | 4060 | BOX_PAT => Pat::BoxPat(BoxPat { syntax }), |
3990 | BIND_PAT => Pat::BindPat(BindPat { syntax }), | 4061 | BIND_PAT => Pat::BindPat(BindPat { syntax }), |
@@ -4003,6 +4074,8 @@ impl AstNode for Pat { | |||
4003 | } | 4074 | } |
4004 | fn syntax(&self) -> &SyntaxNode { | 4075 | fn syntax(&self) -> &SyntaxNode { |
4005 | match self { | 4076 | match self { |
4077 | Pat::OrPat(it) => &it.syntax, | ||
4078 | Pat::ParenPat(it) => &it.syntax, | ||
4006 | Pat::RefPat(it) => &it.syntax, | 4079 | Pat::RefPat(it) => &it.syntax, |
4007 | Pat::BoxPat(it) => &it.syntax, | 4080 | Pat::BoxPat(it) => &it.syntax, |
4008 | Pat::BindPat(it) => &it.syntax, | 4081 | Pat::BindPat(it) => &it.syntax, |