From b5021411a84822cb3f1e3aeffad9550dd15bdeb6 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 16 Sep 2018 12:54:24 +0300 Subject: rename all things --- crates/libsyntax2/src/algo/mod.rs | 129 -- crates/libsyntax2/src/algo/visit.rs | 110 - crates/libsyntax2/src/algo/walk.rs | 38 - crates/libsyntax2/src/ast/generated.rs | 2142 -------------------- crates/libsyntax2/src/ast/generated.rs.tera | 83 - crates/libsyntax2/src/ast/mod.rs | 206 -- crates/libsyntax2/src/grammar.ron | 538 ----- crates/libsyntax2/src/grammar/attributes.rs | 31 - crates/libsyntax2/src/grammar/expressions/atom.rs | 400 ---- crates/libsyntax2/src/grammar/expressions/mod.rs | 450 ---- crates/libsyntax2/src/grammar/items/consts.rs | 21 - crates/libsyntax2/src/grammar/items/mod.rs | 393 ---- crates/libsyntax2/src/grammar/items/nominal.rs | 154 -- crates/libsyntax2/src/grammar/items/traits.rs | 117 -- crates/libsyntax2/src/grammar/items/use_item.rs | 68 - crates/libsyntax2/src/grammar/mod.rs | 188 -- crates/libsyntax2/src/grammar/params.rs | 142 -- crates/libsyntax2/src/grammar/paths.rs | 101 - crates/libsyntax2/src/grammar/patterns.rs | 224 -- crates/libsyntax2/src/grammar/type_args.rs | 48 - crates/libsyntax2/src/grammar/type_params.rs | 136 -- crates/libsyntax2/src/grammar/types.rs | 247 --- crates/libsyntax2/src/lexer/classes.rs | 26 - crates/libsyntax2/src/lexer/comments.rs | 57 - crates/libsyntax2/src/lexer/mod.rs | 209 -- crates/libsyntax2/src/lexer/numbers.rs | 67 - crates/libsyntax2/src/lexer/ptr.rs | 166 -- crates/libsyntax2/src/lexer/strings.rs | 123 -- crates/libsyntax2/src/lib.rs | 105 - crates/libsyntax2/src/parser_api.rs | 178 -- crates/libsyntax2/src/parser_impl/event.rs | 154 -- crates/libsyntax2/src/parser_impl/input.rs | 86 - crates/libsyntax2/src/parser_impl/mod.rs | 194 -- crates/libsyntax2/src/reparsing.rs | 343 ---- crates/libsyntax2/src/syntax_kinds/generated.rs | 562 ----- .../libsyntax2/src/syntax_kinds/generated.rs.tera | 73 - crates/libsyntax2/src/syntax_kinds/mod.rs | 26 - crates/libsyntax2/src/text_utils.rs | 26 - crates/libsyntax2/src/token_set.rs | 37 - crates/libsyntax2/src/utils.rs | 85 - crates/libsyntax2/src/yellow/builder.rs | 64 - crates/libsyntax2/src/yellow/green.rs | 90 - crates/libsyntax2/src/yellow/mod.rs | 100 - crates/libsyntax2/src/yellow/red.rs | 113 -- crates/libsyntax2/src/yellow/syntax.rs | 215 -- crates/libsyntax2/src/yellow/syntax_text.rs | 122 -- 46 files changed, 9187 deletions(-) delete mode 100644 crates/libsyntax2/src/algo/mod.rs delete mode 100644 crates/libsyntax2/src/algo/visit.rs delete mode 100644 crates/libsyntax2/src/algo/walk.rs delete mode 100644 crates/libsyntax2/src/ast/generated.rs delete mode 100644 crates/libsyntax2/src/ast/generated.rs.tera delete mode 100644 crates/libsyntax2/src/ast/mod.rs delete mode 100644 crates/libsyntax2/src/grammar.ron delete mode 100644 crates/libsyntax2/src/grammar/attributes.rs delete mode 100644 crates/libsyntax2/src/grammar/expressions/atom.rs delete mode 100644 crates/libsyntax2/src/grammar/expressions/mod.rs delete mode 100644 crates/libsyntax2/src/grammar/items/consts.rs delete mode 100644 crates/libsyntax2/src/grammar/items/mod.rs delete mode 100644 crates/libsyntax2/src/grammar/items/nominal.rs delete mode 100644 crates/libsyntax2/src/grammar/items/traits.rs delete mode 100644 crates/libsyntax2/src/grammar/items/use_item.rs delete mode 100644 crates/libsyntax2/src/grammar/mod.rs delete mode 100644 crates/libsyntax2/src/grammar/params.rs delete mode 100644 crates/libsyntax2/src/grammar/paths.rs delete mode 100644 crates/libsyntax2/src/grammar/patterns.rs delete mode 100644 crates/libsyntax2/src/grammar/type_args.rs delete mode 100644 crates/libsyntax2/src/grammar/type_params.rs delete mode 100644 crates/libsyntax2/src/grammar/types.rs delete mode 100644 crates/libsyntax2/src/lexer/classes.rs delete mode 100644 crates/libsyntax2/src/lexer/comments.rs delete mode 100644 crates/libsyntax2/src/lexer/mod.rs delete mode 100644 crates/libsyntax2/src/lexer/numbers.rs delete mode 100644 crates/libsyntax2/src/lexer/ptr.rs delete mode 100644 crates/libsyntax2/src/lexer/strings.rs delete mode 100644 crates/libsyntax2/src/lib.rs delete mode 100644 crates/libsyntax2/src/parser_api.rs delete mode 100644 crates/libsyntax2/src/parser_impl/event.rs delete mode 100644 crates/libsyntax2/src/parser_impl/input.rs delete mode 100644 crates/libsyntax2/src/parser_impl/mod.rs delete mode 100644 crates/libsyntax2/src/reparsing.rs delete mode 100644 crates/libsyntax2/src/syntax_kinds/generated.rs delete mode 100644 crates/libsyntax2/src/syntax_kinds/generated.rs.tera delete mode 100644 crates/libsyntax2/src/syntax_kinds/mod.rs delete mode 100644 crates/libsyntax2/src/text_utils.rs delete mode 100644 crates/libsyntax2/src/token_set.rs delete mode 100644 crates/libsyntax2/src/utils.rs delete mode 100644 crates/libsyntax2/src/yellow/builder.rs delete mode 100644 crates/libsyntax2/src/yellow/green.rs delete mode 100644 crates/libsyntax2/src/yellow/mod.rs delete mode 100644 crates/libsyntax2/src/yellow/red.rs delete mode 100644 crates/libsyntax2/src/yellow/syntax.rs delete mode 100644 crates/libsyntax2/src/yellow/syntax_text.rs (limited to 'crates/libsyntax2/src') diff --git a/crates/libsyntax2/src/algo/mod.rs b/crates/libsyntax2/src/algo/mod.rs deleted file mode 100644 index 7287f5bb2..000000000 --- a/crates/libsyntax2/src/algo/mod.rs +++ /dev/null @@ -1,129 +0,0 @@ -pub mod walk; -pub mod visit; - -use { - SyntaxNodeRef, TextUnit, TextRange, - text_utils::{contains_offset_nonstrict, is_subrange}, -}; - -pub fn find_leaf_at_offset(node: SyntaxNodeRef, offset: TextUnit) -> LeafAtOffset { - let range = node.range(); - assert!( - contains_offset_nonstrict(range, offset), - "Bad offset: range {:?} offset {:?}", range, offset - ); - if range.is_empty() { - return LeafAtOffset::None; - } - - if node.is_leaf() { - return LeafAtOffset::Single(node); - } - - let mut children = node.children() - .filter(|child| { - let child_range = child.range(); - !child_range.is_empty() && contains_offset_nonstrict(child_range, offset) - }); - - let left = children.next().unwrap(); - let right = children.next(); - assert!(children.next().is_none()); - return if let Some(right) = right { - match (find_leaf_at_offset(left, offset), find_leaf_at_offset(right, offset)) { - (LeafAtOffset::Single(left), LeafAtOffset::Single(right)) => - LeafAtOffset::Between(left, right), - _ => unreachable!() - } - } else { - find_leaf_at_offset(left, offset) - }; -} - -#[derive(Clone, Copy, Debug)] -pub enum LeafAtOffset<'a> { - None, - Single(SyntaxNodeRef<'a>), - Between(SyntaxNodeRef<'a>, SyntaxNodeRef<'a>) -} - -impl<'a> LeafAtOffset<'a> { - pub fn right_biased(self) -> Option> { - match self { - LeafAtOffset::None => None, - LeafAtOffset::Single(node) => Some(node), - LeafAtOffset::Between(_, right) => Some(right) - } - } - - pub fn left_biased(self) -> Option> { - match self { - LeafAtOffset::None => None, - LeafAtOffset::Single(node) => Some(node), - LeafAtOffset::Between(left, _) => Some(left) - } - } -} - -impl<'f> Iterator for LeafAtOffset<'f> { - type Item = SyntaxNodeRef<'f>; - - fn next(&mut self) -> Option> { - match *self { - LeafAtOffset::None => None, - LeafAtOffset::Single(node) => { *self = LeafAtOffset::None; Some(node) } - LeafAtOffset::Between(left, right) => { *self = LeafAtOffset::Single(right); Some(left) } - } - } -} - -pub fn find_covering_node(root: SyntaxNodeRef, range: TextRange) -> SyntaxNodeRef { - assert!(is_subrange(root.range(), range)); - let (left, right) = match ( - find_leaf_at_offset(root, range.start()).right_biased(), - find_leaf_at_offset(root, range.end()).left_biased() - ) { - (Some(l), Some(r)) => (l, r), - _ => return root - }; - - common_ancestor(left, right) -} - -pub fn ancestors<'a>(node: SyntaxNodeRef<'a>) -> impl Iterator> { - generate(Some(node), |&node| node.parent()) -} - -#[derive(Debug)] -pub enum Direction { - Forward, - Backward, -} - -pub fn siblings<'a>( - node: SyntaxNodeRef<'a>, - direction: Direction -) -> impl Iterator> { - generate(Some(node), move |&node| match direction { - Direction::Forward => node.next_sibling(), - Direction::Backward => node.prev_sibling(), - }) -} - -fn common_ancestor<'a>(n1: SyntaxNodeRef<'a>, n2: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a> { - for p in ancestors(n1) { - if ancestors(n2).any(|a| a == p) { - return p; - } - } - panic!("Can't find common ancestor of {:?} and {:?}", n1, n2) -} - -pub fn generate(seed: Option, step: impl Fn(&T) -> Option) -> impl Iterator { - ::itertools::unfold(seed, move |slot| { - slot.take().map(|curr| { - *slot = step(&curr); - curr - }) - }) -} diff --git a/crates/libsyntax2/src/algo/visit.rs b/crates/libsyntax2/src/algo/visit.rs deleted file mode 100644 index 9f1c127c7..000000000 --- a/crates/libsyntax2/src/algo/visit.rs +++ /dev/null @@ -1,110 +0,0 @@ -use std::marker::PhantomData; -use {SyntaxNodeRef, AstNode}; - - -pub fn visitor<'a, T>() -> impl Visitor<'a, Output=T> { - EmptyVisitor { ph: PhantomData } -} - -pub fn visitor_ctx<'a, T, C>(ctx: C) -> impl VisitorCtx<'a, Output=T, Ctx=C> { - EmptyVisitorCtx { ph: PhantomData, ctx } -} - -pub trait Visitor<'a>: Sized { - type Output; - fn accept(self, node: SyntaxNodeRef<'a>) -> Option; - fn visit(self, f: F) -> Vis - where N: AstNode<'a>, - F: FnOnce(N) -> Self::Output, - { - Vis { inner: self, f, ph: PhantomData } - } -} - -pub trait VisitorCtx<'a>: Sized { - type Output; - type Ctx; - fn accept(self, node: SyntaxNodeRef<'a>) -> Result; - fn visit(self, f: F) -> VisCtx - where N: AstNode<'a>, - F: FnOnce(N, Self::Ctx) -> Self::Output, - { - VisCtx { inner: self, f, ph: PhantomData } - } -} - -#[derive(Debug)] -struct EmptyVisitor { - ph: PhantomData T> -} - -impl<'a, T> Visitor<'a> for EmptyVisitor { - type Output = T; - - fn accept(self, _node: SyntaxNodeRef<'a>) -> Option { - None - } -} - -#[derive(Debug)] -struct EmptyVisitorCtx { - ctx: C, - ph: PhantomData T>, -} - -impl<'a, T, C> VisitorCtx<'a> for EmptyVisitorCtx { - type Output = T; - type Ctx = C; - - fn accept(self, _node: SyntaxNodeRef<'a>) -> Result { - Err(self.ctx) - } -} - -#[derive(Debug)] -pub struct Vis { - inner: V, - f: F, - ph: PhantomData, -} - -impl<'a, V, N, F> Visitor<'a> for Vis - where - V: Visitor<'a>, - N: AstNode<'a>, - F: FnOnce(N) -> >::Output, -{ - type Output = >::Output; - - fn accept(self, node: SyntaxNodeRef<'a>) -> Option { - let Vis { inner, f, .. } = self; - inner.accept(node).or_else(|| N::cast(node).map(f)) - } -} - -#[derive(Debug)] -pub struct VisCtx { - inner: V, - f: F, - ph: PhantomData, -} - -impl<'a, V, N, F> VisitorCtx<'a> for VisCtx - where - V: VisitorCtx<'a>, - N: AstNode<'a>, - F: FnOnce(N, >::Ctx) -> >::Output, -{ - type Output = >::Output; - type Ctx = >::Ctx; - - fn accept(self, node: SyntaxNodeRef<'a>) -> Result { - let VisCtx { inner, f, .. } = self; - inner.accept(node).or_else(|ctx| - match N::cast(node) { - None => Err(ctx), - Some(node) => Ok(f(node, ctx)) - } - ) - } -} diff --git a/crates/libsyntax2/src/algo/walk.rs b/crates/libsyntax2/src/algo/walk.rs deleted file mode 100644 index 536ee705f..000000000 --- a/crates/libsyntax2/src/algo/walk.rs +++ /dev/null @@ -1,38 +0,0 @@ -use { - SyntaxNodeRef, - algo::generate, -}; - -pub fn preorder<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator> { - walk(root).filter_map(|event| match event { - WalkEvent::Enter(node) => Some(node), - WalkEvent::Exit(_) => None, - }) -} - -#[derive(Debug, Copy, Clone)] -pub enum WalkEvent<'a> { - Enter(SyntaxNodeRef<'a>), - Exit(SyntaxNodeRef<'a>), -} - -pub fn walk<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator> { - generate(Some(WalkEvent::Enter(root)), move |pos| { - let next = match *pos { - WalkEvent::Enter(node) => match node.first_child() { - Some(child) => WalkEvent::Enter(child), - None => WalkEvent::Exit(node), - }, - WalkEvent::Exit(node) => { - if node == root { - return None; - } - match node.next_sibling() { - Some(sibling) => WalkEvent::Enter(sibling), - None => WalkEvent::Exit(node.parent().unwrap()), - } - } - }; - Some(next) - }) -} diff --git a/crates/libsyntax2/src/ast/generated.rs b/crates/libsyntax2/src/ast/generated.rs deleted file mode 100644 index c945c094a..000000000 --- a/crates/libsyntax2/src/ast/generated.rs +++ /dev/null @@ -1,2142 +0,0 @@ -use { - ast, - SyntaxNodeRef, AstNode, - SyntaxKind::*, -}; - -// ArgList -#[derive(Debug, Clone, Copy)] -pub struct ArgList<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for ArgList<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - ARG_LIST => Some(ArgList { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ArgList<'a> { - pub fn args(self) -> impl Iterator> + 'a { - super::children(self) - } -} - -// ArrayExpr -#[derive(Debug, Clone, Copy)] -pub struct ArrayExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for ArrayExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - ARRAY_EXPR => Some(ArrayExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ArrayExpr<'a> {} - -// ArrayType -#[derive(Debug, Clone, Copy)] -pub struct ArrayType<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for ArrayType<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - ARRAY_TYPE => Some(ArrayType { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ArrayType<'a> {} - -// Attr -#[derive(Debug, Clone, Copy)] -pub struct Attr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for Attr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - ATTR => Some(Attr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> Attr<'a> {pub fn value(self) -> Option> { - super::child_opt(self) - } -} - -// BinExpr -#[derive(Debug, Clone, Copy)] -pub struct BinExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for BinExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - BIN_EXPR => Some(BinExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> BinExpr<'a> {} - -// BindPat -#[derive(Debug, Clone, Copy)] -pub struct BindPat<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for BindPat<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - BIND_PAT => Some(BindPat { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ast::NameOwner<'a> for BindPat<'a> {} -impl<'a> BindPat<'a> {} - -// Block -#[derive(Debug, Clone, Copy)] -pub struct Block<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for Block<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - BLOCK => Some(Block { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> Block<'a> { - pub fn statements(self) -> impl Iterator> + 'a { - super::children(self) - } -pub fn expr(self) -> Option> { - super::child_opt(self) - } -} - -// BlockExpr -#[derive(Debug, Clone, Copy)] -pub struct BlockExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for BlockExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - BLOCK_EXPR => Some(BlockExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> BlockExpr<'a> {pub fn block(self) -> Option> { - super::child_opt(self) - } -} - -// BreakExpr -#[derive(Debug, Clone, Copy)] -pub struct BreakExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for BreakExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - BREAK_EXPR => Some(BreakExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> BreakExpr<'a> {} - -// CallExpr -#[derive(Debug, Clone, Copy)] -pub struct CallExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for CallExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - CALL_EXPR => Some(CallExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ast::ArgListOwner<'a> for CallExpr<'a> {} -impl<'a> CallExpr<'a> {pub fn expr(self) -> Option> { - super::child_opt(self) - } -} - -// CastExpr -#[derive(Debug, Clone, Copy)] -pub struct CastExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for CastExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - CAST_EXPR => Some(CastExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> CastExpr<'a> {} - -// Condition -#[derive(Debug, Clone, Copy)] -pub struct Condition<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for Condition<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - CONDITION => Some(Condition { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> Condition<'a> {pub fn pat(self) -> Option> { - super::child_opt(self) - } -pub fn expr(self) -> Option> { - super::child_opt(self) - } -} - -// ConstDef -#[derive(Debug, Clone, Copy)] -pub struct ConstDef<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for ConstDef<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - CONST_DEF => Some(ConstDef { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ast::NameOwner<'a> for ConstDef<'a> {} -impl<'a> ast::TypeParamsOwner<'a> for ConstDef<'a> {} -impl<'a> ast::AttrsOwner<'a> for ConstDef<'a> {} -impl<'a> ConstDef<'a> {} - -// ContinueExpr -#[derive(Debug, Clone, Copy)] -pub struct ContinueExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for ContinueExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - CONTINUE_EXPR => Some(ContinueExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ContinueExpr<'a> {} - -// DynTraitType -#[derive(Debug, Clone, Copy)] -pub struct DynTraitType<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for DynTraitType<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - DYN_TRAIT_TYPE => Some(DynTraitType { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> DynTraitType<'a> {} - -// EnumDef -#[derive(Debug, Clone, Copy)] -pub struct EnumDef<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for EnumDef<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - ENUM_DEF => Some(EnumDef { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ast::NameOwner<'a> for EnumDef<'a> {} -impl<'a> ast::TypeParamsOwner<'a> for EnumDef<'a> {} -impl<'a> ast::AttrsOwner<'a> for EnumDef<'a> {} -impl<'a> EnumDef<'a> {} - -// Expr -#[derive(Debug, Clone, Copy)] -pub enum Expr<'a> { - TupleExpr(TupleExpr<'a>), - ArrayExpr(ArrayExpr<'a>), - ParenExpr(ParenExpr<'a>), - PathExpr(PathExpr<'a>), - LambdaExpr(LambdaExpr<'a>), - IfExpr(IfExpr<'a>), - LoopExpr(LoopExpr<'a>), - ForExpr(ForExpr<'a>), - WhileExpr(WhileExpr<'a>), - ContinueExpr(ContinueExpr<'a>), - BreakExpr(BreakExpr<'a>), - Label(Label<'a>), - BlockExpr(BlockExpr<'a>), - ReturnExpr(ReturnExpr<'a>), - MatchExpr(MatchExpr<'a>), - MatchArmList(MatchArmList<'a>), - MatchArm(MatchArm<'a>), - MatchGuard(MatchGuard<'a>), - StructLit(StructLit<'a>), - NamedFieldList(NamedFieldList<'a>), - NamedField(NamedField<'a>), - CallExpr(CallExpr<'a>), - IndexExpr(IndexExpr<'a>), - MethodCallExpr(MethodCallExpr<'a>), - FieldExpr(FieldExpr<'a>), - TryExpr(TryExpr<'a>), - CastExpr(CastExpr<'a>), - RefExpr(RefExpr<'a>), - PrefixExpr(PrefixExpr<'a>), - RangeExpr(RangeExpr<'a>), - BinExpr(BinExpr<'a>), - Literal(Literal<'a>), -} - -impl<'a> AstNode<'a> for Expr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - TUPLE_EXPR => Some(Expr::TupleExpr(TupleExpr { syntax })), - ARRAY_EXPR => Some(Expr::ArrayExpr(ArrayExpr { syntax })), - PAREN_EXPR => Some(Expr::ParenExpr(ParenExpr { syntax })), - PATH_EXPR => Some(Expr::PathExpr(PathExpr { syntax })), - LAMBDA_EXPR => Some(Expr::LambdaExpr(LambdaExpr { syntax })), - IF_EXPR => Some(Expr::IfExpr(IfExpr { syntax })), - LOOP_EXPR => Some(Expr::LoopExpr(LoopExpr { syntax })), - FOR_EXPR => Some(Expr::ForExpr(ForExpr { syntax })), - WHILE_EXPR => Some(Expr::WhileExpr(WhileExpr { syntax })), - CONTINUE_EXPR => Some(Expr::ContinueExpr(ContinueExpr { syntax })), - BREAK_EXPR => Some(Expr::BreakExpr(BreakExpr { syntax })), - LABEL => Some(Expr::Label(Label { syntax })), - BLOCK_EXPR => Some(Expr::BlockExpr(BlockExpr { syntax })), - RETURN_EXPR => Some(Expr::ReturnExpr(ReturnExpr { syntax })), - MATCH_EXPR => Some(Expr::MatchExpr(MatchExpr { syntax })), - MATCH_ARM_LIST => Some(Expr::MatchArmList(MatchArmList { syntax })), - MATCH_ARM => Some(Expr::MatchArm(MatchArm { syntax })), - MATCH_GUARD => Some(Expr::MatchGuard(MatchGuard { syntax })), - STRUCT_LIT => Some(Expr::StructLit(StructLit { syntax })), - NAMED_FIELD_LIST => Some(Expr::NamedFieldList(NamedFieldList { syntax })), - NAMED_FIELD => Some(Expr::NamedField(NamedField { syntax })), - CALL_EXPR => Some(Expr::CallExpr(CallExpr { syntax })), - INDEX_EXPR => Some(Expr::IndexExpr(IndexExpr { syntax })), - METHOD_CALL_EXPR => Some(Expr::MethodCallExpr(MethodCallExpr { syntax })), - FIELD_EXPR => Some(Expr::FieldExpr(FieldExpr { syntax })), - TRY_EXPR => Some(Expr::TryExpr(TryExpr { syntax })), - CAST_EXPR => Some(Expr::CastExpr(CastExpr { syntax })), - REF_EXPR => Some(Expr::RefExpr(RefExpr { syntax })), - PREFIX_EXPR => Some(Expr::PrefixExpr(PrefixExpr { syntax })), - RANGE_EXPR => Some(Expr::RangeExpr(RangeExpr { syntax })), - BIN_EXPR => Some(Expr::BinExpr(BinExpr { syntax })), - LITERAL => Some(Expr::Literal(Literal { syntax })), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { - match self { - Expr::TupleExpr(inner) => inner.syntax(), - Expr::ArrayExpr(inner) => inner.syntax(), - Expr::ParenExpr(inner) => inner.syntax(), - Expr::PathExpr(inner) => inner.syntax(), - Expr::LambdaExpr(inner) => inner.syntax(), - Expr::IfExpr(inner) => inner.syntax(), - Expr::LoopExpr(inner) => inner.syntax(), - Expr::ForExpr(inner) => inner.syntax(), - Expr::WhileExpr(inner) => inner.syntax(), - Expr::ContinueExpr(inner) => inner.syntax(), - Expr::BreakExpr(inner) => inner.syntax(), - Expr::Label(inner) => inner.syntax(), - Expr::BlockExpr(inner) => inner.syntax(), - Expr::ReturnExpr(inner) => inner.syntax(), - Expr::MatchExpr(inner) => inner.syntax(), - Expr::MatchArmList(inner) => inner.syntax(), - Expr::MatchArm(inner) => inner.syntax(), - Expr::MatchGuard(inner) => inner.syntax(), - Expr::StructLit(inner) => inner.syntax(), - Expr::NamedFieldList(inner) => inner.syntax(), - Expr::NamedField(inner) => inner.syntax(), - Expr::CallExpr(inner) => inner.syntax(), - Expr::IndexExpr(inner) => inner.syntax(), - Expr::MethodCallExpr(inner) => inner.syntax(), - Expr::FieldExpr(inner) => inner.syntax(), - Expr::TryExpr(inner) => inner.syntax(), - Expr::CastExpr(inner) => inner.syntax(), - Expr::RefExpr(inner) => inner.syntax(), - Expr::PrefixExpr(inner) => inner.syntax(), - Expr::RangeExpr(inner) => inner.syntax(), - Expr::BinExpr(inner) => inner.syntax(), - Expr::Literal(inner) => inner.syntax(), - } - } -} - -impl<'a> Expr<'a> {} - -// ExprStmt -#[derive(Debug, Clone, Copy)] -pub struct ExprStmt<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for ExprStmt<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - EXPR_STMT => Some(ExprStmt { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ExprStmt<'a> {pub fn expr(self) -> Option> { - super::child_opt(self) - } -} - -// ExternCrateItem -#[derive(Debug, Clone, Copy)] -pub struct ExternCrateItem<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for ExternCrateItem<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - EXTERN_CRATE_ITEM => Some(ExternCrateItem { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ExternCrateItem<'a> {} - -// FieldExpr -#[derive(Debug, Clone, Copy)] -pub struct FieldExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for FieldExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - FIELD_EXPR => Some(FieldExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> FieldExpr<'a> {} - -// FieldPatList -#[derive(Debug, Clone, Copy)] -pub struct FieldPatList<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for FieldPatList<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - FIELD_PAT_LIST => Some(FieldPatList { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> FieldPatList<'a> {} - -// FnDef -#[derive(Debug, Clone, Copy)] -pub struct FnDef<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for FnDef<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - FN_DEF => Some(FnDef { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ast::NameOwner<'a> for FnDef<'a> {} -impl<'a> ast::TypeParamsOwner<'a> for FnDef<'a> {} -impl<'a> ast::AttrsOwner<'a> for FnDef<'a> {} -impl<'a> FnDef<'a> {pub fn param_list(self) -> Option> { - super::child_opt(self) - } -pub fn body(self) -> Option> { - super::child_opt(self) - } -pub fn ret_type(self) -> Option> { - super::child_opt(self) - } -} - -// FnPointerType -#[derive(Debug, Clone, Copy)] -pub struct FnPointerType<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for FnPointerType<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - FN_POINTER_TYPE => Some(FnPointerType { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> FnPointerType<'a> {} - -// ForExpr -#[derive(Debug, Clone, Copy)] -pub struct ForExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for ForExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - FOR_EXPR => Some(ForExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ast::LoopBodyOwner<'a> for ForExpr<'a> {} -impl<'a> ForExpr<'a> {pub fn pat(self) -> Option> { - super::child_opt(self) - } -pub fn iterable(self) -> Option> { - super::child_opt(self) - } -} - -// ForType -#[derive(Debug, Clone, Copy)] -pub struct ForType<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for ForType<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - FOR_TYPE => Some(ForType { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ForType<'a> {} - -// IfExpr -#[derive(Debug, Clone, Copy)] -pub struct IfExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for IfExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - IF_EXPR => Some(IfExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> IfExpr<'a> {pub fn condition(self) -> Option> { - super::child_opt(self) - } -} - -// ImplItem -#[derive(Debug, Clone, Copy)] -pub struct ImplItem<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for ImplItem<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - IMPL_ITEM => Some(ImplItem { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ImplItem<'a> {} - -// ImplTraitType -#[derive(Debug, Clone, Copy)] -pub struct ImplTraitType<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for ImplTraitType<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - IMPL_TRAIT_TYPE => Some(ImplTraitType { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ImplTraitType<'a> {} - -// IndexExpr -#[derive(Debug, Clone, Copy)] -pub struct IndexExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for IndexExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - INDEX_EXPR => Some(IndexExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> IndexExpr<'a> {} - -// ItemList -#[derive(Debug, Clone, Copy)] -pub struct ItemList<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for ItemList<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - ITEM_LIST => Some(ItemList { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ast::FnDefOwner<'a> for ItemList<'a> {} -impl<'a> ast::ModuleItemOwner<'a> for ItemList<'a> {} -impl<'a> ItemList<'a> {} - -// Label -#[derive(Debug, Clone, Copy)] -pub struct Label<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for Label<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - LABEL => Some(Label { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> Label<'a> {} - -// LambdaExpr -#[derive(Debug, Clone, Copy)] -pub struct LambdaExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for LambdaExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - LAMBDA_EXPR => Some(LambdaExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> LambdaExpr<'a> {pub fn param_list(self) -> Option> { - super::child_opt(self) - } -pub fn body(self) -> Option> { - super::child_opt(self) - } -} - -// LetStmt -#[derive(Debug, Clone, Copy)] -pub struct LetStmt<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for LetStmt<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - LET_STMT => Some(LetStmt { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> LetStmt<'a> {pub fn pat(self) -> Option> { - super::child_opt(self) - } -pub fn initializer(self) -> Option> { - super::child_opt(self) - } -} - -// Lifetime -#[derive(Debug, Clone, Copy)] -pub struct Lifetime<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for Lifetime<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - LIFETIME => Some(Lifetime { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> Lifetime<'a> {} - -// LifetimeParam -#[derive(Debug, Clone, Copy)] -pub struct LifetimeParam<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for LifetimeParam<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - LIFETIME_PARAM => Some(LifetimeParam { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> LifetimeParam<'a> {pub fn lifetime(self) -> Option> { - super::child_opt(self) - } -} - -// Literal -#[derive(Debug, Clone, Copy)] -pub struct Literal<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for Literal<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - LITERAL => Some(Literal { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> Literal<'a> {} - -// LoopExpr -#[derive(Debug, Clone, Copy)] -pub struct LoopExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for LoopExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - LOOP_EXPR => Some(LoopExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ast::LoopBodyOwner<'a> for LoopExpr<'a> {} -impl<'a> LoopExpr<'a> {} - -// MatchArm -#[derive(Debug, Clone, Copy)] -pub struct MatchArm<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for MatchArm<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - MATCH_ARM => Some(MatchArm { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> MatchArm<'a> { - pub fn pats(self) -> impl Iterator> + 'a { - super::children(self) - } -pub fn guard(self) -> Option> { - super::child_opt(self) - } -pub fn expr(self) -> Option> { - super::child_opt(self) - } -} - -// MatchArmList -#[derive(Debug, Clone, Copy)] -pub struct MatchArmList<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for MatchArmList<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - MATCH_ARM_LIST => Some(MatchArmList { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> MatchArmList<'a> { - pub fn arms(self) -> impl Iterator> + 'a { - super::children(self) - } -} - -// MatchExpr -#[derive(Debug, Clone, Copy)] -pub struct MatchExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for MatchExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - MATCH_EXPR => Some(MatchExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> MatchExpr<'a> {pub fn expr(self) -> Option> { - super::child_opt(self) - } -pub fn match_arm_list(self) -> Option> { - super::child_opt(self) - } -} - -// MatchGuard -#[derive(Debug, Clone, Copy)] -pub struct MatchGuard<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for MatchGuard<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - MATCH_GUARD => Some(MatchGuard { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> MatchGuard<'a> {} - -// MethodCallExpr -#[derive(Debug, Clone, Copy)] -pub struct MethodCallExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for MethodCallExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - METHOD_CALL_EXPR => Some(MethodCallExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ast::ArgListOwner<'a> for MethodCallExpr<'a> {} -impl<'a> MethodCallExpr<'a> {pub fn expr(self) -> Option> { - super::child_opt(self) - } -} - -// Module -#[derive(Debug, Clone, Copy)] -pub struct Module<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for Module<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - MODULE => Some(Module { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ast::NameOwner<'a> for Module<'a> {} -impl<'a> ast::AttrsOwner<'a> for Module<'a> {} -impl<'a> Module<'a> {pub fn item_list(self) -> Option> { - super::child_opt(self) - } -} - -// ModuleItem -#[derive(Debug, Clone, Copy)] -pub enum ModuleItem<'a> { - StructDef(StructDef<'a>), - EnumDef(EnumDef<'a>), - FnDef(FnDef<'a>), - TraitDef(TraitDef<'a>), - TypeDef(TypeDef<'a>), - ImplItem(ImplItem<'a>), - UseItem(UseItem<'a>), - ExternCrateItem(ExternCrateItem<'a>), - ConstDef(ConstDef<'a>), - StaticDef(StaticDef<'a>), - Module(Module<'a>), -} - -impl<'a> AstNode<'a> for ModuleItem<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - STRUCT_DEF => Some(ModuleItem::StructDef(StructDef { syntax })), - ENUM_DEF => Some(ModuleItem::EnumDef(EnumDef { syntax })), - FN_DEF => Some(ModuleItem::FnDef(FnDef { syntax })), - TRAIT_DEF => Some(ModuleItem::TraitDef(TraitDef { syntax })), - TYPE_DEF => Some(ModuleItem::TypeDef(TypeDef { syntax })), - IMPL_ITEM => Some(ModuleItem::ImplItem(ImplItem { syntax })), - USE_ITEM => Some(ModuleItem::UseItem(UseItem { syntax })), - EXTERN_CRATE_ITEM => Some(ModuleItem::ExternCrateItem(ExternCrateItem { syntax })), - CONST_DEF => Some(ModuleItem::ConstDef(ConstDef { syntax })), - STATIC_DEF => Some(ModuleItem::StaticDef(StaticDef { syntax })), - MODULE => Some(ModuleItem::Module(Module { syntax })), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { - match self { - ModuleItem::StructDef(inner) => inner.syntax(), - ModuleItem::EnumDef(inner) => inner.syntax(), - ModuleItem::FnDef(inner) => inner.syntax(), - ModuleItem::TraitDef(inner) => inner.syntax(), - ModuleItem::TypeDef(inner) => inner.syntax(), - ModuleItem::ImplItem(inner) => inner.syntax(), - ModuleItem::UseItem(inner) => inner.syntax(), - ModuleItem::ExternCrateItem(inner) => inner.syntax(), - ModuleItem::ConstDef(inner) => inner.syntax(), - ModuleItem::StaticDef(inner) => inner.syntax(), - ModuleItem::Module(inner) => inner.syntax(), - } - } -} - -impl<'a> ModuleItem<'a> {} - -// Name -#[derive(Debug, Clone, Copy)] -pub struct Name<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for Name<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - NAME => Some(Name { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> Name<'a> {} - -// NameRef -#[derive(Debug, Clone, Copy)] -pub struct NameRef<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for NameRef<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - NAME_REF => Some(NameRef { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> NameRef<'a> {} - -// NamedField -#[derive(Debug, Clone, Copy)] -pub struct NamedField<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for NamedField<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - NAMED_FIELD => Some(NamedField { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> NamedField<'a> {} - -// NamedFieldDef -#[derive(Debug, Clone, Copy)] -pub struct NamedFieldDef<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for NamedFieldDef<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - NAMED_FIELD_DEF => Some(NamedFieldDef { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ast::NameOwner<'a> for NamedFieldDef<'a> {} -impl<'a> ast::AttrsOwner<'a> for NamedFieldDef<'a> {} -impl<'a> NamedFieldDef<'a> {} - -// NamedFieldList -#[derive(Debug, Clone, Copy)] -pub struct NamedFieldList<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for NamedFieldList<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - NAMED_FIELD_LIST => Some(NamedFieldList { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> NamedFieldList<'a> {} - -// NeverType -#[derive(Debug, Clone, Copy)] -pub struct NeverType<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for NeverType<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - NEVER_TYPE => Some(NeverType { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> NeverType<'a> {} - -// NominalDef -#[derive(Debug, Clone, Copy)] -pub enum NominalDef<'a> { - StructDef(StructDef<'a>), - EnumDef(EnumDef<'a>), -} - -impl<'a> AstNode<'a> for NominalDef<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - STRUCT_DEF => Some(NominalDef::StructDef(StructDef { syntax })), - ENUM_DEF => Some(NominalDef::EnumDef(EnumDef { syntax })), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { - match self { - NominalDef::StructDef(inner) => inner.syntax(), - NominalDef::EnumDef(inner) => inner.syntax(), - } - } -} - -impl<'a> ast::NameOwner<'a> for NominalDef<'a> {} -impl<'a> ast::TypeParamsOwner<'a> for NominalDef<'a> {} -impl<'a> ast::AttrsOwner<'a> for NominalDef<'a> {} -impl<'a> NominalDef<'a> {} - -// Param -#[derive(Debug, Clone, Copy)] -pub struct Param<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for Param<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - PARAM => Some(Param { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> Param<'a> {pub fn pat(self) -> Option> { - super::child_opt(self) - } -} - -// ParamList -#[derive(Debug, Clone, Copy)] -pub struct ParamList<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for ParamList<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - PARAM_LIST => Some(ParamList { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ParamList<'a> { - pub fn params(self) -> impl Iterator> + 'a { - super::children(self) - } -pub fn self_param(self) -> Option> { - super::child_opt(self) - } -} - -// ParenExpr -#[derive(Debug, Clone, Copy)] -pub struct ParenExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for ParenExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - PAREN_EXPR => Some(ParenExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ParenExpr<'a> {} - -// ParenType -#[derive(Debug, Clone, Copy)] -pub struct ParenType<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for ParenType<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - PAREN_TYPE => Some(ParenType { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ParenType<'a> {} - -// Pat -#[derive(Debug, Clone, Copy)] -pub enum Pat<'a> { - RefPat(RefPat<'a>), - BindPat(BindPat<'a>), - PlaceholderPat(PlaceholderPat<'a>), - PathPat(PathPat<'a>), - StructPat(StructPat<'a>), - FieldPatList(FieldPatList<'a>), - TupleStructPat(TupleStructPat<'a>), - TuplePat(TuplePat<'a>), - SlicePat(SlicePat<'a>), - RangePat(RangePat<'a>), -} - -impl<'a> AstNode<'a> for Pat<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - REF_PAT => Some(Pat::RefPat(RefPat { syntax })), - BIND_PAT => Some(Pat::BindPat(BindPat { syntax })), - PLACEHOLDER_PAT => Some(Pat::PlaceholderPat(PlaceholderPat { syntax })), - PATH_PAT => Some(Pat::PathPat(PathPat { syntax })), - STRUCT_PAT => Some(Pat::StructPat(StructPat { syntax })), - FIELD_PAT_LIST => Some(Pat::FieldPatList(FieldPatList { syntax })), - TUPLE_STRUCT_PAT => Some(Pat::TupleStructPat(TupleStructPat { syntax })), - TUPLE_PAT => Some(Pat::TuplePat(TuplePat { syntax })), - SLICE_PAT => Some(Pat::SlicePat(SlicePat { syntax })), - RANGE_PAT => Some(Pat::RangePat(RangePat { syntax })), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { - match self { - Pat::RefPat(inner) => inner.syntax(), - Pat::BindPat(inner) => inner.syntax(), - Pat::PlaceholderPat(inner) => inner.syntax(), - Pat::PathPat(inner) => inner.syntax(), - Pat::StructPat(inner) => inner.syntax(), - Pat::FieldPatList(inner) => inner.syntax(), - Pat::TupleStructPat(inner) => inner.syntax(), - Pat::TuplePat(inner) => inner.syntax(), - Pat::SlicePat(inner) => inner.syntax(), - Pat::RangePat(inner) => inner.syntax(), - } - } -} - -impl<'a> Pat<'a> {} - -// Path -#[derive(Debug, Clone, Copy)] -pub struct Path<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for Path<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - PATH => Some(Path { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> Path<'a> {pub fn segment(self) -> Option> { - super::child_opt(self) - } -} - -// PathExpr -#[derive(Debug, Clone, Copy)] -pub struct PathExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for PathExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - PATH_EXPR => Some(PathExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> PathExpr<'a> {} - -// PathPat -#[derive(Debug, Clone, Copy)] -pub struct PathPat<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for PathPat<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - PATH_PAT => Some(PathPat { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> PathPat<'a> {} - -// PathSegment -#[derive(Debug, Clone, Copy)] -pub struct PathSegment<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for PathSegment<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - PATH_SEGMENT => Some(PathSegment { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> PathSegment<'a> {pub fn name_ref(self) -> Option> { - super::child_opt(self) - } -} - -// PathType -#[derive(Debug, Clone, Copy)] -pub struct PathType<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for PathType<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - PATH_TYPE => Some(PathType { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> PathType<'a> {} - -// PlaceholderPat -#[derive(Debug, Clone, Copy)] -pub struct PlaceholderPat<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for PlaceholderPat<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - PLACEHOLDER_PAT => Some(PlaceholderPat { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> PlaceholderPat<'a> {} - -// PlaceholderType -#[derive(Debug, Clone, Copy)] -pub struct PlaceholderType<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for PlaceholderType<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - PLACEHOLDER_TYPE => Some(PlaceholderType { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> PlaceholderType<'a> {} - -// PointerType -#[derive(Debug, Clone, Copy)] -pub struct PointerType<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for PointerType<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - POINTER_TYPE => Some(PointerType { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> PointerType<'a> {} - -// PrefixExpr -#[derive(Debug, Clone, Copy)] -pub struct PrefixExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for PrefixExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - PREFIX_EXPR => Some(PrefixExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> PrefixExpr<'a> {} - -// RangeExpr -#[derive(Debug, Clone, Copy)] -pub struct RangeExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for RangeExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - RANGE_EXPR => Some(RangeExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> RangeExpr<'a> {} - -// RangePat -#[derive(Debug, Clone, Copy)] -pub struct RangePat<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for RangePat<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - RANGE_PAT => Some(RangePat { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> RangePat<'a> {} - -// RefExpr -#[derive(Debug, Clone, Copy)] -pub struct RefExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for RefExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - REF_EXPR => Some(RefExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> RefExpr<'a> {} - -// RefPat -#[derive(Debug, Clone, Copy)] -pub struct RefPat<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for RefPat<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - REF_PAT => Some(RefPat { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> RefPat<'a> {} - -// ReferenceType -#[derive(Debug, Clone, Copy)] -pub struct ReferenceType<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for ReferenceType<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - REFERENCE_TYPE => Some(ReferenceType { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ReferenceType<'a> {} - -// RetType -#[derive(Debug, Clone, Copy)] -pub struct RetType<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for RetType<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - RET_TYPE => Some(RetType { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> RetType<'a> {} - -// ReturnExpr -#[derive(Debug, Clone, Copy)] -pub struct ReturnExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for ReturnExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - RETURN_EXPR => Some(ReturnExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ReturnExpr<'a> {} - -// Root -#[derive(Debug, Clone, Copy)] -pub struct Root<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for Root<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - ROOT => Some(Root { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ast::ModuleItemOwner<'a> for Root<'a> {} -impl<'a> ast::FnDefOwner<'a> for Root<'a> {} -impl<'a> Root<'a> { - pub fn modules(self) -> impl Iterator> + 'a { - super::children(self) - } -} - -// SelfParam -#[derive(Debug, Clone, Copy)] -pub struct SelfParam<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for SelfParam<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - SELF_PARAM => Some(SelfParam { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> SelfParam<'a> {} - -// SlicePat -#[derive(Debug, Clone, Copy)] -pub struct SlicePat<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for SlicePat<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - SLICE_PAT => Some(SlicePat { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> SlicePat<'a> {} - -// SliceType -#[derive(Debug, Clone, Copy)] -pub struct SliceType<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for SliceType<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - SLICE_TYPE => Some(SliceType { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> SliceType<'a> {} - -// StaticDef -#[derive(Debug, Clone, Copy)] -pub struct StaticDef<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for StaticDef<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - STATIC_DEF => Some(StaticDef { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ast::NameOwner<'a> for StaticDef<'a> {} -impl<'a> ast::TypeParamsOwner<'a> for StaticDef<'a> {} -impl<'a> ast::AttrsOwner<'a> for StaticDef<'a> {} -impl<'a> StaticDef<'a> {} - -// Stmt -#[derive(Debug, Clone, Copy)] -pub enum Stmt<'a> { - ExprStmt(ExprStmt<'a>), - LetStmt(LetStmt<'a>), -} - -impl<'a> AstNode<'a> for Stmt<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - EXPR_STMT => Some(Stmt::ExprStmt(ExprStmt { syntax })), - LET_STMT => Some(Stmt::LetStmt(LetStmt { syntax })), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { - match self { - Stmt::ExprStmt(inner) => inner.syntax(), - Stmt::LetStmt(inner) => inner.syntax(), - } - } -} - -impl<'a> Stmt<'a> {} - -// StructDef -#[derive(Debug, Clone, Copy)] -pub struct StructDef<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for StructDef<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - STRUCT_DEF => Some(StructDef { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ast::NameOwner<'a> for StructDef<'a> {} -impl<'a> ast::TypeParamsOwner<'a> for StructDef<'a> {} -impl<'a> ast::AttrsOwner<'a> for StructDef<'a> {} -impl<'a> StructDef<'a> { - pub fn fields(self) -> impl Iterator> + 'a { - super::children(self) - } -} - -// StructLit -#[derive(Debug, Clone, Copy)] -pub struct StructLit<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for StructLit<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - STRUCT_LIT => Some(StructLit { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> StructLit<'a> {} - -// StructPat -#[derive(Debug, Clone, Copy)] -pub struct StructPat<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for StructPat<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - STRUCT_PAT => Some(StructPat { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> StructPat<'a> {} - -// TokenTree -#[derive(Debug, Clone, Copy)] -pub struct TokenTree<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for TokenTree<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - TOKEN_TREE => Some(TokenTree { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> TokenTree<'a> {} - -// TraitDef -#[derive(Debug, Clone, Copy)] -pub struct TraitDef<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for TraitDef<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - TRAIT_DEF => Some(TraitDef { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ast::NameOwner<'a> for TraitDef<'a> {} -impl<'a> ast::AttrsOwner<'a> for TraitDef<'a> {} -impl<'a> TraitDef<'a> {} - -// TryExpr -#[derive(Debug, Clone, Copy)] -pub struct TryExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for TryExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - TRY_EXPR => Some(TryExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> TryExpr<'a> {} - -// TupleExpr -#[derive(Debug, Clone, Copy)] -pub struct TupleExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for TupleExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - TUPLE_EXPR => Some(TupleExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> TupleExpr<'a> {} - -// TuplePat -#[derive(Debug, Clone, Copy)] -pub struct TuplePat<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for TuplePat<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - TUPLE_PAT => Some(TuplePat { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> TuplePat<'a> {} - -// TupleStructPat -#[derive(Debug, Clone, Copy)] -pub struct TupleStructPat<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for TupleStructPat<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - TUPLE_STRUCT_PAT => Some(TupleStructPat { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> TupleStructPat<'a> {} - -// TupleType -#[derive(Debug, Clone, Copy)] -pub struct TupleType<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for TupleType<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - TUPLE_TYPE => Some(TupleType { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> TupleType<'a> {} - -// TypeDef -#[derive(Debug, Clone, Copy)] -pub struct TypeDef<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for TypeDef<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - TYPE_DEF => Some(TypeDef { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ast::NameOwner<'a> for TypeDef<'a> {} -impl<'a> ast::TypeParamsOwner<'a> for TypeDef<'a> {} -impl<'a> ast::AttrsOwner<'a> for TypeDef<'a> {} -impl<'a> TypeDef<'a> {} - -// TypeParam -#[derive(Debug, Clone, Copy)] -pub struct TypeParam<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for TypeParam<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - TYPE_PARAM => Some(TypeParam { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ast::NameOwner<'a> for TypeParam<'a> {} -impl<'a> TypeParam<'a> {} - -// TypeParamList -#[derive(Debug, Clone, Copy)] -pub struct TypeParamList<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for TypeParamList<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - TYPE_PARAM_LIST => Some(TypeParamList { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> TypeParamList<'a> { - pub fn type_params(self) -> impl Iterator> + 'a { - super::children(self) - } - - pub fn lifetime_params(self) -> impl Iterator> + 'a { - super::children(self) - } -} - -// TypeRef -#[derive(Debug, Clone, Copy)] -pub enum TypeRef<'a> { - ParenType(ParenType<'a>), - TupleType(TupleType<'a>), - NeverType(NeverType<'a>), - PathType(PathType<'a>), - PointerType(PointerType<'a>), - ArrayType(ArrayType<'a>), - SliceType(SliceType<'a>), - ReferenceType(ReferenceType<'a>), - PlaceholderType(PlaceholderType<'a>), - FnPointerType(FnPointerType<'a>), - ForType(ForType<'a>), - ImplTraitType(ImplTraitType<'a>), - DynTraitType(DynTraitType<'a>), -} - -impl<'a> AstNode<'a> for TypeRef<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - PAREN_TYPE => Some(TypeRef::ParenType(ParenType { syntax })), - TUPLE_TYPE => Some(TypeRef::TupleType(TupleType { syntax })), - NEVER_TYPE => Some(TypeRef::NeverType(NeverType { syntax })), - PATH_TYPE => Some(TypeRef::PathType(PathType { syntax })), - POINTER_TYPE => Some(TypeRef::PointerType(PointerType { syntax })), - ARRAY_TYPE => Some(TypeRef::ArrayType(ArrayType { syntax })), - SLICE_TYPE => Some(TypeRef::SliceType(SliceType { syntax })), - REFERENCE_TYPE => Some(TypeRef::ReferenceType(ReferenceType { syntax })), - PLACEHOLDER_TYPE => Some(TypeRef::PlaceholderType(PlaceholderType { syntax })), - FN_POINTER_TYPE => Some(TypeRef::FnPointerType(FnPointerType { syntax })), - FOR_TYPE => Some(TypeRef::ForType(ForType { syntax })), - IMPL_TRAIT_TYPE => Some(TypeRef::ImplTraitType(ImplTraitType { syntax })), - DYN_TRAIT_TYPE => Some(TypeRef::DynTraitType(DynTraitType { syntax })), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { - match self { - TypeRef::ParenType(inner) => inner.syntax(), - TypeRef::TupleType(inner) => inner.syntax(), - TypeRef::NeverType(inner) => inner.syntax(), - TypeRef::PathType(inner) => inner.syntax(), - TypeRef::PointerType(inner) => inner.syntax(), - TypeRef::ArrayType(inner) => inner.syntax(), - TypeRef::SliceType(inner) => inner.syntax(), - TypeRef::ReferenceType(inner) => inner.syntax(), - TypeRef::PlaceholderType(inner) => inner.syntax(), - TypeRef::FnPointerType(inner) => inner.syntax(), - TypeRef::ForType(inner) => inner.syntax(), - TypeRef::ImplTraitType(inner) => inner.syntax(), - TypeRef::DynTraitType(inner) => inner.syntax(), - } - } -} - -impl<'a> TypeRef<'a> {} - -// UseItem -#[derive(Debug, Clone, Copy)] -pub struct UseItem<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for UseItem<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - USE_ITEM => Some(UseItem { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> UseItem<'a> {pub fn use_tree(self) -> Option> { - super::child_opt(self) - } -} - -// UseTree -#[derive(Debug, Clone, Copy)] -pub struct UseTree<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for UseTree<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - USE_TREE => Some(UseTree { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> UseTree<'a> {pub fn path(self) -> Option> { - super::child_opt(self) - } -pub fn use_tree_list(self) -> Option> { - super::child_opt(self) - } -} - -// UseTreeList -#[derive(Debug, Clone, Copy)] -pub struct UseTreeList<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for UseTreeList<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - USE_TREE_LIST => Some(UseTreeList { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> UseTreeList<'a> { - pub fn use_trees(self) -> impl Iterator> + 'a { - super::children(self) - } -} - -// WhereClause -#[derive(Debug, Clone, Copy)] -pub struct WhereClause<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for WhereClause<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - WHERE_CLAUSE => Some(WhereClause { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> WhereClause<'a> {} - -// WhileExpr -#[derive(Debug, Clone, Copy)] -pub struct WhileExpr<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for WhileExpr<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - WHILE_EXPR => Some(WhileExpr { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} - -impl<'a> ast::LoopBodyOwner<'a> for WhileExpr<'a> {} -impl<'a> WhileExpr<'a> {pub fn condition(self) -> Option> { - super::child_opt(self) - } -} - diff --git a/crates/libsyntax2/src/ast/generated.rs.tera b/crates/libsyntax2/src/ast/generated.rs.tera deleted file mode 100644 index a72e9b732..000000000 --- a/crates/libsyntax2/src/ast/generated.rs.tera +++ /dev/null @@ -1,83 +0,0 @@ -use { - ast, - SyntaxNodeRef, AstNode, - SyntaxKind::*, -}; -{% for node, methods in ast %} -// {{ node }} -{%- if methods.enum %} -#[derive(Debug, Clone, Copy)] -pub enum {{ node }}<'a> { -{%- for kind in methods.enum %} - {{ kind }}({{ kind }}<'a>), -{%- endfor %} -} - -impl<'a> AstNode<'a> for {{ node }}<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { -{%- for kind in methods.enum %} - {{ kind | SCREAM }} => Some({{ node }}::{{ kind }}({{ kind }} { syntax })), -{%- endfor %} - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { - match self { -{%- for kind in methods.enum %} - {{ node }}::{{ kind }}(inner) => inner.syntax(), -{%- endfor %} - } - } -} -{% else %} -#[derive(Debug, Clone, Copy)] -pub struct {{ node }}<'a> { - syntax: SyntaxNodeRef<'a>, -} - -impl<'a> AstNode<'a> for {{ node }}<'a> { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option { - match syntax.kind() { - {{ node | SCREAM }} => Some({{ node }} { syntax }), - _ => None, - } - } - fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } -} -{% endif %} -{% if methods.traits -%} -{%- for t in methods.traits -%} -impl<'a> ast::{{ t }}<'a> for {{ node }}<'a> {} -{% endfor -%} -{%- endif -%} - -impl<'a> {{ node }}<'a> { -{%- if methods.collections -%} -{%- for m in methods.collections -%} -{%- set method_name = m.0 -%} -{%- set ChildName = m.1 %} - pub fn {{ method_name }}(self) -> impl Iterator> + 'a { - super::children(self) - } -{% endfor -%} -{%- endif -%} - -{%- if methods.options -%} -{%- for m in methods.options -%} - -{%- if m is string -%} -{%- set method_name = m | snake -%} -{%- set ChildName = m %} -{%- else -%} -{%- set method_name = m.0 -%} -{%- set ChildName = m.1 %} -{%- endif -%} - - pub fn {{ method_name }}(self) -> Option<{{ ChildName }}<'a>> { - super::child_opt(self) - } -{% endfor -%} -{%- endif -%} -} -{% endfor %} diff --git a/crates/libsyntax2/src/ast/mod.rs b/crates/libsyntax2/src/ast/mod.rs deleted file mode 100644 index a6da82957..000000000 --- a/crates/libsyntax2/src/ast/mod.rs +++ /dev/null @@ -1,206 +0,0 @@ -mod generated; - -use std::marker::PhantomData; - -use itertools::Itertools; -use smol_str::SmolStr; - -use { - SyntaxNodeRef, SyntaxKind::*, - yellow::{RefRoot, SyntaxNodeChildren}, -}; -pub use self::generated::*; - -pub trait AstNode<'a>: Clone + Copy + 'a { - fn cast(syntax: SyntaxNodeRef<'a>) -> Option - where Self: Sized; - fn syntax(self) -> SyntaxNodeRef<'a>; -} - -pub trait NameOwner<'a>: AstNode<'a> { - fn name(self) -> Option> { - child_opt(self) - } -} - -pub trait LoopBodyOwner<'a>: AstNode<'a> { - fn loop_body(self) -> Option> { - child_opt(self) - } -} - -pub trait ArgListOwner<'a>: AstNode<'a> { - fn arg_list(self) -> Option> { - child_opt(self) - } -} - -pub trait FnDefOwner<'a>: AstNode<'a> { - fn functions(self) -> AstChildren<'a, FnDef<'a>> { - children(self) - } -} - -pub trait ModuleItemOwner<'a>: AstNode<'a> { - fn items(self) -> AstChildren<'a, ModuleItem<'a>> { - children(self) - } -} - -pub trait TypeParamsOwner<'a>: AstNode<'a> { - fn type_param_list(self) -> Option> { - child_opt(self) - } - - fn where_clause(self) -> Option> { - child_opt(self) - } -} - -pub trait AttrsOwner<'a>: AstNode<'a> { - fn attrs(self) -> AstChildren<'a, Attr<'a>> { - children(self) - } -} - -impl<'a> FnDef<'a> { - pub fn has_atom_attr(&self, atom: &str) -> bool { - self.attrs() - .filter_map(|x| x.as_atom()) - .any(|x| x == atom) - } -} - -impl<'a> Attr<'a> { - pub fn as_atom(&self) -> Option { - let tt = self.value()?; - let (_bra, attr, _ket) = tt.syntax().children().collect_tuple()?; - if attr.kind() == IDENT { - Some(attr.leaf_text().unwrap()) - } else { - None - } - } - - pub fn as_call(&self) -> Option<(SmolStr, TokenTree<'a>)> { - let tt = self.value()?; - let (_bra, attr, args, _ket) = tt.syntax().children().collect_tuple()?; - let args = TokenTree::cast(args)?; - if attr.kind() == IDENT { - Some((attr.leaf_text().unwrap(), args)) - } else { - None - } - } -} - -impl<'a> Lifetime<'a> { - pub fn text(&self) -> SmolStr { - self.syntax().leaf_text().unwrap() - } -} - -impl<'a> Name<'a> { - pub fn text(&self) -> SmolStr { - let ident = self.syntax().first_child() - .unwrap(); - ident.leaf_text().unwrap() - } -} - -impl<'a> NameRef<'a> { - pub fn text(&self) -> SmolStr { - let ident = self.syntax().first_child() - .unwrap(); - ident.leaf_text().unwrap() - } -} - -impl<'a> ImplItem<'a> { - pub fn target_type(self) -> Option> { - match self.target() { - (Some(t), None) | (_, Some(t)) => Some(t), - _ => None, - } - } - - pub fn target_trait(self) -> Option> { - match self.target() { - (Some(t), Some(_)) => Some(t), - _ => None, - } - } - - fn target(self) -> (Option>, Option>) { - let mut types = children(self); - let first = types.next(); - let second = types.next(); - (first, second) - } -} - -impl<'a> Module<'a> { - pub fn has_semi(self) -> bool { - match self.syntax().last_child() { - None => false, - Some(node) => node.kind() == SEMI, - } - } -} - -impl<'a> LetStmt<'a> { - pub fn has_semi(self) -> bool { - match self.syntax().last_child() { - None => false, - Some(node) => node.kind() == SEMI, - } - } -} - -impl<'a> IfExpr<'a> { - pub fn then_branch(self) -> Option> { - self.blocks().nth(0) - } - pub fn else_branch(self) -> Option> { - self.blocks().nth(1) - } - fn blocks(self) -> AstChildren<'a, Block<'a>> { - children(self) - } -} - -fn child_opt<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> Option { - children(parent).next() -} - -fn children<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> AstChildren<'a, C> { - AstChildren::new(parent.syntax()) -} - - -#[derive(Debug)] -pub struct AstChildren<'a, N> { - inner: SyntaxNodeChildren>, - ph: PhantomData, -} - -impl<'a, N> AstChildren<'a, N> { - fn new(parent: SyntaxNodeRef<'a>) -> Self { - AstChildren { - inner: parent.children(), - ph: PhantomData, - } - } -} - -impl<'a, N: AstNode<'a>> Iterator for AstChildren<'a, N> { - type Item = N; - fn next(&mut self) -> Option { - loop { - match N::cast(self.inner.next()?) { - Some(n) => return Some(n), - None => (), - } - } - } -} diff --git a/crates/libsyntax2/src/grammar.ron b/crates/libsyntax2/src/grammar.ron deleted file mode 100644 index 77ae4c7db..000000000 --- a/crates/libsyntax2/src/grammar.ron +++ /dev/null @@ -1,538 +0,0 @@ -Grammar( - single_byte_tokens: [ - [";", "SEMI"], - [",", "COMMA"], - ["(", "L_PAREN"], - [")", "R_PAREN"], - ["{", "L_CURLY"], - ["}", "R_CURLY"], - ["[", "L_BRACK"], - ["]", "R_BRACK"], - ["<", "L_ANGLE"], - [">", "R_ANGLE"], - ["@", "AT"], - ["#", "POUND"], - ["~", "TILDE"], - ["?", "QUESTION"], - ["$", "DOLLAR"], - ["&", "AMP"], - ["|", "PIPE"], - ["+", "PLUS"], - ["*", "STAR"], - ["/", "SLASH"], - ["^", "CARET"], - ["%", "PERCENT"], - ], - multi_byte_tokens: [ - [".", "DOT"], - ["..", "DOTDOT"], - ["...", "DOTDOTDOT"], - ["..=", "DOTDOTEQ"], - [":", "COLON"], - ["::", "COLONCOLON"], - ["=", "EQ"], - ["==", "EQEQ"], - ["=>", "FAT_ARROW"], - ["!", "EXCL"], - ["!=", "NEQ"], - ["-", "MINUS"], - ["->", "THIN_ARROW"], - ["<=", "LTEQ"], - [">=", "GTEQ"], - ["+=", "PLUSEQ"], - ["-=", "MINUSEQ"], - ["|=", "PIPEEQ"], - ["&=", "AMPEQ"], - ["^=", "CARETEQ"], - ["/=", "SLASHEQ"], - ["*=", "STAREQ"], - ["&&", "AMPAMP"], - ["||", "PIPEPIPE"], - ["<<", "SHL"], - [">>", "SHR"], - ["<<=", "SHLEQ"], - [">>=", "SHREQ"], - ], - keywords: [ - "use", - "fn", - "struct", - "enum", - "trait", - "impl", - "dyn", - "true", - "false", - "as", - "extern", - "crate", - "mod", - "pub", - "self", - "super", - "in", - "where", - "for", - "loop", - "while", - "continue", - "break", - "if", - "else", - "match", - "const", - "static", - "mut", - "unsafe", - "type", - "ref", - "let", - "move", - "return", - ], - contextual_keywords: [ - "auto", - "default", - "union", - ], - tokens: [ - "ERROR", - "IDENT", - "UNDERSCORE", - "WHITESPACE", - "INT_NUMBER", - "FLOAT_NUMBER", - "LIFETIME", - "CHAR", - "BYTE", - "STRING", - "RAW_STRING", - "BYTE_STRING", - "RAW_BYTE_STRING", - "COMMENT", - "DOC_COMMENT", - "SHEBANG", - ], - nodes: [ - "ROOT", - - "STRUCT_DEF", - "ENUM_DEF", - "FN_DEF", - "RET_TYPE", - "EXTERN_CRATE_ITEM", - "MODULE", - "USE_ITEM", - "STATIC_DEF", - "CONST_DEF", - "TRAIT_DEF", - "IMPL_ITEM", - "TYPE_DEF", - "MACRO_CALL", - "TOKEN_TREE", - - "PAREN_TYPE", - "TUPLE_TYPE", - "NEVER_TYPE", - "PATH_TYPE", - "POINTER_TYPE", - "ARRAY_TYPE", - "SLICE_TYPE", - "REFERENCE_TYPE", - "PLACEHOLDER_TYPE", - "FN_POINTER_TYPE", - "FOR_TYPE", - "IMPL_TRAIT_TYPE", - "DYN_TRAIT_TYPE", - - "REF_PAT", - "BIND_PAT", - "PLACEHOLDER_PAT", - "PATH_PAT", - "STRUCT_PAT", - "FIELD_PAT_LIST", - "TUPLE_STRUCT_PAT", - "TUPLE_PAT", - "SLICE_PAT", - "RANGE_PAT", - - // atoms - "TUPLE_EXPR", - "ARRAY_EXPR", - "PAREN_EXPR", - "PATH_EXPR", - "LAMBDA_EXPR", - "IF_EXPR", - "WHILE_EXPR", - "CONDITION", - "LOOP_EXPR", - "FOR_EXPR", - "CONTINUE_EXPR", - "BREAK_EXPR", - "LABEL", - "BLOCK_EXPR", - "RETURN_EXPR", - "MATCH_EXPR", - "MATCH_ARM_LIST", - "MATCH_ARM", - "MATCH_GUARD", - "STRUCT_LIT", - "NAMED_FIELD_LIST", - "NAMED_FIELD", - - // postfix - "CALL_EXPR", - "INDEX_EXPR", - "METHOD_CALL_EXPR", - "FIELD_EXPR", - "TRY_EXPR", - "CAST_EXPR", - - // unary - "REF_EXPR", - "PREFIX_EXPR", - - "RANGE_EXPR", // just weird - "BIN_EXPR", - - "BLOCK", - "EXTERN_BLOCK", - "EXTERN_ITEM_LIST", - "ENUM_VARIANT", - "NAMED_FIELD_DEF_LIST", - "NAMED_FIELD_DEF", - "POS_FIELD_LIST", - "POS_FIELD", - "ENUM_VARIANT_LIST", - "ITEM_LIST", - "ATTR", - "META_ITEM", // not an item actually - "USE_TREE", - "USE_TREE_LIST", - "PATH", - "PATH_SEGMENT", - "LITERAL", - "ALIAS", - "VISIBILITY", - "WHERE_CLAUSE", - "WHERE_PRED", - "ABI", - "NAME", - "NAME_REF", - - "LET_STMT", - "EXPR_STMT", - - "TYPE_PARAM_LIST", - "LIFETIME_PARAM", - "TYPE_PARAM", - "TYPE_ARG_LIST", - "LIFETIME_ARG", - "TYPE_ARG", - "ASSOC_TYPE_ARG", - - "PARAM_LIST", - "PARAM", - "SELF_PARAM", - "ARG_LIST", - ], - ast: { - "Root": ( - traits: [ "ModuleItemOwner", "FnDefOwner" ], - collections: [ - ["modules", "Module"], - ] - ), - "FnDef": ( - traits: [ - "NameOwner", - "TypeParamsOwner", - "AttrsOwner", - ], - options: [ "ParamList", ["body", "Block"], "RetType" ], - ), - "RetType": (), - "StructDef": ( - traits: [ - "NameOwner", - "TypeParamsOwner", - "AttrsOwner", - ], - collections: [ - ["fields", "NamedFieldDef"] - ] - ), - "NamedFieldDef": ( traits: ["NameOwner", "AttrsOwner"] ), - "EnumDef": ( traits: [ - "NameOwner", - "TypeParamsOwner", - "AttrsOwner", - ] ), - "TraitDef": ( traits: ["NameOwner", "AttrsOwner"] ), - "Module": ( - traits: ["NameOwner", "AttrsOwner" ], - options: [ "ItemList" ] - ), - "ItemList": ( - traits: [ "FnDefOwner", "ModuleItemOwner" ], - ), - "ConstDef": ( traits: [ - "NameOwner", - "TypeParamsOwner", - "AttrsOwner", - ] ), - "StaticDef": ( traits: [ - "NameOwner", - "TypeParamsOwner", - "AttrsOwner", - ] ), - "TypeDef": ( traits: [ - "NameOwner", - "TypeParamsOwner", - "AttrsOwner", - ] ), - "ImplItem": (), - - "ParenType": (), - "TupleType": (), - "NeverType": (), - "PathType": (), - "PointerType": (), - "ArrayType": (), - "SliceType": (), - "ReferenceType": (), - "PlaceholderType": (), - "FnPointerType": (), - "ForType": (), - "ImplTraitType": (), - "DynTraitType": (), - - "TypeRef": ( enum: [ - "ParenType", - "TupleType", - "NeverType", - "PathType", - "PointerType", - "ArrayType", - "SliceType", - "ReferenceType", - "PlaceholderType", - "FnPointerType", - "ForType", - "ImplTraitType", - "DynTraitType", - ]), - - "NominalDef": ( - enum: ["StructDef", "EnumDef"], - traits: [ - "NameOwner", - "TypeParamsOwner", - "AttrsOwner" - ], - ), - "ModuleItem": ( - enum: ["StructDef", "EnumDef", "FnDef", "TraitDef", "TypeDef", "ImplItem", - "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ] - ), - - "TupleExpr": (), - "ArrayExpr": (), - "ParenExpr": (), - "PathExpr": (), - "LambdaExpr": ( - options: [ - "ParamList", - ["body", "Expr"], - ] - ), - "IfExpr": ( - options: [ "Condition" ] - ), - "LoopExpr": ( - traits: ["LoopBodyOwner"], - ), - "ForExpr": ( - traits: ["LoopBodyOwner"], - options: [ - "Pat", - ["iterable", "Expr"], - ] - ), - "WhileExpr": ( - traits: ["LoopBodyOwner"], - options: [ "Condition" ] - ), - "ContinueExpr": (), - "BreakExpr": (), - "Label": (), - "BlockExpr": ( - options: [ "Block" ] - ), - "ReturnExpr": (), - "MatchExpr": ( - options: [ "Expr", "MatchArmList" ], - ), - "MatchArmList": ( - collections: [ ["arms", "MatchArm"] ], - ), - "MatchArm": ( - options: [ - [ "guard", "MatchGuard" ], - "Expr", - ], - collections: [ [ "pats", "Pat" ] ] - ), - "MatchGuard": (), - "StructLit": (), - "NamedFieldList": (), - "NamedField": (), - "CallExpr": ( - traits: ["ArgListOwner"], - options: [ "Expr" ], - ), - "MethodCallExpr": ( - traits: ["ArgListOwner"], - options: [ "Expr" ], - ), - "IndexExpr": (), - "FieldExpr": (), - "TryExpr": (), - "CastExpr": (), - "RefExpr": (), - "PrefixExpr": (), - "RangeExpr": (), - "BinExpr": (), - "Literal": (), - - "Expr": ( - enum: [ - "TupleExpr", - "ArrayExpr", - "ParenExpr", - "PathExpr", - "LambdaExpr", - "IfExpr", - "LoopExpr", - "ForExpr", - "WhileExpr", - "ContinueExpr", - "BreakExpr", - "Label", - "BlockExpr", - "ReturnExpr", - "MatchExpr", - "MatchArmList", - "MatchArm", - "MatchGuard", - "StructLit", - "NamedFieldList", - "NamedField", - "CallExpr", - "IndexExpr", - "MethodCallExpr", - "FieldExpr", - "TryExpr", - "CastExpr", - "RefExpr", - "PrefixExpr", - "RangeExpr", - "BinExpr", - "Literal", - ], - ), - - "RefPat": (), - "BindPat": ( traits: ["NameOwner"] ), - "PlaceholderPat": (), - "PathPat": (), - "StructPat": (), - "FieldPatList": (), - "TupleStructPat": (), - "TuplePat": (), - "SlicePat": (), - "RangePat": (), - - "Pat": ( - enum: [ - "RefPat", - "BindPat", - "PlaceholderPat", - "PathPat", - "StructPat", - "FieldPatList", - "TupleStructPat", - "TuplePat", - "SlicePat", - "RangePat", - ], - ), - - "Name": (), - "NameRef": (), - "Attr": ( options: [ ["value", "TokenTree"] ] ), - "TokenTree": (), - "TypeParamList": ( - collections: [ - ["type_params", "TypeParam" ], - ["lifetime_params", "LifetimeParam" ], - ] - ), - "TypeParam": ( traits: ["NameOwner"] ), - "LifetimeParam": ( options: [ "Lifetime" ] ), - "Lifetime": (), - "WhereClause": (), - "ExprStmt": ( - options: [ ["expr", "Expr"] ] - ), - "LetStmt": ( options: [ - ["pat", "Pat"], - ["initializer", "Expr"], - ]), - "Condition": ( - options: [ "Pat", "Expr" ] - ), - "Stmt": ( - enum: ["ExprStmt", "LetStmt"], - ), - "Block": ( - options: [ "Expr" ], - collections: [ - ["statements", "Stmt"], - ] - ), - "ParamList": ( - options: [ "SelfParam" ], - collections: [ - ["params", "Param"] - ] - ), - "SelfParam": (), - "Param": ( - options: [ "Pat" ], - ), - "UseItem": ( - options: [ "UseTree" ] - ), - "UseTree": ( - options: [ "Path", "UseTreeList" ] - ), - "UseTreeList": ( - collections: [["use_trees", "UseTree"]] - ), - "ExternCrateItem": (), - "ArgList": ( - collections: [ - ["args", "Expr"] - ] - ), - "Path": ( - options: [ - ["segment", "PathSegment"] - ] - ), - "PathSegment": ( - options: [ "NameRef" ] - ), - }, -) diff --git a/crates/libsyntax2/src/grammar/attributes.rs b/crates/libsyntax2/src/grammar/attributes.rs deleted file mode 100644 index cd30e8a45..000000000 --- a/crates/libsyntax2/src/grammar/attributes.rs +++ /dev/null @@ -1,31 +0,0 @@ -use super::*; - -pub(super) fn inner_attributes(p: &mut Parser) { - while p.current() == POUND && p.nth(1) == EXCL { - attribute(p, true) - } -} - -pub(super) fn outer_attributes(p: &mut Parser) { - while p.at(POUND) { - attribute(p, false) - } -} - -fn attribute(p: &mut Parser, inner: bool) { - let attr = p.start(); - assert!(p.at(POUND)); - p.bump(); - - if inner { - assert!(p.at(EXCL)); - p.bump(); - } - - if p.at(L_BRACK) { - items::token_tree(p); - } else { - p.error("expected `[`"); - } - attr.complete(p, ATTR); -} diff --git a/crates/libsyntax2/src/grammar/expressions/atom.rs b/crates/libsyntax2/src/grammar/expressions/atom.rs deleted file mode 100644 index f01df56bc..000000000 --- a/crates/libsyntax2/src/grammar/expressions/atom.rs +++ /dev/null @@ -1,400 +0,0 @@ -use super::*; - -// test expr_literals -// fn foo() { -// let _ = true; -// let _ = false; -// let _ = 1; -// let _ = 2.0; -// let _ = b'a'; -// let _ = 'b'; -// let _ = "c"; -// let _ = r"d"; -// let _ = b"e"; -// let _ = br"f"; -// } -pub(crate) const LITERAL_FIRST: TokenSet = - token_set![TRUE_KW, FALSE_KW, INT_NUMBER, FLOAT_NUMBER, BYTE, CHAR, - STRING, RAW_STRING, BYTE_STRING, RAW_BYTE_STRING]; - -pub(crate) fn literal(p: &mut Parser) -> Option { - if !p.at_ts(LITERAL_FIRST) { - return None; - } - let m = p.start(); - p.bump(); - Some(m.complete(p, LITERAL)) -} - -pub(super) const ATOM_EXPR_FIRST: TokenSet = - token_set_union![ - LITERAL_FIRST, - token_set![L_CURLY, L_PAREN, L_BRACK, PIPE, MOVE_KW, IF_KW, WHILE_KW, MATCH_KW, UNSAFE_KW, - RETURN_KW, IDENT, SELF_KW, SUPER_KW, COLONCOLON, BREAK_KW, CONTINUE_KW, LIFETIME ], - ]; - -const EXPR_RECOVERY_SET: TokenSet = - token_set![LET_KW]; - -pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option { - match literal(p) { - Some(m) => return Some(m), - None => (), - } - if paths::is_path_start(p) || p.at(L_ANGLE) { - return Some(path_expr(p, r)); - } - let la = p.nth(1); - let done = match p.current() { - L_PAREN => tuple_expr(p), - L_BRACK => array_expr(p), - PIPE => lambda_expr(p), - MOVE_KW if la == PIPE => lambda_expr(p), - IF_KW => if_expr(p), - - LOOP_KW => loop_expr(p, None), - FOR_KW => for_expr(p, None), - WHILE_KW => while_expr(p, None), - LIFETIME if la == COLON => { - let m = p.start(); - label(p); - match p.current() { - LOOP_KW => loop_expr(p, Some(m)), - FOR_KW => for_expr(p, Some(m)), - WHILE_KW => while_expr(p, Some(m)), - L_CURLY => block_expr(p, Some(m)), - _ => { - // test misplaced_label_err - // fn main() { - // 'loop: impl - // } - p.error("expected a loop"); - m.complete(p, ERROR); - return None; - } - } - } - - MATCH_KW => match_expr(p), - UNSAFE_KW if la == L_CURLY => { - let m = p.start(); - p.bump(); - block_expr(p, Some(m)) - }, - L_CURLY => block_expr(p, None), - RETURN_KW => return_expr(p), - CONTINUE_KW => continue_expr(p), - BREAK_KW => break_expr(p), - _ => { - p.err_recover("expected expression", EXPR_RECOVERY_SET); - return None; - } - }; - Some(done) -} - -// test tuple_expr -// fn foo() { -// (); -// (1); -// (1,); -// } -fn tuple_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(L_PAREN)); - let m = p.start(); - p.expect(L_PAREN); - - let mut saw_comma = false; - let mut saw_expr = false; - while !p.at(EOF) && !p.at(R_PAREN) { - saw_expr = true; - if !p.at_ts(EXPR_FIRST) { - p.error("expected expression"); - break; - } - expr(p); - if !p.at(R_PAREN) { - saw_comma = true; - p.expect(COMMA); - } - } - p.expect(R_PAREN); - m.complete(p, if saw_expr && !saw_comma { PAREN_EXPR } else { TUPLE_EXPR }) -} - -// test array_expr -// fn foo() { -// []; -// [1]; -// [1, 2,]; -// [1; 2]; -// } -fn array_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(L_BRACK)); - let m = p.start(); - p.bump(); - if p.eat(R_BRACK) { - return m.complete(p, ARRAY_EXPR); - } - expr(p); - if p.eat(SEMI) { - expr(p); - p.expect(R_BRACK); - return m.complete(p, ARRAY_EXPR); - } - while !p.at(EOF) && !p.at(R_BRACK) { - p.expect(COMMA); - if p.at(R_BRACK) { - break; - } - if !p.at_ts(EXPR_FIRST) { - p.error("expected expression"); - break; - } - expr(p); - } - p.expect(R_BRACK); - m.complete(p, ARRAY_EXPR) -} - -// test lambda_expr -// fn foo() { -// || (); -// || -> i32 { 92 }; -// |x| x; -// move |x: i32,| x; -// } -fn lambda_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(PIPE) || (p.at(MOVE_KW) && p.nth(1) == PIPE)); - let m = p.start(); - p.eat(MOVE_KW); - params::param_list_opt_types(p); - if opt_fn_ret_type(p) { - if !p.at(L_CURLY) { - p.error("expected `{`"); - } - } - expr(p); - m.complete(p, LAMBDA_EXPR) -} - -// test if_expr -// fn foo() { -// if true {}; -// if true {} else {}; -// if true {} else if false {} else {}; -// if S {}; -// } -fn if_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(IF_KW)); - let m = p.start(); - p.bump(); - cond(p); - block(p); - if p.at(ELSE_KW) { - p.bump(); - if p.at(IF_KW) { - if_expr(p); - } else { - block(p); - } - } - m.complete(p, IF_EXPR) -} - -// test label -// fn foo() { -// 'a: loop {} -// 'b: while true {} -// 'c: for x in () {} -// } -fn label(p: &mut Parser) { - assert!(p.at(LIFETIME) && p.nth(1) == COLON); - let m = p.start(); - p.bump(); - p.bump(); - m.complete(p, LABEL); -} - -// test loop_expr -// fn foo() { -// loop {}; -// } -fn loop_expr(p: &mut Parser, m: Option) -> CompletedMarker { - assert!(p.at(LOOP_KW)); - let m = m.unwrap_or_else(|| p.start()); - p.bump(); - block(p); - m.complete(p, LOOP_EXPR) -} - -// test while_expr -// fn foo() { -// while true {}; -// while let Some(x) = it.next() {}; -// } -fn while_expr(p: &mut Parser, m: Option) -> CompletedMarker { - assert!(p.at(WHILE_KW)); - let m = m.unwrap_or_else(|| p.start()); - p.bump(); - cond(p); - block(p); - m.complete(p, WHILE_EXPR) -} - -// test for_expr -// fn foo() { -// for x in [] {}; -// } -fn for_expr(p: &mut Parser, m: Option) -> CompletedMarker { - assert!(p.at(FOR_KW)); - let m = m.unwrap_or_else(|| p.start()); - p.bump(); - patterns::pattern(p); - p.expect(IN_KW); - expr_no_struct(p); - block(p); - m.complete(p, FOR_EXPR) -} - -// test cond -// fn foo() { if let Some(_) = None {} } -fn cond(p: &mut Parser) { - let m = p.start(); - if p.eat(LET_KW) { - patterns::pattern(p); - p.expect(EQ); - } - expr_no_struct(p); - m.complete(p, CONDITION); -} - -// test match_expr -// fn foo() { -// match () { }; -// match S {}; -// } -fn match_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(MATCH_KW)); - let m = p.start(); - p.bump(); - expr_no_struct(p); - if p.at(L_CURLY) { - match_arm_list(p); - } else { - p.error("expected `{`") - } - m.complete(p, MATCH_EXPR) -} - -pub(crate) fn match_arm_list(p: &mut Parser) { - assert!(p.at(L_CURLY)); - let m = p.start(); - p.eat(L_CURLY); - while !p.at(EOF) && !p.at(R_CURLY) { - if p.at(L_CURLY) { - error_block(p, "expected match arm"); - continue; - } - // test match_arms_commas - // fn foo() { - // match () { - // _ => (), - // _ => {} - // _ => () - // } - // } - if match_arm(p).is_block() { - p.eat(COMMA); - } else if !p.at(R_CURLY) { - p.expect(COMMA); - } - } - p.expect(R_CURLY); - m.complete(p, MATCH_ARM_LIST); -} - -// test match_arm -// fn foo() { -// match () { -// _ => (), -// X | Y if Z => (), -// }; -// } -fn match_arm(p: &mut Parser) -> BlockLike { - let m = p.start(); - patterns::pattern_r(p, TokenSet::EMPTY); - while p.eat(PIPE) { - patterns::pattern(p); - } - if p.eat(IF_KW) { - expr_no_struct(p); - } - p.expect(FAT_ARROW); - let ret = expr_stmt(p); - m.complete(p, MATCH_ARM); - ret -} - -// test block_expr -// fn foo() { -// {}; -// unsafe {}; -// 'label: {}; -// } -fn block_expr(p: &mut Parser, m: Option) -> CompletedMarker { - assert!(p.at(L_CURLY)); - let m = m.unwrap_or_else(|| p.start()); - block(p); - m.complete(p, BLOCK_EXPR) -} - -// test return_expr -// fn foo() { -// return; -// return 92; -// } -fn return_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(RETURN_KW)); - let m = p.start(); - p.bump(); - if p.at_ts(EXPR_FIRST) { - expr(p); - } - m.complete(p, RETURN_EXPR) -} - -// test continue_expr -// fn foo() { -// loop { -// continue; -// continue 'l; -// } -// } -fn continue_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(CONTINUE_KW)); - let m = p.start(); - p.bump(); - p.eat(LIFETIME); - m.complete(p, CONTINUE_EXPR) -} - -// test break_expr -// fn foo() { -// loop { -// break; -// break 'l; -// break 92; -// break 'l 92; -// } -// } -fn break_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(BREAK_KW)); - let m = p.start(); - p.bump(); - p.eat(LIFETIME); - if p.at_ts(EXPR_FIRST) { - expr(p); - } - m.complete(p, BREAK_EXPR) -} diff --git a/crates/libsyntax2/src/grammar/expressions/mod.rs b/crates/libsyntax2/src/grammar/expressions/mod.rs deleted file mode 100644 index 20e0fa328..000000000 --- a/crates/libsyntax2/src/grammar/expressions/mod.rs +++ /dev/null @@ -1,450 +0,0 @@ -mod atom; - -use super::*; -pub(super) use self::atom::{literal, LITERAL_FIRST}; -pub(crate) use self::atom::match_arm_list; - -const EXPR_FIRST: TokenSet = LHS_FIRST; - -pub(super) fn expr(p: &mut Parser) -> BlockLike { - let r = Restrictions { forbid_structs: false, prefer_stmt: false }; - expr_bp(p, r, 1) -} - -pub(super) fn expr_stmt(p: &mut Parser) -> BlockLike { - let r = Restrictions { forbid_structs: false, prefer_stmt: true }; - expr_bp(p, r, 1) -} - -fn expr_no_struct(p: &mut Parser) { - let r = Restrictions { forbid_structs: true, prefer_stmt: false }; - expr_bp(p, r, 1); -} - -// test block -// fn a() {} -// fn b() { let _ = 1; } -// fn c() { 1; 2; } -// fn d() { 1; 2 } -pub(crate) fn block(p: &mut Parser) { - if !p.at(L_CURLY) { - p.error("expected a block"); - return; - } - let m = p.start(); - p.bump(); - while !p.at(EOF) && !p.at(R_CURLY) { - match p.current() { - LET_KW => let_stmt(p), - _ => { - // test block_items - // fn a() { fn b() {} } - let m = p.start(); - match items::maybe_item(p, items::ItemFlavor::Mod) { - items::MaybeItem::Item(kind) => { - m.complete(p, kind); - } - items::MaybeItem::Modifiers => { - m.abandon(p); - p.error("expected an item"); - } - // test pub_expr - // fn foo() { pub 92; } //FIXME - items::MaybeItem::None => { - let is_blocklike = expressions::expr_stmt(p) == BlockLike::Block; - if p.at(R_CURLY) { - m.abandon(p); - } else { - if is_blocklike { - p.eat(SEMI); - } else { - p.expect(SEMI); - } - m.complete(p, EXPR_STMT); - } - } - } - } - } - } - p.expect(R_CURLY); - m.complete(p, BLOCK); - - // test let_stmt; - // fn foo() { - // let a; - // let b: i32; - // let c = 92; - // let d: i32 = 92; - // } - fn let_stmt(p: &mut Parser) { - assert!(p.at(LET_KW)); - let m = p.start(); - p.bump(); - patterns::pattern(p); - if p.at(COLON) { - types::ascription(p); - } - if p.eat(EQ) { - expressions::expr(p); - } - p.expect(SEMI); - m.complete(p, LET_STMT); - } -} - -#[derive(Clone, Copy)] -struct Restrictions { - forbid_structs: bool, - prefer_stmt: bool, -} - -enum Op { - Simple, - Composite(SyntaxKind, u8), -} - -fn current_op(p: &Parser) -> (u8, Op) { - if let Some(t) = p.next3() { - match t { - (L_ANGLE, L_ANGLE, EQ) => - return (1, Op::Composite(SHLEQ, 3)), - (R_ANGLE, R_ANGLE, EQ) => - return (1, Op::Composite(SHREQ, 3)), - _ => (), - } - } - - if let Some(t) = p.next2() { - match t { - (PLUS, EQ) => return (1, Op::Composite(PLUSEQ, 2)), - (MINUS, EQ) => return (1, Op::Composite(MINUSEQ, 2)), - (STAR, EQ) => return (1, Op::Composite(STAREQ, 2)), - (SLASH, EQ) => return (1, Op::Composite(SLASHEQ, 2)), - (PIPE, EQ) => return (1, Op::Composite(PIPEEQ, 2)), - (AMP, EQ) => return (1, Op::Composite(AMPEQ, 2)), - (CARET, EQ) => return (1, Op::Composite(CARETEQ, 2)), - (PIPE, PIPE) => return (3, Op::Composite(PIPEPIPE, 2)), - (AMP, AMP) => return (4, Op::Composite(AMPAMP, 2)), - (L_ANGLE, EQ) => return (5, Op::Composite(LTEQ, 2)), - (R_ANGLE, EQ) => return (5, Op::Composite(GTEQ, 2)), - (L_ANGLE, L_ANGLE) => return (9, Op::Composite(SHL, 2)), - (R_ANGLE, R_ANGLE) => return (9, Op::Composite(SHR, 2)), - _ => (), - } - } - - let bp = match p.current() { - EQ => 1, - DOTDOT => 2, - EQEQ | NEQ | L_ANGLE | R_ANGLE => 5, - PIPE => 6, - CARET => 7, - AMP => 8, - MINUS | PLUS => 10, - STAR | SLASH | PERCENT => 11, - _ => 0, - }; - (bp, Op::Simple) -} - -// Parses expression with binding power of at least bp. -fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> BlockLike { - let mut lhs = match lhs(p, r) { - Some(lhs) => { - // test stmt_bin_expr_ambiguity - // fn foo() { - // let _ = {1} & 2; - // {1} &2; - // } - if r.prefer_stmt && is_block(lhs.kind()) { - return BlockLike::Block; - } - lhs - } - None => return BlockLike::NotBlock, - }; - - loop { - let is_range = p.current() == DOTDOT; - let (op_bp, op) = current_op(p); - if op_bp < bp { - break; - } - let m = lhs.precede(p); - match op { - Op::Simple => p.bump(), - Op::Composite(kind, n) => { - p.bump_compound(kind, n); - } - } - expr_bp(p, r, op_bp + 1); - lhs = m.complete(p, if is_range { RANGE_EXPR } else { BIN_EXPR }); - } - BlockLike::NotBlock -} - -// test no_semi_after_block -// fn foo() { -// if true {} -// loop {} -// match () {} -// while true {} -// for _ in () {} -// {} -// {} -// } -fn is_block(kind: SyntaxKind) -> bool { - match kind { - IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR => true, - _ => false, - } -} - -const LHS_FIRST: TokenSet = - token_set_union![ - token_set![AMP, STAR, EXCL, DOTDOT, MINUS], - atom::ATOM_EXPR_FIRST, - ]; - -fn lhs(p: &mut Parser, r: Restrictions) -> Option { - let m; - let kind = match p.current() { - // test ref_expr - // fn foo() { - // let _ = &1; - // let _ = &mut &f(); - // } - AMP => { - m = p.start(); - p.bump(); - p.eat(MUT_KW); - REF_EXPR - } - // test unary_expr - // fn foo() { - // **&1; - // !!true; - // --1; - // } - STAR | EXCL | MINUS => { - m = p.start(); - p.bump(); - PREFIX_EXPR - } - // test full_range_expr - // fn foo() { xs[..]; } - DOTDOT => { - m = p.start(); - p.bump(); - if p.at_ts(EXPR_FIRST) { - expr_bp(p, r, 2); - } - return Some(m.complete(p, RANGE_EXPR)); - } - _ => { - let lhs = atom::atom_expr(p, r)?; - return Some(postfix_expr(p, r, lhs)); - } - }; - expr_bp(p, r, 255); - Some(m.complete(p, kind)) -} - -fn postfix_expr(p: &mut Parser, r: Restrictions, mut lhs: CompletedMarker) -> CompletedMarker { - let mut allow_calls = !r.prefer_stmt || !is_block(lhs.kind()); - loop { - lhs = match p.current() { - // test stmt_postfix_expr_ambiguity - // fn foo() { - // match () { - // _ => {} - // () => {} - // [] => {} - // } - // } - L_PAREN if allow_calls => call_expr(p, lhs), - L_BRACK if allow_calls => index_expr(p, lhs), - DOT if p.nth(1) == IDENT => if p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON { - method_call_expr(p, lhs) - } else { - field_expr(p, lhs) - }, - DOT if p.nth(1) == INT_NUMBER => field_expr(p, lhs), - // test postfix_range - // fn foo() { let x = 1..; } - DOTDOT if !EXPR_FIRST.contains(p.nth(1)) => { - let m = lhs.precede(p); - p.bump(); - m.complete(p, RANGE_EXPR) - } - QUESTION => try_expr(p, lhs), - AS_KW => cast_expr(p, lhs), - _ => break, - }; - allow_calls = true - } - lhs -} - -// test call_expr -// fn foo() { -// let _ = f(); -// let _ = f()(1)(1, 2,); -// } -fn call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { - assert!(p.at(L_PAREN)); - let m = lhs.precede(p); - arg_list(p); - m.complete(p, CALL_EXPR) -} - -// test index_expr -// fn foo() { -// x[1][2]; -// } -fn index_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { - assert!(p.at(L_BRACK)); - let m = lhs.precede(p); - p.bump(); - expr(p); - p.expect(R_BRACK); - m.complete(p, INDEX_EXPR) -} - -// test method_call_expr -// fn foo() { -// x.foo(); -// y.bar::(1, 2,); -// } -fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { - assert!( - p.at(DOT) && p.nth(1) == IDENT - && (p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON) - ); - let m = lhs.precede(p); - p.bump(); - name_ref(p); - type_args::opt_type_arg_list(p, true); - if p.at(L_PAREN) { - arg_list(p); - } - m.complete(p, METHOD_CALL_EXPR) -} - -// test field_expr -// fn foo() { -// x.foo; -// x.0.bar; -// } -fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { - assert!(p.at(DOT) && (p.nth(1) == IDENT || p.nth(1) == INT_NUMBER)); - let m = lhs.precede(p); - p.bump(); - if p.at(IDENT) { - name_ref(p) - } else { - p.bump() - } - m.complete(p, FIELD_EXPR) -} - -// test try_expr -// fn foo() { -// x?; -// } -fn try_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { - assert!(p.at(QUESTION)); - let m = lhs.precede(p); - p.bump(); - m.complete(p, TRY_EXPR) -} - -// test cast_expr -// fn foo() { -// 82 as i32; -// } -fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { - assert!(p.at(AS_KW)); - let m = lhs.precede(p); - p.bump(); - types::type_(p); - m.complete(p, CAST_EXPR) -} - -fn arg_list(p: &mut Parser) { - assert!(p.at(L_PAREN)); - let m = p.start(); - p.bump(); - while !p.at(R_PAREN) && !p.at(EOF) { - if !p.at_ts(EXPR_FIRST) { - p.error("expected expression"); - break; - } - expr(p); - if !p.at(R_PAREN) && !p.expect(COMMA) { - break; - } - } - p.eat(R_PAREN); - m.complete(p, ARG_LIST); -} - -// test path_expr -// fn foo() { -// let _ = a; -// let _ = a::b; -// let _ = ::a::; -// let _ = format!(); -// } -fn path_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker { - assert!(paths::is_path_start(p) || p.at(L_ANGLE)); - let m = p.start(); - paths::expr_path(p); - match p.current() { - L_CURLY if !r.forbid_structs => { - named_field_list(p); - m.complete(p, STRUCT_LIT) - } - EXCL => { - items::macro_call_after_excl(p); - m.complete(p, MACRO_CALL) - } - _ => m.complete(p, PATH_EXPR) - } -} - -// test struct_lit -// fn foo() { -// S {}; -// S { x, y: 32, }; -// S { x, y: 32, ..Default::default() }; -// } -pub(crate) fn named_field_list(p: &mut Parser) { - assert!(p.at(L_CURLY)); - let m = p.start(); - p.bump(); - while !p.at(EOF) && !p.at(R_CURLY) { - match p.current() { - IDENT => { - let m = p.start(); - name_ref(p); - if p.eat(COLON) { - expr(p); - } - m.complete(p, NAMED_FIELD); - } - DOTDOT => { - p.bump(); - expr(p); - } - L_CURLY => error_block(p, "expected a field"), - _ => p.err_and_bump("expected identifier"), - } - if !p.at(R_CURLY) { - p.expect(COMMA); - } - } - p.expect(R_CURLY); - m.complete(p, NAMED_FIELD_LIST); -} diff --git a/crates/libsyntax2/src/grammar/items/consts.rs b/crates/libsyntax2/src/grammar/items/consts.rs deleted file mode 100644 index 5a5852f83..000000000 --- a/crates/libsyntax2/src/grammar/items/consts.rs +++ /dev/null @@ -1,21 +0,0 @@ -use super::*; - -pub(super) fn static_def(p: &mut Parser) { - const_or_static(p, STATIC_KW) -} - -pub(super) fn const_def(p: &mut Parser) { - const_or_static(p, CONST_KW) -} - -fn const_or_static(p: &mut Parser, kw: SyntaxKind) { - assert!(p.at(kw)); - p.bump(); - p.eat(MUT_KW); // TODO: validator to forbid const mut - name(p); - types::ascription(p); - if p.eat(EQ) { - expressions::expr(p); - } - p.expect(SEMI); -} diff --git a/crates/libsyntax2/src/grammar/items/mod.rs b/crates/libsyntax2/src/grammar/items/mod.rs deleted file mode 100644 index 2567313ab..000000000 --- a/crates/libsyntax2/src/grammar/items/mod.rs +++ /dev/null @@ -1,393 +0,0 @@ - -mod consts; -mod nominal; -mod traits; -mod use_item; - -use super::*; -pub(crate) use self::{ - expressions::{named_field_list, match_arm_list}, - nominal::{enum_variant_list, named_field_def_list}, - traits::{trait_item_list, impl_item_list}, - use_item::use_tree_list, -}; - -// test mod_contents -// fn foo() {} -// macro_rules! foo {} -// foo::bar!(); -// super::baz! {} -// struct S; -pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) { - attributes::inner_attributes(p); - while !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) { - item_or_macro(p, stop_on_r_curly, ItemFlavor::Mod) - } -} - -pub(super) enum ItemFlavor { - Mod, Trait -} - -const ITEM_RECOVERY_SET: TokenSet = - token_set![FN_KW, STRUCT_KW, ENUM_KW, IMPL_KW, TRAIT_KW, CONST_KW, STATIC_KW, LET_KW, - MOD_KW, PUB_KW, CRATE_KW]; - -pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool, flavor: ItemFlavor) { - let m = p.start(); - match maybe_item(p, flavor) { - MaybeItem::Item(kind) => { - m.complete(p, kind); - } - MaybeItem::None => { - if paths::is_path_start(p) { - match macro_call(p) { - BlockLike::Block => (), - BlockLike::NotBlock => { - p.expect(SEMI); - } - } - m.complete(p, MACRO_CALL); - } else { - m.abandon(p); - if p.at(L_CURLY) { - error_block(p, "expected an item"); - } else if p.at(R_CURLY) && !stop_on_r_curly { - let e = p.start(); - p.error("unmatched `}`"); - p.bump(); - e.complete(p, ERROR); - } else if !p.at(EOF) && !p.at(R_CURLY) { - p.err_and_bump("expected an item"); - } else { - p.error("expected an item"); - } - } - } - MaybeItem::Modifiers => { - p.error("expected fn, trait or impl"); - m.complete(p, ERROR); - } - } -} - -pub(super) enum MaybeItem { - None, - Item(SyntaxKind), - Modifiers, -} - -pub(super) fn maybe_item(p: &mut Parser, flavor: ItemFlavor) -> MaybeItem { - attributes::outer_attributes(p); - opt_visibility(p); - if let Some(kind) = items_without_modifiers(p) { - return MaybeItem::Item(kind); - } - - let mut has_mods = false; - // modifiers - has_mods |= p.eat(CONST_KW); - - // test unsafe_block_in_mod - // fn foo(){} unsafe { } fn bar(){} - if p.at(UNSAFE_KW) && p.nth(1) != L_CURLY { - p.eat(UNSAFE_KW); - has_mods = true; - } - if p.at(EXTERN_KW) { - has_mods = true; - abi(p); - } - if p.at(IDENT) && p.at_contextual_kw("auto") && p.nth(1) == TRAIT_KW { - p.bump_remap(AUTO_KW); - has_mods = true; - } - if p.at(IDENT) && p.at_contextual_kw("default") && p.nth(1) == IMPL_KW { - p.bump_remap(DEFAULT_KW); - has_mods = true; - } - - // items - let kind = match p.current() { - // test extern_fn - // extern fn foo() {} - - // test const_fn - // const fn foo() {} - - // test const_unsafe_fn - // const unsafe fn foo() {} - - // test unsafe_extern_fn - // unsafe extern "C" fn foo() {} - - // test unsafe_fn - // unsafe fn foo() {} - FN_KW => { - fn_def(p, flavor); - FN_DEF - } - - // test unsafe_trait - // unsafe trait T {} - - // test auto_trait - // auto trait T {} - - // test unsafe_auto_trait - // unsafe auto trait T {} - TRAIT_KW => { - traits::trait_def(p); - TRAIT_DEF - } - - // test unsafe_impl - // unsafe impl Foo {} - - // test default_impl - // default impl Foo {} - - // test unsafe_default_impl - // unsafe default impl Foo {} - IMPL_KW => { - traits::impl_item(p); - IMPL_ITEM - } - _ => return if has_mods { - MaybeItem::Modifiers - } else { - MaybeItem::None - } - }; - - MaybeItem::Item(kind) -} - -fn items_without_modifiers(p: &mut Parser) -> Option { - let la = p.nth(1); - let kind = match p.current() { - // test extern_crate - // extern crate foo; - EXTERN_KW if la == CRATE_KW => { - extern_crate_item(p); - EXTERN_CRATE_ITEM - } - TYPE_KW => { - type_def(p); - TYPE_DEF - } - MOD_KW => { - mod_item(p); - MODULE - } - STRUCT_KW => { - // test struct_items - // struct Foo; - // struct Foo {} - // struct Foo(); - // struct Foo(String, usize); - // struct Foo { - // a: i32, - // b: f32, - // } - nominal::struct_def(p, STRUCT_KW); - if p.at(SEMI) { - p.err_and_bump( - "expected item, found `;`\n\ - consider removing this semicolon" - ); - } - STRUCT_DEF - } - IDENT if p.at_contextual_kw("union") => { - // test union_items - // union Foo {} - // union Foo { - // a: i32, - // b: f32, - // } - nominal::struct_def(p, UNION_KW); - STRUCT_DEF - } - ENUM_KW => { - nominal::enum_def(p); - ENUM_DEF - } - USE_KW => { - use_item::use_item(p); - USE_ITEM - } - CONST_KW if (la == IDENT || la == MUT_KW) => { - consts::const_def(p); - CONST_DEF - } - STATIC_KW => { - consts::static_def(p); - STATIC_DEF - } - // test extern_block - // extern {} - EXTERN_KW if la == L_CURLY || ((la == STRING || la == RAW_STRING) && p.nth(2) == L_CURLY) => { - abi(p); - extern_item_list(p); - EXTERN_BLOCK - } - _ => return None, - }; - Some(kind) -} - -fn extern_crate_item(p: &mut Parser) { - assert!(p.at(EXTERN_KW)); - p.bump(); - assert!(p.at(CRATE_KW)); - p.bump(); - name(p); - opt_alias(p); - p.expect(SEMI); -} - -pub(crate) fn extern_item_list(p: &mut Parser) { - assert!(p.at(L_CURLY)); - let m = p.start(); - p.bump(); - mod_contents(p, true); - p.expect(R_CURLY); - m.complete(p, EXTERN_ITEM_LIST); -} - -fn fn_def(p: &mut Parser, flavor: ItemFlavor) { - assert!(p.at(FN_KW)); - p.bump(); - - name_r(p, ITEM_RECOVERY_SET); - // test function_type_params - // fn foo(){} - type_params::opt_type_param_list(p); - - if p.at(L_PAREN) { - match flavor { - ItemFlavor::Mod => - params::param_list(p), - ItemFlavor::Trait => - params::param_list_opt_patterns(p), - } - } else { - p.error("expected function arguments"); - } - // test function_ret_type - // fn foo() {} - // fn bar() -> () {} - opt_fn_ret_type(p); - - // test function_where_clause - // fn foo() where T: Copy {} - type_params::opt_where_clause(p); - - // test fn_decl - // trait T { fn foo(); } - if p.at(SEMI) { - p.bump(); - } else { - expressions::block(p) - } -} - -// test type_item -// type Foo = Bar; -fn type_def(p: &mut Parser) { - assert!(p.at(TYPE_KW)); - p.bump(); - - name(p); - - // test type_item_type_params - // type Result = (); - type_params::opt_type_param_list(p); - - if p.at(COLON) { - type_params::bounds(p); - } - - // test type_item_where_clause - // type Foo where Foo: Copy = (); - type_params::opt_where_clause(p); - - if p.eat(EQ) { - types::type_(p); - } - p.expect(SEMI); -} - -pub(crate) fn mod_item(p: &mut Parser) { - assert!(p.at(MOD_KW)); - p.bump(); - - name(p); - if p.at(L_CURLY) { - mod_item_list(p); - } else if !p.eat(SEMI) { - p.error("expected `;` or `{`"); - } -} - -pub(crate) fn mod_item_list(p: &mut Parser) { - assert!(p.at(L_CURLY)); - let m = p.start(); - p.bump(); - mod_contents(p, true); - p.expect(R_CURLY); - m.complete(p, ITEM_LIST); -} - -fn macro_call(p: &mut Parser) -> BlockLike { - assert!(paths::is_path_start(p)); - paths::use_path(p); - macro_call_after_excl(p) -} - -pub(super) fn macro_call_after_excl(p: &mut Parser) -> BlockLike { - p.expect(EXCL); - p.eat(IDENT); - let flavor = match p.current() { - L_CURLY => { - token_tree(p); - BlockLike::Block - } - L_PAREN | L_BRACK => { - token_tree(p); - BlockLike::NotBlock - } - _ => { - p.error("expected `{`, `[`, `(`"); - BlockLike::NotBlock - }, - }; - - flavor -} - -pub(crate) fn token_tree(p: &mut Parser) { - let closing_paren_kind = match p.current() { - L_CURLY => R_CURLY, - L_PAREN => R_PAREN, - L_BRACK => R_BRACK, - _ => unreachable!(), - }; - let m = p.start(); - p.bump(); - while !p.at(EOF) && !p.at(closing_paren_kind) { - match p.current() { - L_CURLY | L_PAREN | L_BRACK => token_tree(p), - R_CURLY => { - p.error("unmatched `}`"); - m.complete(p, TOKEN_TREE); - return; - } - R_PAREN | R_BRACK => p.err_and_bump("unmatched brace"), - _ => p.bump() - } - }; - p.expect(closing_paren_kind); - m.complete(p, TOKEN_TREE); -} diff --git a/crates/libsyntax2/src/grammar/items/nominal.rs b/crates/libsyntax2/src/grammar/items/nominal.rs deleted file mode 100644 index 8d02ad555..000000000 --- a/crates/libsyntax2/src/grammar/items/nominal.rs +++ /dev/null @@ -1,154 +0,0 @@ -use super::*; - -pub(super) fn struct_def(p: &mut Parser, kind: SyntaxKind) { - assert!(p.at(STRUCT_KW) || p.at_contextual_kw("union")); - p.bump_remap(kind); - - name_r(p, ITEM_RECOVERY_SET); - type_params::opt_type_param_list(p); - match p.current() { - WHERE_KW => { - type_params::opt_where_clause(p); - match p.current() { - SEMI => { - p.bump(); - return; - } - L_CURLY => named_field_def_list(p), - _ => { - //TODO: special case `(` error message - p.error("expected `;` or `{`"); - return; - } - } - } - SEMI if kind == STRUCT_KW => { - p.bump(); - return; - } - L_CURLY => named_field_def_list(p), - L_PAREN if kind == STRUCT_KW => { - pos_field_list(p); - p.expect(SEMI); - } - _ if kind == STRUCT_KW => { - p.error("expected `;`, `{`, or `(`"); - return; - } - _ => { - p.error("expected `{`"); - return; - } - } -} - -pub(super) fn enum_def(p: &mut Parser) { - assert!(p.at(ENUM_KW)); - p.bump(); - name_r(p, ITEM_RECOVERY_SET); - type_params::opt_type_param_list(p); - type_params::opt_where_clause(p); - if p.at(L_CURLY) { - enum_variant_list(p); - } else { - p.error("expected `{`") - } -} - -pub(crate) fn enum_variant_list(p: &mut Parser) { - assert!(p.at(L_CURLY)); - let m = p.start(); - p.bump(); - while !p.at(EOF) && !p.at(R_CURLY) { - if p.at(L_CURLY) { - error_block(p, "expected enum variant"); - continue; - } - let var = p.start(); - attributes::outer_attributes(p); - if p.at(IDENT) { - name(p); - match p.current() { - L_CURLY => named_field_def_list(p), - L_PAREN => pos_field_list(p), - EQ => { - p.bump(); - expressions::expr(p); - } - _ => (), - } - var.complete(p, ENUM_VARIANT); - } else { - var.abandon(p); - p.err_and_bump("expected enum variant"); - } - if !p.at(R_CURLY) { - p.expect(COMMA); - } - } - p.expect(R_CURLY); - m.complete(p, ENUM_VARIANT_LIST); -} - -pub(crate) fn named_field_def_list(p: &mut Parser) { - assert!(p.at(L_CURLY)); - let m = p.start(); - p.bump(); - while !p.at(R_CURLY) && !p.at(EOF) { - if p.at(L_CURLY) { - error_block(p, "expected field"); - continue; - } - named_field_def(p); - if !p.at(R_CURLY) { - p.expect(COMMA); - } - } - p.expect(R_CURLY); - m.complete(p, NAMED_FIELD_DEF_LIST); - - fn named_field_def(p: &mut Parser) { - let m = p.start(); - // test field_attrs - // struct S { - // #[serde(with = "url_serde")] - // pub uri: Uri, - // } - attributes::outer_attributes(p); - opt_visibility(p); - if p.at(IDENT) { - name(p); - p.expect(COLON); - types::type_(p); - m.complete(p, NAMED_FIELD_DEF); - } else { - m.abandon(p); - p.err_and_bump("expected field declaration"); - } - } -} - -fn pos_field_list(p: &mut Parser) { - assert!(p.at(L_PAREN)); - let m = p.start(); - if !p.expect(L_PAREN) { - return; - } - while !p.at(R_PAREN) && !p.at(EOF) { - let m = p.start(); - opt_visibility(p); - if !p.at_ts(types::TYPE_FIRST) { - p.error("expected a type"); - m.complete(p, ERROR); - break; - } - types::type_(p); - m.complete(p, POS_FIELD); - - if !p.at(R_PAREN) { - p.expect(COMMA); - } - } - p.expect(R_PAREN); - m.complete(p, POS_FIELD_LIST); -} diff --git a/crates/libsyntax2/src/grammar/items/traits.rs b/crates/libsyntax2/src/grammar/items/traits.rs deleted file mode 100644 index c21cfb1a9..000000000 --- a/crates/libsyntax2/src/grammar/items/traits.rs +++ /dev/null @@ -1,117 +0,0 @@ -use super::*; - -// test trait_item -// trait T: Hash + Clone where U: Copy {} -pub(super) fn trait_def(p: &mut Parser) { - assert!(p.at(TRAIT_KW)); - p.bump(); - name_r(p, ITEM_RECOVERY_SET); - type_params::opt_type_param_list(p); - if p.at(COLON) { - type_params::bounds(p); - } - type_params::opt_where_clause(p); - if p.at(L_CURLY) { - trait_item_list(p); - } else { - p.error("expected `{`"); - } -} - -// test trait_item_list -// impl F { -// type A: Clone; -// const B: i32; -// fn foo() {} -// fn bar(&self); -// } -pub(crate) fn trait_item_list(p: &mut Parser) { - assert!(p.at(L_CURLY)); - let m = p.start(); - p.bump(); - while !p.at(EOF) && !p.at(R_CURLY) { - if p.at(L_CURLY) { - error_block(p, "expected an item"); - continue; - } - item_or_macro(p, true, ItemFlavor::Trait); - } - p.expect(R_CURLY); - m.complete(p, ITEM_LIST); -} - -// test impl_item -// impl Foo {} -pub(super) fn impl_item(p: &mut Parser) { - assert!(p.at(IMPL_KW)); - p.bump(); - if choose_type_params_over_qpath(p) { - type_params::opt_type_param_list(p); - } - - // TODO: never type - // impl ! {} - - // test impl_item_neg - // impl !Send for X {} - p.eat(EXCL); - types::type_(p); - if p.eat(FOR_KW) { - types::type_(p); - } - type_params::opt_where_clause(p); - if p.at(L_CURLY) { - impl_item_list(p); - } else { - p.error("expected `{`"); - } -} - -// test impl_item_list -// impl F { -// type A = i32; -// const B: i32 = 92; -// fn foo() {} -// fn bar(&self) {} -// } -pub(crate) fn impl_item_list(p: &mut Parser) { - assert!(p.at(L_CURLY)); - let m = p.start(); - p.bump(); - - while !p.at(EOF) && !p.at(R_CURLY) { - if p.at(L_CURLY) { - error_block(p, "expected an item"); - continue; - } - item_or_macro(p, true, ItemFlavor::Mod); - } - p.expect(R_CURLY); - m.complete(p, ITEM_LIST); -} - -fn choose_type_params_over_qpath(p: &Parser) -> bool { - // There's an ambiguity between generic parameters and qualified paths in impls. - // If we see `<` it may start both, so we have to inspect some following tokens. - // The following combinations can only start generics, - // but not qualified paths (with one exception): - // `<` `>` - empty generic parameters - // `<` `#` - generic parameters with attributes - // `<` (LIFETIME|IDENT) `>` - single generic parameter - // `<` (LIFETIME|IDENT) `,` - first generic parameter in a list - // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds - // `<` (LIFETIME|IDENT) `=` - generic parameter with a default - // The only truly ambiguous case is - // `<` IDENT `>` `::` IDENT ... - // we disambiguate it in favor of generics (`impl ::absolute::Path { ... }`) - // because this is what almost always expected in practice, qualified paths in impls - // (`impl ::AssocTy { ... }`) aren't even allowed by type checker at the moment. - if !p.at(L_ANGLE) { - return false; - } - if p.nth(1) == POUND || p.nth(1) == R_ANGLE { - return true; - } - (p.nth(1) == LIFETIME || p.nth(1) == IDENT) - && (p.nth(2) == R_ANGLE || p.nth(2) == COMMA || p.nth(2) == COLON || p.nth(2) == EQ) -} diff --git a/crates/libsyntax2/src/grammar/items/use_item.rs b/crates/libsyntax2/src/grammar/items/use_item.rs deleted file mode 100644 index 1ee4349fd..000000000 --- a/crates/libsyntax2/src/grammar/items/use_item.rs +++ /dev/null @@ -1,68 +0,0 @@ -use super::*; - -pub(super) fn use_item(p: &mut Parser) { - assert!(p.at(USE_KW)); - p.bump(); - use_tree(p); - p.expect(SEMI); -} - -fn use_tree(p: &mut Parser) { - let la = p.nth(1); - let m = p.start(); - match (p.current(), la) { - (STAR, _) => p.bump(), - (COLONCOLON, STAR) => { - p.bump(); - p.bump(); - } - (L_CURLY, _) | (COLONCOLON, L_CURLY) => { - if p.at(COLONCOLON) { - p.bump(); - } - use_tree_list(p); - } - _ if paths::is_path_start(p) => { - paths::use_path(p); - match p.current() { - AS_KW => { - opt_alias(p); - } - COLONCOLON => { - p.bump(); - match p.current() { - STAR => { - p.bump(); - } - L_CURLY => use_tree_list(p), - _ => { - // is this unreachable? - p.error("expected `{` or `*`"); - } - } - } - _ => (), - } - } - _ => { - m.abandon(p); - p.err_and_bump("expected one of `*`, `::`, `{`, `self`, `super`, `indent`"); - return; - } - } - m.complete(p, USE_TREE); -} - -pub(crate) fn use_tree_list(p: &mut Parser) { - assert!(p.at(L_CURLY)); - let m = p.start(); - p.bump(); - while !p.at(EOF) && !p.at(R_CURLY) { - use_tree(p); - if !p.at(R_CURLY) { - p.expect(COMMA); - } - } - p.expect(R_CURLY); - m.complete(p, USE_TREE_LIST); -} diff --git a/crates/libsyntax2/src/grammar/mod.rs b/crates/libsyntax2/src/grammar/mod.rs deleted file mode 100644 index 2cb11dc1e..000000000 --- a/crates/libsyntax2/src/grammar/mod.rs +++ /dev/null @@ -1,188 +0,0 @@ -//! This is the actual "grammar" of the Rust language. -//! -//! Each function in this module and its children corresponds -//! to a production of the format grammar. Submodules roughly -//! correspond to different *areas* of the grammar. By convention, -//! each submodule starts with `use super::*` import and exports -//! "public" productions via `pub(super)`. -//! -//! See docs for `Parser` to learn about API, available to the grammar, -//! and see docs for `Event` to learn how this actually manages to -//! produce parse trees. -//! -//! Code in this module also contains inline tests, which start with -//! `// test name-of-the-test` comment and look like this: -//! -//! ``` -//! // test function_with_zero_parameters -//! // fn foo() {} -//! ``` -//! -//! After adding a new inline-test, run `cargo collect-tests` to extract -//! it as a standalone text-fixture into `tests/data/parser/inline`, and -//! run `cargo test` once to create the "gold" value. -mod attributes; -mod expressions; -mod items; -mod params; -mod paths; -mod patterns; -mod type_args; -mod type_params; -mod types; - -use { - token_set::TokenSet, - parser_api::{Marker, CompletedMarker, Parser}, - SyntaxKind::{self, *}, -}; -pub(crate) use self::{ - expressions::{ - block, - }, - items::{ - enum_variant_list, - extern_item_list, - impl_item_list, - match_arm_list, - mod_item_list, - named_field_def_list, - named_field_list, - token_tree, - trait_item_list, - use_tree_list, - }, -}; - -pub(crate) fn root(p: &mut Parser) { - let m = p.start(); - p.eat(SHEBANG); - items::mod_contents(p, false); - m.complete(p, ROOT); -} - - -#[derive(Clone, Copy, PartialEq, Eq)] -enum BlockLike { - Block, - NotBlock, -} - -impl BlockLike { - fn is_block(self) -> bool { self == BlockLike::Block } -} - -fn opt_visibility(p: &mut Parser) { - match p.current() { - PUB_KW => { - let m = p.start(); - p.bump(); - if p.at(L_PAREN) { - match p.nth(1) { - // test crate_visibility - // pub(crate) struct S; - // pub(self) struct S; - // pub(self) struct S; - // pub(self) struct S; - CRATE_KW | SELF_KW | SUPER_KW => { - p.bump(); - p.bump(); - p.expect(R_PAREN); - } - IN_KW => { - p.bump(); - p.bump(); - paths::use_path(p); - p.expect(R_PAREN); - } - _ => (), - } - } - m.complete(p, VISIBILITY); - } - // test crate_keyword_vis - // crate fn main() { } - CRATE_KW => { - let m = p.start(); - p.bump(); - m.complete(p, VISIBILITY); - } - _ => (), - } -} - -fn opt_alias(p: &mut Parser) { - if p.at(AS_KW) { - let m = p.start(); - p.bump(); - name(p); - m.complete(p, ALIAS); - } -} - -fn abi(p: &mut Parser) { - assert!(p.at(EXTERN_KW)); - let abi = p.start(); - p.bump(); - match p.current() { - STRING | RAW_STRING => p.bump(), - _ => (), - } - abi.complete(p, ABI); -} - -fn opt_fn_ret_type(p: &mut Parser) -> bool { - if p.at(THIN_ARROW) { - let m = p.start(); - p.bump(); - types::type_(p); - m.complete(p, RET_TYPE); - true - } else { - false - } -} - -fn name_r(p: &mut Parser, recovery: TokenSet) { - if p.at(IDENT) { - let m = p.start(); - p.bump(); - m.complete(p, NAME); - } else { - p.err_recover("expected a name", recovery); - } -} - -fn name(p: &mut Parser) { - name_r(p, TokenSet::EMPTY) -} - -fn name_ref(p: &mut Parser) { - if p.at(IDENT) { - let m = p.start(); - p.bump(); - m.complete(p, NAME_REF); - } else { - p.err_and_bump("expected identifier"); - } -} - -fn error_block(p: &mut Parser, message: &str) { - go(p, Some(message)); - fn go(p: &mut Parser, message: Option<&str>) { - assert!(p.at(L_CURLY)); - let m = p.start(); - if let Some(message) = message { - p.error(message); - } - p.bump(); - while !p.at(EOF) && !p.at(R_CURLY) { - match p.current() { - L_CURLY => go(p, None), - _ => p.bump(), - } - } - p.eat(R_CURLY); - m.complete(p, ERROR); - } -} diff --git a/crates/libsyntax2/src/grammar/params.rs b/crates/libsyntax2/src/grammar/params.rs deleted file mode 100644 index 903c25939..000000000 --- a/crates/libsyntax2/src/grammar/params.rs +++ /dev/null @@ -1,142 +0,0 @@ -use super::*; - -// test param_list -// fn a() {} -// fn b(x: i32) {} -// fn c(x: i32, ) {} -// fn d(x: i32, y: ()) {} -pub(super) fn param_list(p: &mut Parser) { - list_(p, Flavor::Normal) -} - -// test param_list_opt_patterns -// fn foo)>(){} -pub(super) fn param_list_opt_patterns(p: &mut Parser) { - list_(p, Flavor::OptionalPattern) -} - -pub(super) fn param_list_opt_types(p: &mut Parser) { - list_(p, Flavor::OptionalType) -} - -#[derive(Clone, Copy, Eq, PartialEq)] -enum Flavor { - OptionalType, - OptionalPattern, - Normal, -} - -impl Flavor { - fn type_required(self) -> bool { - match self { - Flavor::OptionalType => false, - _ => true, - } - } -} - -fn list_(p: &mut Parser, flavor: Flavor) { - let (bra, ket) = if flavor.type_required() { - (L_PAREN, R_PAREN) - } else { - (PIPE, PIPE) - }; - assert!(p.at(bra)); - let m = p.start(); - p.bump(); - if flavor.type_required() { - opt_self_param(p); - } - while !p.at(EOF) && !p.at(ket) { - if !p.at_ts(VALUE_PARAMETER_FIRST) { - p.error("expected value parameter"); - break; - } - value_parameter(p, flavor); - if !p.at(ket) { - p.expect(COMMA); - } - } - p.expect(ket); - m.complete(p, PARAM_LIST); -} - - -const VALUE_PARAMETER_FIRST: TokenSet = - token_set_union![ - patterns::PATTERN_FIRST, - types::TYPE_FIRST, - ]; - -fn value_parameter(p: &mut Parser, flavor: Flavor) { - let m = p.start(); - match flavor { - Flavor::OptionalType | Flavor::Normal => { - patterns::pattern(p); - if p.at(COLON) || flavor.type_required() { - types::ascription(p) - } - }, - // test value_parameters_no_patterns - // type F = Box; - Flavor::OptionalPattern => { - let la0 = p.current(); - let la1 = p.nth(1); - let la2 = p.nth(2); - let la3 = p.nth(3); - if la0 == IDENT && la1 == COLON - || la0 == AMP && la1 == IDENT && la2 == COLON - || la0 == AMP && la1 == MUT_KW && la2 == IDENT && la3 == COLON { - patterns::pattern(p); - types::ascription(p); - } else { - types::type_(p); - } - }, - } - m.complete(p, PARAM); -} - -// test self_param -// impl S { -// fn a(self) {} -// fn b(&self,) {} -// fn c(&'a self,) {} -// fn d(&'a mut self, x: i32) {} -// fn e(mut self) {} -// } -fn opt_self_param(p: &mut Parser) { - let m; - if p.at(SELF_KW) || p.at(MUT_KW) && p.nth(1) == SELF_KW { - m = p.start(); - p.eat(MUT_KW); - p.eat(SELF_KW); - // test arb_self_types - // impl S { - // fn a(self: &Self) {} - // fn b(mut self: Box) {} - // } - if p.at(COLON) { - types::ascription(p); - } - } else { - let la1 = p.nth(1); - let la2 = p.nth(2); - let la3 = p.nth(3); - let n_toks = match (p.current(), la1, la2, la3) { - (AMP, SELF_KW, _, _) => 2, - (AMP, MUT_KW, SELF_KW, _) => 3, - (AMP, LIFETIME, SELF_KW, _) => 3, - (AMP, LIFETIME, MUT_KW, SELF_KW) => 4, - _ => return, - }; - m = p.start(); - for _ in 0..n_toks { - p.bump(); - } - } - m.complete(p, SELF_PARAM); - if !p.at(R_PAREN) { - p.expect(COMMA); - } -} diff --git a/crates/libsyntax2/src/grammar/paths.rs b/crates/libsyntax2/src/grammar/paths.rs deleted file mode 100644 index 7c9fb8be2..000000000 --- a/crates/libsyntax2/src/grammar/paths.rs +++ /dev/null @@ -1,101 +0,0 @@ -use super::*; - -pub(super) const PATH_FIRST: TokenSet = - token_set![IDENT, SELF_KW, SUPER_KW, COLONCOLON, L_ANGLE]; - -pub(super) fn is_path_start(p: &Parser) -> bool { - match p.current() { - IDENT | SELF_KW | SUPER_KW | COLONCOLON => true, - _ => false, - } -} - -pub(super) fn use_path(p: &mut Parser) { - path(p, Mode::Use) -} - -pub(super) fn type_path(p: &mut Parser) { - path(p, Mode::Type) -} - -pub(super) fn expr_path(p: &mut Parser) { - path(p, Mode::Expr) -} - -#[derive(Clone, Copy, Eq, PartialEq)] -enum Mode { - Use, - Type, - Expr, -} - -fn path(p: &mut Parser, mode: Mode) { - let path = p.start(); - path_segment(p, mode, true); - let mut qual = path.complete(p, PATH); - loop { - let use_tree = match p.nth(1) { - STAR | L_CURLY => true, - _ => false, - }; - if p.at(COLONCOLON) && !use_tree { - let path = qual.precede(p); - p.bump(); - path_segment(p, mode, false); - let path = path.complete(p, PATH); - qual = path; - } else { - break; - } - } -} - -fn path_segment(p: &mut Parser, mode: Mode, first: bool) { - let m = p.start(); - // test qual_paths - // type X = ::Output; - // fn foo() { ::default(); } - if first && p.eat(L_ANGLE) { - types::type_(p); - if p.eat(AS_KW) { - if is_path_start(p) { - types::path_type(p); - } else { - p.error("expected a trait"); - } - } - p.expect(R_ANGLE); - } else { - if first { - p.eat(COLONCOLON); - } - match p.current() { - IDENT => { - name_ref(p); - opt_path_type_args(p, mode); - } - SELF_KW | SUPER_KW => p.bump(), - _ => { - p.err_and_bump("expected identifier"); - } - }; - } - m.complete(p, PATH_SEGMENT); -} - -fn opt_path_type_args(p: &mut Parser, mode: Mode) { - match mode { - Mode::Use => return, - Mode::Type => { - // test path_fn_trait_args - // type F = Box ()>; - if p.at(L_PAREN) { - params::param_list_opt_patterns(p); - opt_fn_ret_type(p); - } else { - type_args::opt_type_arg_list(p, false) - } - }, - Mode::Expr => type_args::opt_type_arg_list(p, true), - } -} diff --git a/crates/libsyntax2/src/grammar/patterns.rs b/crates/libsyntax2/src/grammar/patterns.rs deleted file mode 100644 index 420bae7a7..000000000 --- a/crates/libsyntax2/src/grammar/patterns.rs +++ /dev/null @@ -1,224 +0,0 @@ -use super::*; - -pub(super) const PATTERN_FIRST: TokenSet = - token_set_union![ - token_set![REF_KW, MUT_KW, L_PAREN, L_BRACK, AMP, UNDERSCORE], - expressions::LITERAL_FIRST, - paths::PATH_FIRST, - ]; - -pub(super) fn pattern(p: &mut Parser) { - pattern_r(p, PAT_RECOVERY_SET) -} - -pub(super) fn pattern_r(p: &mut Parser, recovery_set: TokenSet) { - if let Some(lhs) = atom_pat(p, recovery_set) { - // test range_pat - // fn main() { - // match 92 { 0 ... 100 => () } - // } - if p.at(DOTDOTDOT) { - let m = lhs.precede(p); - p.bump(); - atom_pat(p, recovery_set); - m.complete(p, RANGE_PAT); - } - } -} - -const PAT_RECOVERY_SET: TokenSet = - token_set![LET_KW, IF_KW, WHILE_KW, LOOP_KW, MATCH_KW, R_PAREN, COMMA]; - - -fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option { - let la0 = p.nth(0); - let la1 = p.nth(1); - if la0 == REF_KW || la0 == MUT_KW - || (la0 == IDENT && !(la1 == COLONCOLON || la1 == L_PAREN || la1 == L_CURLY)) { - return Some(bind_pat(p, true)); - } - if paths::is_path_start(p) { - return Some(path_pat(p)); - } - - // test literal_pattern - // fn main() { - // match () { - // 92 => (), - // 'c' => (), - // "hello" => (), - // } - // } - match expressions::literal(p) { - Some(m) => return Some(m), - None => (), - } - - let m = match la0 { - UNDERSCORE => placeholder_pat(p), - AMP => ref_pat(p), - L_PAREN => tuple_pat(p), - L_BRACK => slice_pat(p), - _ => { - p.err_recover("expected pattern", recovery_set); - return None; - } - }; - Some(m) -} - -// test path_part -// fn foo() { -// let foo::Bar = (); -// let ::Bar = (); -// let Bar { .. } = (); -// let Bar(..) = (); -// } -fn path_pat(p: &mut Parser) -> CompletedMarker { - assert!(paths::is_path_start(p)); - let m = p.start(); - paths::expr_path(p); - let kind = match p.current() { - L_PAREN => { - tuple_pat_fields(p); - TUPLE_STRUCT_PAT - } - L_CURLY => { - field_pat_list(p); - STRUCT_PAT - } - _ => PATH_PAT - }; - m.complete(p, kind) -} - -// test tuple_pat_fields -// fn foo() { -// let S() = (); -// let S(_) = (); -// let S(_,) = (); -// let S(_, .. , x) = (); -// } -fn tuple_pat_fields(p: &mut Parser) { - assert!(p.at(L_PAREN)); - p.bump(); - pat_list(p, R_PAREN); - p.expect(R_PAREN); -} - -// test field_pat_list -// fn foo() { -// let S {} = (); -// let S { f, ref mut g } = (); -// let S { h: _, ..} = (); -// let S { h: _, } = (); -// } -fn field_pat_list(p: &mut Parser) { - assert!(p.at(L_CURLY)); - let m = p.start(); - p.bump(); - while !p.at(EOF) && !p.at(R_CURLY) { - match p.current() { - DOTDOT => p.bump(), - IDENT if p.nth(1) == COLON => { - p.bump(); - p.bump(); - pattern(p); - } - L_CURLY => error_block(p, "expected ident"), - _ => { - bind_pat(p, false); - } - } - if !p.at(R_CURLY) { - p.expect(COMMA); - } - } - p.expect(R_CURLY); - m.complete(p, FIELD_PAT_LIST); -} - -// test placeholder_pat -// fn main() { let _ = (); } -fn placeholder_pat(p: &mut Parser) -> CompletedMarker { - assert!(p.at(UNDERSCORE)); - let m = p.start(); - p.bump(); - m.complete(p, PLACEHOLDER_PAT) -} - -// test ref_pat -// fn main() { -// let &a = (); -// let &mut b = (); -// } -fn ref_pat(p: &mut Parser) -> CompletedMarker { - assert!(p.at(AMP)); - let m = p.start(); - p.bump(); - p.eat(MUT_KW); - pattern(p); - m.complete(p, REF_PAT) -} - -// test tuple_pat -// fn main() { -// let (a, b, ..) = (); -// } -fn tuple_pat(p: &mut Parser) -> CompletedMarker { - assert!(p.at(L_PAREN)); - let m = p.start(); - tuple_pat_fields(p); - m.complete(p, TUPLE_PAT) -} - -// test slice_pat -// fn main() { -// let [a, b, ..] = []; -// } -fn slice_pat(p: &mut Parser) -> CompletedMarker { - assert!(p.at(L_BRACK)); - let m = p.start(); - p.bump(); - pat_list(p, R_BRACK); - p.expect(R_BRACK); - m.complete(p, SLICE_PAT) -} - -fn pat_list(p: &mut Parser, ket: SyntaxKind) { - while !p.at(EOF) && !p.at(ket) { - match p.current() { - DOTDOT => p.bump(), - _ => { - if !p.at_ts(PATTERN_FIRST) { - p.error("expected a pattern"); - break; - } - pattern(p) - }, - } - if !p.at(ket) { - p.expect(COMMA); - } - } -} - -// test bind_pat -// fn main() { -// let a = (); -// let mut b = (); -// let ref c = (); -// let ref mut d = (); -// let e @ _ = (); -// let ref mut f @ g @ _ = (); -// } -fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker { - let m = p.start(); - p.eat(REF_KW); - p.eat(MUT_KW); - name(p); - if with_at && p.eat(AT) { - pattern(p); - } - m.complete(p, BIND_PAT) -} diff --git a/crates/libsyntax2/src/grammar/type_args.rs b/crates/libsyntax2/src/grammar/type_args.rs deleted file mode 100644 index 29ff6e534..000000000 --- a/crates/libsyntax2/src/grammar/type_args.rs +++ /dev/null @@ -1,48 +0,0 @@ -use super::*; - -pub(super) fn opt_type_arg_list(p: &mut Parser, colon_colon_required: bool) { - let m; - match (colon_colon_required, p.nth(0), p.nth(1)) { - (_, COLONCOLON, L_ANGLE) => { - m = p.start(); - p.bump(); - p.bump(); - } - (false, L_ANGLE, _) => { - m = p.start(); - p.bump(); - } - _ => return, - }; - - while !p.at(EOF) && !p.at(R_ANGLE) { - type_arg(p); - if !p.at(R_ANGLE) && !p.expect(COMMA) { - break; - } - } - p.expect(R_ANGLE); - m.complete(p, TYPE_ARG_LIST); -} - -// test type_arg -// type A = B<'static, i32, Item=u64> -fn type_arg(p: &mut Parser) { - let m = p.start(); - match p.current() { - LIFETIME => { - p.bump(); - m.complete(p, LIFETIME_ARG); - } - IDENT if p.nth(1) == EQ => { - name_ref(p); - p.bump(); - types::type_(p); - m.complete(p, ASSOC_TYPE_ARG); - } - _ => { - types::type_(p); - m.complete(p, TYPE_ARG); - } - } -} diff --git a/crates/libsyntax2/src/grammar/type_params.rs b/crates/libsyntax2/src/grammar/type_params.rs deleted file mode 100644 index 79bc95ce4..000000000 --- a/crates/libsyntax2/src/grammar/type_params.rs +++ /dev/null @@ -1,136 +0,0 @@ -use super::*; - -pub(super) fn opt_type_param_list(p: &mut Parser) { - if !p.at(L_ANGLE) { - return; - } - let m = p.start(); - p.bump(); - - while !p.at(EOF) && !p.at(R_ANGLE) { - match p.current() { - LIFETIME => lifetime_param(p), - IDENT => type_param(p), - _ => p.err_and_bump("expected type parameter"), - } - if !p.at(R_ANGLE) && !p.expect(COMMA) { - break; - } - } - p.expect(R_ANGLE); - m.complete(p, TYPE_PARAM_LIST); - - fn lifetime_param(p: &mut Parser) { - assert!(p.at(LIFETIME)); - let m = p.start(); - p.bump(); - if p.at(COLON) { - lifetime_bounds(p); - } - m.complete(p, LIFETIME_PARAM); - } - - fn type_param(p: &mut Parser) { - assert!(p.at(IDENT)); - let m = p.start(); - name(p); - if p.at(COLON) { - bounds(p); - } - // test type_param_default - // struct S; - if p.at(EQ) { - p.bump(); - types::type_(p) - } - m.complete(p, TYPE_PARAM); - } -} - -// test type_param_bounds -// struct S; -pub(super) fn bounds(p: &mut Parser) { - assert!(p.at(COLON)); - p.bump(); - bounds_without_colon(p); -} - -fn lifetime_bounds(p: &mut Parser) { - assert!(p.at(COLON)); - p.bump(); - while p.at(LIFETIME) { - p.bump(); - if !p.eat(PLUS) { - break; - } - } -} - -pub(super) fn bounds_without_colon(p: &mut Parser) { - loop { - let has_paren = p.eat(L_PAREN); - p.eat(QUESTION); - match p.current() { - LIFETIME => p.bump(), - FOR_KW => { - types::for_type(p) - } - _ if paths::is_path_start(p) => { - types::path_type(p) - } - _ => break, - } - if has_paren { - p.expect(R_PAREN); - } - if !p.eat(PLUS) { - break; - } - } -} - -// test where_clause -// fn foo() -// where -// 'a: 'b + 'c, -// T: Clone + Copy + 'static, -// Iterator::Item: 'a, -// {} -pub(super) fn opt_where_clause(p: &mut Parser) { - if !p.at(WHERE_KW) { - return; - } - let m = p.start(); - p.bump(); - loop { - if !(paths::is_path_start(p) || p.current() == LIFETIME) { - break - } - where_predicate(p); - if p.current() != L_CURLY && p.current() != SEMI { - p.expect(COMMA); - } - } - m.complete(p, WHERE_CLAUSE); -} - -fn where_predicate(p: &mut Parser) { - let m = p.start(); - if p.at(LIFETIME) { - p.eat(LIFETIME); - if p.at(COLON) { - lifetime_bounds(p) - } else { - p.error("expected colon") - } - } else { - types::path_type(p); - if p.at(COLON) { - bounds(p); - } else { - p.error("expected colon") - } - - } - m.complete(p, WHERE_PRED); -} diff --git a/crates/libsyntax2/src/grammar/types.rs b/crates/libsyntax2/src/grammar/types.rs deleted file mode 100644 index 27e5b086e..000000000 --- a/crates/libsyntax2/src/grammar/types.rs +++ /dev/null @@ -1,247 +0,0 @@ -use super::*; - -pub(super) const TYPE_FIRST: TokenSet = - token_set_union![ - token_set![ - L_PAREN, EXCL, STAR, L_BRACK, AMP, UNDERSCORE, FN_KW, UNSAFE_KW, EXTERN_KW, FOR_KW, IMPL_KW, DYN_KW, L_ANGLE, - ], - paths::PATH_FIRST, - ]; - -const TYPE_RECOVERY_SET: TokenSet = - token_set![R_PAREN, COMMA]; - -pub(super) fn type_(p: &mut Parser) { - match p.current() { - L_PAREN => paren_or_tuple_type(p), - EXCL => never_type(p), - STAR => pointer_type(p), - L_BRACK => array_or_slice_type(p), - AMP => reference_type(p), - UNDERSCORE => placeholder_type(p), - FN_KW | UNSAFE_KW | EXTERN_KW => fn_pointer_type(p), - FOR_KW => for_type(p), - IMPL_KW => impl_trait_type(p), - DYN_KW => dyn_trait_type(p), - L_ANGLE => path_type(p), - _ if paths::is_path_start(p) => path_type(p), - _ => { - p.err_recover("expected type", TYPE_RECOVERY_SET); - } - } -} - -pub(super) fn ascription(p: &mut Parser) { - p.expect(COLON); - type_(p) -} - -fn type_no_plus(p: &mut Parser) { - type_(p); -} - -fn paren_or_tuple_type(p: &mut Parser) { - assert!(p.at(L_PAREN)); - let m = p.start(); - p.bump(); - let mut n_types: u32 = 0; - let mut trailing_comma: bool = false; - while !p.at(EOF) && !p.at(R_PAREN) { - n_types += 1; - type_(p); - if p.eat(COMMA) { - trailing_comma = true; - } else { - trailing_comma = false; - break; - } - } - p.expect(R_PAREN); - - let kind = if n_types == 1 && !trailing_comma { - // test paren_type - // type T = (i32); - PAREN_TYPE - } else { - // test unit_type - // type T = (); - - // test singleton_tuple_type - // type T = (i32,); - TUPLE_TYPE - }; - m.complete(p, kind); -} - -// test never_type -// type Never = !; -fn never_type(p: &mut Parser) { - assert!(p.at(EXCL)); - let m = p.start(); - p.bump(); - m.complete(p, NEVER_TYPE); -} - -fn pointer_type(p: &mut Parser) { - assert!(p.at(STAR)); - let m = p.start(); - p.bump(); - - match p.current() { - // test pointer_type_mut - // type M = *mut (); - // type C = *mut (); - MUT_KW | CONST_KW => p.bump(), - _ => { - // test pointer_type_no_mutability - // type T = *(); - p.error( - "expected mut or const in raw pointer type \ - (use `*mut T` or `*const T` as appropriate)", - ); - } - }; - - type_no_plus(p); - m.complete(p, POINTER_TYPE); -} - -fn array_or_slice_type(p: &mut Parser) { - assert!(p.at(L_BRACK)); - let m = p.start(); - p.bump(); - - type_(p); - let kind = match p.current() { - // test slice_type - // type T = [()]; - R_BRACK => { - p.bump(); - SLICE_TYPE - } - - // test array_type - // type T = [(); 92]; - SEMI => { - p.bump(); - expressions::expr(p); - p.expect(R_BRACK); - ARRAY_TYPE - } - // test array_type_missing_semi - // type T = [() 92]; - _ => { - p.error("expected `;` or `]`"); - SLICE_TYPE - } - }; - m.complete(p, kind); -} - -// test reference_type; -// type A = &(); -// type B = &'static (); -// type C = &mut (); -fn reference_type(p: &mut Parser) { - assert!(p.at(AMP)); - let m = p.start(); - p.bump(); - p.eat(LIFETIME); - p.eat(MUT_KW); - type_no_plus(p); - m.complete(p, REFERENCE_TYPE); -} - -// test placeholder_type -// type Placeholder = _; -fn placeholder_type(p: &mut Parser) { - assert!(p.at(UNDERSCORE)); - let m = p.start(); - p.bump(); - m.complete(p, PLACEHOLDER_TYPE); -} - -// test fn_pointer_type -// type A = fn(); -// type B = unsafe fn(); -// type C = unsafe extern "C" fn(); -fn fn_pointer_type(p: &mut Parser) { - let m = p.start(); - p.eat(UNSAFE_KW); - if p.at(EXTERN_KW) { - abi(p); - } - // test fn_pointer_type_missing_fn - // type F = unsafe (); - if !p.eat(FN_KW) { - m.abandon(p); - p.error("expected `fn`"); - return; - } - if p.at(L_PAREN) { - params::param_list_opt_patterns(p); - } else { - p.error("expected parameters") - } - // test fn_pointer_type_with_ret - // type F = fn() -> (); - opt_fn_ret_type(p); - m.complete(p, FN_POINTER_TYPE); -} - -// test for_type -// type A = for<'a> fn() -> (); -pub(super) fn for_type(p: &mut Parser) { - assert!(p.at(FOR_KW)); - let m = p.start(); - p.bump(); - type_params::opt_type_param_list(p); - match p.current() { - FN_KW | UNSAFE_KW | EXTERN_KW => fn_pointer_type(p), - _ if paths::is_path_start(p) => path_type_(p, false), - _ => p.error("expected a path"), - - } - m.complete(p, FOR_TYPE); -} - -// test impl_trait_type -// type A = impl Iterator> + 'a; -fn impl_trait_type(p: &mut Parser) { - assert!(p.at(IMPL_KW)); - let m = p.start(); - p.bump(); - type_params::bounds_without_colon(p); - m.complete(p, IMPL_TRAIT_TYPE); -} - -// test dyn_trait_type -// type A = dyn Iterator> + 'a; -fn dyn_trait_type(p: &mut Parser) { - assert!(p.at(DYN_KW)); - let m = p.start(); - p.bump(); - type_params::bounds_without_colon(p); - m.complete(p, DYN_TRAIT_TYPE); -} - -// test path_type -// type A = Foo; -// type B = ::Foo; -// type C = self::Foo; -// type D = super::Foo; -pub(super) fn path_type(p: &mut Parser) { - path_type_(p, true) -} - -pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) { - assert!(paths::is_path_start(p) || p.at(L_ANGLE)); - let m = p.start(); - paths::type_path(p); - // test path_type_with_bounds - // fn foo() -> Box {} - if allow_bounds && p.eat(PLUS) { - type_params::bounds_without_colon(p); - } - m.complete(p, PATH_TYPE); -} diff --git a/crates/libsyntax2/src/lexer/classes.rs b/crates/libsyntax2/src/lexer/classes.rs deleted file mode 100644 index 4235d2648..000000000 --- a/crates/libsyntax2/src/lexer/classes.rs +++ /dev/null @@ -1,26 +0,0 @@ -use unicode_xid::UnicodeXID; - -pub fn is_ident_start(c: char) -> bool { - (c >= 'a' && c <= 'z') - || (c >= 'A' && c <= 'Z') - || c == '_' - || (c > '\x7f' && UnicodeXID::is_xid_start(c)) -} - -pub fn is_ident_continue(c: char) -> bool { - (c >= 'a' && c <= 'z') - || (c >= 'A' && c <= 'Z') - || (c >= '0' && c <= '9') - || c == '_' - || (c > '\x7f' && UnicodeXID::is_xid_continue(c)) -} - -pub fn is_whitespace(c: char) -> bool { - //FIXME: use is_pattern_whitespace - //https://github.com/behnam/rust-unic/issues/192 - c.is_whitespace() -} - -pub fn is_dec_digit(c: char) -> bool { - '0' <= c && c <= '9' -} diff --git a/crates/libsyntax2/src/lexer/comments.rs b/crates/libsyntax2/src/lexer/comments.rs deleted file mode 100644 index eb417c2dc..000000000 --- a/crates/libsyntax2/src/lexer/comments.rs +++ /dev/null @@ -1,57 +0,0 @@ -use lexer::ptr::Ptr; - -use SyntaxKind::{self, *}; - -pub(crate) fn scan_shebang(ptr: &mut Ptr) -> bool { - if ptr.at_str("!/") { - ptr.bump(); - ptr.bump(); - bump_until_eol(ptr); - true - } else { - false - } -} - -fn scan_block_comment(ptr: &mut Ptr) -> Option { - if ptr.at('*') { - ptr.bump(); - let mut depth: u32 = 1; - while depth > 0 { - if ptr.at_str("*/") { - depth -= 1; - ptr.bump(); - ptr.bump(); - } else if ptr.at_str("/*") { - depth += 1; - ptr.bump(); - ptr.bump(); - } else if ptr.bump().is_none() { - break; - } - } - Some(COMMENT) - } else { - None - } -} - -pub(crate) fn scan_comment(ptr: &mut Ptr) -> Option { - if ptr.at('/') { - bump_until_eol(ptr); - Some(COMMENT) - } else { - scan_block_comment(ptr) - } -} - -fn bump_until_eol(ptr: &mut Ptr) { - loop { - if ptr.at('\n') || ptr.at_str("\r\n") { - return; - } - if ptr.bump().is_none() { - break; - } - } -} diff --git a/crates/libsyntax2/src/lexer/mod.rs b/crates/libsyntax2/src/lexer/mod.rs deleted file mode 100644 index 3e11db88b..000000000 --- a/crates/libsyntax2/src/lexer/mod.rs +++ /dev/null @@ -1,209 +0,0 @@ -mod classes; -mod comments; -mod numbers; -mod ptr; -mod strings; - -use { - SyntaxKind::{self, *}, - TextUnit, -}; - -use self::{ - classes::*, - comments::{scan_comment, scan_shebang}, - numbers::scan_number, - ptr::Ptr, - strings::{ - is_string_literal_start, scan_byte_char_or_string, scan_char, scan_raw_string, scan_string, - }, -}; - -/// A token of Rust source. -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct Token { - /// The kind of token. - pub kind: SyntaxKind, - /// The length of the token. - pub len: TextUnit, -} - -/// Break a string up into its component tokens -pub fn tokenize(text: &str) -> Vec { - let mut text = text; - let mut acc = Vec::new(); - while !text.is_empty() { - let token = next_token(text); - acc.push(token); - let len: u32 = token.len.into(); - text = &text[len as usize..]; - } - acc -} - -/// Get the next token from a string -pub fn next_token(text: &str) -> Token { - assert!(!text.is_empty()); - let mut ptr = Ptr::new(text); - let c = ptr.bump().unwrap(); - let kind = next_token_inner(c, &mut ptr); - let len = ptr.into_len(); - Token { kind, len } -} - -fn next_token_inner(c: char, ptr: &mut Ptr) -> SyntaxKind { - if is_whitespace(c) { - ptr.bump_while(is_whitespace); - return WHITESPACE; - } - - match c { - '#' => if scan_shebang(ptr) { - return SHEBANG; - }, - '/' => if let Some(kind) = scan_comment(ptr) { - return kind; - }, - _ => (), - } - - let ident_start = is_ident_start(c) && !is_string_literal_start(c, ptr.current(), ptr.nth(1)); - if ident_start { - return scan_ident(c, ptr); - } - - if is_dec_digit(c) { - let kind = scan_number(c, ptr); - scan_literal_suffix(ptr); - return kind; - } - - // One-byte tokens. - if let Some(kind) = SyntaxKind::from_char(c) { - return kind; - } - - match c { - // Multi-byte tokens. - '.' => { - return match (ptr.current(), ptr.nth(1)) { - (Some('.'), Some('.')) => { - ptr.bump(); - ptr.bump(); - DOTDOTDOT - } - (Some('.'), Some('=')) => { - ptr.bump(); - ptr.bump(); - DOTDOTEQ - } - (Some('.'), _) => { - ptr.bump(); - DOTDOT - } - _ => DOT, - }; - } - ':' => { - return match ptr.current() { - Some(':') => { - ptr.bump(); - COLONCOLON - } - _ => COLON, - }; - } - '=' => { - return match ptr.current() { - Some('=') => { - ptr.bump(); - EQEQ - } - Some('>') => { - ptr.bump(); - FAT_ARROW - } - _ => EQ, - }; - } - '!' => { - return match ptr.current() { - Some('=') => { - ptr.bump(); - NEQ - } - _ => EXCL, - }; - } - '-' => { - return if ptr.at('>') { - ptr.bump(); - THIN_ARROW - } else { - MINUS - }; - } - - // If the character is an ident start not followed by another single - // quote, then this is a lifetime name: - '\'' => { - return if ptr.at_p(is_ident_start) && !ptr.at_str("''") { - ptr.bump(); - while ptr.at_p(is_ident_continue) { - ptr.bump(); - } - // lifetimes shouldn't end with a single quote - // if we find one, then this is an invalid character literal - if ptr.at('\'') { - ptr.bump(); - return CHAR; // TODO: error reporting - } - LIFETIME - } else { - scan_char(ptr); - scan_literal_suffix(ptr); - CHAR - }; - } - 'b' => { - let kind = scan_byte_char_or_string(ptr); - scan_literal_suffix(ptr); - return kind; - } - '"' => { - scan_string(ptr); - scan_literal_suffix(ptr); - return STRING; - } - 'r' => { - scan_raw_string(ptr); - scan_literal_suffix(ptr); - return RAW_STRING; - } - _ => (), - } - ERROR -} - -fn scan_ident(c: char, ptr: &mut Ptr) -> SyntaxKind { - let is_single_letter = match ptr.current() { - None => true, - Some(c) if !is_ident_continue(c) => true, - _ => false, - }; - if is_single_letter { - return if c == '_' { UNDERSCORE } else { IDENT }; - } - ptr.bump_while(is_ident_continue); - if let Some(kind) = SyntaxKind::from_keyword(ptr.current_token_text()) { - return kind; - } - IDENT -} - -fn scan_literal_suffix(ptr: &mut Ptr) { - if ptr.at_p(is_ident_start) { - ptr.bump(); - } - ptr.bump_while(is_ident_continue); -} diff --git a/crates/libsyntax2/src/lexer/numbers.rs b/crates/libsyntax2/src/lexer/numbers.rs deleted file mode 100644 index 22e7d4e99..000000000 --- a/crates/libsyntax2/src/lexer/numbers.rs +++ /dev/null @@ -1,67 +0,0 @@ -use lexer::classes::*; -use lexer::ptr::Ptr; - -use SyntaxKind::{self, *}; - -pub(crate) fn scan_number(c: char, ptr: &mut Ptr) -> SyntaxKind { - if c == '0' { - match ptr.current().unwrap_or('\0') { - 'b' | 'o' => { - ptr.bump(); - scan_digits(ptr, false); - } - 'x' => { - ptr.bump(); - scan_digits(ptr, true); - } - '0'...'9' | '_' | '.' | 'e' | 'E' => { - scan_digits(ptr, true); - } - _ => return INT_NUMBER, - } - } else { - scan_digits(ptr, false); - } - - // might be a float, but don't be greedy if this is actually an - // integer literal followed by field/method access or a range pattern - // (`0..2` and `12.foo()`) - if ptr.at('.') && !(ptr.at_str("..") || ptr.nth_is_p(1, is_ident_start)) { - // might have stuff after the ., and if it does, it needs to start - // with a number - ptr.bump(); - scan_digits(ptr, false); - scan_float_exponent(ptr); - return FLOAT_NUMBER; - } - // it might be a float if it has an exponent - if ptr.at('e') || ptr.at('E') { - scan_float_exponent(ptr); - return FLOAT_NUMBER; - } - INT_NUMBER -} - -fn scan_digits(ptr: &mut Ptr, allow_hex: bool) { - while let Some(c) = ptr.current() { - match c { - '_' | '0'...'9' => { - ptr.bump(); - } - 'a'...'f' | 'A'...'F' if allow_hex => { - ptr.bump(); - } - _ => return, - } - } -} - -fn scan_float_exponent(ptr: &mut Ptr) { - if ptr.at('e') || ptr.at('E') { - ptr.bump(); - if ptr.at('-') || ptr.at('+') { - ptr.bump(); - } - scan_digits(ptr, false); - } -} diff --git a/crates/libsyntax2/src/lexer/ptr.rs b/crates/libsyntax2/src/lexer/ptr.rs deleted file mode 100644 index c9a5354ea..000000000 --- a/crates/libsyntax2/src/lexer/ptr.rs +++ /dev/null @@ -1,166 +0,0 @@ -use TextUnit; - -use std::str::Chars; - -/// A simple view into the characters of a string. -pub(crate) struct Ptr<'s> { - text: &'s str, - len: TextUnit, -} - -impl<'s> Ptr<'s> { - /// Creates a new `Ptr` from a string. - pub fn new(text: &'s str) -> Ptr<'s> { - Ptr { - text, - len: 0.into(), - } - } - - /// Gets the length of the remaining string. - pub fn into_len(self) -> TextUnit { - self.len - } - - /// Gets the current character, if one exists. - pub fn current(&self) -> Option { - self.chars().next() - } - - /// Gets the nth character from the current. - /// For example, 0 will return the current token, 1 will return the next, etc. - pub fn nth(&self, n: u32) -> Option { - let mut chars = self.chars().peekable(); - chars.by_ref().skip(n as usize).next() - } - - /// Checks whether the current character is `c`. - pub fn at(&self, c: char) -> bool { - self.current() == Some(c) - } - - /// Checks whether the next characters match `s`. - pub fn at_str(&self, s: &str) -> bool { - let chars = self.chars(); - chars.as_str().starts_with(s) - } - - /// Checks whether the current character satisfies the predicate `p`. - pub fn at_p bool>(&self, p: P) -> bool { - self.current().map(p) == Some(true) - } - - /// Checks whether the nth character satisfies the predicate `p`. - pub fn nth_is_p bool>(&self, n: u32, p: P) -> bool { - self.nth(n).map(p) == Some(true) - } - - /// Moves to the next character. - pub fn bump(&mut self) -> Option { - let ch = self.chars().next()?; - self.len += TextUnit::of_char(ch); - Some(ch) - } - - /// Moves to the next character as long as `pred` is satisfied. - pub fn bump_while bool>(&mut self, pred: F) { - loop { - match self.current() { - Some(c) if pred(c) => { - self.bump(); - } - _ => return, - } - } - } - - /// Returns the text up to the current point. - pub fn current_token_text(&self) -> &str { - let len: u32 = self.len.into(); - &self.text[..len as usize] - } - - /// Returns an iterator over the remaining characters. - fn chars(&self) -> Chars { - let len: u32 = self.len.into(); - self.text[len as usize..].chars() - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_current() { - let ptr = Ptr::new("test"); - assert_eq!(ptr.current(), Some('t')); - } - - #[test] - fn test_nth() { - let ptr = Ptr::new("test"); - assert_eq!(ptr.nth(0), Some('t')); - assert_eq!(ptr.nth(1), Some('e')); - assert_eq!(ptr.nth(2), Some('s')); - assert_eq!(ptr.nth(3), Some('t')); - assert_eq!(ptr.nth(4), None); - } - - #[test] - fn test_at() { - let ptr = Ptr::new("test"); - assert!(ptr.at('t')); - assert!(!ptr.at('a')); - } - - #[test] - fn test_at_str() { - let ptr = Ptr::new("test"); - assert!(ptr.at_str("t")); - assert!(ptr.at_str("te")); - assert!(ptr.at_str("test")); - assert!(!ptr.at_str("tests")); - assert!(!ptr.at_str("rust")); - } - - #[test] - fn test_at_p() { - let ptr = Ptr::new("test"); - assert!(ptr.at_p(|c| c == 't')); - assert!(!ptr.at_p(|c| c == 'e')); - } - - #[test] - fn test_nth_is_p() { - let ptr = Ptr::new("test"); - assert!(ptr.nth_is_p(0,|c| c == 't')); - assert!(!ptr.nth_is_p(1,|c| c == 't')); - assert!(ptr.nth_is_p(3,|c| c == 't')); - assert!(!ptr.nth_is_p(150,|c| c == 't')); - } - - #[test] - fn test_bump() { - let mut ptr = Ptr::new("test"); - assert_eq!(ptr.current(), Some('t')); - ptr.bump(); - assert_eq!(ptr.current(), Some('e')); - ptr.bump(); - assert_eq!(ptr.current(), Some('s')); - ptr.bump(); - assert_eq!(ptr.current(), Some('t')); - ptr.bump(); - assert_eq!(ptr.current(), None); - ptr.bump(); - assert_eq!(ptr.current(), None); - } - - #[test] - fn test_bump_while() { - let mut ptr = Ptr::new("test"); - assert_eq!(ptr.current(), Some('t')); - ptr.bump_while(|c| c != 's'); - assert_eq!(ptr.current(), Some('s')); - } -} diff --git a/crates/libsyntax2/src/lexer/strings.rs b/crates/libsyntax2/src/lexer/strings.rs deleted file mode 100644 index 5ff483d14..000000000 --- a/crates/libsyntax2/src/lexer/strings.rs +++ /dev/null @@ -1,123 +0,0 @@ -use SyntaxKind::{self, *}; - -use lexer::ptr::Ptr; - -pub(crate) fn is_string_literal_start(c: char, c1: Option, c2: Option) -> bool { - match (c, c1, c2) { - ('r', Some('"'), _) - | ('r', Some('#'), _) - | ('b', Some('"'), _) - | ('b', Some('\''), _) - | ('b', Some('r'), Some('"')) - | ('b', Some('r'), Some('#')) => true, - _ => false, - } -} - -pub(crate) fn scan_char(ptr: &mut Ptr) { - while let Some(c) = ptr.current() { - match c { - '\\' => { - ptr.bump(); - if ptr.at('\\') || ptr.at('\'') { - ptr.bump(); - } - } - '\'' => { - ptr.bump(); - return; - } - '\n' => return, - _ => { - ptr.bump(); - } - } - } -} - -pub(crate) fn scan_byte_char_or_string(ptr: &mut Ptr) -> SyntaxKind { - // unwrapping and not-exhaustive match are ok - // because of string_literal_start - let c = ptr.bump().unwrap(); - match c { - '\'' => { - scan_byte(ptr); - BYTE - } - '"' => { - scan_byte_string(ptr); - BYTE_STRING - } - 'r' => { - scan_raw_byte_string(ptr); - RAW_BYTE_STRING - } - _ => unreachable!(), - } -} - -pub(crate) fn scan_string(ptr: &mut Ptr) { - while let Some(c) = ptr.current() { - match c { - '\\' => { - ptr.bump(); - if ptr.at('\\') || ptr.at('"') { - ptr.bump(); - } - } - '"' => { - ptr.bump(); - return; - } - _ => { - ptr.bump(); - }, - } - } -} - -pub(crate) fn scan_raw_string(ptr: &mut Ptr) { - let mut hashes = 0; - while ptr.at('#') { - hashes += 1; - ptr.bump(); - } - if !ptr.at('"') { - return; - } - ptr.bump(); - - while let Some(c) = ptr.bump() { - if c == '"' { - let mut hashes_left = hashes; - while ptr.at('#') && hashes_left > 0{ - hashes_left -= 1; - ptr.bump(); - } - if hashes_left == 0 { - return; - } - } - } -} - -fn scan_byte(ptr: &mut Ptr) { - scan_char(ptr) -} - -fn scan_byte_string(ptr: &mut Ptr) { - scan_string(ptr) -} - -fn scan_raw_byte_string(ptr: &mut Ptr) { - if !ptr.at('"') { - return; - } - ptr.bump(); - - while let Some(c) = ptr.bump() { - if c == '"' { - return; - } - } -} diff --git a/crates/libsyntax2/src/lib.rs b/crates/libsyntax2/src/lib.rs deleted file mode 100644 index eb271762e..000000000 --- a/crates/libsyntax2/src/lib.rs +++ /dev/null @@ -1,105 +0,0 @@ -//! An experimental implementation of [Rust RFC#2256 libsyntax2.0][rfc#2256]. -//! -//! The intent is to be an IDE-ready parser, i.e. one that offers -//! -//! - easy and fast incremental re-parsing, -//! - graceful handling of errors, and -//! - maintains all information in the source file. -//! -//! For more information, see [the RFC][rfc#2265], or [the working draft][RFC.md]. -//! -//! [rfc#2256]: -//! [RFC.md]: - -#![forbid( - missing_debug_implementations, - unconditional_recursion, - future_incompatible -)] -#![deny(bad_style, missing_docs)] -#![allow(missing_docs)] -//#![warn(unreachable_pub)] // rust-lang/rust#47816 - -extern crate itertools; -extern crate unicode_xid; -extern crate drop_bomb; -extern crate parking_lot; -extern crate smol_str; -extern crate text_unit; - -#[cfg(test)] -#[macro_use] -extern crate test_utils; - -pub mod algo; -pub mod ast; -mod lexer; -#[macro_use] -mod token_set; -mod parser_api; -mod grammar; -mod parser_impl; -mod reparsing; - -mod syntax_kinds; -mod yellow; -/// Utilities for simple uses of the parser. -pub mod utils; -pub mod text_utils; - -pub use { - text_unit::{TextRange, TextUnit}, - smol_str::SmolStr, - ast::AstNode, - lexer::{tokenize, Token}, - syntax_kinds::SyntaxKind, - yellow::{SyntaxNode, SyntaxNodeRef, OwnedRoot, RefRoot, TreeRoot, SyntaxError}, - reparsing::AtomEdit, -}; - -use { - yellow::{GreenNode, SyntaxRoot}, -}; - -#[derive(Clone, Debug, Hash)] -pub struct File { - root: SyntaxNode -} - -impl File { - fn new(green: GreenNode, errors: Vec) -> File { - let root = SyntaxRoot::new(green, errors); - let root = SyntaxNode::new_owned(root); - if cfg!(debug_assertions) { - utils::validate_block_structure(root.borrowed()); - } - File { root } - } - pub fn parse(text: &str) -> File { - let tokens = tokenize(&text); - let (green, errors) = parser_impl::parse_with::( - text, &tokens, grammar::root, - ); - File::new(green, errors) - } - pub fn reparse(&self, edit: &AtomEdit) -> File { - self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit)) - } - pub fn incremental_reparse(&self, edit: &AtomEdit) -> Option { - reparsing::incremental_reparse(self.syntax(), edit, self.errors()) - .map(|(green_node, errors)| File::new(green_node, errors)) - } - fn full_reparse(&self, edit: &AtomEdit) -> File { - let text = text_utils::replace_range(self.syntax().text().to_string(), edit.delete, &edit.insert); - File::parse(&text) - } - pub fn ast(&self) -> ast::Root { - ast::Root::cast(self.syntax()).unwrap() - } - pub fn syntax(&self) -> SyntaxNodeRef { - self.root.borrowed() - } - pub fn errors(&self) -> Vec { - self.syntax().root.syntax_root().errors.clone() - } -} diff --git a/crates/libsyntax2/src/parser_api.rs b/crates/libsyntax2/src/parser_api.rs deleted file mode 100644 index 772d753af..000000000 --- a/crates/libsyntax2/src/parser_api.rs +++ /dev/null @@ -1,178 +0,0 @@ -use { - token_set::TokenSet, - parser_impl::ParserImpl, - SyntaxKind::{self, ERROR}, - drop_bomb::DropBomb, -}; - -/// `Parser` struct provides the low-level API for -/// navigating through the stream of tokens and -/// constructing the parse tree. The actual parsing -/// happens in the `grammar` module. -/// -/// However, the result of this `Parser` is not a real -/// tree, but rather a flat stream of events of the form -/// "start expression, consume number literal, -/// finish expression". See `Event` docs for more. -pub(crate) struct Parser<'t>(pub(super) ParserImpl<'t>); - -impl<'t> Parser<'t> { - /// Returns the kind of the current token. - /// If parser has already reached the end of input, - /// the special `EOF` kind is returned. - pub(crate) fn current(&self) -> SyntaxKind { - self.nth(0) - } - - /// Lookahead operation: returns the kind of the next nth - /// token. - pub(crate) fn nth(&self, n: u32) -> SyntaxKind { - self.0.nth(n) - } - - /// Checks if the current token is `kind`. - pub(crate) fn at(&self, kind: SyntaxKind) -> bool { - self.current() == kind - } - - /// Checks if the current token is `kind`. - pub(crate) fn at_ts(&self, kinds: TokenSet) -> bool { - kinds.contains(self.current()) - } - - pub(crate) fn next2(&self) -> Option<(SyntaxKind, SyntaxKind)> { - self.0.next2() - } - - pub(crate) fn next3(&self) -> Option<(SyntaxKind, SyntaxKind, SyntaxKind)> { - self.0.next3() - } - - /// Checks if the current token is contextual keyword with text `t`. - pub(crate) fn at_contextual_kw(&self, t: &str) -> bool { - self.0.at_kw(t) - } - - /// Starts a new node in the syntax tree. All nodes and tokens - /// consumed between the `start` and the corresponding `Marker::complete` - /// belong to the same node. - pub(crate) fn start(&mut self) -> Marker { - Marker::new(self.0.start()) - } - - /// Advances the parser by one token. - pub(crate) fn bump(&mut self) { - self.0.bump(); - } - - /// Advances the parser by one token, remapping its kind. - /// This is useful to create contextual keywords from - /// identifiers. For example, the lexer creates an `union` - /// *identifier* token, but the parser remaps it to the - /// `union` keyword, and keyword is what ends up in the - /// final tree. - pub(crate) fn bump_remap(&mut self, kind: SyntaxKind) { - self.0.bump_remap(kind); - } - - /// Advances the parser by `n` tokens, remapping its kind. - /// This is useful to create compound tokens from parts. For - /// example, an `<<` token is two consecutive remapped `<` tokens - pub(crate) fn bump_compound(&mut self, kind: SyntaxKind, n: u8) { - self.0.bump_compound(kind, n); - } - - /// Emit error with the `message` - /// TODO: this should be much more fancy and support - /// structured errors with spans and notes, like rustc - /// does. - pub(crate) fn error>(&mut self, message: T) { - self.0.error(message.into()) - } - - /// Consume the next token if it is `kind`. - pub(crate) fn eat(&mut self, kind: SyntaxKind) -> bool { - if !self.at(kind) { - return false; - } - self.bump(); - true - } - - /// Consume the next token if it is `kind` or emit an error - /// otherwise. - pub(crate) fn expect(&mut self, kind: SyntaxKind) -> bool { - if self.eat(kind) { - return true; - } - self.error(format!("expected {:?}", kind)); - false - } - - /// Create an error node and consume the next token. - pub(crate) fn err_and_bump(&mut self, message: &str) { - self.err_recover(message, TokenSet::EMPTY); - } - - /// Create an error node and consume the next token. - pub(crate) fn err_recover(&mut self, message: &str, recovery: TokenSet) { - if self.at(SyntaxKind::L_CURLY) - || self.at(SyntaxKind::R_CURLY) - || self.at_ts(recovery) { - self.error(message); - } else { - let m = self.start(); - self.error(message); - self.bump(); - m.complete(self, ERROR); - }; - } -} - -/// See `Parser::start`. -pub(crate) struct Marker { - pos: u32, - bomb: DropBomb, -} - -impl Marker { - fn new(pos: u32) -> Marker { - Marker { - pos, - bomb: DropBomb::new("Marker must be either completed or abandoned"), - } - } - - /// Finishes the syntax tree node and assigns `kind` to it. - pub(crate) fn complete(mut self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker { - self.bomb.defuse(); - p.0.complete(self.pos, kind); - CompletedMarker(self.pos, kind) - } - - /// Abandons the syntax tree node. All its children - /// are attached to its parent instead. - pub(crate) fn abandon(mut self, p: &mut Parser) { - self.bomb.defuse(); - p.0.abandon(self.pos); - } -} - -pub(crate) struct CompletedMarker(u32, SyntaxKind); - -impl CompletedMarker { - /// This one is tricky :-) - /// This method allows to create a new node which starts - /// *before* the current one. That is, parser could start - /// node `A`, then complete it, and then after parsing the - /// whole `A`, decide that it should have started some node - /// `B` before starting `A`. `precede` allows to do exactly - /// that. See also docs about `forward_parent` in `Event::Start`. - pub(crate) fn precede(self, p: &mut Parser) -> Marker { - Marker::new(p.0.precede(self.0)) - } - - pub(crate) fn kind(&self) -> SyntaxKind { - self.1 - } -} diff --git a/crates/libsyntax2/src/parser_impl/event.rs b/crates/libsyntax2/src/parser_impl/event.rs deleted file mode 100644 index 9fd56b996..000000000 --- a/crates/libsyntax2/src/parser_impl/event.rs +++ /dev/null @@ -1,154 +0,0 @@ -//! This module provides a way to construct a `File`. -//! It is intended to be completely decoupled from the -//! parser, so as to allow to evolve the tree representation -//! and the parser algorithm independently. -//! -//! The `Sink` trait is the bridge between the parser and the -//! tree builder: the parser produces a stream of events like -//! `start node`, `finish node`, and `FileBuilder` converts -//! this stream to a real tree. -use std::mem; -use { - lexer::Token, - parser_impl::Sink, - SyntaxKind::{self, TOMBSTONE}, -}; - - -/// `Parser` produces a flat list of `Event`s. -/// They are converted to a tree-structure in -/// a separate pass, via `TreeBuilder`. -#[derive(Debug)] -pub(crate) enum Event { - /// This event signifies the start of the node. - /// It should be either abandoned (in which case the - /// `kind` is `TOMBSTONE`, and the event is ignored), - /// or completed via a `Finish` event. - /// - /// All tokens between a `Start` and a `Finish` would - /// become the children of the respective node. - /// - /// For left-recursive syntactic constructs, the parser produces - /// a child node before it sees a parent. `forward_parent` - /// exists to allow to tweak parent-child relationships. - /// - /// Consider this path - /// - /// foo::bar - /// - /// The events for it would look like this: - /// - /// - /// START(PATH) IDENT('foo') FINISH START(PATH) COLONCOLON IDENT('bar') FINISH - /// | /\ - /// | | - /// +------forward-parent------+ - /// - /// And the tree would look like this - /// - /// +--PATH---------+ - /// | | | - /// | | | - /// | '::' 'bar' - /// | - /// PATH - /// | - /// 'foo' - /// - /// See also `CompletedMarker::precede`. - Start { - kind: SyntaxKind, - forward_parent: Option, - }, - - /// Complete the previous `Start` event - Finish, - - /// Produce a single leaf-element. - /// `n_raw_tokens` is used to glue complex contextual tokens. - /// For example, lexer tokenizes `>>` as `>`, `>`, and - /// `n_raw_tokens = 2` is used to produced a single `>>`. - Token { - kind: SyntaxKind, - n_raw_tokens: u8, - }, - - Error { - msg: String, - }, -} - - -pub(super) fn process<'a, S: Sink<'a>>(builder: &mut S, tokens: &[Token], mut events: Vec) { - fn tombstone() -> Event { - Event::Start { kind: TOMBSTONE, forward_parent: None } - } - let eat_ws = |idx: &mut usize, builder: &mut S| { - while let Some(token) = tokens.get(*idx) { - if !token.kind.is_trivia() { - break; - } - builder.leaf(token.kind, token.len); - *idx += 1 - } - }; - - let events: &mut [Event] = &mut events; - let mut depth = 0; - let mut forward_parents = Vec::new(); - let mut next_tok_idx = 0; - for i in 0..events.len() { - match mem::replace(&mut events[i], tombstone()) { - Event::Start { - kind: TOMBSTONE, .. - } => (), - - Event::Start { kind, forward_parent } => { - forward_parents.push(kind); - let mut idx = i; - let mut fp = forward_parent; - while let Some(fwd) = fp { - idx += fwd as usize; - fp = match mem::replace(&mut events[idx], tombstone()) { - Event::Start { - kind, - forward_parent, - } => { - forward_parents.push(kind); - forward_parent - }, - _ => unreachable!(), - }; - } - for kind in forward_parents.drain(..).rev() { - if depth > 0 { - eat_ws(&mut next_tok_idx, builder); - } - depth += 1; - builder.start_internal(kind); - } - } - Event::Finish => { - depth -= 1; - if depth == 0 { - eat_ws(&mut next_tok_idx, builder); - } - - builder.finish_internal(); - } - Event::Token { - kind, - mut n_raw_tokens, - } => { - eat_ws(&mut next_tok_idx, builder); - let mut len = 0.into(); - for _ in 0..n_raw_tokens { - len += tokens[next_tok_idx].len; - next_tok_idx += 1; - } - builder.leaf(kind, len); - } - Event::Error { msg } => builder.error(msg), - } - } -} diff --git a/crates/libsyntax2/src/parser_impl/input.rs b/crates/libsyntax2/src/parser_impl/input.rs deleted file mode 100644 index c0fe4d488..000000000 --- a/crates/libsyntax2/src/parser_impl/input.rs +++ /dev/null @@ -1,86 +0,0 @@ -use {lexer::Token, SyntaxKind, SyntaxKind::EOF, TextRange, TextUnit}; - -use std::ops::{Add, AddAssign}; - -pub(crate) struct ParserInput<'t> { - text: &'t str, - start_offsets: Vec, - tokens: Vec, // non-whitespace tokens -} - -impl<'t> ParserInput<'t> { - pub fn new(text: &'t str, raw_tokens: &'t [Token]) -> ParserInput<'t> { - let mut tokens = Vec::new(); - let mut start_offsets = Vec::new(); - let mut len = 0.into(); - for &token in raw_tokens.iter() { - if !token.kind.is_trivia() { - tokens.push(token); - start_offsets.push(len); - } - len += token.len; - } - - ParserInput { - text, - start_offsets, - tokens, - } - } - - pub fn kind(&self, pos: InputPosition) -> SyntaxKind { - let idx = pos.0 as usize; - if !(idx < self.tokens.len()) { - return EOF; - } - self.tokens[idx].kind - } - - pub fn len(&self, pos: InputPosition) -> TextUnit { - let idx = pos.0 as usize; - if !(idx < self.tokens.len()) { - return 0.into(); - } - self.tokens[idx].len - } - - pub fn start(&self, pos: InputPosition) -> TextUnit { - let idx = pos.0 as usize; - if !(idx < self.tokens.len()) { - return 0.into(); - } - self.start_offsets[idx] - } - - pub fn text(&self, pos: InputPosition) -> &'t str { - let idx = pos.0 as usize; - if !(idx < self.tokens.len()) { - return ""; - } - let range = TextRange::offset_len(self.start_offsets[idx], self.tokens[idx].len); - &self.text[range] - } -} - -#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] -pub(crate) struct InputPosition(u32); - -impl InputPosition { - pub fn new() -> Self { - InputPosition(0) - } -} - -impl Add for InputPosition { - type Output = InputPosition; - - fn add(self, rhs: u32) -> InputPosition { - InputPosition(self.0 + rhs) - } -} - -impl AddAssign for InputPosition { - fn add_assign(&mut self, rhs: u32) { - self.0 += rhs - } -} diff --git a/crates/libsyntax2/src/parser_impl/mod.rs b/crates/libsyntax2/src/parser_impl/mod.rs deleted file mode 100644 index b343b404f..000000000 --- a/crates/libsyntax2/src/parser_impl/mod.rs +++ /dev/null @@ -1,194 +0,0 @@ -mod event; -mod input; - -use std::cell::Cell; - -use { - lexer::Token, - parser_api::Parser, - parser_impl::{ - event::{process, Event}, - input::{InputPosition, ParserInput}, - }, - TextUnit, -}; - -use SyntaxKind::{self, EOF, TOMBSTONE}; - -pub(crate) trait Sink<'a> { - type Tree; - - fn new(text: &'a str) -> Self; - - fn leaf(&mut self, kind: SyntaxKind, len: TextUnit); - fn start_internal(&mut self, kind: SyntaxKind); - fn finish_internal(&mut self); - fn error(&mut self, err: String); - fn finish(self) -> Self::Tree; -} - -/// Parse a sequence of tokens into the representative node tree -pub(crate) fn parse_with<'a, S: Sink<'a>>( - text: &'a str, - tokens: &[Token], - parser: fn(&mut Parser), -) -> S::Tree { - let events = { - let input = input::ParserInput::new(text, tokens); - let parser_impl = ParserImpl::new(&input); - let mut parser_api = Parser(parser_impl); - parser(&mut parser_api); - parser_api.0.into_events() - }; - let mut sink = S::new(text); - process(&mut sink, tokens, events); - sink.finish() -} - -/// Implementation details of `Parser`, extracted -/// to a separate struct in order not to pollute -/// the public API of the `Parser`. -pub(crate) struct ParserImpl<'t> { - inp: &'t ParserInput<'t>, - - pos: InputPosition, - events: Vec, - steps: Cell, -} - -impl<'t> ParserImpl<'t> { - pub(crate) fn new(inp: &'t ParserInput<'t>) -> ParserImpl<'t> { - ParserImpl { - inp, - - pos: InputPosition::new(), - events: Vec::new(), - steps: Cell::new(0), - } - } - - pub(crate) fn into_events(self) -> Vec { - assert_eq!(self.nth(0), EOF); - self.events - } - - pub(super) fn next2(&self) -> Option<(SyntaxKind, SyntaxKind)> { - let c1 = self.inp.kind(self.pos); - let c2 = self.inp.kind(self.pos + 1); - if self.inp.start(self.pos + 1) == self.inp.start(self.pos) + self.inp.len(self.pos) { - Some((c1, c2)) - } else { - None - } - } - - pub(super) fn next3(&self) -> Option<(SyntaxKind, SyntaxKind, SyntaxKind)> { - let c1 = self.inp.kind(self.pos); - let c2 = self.inp.kind(self.pos + 1); - let c3 = self.inp.kind(self.pos + 2); - if self.inp.start(self.pos + 1) == self.inp.start(self.pos) + self.inp.len(self.pos) - && self.inp.start(self.pos + 2) == self.inp.start(self.pos + 1) + self.inp.len(self.pos + 1){ - Some((c1, c2, c3)) - } else { - None - } - } - - pub(super) fn nth(&self, n: u32) -> SyntaxKind { - let steps = self.steps.get(); - if steps > 10_000_000 { - panic!("the parser seems stuck"); - } - self.steps.set(steps + 1); - - self.inp.kind(self.pos + n) - } - - pub(super) fn at_kw(&self, t: &str) -> bool { - self.inp.text(self.pos) == t - } - - pub(super) fn start(&mut self) -> u32 { - let pos = self.events.len() as u32; - self.event(Event::Start { - kind: TOMBSTONE, - forward_parent: None, - }); - pos - } - - pub(super) fn bump(&mut self) { - let kind = self.nth(0); - if kind == EOF { - return; - } - self.do_bump(kind, 1); - } - - pub(super) fn bump_remap(&mut self, kind: SyntaxKind) { - if self.nth(0) == EOF { - // TODO: panic!? - return; - } - self.do_bump(kind, 1); - } - - pub(super) fn bump_compound(&mut self, kind: SyntaxKind, n: u8) { - self.do_bump(kind, n); - } - - fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) { - self.pos += u32::from(n_raw_tokens); - self.event(Event::Token { - kind, - n_raw_tokens, - }); - } - - pub(super) fn error(&mut self, msg: String) { - self.event(Event::Error { msg }) - } - - pub(super) fn complete(&mut self, pos: u32, kind: SyntaxKind) { - match self.events[pos as usize] { - Event::Start { - kind: ref mut slot, .. - } => { - *slot = kind; - } - _ => unreachable!(), - } - self.event(Event::Finish); - } - - pub(super) fn abandon(&mut self, pos: u32) { - let idx = pos as usize; - if idx == self.events.len() - 1 { - match self.events.pop() { - Some(Event::Start { - kind: TOMBSTONE, - forward_parent: None, - }) => (), - _ => unreachable!(), - } - } - } - - pub(super) fn precede(&mut self, pos: u32) -> u32 { - let new_pos = self.start(); - match self.events[pos as usize] { - Event::Start { - ref mut forward_parent, - .. - } => { - *forward_parent = Some(new_pos - pos); - } - _ => unreachable!(), - } - new_pos - } - - fn event(&mut self, event: Event) { - self.events.push(event) - } -} diff --git a/crates/libsyntax2/src/reparsing.rs b/crates/libsyntax2/src/reparsing.rs deleted file mode 100644 index da44913c5..000000000 --- a/crates/libsyntax2/src/reparsing.rs +++ /dev/null @@ -1,343 +0,0 @@ -use algo; -use grammar; -use lexer::{tokenize, Token}; -use text_unit::{TextRange, TextUnit}; -use yellow::{self, SyntaxNodeRef, GreenNode, SyntaxError}; -use parser_impl; -use parser_api::Parser; -use { - SyntaxKind::*, -}; -use text_utils::replace_range; - -#[derive(Debug, Clone)] -pub struct AtomEdit { - pub delete: TextRange, - pub insert: String, -} - -impl AtomEdit { - pub fn replace(range: TextRange, replace_with: String) -> AtomEdit { - AtomEdit { delete: range, insert: replace_with } - } - - pub fn delete(range: TextRange) -> AtomEdit { - AtomEdit::replace(range, String::new()) - } - - pub fn insert(offset: TextUnit, text: String) -> AtomEdit { - AtomEdit::replace(TextRange::offset_len(offset, 0.into()), text) - } -} - -pub(crate) fn incremental_reparse( - node: SyntaxNodeRef, - edit: &AtomEdit, - errors: Vec, -) -> Option<(GreenNode, Vec)> { - let (node, green, new_errors) = - reparse_leaf(node, &edit).or_else(|| reparse_block(node, &edit))?; - let green_root = node.replace_with(green); - let errors = merge_errors(errors, new_errors, node, edit); - Some((green_root, errors)) -} - -fn reparse_leaf<'node>( - node: SyntaxNodeRef<'node>, - edit: &AtomEdit, -) -> Option<(SyntaxNodeRef<'node>, GreenNode, Vec)> { - let node = algo::find_covering_node(node, edit.delete); - match node.kind() { - | WHITESPACE - | COMMENT - | DOC_COMMENT - | IDENT - | STRING - | RAW_STRING => { - let text = get_text_after_edit(node, &edit); - let tokens = tokenize(&text); - let token = match tokens[..] { - [token] if token.kind == node.kind() => token, - _ => return None, - }; - - if token.kind == IDENT && is_contextual_kw(&text) { - return None; - } - - let green = GreenNode::new_leaf(node.kind(), &text); - let new_errors = vec![]; - Some((node, green, new_errors)) - } - _ => None, - } -} - -fn reparse_block<'node>( - node: SyntaxNodeRef<'node>, - edit: &AtomEdit, -) -> Option<(SyntaxNodeRef<'node>, GreenNode, Vec)> { - let (node, reparser) = find_reparsable_node(node, edit.delete)?; - let text = get_text_after_edit(node, &edit); - let tokens = tokenize(&text); - if !is_balanced(&tokens) { - return None; - } - let (green, new_errors) = - parser_impl::parse_with::( - &text, &tokens, reparser, - ); - Some((node, green, new_errors)) -} - -fn get_text_after_edit(node: SyntaxNodeRef, edit: &AtomEdit) -> String { - replace_range( - node.text().to_string(), - edit.delete - node.range().start(), - &edit.insert, - ) -} - -fn is_contextual_kw(text: &str) -> bool { - match text { - | "auto" - | "default" - | "union" => true, - _ => false, - } -} - -fn find_reparsable_node<'node>( - node: SyntaxNodeRef<'node>, - range: TextRange, -) -> Option<(SyntaxNodeRef<'node>, fn(&mut Parser))> { - let node = algo::find_covering_node(node, range); - return algo::ancestors(node) - .filter_map(|node| reparser(node).map(|r| (node, r))) - .next(); - - fn reparser(node: SyntaxNodeRef) -> Option { - let res = match node.kind() { - BLOCK => grammar::block, - NAMED_FIELD_DEF_LIST => grammar::named_field_def_list, - NAMED_FIELD_LIST => grammar::named_field_list, - ENUM_VARIANT_LIST => grammar::enum_variant_list, - MATCH_ARM_LIST => grammar::match_arm_list, - USE_TREE_LIST => grammar::use_tree_list, - EXTERN_ITEM_LIST => grammar::extern_item_list, - TOKEN_TREE if node.first_child().unwrap().kind() == L_CURLY => grammar::token_tree, - ITEM_LIST => { - let parent = node.parent().unwrap(); - match parent.kind() { - IMPL_ITEM => grammar::impl_item_list, - TRAIT_DEF => grammar::trait_item_list, - MODULE => grammar::mod_item_list, - _ => return None, - } - } - _ => return None, - }; - Some(res) - } -} - -fn is_balanced(tokens: &[Token]) -> bool { - if tokens.len() == 0 - || tokens.first().unwrap().kind != L_CURLY - || tokens.last().unwrap().kind != R_CURLY { - return false; - } - let mut balance = 0usize; - for t in tokens.iter() { - match t.kind { - L_CURLY => balance += 1, - R_CURLY => balance = match balance.checked_sub(1) { - Some(b) => b, - None => return false, - }, - _ => (), - } - } - balance == 0 -} - -fn merge_errors( - old_errors: Vec, - new_errors: Vec, - old_node: SyntaxNodeRef, - edit: &AtomEdit, -) -> Vec { - let mut res = Vec::new(); - for e in old_errors { - if e.offset <= old_node.range().start() { - res.push(e) - } else if e.offset >= old_node.range().end() { - res.push(SyntaxError { - msg: e.msg, - offset: e.offset + TextUnit::of_str(&edit.insert) - edit.delete.len(), - }) - } - } - for e in new_errors { - res.push(SyntaxError { - msg: e.msg, - offset: e.offset + old_node.range().start(), - }) - } - res -} - -#[cfg(test)] -mod tests { - use super::{ - super::{ - File, - test_utils::extract_range, - text_utils::replace_range, - utils::dump_tree, - }, - reparse_leaf, reparse_block, AtomEdit, GreenNode, SyntaxError, SyntaxNodeRef, - }; - - fn do_check( - before: &str, - replace_with: &str, - reparser: F, - ) where - for<'a> F: Fn( - SyntaxNodeRef<'a>, - &AtomEdit, - ) -> Option<(SyntaxNodeRef<'a>, GreenNode, Vec)> - { - let (range, before) = extract_range(before); - let after = replace_range(before.clone(), range, replace_with); - - let fully_reparsed = File::parse(&after); - let incrementally_reparsed = { - let f = File::parse(&before); - let edit = AtomEdit { delete: range, insert: replace_with.to_string() }; - let (node, green, new_errors) = - reparser(f.syntax(), &edit).expect("cannot incrementally reparse"); - let green_root = node.replace_with(green); - let errors = super::merge_errors(f.errors(), new_errors, node, &edit); - File::new(green_root, errors) - }; - - assert_eq_text!( - &dump_tree(fully_reparsed.syntax()), - &dump_tree(incrementally_reparsed.syntax()), - ) - } - - #[test] - fn reparse_block_tests() { - let do_check = |before, replace_to| - do_check(before, replace_to, reparse_block); - - do_check(r" -fn foo() { - let x = foo + <|>bar<|> -} -", "baz"); - do_check(r" -fn foo() { - let x = foo<|> + bar<|> -} -", "baz"); - do_check(r" -struct Foo { - f: foo<|><|> -} -", ",\n g: (),"); - do_check(r" -fn foo { - let; - 1 + 1; - <|>92<|>; -} -", "62"); - do_check(r" -mod foo { - fn <|><|> -} -", "bar"); - do_check(r" -trait Foo { - type <|>Foo<|>; -} -", "Output"); - do_check(r" -impl IntoIterator for Foo { - f<|><|> -} -", "n next("); - do_check(r" -use a::b::{foo,<|>,bar<|>}; - ", "baz"); - do_check(r" -pub enum A { - Foo<|><|> -} -", "\nBar;\n"); - do_check(r" -foo!{a, b<|><|> d} -", ", c[3]"); - do_check(r" -fn foo() { - vec![<|><|>] -} -", "123"); - do_check(r" -extern { - fn<|>;<|> -} -", " exit(code: c_int)"); - } - - #[test] - fn reparse_leaf_tests() { - let do_check = |before, replace_to| - do_check(before, replace_to, reparse_leaf); - - do_check(r"<|><|> -fn foo() -> i32 { 1 } -", "\n\n\n \n"); - do_check(r" -fn foo() -> <|><|> {} -", " \n"); - do_check(r" -fn <|>foo<|>() -> i32 { 1 } -", "bar"); - do_check(r" -fn foo<|><|>foo() { } -", "bar"); - do_check(r" -fn foo /* <|><|> */ () {} -", "some comment"); - do_check(r" -fn baz <|><|> () {} -", " \t\t\n\n"); - do_check(r" -fn baz <|><|> () {} -", " \t\t\n\n"); - do_check(r" -/// foo <|><|>omment -mod { } -", "c"); - do_check(r#" -fn -> &str { "Hello<|><|>" } -"#, ", world"); - do_check(r#" -fn -> &str { // "Hello<|><|>" -"#, ", world"); - do_check(r##" -fn -> &str { r#"Hello<|><|>"# -"##, ", world"); - do_check(r" -#[derive(<|>Copy<|>)] -enum Foo { - -} -", "Clone"); - } -} \ No newline at end of file diff --git a/crates/libsyntax2/src/syntax_kinds/generated.rs b/crates/libsyntax2/src/syntax_kinds/generated.rs deleted file mode 100644 index 7882bded9..000000000 --- a/crates/libsyntax2/src/syntax_kinds/generated.rs +++ /dev/null @@ -1,562 +0,0 @@ -#![allow(bad_style, missing_docs, unreachable_pub)] -#![cfg_attr(rustfmt, rustfmt_skip)] -use super::SyntaxInfo; - -/// The kind of syntax node, e.g. `IDENT`, `USE_KW`, or `STRUCT_DEF`. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub enum SyntaxKind { - // Technical SyntaxKinds: they appear temporally during parsing, - // but never end up in the final tree - #[doc(hidden)] - TOMBSTONE, - #[doc(hidden)] - EOF, - SEMI, - COMMA, - L_PAREN, - R_PAREN, - L_CURLY, - R_CURLY, - L_BRACK, - R_BRACK, - L_ANGLE, - R_ANGLE, - AT, - POUND, - TILDE, - QUESTION, - DOLLAR, - AMP, - PIPE, - PLUS, - STAR, - SLASH, - CARET, - PERCENT, - DOT, - DOTDOT, - DOTDOTDOT, - DOTDOTEQ, - COLON, - COLONCOLON, - EQ, - EQEQ, - FAT_ARROW, - EXCL, - NEQ, - MINUS, - THIN_ARROW, - LTEQ, - GTEQ, - PLUSEQ, - MINUSEQ, - PIPEEQ, - AMPEQ, - CARETEQ, - SLASHEQ, - STAREQ, - AMPAMP, - PIPEPIPE, - SHL, - SHR, - SHLEQ, - SHREQ, - USE_KW, - FN_KW, - STRUCT_KW, - ENUM_KW, - TRAIT_KW, - IMPL_KW, - DYN_KW, - TRUE_KW, - FALSE_KW, - AS_KW, - EXTERN_KW, - CRATE_KW, - MOD_KW, - PUB_KW, - SELF_KW, - SUPER_KW, - IN_KW, - WHERE_KW, - FOR_KW, - LOOP_KW, - WHILE_KW, - CONTINUE_KW, - BREAK_KW, - IF_KW, - ELSE_KW, - MATCH_KW, - CONST_KW, - STATIC_KW, - MUT_KW, - UNSAFE_KW, - TYPE_KW, - REF_KW, - LET_KW, - MOVE_KW, - RETURN_KW, - AUTO_KW, - DEFAULT_KW, - UNION_KW, - ERROR, - IDENT, - UNDERSCORE, - WHITESPACE, - INT_NUMBER, - FLOAT_NUMBER, - LIFETIME, - CHAR, - BYTE, - STRING, - RAW_STRING, - BYTE_STRING, - RAW_BYTE_STRING, - COMMENT, - DOC_COMMENT, - SHEBANG, - ROOT, - STRUCT_DEF, - ENUM_DEF, - FN_DEF, - RET_TYPE, - EXTERN_CRATE_ITEM, - MODULE, - USE_ITEM, - STATIC_DEF, - CONST_DEF, - TRAIT_DEF, - IMPL_ITEM, - TYPE_DEF, - MACRO_CALL, - TOKEN_TREE, - PAREN_TYPE, - TUPLE_TYPE, - NEVER_TYPE, - PATH_TYPE, - POINTER_TYPE, - ARRAY_TYPE, - SLICE_TYPE, - REFERENCE_TYPE, - PLACEHOLDER_TYPE, - FN_POINTER_TYPE, - FOR_TYPE, - IMPL_TRAIT_TYPE, - DYN_TRAIT_TYPE, - REF_PAT, - BIND_PAT, - PLACEHOLDER_PAT, - PATH_PAT, - STRUCT_PAT, - FIELD_PAT_LIST, - TUPLE_STRUCT_PAT, - TUPLE_PAT, - SLICE_PAT, - RANGE_PAT, - TUPLE_EXPR, - ARRAY_EXPR, - PAREN_EXPR, - PATH_EXPR, - LAMBDA_EXPR, - IF_EXPR, - WHILE_EXPR, - CONDITION, - LOOP_EXPR, - FOR_EXPR, - CONTINUE_EXPR, - BREAK_EXPR, - LABEL, - BLOCK_EXPR, - RETURN_EXPR, - MATCH_EXPR, - MATCH_ARM_LIST, - MATCH_ARM, - MATCH_GUARD, - STRUCT_LIT, - NAMED_FIELD_LIST, - NAMED_FIELD, - CALL_EXPR, - INDEX_EXPR, - METHOD_CALL_EXPR, - FIELD_EXPR, - TRY_EXPR, - CAST_EXPR, - REF_EXPR, - PREFIX_EXPR, - RANGE_EXPR, - BIN_EXPR, - BLOCK, - EXTERN_BLOCK, - EXTERN_ITEM_LIST, - ENUM_VARIANT, - NAMED_FIELD_DEF_LIST, - NAMED_FIELD_DEF, - POS_FIELD_LIST, - POS_FIELD, - ENUM_VARIANT_LIST, - ITEM_LIST, - ATTR, - META_ITEM, - USE_TREE, - USE_TREE_LIST, - PATH, - PATH_SEGMENT, - LITERAL, - ALIAS, - VISIBILITY, - WHERE_CLAUSE, - WHERE_PRED, - ABI, - NAME, - NAME_REF, - LET_STMT, - EXPR_STMT, - TYPE_PARAM_LIST, - LIFETIME_PARAM, - TYPE_PARAM, - TYPE_ARG_LIST, - LIFETIME_ARG, - TYPE_ARG, - ASSOC_TYPE_ARG, - PARAM_LIST, - PARAM, - SELF_PARAM, - ARG_LIST, -} -use self::SyntaxKind::*; - -impl SyntaxKind { - pub fn is_keyword(self) -> bool { - match self { - | USE_KW - | FN_KW - | STRUCT_KW - | ENUM_KW - | TRAIT_KW - | IMPL_KW - | DYN_KW - | TRUE_KW - | FALSE_KW - | AS_KW - | EXTERN_KW - | CRATE_KW - | MOD_KW - | PUB_KW - | SELF_KW - | SUPER_KW - | IN_KW - | WHERE_KW - | FOR_KW - | LOOP_KW - | WHILE_KW - | CONTINUE_KW - | BREAK_KW - | IF_KW - | ELSE_KW - | MATCH_KW - | CONST_KW - | STATIC_KW - | MUT_KW - | UNSAFE_KW - | TYPE_KW - | REF_KW - | LET_KW - | MOVE_KW - | RETURN_KW - | AUTO_KW - | DEFAULT_KW - | UNION_KW - => true, - _ => false - } - } - - pub(crate) fn info(self) -> &'static SyntaxInfo { - match self { - SEMI => &SyntaxInfo { name: "SEMI" }, - COMMA => &SyntaxInfo { name: "COMMA" }, - L_PAREN => &SyntaxInfo { name: "L_PAREN" }, - R_PAREN => &SyntaxInfo { name: "R_PAREN" }, - L_CURLY => &SyntaxInfo { name: "L_CURLY" }, - R_CURLY => &SyntaxInfo { name: "R_CURLY" }, - L_BRACK => &SyntaxInfo { name: "L_BRACK" }, - R_BRACK => &SyntaxInfo { name: "R_BRACK" }, - L_ANGLE => &SyntaxInfo { name: "L_ANGLE" }, - R_ANGLE => &SyntaxInfo { name: "R_ANGLE" }, - AT => &SyntaxInfo { name: "AT" }, - POUND => &SyntaxInfo { name: "POUND" }, - TILDE => &SyntaxInfo { name: "TILDE" }, - QUESTION => &SyntaxInfo { name: "QUESTION" }, - DOLLAR => &SyntaxInfo { name: "DOLLAR" }, - AMP => &SyntaxInfo { name: "AMP" }, - PIPE => &SyntaxInfo { name: "PIPE" }, - PLUS => &SyntaxInfo { name: "PLUS" }, - STAR => &SyntaxInfo { name: "STAR" }, - SLASH => &SyntaxInfo { name: "SLASH" }, - CARET => &SyntaxInfo { name: "CARET" }, - PERCENT => &SyntaxInfo { name: "PERCENT" }, - DOT => &SyntaxInfo { name: "DOT" }, - DOTDOT => &SyntaxInfo { name: "DOTDOT" }, - DOTDOTDOT => &SyntaxInfo { name: "DOTDOTDOT" }, - DOTDOTEQ => &SyntaxInfo { name: "DOTDOTEQ" }, - COLON => &SyntaxInfo { name: "COLON" }, - COLONCOLON => &SyntaxInfo { name: "COLONCOLON" }, - EQ => &SyntaxInfo { name: "EQ" }, - EQEQ => &SyntaxInfo { name: "EQEQ" }, - FAT_ARROW => &SyntaxInfo { name: "FAT_ARROW" }, - EXCL => &SyntaxInfo { name: "EXCL" }, - NEQ => &SyntaxInfo { name: "NEQ" }, - MINUS => &SyntaxInfo { name: "MINUS" }, - THIN_ARROW => &SyntaxInfo { name: "THIN_ARROW" }, - LTEQ => &SyntaxInfo { name: "LTEQ" }, - GTEQ => &SyntaxInfo { name: "GTEQ" }, - PLUSEQ => &SyntaxInfo { name: "PLUSEQ" }, - MINUSEQ => &SyntaxInfo { name: "MINUSEQ" }, - PIPEEQ => &SyntaxInfo { name: "PIPEEQ" }, - AMPEQ => &SyntaxInfo { name: "AMPEQ" }, - CARETEQ => &SyntaxInfo { name: "CARETEQ" }, - SLASHEQ => &SyntaxInfo { name: "SLASHEQ" }, - STAREQ => &SyntaxInfo { name: "STAREQ" }, - AMPAMP => &SyntaxInfo { name: "AMPAMP" }, - PIPEPIPE => &SyntaxInfo { name: "PIPEPIPE" }, - SHL => &SyntaxInfo { name: "SHL" }, - SHR => &SyntaxInfo { name: "SHR" }, - SHLEQ => &SyntaxInfo { name: "SHLEQ" }, - SHREQ => &SyntaxInfo { name: "SHREQ" }, - USE_KW => &SyntaxInfo { name: "USE_KW" }, - FN_KW => &SyntaxInfo { name: "FN_KW" }, - STRUCT_KW => &SyntaxInfo { name: "STRUCT_KW" }, - ENUM_KW => &SyntaxInfo { name: "ENUM_KW" }, - TRAIT_KW => &SyntaxInfo { name: "TRAIT_KW" }, - IMPL_KW => &SyntaxInfo { name: "IMPL_KW" }, - DYN_KW => &SyntaxInfo { name: "DYN_KW" }, - TRUE_KW => &SyntaxInfo { name: "TRUE_KW" }, - FALSE_KW => &SyntaxInfo { name: "FALSE_KW" }, - AS_KW => &SyntaxInfo { name: "AS_KW" }, - EXTERN_KW => &SyntaxInfo { name: "EXTERN_KW" }, - CRATE_KW => &SyntaxInfo { name: "CRATE_KW" }, - MOD_KW => &SyntaxInfo { name: "MOD_KW" }, - PUB_KW => &SyntaxInfo { name: "PUB_KW" }, - SELF_KW => &SyntaxInfo { name: "SELF_KW" }, - SUPER_KW => &SyntaxInfo { name: "SUPER_KW" }, - IN_KW => &SyntaxInfo { name: "IN_KW" }, - WHERE_KW => &SyntaxInfo { name: "WHERE_KW" }, - FOR_KW => &SyntaxInfo { name: "FOR_KW" }, - LOOP_KW => &SyntaxInfo { name: "LOOP_KW" }, - WHILE_KW => &SyntaxInfo { name: "WHILE_KW" }, - CONTINUE_KW => &SyntaxInfo { name: "CONTINUE_KW" }, - BREAK_KW => &SyntaxInfo { name: "BREAK_KW" }, - IF_KW => &SyntaxInfo { name: "IF_KW" }, - ELSE_KW => &SyntaxInfo { name: "ELSE_KW" }, - MATCH_KW => &SyntaxInfo { name: "MATCH_KW" }, - CONST_KW => &SyntaxInfo { name: "CONST_KW" }, - STATIC_KW => &SyntaxInfo { name: "STATIC_KW" }, - MUT_KW => &SyntaxInfo { name: "MUT_KW" }, - UNSAFE_KW => &SyntaxInfo { name: "UNSAFE_KW" }, - TYPE_KW => &SyntaxInfo { name: "TYPE_KW" }, - REF_KW => &SyntaxInfo { name: "REF_KW" }, - LET_KW => &SyntaxInfo { name: "LET_KW" }, - MOVE_KW => &SyntaxInfo { name: "MOVE_KW" }, - RETURN_KW => &SyntaxInfo { name: "RETURN_KW" }, - AUTO_KW => &SyntaxInfo { name: "AUTO_KW" }, - DEFAULT_KW => &SyntaxInfo { name: "DEFAULT_KW" }, - UNION_KW => &SyntaxInfo { name: "UNION_KW" }, - ERROR => &SyntaxInfo { name: "ERROR" }, - IDENT => &SyntaxInfo { name: "IDENT" }, - UNDERSCORE => &SyntaxInfo { name: "UNDERSCORE" }, - WHITESPACE => &SyntaxInfo { name: "WHITESPACE" }, - INT_NUMBER => &SyntaxInfo { name: "INT_NUMBER" }, - FLOAT_NUMBER => &SyntaxInfo { name: "FLOAT_NUMBER" }, - LIFETIME => &SyntaxInfo { name: "LIFETIME" }, - CHAR => &SyntaxInfo { name: "CHAR" }, - BYTE => &SyntaxInfo { name: "BYTE" }, - STRING => &SyntaxInfo { name: "STRING" }, - RAW_STRING => &SyntaxInfo { name: "RAW_STRING" }, - BYTE_STRING => &SyntaxInfo { name: "BYTE_STRING" }, - RAW_BYTE_STRING => &SyntaxInfo { name: "RAW_BYTE_STRING" }, - COMMENT => &SyntaxInfo { name: "COMMENT" }, - DOC_COMMENT => &SyntaxInfo { name: "DOC_COMMENT" }, - SHEBANG => &SyntaxInfo { name: "SHEBANG" }, - ROOT => &SyntaxInfo { name: "ROOT" }, - STRUCT_DEF => &SyntaxInfo { name: "STRUCT_DEF" }, - ENUM_DEF => &SyntaxInfo { name: "ENUM_DEF" }, - FN_DEF => &SyntaxInfo { name: "FN_DEF" }, - RET_TYPE => &SyntaxInfo { name: "RET_TYPE" }, - EXTERN_CRATE_ITEM => &SyntaxInfo { name: "EXTERN_CRATE_ITEM" }, - MODULE => &SyntaxInfo { name: "MODULE" }, - USE_ITEM => &SyntaxInfo { name: "USE_ITEM" }, - STATIC_DEF => &SyntaxInfo { name: "STATIC_DEF" }, - CONST_DEF => &SyntaxInfo { name: "CONST_DEF" }, - TRAIT_DEF => &SyntaxInfo { name: "TRAIT_DEF" }, - IMPL_ITEM => &SyntaxInfo { name: "IMPL_ITEM" }, - TYPE_DEF => &SyntaxInfo { name: "TYPE_DEF" }, - MACRO_CALL => &SyntaxInfo { name: "MACRO_CALL" }, - TOKEN_TREE => &SyntaxInfo { name: "TOKEN_TREE" }, - PAREN_TYPE => &SyntaxInfo { name: "PAREN_TYPE" }, - TUPLE_TYPE => &SyntaxInfo { name: "TUPLE_TYPE" }, - NEVER_TYPE => &SyntaxInfo { name: "NEVER_TYPE" }, - PATH_TYPE => &SyntaxInfo { name: "PATH_TYPE" }, - POINTER_TYPE => &SyntaxInfo { name: "POINTER_TYPE" }, - ARRAY_TYPE => &SyntaxInfo { name: "ARRAY_TYPE" }, - SLICE_TYPE => &SyntaxInfo { name: "SLICE_TYPE" }, - REFERENCE_TYPE => &SyntaxInfo { name: "REFERENCE_TYPE" }, - PLACEHOLDER_TYPE => &SyntaxInfo { name: "PLACEHOLDER_TYPE" }, - FN_POINTER_TYPE => &SyntaxInfo { name: "FN_POINTER_TYPE" }, - FOR_TYPE => &SyntaxInfo { name: "FOR_TYPE" }, - IMPL_TRAIT_TYPE => &SyntaxInfo { name: "IMPL_TRAIT_TYPE" }, - DYN_TRAIT_TYPE => &SyntaxInfo { name: "DYN_TRAIT_TYPE" }, - REF_PAT => &SyntaxInfo { name: "REF_PAT" }, - BIND_PAT => &SyntaxInfo { name: "BIND_PAT" }, - PLACEHOLDER_PAT => &SyntaxInfo { name: "PLACEHOLDER_PAT" }, - PATH_PAT => &SyntaxInfo { name: "PATH_PAT" }, - STRUCT_PAT => &SyntaxInfo { name: "STRUCT_PAT" }, - FIELD_PAT_LIST => &SyntaxInfo { name: "FIELD_PAT_LIST" }, - TUPLE_STRUCT_PAT => &SyntaxInfo { name: "TUPLE_STRUCT_PAT" }, - TUPLE_PAT => &SyntaxInfo { name: "TUPLE_PAT" }, - SLICE_PAT => &SyntaxInfo { name: "SLICE_PAT" }, - RANGE_PAT => &SyntaxInfo { name: "RANGE_PAT" }, - TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" }, - ARRAY_EXPR => &SyntaxInfo { name: "ARRAY_EXPR" }, - PAREN_EXPR => &SyntaxInfo { name: "PAREN_EXPR" }, - PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" }, - LAMBDA_EXPR => &SyntaxInfo { name: "LAMBDA_EXPR" }, - IF_EXPR => &SyntaxInfo { name: "IF_EXPR" }, - WHILE_EXPR => &SyntaxInfo { name: "WHILE_EXPR" }, - CONDITION => &SyntaxInfo { name: "CONDITION" }, - LOOP_EXPR => &SyntaxInfo { name: "LOOP_EXPR" }, - FOR_EXPR => &SyntaxInfo { name: "FOR_EXPR" }, - CONTINUE_EXPR => &SyntaxInfo { name: "CONTINUE_EXPR" }, - BREAK_EXPR => &SyntaxInfo { name: "BREAK_EXPR" }, - LABEL => &SyntaxInfo { name: "LABEL" }, - BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" }, - RETURN_EXPR => &SyntaxInfo { name: "RETURN_EXPR" }, - MATCH_EXPR => &SyntaxInfo { name: "MATCH_EXPR" }, - MATCH_ARM_LIST => &SyntaxInfo { name: "MATCH_ARM_LIST" }, - MATCH_ARM => &SyntaxInfo { name: "MATCH_ARM" }, - MATCH_GUARD => &SyntaxInfo { name: "MATCH_GUARD" }, - STRUCT_LIT => &SyntaxInfo { name: "STRUCT_LIT" }, - NAMED_FIELD_LIST => &SyntaxInfo { name: "NAMED_FIELD_LIST" }, - NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, - CALL_EXPR => &SyntaxInfo { name: "CALL_EXPR" }, - INDEX_EXPR => &SyntaxInfo { name: "INDEX_EXPR" }, - METHOD_CALL_EXPR => &SyntaxInfo { name: "METHOD_CALL_EXPR" }, - FIELD_EXPR => &SyntaxInfo { name: "FIELD_EXPR" }, - TRY_EXPR => &SyntaxInfo { name: "TRY_EXPR" }, - CAST_EXPR => &SyntaxInfo { name: "CAST_EXPR" }, - REF_EXPR => &SyntaxInfo { name: "REF_EXPR" }, - PREFIX_EXPR => &SyntaxInfo { name: "PREFIX_EXPR" }, - RANGE_EXPR => &SyntaxInfo { name: "RANGE_EXPR" }, - BIN_EXPR => &SyntaxInfo { name: "BIN_EXPR" }, - BLOCK => &SyntaxInfo { name: "BLOCK" }, - EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, - EXTERN_ITEM_LIST => &SyntaxInfo { name: "EXTERN_ITEM_LIST" }, - ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, - NAMED_FIELD_DEF_LIST => &SyntaxInfo { name: "NAMED_FIELD_DEF_LIST" }, - NAMED_FIELD_DEF => &SyntaxInfo { name: "NAMED_FIELD_DEF" }, - POS_FIELD_LIST => &SyntaxInfo { name: "POS_FIELD_LIST" }, - POS_FIELD => &SyntaxInfo { name: "POS_FIELD" }, - ENUM_VARIANT_LIST => &SyntaxInfo { name: "ENUM_VARIANT_LIST" }, - ITEM_LIST => &SyntaxInfo { name: "ITEM_LIST" }, - ATTR => &SyntaxInfo { name: "ATTR" }, - META_ITEM => &SyntaxInfo { name: "META_ITEM" }, - USE_TREE => &SyntaxInfo { name: "USE_TREE" }, - USE_TREE_LIST => &SyntaxInfo { name: "USE_TREE_LIST" }, - PATH => &SyntaxInfo { name: "PATH" }, - PATH_SEGMENT => &SyntaxInfo { name: "PATH_SEGMENT" }, - LITERAL => &SyntaxInfo { name: "LITERAL" }, - ALIAS => &SyntaxInfo { name: "ALIAS" }, - VISIBILITY => &SyntaxInfo { name: "VISIBILITY" }, - WHERE_CLAUSE => &SyntaxInfo { name: "WHERE_CLAUSE" }, - WHERE_PRED => &SyntaxInfo { name: "WHERE_PRED" }, - ABI => &SyntaxInfo { name: "ABI" }, - NAME => &SyntaxInfo { name: "NAME" }, - NAME_REF => &SyntaxInfo { name: "NAME_REF" }, - LET_STMT => &SyntaxInfo { name: "LET_STMT" }, - EXPR_STMT => &SyntaxInfo { name: "EXPR_STMT" }, - TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" }, - LIFETIME_PARAM => &SyntaxInfo { name: "LIFETIME_PARAM" }, - TYPE_PARAM => &SyntaxInfo { name: "TYPE_PARAM" }, - TYPE_ARG_LIST => &SyntaxInfo { name: "TYPE_ARG_LIST" }, - LIFETIME_ARG => &SyntaxInfo { name: "LIFETIME_ARG" }, - TYPE_ARG => &SyntaxInfo { name: "TYPE_ARG" }, - ASSOC_TYPE_ARG => &SyntaxInfo { name: "ASSOC_TYPE_ARG" }, - PARAM_LIST => &SyntaxInfo { name: "PARAM_LIST" }, - PARAM => &SyntaxInfo { name: "PARAM" }, - SELF_PARAM => &SyntaxInfo { name: "SELF_PARAM" }, - ARG_LIST => &SyntaxInfo { name: "ARG_LIST" }, - TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" }, - EOF => &SyntaxInfo { name: "EOF" }, - } - } - pub(crate) fn from_keyword(ident: &str) -> Option { - let kw = match ident { - "use" => USE_KW, - "fn" => FN_KW, - "struct" => STRUCT_KW, - "enum" => ENUM_KW, - "trait" => TRAIT_KW, - "impl" => IMPL_KW, - "dyn" => DYN_KW, - "true" => TRUE_KW, - "false" => FALSE_KW, - "as" => AS_KW, - "extern" => EXTERN_KW, - "crate" => CRATE_KW, - "mod" => MOD_KW, - "pub" => PUB_KW, - "self" => SELF_KW, - "super" => SUPER_KW, - "in" => IN_KW, - "where" => WHERE_KW, - "for" => FOR_KW, - "loop" => LOOP_KW, - "while" => WHILE_KW, - "continue" => CONTINUE_KW, - "break" => BREAK_KW, - "if" => IF_KW, - "else" => ELSE_KW, - "match" => MATCH_KW, - "const" => CONST_KW, - "static" => STATIC_KW, - "mut" => MUT_KW, - "unsafe" => UNSAFE_KW, - "type" => TYPE_KW, - "ref" => REF_KW, - "let" => LET_KW, - "move" => MOVE_KW, - "return" => RETURN_KW, - _ => return None, - }; - Some(kw) - } - - pub(crate) fn from_char(c: char) -> Option { - let tok = match c { - ';' => SEMI, - ',' => COMMA, - '(' => L_PAREN, - ')' => R_PAREN, - '{' => L_CURLY, - '}' => R_CURLY, - '[' => L_BRACK, - ']' => R_BRACK, - '<' => L_ANGLE, - '>' => R_ANGLE, - '@' => AT, - '#' => POUND, - '~' => TILDE, - '?' => QUESTION, - '$' => DOLLAR, - '&' => AMP, - '|' => PIPE, - '+' => PLUS, - '*' => STAR, - '/' => SLASH, - '^' => CARET, - '%' => PERCENT, - _ => return None, - }; - Some(tok) - } -} - diff --git a/crates/libsyntax2/src/syntax_kinds/generated.rs.tera b/crates/libsyntax2/src/syntax_kinds/generated.rs.tera deleted file mode 100644 index 90618721a..000000000 --- a/crates/libsyntax2/src/syntax_kinds/generated.rs.tera +++ /dev/null @@ -1,73 +0,0 @@ -#![allow(bad_style, missing_docs, unreachable_pub)] -#![cfg_attr(rustfmt, rustfmt_skip)] -use super::SyntaxInfo; - -/// The kind of syntax node, e.g. `IDENT`, `USE_KW`, or `STRUCT_DEF`. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub enum SyntaxKind { - // Technical SyntaxKinds: they appear temporally during parsing, - // but never end up in the final tree - #[doc(hidden)] - TOMBSTONE, - #[doc(hidden)] - EOF, - -{%- for t in concat(a=single_byte_tokens, b=multi_byte_tokens) %} - {{t.1}}, -{%- endfor -%} -{% for kw in concat(a=keywords, b=contextual_keywords) %} - {{kw | upper}}_KW, -{%- endfor -%} -{% for t in concat(a=tokens, b=nodes) %} - {{t}}, -{%- endfor %} -} -use self::SyntaxKind::*; - -impl SyntaxKind { - pub fn is_keyword(self) -> bool { - match self { -{%- for kw in concat(a=keywords, b=contextual_keywords) %} - | {{kw | upper}}_KW -{%- endfor %} - => true, - _ => false - } - } - - pub(crate) fn info(self) -> &'static SyntaxInfo { - match self { -{%- for t in concat(a=single_byte_tokens, b=multi_byte_tokens) %} - {{t.1}} => &SyntaxInfo { name: "{{t.1}}" }, -{%- endfor -%} -{% for kw in concat(a=keywords, b=contextual_keywords) %} - {{kw | upper}}_KW => &SyntaxInfo { name: "{{kw | upper}}_KW" }, -{%- endfor -%} -{% for t in concat(a=tokens, b=nodes) %} - {{t}} => &SyntaxInfo { name: "{{t}}" }, -{%- endfor %} - TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" }, - EOF => &SyntaxInfo { name: "EOF" }, - } - } - pub(crate) fn from_keyword(ident: &str) -> Option { - let kw = match ident { -{%- for kw in keywords %} - "{{kw}}" => {{kw | upper}}_KW, -{%- endfor %} - _ => return None, - }; - Some(kw) - } - - pub(crate) fn from_char(c: char) -> Option { - let tok = match c { -{%- for t in single_byte_tokens %} - '{{t.0}}' => {{t.1}}, -{%- endfor %} - _ => return None, - }; - Some(tok) - } -} - diff --git a/crates/libsyntax2/src/syntax_kinds/mod.rs b/crates/libsyntax2/src/syntax_kinds/mod.rs deleted file mode 100644 index 332cd13ac..000000000 --- a/crates/libsyntax2/src/syntax_kinds/mod.rs +++ /dev/null @@ -1,26 +0,0 @@ -mod generated; - -use std::fmt; -use SyntaxKind::*; - -pub use self::generated::SyntaxKind; - -impl fmt::Debug for SyntaxKind { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let name = self.info().name; - f.write_str(name) - } -} - -pub(crate) struct SyntaxInfo { - pub name: &'static str, -} - -impl SyntaxKind { - pub fn is_trivia(self) -> bool { - match self { - WHITESPACE | COMMENT | DOC_COMMENT => true, - _ => false, - } - } -} diff --git a/crates/libsyntax2/src/text_utils.rs b/crates/libsyntax2/src/text_utils.rs deleted file mode 100644 index 58ae1e43e..000000000 --- a/crates/libsyntax2/src/text_utils.rs +++ /dev/null @@ -1,26 +0,0 @@ -use {TextRange, TextUnit}; - -pub fn contains_offset_nonstrict(range: TextRange, offset: TextUnit) -> bool { - range.start() <= offset && offset <= range.end() -} - -pub fn is_subrange(range: TextRange, subrange: TextRange) -> bool { - range.start() <= subrange.start() && subrange.end() <= range.end() -} - -pub fn intersect(r1: TextRange, r2: TextRange) -> Option { - let start = r1.start().max(r2.start()); - let end = r1.end().min(r2.end()); - if start <= end { - Some(TextRange::from_to(start, end)) - } else { - None - } -} - -pub fn replace_range(mut text: String, range: TextRange, replace_with: &str) -> String { - let start = u32::from(range.start()) as usize; - let end = u32::from(range.end()) as usize; - text.replace_range(start..end, replace_with); - text -} \ No newline at end of file diff --git a/crates/libsyntax2/src/token_set.rs b/crates/libsyntax2/src/token_set.rs deleted file mode 100644 index c83fba81b..000000000 --- a/crates/libsyntax2/src/token_set.rs +++ /dev/null @@ -1,37 +0,0 @@ -use SyntaxKind; - -#[derive(Clone, Copy)] -pub(crate) struct TokenSet(pub(crate) u128); - -fn mask(kind: SyntaxKind) -> u128 { - 1u128 << (kind as usize) -} - -impl TokenSet { - pub const EMPTY: TokenSet = TokenSet(0); - - pub fn contains(&self, kind: SyntaxKind) -> bool { - self.0 & mask(kind) != 0 - } -} - -#[macro_export] -macro_rules! token_set { - ($($t:ident),*) => { TokenSet($(1u128 << ($t as usize))|*) }; - ($($t:ident),* ,) => { token_set!($($t),*) }; -} - -#[macro_export] -macro_rules! token_set_union { - ($($ts:expr),*) => { TokenSet($($ts.0)|*) }; - ($($ts:expr),* ,) => { token_set_union!($($ts),*) }; -} - -#[test] -fn token_set_works_for_tokens() { - use SyntaxKind::*; - let ts = token_set! { EOF, SHEBANG }; - assert!(ts.contains(EOF)); - assert!(ts.contains(SHEBANG)); - assert!(!ts.contains(PLUS)); -} diff --git a/crates/libsyntax2/src/utils.rs b/crates/libsyntax2/src/utils.rs deleted file mode 100644 index 671dd7afa..000000000 --- a/crates/libsyntax2/src/utils.rs +++ /dev/null @@ -1,85 +0,0 @@ -use std::fmt::Write; -use { - algo::walk::{preorder, walk, WalkEvent}, - SyntaxKind, File, SyntaxNodeRef, TreeRoot, -}; - -/// Parse a file and create a string representation of the resulting parse tree. -pub fn dump_tree(syntax: SyntaxNodeRef) -> String { - let mut errors: Vec<_> = syntax.root.syntax_root().errors.iter().cloned().collect(); - errors.sort_by_key(|e| e.offset); - let mut err_pos = 0; - let mut level = 0; - let mut buf = String::new(); - macro_rules! indent { - () => { - for _ in 0..level { - buf.push_str(" "); - } - }; - } - - for event in walk(syntax) { - match event { - WalkEvent::Enter(node) => { - indent!(); - writeln!(buf, "{:?}", node).unwrap(); - if node.first_child().is_none() { - let off = node.range().end(); - while err_pos < errors.len() && errors[err_pos].offset <= off { - indent!(); - writeln!(buf, "err: `{}`", errors[err_pos].msg).unwrap(); - err_pos += 1; - } - } - level += 1; - } - WalkEvent::Exit(_) => level -= 1, - } - } - - assert_eq!(level, 0); - for err in errors[err_pos..].iter() { - writeln!(buf, "err: `{}`", err.msg).unwrap(); - } - - return buf; -} - -pub fn check_fuzz_invariants(text: &str) { - let file = File::parse(text); - let root = file.syntax(); - validate_block_structure(root); - let _ = file.ast(); - let _ = file.errors(); -} - -pub(crate) fn validate_block_structure(root: SyntaxNodeRef) { - let mut stack = Vec::new(); - for node in preorder(root) { - match node.kind() { - SyntaxKind::L_CURLY => { - stack.push(node) - } - SyntaxKind::R_CURLY => { - if let Some(pair) = stack.pop() { - assert_eq!( - node.parent(), - pair.parent(), - "\nunpaired curleys:\n{}\n{}\n", - root.text(), - dump_tree(root), - ); - assert!( - node.next_sibling().is_none() && pair.prev_sibling().is_none(), - "\nfloating curlys at {:?}\nfile:\n{}\nerror:\n{}\n", - node, - root.text(), - node.text(), - ); - } - } - _ => (), - } - } -} diff --git a/crates/libsyntax2/src/yellow/builder.rs b/crates/libsyntax2/src/yellow/builder.rs deleted file mode 100644 index e4ab37899..000000000 --- a/crates/libsyntax2/src/yellow/builder.rs +++ /dev/null @@ -1,64 +0,0 @@ -use { - parser_impl::Sink, - yellow::{GreenNode, SyntaxError}, - SyntaxKind, TextRange, TextUnit, -}; - -pub(crate) struct GreenBuilder<'a> { - text: &'a str, - parents: Vec<(SyntaxKind, usize)>, - children: Vec, - pos: TextUnit, - errors: Vec, -} - -impl<'a> Sink<'a> for GreenBuilder<'a> { - type Tree = (GreenNode, Vec); - - fn new(text: &'a str) -> Self { - GreenBuilder { - text, - parents: Vec::new(), - children: Vec::new(), - pos: 0.into(), - errors: Vec::new(), - } - } - - fn leaf(&mut self, kind: SyntaxKind, len: TextUnit) { - let range = TextRange::offset_len(self.pos, len); - self.pos += len; - let text = &self.text[range]; - self.children.push( - GreenNode::new_leaf(kind, text) - ); - } - - fn start_internal(&mut self, kind: SyntaxKind) { - let len = self.children.len(); - self.parents.push((kind, len)); - } - - fn finish_internal(&mut self) { - let (kind, first_child) = self.parents.pop().unwrap(); - let children: Vec<_> = self.children - .drain(first_child..) - .collect(); - self.children.push( - GreenNode::new_branch(kind, children.into_boxed_slice()) - ); - } - - fn error(&mut self, message: String) { - self.errors.push(SyntaxError { - msg: message, - offset: self.pos, - }) - } - - fn finish(mut self) -> (GreenNode, Vec) { - assert_eq!(self.children.len(), 1); - let root = self.children.pop().unwrap(); - (root, self.errors) - } -} diff --git a/crates/libsyntax2/src/yellow/green.rs b/crates/libsyntax2/src/yellow/green.rs deleted file mode 100644 index 8fb691643..000000000 --- a/crates/libsyntax2/src/yellow/green.rs +++ /dev/null @@ -1,90 +0,0 @@ -use std::sync::Arc; - -use smol_str::SmolStr; - -use {SyntaxKind, TextUnit}; - -#[derive(Clone, Debug)] -pub(crate) enum GreenNode { - Leaf { - kind: SyntaxKind, - text: SmolStr, - }, - Branch(Arc), -} - -impl GreenNode { - pub(crate) fn new_leaf(kind: SyntaxKind, text: &str) -> GreenNode { - GreenNode::Leaf { kind, text: SmolStr::new(text) } - } - - pub(crate) fn new_branch(kind: SyntaxKind, children: Box<[GreenNode]>) -> GreenNode { - GreenNode::Branch(Arc::new(GreenBranch::new(kind, children))) - } - - pub fn kind(&self) -> SyntaxKind { - match self { - GreenNode::Leaf { kind, .. } => *kind, - GreenNode::Branch(b) => b.kind(), - } - } - - pub fn text_len(&self) -> TextUnit { - match self { - GreenNode::Leaf { text, .. } => TextUnit::from(text.len() as u32), - GreenNode::Branch(b) => b.text_len(), - } - } - - pub fn children(&self) -> &[GreenNode] { - match self { - GreenNode::Leaf { .. } => &[], - GreenNode::Branch(b) => b.children(), - } - } - - pub fn leaf_text_ref(&self) -> Option<&SmolStr> { - match self { - GreenNode::Leaf { text, .. } => Some(text), - GreenNode::Branch(_) => None, - } - } -} - -#[derive(Clone, Debug)] -pub(crate) struct GreenBranch { - text_len: TextUnit, - kind: SyntaxKind, - children: Box<[GreenNode]>, -} - -impl GreenBranch { - fn new(kind: SyntaxKind, children: Box<[GreenNode]>) -> GreenBranch { - let text_len = children.iter().map(|x| x.text_len()).sum::(); - GreenBranch { - text_len, - kind, - children, - } - } - - pub fn kind(&self) -> SyntaxKind { - self.kind - } - - pub fn text_len(&self) -> TextUnit { - self.text_len - } - - pub fn children(&self) -> &[GreenNode] { - &*self.children - } -} - -#[test] -fn test_sizes() { - use std::mem::size_of; - println!("GreenBranch = {}", size_of::()); - println!("GreenNode = {}", size_of::()); - println!("SmolStr = {}", size_of::()); -} diff --git a/crates/libsyntax2/src/yellow/mod.rs b/crates/libsyntax2/src/yellow/mod.rs deleted file mode 100644 index 0596e702f..000000000 --- a/crates/libsyntax2/src/yellow/mod.rs +++ /dev/null @@ -1,100 +0,0 @@ -mod builder; -mod green; -mod red; -mod syntax; -mod syntax_text; - -use std::{ - sync::Arc, - ptr, -}; -pub use self::syntax::{SyntaxNode, SyntaxNodeRef, SyntaxError, SyntaxNodeChildren}; -pub(crate) use self::{ - builder::GreenBuilder, - green::GreenNode, - red::RedNode, - syntax_text::SyntaxText, -}; - -#[derive(Debug)] -pub struct SyntaxRoot { - red: RedNode, - pub(crate) errors: Vec, -} - -pub trait TreeRoot: Clone + Send + Sync { - fn borrowed(&self) -> RefRoot; - fn owned(&self) -> OwnedRoot; - - #[doc(hidden)] - fn syntax_root(&self) -> &SyntaxRoot; -} -#[derive(Clone, Debug)] -pub struct OwnedRoot(Arc); -#[derive(Clone, Copy, Debug)] -pub struct RefRoot<'a>(&'a OwnedRoot); // TODO: shared_from_this instead of double indirection - -impl<'a> RefRoot<'a> { - fn syntax_root(&self) -> &'a SyntaxRoot { - self.0.syntax_root() - } -} - -impl TreeRoot for OwnedRoot { - fn borrowed(&self) -> RefRoot { - RefRoot(&self) - } - fn owned(&self) -> OwnedRoot { - self.clone() - } - - fn syntax_root(&self) -> &SyntaxRoot { - &*self.0 - } -} - -impl<'a> TreeRoot for RefRoot<'a> { - fn borrowed(&self) -> RefRoot { - *self - } - fn owned(&self) -> OwnedRoot { - self.0.clone() - } - fn syntax_root(&self) -> &SyntaxRoot { - self.0.syntax_root() - } -} - -impl SyntaxRoot { - pub(crate) fn new(green: GreenNode, errors: Vec) -> SyntaxRoot { - SyntaxRoot { - red: RedNode::new_root(green), - errors, - } - } -} - -#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] -pub(crate) struct RedPtr(ptr::NonNull); - -unsafe impl Send for RedPtr {} - -unsafe impl Sync for RedPtr {} - -impl RedPtr { - fn new(red: &RedNode) -> RedPtr { - RedPtr(red.into()) - } - - unsafe fn get<'a>(self, _root: &'a SyntaxRoot) -> &'a RedNode { - &*self.0.as_ptr() - } -} - -#[test] -fn assert_send_sync() { - fn f() {} - f::(); - f::(); - f::(); -} diff --git a/crates/libsyntax2/src/yellow/red.rs b/crates/libsyntax2/src/yellow/red.rs deleted file mode 100644 index 84cfe4fba..000000000 --- a/crates/libsyntax2/src/yellow/red.rs +++ /dev/null @@ -1,113 +0,0 @@ -use parking_lot::RwLock; -use {yellow::{GreenNode, RedPtr}, TextUnit}; - -#[derive(Debug)] -pub(crate) struct RedNode { - green: GreenNode, - parent: Option, - children: RwLock>, -} - -#[derive(Debug)] -enum RedChild { - Zigot(TextUnit), - Child(RedNode) -} - -impl RedChild { - fn set(&mut self, node: RedNode) -> &RedNode { - match self { - RedChild::Child(node) => return node, - RedChild::Zigot(_) => { - *self = RedChild::Child(node); - match self { - RedChild::Child(node) => return node, - RedChild::Zigot(_) => unreachable!() - } - } - } - } -} - -#[derive(Debug)] -struct ParentData { - parent: RedPtr, - start_offset: TextUnit, - index_in_parent: usize, -} - -impl RedNode { - pub fn new_root(green: GreenNode) -> RedNode { - RedNode::new(green, None) - } - - fn new_child( - green: GreenNode, - parent: RedPtr, - start_offset: TextUnit, - index_in_parent: usize, - ) -> RedNode { - let parent_data = ParentData { - parent, - start_offset, - index_in_parent, - }; - RedNode::new(green, Some(parent_data)) - } - - fn new(green: GreenNode, parent: Option) -> RedNode { - let mut start_offset = parent.as_ref().map(|it| it.start_offset).unwrap_or(0.into()); - let children = green.children() - .iter() - .map(|child| { - let off = start_offset; - start_offset += child.text_len(); - RedChild::Zigot(off) - }) - .collect::>() - .into_boxed_slice(); - RedNode { - green, - parent, - children: RwLock::new(children), - } - } - - pub(crate) fn green(&self) -> &GreenNode { - &self.green - } - - pub(crate) fn start_offset(&self) -> TextUnit { - match &self.parent { - None => 0.into(), - Some(p) => p.start_offset, - } - } - - pub(crate) fn n_children(&self) -> usize { - self.green.children().len() - } - - pub(crate) fn get_child(&self, idx: usize) -> Option { - if idx >= self.n_children() { - return None; - } - let start_offset = match &self.children.read()[idx] { - RedChild::Child(child) => return Some(RedPtr::new(child)), - RedChild::Zigot(start_offset) => *start_offset, - }; - let green_children = self.green.children(); - let child = - RedNode::new_child(green_children[idx].clone(), RedPtr::new(self), start_offset, idx); - let mut children = self.children.write(); - let child = children[idx].set(child); - Some(RedPtr::new(child)) - } - - pub(crate) fn parent(&self) -> Option { - Some(self.parent.as_ref()?.parent) - } - pub(crate) fn index_in_parent(&self) -> Option { - Some(self.parent.as_ref()?.index_in_parent) - } -} diff --git a/crates/libsyntax2/src/yellow/syntax.rs b/crates/libsyntax2/src/yellow/syntax.rs deleted file mode 100644 index 1d99cab4a..000000000 --- a/crates/libsyntax2/src/yellow/syntax.rs +++ /dev/null @@ -1,215 +0,0 @@ -use std::{ - fmt, sync::Arc, - hash::{Hasher, Hash}, - ops::Range, -}; - -use smol_str::SmolStr; - -use { - yellow::{GreenNode, RedNode, TreeRoot, SyntaxRoot, RedPtr, RefRoot, OwnedRoot, SyntaxText}, - SyntaxKind::{self, *}, - TextRange, TextUnit, -}; - - -#[derive(Clone, Copy)] -pub struct SyntaxNode { - pub(crate) root: R, - // Guaranteed to not dangle, because `root` holds a - // strong reference to red's ancestor - red: RedPtr, -} - -unsafe impl Send for SyntaxNode {} -unsafe impl Sync for SyntaxNode {} - -impl PartialEq> for SyntaxNode { - fn eq(&self, other: &SyntaxNode) -> bool { - self.red == other.red - } -} - -impl Eq for SyntaxNode {} -impl Hash for SyntaxNode { - fn hash(&self, state: &mut H) { - self.red.hash(state) - } -} - -pub type SyntaxNodeRef<'a> = SyntaxNode>; - -#[test] -fn syntax_node_ref_is_copy() { - fn assert_copy(){} - assert_copy::() -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct SyntaxError { - pub msg: String, - pub offset: TextUnit, -} - -impl SyntaxNode { - pub(crate) fn new_owned(root: SyntaxRoot) -> Self { - let root = OwnedRoot(Arc::new(root)); - let red = RedPtr::new(&root.syntax_root().red); - SyntaxNode { root, red } - } -} - -impl<'a> SyntaxNode> { - pub(crate) fn leaf_text_ref(self) -> Option<&'a SmolStr> { - let red = unsafe { self.red.get(self.root.syntax_root()) }; - red.green().leaf_text_ref() - } -} - -impl SyntaxNode { - pub fn borrowed<'a>(&'a self) -> SyntaxNodeRef<'a> { - SyntaxNode { - root: self.root.borrowed(), - red: self.red, - } - } - - pub fn owned(&self) -> SyntaxNode { - SyntaxNode { - root: self.root.owned(), - red: self.red, - } - } - - pub fn kind(&self) -> SyntaxKind { - self.red().green().kind() - } - - pub fn range(&self) -> TextRange { - let red = self.red(); - TextRange::offset_len(red.start_offset(), red.green().text_len()) - } - - pub fn text(&self) -> SyntaxText { - SyntaxText::new(self.borrowed()) - } - - pub fn children(&self) -> SyntaxNodeChildren { - SyntaxNodeChildren { - parent: self.clone(), - iter: (0..self.red().n_children()) - } - } - - pub fn parent(&self) -> Option> { - let parent = self.red().parent()?; - Some(SyntaxNode { - root: self.root.clone(), - red: parent, - }) - } - - pub fn first_child(&self) -> Option> { - let red = self.red().get_child(0)?; - Some(SyntaxNode { root: self.root.clone(), red }) - } - - pub fn last_child(&self) -> Option> { - let n = self.red().n_children(); - let n = n.checked_sub(1)?; - let red = self.red().get_child(n)?; - Some(SyntaxNode { root: self.root.clone(), red }) - } - - pub fn next_sibling(&self) -> Option> { - let red = self.red(); - let parent = self.parent()?; - let next_sibling_idx = red.index_in_parent()? + 1; - let sibling_red = parent.red().get_child(next_sibling_idx)?; - Some(SyntaxNode { - root: self.root.clone(), - red: sibling_red, - }) - } - - pub fn prev_sibling(&self) -> Option> { - let red = self.red(); - let parent = self.parent()?; - let prev_sibling_idx = red.index_in_parent()?.checked_sub(1)?; - let sibling_red = parent.red().get_child(prev_sibling_idx)?; - Some(SyntaxNode { - root: self.root.clone(), - red: sibling_red, - }) - } - - pub fn is_leaf(&self) -> bool { - self.first_child().is_none() - } - - pub fn leaf_text(&self) -> Option { - self.borrowed().leaf_text_ref().map(|it| it.clone()) - } - - pub(crate) fn replace_with(&self, green: GreenNode) -> GreenNode { - assert_eq!(self.kind(), green.kind()); - match self.parent() { - None => green, - Some(parent) => { - let children: Vec<_> = parent.children().map(|child| { - if child == *self { - green.clone() - } else { - child.red().green().clone() - } - }).collect(); - let new_parent = GreenNode::new_branch( - parent.kind(), - children.into_boxed_slice(), - ); - parent.replace_with(new_parent) - }, - } - } - - fn red(&self) -> &RedNode { - unsafe { self.red.get(self.root.syntax_root()) } - } -} - -impl fmt::Debug for SyntaxNode { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "{:?}@{:?}", self.kind(), self.range())?; - if has_short_text(self.kind()) { - write!(fmt, " \"{}\"", self.text())?; - } - Ok(()) - } -} - -#[derive(Debug)] -pub struct SyntaxNodeChildren { - parent: SyntaxNode, - iter: Range, -} - -impl Iterator for SyntaxNodeChildren { - type Item = SyntaxNode; - - fn next(&mut self) -> Option> { - self.iter.next().map(|i| { - let red = self.parent.red(); - SyntaxNode { - root: self.parent.root.clone(), - red: red.get_child(i).unwrap(), - } - }) - } -} - -fn has_short_text(kind: SyntaxKind) -> bool { - match kind { - IDENT | LIFETIME | INT_NUMBER | FLOAT_NUMBER => true, - _ => false, - } -} diff --git a/crates/libsyntax2/src/yellow/syntax_text.rs b/crates/libsyntax2/src/yellow/syntax_text.rs deleted file mode 100644 index 280bedd78..000000000 --- a/crates/libsyntax2/src/yellow/syntax_text.rs +++ /dev/null @@ -1,122 +0,0 @@ -use std::{ - fmt, ops, -}; - -use { - SyntaxNodeRef, TextRange, TextUnit, - algo::walk::preorder, - text_utils::{intersect, contains_offset_nonstrict}, -}; - -#[derive(Clone)] -pub struct SyntaxText<'a> { - node: SyntaxNodeRef<'a>, - range: TextRange, -} - -impl<'a> SyntaxText<'a> { - pub(crate) fn new(node: SyntaxNodeRef<'a>) -> SyntaxText<'a> { - SyntaxText { - node, - range: node.range() - } - } - pub fn chunks(&self) -> impl Iterator { - let range = self.range; - preorder(self.node) - .filter_map(move |node| { - let text = node.leaf_text_ref()?; - let range = intersect(range, node.range())?; - let range = range - node.range().start(); - Some(&text[range]) - }) - } - pub fn push_to(&self, buf: &mut String) { - self.chunks().for_each(|it| buf.push_str(it)); - } - pub fn to_string(&self) -> String { - self.chunks().collect() - } - pub fn contains(&self, c: char) -> bool { - self.chunks().any(|it| it.contains(c)) - } - pub fn find(&self, c: char) -> Option { - let mut acc: TextUnit = 0.into(); - for chunk in self.chunks() { - if let Some(pos) = chunk.find(c) { - let pos: TextUnit = (pos as u32).into(); - return Some(acc + pos); - } - acc += TextUnit::of_str(chunk); - } - None - } - pub fn len(&self) -> TextUnit { - self.range.len() - } - pub fn slice(&self, range: impl SyntaxTextSlice) -> SyntaxText<'a> { - let range = range.restrict(self.range) - .unwrap_or_else(|| { - panic!("invalid slice, range: {:?}, slice: {:?}", self.range, range) - }); - SyntaxText { node: self.node, range } - } - pub fn char_at(&self, offset: TextUnit) -> Option { - let mut start: TextUnit = 0.into(); - for chunk in self.chunks() { - let end = start + TextUnit::of_str(chunk); - if start <= offset && offset < end { - let off: usize = u32::from(offset - start) as usize; - return Some(chunk[off..].chars().next().unwrap()); - } - start = end; - } - None - } -} - -impl<'a> fmt::Debug for SyntaxText<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&self.to_string(), f) - } -} - -impl<'a> fmt::Display for SyntaxText<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(&self.to_string(), f) - } -} - -pub trait SyntaxTextSlice: fmt::Debug { - fn restrict(&self, range: TextRange) -> Option; -} - -impl SyntaxTextSlice for TextRange { - fn restrict(&self, range: TextRange) -> Option { - intersect(*self, range) - } -} - -impl SyntaxTextSlice for ops::RangeTo { - fn restrict(&self, range: TextRange) -> Option { - if !contains_offset_nonstrict(range, self.end) { - return None; - } - Some(TextRange::from_to(range.start(), self.end)) - } -} - -impl SyntaxTextSlice for ops::RangeFrom { - fn restrict(&self, range: TextRange) -> Option { - if !contains_offset_nonstrict(range, self.start) { - return None; - } - Some(TextRange::from_to(self.start, range.end())) - } -} - -impl SyntaxTextSlice for ops::Range { - fn restrict(&self, range: TextRange) -> Option { - TextRange::from_to(self.start, self.end).restrict(range) - } -} -- cgit v1.2.3