fix(parser): parse named rest element in type tuple (#2655)

This is fixing the parser for `type X = [...args: string[]];`

In TSESLint TSNamedTupleMember in part of the TSType union, so I did the
same.
This commit is contained in:
Arnaud Barré 2024-03-10 06:25:15 +01:00 committed by GitHub
parent 776812315d
commit b453a072cc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 40 additions and 5 deletions

View file

@ -118,6 +118,7 @@ pub enum TSType<'a> {
TSIntersectionType(Box<'a, TSIntersectionType<'a>>),
TSLiteralType(Box<'a, TSLiteralType<'a>>),
TSMappedType(Box<'a, TSMappedType<'a>>),
TSNamedTupleMember(Box<'a, TSNamedTupleMember<'a>>),
TSQualifiedName(Box<'a, TSQualifiedName<'a>>),
TSTemplateLiteralType(Box<'a, TSTemplateLiteralType<'a>>),
TSTupleType(Box<'a, TSTupleType<'a>>),

View file

@ -323,6 +323,7 @@ impl<'a> GetSpan for TSType<'a> {
Self::TSArrayType(t) => t.span,
Self::TSIntersectionType(t) => t.span,
Self::TSMappedType(t) => t.span,
Self::TSNamedTupleMember(t) => t.span,
Self::TSInferType(t) => t.span,
Self::TSConstructorType(t) => t.span,
Self::TSIndexedAccessType(t) => t.span,

View file

@ -139,6 +139,9 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for TSType<'a> {
p.print_semicolon_if_needed();
p.print_str(b"}");
}
Self::TSNamedTupleMember(decl) => {
decl.gen(p, ctx);
}
Self::TSLiteralType(decl) => {
decl.literal.gen(p, ctx);
}
@ -507,15 +510,21 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for TSTupleElement<'a> {
ts_type.type_annotation.gen(p, ctx);
}
TSTupleElement::TSNamedTupleMember(ts_type) => {
ts_type.label.gen(p, ctx);
p.print_str(b":");
p.print_soft_space();
ts_type.element_type.gen(p, ctx);
ts_type.gen(p, ctx);
}
}
}
}
impl<'a, const MINIFY: bool> Gen<MINIFY> for TSNamedTupleMember<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
self.label.gen(p, ctx);
p.print_str(b":");
p.print_soft_space();
self.element_type.gen(p, ctx);
}
}
impl<'a, const MINIFY: bool> Gen<MINIFY> for TSModuleDeclaration<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
if self.modifiers.contains(ModifierKind::Export) {

View file

@ -408,6 +408,7 @@ fn get_ts_element_type_span(ts_type: &TSType) -> Option<Span> {
TSType::TSIntersectionType(t) => Some(t.span),
TSType::TSLiteralType(t) => Some(t.span),
TSType::TSMappedType(t) => Some(t.span),
TSType::TSNamedTupleMember(t) => Some(t.span),
TSType::TSQualifiedName(t) => Some(t.span),
TSType::TSTemplateLiteralType(t) => Some(t.span),
TSType::TSTupleType(t) => Some(t.span),

View file

@ -52,7 +52,23 @@ impl<'a> SeparatedList<'a> for TSTupleElementList<'a> {
fn parse_element(&mut self, p: &mut ParserImpl<'a>) -> Result<()> {
let span = p.start_span();
if p.is_at_named_tuple_element() {
let _is_rest = p.eat(Kind::Dot3);
if p.eat(Kind::Dot3) {
let member_span = p.start_span();
let label = p.parse_identifier_name()?;
p.expect(Kind::Colon)?;
let element_type = p.parse_ts_type()?;
self.elements.push(TSTupleElement::TSRestType(p.ast.alloc(TSRestType {
span: p.end_span(span),
type_annotation: TSType::TSNamedTupleMember(p.ast.alloc(TSNamedTupleMember {
span: p.end_span(member_span),
element_type,
label,
optional: false, // A tuple member cannot be both optional and rest. (TS5085)
})),
})));
return Ok(());
}
let label = p.parse_identifier_name()?;
let optional = p.eat(Kind::Question);
p.expect(Kind::Colon)?;

View file

@ -676,6 +676,7 @@ impl<'a> Format<'a> for TSType<'a> {
TSType::TSIntersectionType(v) => v.format(p),
TSType::TSLiteralType(v) => v.format(p),
TSType::TSMappedType(v) => v.format(p),
TSType::TSNamedTupleMember(v) => v.format(p),
TSType::TSQualifiedName(v) => v.format(p),
TSType::TSTemplateLiteralType(v) => v.format(p),
TSType::TSTupleType(v) => v.format(p),
@ -843,6 +844,12 @@ impl<'a> Format<'a> for TSMappedType<'a> {
}
}
impl<'a> Format<'a> for TSNamedTupleMember<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
line!()
}
}
impl<'a> Format<'a> for TSQualifiedName<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
line!()