mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-10-30 19:49:36 +00:00 
			
		
		
		
	internal: Add some expr constructors to SyntaxFactory
				
					
				
			This commit is contained in:
		
							parent
							
								
									f5ff966dea
								
							
						
					
					
						commit
						ce2398fee8
					
				
					 2 changed files with 175 additions and 2 deletions
				
			
		|  | @ -10,7 +10,7 @@ use crate::{ | |||
|         FormatArgsArg, FormatArgsExpr, MacroDef, Static, TokenTree, | ||||
|     }, | ||||
|     AstToken, | ||||
|     SyntaxKind::*, | ||||
|     SyntaxKind::{self, *}, | ||||
|     SyntaxNode, SyntaxToken, T, | ||||
| }; | ||||
| 
 | ||||
|  | @ -50,6 +50,27 @@ impl From<ast::IfExpr> for ElseBranch { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| impl AstNode for ElseBranch { | ||||
|     fn can_cast(kind: SyntaxKind) -> bool { | ||||
|         ast::BlockExpr::can_cast(kind) || ast::IfExpr::can_cast(kind) | ||||
|     } | ||||
| 
 | ||||
|     fn cast(syntax: SyntaxNode) -> Option<Self> { | ||||
|         if let Some(block_expr) = ast::BlockExpr::cast(syntax.clone()) { | ||||
|             Some(Self::Block(block_expr)) | ||||
|         } else { | ||||
|             ast::IfExpr::cast(syntax).map(Self::IfExpr) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn syntax(&self) -> &SyntaxNode { | ||||
|         match self { | ||||
|             ElseBranch::Block(block_expr) => block_expr.syntax(), | ||||
|             ElseBranch::IfExpr(if_expr) => if_expr.syntax(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ast::IfExpr { | ||||
|     pub fn condition(&self) -> Option<ast::Expr> { | ||||
|         // If the condition is a BlockExpr, check if the then body is missing.
 | ||||
|  |  | |||
|  | @ -167,6 +167,19 @@ impl SyntaxFactory { | |||
|         ast::BlockExpr { syntax: make::expr_empty_block().syntax().clone_for_update() } | ||||
|     } | ||||
| 
 | ||||
|     pub fn expr_tuple(&self, fields: impl IntoIterator<Item = ast::Expr>) -> ast::TupleExpr { | ||||
|         let (fields, input) = iterator_input(fields); | ||||
|         let ast = make::expr_tuple(fields).clone_for_update(); | ||||
| 
 | ||||
|         if let Some(mut mapping) = self.mappings() { | ||||
|             let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); | ||||
|             builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone())); | ||||
|             builder.finish(&mut mapping); | ||||
|         } | ||||
| 
 | ||||
|         ast | ||||
|     } | ||||
| 
 | ||||
|     pub fn expr_bin(&self, lhs: ast::Expr, op: ast::BinaryOp, rhs: ast::Expr) -> ast::BinExpr { | ||||
|         let ast::Expr::BinExpr(ast) = | ||||
|             make::expr_bin_op(lhs.clone(), op, rhs.clone()).clone_for_update() | ||||
|  | @ -184,6 +197,10 @@ impl SyntaxFactory { | |||
|         ast | ||||
|     } | ||||
| 
 | ||||
|     pub fn expr_literal(&self, text: &str) -> ast::Literal { | ||||
|         make::expr_literal(text).clone_for_update() | ||||
|     } | ||||
| 
 | ||||
|     pub fn expr_path(&self, path: ast::Path) -> ast::Expr { | ||||
|         let ast::Expr::PathExpr(ast) = make::expr_path(path.clone()).clone_for_update() else { | ||||
|             unreachable!() | ||||
|  | @ -198,6 +215,18 @@ impl SyntaxFactory { | |||
|         ast.into() | ||||
|     } | ||||
| 
 | ||||
|     pub fn expr_prefix(&self, op: SyntaxKind, expr: ast::Expr) -> ast::PrefixExpr { | ||||
|         let ast = make::expr_prefix(op, expr.clone()).clone_for_update(); | ||||
| 
 | ||||
|         if let Some(mut mapping) = self.mappings() { | ||||
|             let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); | ||||
|             builder.map_node(expr.syntax().clone(), ast.expr().unwrap().syntax().clone()); | ||||
|             builder.finish(&mut mapping); | ||||
|         } | ||||
| 
 | ||||
|         ast | ||||
|     } | ||||
| 
 | ||||
|     pub fn expr_ref(&self, expr: ast::Expr, exclusive: bool) -> ast::Expr { | ||||
|         let ast::Expr::RefExpr(ast) = make::expr_ref(expr.clone(), exclusive).clone_for_update() | ||||
|         else { | ||||
|  | @ -229,6 +258,125 @@ impl SyntaxFactory { | |||
|         ast | ||||
|     } | ||||
| 
 | ||||
|     pub fn expr_if( | ||||
|         &self, | ||||
|         condition: ast::Expr, | ||||
|         then_branch: ast::BlockExpr, | ||||
|         else_branch: Option<ast::ElseBranch>, | ||||
|     ) -> ast::IfExpr { | ||||
|         let ast = make::expr_if(condition.clone(), then_branch.clone(), else_branch.clone()) | ||||
|             .clone_for_update(); | ||||
| 
 | ||||
|         if let Some(mut mapping) = self.mappings() { | ||||
|             let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); | ||||
|             builder.map_node(condition.syntax().clone(), ast.condition().unwrap().syntax().clone()); | ||||
|             builder.map_node( | ||||
|                 then_branch.syntax().clone(), | ||||
|                 ast.then_branch().unwrap().syntax().clone(), | ||||
|             ); | ||||
| 
 | ||||
|             if let Some(else_branch) = else_branch { | ||||
|                 builder.map_node( | ||||
|                     else_branch.syntax().clone(), | ||||
|                     ast.else_branch().unwrap().syntax().clone(), | ||||
|                 ); | ||||
|             } | ||||
|             builder.finish(&mut mapping); | ||||
|         } | ||||
| 
 | ||||
|         ast | ||||
|     } | ||||
| 
 | ||||
|     pub fn expr_let(&self, pattern: ast::Pat, expr: ast::Expr) -> ast::LetExpr { | ||||
|         let ast = make::expr_let(pattern.clone(), expr.clone()).clone_for_update(); | ||||
| 
 | ||||
|         if let Some(mut mapping) = self.mappings() { | ||||
|             let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); | ||||
|             builder.map_node(pattern.syntax().clone(), ast.pat().unwrap().syntax().clone()); | ||||
|             builder.map_node(expr.syntax().clone(), ast.expr().unwrap().syntax().clone()); | ||||
|             builder.finish(&mut mapping); | ||||
|         } | ||||
| 
 | ||||
|         ast | ||||
|     } | ||||
| 
 | ||||
|     pub fn expr_stmt(&self, expr: ast::Expr) -> ast::ExprStmt { | ||||
|         let ast = make::expr_stmt(expr.clone()).clone_for_update(); | ||||
| 
 | ||||
|         if let Some(mut mapping) = self.mappings() { | ||||
|             let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); | ||||
|             builder.map_node(expr.syntax().clone(), ast.expr().unwrap().syntax().clone()); | ||||
|             builder.finish(&mut mapping); | ||||
|         } | ||||
| 
 | ||||
|         ast | ||||
|     } | ||||
| 
 | ||||
|     pub fn expr_match(&self, expr: ast::Expr, match_arm_list: ast::MatchArmList) -> ast::MatchExpr { | ||||
|         let ast = make::expr_match(expr.clone(), match_arm_list.clone()).clone_for_update(); | ||||
| 
 | ||||
|         if let Some(mut mapping) = self.mappings() { | ||||
|             let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); | ||||
|             builder.map_node(expr.syntax().clone(), ast.expr().unwrap().syntax().clone()); | ||||
|             builder.map_node( | ||||
|                 match_arm_list.syntax().clone(), | ||||
|                 ast.match_arm_list().unwrap().syntax().clone(), | ||||
|             ); | ||||
|             builder.finish(&mut mapping); | ||||
|         } | ||||
| 
 | ||||
|         ast | ||||
|     } | ||||
| 
 | ||||
|     pub fn match_arm( | ||||
|         &self, | ||||
|         pat: ast::Pat, | ||||
|         guard: Option<ast::MatchGuard>, | ||||
|         expr: ast::Expr, | ||||
|     ) -> ast::MatchArm { | ||||
|         let ast = make::match_arm(pat.clone(), guard.clone(), expr.clone()).clone_for_update(); | ||||
| 
 | ||||
|         if let Some(mut mapping) = self.mappings() { | ||||
|             let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); | ||||
|             builder.map_node(pat.syntax().clone(), ast.pat().unwrap().syntax().clone()); | ||||
|             if let Some(guard) = guard { | ||||
|                 builder.map_node(guard.syntax().clone(), ast.guard().unwrap().syntax().clone()); | ||||
|             } | ||||
|             builder.map_node(expr.syntax().clone(), ast.expr().unwrap().syntax().clone()); | ||||
|             builder.finish(&mut mapping); | ||||
|         } | ||||
| 
 | ||||
|         ast | ||||
|     } | ||||
| 
 | ||||
|     pub fn match_guard(&self, condition: ast::Expr) -> ast::MatchGuard { | ||||
|         let ast = make::match_guard(condition.clone()).clone_for_update(); | ||||
| 
 | ||||
|         if let Some(mut mapping) = self.mappings() { | ||||
|             let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); | ||||
|             builder.map_node(condition.syntax().clone(), ast.condition().unwrap().syntax().clone()); | ||||
|             builder.finish(&mut mapping); | ||||
|         } | ||||
| 
 | ||||
|         ast | ||||
|     } | ||||
| 
 | ||||
|     pub fn match_arm_list( | ||||
|         &self, | ||||
|         match_arms: impl IntoIterator<Item = ast::MatchArm>, | ||||
|     ) -> ast::MatchArmList { | ||||
|         let (match_arms, input) = iterator_input(match_arms); | ||||
|         let ast = make::match_arm_list(match_arms).clone_for_update(); | ||||
| 
 | ||||
|         if let Some(mut mapping) = self.mappings() { | ||||
|             let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); | ||||
|             builder.map_children(input.into_iter(), ast.arms().map(|it| it.syntax().clone())); | ||||
|             builder.finish(&mut mapping); | ||||
|         } | ||||
| 
 | ||||
|         ast | ||||
|     } | ||||
| 
 | ||||
|     pub fn let_stmt( | ||||
|         &self, | ||||
|         pattern: ast::Pat, | ||||
|  | @ -572,13 +720,17 @@ impl SyntaxFactory { | |||
|         make::token(kind) | ||||
|     } | ||||
| 
 | ||||
|     pub fn whitespace(&self, text: &str) -> ast::SyntaxToken { | ||||
|     pub fn whitespace(&self, text: &str) -> SyntaxToken { | ||||
|         make::tokens::whitespace(text) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // `ext` constructors
 | ||||
| impl SyntaxFactory { | ||||
|     pub fn expr_unit(&self) -> ast::Expr { | ||||
|         self.expr_tuple([]).into() | ||||
|     } | ||||
| 
 | ||||
|     pub fn ident_path(&self, ident: &str) -> ast::Path { | ||||
|         self.path_unqualified(self.path_segment(self.name_ref(ident))) | ||||
|     } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Giga Bowser
						Giga Bowser