From 60f4d7bd8c0ecb9f23557464e824140a2be8f41a Mon Sep 17 00:00:00 2001 From: Luca Barbieri Date: Fri, 3 Apr 2020 21:12:09 +0200 Subject: [PATCH 1/2] Provide more complete AST accessors to support usage in rustc --- crates/ra_assists/src/handlers/add_impl.rs | 4 +- crates/ra_assists/src/handlers/add_new.rs | 5 +- .../src/handlers/introduce_variable.rs | 4 +- .../ra_assists/src/handlers/merge_imports.rs | 4 +- crates/ra_fmt/src/lib.rs | 6 +- crates/ra_hir_def/src/body/lower.rs | 10 +- crates/ra_hir_def/src/nameres/raw.rs | 4 + crates/ra_hir_def/src/path/lower.rs | 2 +- crates/ra_hir_def/src/path/lower/lower_use.rs | 2 +- crates/ra_hir_def/src/visibility.rs | 4 + crates/ra_hir_ty/src/tests.rs | 4 +- crates/ra_parser/src/syntax_kind/generated.rs | 6 +- crates/ra_syntax/src/ast.rs | 2 +- crates/ra_syntax/src/ast/edit.rs | 26 +- crates/ra_syntax/src/ast/expr_extensions.rs | 4 + crates/ra_syntax/src/ast/extensions.rs | 148 +++---- crates/ra_syntax/src/ast/traits.rs | 32 +- xtask/src/ast_src.rs | 377 ++++++++++++++---- 18 files changed, 433 insertions(+), 211 deletions(-) diff --git a/crates/ra_assists/src/handlers/add_impl.rs b/crates/ra_assists/src/handlers/add_impl.rs index 6622eadb2d..72a201b6d2 100644 --- a/crates/ra_assists/src/handlers/add_impl.rs +++ b/crates/ra_assists/src/handlers/add_impl.rs @@ -1,5 +1,5 @@ use ra_syntax::{ - ast::{self, AstNode, NameOwner, TypeParamsOwner}, + ast::{self, AstNode, AstToken, NameOwner, TypeParamsOwner}, TextUnit, }; use stdx::{format_to, SepBy}; @@ -42,7 +42,7 @@ pub(crate) fn add_impl(ctx: AssistCtx) -> Option { if let Some(type_params) = type_params { let lifetime_params = type_params .lifetime_params() - .filter_map(|it| it.lifetime_token()) + .filter_map(|it| it.lifetime()) .map(|it| it.text().clone()); let type_params = type_params.type_params().filter_map(|it| it.name()).map(|it| it.text().clone()); diff --git a/crates/ra_assists/src/handlers/add_new.rs b/crates/ra_assists/src/handlers/add_new.rs index 240b19fa37..c10397249f 100644 --- a/crates/ra_assists/src/handlers/add_new.rs +++ b/crates/ra_assists/src/handlers/add_new.rs @@ -1,7 +1,8 @@ use hir::Adt; use ra_syntax::{ ast::{ - self, AstNode, NameOwner, StructKind, TypeAscriptionOwner, TypeParamsOwner, VisibilityOwner, + self, AstNode, AstToken, NameOwner, StructKind, TypeAscriptionOwner, TypeParamsOwner, + VisibilityOwner, }, TextUnit, T, }; @@ -105,7 +106,7 @@ fn generate_impl_text(strukt: &ast::StructDef, code: &str) -> String { if let Some(type_params) = type_params { let lifetime_params = type_params .lifetime_params() - .filter_map(|it| it.lifetime_token()) + .filter_map(|it| it.lifetime()) .map(|it| it.text().clone()); let type_params = type_params.type_params().filter_map(|it| it.name()).map(|it| it.text().clone()); diff --git a/crates/ra_assists/src/handlers/introduce_variable.rs b/crates/ra_assists/src/handlers/introduce_variable.rs index 1edbdc14c7..9963f884bb 100644 --- a/crates/ra_assists/src/handlers/introduce_variable.rs +++ b/crates/ra_assists/src/handlers/introduce_variable.rs @@ -1,5 +1,5 @@ use ra_syntax::{ - ast::{self, AstNode}, + ast::{self, AstElement, AstNode}, SyntaxKind::{ BLOCK_EXPR, BREAK_EXPR, COMMENT, LAMBDA_EXPR, LOOP_EXPR, MATCH_ARM, PATH_EXPR, RETURN_EXPR, WHITESPACE, @@ -124,7 +124,7 @@ fn anchor_stmt(expr: ast::Expr) -> Option<(SyntaxNode, bool)> { } } - if ast::Stmt::cast(node.clone()).is_some() { + if ast::Stmt::cast_element(node.clone().into()).is_some() { return Some((node, false)); } diff --git a/crates/ra_assists/src/handlers/merge_imports.rs b/crates/ra_assists/src/handlers/merge_imports.rs index 5d4b74e567..f8b3ddb4e1 100644 --- a/crates/ra_assists/src/handlers/merge_imports.rs +++ b/crates/ra_assists/src/handlers/merge_imports.rs @@ -3,7 +3,7 @@ use std::iter::successors; use ra_syntax::{ algo::{neighbor, SyntaxRewriter}, ast::{self, edit::AstNodeEdit, make}, - AstNode, Direction, InsertPosition, SyntaxElement, T, + AstNode, AstToken, Direction, InsertPosition, SyntaxElement, T, }; use crate::{Assist, AssistCtx, AssistId}; @@ -82,7 +82,7 @@ fn try_merge_trees(old: &ast::UseTree, new: &ast::UseTree) -> Option Option { } else { // Unwrap `{ continue; }` let (stmt,) = block.statements().next_tuple()?; - if has_anything_else(stmt.syntax()) { - return None; - } if let ast::Stmt::ExprStmt(expr_stmt) = stmt { + if has_anything_else(expr_stmt.syntax()) { + return None; + } let expr = expr_stmt.expr()?; match expr.syntax().kind() { CONTINUE_EXPR | BREAK_EXPR | RETURN_EXPR => return Some(expr), diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 8d4b8b0f0f..8338414faa 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -482,14 +482,17 @@ impl ExprCollector<'_> { self.collect_block_items(&block); let statements = block .statements() - .map(|s| match s { + .filter_map(|s| match s { ast::Stmt::LetStmt(stmt) => { let pat = self.collect_pat_opt(stmt.pat()); let type_ref = stmt.ascribed_type().map(TypeRef::from_ast); let initializer = stmt.initializer().map(|e| self.collect_expr(e)); - Statement::Let { pat, type_ref, initializer } + Some(Statement::Let { pat, type_ref, initializer }) } - ast::Stmt::ExprStmt(stmt) => Statement::Expr(self.collect_expr_opt(stmt.expr())), + ast::Stmt::ExprStmt(stmt) => { + Some(Statement::Expr(self.collect_expr_opt(stmt.expr()))) + } + ast::Stmt::ModuleItem(_) => None, }) .collect(); let tail = block.expr().map(|e| self.collect_expr(e)); @@ -541,6 +544,7 @@ impl ExprCollector<'_> { let ast_id = self.expander.ast_id(&def); (TraitLoc { container, ast_id }.intern(self.db).into(), def.name()) } + ast::ModuleItem::ExternBlock(_) => continue, // FIXME: collect from extern blocks ast::ModuleItem::ImplDef(_) | ast::ModuleItem::UseItem(_) | ast::ModuleItem::ExternCrateItem(_) diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index 8f190e7f91..a9dff3a5d5 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs @@ -266,6 +266,10 @@ impl RawItemsCollector { self.add_macro(current_module, it); return; } + ast::ModuleItem::ExternBlock(_) => { + // FIXME: add extern block + return; + } }; if let Some(name) = name { let name = name.as_name(); diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs index 4900000fe4..3c13cb2c78 100644 --- a/crates/ra_hir_def/src/path/lower.rs +++ b/crates/ra_hir_def/src/path/lower.rs @@ -28,7 +28,7 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option loop { let segment = path.segment()?; - if segment.has_colon_colon() { + if segment.coloncolon().is_some() { kind = PathKind::Abs; } diff --git a/crates/ra_hir_def/src/path/lower/lower_use.rs b/crates/ra_hir_def/src/path/lower/lower_use.rs index 278d5196e7..6ec944228c 100644 --- a/crates/ra_hir_def/src/path/lower/lower_use.rs +++ b/crates/ra_hir_def/src/path/lower/lower_use.rs @@ -34,7 +34,7 @@ pub(crate) fn lower_use_tree( let alias = tree.alias().map(|a| { a.name().map(|it| it.as_name()).map_or(ImportAlias::Underscore, ImportAlias::Alias) }); - let is_glob = tree.has_star(); + let is_glob = tree.star().is_some(); if let Some(ast_path) = tree.path() { // Handle self in a path. // E.g. `use something::{self, <...>}` diff --git a/crates/ra_hir_def/src/visibility.rs b/crates/ra_hir_def/src/visibility.rs index 62513873ef..1482d3be04 100644 --- a/crates/ra_hir_def/src/visibility.rs +++ b/crates/ra_hir_def/src/visibility.rs @@ -84,6 +84,10 @@ impl RawVisibility { let path = ModPath { kind: PathKind::Super(1), segments: Vec::new() }; RawVisibility::Module(path) } + ast::VisibilityKind::PubSelf => { + let path = ModPath { kind: PathKind::Plain, segments: Vec::new() }; + RawVisibility::Module(path) + } ast::VisibilityKind::Pub => RawVisibility::Public, } } diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs index 608408d88c..ac09662368 100644 --- a/crates/ra_hir_ty/src/tests.rs +++ b/crates/ra_hir_ty/src/tests.rs @@ -23,7 +23,7 @@ use insta::assert_snapshot; use ra_db::{fixture::WithFixture, salsa::Database, FilePosition, SourceDatabase}; use ra_syntax::{ algo, - ast::{self, AstNode}, + ast::{self, AstNode, AstToken}, }; use stdx::format_to; @@ -101,7 +101,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { let node = src_ptr.value.to_node(&src_ptr.file_syntax(&db)); let (range, text) = if let Some(self_param) = ast::SelfParam::cast(node.clone()) { - (self_param.self_kw_token().text_range(), "self".to_string()) + (self_param.self_kw().unwrap().syntax().text_range(), "self".to_string()) } else { (src_ptr.value.range(), node.text().to_string().replace("\n", " ")) }; diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs index 4c16cf1cd9..004f4e5643 100644 --- a/crates/ra_parser/src/syntax_kind/generated.rs +++ b/crates/ra_parser/src/syntax_kind/generated.rs @@ -105,6 +105,7 @@ pub enum SyntaxKind { DEFAULT_KW, EXISTENTIAL_KW, UNION_KW, + RAW_KW, INT_NUMBER, FLOAT_NUMBER, CHAR, @@ -258,7 +259,7 @@ impl SyntaxKind { | IMPL_KW | IN_KW | LET_KW | LOOP_KW | MACRO_KW | MATCH_KW | MOD_KW | MOVE_KW | MUT_KW | PUB_KW | REF_KW | RETURN_KW | SELF_KW | STATIC_KW | STRUCT_KW | SUPER_KW | TRAIT_KW | TRUE_KW | TRY_KW | TYPE_KW | UNSAFE_KW | USE_KW | WHERE_KW | WHILE_KW - | AUTO_KW | DEFAULT_KW | EXISTENTIAL_KW | UNION_KW => true, + | AUTO_KW | DEFAULT_KW | EXISTENTIAL_KW | UNION_KW | RAW_KW => true, _ => false, } } @@ -651,4 +652,7 @@ macro_rules! T { ( union ) => { $crate::SyntaxKind::UNION_KW }; + ( raw ) => { + $crate::SyntaxKind::RAW_KW + }; } diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index ab0f44dd2e..c81b68d3e2 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs @@ -271,7 +271,7 @@ where let pred = predicates.next().unwrap(); let mut bounds = pred.type_bound_list().unwrap().bounds(); - assert_eq!("'a", pred.lifetime_token().unwrap().text()); + assert_eq!("'a", pred.lifetime().unwrap().text()); assert_bound("'b", bounds.next()); assert_bound("'c", bounds.next()); diff --git a/crates/ra_syntax/src/ast/edit.rs b/crates/ra_syntax/src/ast/edit.rs index b69cae234c..d793109953 100644 --- a/crates/ra_syntax/src/ast/edit.rs +++ b/crates/ra_syntax/src/ast/edit.rs @@ -99,7 +99,7 @@ impl ast::ItemList { None => match self.l_curly() { Some(it) => ( " ".to_string() + &leading_indent(self.syntax()).unwrap_or_default(), - InsertPosition::After(it), + InsertPosition::After(it.syntax().clone().into()), ), None => return self.clone(), }, @@ -109,10 +109,6 @@ impl ast::ItemList { [ws.ws().into(), item.syntax().clone().into()].into(); self.insert_children(position, to_insert) } - - fn l_curly(&self) -> Option { - self.syntax().children_with_tokens().find(|it| it.kind() == T!['{']) - } } impl ast::RecordFieldList { @@ -147,7 +143,7 @@ impl ast::RecordFieldList { macro_rules! after_l_curly { () => {{ let anchor = match self.l_curly() { - Some(it) => it, + Some(it) => it.syntax().clone().into(), None => return self.clone(), }; InsertPosition::After(anchor) @@ -189,24 +185,20 @@ impl ast::RecordFieldList { self.insert_children(position, to_insert) } - - fn l_curly(&self) -> Option { - self.syntax().children_with_tokens().find(|it| it.kind() == T!['{']) - } } impl ast::TypeParam { #[must_use] pub fn remove_bounds(&self) -> ast::TypeParam { - let colon = match self.colon_token() { + let colon = match self.colon() { Some(it) => it, None => return self.clone(), }; let end = match self.type_bound_list() { Some(it) => it.syntax().clone().into(), - None => colon.clone().into(), + None => colon.syntax().clone().into(), }; - self.replace_children(colon.into()..=end, iter::empty()) + self.replace_children(colon.syntax().clone().into()..=end, iter::empty()) } } @@ -305,8 +297,12 @@ impl ast::UseTree { Some(it) => it, None => return self.clone(), }; - let use_tree = - make::use_tree(suffix.clone(), self.use_tree_list(), self.alias(), self.has_star()); + let use_tree = make::use_tree( + suffix.clone(), + self.use_tree_list(), + self.alias(), + self.star().is_some(), + ); let nested = make::use_tree_list(iter::once(use_tree)); return make::use_tree(prefix.clone(), Some(nested), None, false); diff --git a/crates/ra_syntax/src/ast/expr_extensions.rs b/crates/ra_syntax/src/ast/expr_extensions.rs index 8bbd946c07..40c8fca3be 100644 --- a/crates/ra_syntax/src/ast/expr_extensions.rs +++ b/crates/ra_syntax/src/ast/expr_extensions.rs @@ -52,6 +52,10 @@ impl ast::RefExpr { pub fn is_mut(&self) -> bool { self.syntax().children_with_tokens().any(|n| n.kind() == T![mut]) } + + pub fn raw_token(&self) -> Option { + None // FIXME: implement &raw + } } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs index bf7d137be7..400eba210a 100644 --- a/crates/ra_syntax/src/ast/extensions.rs +++ b/crates/ra_syntax/src/ast/extensions.rs @@ -4,7 +4,10 @@ use itertools::Itertools; use crate::{ - ast::{self, child_opt, children, AstNode, AttrInput, NameOwner, SyntaxNode}, + ast::{ + self, child_opt, child_token_opt, children, AstElement, AstNode, AstToken, AttrInput, + NameOwner, SyntaxNode, + }, SmolStr, SyntaxElement, SyntaxKind::*, SyntaxToken, T, @@ -130,13 +133,6 @@ impl ast::PathSegment { }; Some(res) } - - pub fn has_colon_colon(&self) -> bool { - match self.syntax.first_child_or_token().map(|s| s.kind()) { - Some(T![::]) => true, - _ => false, - } - } } impl ast::Path { @@ -154,12 +150,6 @@ impl ast::Module { } } -impl ast::UseTree { - pub fn has_star(&self) -> bool { - self.syntax().children_with_tokens().any(|it| it.kind() == T![*]) - } -} - impl ast::UseTreeList { pub fn parent_use_tree(&self) -> ast::UseTree { self.syntax() @@ -167,20 +157,6 @@ impl ast::UseTreeList { .and_then(ast::UseTree::cast) .expect("UseTreeLists are always nested in UseTrees") } - pub fn l_curly(&self) -> Option { - self.token(T!['{']) - } - - pub fn r_curly(&self) -> Option { - self.token(T!['}']) - } - - fn token(&self, kind: SyntaxKind) -> Option { - self.syntax() - .children_with_tokens() - .filter_map(|it| it.into_token()) - .find(|it| it.kind() == kind) - } } impl ast::ImplDef { @@ -387,24 +363,9 @@ pub enum SelfParamKind { } impl ast::SelfParam { - pub fn self_kw_token(&self) -> SyntaxToken { - self.syntax() - .children_with_tokens() - .filter_map(|it| it.into_token()) - .find(|it| it.kind() == T![self]) - .expect("invalid tree: self param must have self") - } - pub fn kind(&self) -> SelfParamKind { - let borrowed = self.syntax().children_with_tokens().any(|n| n.kind() == T![&]); - if borrowed { - // check for a `mut` coming after the & -- `mut &self` != `&mut self` - if self - .syntax() - .children_with_tokens() - .skip_while(|n| n.kind() != T![&]) - .any(|n| n.kind() == T![mut]) - { + if self.amp().is_some() { + if self.amp_mut_kw().is_some() { SelfParamKind::MutRef } else { SelfParamKind::Ref @@ -413,32 +374,23 @@ impl ast::SelfParam { SelfParamKind::Owned } } -} -impl ast::LifetimeParam { - pub fn lifetime_token(&self) -> Option { + /// the "mut" in "mut self", not the one in "&mut self" + pub fn mut_kw(&self) -> Option { self.syntax() .children_with_tokens() .filter_map(|it| it.into_token()) - .find(|it| it.kind() == LIFETIME) + .take_while(|it| it.kind() != T![&]) + .find_map(ast::MutKw::cast) } -} -impl ast::TypeParam { - pub fn colon_token(&self) -> Option { + /// the "mut" in "&mut self", not the one in "mut self" + pub fn amp_mut_kw(&self) -> Option { self.syntax() .children_with_tokens() .filter_map(|it| it.into_token()) - .find(|it| it.kind() == T![:]) - } -} - -impl ast::WherePred { - pub fn lifetime_token(&self) -> Option { - self.syntax() - .children_with_tokens() - .filter_map(|it| it.into_token()) - .find(|it| it.kind() == LIFETIME) + .skip_while(|it| it.kind() != T![&]) + .find_map(ast::MutKw::cast) } } @@ -449,7 +401,7 @@ pub enum TypeBoundKind { /// for<'a> ... ForType(ast::ForType), /// 'a - Lifetime(ast::SyntaxToken), + Lifetime(ast::Lifetime), } impl ast::TypeBound { @@ -465,21 +417,28 @@ impl ast::TypeBound { } } - fn lifetime(&self) -> Option { - self.syntax() - .children_with_tokens() - .filter_map(|it| it.into_token()) - .find(|it| it.kind() == LIFETIME) + pub fn has_question_mark(&self) -> bool { + self.question().is_some() } - pub fn question_mark_token(&self) -> Option { + pub fn const_question(&self) -> Option { self.syntax() .children_with_tokens() .filter_map(|it| it.into_token()) - .find(|it| it.kind() == T![?]) + .take_while(|it| it.kind() != T![const]) + .find_map(ast::Question::cast) } - pub fn has_question_mark(&self) -> bool { - self.question_mark_token().is_some() + + pub fn question(&self) -> Option { + if self.const_kw().is_some() { + self.syntax() + .children_with_tokens() + .filter_map(|it| it.into_token()) + .skip_while(|it| it.kind() != T![const]) + .find_map(ast::Question::cast) + } else { + child_token_opt(self) + } } } @@ -493,6 +452,7 @@ pub enum VisibilityKind { In(ast::Path), PubCrate, PubSuper, + PubSelf, Pub, } @@ -504,6 +464,8 @@ impl ast::Visibility { VisibilityKind::PubCrate } else if self.is_pub_super() { VisibilityKind::PubSuper + } else if self.is_pub_self() { + VisibilityKind::PubSuper } else { VisibilityKind::Pub } @@ -516,6 +478,10 @@ impl ast::Visibility { fn is_pub_super(&self) -> bool { self.syntax().children_with_tokens().any(|it| it.kind() == T![super]) } + + fn is_pub_self(&self) -> bool { + self.syntax().children_with_tokens().any(|it| it.kind() == T![self]) + } } impl ast::MacroCall { @@ -528,3 +494,41 @@ impl ast::MacroCall { } } } + +impl ast::LifetimeParam { + pub fn lifetime_bounds(&self) -> impl Iterator { + self.syntax() + .children_with_tokens() + .filter_map(|it| it.into_token()) + .skip_while(|x| x.kind() != T![:]) + .filter_map(ast::Lifetime::cast) + } +} + +impl ast::RangePat { + pub fn start(&self) -> Option { + self.syntax() + .children_with_tokens() + .take_while(|it| !ast::RangeSeparator::can_cast_element(it.kind())) + .filter_map(|it| it.into_node()) + .find_map(ast::Pat::cast) + } + + pub fn end(&self) -> Option { + self.syntax() + .children_with_tokens() + .skip_while(|it| !ast::RangeSeparator::can_cast_element(it.kind())) + .filter_map(|it| it.into_node()) + .find_map(ast::Pat::cast) + } +} + +impl ast::TokenTree { + pub fn left_delimiter(&self) -> Option { + self.syntax().first_child_or_token().and_then(ast::LeftDelimiter::cast_element) + } + + pub fn right_delimiter(&self) -> Option { + self.syntax().last_child_or_token().and_then(ast::RightDelimiter::cast_element) + } +} diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs index 576378306f..e6f3a4ebb7 100644 --- a/crates/ra_syntax/src/ast/traits.rs +++ b/crates/ra_syntax/src/ast/traits.rs @@ -4,9 +4,9 @@ use itertools::Itertools; -use crate::{ - ast::{self, child_opt, children, AstChildren, AstNode, AstToken}, - syntax_node::SyntaxElementChildren, +use crate::ast::{ + self, child_elements, child_opt, child_token_opt, child_tokens, children, AstChildElements, + AstChildTokens, AstChildren, AstNode, AstToken, }; pub trait TypeAscriptionOwner: AstNode { @@ -31,6 +31,10 @@ pub trait LoopBodyOwner: AstNode { fn loop_body(&self) -> Option { child_opt(self) } + + fn label(&self) -> Option { + child_opt(self) + } } pub trait ArgListOwner: AstNode { @@ -65,6 +69,10 @@ pub trait TypeBoundsOwner: AstNode { fn type_bound_list(&self) -> Option { child_opt(self) } + + fn colon(&self) -> Option { + child_token_opt(self) + } } pub trait AttrsOwner: AstNode { @@ -74,11 +82,14 @@ pub trait AttrsOwner: AstNode { fn has_atom_attr(&self, atom: &str) -> bool { self.attrs().filter_map(|x| x.as_simple_atom()).any(|x| x == atom) } + fn attr_or_comments(&self) -> AstChildElements { + child_elements(self) + } } pub trait DocCommentsOwner: AstNode { - fn doc_comments(&self) -> CommentIter { - CommentIter { iter: self.syntax().children_with_tokens() } + fn doc_comments(&self) -> AstChildTokens { + child_tokens(self) } /// Returns the textual content of a doc comment block as a single string. @@ -123,14 +134,3 @@ pub trait DocCommentsOwner: AstNode { } } } - -pub struct CommentIter { - iter: SyntaxElementChildren, -} - -impl Iterator for CommentIter { - type Item = ast::Comment; - fn next(&mut self) -> Option { - self.iter.by_ref().find_map(|el| el.into_token().and_then(ast::Comment::cast)) - } -} diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs index d9f51ec399..3200acc867 100644 --- a/xtask/src/ast_src.rs +++ b/xtask/src/ast_src.rs @@ -70,7 +70,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc { "match", "mod", "move", "mut", "pub", "ref", "return", "self", "static", "struct", "super", "trait", "true", "try", "type", "unsafe", "use", "where", "while", ], - contextual_keywords: &["auto", "default", "existential", "union"], + contextual_keywords: &["auto", "default", "existential", "union", "raw"], literals: &[ "INT_NUMBER", "FLOAT_NUMBER", @@ -297,235 +297,311 @@ macro_rules! ast_enums { pub(crate) const AST_SRC: AstSrc = AstSrc { nodes: &ast_nodes! { - struct SourceFile: ModuleItemOwner, FnDefOwner { + struct SourceFile: ModuleItemOwner, FnDefOwner, AttrsOwner { modules: [Module], } struct FnDef: VisibilityOwner, NameOwner, TypeParamsOwner, DocCommentsOwner, AttrsOwner { + Abi, + ConstKw, + DefaultKw, + AsyncKw, + UnsafeKw, + FnKw, ParamList, RetType, body: BlockExpr, + Semi } - struct RetType { TypeRef } + struct RetType { ThinArrow, TypeRef } struct StructDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner { + StructKw, + FieldDefList, + Semi } struct UnionDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner { + UnionKw, RecordFieldDefList, } - struct RecordFieldDefList { fields: [RecordFieldDef] } + struct RecordFieldDefList { LCurly, fields: [RecordFieldDef], RCurly } struct RecordFieldDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner { } - struct TupleFieldDefList { fields: [TupleFieldDef] } + struct TupleFieldDefList { LParen, fields: [TupleFieldDef], RParen } struct TupleFieldDef: VisibilityOwner, AttrsOwner { TypeRef, } struct EnumDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner { + EnumKw, variant_list: EnumVariantList, } struct EnumVariantList { + LCurly, variants: [EnumVariant], + RCurly } - struct EnumVariant: NameOwner, DocCommentsOwner, AttrsOwner { + struct EnumVariant: VisibilityOwner, NameOwner, DocCommentsOwner, AttrsOwner { + FieldDefList, + Eq, Expr } struct TraitDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeParamsOwner, TypeBoundsOwner { + UnsafeKw, + AutoKw, + TraitKw, ItemList, } struct Module: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner { + ModKw, ItemList, + Semi } struct ItemList: FnDefOwner, ModuleItemOwner { + LCurly, impl_items: [ImplItem], + RCurly } struct ConstDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner { + DefaultKw, + ConstKw, + Eq, body: Expr, + Semi } struct StaticDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner { + StaticKw, + MutKw, + Eq, body: Expr, + Semi } struct TypeAliasDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeBoundsOwner { + DefaultKw, + TypeKw, + Eq, TypeRef, + Semi } struct ImplDef: TypeParamsOwner, AttrsOwner { + DefaultKw, + ConstKw, + UnsafeKw, + ImplKw, + Excl, + ForKw, ItemList, } - struct ParenType { TypeRef } - struct TupleType { fields: [TypeRef] } - struct NeverType { } + struct ParenType { LParen, TypeRef, RParen } + struct TupleType { LParen, fields: [TypeRef], RParen } + struct NeverType { Excl } struct PathType { Path } - struct PointerType { TypeRef } - struct ArrayType { TypeRef, Expr } - struct SliceType { TypeRef } - struct ReferenceType { TypeRef } - struct PlaceholderType { } - struct FnPointerType { ParamList, RetType } - struct ForType { TypeRef } - struct ImplTraitType: TypeBoundsOwner {} - struct DynTraitType: TypeBoundsOwner {} + struct PointerType { Star, ConstKw, TypeRef } + struct ArrayType { LBrack, TypeRef, Semi, Expr, RBrack } + struct SliceType { LBrack, TypeRef, RBrack } + struct ReferenceType { Amp, Lifetime, MutKw, TypeRef } + struct PlaceholderType { Underscore } + struct FnPointerType { Abi, UnsafeKw, FnKw, ParamList, RetType } + struct ForType { ForKw, TypeParamList, TypeRef } + struct ImplTraitType: TypeBoundsOwner { ImplKw } + struct DynTraitType: TypeBoundsOwner { DynKw } - struct TupleExpr { exprs: [Expr] } - struct ArrayExpr { exprs: [Expr] } - struct ParenExpr { Expr } + struct TupleExpr: AttrsOwner { LParen, exprs: [Expr], RParen } + struct ArrayExpr: AttrsOwner { LBrack, exprs: [Expr], Semi, RBrack } + struct ParenExpr: AttrsOwner { LParen, Expr, RParen } struct PathExpr { Path } - struct LambdaExpr { + struct LambdaExpr: AttrsOwner { + StaticKw, + AsyncKw, + MoveKw, ParamList, RetType, body: Expr, } - struct IfExpr { Condition } - struct LoopExpr: LoopBodyOwner { } - struct TryBlockExpr { body: BlockExpr } - struct ForExpr: LoopBodyOwner { + struct IfExpr: AttrsOwner { IfKw, Condition } + struct LoopExpr: AttrsOwner, LoopBodyOwner { LoopKw } + struct TryBlockExpr: AttrsOwner { TryKw, body: BlockExpr } + struct ForExpr: AttrsOwner, LoopBodyOwner { + ForKw, Pat, + InKw, iterable: Expr, } - struct WhileExpr: LoopBodyOwner { Condition } - struct ContinueExpr {} - struct BreakExpr { Expr } - struct Label {} - struct BlockExpr { Block } - struct ReturnExpr { Expr } + struct WhileExpr: AttrsOwner, LoopBodyOwner { WhileKw, Condition } + struct ContinueExpr: AttrsOwner { ContinueKw, Lifetime } + struct BreakExpr: AttrsOwner { BreakKw, Lifetime, Expr } + struct Label { Lifetime } + struct BlockExpr: AttrsOwner { Label, UnsafeKw, Block } + struct ReturnExpr: AttrsOwner { Expr } struct CallExpr: ArgListOwner { Expr } - struct MethodCallExpr: ArgListOwner { - Expr, NameRef, TypeArgList, + struct MethodCallExpr: AttrsOwner, ArgListOwner { + Expr, Dot, NameRef, TypeArgList, } - struct IndexExpr {} - struct FieldExpr { Expr, NameRef } - struct AwaitExpr { Expr } - struct TryExpr { Expr } - struct CastExpr { Expr, TypeRef } - struct RefExpr { Expr } - struct PrefixExpr { Expr } - struct BoxExpr { Expr } - struct RangeExpr {} - struct BinExpr {} - struct Literal {} + struct IndexExpr: AttrsOwner { LBrack, RBrack } + struct FieldExpr: AttrsOwner { Expr, Dot, NameRef } + struct AwaitExpr: AttrsOwner { Expr, Dot, AwaitKw } + struct TryExpr: AttrsOwner { TryKw, Expr } + struct CastExpr: AttrsOwner { Expr, AsKw, TypeRef } + struct RefExpr: AttrsOwner { Amp, RawKw, MutKw, Expr } + struct PrefixExpr: AttrsOwner { PrefixOp, Expr } + struct BoxExpr: AttrsOwner { BoxKw, Expr } + struct RangeExpr: AttrsOwner { RangeOp } + struct BinExpr: AttrsOwner { BinOp } + struct Literal { LiteralToken } - struct MatchExpr { Expr, MatchArmList } - struct MatchArmList: AttrsOwner { arms: [MatchArm] } + struct MatchExpr: AttrsOwner { MatchKw, Expr, MatchArmList } + struct MatchArmList: AttrsOwner { LCurly, arms: [MatchArm], RCurly } struct MatchArm: AttrsOwner { pat: Pat, guard: MatchGuard, + FatArrow, Expr, } - struct MatchGuard { Expr } + struct MatchGuard { IfKw, Expr } - struct RecordLit { Path, RecordFieldList } + struct RecordLit { Path, RecordFieldList} struct RecordFieldList { + LCurly, fields: [RecordField], + Dotdot, spread: Expr, + RCurly } - struct RecordField { NameRef, Expr } + struct RecordField: AttrsOwner { NameRef, Colon, Expr } struct OrPat { pats: [Pat] } - struct ParenPat { Pat } - struct RefPat { Pat } - struct BoxPat { Pat } - struct BindPat: NameOwner { Pat } - struct PlaceholderPat { } - struct DotDotPat { } + struct ParenPat { LParen, Pat, RParen } + struct RefPat { Amp, MutKw, Pat } + struct BoxPat { BoxKw, Pat } + struct BindPat: AttrsOwner, NameOwner { RefKw, MutKw, Pat } + struct PlaceholderPat { Underscore } + struct DotDotPat { Dotdot } struct PathPat { Path } - struct SlicePat { args: [Pat] } - struct RangePat {} + struct SlicePat { LBrack, args: [Pat], RBrack } + struct RangePat { RangeSeparator } struct LiteralPat { Literal } struct MacroPat { MacroCall } struct RecordPat { RecordFieldPatList, Path } struct RecordFieldPatList { + LCurly, + pats: [RecordInnerPat], record_field_pats: [RecordFieldPat], bind_pats: [BindPat], + Dotdot, + RCurly } - struct RecordFieldPat: NameOwner { Pat } + struct RecordFieldPat: AttrsOwner, NameOwner { Colon, Pat } - struct TupleStructPat { Path, args: [Pat] } - struct TuplePat { args: [Pat] } + struct TupleStructPat { Path, LParen, args: [Pat], RParen } + struct TuplePat { LParen, args: [Pat], RParen } - struct Visibility {} - struct Name {} - struct NameRef {} + struct Visibility { PubKw, SuperKw, SelfKw, CrateKw } + struct Name { Ident } + struct NameRef { NameRefToken } struct MacroCall: NameOwner, AttrsOwner,DocCommentsOwner { - TokenTree, Path + Path, Excl, TokenTree, Semi } - struct Attr { Path, input: AttrInput } + struct Attr { Pound, Excl, LBrack, Path, Eq, input: AttrInput, RBrack } struct TokenTree {} struct TypeParamList { + LAngle, + generic_params: [GenericParam], type_params: [TypeParam], lifetime_params: [LifetimeParam], + const_params: [ConstParam], + RAngle } struct TypeParam: NameOwner, AttrsOwner, TypeBoundsOwner { + Eq, default_type: TypeRef, } struct ConstParam: NameOwner, AttrsOwner, TypeAscriptionOwner { + Eq, default_val: Expr, } - struct LifetimeParam: AttrsOwner { } - struct TypeBound { TypeRef} + struct LifetimeParam: AttrsOwner { Lifetime} + struct TypeBound { Lifetime, /* Question, */ ConstKw, /* Question, */ TypeRef} struct TypeBoundList { bounds: [TypeBound] } - struct WherePred: TypeBoundsOwner { TypeRef } - struct WhereClause { predicates: [WherePred] } - struct ExprStmt { Expr } - struct LetStmt: TypeAscriptionOwner { + struct WherePred: TypeBoundsOwner { Lifetime, TypeRef } + struct WhereClause { WhereKw, predicates: [WherePred] } + struct Abi { String } + struct ExprStmt: AttrsOwner { Expr, Semi } + struct LetStmt: AttrsOwner, TypeAscriptionOwner { + LetKw, Pat, + Eq, initializer: Expr, } - struct Condition { Pat, Expr } + struct Condition { LetKw, Pat, Eq, Expr } struct Block: AttrsOwner, ModuleItemOwner { + LCurly, statements: [Stmt], + statements_or_semi: [StmtOrSemi], Expr, + RCurly, } struct ParamList { + LParen, SelfParam, params: [Param], + RParen } - struct SelfParam: TypeAscriptionOwner, AttrsOwner { } + struct SelfParam: TypeAscriptionOwner, AttrsOwner { Amp, Lifetime, SelfKw } struct Param: TypeAscriptionOwner, AttrsOwner { Pat, + Dotdotdot } struct UseItem: AttrsOwner, VisibilityOwner { + UseKw, UseTree, } struct UseTree { - Path, UseTreeList, Alias + Path, Star, UseTreeList, Alias } - struct Alias: NameOwner { } - struct UseTreeList { use_trees: [UseTree] } + struct Alias: NameOwner { AsKw } + struct UseTreeList { LCurly, use_trees: [UseTree], RCurly } struct ExternCrateItem: AttrsOwner, VisibilityOwner { - NameRef, Alias, + ExternKw, CrateKw, NameRef, Alias, } struct ArgList { + LParen, args: [Expr], + RParen } struct Path { segment: PathSegment, qualifier: Path, } struct PathSegment { - NameRef, TypeArgList, ParamList, RetType, PathType, + Coloncolon, LAngle, NameRef, TypeArgList, ParamList, RetType, PathType, RAngle } struct TypeArgList { + Coloncolon, + LAngle, + generic_args: [GenericArg], type_args: [TypeArg], lifetime_args: [LifetimeArg], assoc_type_args: [AssocTypeArg], - const_arg: [ConstArg], + const_args: [ConstArg], + RAngle } struct TypeArg { TypeRef } - struct AssocTypeArg { NameRef, TypeRef } - struct LifetimeArg {} - struct ConstArg { Literal, BlockExpr } + struct AssocTypeArg : TypeBoundsOwner { NameRef, Eq, TypeRef } + struct LifetimeArg { Lifetime } + struct ConstArg { Literal, Eq, BlockExpr } struct MacroItems: ModuleItemOwner, FnDefOwner { } @@ -533,12 +609,44 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { statements: [Stmt], Expr, } + + struct ExternItemList: FnDefOwner, ModuleItemOwner { + LCurly, + extern_items: [ExternItem], + RCurly + } + + struct ExternBlock { + Abi, + ExternItemList + } + + struct MetaItem { + Path, Eq, AttrInput, nested_meta_items: [MetaItem] + } + + struct MacroDef { + Name, TokenTree + } }, enums: &ast_enums! { enum NominalDef: NameOwner, TypeParamsOwner, AttrsOwner { StructDef, EnumDef, UnionDef, } + enum GenericParam { + LifetimeParam, + TypeParam, + ConstParam + } + + enum GenericArg { + LifetimeArg, + TypeArg, + ConstArg, + AssocTypeArg + } + enum TypeRef { ParenType, TupleType, @@ -555,7 +663,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { DynTraitType, } - enum ModuleItem: AttrsOwner, VisibilityOwner { + enum ModuleItem: NameOwner, AttrsOwner, VisibilityOwner { StructDef, UnionDef, EnumDef, @@ -569,13 +677,20 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { StaticDef, Module, MacroCall, + ExternBlock } - enum ImplItem: AttrsOwner { - FnDef, TypeAliasDef, ConstDef, + /* impl blocks can also contain MacroCall */ + enum ImplItem: NameOwner, AttrsOwner { + FnDef, TypeAliasDef, ConstDef } - enum Expr { + /* extern blocks can also contain MacroCall */ + enum ExternItem: NameOwner, AttrsOwner, VisibilityOwner { + FnDef, StaticDef + } + + enum Expr: AttrsOwner { TupleExpr, ArrayExpr, ParenExpr, @@ -627,7 +742,93 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { MacroPat, } + enum RecordInnerPat { + RecordFieldPat, + BindPat + } + enum AttrInput { Literal, TokenTree } - enum Stmt { ExprStmt, LetStmt } + enum Stmt { + ModuleItem, + LetStmt, + ExprStmt, + // macro calls are parsed as expression statements */ + } + enum StmtOrSemi {Stmt, Semi} + + enum LeftDelimiter { LParen, LBrack, LCurly } + enum RightDelimiter { RParen, RBrack, RCurly } + enum RangeSeparator { Dotdot, Dotdotdot, Dotdoteq} + + enum BinOp { + Pipepipe, + Ampamp, + Eqeq, + Neq, + Lteq, + Gteq, + LAngle, + RAngle, + Plus, + Star, + Minus, + Slash, + Percent, + Shl, + Shr, + Caret, + Pipe, + Amp, + Eq, + Pluseq, + Slasheq, + Stareq, + Percenteq, + Shreq, + Shleq, + Minuseq, + Pipeeq, + Ampeq, + Careteq, + } + + enum PrefixOp { + Minus, + Excl, + Star + } + + enum RangeOp { + Dotdot, + Dotdoteq + } + + enum LiteralToken { + IntNumber, + FloatNumber, + String, + RawString, + TrueKw, + FalseKw, + ByteString, + RawByteString, + Char, + Byte + } + + enum NameRefToken { + Ident, + IntNumber + } + + enum FieldDefList { + RecordFieldDefList, + TupleFieldDefList, + } + + enum AttrOrComment { + Attr, + Comment + } }, }; From 689661c95968cb438f8bd1f10ce0ee096287741b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 9 Apr 2020 13:00:09 +0200 Subject: [PATCH 2/2] Scale back to only two traits --- .../src/handlers/introduce_variable.rs | 4 +- crates/ra_hir_def/src/body/lower.rs | 1 - crates/ra_syntax/src/ast.rs | 16 + crates/ra_syntax/src/ast/extensions.rs | 13 +- crates/ra_syntax/src/ast/generated.rs | 2093 +++++++++++++++-- crates/ra_syntax/src/ast/traits.rs | 26 +- xtask/src/ast_src.rs | 8 - xtask/src/codegen/gen_syntax.rs | 87 +- 8 files changed, 2020 insertions(+), 228 deletions(-) diff --git a/crates/ra_assists/src/handlers/introduce_variable.rs b/crates/ra_assists/src/handlers/introduce_variable.rs index 9963f884bb..8a02f1a32c 100644 --- a/crates/ra_assists/src/handlers/introduce_variable.rs +++ b/crates/ra_assists/src/handlers/introduce_variable.rs @@ -1,5 +1,5 @@ use ra_syntax::{ - ast::{self, AstElement, AstNode}, + ast::{self, AstNode}, SyntaxKind::{ BLOCK_EXPR, BREAK_EXPR, COMMENT, LAMBDA_EXPR, LOOP_EXPR, MATCH_ARM, PATH_EXPR, RETURN_EXPR, WHITESPACE, @@ -124,7 +124,7 @@ fn anchor_stmt(expr: ast::Expr) -> Option<(SyntaxNode, bool)> { } } - if ast::Stmt::cast_element(node.clone().into()).is_some() { + if ast::Stmt::cast(node.clone().into()).is_some() { return Some((node, false)); } diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 8338414faa..b02de5d67d 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -492,7 +492,6 @@ impl ExprCollector<'_> { ast::Stmt::ExprStmt(stmt) => { Some(Statement::Expr(self.collect_expr_opt(stmt.expr()))) } - ast::Stmt::ModuleItem(_) => None, }) .collect(); let tail = block.expr().map(|e| self.collect_expr(e)); diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index c81b68d3e2..e1ebd5b928 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs @@ -64,6 +64,22 @@ pub trait AstToken { } } +mod support { + use super::{AstChildren, AstNode, AstToken, SyntaxNode}; + + pub(super) fn child(parent: &SyntaxNode) -> Option { + parent.children().find_map(N::cast) + } + + pub(super) fn children(parent: &SyntaxNode) -> AstChildren { + AstChildren::new(parent) + } + + pub(super) fn token(parent: &SyntaxNode) -> Option { + parent.children_with_tokens().filter_map(|it| it.into_token()).find_map(T::cast) + } +} + /// An iterator over `SyntaxNode` children of a particular AST type. #[derive(Debug, Clone)] pub struct AstChildren { diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs index 400eba210a..33fe60762a 100644 --- a/crates/ra_syntax/src/ast/extensions.rs +++ b/crates/ra_syntax/src/ast/extensions.rs @@ -5,8 +5,7 @@ use itertools::Itertools; use crate::{ ast::{ - self, child_opt, child_token_opt, children, AstElement, AstNode, AstToken, AttrInput, - NameOwner, SyntaxNode, + self, child_opt, children, support, AstNode, AstToken, AttrInput, NameOwner, SyntaxNode, }, SmolStr, SyntaxElement, SyntaxKind::*, @@ -437,7 +436,7 @@ impl ast::TypeBound { .skip_while(|it| it.kind() != T![const]) .find_map(ast::Question::cast) } else { - child_token_opt(self) + support::token(&self.syntax) } } } @@ -509,7 +508,7 @@ impl ast::RangePat { pub fn start(&self) -> Option { self.syntax() .children_with_tokens() - .take_while(|it| !ast::RangeSeparator::can_cast_element(it.kind())) + .take_while(|it| !ast::RangeSeparator::can_cast(it.kind())) .filter_map(|it| it.into_node()) .find_map(ast::Pat::cast) } @@ -517,7 +516,7 @@ impl ast::RangePat { pub fn end(&self) -> Option { self.syntax() .children_with_tokens() - .skip_while(|it| !ast::RangeSeparator::can_cast_element(it.kind())) + .skip_while(|it| !ast::RangeSeparator::can_cast(it.kind())) .filter_map(|it| it.into_node()) .find_map(ast::Pat::cast) } @@ -525,10 +524,10 @@ impl ast::RangePat { impl ast::TokenTree { pub fn left_delimiter(&self) -> Option { - self.syntax().first_child_or_token().and_then(ast::LeftDelimiter::cast_element) + self.syntax().first_child_or_token()?.into_token().and_then(ast::LeftDelimiter::cast) } pub fn right_delimiter(&self) -> Option { - self.syntax().last_child_or_token().and_then(ast::RightDelimiter::cast_element) + self.syntax().last_child_or_token()?.into_token().and_then(ast::RightDelimiter::cast) } } diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 385fddc89e..bd92e9c874 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -2,7 +2,7 @@ #[allow(unused_imports)] use crate::{ - ast::{self, AstChildren, AstNode, AstToken}, + ast::{self, support, AstChildren, AstNode, AstToken}, NodeOrToken, SyntaxElement, SyntaxKind::{self, *}, SyntaxNode, SyntaxToken, @@ -2600,6 +2600,33 @@ impl AstToken for UnionKw { } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct RawKw { + pub(crate) syntax: SyntaxToken, +} +impl std::fmt::Display for RawKw { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + std::fmt::Display::fmt(&self.syntax, f) + } +} +impl AstToken for RawKw { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + RAW_KW => true, + _ => false, + } + } + fn cast(syntax: SyntaxToken) -> Option { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + fn syntax(&self) -> &SyntaxToken { + &self.syntax + } +} +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct IntNumber { pub(crate) syntax: SyntaxToken, } @@ -3060,9 +3087,10 @@ impl AstNode for SourceFile { } impl ast::ModuleItemOwner for SourceFile {} impl ast::FnDefOwner for SourceFile {} +impl ast::AttrsOwner for SourceFile {} impl SourceFile { pub fn modules(&self) -> AstChildren { - AstChildren::new(&self.syntax) + support::children(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3098,14 +3126,35 @@ impl ast::TypeParamsOwner for FnDef {} impl ast::DocCommentsOwner for FnDef {} impl ast::AttrsOwner for FnDef {} impl FnDef { + pub fn abi(&self) -> Option { + support::child(&self.syntax) + } + pub fn const_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn default_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn async_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn unsafe_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn fn_kw(&self) -> Option { + support::token(&self.syntax) + } pub fn param_list(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } pub fn ret_type(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } pub fn body(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) + } + pub fn semi(&self) -> Option { + support::token(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3136,8 +3185,11 @@ impl AstNode for RetType { } } impl RetType { + pub fn thin_arrow(&self) -> Option { + support::token(&self.syntax) + } pub fn type_ref(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3172,7 +3224,17 @@ impl ast::NameOwner for StructDef {} impl ast::TypeParamsOwner for StructDef {} impl ast::AttrsOwner for StructDef {} impl ast::DocCommentsOwner for StructDef {} -impl StructDef {} +impl StructDef { + pub fn struct_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn field_def_list(&self) -> Option { + support::child(&self.syntax) + } + pub fn semi(&self) -> Option { + support::token(&self.syntax) + } +} #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct UnionDef { pub(crate) syntax: SyntaxNode, @@ -3206,8 +3268,11 @@ impl ast::TypeParamsOwner for UnionDef {} impl ast::AttrsOwner for UnionDef {} impl ast::DocCommentsOwner for UnionDef {} impl UnionDef { + pub fn union_kw(&self) -> Option { + support::token(&self.syntax) + } pub fn record_field_def_list(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3238,8 +3303,14 @@ impl AstNode for RecordFieldDefList { } } impl RecordFieldDefList { + pub fn l_curly(&self) -> Option { + support::token(&self.syntax) + } pub fn fields(&self) -> AstChildren { - AstChildren::new(&self.syntax) + support::children(&self.syntax) + } + pub fn r_curly(&self) -> Option { + support::token(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3303,8 +3374,14 @@ impl AstNode for TupleFieldDefList { } } impl TupleFieldDefList { + pub fn l_paren(&self) -> Option { + support::token(&self.syntax) + } pub fn fields(&self) -> AstChildren { - AstChildren::new(&self.syntax) + support::children(&self.syntax) + } + pub fn r_paren(&self) -> Option { + support::token(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3338,7 +3415,7 @@ impl ast::VisibilityOwner for TupleFieldDef {} impl ast::AttrsOwner for TupleFieldDef {} impl TupleFieldDef { pub fn type_ref(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3374,8 +3451,11 @@ impl ast::TypeParamsOwner for EnumDef {} impl ast::AttrsOwner for EnumDef {} impl ast::DocCommentsOwner for EnumDef {} impl EnumDef { + pub fn enum_kw(&self) -> Option { + support::token(&self.syntax) + } pub fn variant_list(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3406,8 +3486,14 @@ impl AstNode for EnumVariantList { } } impl EnumVariantList { + pub fn l_curly(&self) -> Option { + support::token(&self.syntax) + } pub fn variants(&self) -> AstChildren { - AstChildren::new(&self.syntax) + support::children(&self.syntax) + } + pub fn r_curly(&self) -> Option { + support::token(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3437,12 +3523,19 @@ impl AstNode for EnumVariant { &self.syntax } } +impl ast::VisibilityOwner for EnumVariant {} impl ast::NameOwner for EnumVariant {} impl ast::DocCommentsOwner for EnumVariant {} impl ast::AttrsOwner for EnumVariant {} impl EnumVariant { + pub fn field_def_list(&self) -> Option { + support::child(&self.syntax) + } + pub fn eq(&self) -> Option { + support::token(&self.syntax) + } pub fn expr(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3479,8 +3572,17 @@ impl ast::DocCommentsOwner for TraitDef {} impl ast::TypeParamsOwner for TraitDef {} impl ast::TypeBoundsOwner for TraitDef {} impl TraitDef { + pub fn unsafe_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn auto_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn trait_kw(&self) -> Option { + support::token(&self.syntax) + } pub fn item_list(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3515,8 +3617,14 @@ impl ast::NameOwner for Module {} impl ast::AttrsOwner for Module {} impl ast::DocCommentsOwner for Module {} impl Module { + pub fn mod_kw(&self) -> Option { + support::token(&self.syntax) + } pub fn item_list(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) + } + pub fn semi(&self) -> Option { + support::token(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3549,8 +3657,14 @@ impl AstNode for ItemList { impl ast::FnDefOwner for ItemList {} impl ast::ModuleItemOwner for ItemList {} impl ItemList { + pub fn l_curly(&self) -> Option { + support::token(&self.syntax) + } pub fn impl_items(&self) -> AstChildren { - AstChildren::new(&self.syntax) + support::children(&self.syntax) + } + pub fn r_curly(&self) -> Option { + support::token(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3587,8 +3701,20 @@ impl ast::AttrsOwner for ConstDef {} impl ast::DocCommentsOwner for ConstDef {} impl ast::TypeAscriptionOwner for ConstDef {} impl ConstDef { + pub fn default_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn const_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn eq(&self) -> Option { + support::token(&self.syntax) + } pub fn body(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) + } + pub fn semi(&self) -> Option { + support::token(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3625,8 +3751,20 @@ impl ast::AttrsOwner for StaticDef {} impl ast::DocCommentsOwner for StaticDef {} impl ast::TypeAscriptionOwner for StaticDef {} impl StaticDef { + pub fn static_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn mut_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn eq(&self) -> Option { + support::token(&self.syntax) + } pub fn body(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) + } + pub fn semi(&self) -> Option { + support::token(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3663,8 +3801,20 @@ impl ast::AttrsOwner for TypeAliasDef {} impl ast::DocCommentsOwner for TypeAliasDef {} impl ast::TypeBoundsOwner for TypeAliasDef {} impl TypeAliasDef { + pub fn default_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn type_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn eq(&self) -> Option { + support::token(&self.syntax) + } pub fn type_ref(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) + } + pub fn semi(&self) -> Option { + support::token(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3697,8 +3847,26 @@ impl AstNode for ImplDef { impl ast::TypeParamsOwner for ImplDef {} impl ast::AttrsOwner for ImplDef {} impl ImplDef { + pub fn default_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn const_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn unsafe_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn impl_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn excl(&self) -> Option { + support::token(&self.syntax) + } + pub fn for_kw(&self) -> Option { + support::token(&self.syntax) + } pub fn item_list(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3729,8 +3897,14 @@ impl AstNode for ParenType { } } impl ParenType { + pub fn l_paren(&self) -> Option { + support::token(&self.syntax) + } pub fn type_ref(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) + } + pub fn r_paren(&self) -> Option { + support::token(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3761,8 +3935,14 @@ impl AstNode for TupleType { } } impl TupleType { + pub fn l_paren(&self) -> Option { + support::token(&self.syntax) + } pub fn fields(&self) -> AstChildren { - AstChildren::new(&self.syntax) + support::children(&self.syntax) + } + pub fn r_paren(&self) -> Option { + support::token(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3792,7 +3972,11 @@ impl AstNode for NeverType { &self.syntax } } -impl NeverType {} +impl NeverType { + pub fn excl(&self) -> Option { + support::token(&self.syntax) + } +} #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct PathType { pub(crate) syntax: SyntaxNode, @@ -3822,7 +4006,7 @@ impl AstNode for PathType { } impl PathType { pub fn path(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3853,8 +4037,14 @@ impl AstNode for PointerType { } } impl PointerType { + pub fn star(&self) -> Option { + support::token(&self.syntax) + } + pub fn const_kw(&self) -> Option { + support::token(&self.syntax) + } pub fn type_ref(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3885,11 +4075,20 @@ impl AstNode for ArrayType { } } impl ArrayType { + pub fn l_brack(&self) -> Option { + support::token(&self.syntax) + } pub fn type_ref(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) + } + pub fn semi(&self) -> Option { + support::token(&self.syntax) } pub fn expr(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) + } + pub fn r_brack(&self) -> Option { + support::token(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3920,8 +4119,14 @@ impl AstNode for SliceType { } } impl SliceType { + pub fn l_brack(&self) -> Option { + support::token(&self.syntax) + } pub fn type_ref(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) + } + pub fn r_brack(&self) -> Option { + support::token(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3952,8 +4157,17 @@ impl AstNode for ReferenceType { } } impl ReferenceType { + pub fn amp(&self) -> Option { + support::token(&self.syntax) + } + pub fn lifetime(&self) -> Option { + support::token(&self.syntax) + } + pub fn mut_kw(&self) -> Option { + support::token(&self.syntax) + } pub fn type_ref(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3983,7 +4197,11 @@ impl AstNode for PlaceholderType { &self.syntax } } -impl PlaceholderType {} +impl PlaceholderType { + pub fn underscore(&self) -> Option { + support::token(&self.syntax) + } +} #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FnPointerType { pub(crate) syntax: SyntaxNode, @@ -4012,11 +4230,20 @@ impl AstNode for FnPointerType { } } impl FnPointerType { + pub fn abi(&self) -> Option { + support::child(&self.syntax) + } + pub fn unsafe_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn fn_kw(&self) -> Option { + support::token(&self.syntax) + } pub fn param_list(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } pub fn ret_type(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -4047,8 +4274,14 @@ impl AstNode for ForType { } } impl ForType { + pub fn for_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn type_param_list(&self) -> Option { + support::child(&self.syntax) + } pub fn type_ref(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -4079,7 +4312,11 @@ impl AstNode for ImplTraitType { } } impl ast::TypeBoundsOwner for ImplTraitType {} -impl ImplTraitType {} +impl ImplTraitType { + pub fn impl_kw(&self) -> Option { + support::token(&self.syntax) + } +} #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct DynTraitType { pub(crate) syntax: SyntaxNode, @@ -4108,7 +4345,11 @@ impl AstNode for DynTraitType { } } impl ast::TypeBoundsOwner for DynTraitType {} -impl DynTraitType {} +impl DynTraitType { + pub fn dyn_kw(&self) -> Option { + support::token(&self.syntax) + } +} #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct TupleExpr { pub(crate) syntax: SyntaxNode, @@ -4136,9 +4377,16 @@ impl AstNode for TupleExpr { &self.syntax } } +impl ast::AttrsOwner for TupleExpr {} impl TupleExpr { + pub fn l_paren(&self) -> Option { + support::token(&self.syntax) + } pub fn exprs(&self) -> AstChildren { - AstChildren::new(&self.syntax) + support::children(&self.syntax) + } + pub fn r_paren(&self) -> Option { + support::token(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -4168,9 +4416,19 @@ impl AstNode for ArrayExpr { &self.syntax } } +impl ast::AttrsOwner for ArrayExpr {} impl ArrayExpr { + pub fn l_brack(&self) -> Option { + support::token(&self.syntax) + } pub fn exprs(&self) -> AstChildren { - AstChildren::new(&self.syntax) + support::children(&self.syntax) + } + pub fn semi(&self) -> Option { + support::token(&self.syntax) + } + pub fn r_brack(&self) -> Option { + support::token(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -4200,9 +4458,16 @@ impl AstNode for ParenExpr { &self.syntax } } +impl ast::AttrsOwner for ParenExpr {} impl ParenExpr { + pub fn l_paren(&self) -> Option { + support::token(&self.syntax) + } pub fn expr(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) + } + pub fn r_paren(&self) -> Option { + support::token(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -4234,7 +4499,7 @@ impl AstNode for PathExpr { } impl PathExpr { pub fn path(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -4264,15 +4529,25 @@ impl AstNode for LambdaExpr { &self.syntax } } +impl ast::AttrsOwner for LambdaExpr {} impl LambdaExpr { + pub fn static_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn async_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn move_kw(&self) -> Option { + support::token(&self.syntax) + } pub fn param_list(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } pub fn ret_type(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } pub fn body(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -4302,9 +4577,13 @@ impl AstNode for IfExpr { &self.syntax } } +impl ast::AttrsOwner for IfExpr {} impl IfExpr { + pub fn if_kw(&self) -> Option { + support::token(&self.syntax) + } pub fn condition(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -4334,8 +4613,13 @@ impl AstNode for LoopExpr { &self.syntax } } +impl ast::AttrsOwner for LoopExpr {} impl ast::LoopBodyOwner for LoopExpr {} -impl LoopExpr {} +impl LoopExpr { + pub fn loop_kw(&self) -> Option { + support::token(&self.syntax) + } +} #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct TryBlockExpr { pub(crate) syntax: SyntaxNode, @@ -4363,9 +4647,13 @@ impl AstNode for TryBlockExpr { &self.syntax } } +impl ast::AttrsOwner for TryBlockExpr {} impl TryBlockExpr { + pub fn try_kw(&self) -> Option { + support::token(&self.syntax) + } pub fn body(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -4395,13 +4683,20 @@ impl AstNode for ForExpr { &self.syntax } } +impl ast::AttrsOwner for ForExpr {} impl ast::LoopBodyOwner for ForExpr {} impl ForExpr { + pub fn for_kw(&self) -> Option { + support::token(&self.syntax) + } pub fn pat(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) + } + pub fn in_kw(&self) -> Option { + support::token(&self.syntax) } pub fn iterable(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -4431,10 +4726,14 @@ impl AstNode for WhileExpr { &self.syntax } } +impl ast::AttrsOwner for WhileExpr {} impl ast::LoopBodyOwner for WhileExpr {} impl WhileExpr { + pub fn while_kw(&self) -> Option { + support::token(&self.syntax) + } pub fn condition(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -4464,7 +4763,15 @@ impl AstNode for ContinueExpr { &self.syntax } } -impl ContinueExpr {} +impl ast::AttrsOwner for ContinueExpr {} +impl ContinueExpr { + pub fn continue_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn lifetime(&self) -> Option { + support::token(&self.syntax) + } +} #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct BreakExpr { pub(crate) syntax: SyntaxNode, @@ -4492,9 +4799,16 @@ impl AstNode for BreakExpr { &self.syntax } } +impl ast::AttrsOwner for BreakExpr {} impl BreakExpr { + pub fn break_kw(&self) -> Option { + support::token(&self.syntax) + } + pub fn lifetime(&self) -> Option { + support::token(&self.syntax) + } pub fn expr(&self) -> Option { - AstChildren::new(&self.syntax).next() + support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -4524,7 +4838,11 @@ impl AstNode for Label { &self.syntax } } -impl Label {} +impl Label { + pub fn lifetime(&self) -> Option { + support::token(&self.syntax) + } +} #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct BlockExpr { pub(crate) syntax: SyntaxNode, @@ -4552,9 +4870,16 @@ impl AstNode for BlockExpr { &self.syntax } } +impl ast::AttrsOwner for BlockExpr {} impl BlockExpr { + pub fn label(&self) -> Option