fix: comments in record patterns closes #946
This commit is contained in:
		
							parent
							
								
									c16bd06e97
								
							
						
					
					
						commit
						7f38b55c1c
					
				|  | @ -1243,7 +1243,7 @@ pub enum Pattern<Constructor, Type> { | ||||||
|         arguments: Vec<CallArg<Self>>, |         arguments: Vec<CallArg<Self>>, | ||||||
|         module: Option<String>, |         module: Option<String>, | ||||||
|         constructor: Constructor, |         constructor: Constructor, | ||||||
|         with_spread: bool, |         spread_location: Option<Span>, | ||||||
|         tipo: Type, |         tipo: Type, | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|  | @ -1273,6 +1273,15 @@ impl<A, B> Pattern<A, B> { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     pub fn with_spread(&self) -> bool { | ||||||
|  |         match self { | ||||||
|  |             Pattern::Constructor { | ||||||
|  |                 spread_location, .. | ||||||
|  |             } => spread_location.is_some(), | ||||||
|  |             _ => false, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /// Returns `true` if the pattern is [`Discard`].
 |     /// Returns `true` if the pattern is [`Discard`].
 | ||||||
|     ///
 |     ///
 | ||||||
|     /// [`Discard`]: Pattern::Discard
 |     /// [`Discard`]: Pattern::Discard
 | ||||||
|  | @ -1295,7 +1304,7 @@ impl UntypedPattern { | ||||||
|             name: "True".to_string(), |             name: "True".to_string(), | ||||||
|             arguments: vec![], |             arguments: vec![], | ||||||
|             constructor: (), |             constructor: (), | ||||||
|             with_spread: false, |             spread_location: None, | ||||||
|             tipo: (), |             tipo: (), | ||||||
|             module: None, |             module: None, | ||||||
|             is_record: false, |             is_record: false, | ||||||
|  |  | ||||||
|  | @ -1068,7 +1068,7 @@ impl<'comments> Formatter<'comments> { | ||||||
|         name: &'a str, |         name: &'a str, | ||||||
|         args: &'a [CallArg<UntypedPattern>], |         args: &'a [CallArg<UntypedPattern>], | ||||||
|         module: &'a Option<String>, |         module: &'a Option<String>, | ||||||
|         with_spread: bool, |         spread_location: Option<Span>, | ||||||
|         is_record: bool, |         is_record: bool, | ||||||
|     ) -> Document<'a> { |     ) -> Document<'a> { | ||||||
|         fn is_breakable(expr: &UntypedPattern) -> bool { |         fn is_breakable(expr: &UntypedPattern) -> bool { | ||||||
|  | @ -1086,7 +1086,7 @@ impl<'comments> Formatter<'comments> { | ||||||
|             None => name.to_doc(), |             None => name.to_doc(), | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         if args.is_empty() && with_spread { |         if args.is_empty() && spread_location.is_some() { | ||||||
|             if is_record { |             if is_record { | ||||||
|                 name.append(" { .. }") |                 name.append(" { .. }") | ||||||
|             // TODO: not possible
 |             // TODO: not possible
 | ||||||
|  | @ -1095,11 +1095,16 @@ impl<'comments> Formatter<'comments> { | ||||||
|             } |             } | ||||||
|         } else if args.is_empty() { |         } else if args.is_empty() { | ||||||
|             name |             name | ||||||
|         } else if with_spread { |         } else if let Some(spread_location) = spread_location { | ||||||
|  |             let args = args | ||||||
|  |                 .iter() | ||||||
|  |                 .map(|a| self.pattern_call_arg(a)) | ||||||
|  |                 .collect::<Vec<_>>(); | ||||||
|  | 
 | ||||||
|             let wrapped_args = if is_record { |             let wrapped_args = if is_record { | ||||||
|                 wrap_fields_with_spread(args.iter().map(|a| self.pattern_call_arg(a))) |                 self.wrap_fields_with_spread(args, spread_location) | ||||||
|             } else { |             } else { | ||||||
|                 wrap_args_with_spread(args.iter().map(|a| self.pattern_call_arg(a))) |                 self.wrap_args_with_spread(args, spread_location) | ||||||
|             }; |             }; | ||||||
| 
 | 
 | ||||||
|             name.append(wrapped_args) |             name.append(wrapped_args) | ||||||
|  | @ -1120,6 +1125,48 @@ impl<'comments> Formatter<'comments> { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     pub fn wrap_fields_with_spread<'a, I>(&mut self, args: I, spread_location: Span) -> Document<'a> | ||||||
|  |     where | ||||||
|  |         I: IntoIterator<Item = Document<'a>>, | ||||||
|  |     { | ||||||
|  |         let mut args = args.into_iter().peekable(); | ||||||
|  |         if args.peek().is_none() { | ||||||
|  |             return "()".to_doc(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         let comments = self.pop_comments(spread_location.start); | ||||||
|  | 
 | ||||||
|  |         break_(" {", " { ") | ||||||
|  |             .append(join(args, break_(",", ", "))) | ||||||
|  |             .append(break_(",", ", ")) | ||||||
|  |             .append(commented("..".to_doc(), comments)) | ||||||
|  |             .nest(INDENT) | ||||||
|  |             .append(break_("", " ")) | ||||||
|  |             .append("}") | ||||||
|  |             .group() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn wrap_args_with_spread<'a, I>(&mut self, args: I, spread_location: Span) -> Document<'a> | ||||||
|  |     where | ||||||
|  |         I: IntoIterator<Item = Document<'a>>, | ||||||
|  |     { | ||||||
|  |         let mut args = args.into_iter().peekable(); | ||||||
|  |         if args.peek().is_none() { | ||||||
|  |             return "()".to_doc(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         let comments = self.pop_comments(spread_location.start); | ||||||
|  | 
 | ||||||
|  |         break_("(", "(") | ||||||
|  |             .append(join(args, break_(",", ", "))) | ||||||
|  |             .append(break_(",", ", ")) | ||||||
|  |             .append(commented("..".to_doc(), comments)) | ||||||
|  |             .nest(INDENT) | ||||||
|  |             .append(break_(",", "")) | ||||||
|  |             .append(")") | ||||||
|  |             .group() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     fn call<'a>(&mut self, fun: &'a UntypedExpr, args: &'a [CallArg<UntypedExpr>]) -> Document<'a> { |     fn call<'a>(&mut self, fun: &'a UntypedExpr, args: &'a [CallArg<UntypedExpr>]) -> Document<'a> { | ||||||
|         let is_constr = match fun { |         let is_constr = match fun { | ||||||
|             UntypedExpr::Var { name, .. } => name[0..1].chars().all(|c| c.is_uppercase()), |             UntypedExpr::Var { name, .. } => name[0..1].chars().all(|c| c.is_uppercase()), | ||||||
|  | @ -1821,26 +1868,31 @@ impl<'comments> Formatter<'comments> { | ||||||
|                 name, |                 name, | ||||||
|                 arguments: args, |                 arguments: args, | ||||||
|                 module, |                 module, | ||||||
|                 with_spread, |                 spread_location, | ||||||
|                 is_record, |                 is_record, | ||||||
|                 .. |                 .. | ||||||
|             } => self.pattern_constructor(name, args, module, *with_spread, *is_record), |             } => self.pattern_constructor(name, args, module, *spread_location, *is_record), | ||||||
|         }; |         }; | ||||||
|         commented(doc, comments) |         commented(doc, comments) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn pattern_call_arg<'a>(&mut self, arg: &'a CallArg<UntypedPattern>) -> Document<'a> { |     fn pattern_call_arg<'a>(&mut self, arg: &'a CallArg<UntypedPattern>) -> Document<'a> { | ||||||
|  |         let comments = self.pop_comments(arg.location.start); | ||||||
|  | 
 | ||||||
|         if let (UntypedPattern::Var { name, .. }, Some(label)) = (&arg.value, &arg.label) { |         if let (UntypedPattern::Var { name, .. }, Some(label)) = (&arg.value, &arg.label) { | ||||||
|             if name == label { |             if name == label { | ||||||
|                 return self.pattern(&arg.value); |                 return self.pattern(&arg.value); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         arg.label |         let doc = arg | ||||||
|  |             .label | ||||||
|             .as_ref() |             .as_ref() | ||||||
|             .map(|s| s.to_doc().append(": ")) |             .map(|s| s.to_doc().append(": ")) | ||||||
|             .unwrap_or_else(nil) |             .unwrap_or_else(nil) | ||||||
|             .append(self.pattern(&arg.value)) |             .append(self.pattern(&arg.value)); | ||||||
|  | 
 | ||||||
|  |         commented(doc, comments) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn clause_guard_bin_op<'a>( |     pub fn clause_guard_bin_op<'a>( | ||||||
|  | @ -2029,44 +2081,6 @@ where | ||||||
|         .append(line()) |         .append(line()) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn wrap_args_with_spread<'a, I>(args: I) -> Document<'a> |  | ||||||
| where |  | ||||||
|     I: IntoIterator<Item = Document<'a>>, |  | ||||||
| { |  | ||||||
|     let mut args = args.into_iter().peekable(); |  | ||||||
|     if args.peek().is_none() { |  | ||||||
|         return "()".to_doc(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     break_("(", "(") |  | ||||||
|         .append(join(args, break_(",", ", "))) |  | ||||||
|         .append(break_(",", ", ")) |  | ||||||
|         .append("..") |  | ||||||
|         .nest(INDENT) |  | ||||||
|         .append(break_(",", "")) |  | ||||||
|         .append(")") |  | ||||||
|         .group() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub fn wrap_fields_with_spread<'a, I>(args: I) -> Document<'a> |  | ||||||
| where |  | ||||||
|     I: IntoIterator<Item = Document<'a>>, |  | ||||||
| { |  | ||||||
|     let mut args = args.into_iter().peekable(); |  | ||||||
|     if args.peek().is_none() { |  | ||||||
|         return "()".to_doc(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     break_(" {", " { ") |  | ||||||
|         .append(join(args, break_(",", ", "))) |  | ||||||
|         .append(break_(",", ", ")) |  | ||||||
|         .append("..") |  | ||||||
|         .nest(INDENT) |  | ||||||
|         .append(break_("", " ")) |  | ||||||
|         .append("}") |  | ||||||
|         .group() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn list<'a>(elements: Document<'a>, length: usize, tail: Option<Document<'a>>) -> Document<'a> { | fn list<'a>(elements: Document<'a>, length: usize, tail: Option<Document<'a>>) -> Document<'a> { | ||||||
|     if length == 0 { |     if length == 0 { | ||||||
|         return match tail { |         return match tail { | ||||||
|  |  | ||||||
|  | @ -23,7 +23,7 @@ Test( | ||||||
|                                 arguments: [], |                                 arguments: [], | ||||||
|                                 module: None, |                                 module: None, | ||||||
|                                 constructor: (), |                                 constructor: (), | ||||||
|                                 with_spread: false, |                                 spread_location: None, | ||||||
|                                 tipo: (), |                                 tipo: (), | ||||||
|                             }, |                             }, | ||||||
|                             annotation: None, |                             annotation: None, | ||||||
|  |  | ||||||
|  | @ -30,7 +30,7 @@ Assignment { | ||||||
|                 ], |                 ], | ||||||
|                 module: None, |                 module: None, | ||||||
|                 constructor: (), |                 constructor: (), | ||||||
|                 with_spread: false, |                 spread_location: None, | ||||||
|                 tipo: (), |                 tipo: (), | ||||||
|             }, |             }, | ||||||
|             annotation: None, |             annotation: None, | ||||||
|  |  | ||||||
|  | @ -29,7 +29,7 @@ Assignment { | ||||||
|                 arguments: [], |                 arguments: [], | ||||||
|                 module: None, |                 module: None, | ||||||
|                 constructor: (), |                 constructor: (), | ||||||
|                 with_spread: false, |                 spread_location: None, | ||||||
|                 tipo: (), |                 tipo: (), | ||||||
|             }, |             }, | ||||||
|             annotation: None, |             annotation: None, | ||||||
|  |  | ||||||
|  | @ -41,7 +41,7 @@ Assignment { | ||||||
|                 arguments: [], |                 arguments: [], | ||||||
|                 module: None, |                 module: None, | ||||||
|                 constructor: (), |                 constructor: (), | ||||||
|                 with_spread: false, |                 spread_location: None, | ||||||
|                 tipo: (), |                 tipo: (), | ||||||
|             }, |             }, | ||||||
|             annotation: None, |             annotation: None, | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ Assignment { | ||||||
|                 arguments: [], |                 arguments: [], | ||||||
|                 module: None, |                 module: None, | ||||||
|                 constructor: (), |                 constructor: (), | ||||||
|                 with_spread: false, |                 spread_location: None, | ||||||
|                 tipo: (), |                 tipo: (), | ||||||
|             }, |             }, | ||||||
|             annotation: None, |             annotation: None, | ||||||
|  |  | ||||||
|  | @ -19,7 +19,9 @@ When { | ||||||
|                     arguments: [], |                     arguments: [], | ||||||
|                     module: None, |                     module: None, | ||||||
|                     constructor: (), |                     constructor: (), | ||||||
|                     with_spread: true, |                     spread_location: Some( | ||||||
|  |                         21..23, | ||||||
|  |                     ), | ||||||
|                     tipo: (), |                     tipo: (), | ||||||
|                 }, |                 }, | ||||||
|             ], |             ], | ||||||
|  | @ -46,7 +48,9 @@ When { | ||||||
|                     arguments: [], |                     arguments: [], | ||||||
|                     module: None, |                     module: None, | ||||||
|                     constructor: (), |                     constructor: (), | ||||||
|                     with_spread: true, |                     spread_location: Some( | ||||||
|  |                         40..42, | ||||||
|  |                     ), | ||||||
|                     tipo: (), |                     tipo: (), | ||||||
|                 }, |                 }, | ||||||
|             ], |             ], | ||||||
|  |  | ||||||
|  | @ -19,7 +19,9 @@ When { | ||||||
|                     arguments: [], |                     arguments: [], | ||||||
|                     module: None, |                     module: None, | ||||||
|                     constructor: (), |                     constructor: (), | ||||||
|                     with_spread: true, |                     spread_location: Some( | ||||||
|  |                         21..23, | ||||||
|  |                     ), | ||||||
|                     tipo: (), |                     tipo: (), | ||||||
|                 }, |                 }, | ||||||
|             ], |             ], | ||||||
|  |  | ||||||
|  | @ -19,7 +19,9 @@ When { | ||||||
|                     arguments: [], |                     arguments: [], | ||||||
|                     module: None, |                     module: None, | ||||||
|                     constructor: (), |                     constructor: (), | ||||||
|                     with_spread: true, |                     spread_location: Some( | ||||||
|  |                         21..23, | ||||||
|  |                     ), | ||||||
|                     tipo: (), |                     tipo: (), | ||||||
|                 }, |                 }, | ||||||
|             ], |             ], | ||||||
|  | @ -39,7 +41,9 @@ When { | ||||||
|                     arguments: [], |                     arguments: [], | ||||||
|                     module: None, |                     module: None, | ||||||
|                     constructor: (), |                     constructor: (), | ||||||
|                     with_spread: true, |                     spread_location: Some( | ||||||
|  |                         40..42, | ||||||
|  |                     ), | ||||||
|                     tipo: (), |                     tipo: (), | ||||||
|                 }, |                 }, | ||||||
|             ], |             ], | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| use chumsky::prelude::*; | use chumsky::prelude::*; | ||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|     ast::{CallArg, UntypedPattern}, |     ast::{CallArg, Span, UntypedPattern}, | ||||||
|     parser::{error::ParseError, token::Token}, |     parser::{error::ParseError, token::Token}, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -10,7 +10,8 @@ pub fn parser( | ||||||
| ) -> impl Parser<Token, UntypedPattern, Error = ParseError> + '_ { | ) -> impl Parser<Token, UntypedPattern, Error = ParseError> + '_ { | ||||||
|     select! {Token::UpName { name } => name} |     select! {Token::UpName { name } => name} | ||||||
|         .then(args(expression)) |         .then(args(expression)) | ||||||
|         .map_with_span(|(name, (arguments, with_spread, is_record)), location| { |         .map_with_span( | ||||||
|  |             |(name, (arguments, spread_location, is_record)), location| { | ||||||
|                 UntypedPattern::Constructor { |                 UntypedPattern::Constructor { | ||||||
|                     is_record, |                     is_record, | ||||||
|                     location, |                     location, | ||||||
|  | @ -18,15 +19,17 @@ pub fn parser( | ||||||
|                     arguments, |                     arguments, | ||||||
|                     module: None, |                     module: None, | ||||||
|                     constructor: (), |                     constructor: (), | ||||||
|                 with_spread, |                     spread_location, | ||||||
|                     tipo: (), |                     tipo: (), | ||||||
|                 } |                 } | ||||||
|         }) |             }, | ||||||
|  |         ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub(crate) fn args( | pub(crate) fn args( | ||||||
|     expression: Recursive<'_, Token, UntypedPattern, ParseError>, |     expression: Recursive<'_, Token, UntypedPattern, ParseError>, | ||||||
| ) -> impl Parser<Token, (Vec<CallArg<UntypedPattern>>, bool, bool), Error = ParseError> + '_ { | ) -> impl Parser<Token, (Vec<CallArg<UntypedPattern>>, Option<Span>, bool), Error = ParseError> + '_ | ||||||
|  | { | ||||||
|     let record_constructor_pattern_arg_parser = choice(( |     let record_constructor_pattern_arg_parser = choice(( | ||||||
|         select! {Token::Name {name} => name} |         select! {Token::Name {name} => name} | ||||||
|             .then_ignore(just(Token::Colon)) |             .then_ignore(just(Token::Colon)) | ||||||
|  | @ -49,8 +52,9 @@ pub(crate) fn args( | ||||||
|     .allow_trailing() |     .allow_trailing() | ||||||
|     .then( |     .then( | ||||||
|         just(Token::DotDot) |         just(Token::DotDot) | ||||||
|             .then_ignore(just(Token::Comma).or_not()) |  | ||||||
|             .ignored() |             .ignored() | ||||||
|  |             .map_with_span(|_spread, span| span) | ||||||
|  |             .then_ignore(just(Token::Comma).or_not()) | ||||||
|             .or_not(), |             .or_not(), | ||||||
|     ) |     ) | ||||||
|     .delimited_by(just(Token::LeftBrace), just(Token::RightBrace)); |     .delimited_by(just(Token::LeftBrace), just(Token::RightBrace)); | ||||||
|  | @ -66,8 +70,9 @@ pub(crate) fn args( | ||||||
|         .allow_trailing() |         .allow_trailing() | ||||||
|         .then( |         .then( | ||||||
|             just(Token::DotDot) |             just(Token::DotDot) | ||||||
|                 .then_ignore(just(Token::Comma).or_not()) |  | ||||||
|                 .ignored() |                 .ignored() | ||||||
|  |                 .map_with_span(|_spread, span| span) | ||||||
|  |                 .then_ignore(just(Token::Comma).or_not()) | ||||||
|                 .or_not(), |                 .or_not(), | ||||||
|         ) |         ) | ||||||
|         .delimited_by(just(Token::LeftParen), just(Token::RightParen)); |         .delimited_by(just(Token::LeftParen), just(Token::RightParen)); | ||||||
|  | @ -79,8 +84,8 @@ pub(crate) fn args( | ||||||
|     .or_not() |     .or_not() | ||||||
|     .map(|opt_args| { |     .map(|opt_args| { | ||||||
|         opt_args |         opt_args | ||||||
|             .map(|((a, b), c)| (a, b.is_some(), c)) |             .map(|((a, b), c)| (a, b, c)) | ||||||
|             .unwrap_or_else(|| (vec![], false, false)) |             .unwrap_or_else(|| (vec![], None, false)) | ||||||
|     }) |     }) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -9,6 +9,6 @@ Constructor { | ||||||
|     arguments: [], |     arguments: [], | ||||||
|     module: None, |     module: None, | ||||||
|     constructor: (), |     constructor: (), | ||||||
|     with_spread: false, |     spread_location: None, | ||||||
|     tipo: (), |     tipo: (), | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -11,6 +11,6 @@ Constructor { | ||||||
|         "module", |         "module", | ||||||
|     ), |     ), | ||||||
|     constructor: (), |     constructor: (), | ||||||
|     with_spread: false, |     spread_location: None, | ||||||
|     tipo: (), |     tipo: (), | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -30,6 +30,6 @@ Constructor { | ||||||
|     ], |     ], | ||||||
|     module: None, |     module: None, | ||||||
|     constructor: (), |     constructor: (), | ||||||
|     with_spread: false, |     spread_location: None, | ||||||
|     tipo: (), |     tipo: (), | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -26,6 +26,6 @@ Constructor { | ||||||
|     ], |     ], | ||||||
|     module: None, |     module: None, | ||||||
|     constructor: (), |     constructor: (), | ||||||
|     with_spread: false, |     spread_location: None, | ||||||
|     tipo: (), |     tipo: (), | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -39,6 +39,6 @@ Constructor { | ||||||
|     ], |     ], | ||||||
|     module: None, |     module: None, | ||||||
|     constructor: (), |     constructor: (), | ||||||
|     with_spread: false, |     spread_location: None, | ||||||
|     tipo: (), |     tipo: (), | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -20,6 +20,8 @@ Constructor { | ||||||
|     ], |     ], | ||||||
|     module: None, |     module: None, | ||||||
|     constructor: (), |     constructor: (), | ||||||
|     with_spread: true, |     spread_location: Some( | ||||||
|  |         9..11, | ||||||
|  |     ), | ||||||
|     tipo: (), |     tipo: (), | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ Pair { | ||||||
|         arguments: [], |         arguments: [], | ||||||
|         module: None, |         module: None, | ||||||
|         constructor: (), |         constructor: (), | ||||||
|         with_spread: false, |         spread_location: None, | ||||||
|         tipo: (), |         tipo: (), | ||||||
|     }, |     }, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ pub fn parser( | ||||||
|                 .or_not(), |                 .or_not(), | ||||||
|         ) |         ) | ||||||
|         .map_with_span(|(name, opt_pattern), span| { |         .map_with_span(|(name, opt_pattern), span| { | ||||||
|             if let Some((c_name, (arguments, with_spread, is_record))) = opt_pattern { |             if let Some((c_name, (arguments, spread_location, is_record))) = opt_pattern { | ||||||
|                 UntypedPattern::Constructor { |                 UntypedPattern::Constructor { | ||||||
|                     is_record, |                     is_record, | ||||||
|                     location: span, |                     location: span, | ||||||
|  | @ -26,7 +26,7 @@ pub fn parser( | ||||||
|                     arguments, |                     arguments, | ||||||
|                     module: Some(name), |                     module: Some(name), | ||||||
|                     constructor: (), |                     constructor: (), | ||||||
|                     with_spread, |                     spread_location, | ||||||
|                     tipo: (), |                     tipo: (), | ||||||
|                 } |                 } | ||||||
|             } else { |             } else { | ||||||
|  |  | ||||||
|  | @ -749,6 +749,24 @@ fn format_int_uint() { | ||||||
|     ); |     ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #[test] | ||||||
|  | fn preserve_comment_in_record() { | ||||||
|  |     assert_format!( | ||||||
|  |         r#" | ||||||
|  |         fn foo() { | ||||||
|  |           let Output { | ||||||
|  |             // something
 | ||||||
|  |             address: own_address, | ||||||
|  |             // value: own_value,
 | ||||||
|  |             .. | ||||||
|  |           } = own_output | ||||||
|  | 
 | ||||||
|  |           own_address | ||||||
|  |         } | ||||||
|  |         "#
 | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #[test] | #[test] | ||||||
| fn fail_expr() { | fn fail_expr() { | ||||||
|     assert_format!( |     assert_format!( | ||||||
|  |  | ||||||
|  | @ -0,0 +1,14 @@ | ||||||
|  | --- | ||||||
|  | source: crates/aiken-lang/src/tests/format.rs | ||||||
|  | description: "Code:\n\nfn foo() {\n  let Output {\n    // something\n    address: own_address,\n    // value: own_value,\n    ..\n  } = own_output\n\n  own_address\n}\n" | ||||||
|  | --- | ||||||
|  | fn foo() { | ||||||
|  |   let Output { | ||||||
|  |     // something | ||||||
|  |     address: own_address, | ||||||
|  |     // value: own_value, | ||||||
|  |     .. | ||||||
|  |   } = own_output | ||||||
|  | 
 | ||||||
|  |   own_address | ||||||
|  | } | ||||||
|  | @ -732,7 +732,7 @@ Perhaps, try the following: | ||||||
|         , constructor = name |         , constructor = name | ||||||
|             .if_supports_color(Stdout, |s| s.bright_blue()) |             .if_supports_color(Stdout, |s| s.bright_blue()) | ||||||
|             .if_supports_color(Stdout, |s| s.bold()) |             .if_supports_color(Stdout, |s| s.bold()) | ||||||
|         , suggestion = suggest_constructor_pattern(name, args, module, *with_spread) |         , suggestion = suggest_constructor_pattern(name, args, module, *spread_location) | ||||||
|     ))] |     ))] | ||||||
|     UnexpectedLabeledArgInPattern { |     UnexpectedLabeledArgInPattern { | ||||||
|         #[label] |         #[label] | ||||||
|  | @ -741,7 +741,7 @@ Perhaps, try the following: | ||||||
|         name: String, |         name: String, | ||||||
|         args: Vec<CallArg<UntypedPattern>>, |         args: Vec<CallArg<UntypedPattern>>, | ||||||
|         module: Option<String>, |         module: Option<String>, | ||||||
|         with_spread: bool, |         spread_location: Option<Span>, | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     #[error("I discovered a regular let assignment with multiple patterns.\n")] |     #[error("I discovered a regular let assignment with multiple patterns.\n")] | ||||||
|  | @ -1210,7 +1210,7 @@ fn suggest_pattern( | ||||||
|         Some(format!( |         Some(format!( | ||||||
|             "Try instead: {}", |             "Try instead: {}", | ||||||
|             Formatter::new() |             Formatter::new() | ||||||
|                 .pattern_constructor(name, given, module, true, is_record) |                 .pattern_constructor(name, given, module, Some(Span::empty()), is_record) | ||||||
|                 .to_pretty_string(70), |                 .to_pretty_string(70), | ||||||
|         )) |         )) | ||||||
|     } else { |     } else { | ||||||
|  | @ -1239,7 +1239,7 @@ fn suggest_constructor_pattern( | ||||||
|     name: &str, |     name: &str, | ||||||
|     args: &[CallArg<UntypedPattern>], |     args: &[CallArg<UntypedPattern>], | ||||||
|     module: &Option<String>, |     module: &Option<String>, | ||||||
|     with_spread: bool, |     spread_location: Option<Span>, | ||||||
| ) -> String { | ) -> String { | ||||||
|     let fixed_args = args |     let fixed_args = args | ||||||
|         .iter() |         .iter() | ||||||
|  | @ -1251,7 +1251,7 @@ fn suggest_constructor_pattern( | ||||||
|         .collect::<Vec<_>>(); |         .collect::<Vec<_>>(); | ||||||
| 
 | 
 | ||||||
|     Formatter::new() |     Formatter::new() | ||||||
|         .pattern_constructor(name, &fixed_args, module, with_spread, false) |         .pattern_constructor(name, &fixed_args, module, spread_location, false) | ||||||
|         .to_pretty_string(70) |         .to_pretty_string(70) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -558,7 +558,7 @@ pub(super) fn simplify( | ||||||
|             arguments, |             arguments, | ||||||
|             location, |             location, | ||||||
|             tipo, |             tipo, | ||||||
|             with_spread, |             spread_location, | ||||||
|             constructor: super::PatternConstructor::Record { name, .. }, |             constructor: super::PatternConstructor::Record { name, .. }, | ||||||
|             .. |             .. | ||||||
|         } => { |         } => { | ||||||
|  | @ -589,7 +589,7 @@ pub(super) fn simplify( | ||||||
|                 args.push(simplify(environment, &argument.value)?); |                 args.push(simplify(environment, &argument.value)?); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if *with_spread { |             if spread_location.is_some() { | ||||||
|                 for _ in 0..(arity - arguments.len()) { |                 for _ in 0..(arity - arguments.len()) { | ||||||
|                     args.push(Pattern::Wildcard) |                     args.push(Pattern::Wildcard) | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|  | @ -2608,7 +2608,7 @@ fn assert_assignment(expr: TypedExpr) -> Result<TypedExpr, Error> { | ||||||
|                     }, |                     }, | ||||||
|                     arguments: vec![], |                     arguments: vec![], | ||||||
|                     module: None, |                     module: None, | ||||||
|                     with_spread: false, |                     spread_location: None, | ||||||
|                     tipo: void(), |                     tipo: void(), | ||||||
|                 }, |                 }, | ||||||
|                 kind: AssignmentKind::let_(), |                 kind: AssignmentKind::let_(), | ||||||
|  |  | ||||||
|  | @ -344,7 +344,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> { | ||||||
|                 module, |                 module, | ||||||
|                 name, |                 name, | ||||||
|                 arguments: mut pattern_args, |                 arguments: mut pattern_args, | ||||||
|                 with_spread, |                 spread_location, | ||||||
|                 is_record, |                 is_record, | ||||||
|                 .. |                 .. | ||||||
|             } => { |             } => { | ||||||
|  | @ -360,7 +360,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> { | ||||||
|                 match cons.field_map() { |                 match cons.field_map() { | ||||||
|                     // The fun has a field map so labelled arguments may be present and need to be reordered.
 |                     // The fun has a field map so labelled arguments may be present and need to be reordered.
 | ||||||
|                     Some(field_map) => { |                     Some(field_map) => { | ||||||
|                         if with_spread { |                         if spread_location.is_some() { | ||||||
|                             // Using the spread operator when you have already provided variables for all of the
 |                             // Using the spread operator when you have already provided variables for all of the
 | ||||||
|                             // record's fields throws an error
 |                             // record's fields throws an error
 | ||||||
|                             if pattern_args.len() == field_map.arity { |                             if pattern_args.len() == field_map.arity { | ||||||
|  | @ -416,7 +416,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> { | ||||||
|                                 name: name.clone(), |                                 name: name.clone(), | ||||||
|                                 args: pattern_args.clone(), |                                 args: pattern_args.clone(), | ||||||
|                                 module: module.clone(), |                                 module: module.clone(), | ||||||
|                                 with_spread, |                                 spread_location, | ||||||
|                             }) |                             }) | ||||||
|                         }) |                         }) | ||||||
|                         .unwrap_or(Ok(()))?, |                         .unwrap_or(Ok(()))?, | ||||||
|  | @ -445,7 +445,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> { | ||||||
| 
 | 
 | ||||||
|                 match instantiated_constructor_type.deref() { |                 match instantiated_constructor_type.deref() { | ||||||
|                     Type::Fn { args, ret, .. } => { |                     Type::Fn { args, ret, .. } => { | ||||||
|                         if with_spread && has_no_fields { |                         if spread_location.is_some() && has_no_fields { | ||||||
|                             if pattern_args.len() == args.len() { |                             if pattern_args.len() == args.len() { | ||||||
|                                 return Err(Error::UnnecessarySpreadOperator { |                                 return Err(Error::UnnecessarySpreadOperator { | ||||||
|                                     location: Span { |                                     location: Span { | ||||||
|  | @ -502,7 +502,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> { | ||||||
|                                 name, |                                 name, | ||||||
|                                 arguments: pattern_args, |                                 arguments: pattern_args, | ||||||
|                                 constructor, |                                 constructor, | ||||||
|                                 with_spread, |                                 spread_location, | ||||||
|                                 tipo: instantiated_constructor_type, |                                 tipo: instantiated_constructor_type, | ||||||
|                                 is_record, |                                 is_record, | ||||||
|                             }) |                             }) | ||||||
|  | @ -533,7 +533,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> { | ||||||
|                                 name, |                                 name, | ||||||
|                                 arguments: vec![], |                                 arguments: vec![], | ||||||
|                                 constructor, |                                 constructor, | ||||||
|                                 with_spread, |                                 spread_location, | ||||||
|                                 tipo: instantiated_constructor_type, |                                 tipo: instantiated_constructor_type, | ||||||
|                                 is_record, |                                 is_record, | ||||||
|                             }) |                             }) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 rvcas
						rvcas