aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/ast
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/ast')
-rw-r--r--crates/ra_syntax/src/ast/extensions.rs54
-rw-r--r--crates/ra_syntax/src/ast/generated.rs87
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
4use itertools::Itertools;
5
4use crate::{ 6use 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)]
41pub enum AttrKind {
42 Inner,
43 Outer,
44}
45
38impl ast::Attr { 46impl 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
316pub struct SlicePatComponents {
317 pub prefix: Vec<ast::Pat>,
318 pub slice: Option<ast::Pat>,
319 pub suffix: Vec<ast::Pat>,
320}
321
322impl 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
296impl ast::PointerType { 350impl 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}
1760impl ast::AttrsOwner for MatchArm {} 1760impl ast::AttrsOwner for MatchArm {}
1761impl MatchArm { 1761impl 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)]
1890pub struct OrPat {
1891 pub(crate) syntax: SyntaxNode,
1892}
1893impl 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}
1911impl OrPat {
1912 pub fn pats(&self) -> AstChildren<Pat> {
1913 AstChildren::new(&self.syntax)
1914 }
1915}
1916#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1917pub struct ParenPat {
1918 pub(crate) syntax: SyntaxNode,
1919}
1920impl 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}
1938impl ParenPat {
1939 pub fn pat(&self) -> Option<Pat> {
1940 AstChildren::new(&self.syntax).next()
1941 }
1942}
1943#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1890pub struct RefPat { 1944pub 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}
2066impl SlicePat {} 2120impl 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)]
2068pub struct RangePat { 2126pub 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)]
3902pub enum Pat { 3960pub 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}
3976impl From<OrPat> for Pat {
3977 fn from(node: OrPat) -> Pat {
3978 Pat::OrPat(node)
3979 }
3980}
3981impl From<ParenPat> for Pat {
3982 fn from(node: ParenPat) -> Pat {
3983 Pat::ParenPat(node)
3984 }
3985}
3916impl From<RefPat> for Pat { 3986impl 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 {
3976impl AstNode for Pat { 4046impl 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,