fix(es/ast): Fix definition of SetterProp (#8314)

**Related issue:**

 - Closes #8157
 - Closes #8377
This commit is contained in:
Donny/강동윤 2024-01-19 15:06:13 +09:00
parent 572bcaefc1
commit bc38ac906c
33 changed files with 275 additions and 89 deletions

View File

@ -6,10 +6,9 @@ use crate::{
function::Function,
ident::Ident,
lit::{BigInt, Number, Str},
pat::Pat,
stmt::BlockStmt,
typescript::TsTypeAnn,
Id, MemberProp,
Id, MemberProp, Pat,
};
#[ast_node]
@ -76,6 +75,7 @@ pub struct GetterProp {
pub struct SetterProp {
pub span: Span,
pub key: PropName,
pub this_param: Option<Pat>,
pub param: Box<Pat>,
#[cfg_attr(feature = "serde-impl", serde(default))]
pub body: Option<BlockStmt>,

View File

@ -2218,7 +2218,15 @@ where
formatting_space!();
punct!("(");
if let Some(this) = &node.this_param {
emit!(this);
punct!(",");
formatting_space!();
}
emit!(node.param);
punct!(")");
emit!(node.body);

View File

@ -77,14 +77,14 @@ macro_rules! impl_visit_mut_fn {
let (mut params, body) = self.visit_mut_fn_like(
&mut vec![Param {
span: DUMMY_SP,
decorators: Default::default(),
decorators: vec![],
pat: *f.param.take(),
}],
&mut f.body.take().unwrap(),
);
debug_assert!(params.len() == 1);
f.param = Box::new(params.pop().unwrap().pat);
f.param = Box::new(params.into_iter().next().unwrap().pat);
f.body = Some(body);
}

View File

@ -172,6 +172,7 @@ impl VisitMut for ComputedProps {
body,
param,
key,
..
}) => (
key,
Box::new(Function {

View File

@ -1,6 +1,6 @@
//! Parser for object literal.
use swc_common::Spanned;
use swc_common::{Spanned, DUMMY_SP};
use super::*;
use crate::parser::class_and_fn::is_not_this;
@ -355,21 +355,33 @@ impl<I: Tokens> ParseObject<Box<Expr>> for Parser<I> {
|Function {
mut params, body, ..
}| {
params.retain(|p| match &p.pat {
Pat::Ident(p) => p.sym != "this",
_ => true,
});
let mut this = None;
if params.len() >= 2 {
this = Some(params.remove(0).pat);
}
let param = Box::new(
params
.into_iter()
.next()
.map(|v| v.pat)
.unwrap_or_else(|| {
parser.emit_err(
key_span,
SyntaxError::SetterParam,
);
Pat::Invalid(Invalid { span: DUMMY_SP })
}),
);
// debug_assert_eq!(params.len(), 1);
PropOrSpread::Prop(Box::new(Prop::Setter(SetterProp {
span: span!(parser, start),
key,
body,
param: Box::new(
params.into_iter().map(|p| p.pat).next().unwrap_or(
Pat::Invalid(Invalid { span: key_span }),
),
),
param,
this_param: this,
})))
},
)

View File

@ -334,6 +334,7 @@
"value": "b",
"optional": false
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {

View File

@ -334,6 +334,7 @@
"value": "b",
"optional": false
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {

View File

@ -269,6 +269,7 @@
"optional": false
}
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {
@ -408,6 +409,7 @@
}
}
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {
@ -518,6 +520,7 @@
"raw": "\"\""
}
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {
@ -619,6 +622,7 @@
"optional": false
}
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {
@ -748,6 +752,7 @@
]
}
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {

View File

@ -269,6 +269,7 @@
"optional": false
}
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {
@ -408,6 +409,7 @@
}
}
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {
@ -518,6 +520,7 @@
"raw": "\"\""
}
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {
@ -619,6 +622,7 @@
"optional": false
}
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {
@ -748,6 +752,7 @@
]
}
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {

View File

@ -160,6 +160,7 @@
}
}
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {

View File

@ -160,6 +160,7 @@
}
}
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {

View File

@ -270,6 +270,7 @@
}
}
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {

View File

@ -270,6 +270,7 @@
}
}
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {

View File

@ -1728,6 +1728,7 @@
"value": "x",
"optional": false
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {
@ -1935,6 +1936,7 @@
"value": "y",
"optional": false
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {

View File

@ -2808,6 +2808,7 @@
"value": "X",
"optional": false
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {

View File

@ -148,6 +148,7 @@
"value": "a",
"optional": false
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {
@ -275,6 +276,7 @@
"value": "a",
"optional": false
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {

View File

@ -196,6 +196,7 @@
"value": "bar",
"optional": false
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {
@ -391,6 +392,7 @@
"value": "foo",
"optional": false
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {

View File

@ -59,6 +59,7 @@
"value": "Foo",
"optional": false
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {

View File

@ -67,6 +67,7 @@
"optional": false
}
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {

View File

@ -59,6 +59,7 @@
"value": "Foo",
"optional": false
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {

View File

@ -2808,6 +2808,7 @@
"value": "X",
"optional": false
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {

View File

@ -158,6 +158,7 @@
}
}
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {

View File

@ -212,6 +212,7 @@
}
}
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {

View File

@ -274,6 +274,43 @@
"value": "x",
"optional": false
},
"thisParam": {
"type": "Identifier",
"span": {
"start": 204,
"end": 213,
"ctxt": 0
},
"value": "this",
"optional": false,
"typeAnnotation": {
"type": "TsTypeAnnotation",
"span": {
"start": 208,
"end": 213,
"ctxt": 0
},
"typeAnnotation": {
"type": "TsTypeReference",
"span": {
"start": 210,
"end": 213,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 210,
"end": 213,
"ctxt": 0
},
"value": "Foo",
"optional": false
},
"typeParams": null
}
}
},
"param": {
"type": "Identifier",
"span": {
@ -526,6 +563,7 @@
"value": "x",
"optional": false
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {
@ -746,6 +784,43 @@
"value": "x",
"optional": false
},
"thisParam": {
"type": "Identifier",
"span": {
"start": 441,
"end": 450,
"ctxt": 0
},
"value": "this",
"optional": false,
"typeAnnotation": {
"type": "TsTypeAnnotation",
"span": {
"start": 445,
"end": 450,
"ctxt": 0
},
"typeAnnotation": {
"type": "TsTypeReference",
"span": {
"start": 447,
"end": 450,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 447,
"end": 450,
"ctxt": 0
},
"value": "Foo",
"optional": false
},
"typeParams": null
}
}
},
"param": {
"type": "Identifier",
"span": {
@ -982,6 +1057,17 @@
"value": "x",
"optional": false
},
"thisParam": {
"type": "Identifier",
"span": {
"start": 580,
"end": 584,
"ctxt": 0
},
"value": "this",
"optional": false,
"typeAnnotation": null
},
"param": {
"type": "Identifier",
"span": {

View File

@ -403,6 +403,43 @@
"value": "x",
"optional": false
},
"thisParam": {
"type": "Identifier",
"span": {
"start": 267,
"end": 276,
"ctxt": 0
},
"value": "this",
"optional": false,
"typeAnnotation": {
"type": "TsTypeAnnotation",
"span": {
"start": 271,
"end": 276,
"ctxt": 0
},
"typeAnnotation": {
"type": "TsTypeReference",
"span": {
"start": 273,
"end": 276,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 273,
"end": 276,
"ctxt": 0
},
"value": "Bar",
"optional": false
},
"typeParams": null
}
}
},
"param": {
"type": "Identifier",
"span": {

View File

@ -400,6 +400,7 @@
"value": "e",
"optional": false
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {

View File

@ -1050,6 +1050,7 @@
"value": "prop",
"optional": false
},
"thisParam": null,
"param": {
"type": "Identifier",
"span": {

View File

@ -23,7 +23,7 @@ impl_struct!(KeyValueProp, [key, value]);
impl_struct!(AssignProp, [key, value]);
impl_struct!(GetterProp, [span, key, type_ann, body]);
impl_struct!(SetterProp, [span, key, param, body]);
impl_struct!(SetterProp, [span, key, param, this_param, body]);
impl_struct!(MethodProp, [key, function]);

View File

@ -1125,6 +1125,7 @@ impl<'a> VisitMut for Resolver<'a> {
{
self.with_child(ScopeKind::Fn, |child| {
child.ident_type = IdentType::Binding;
n.this_param.visit_mut_with(child);
n.param.visit_mut_with(child);
n.body.visit_mut_with(child);
});

View File

@ -23,75 +23,16 @@ impl VisitMut for StripType {
Box<TsTypeParamInstantiation>
);
fn visit_mut_module_items(&mut self, n: &mut Vec<ModuleItem>) {
n.retain(should_retain_module_item);
n.visit_mut_children_with(self);
}
fn visit_mut_import_specifiers(&mut self, n: &mut Vec<ImportSpecifier>) {
n.retain(|s| !matches!(s, ImportSpecifier::Named(named) if named.is_type_only));
}
fn visit_mut_export_specifiers(&mut self, n: &mut Vec<ExportSpecifier>) {
n.retain(|s| match s {
ExportSpecifier::Named(ExportNamedSpecifier { is_type_only, .. }) => !is_type_only,
_ => true,
})
}
fn visit_mut_stmts(&mut self, n: &mut Vec<Stmt>) {
n.retain(should_retain_stmt);
n.visit_mut_children_with(self);
}
// https://github.com/tc39/proposal-type-annotations#parameter-optionality
fn visit_mut_ident(&mut self, n: &mut Ident) {
n.optional = false;
}
fn visit_mut_array_pat(&mut self, n: &mut ArrayPat) {
n.visit_mut_children_with(self);
n.optional = false;
}
fn visit_mut_object_pat(&mut self, pat: &mut ObjectPat) {
pat.visit_mut_children_with(self);
pat.optional = false;
}
fn visit_mut_expr(&mut self, n: &mut Expr) {
// https://github.com/tc39/proposal-type-annotations#type-assertions
// https://github.com/tc39/proposal-type-annotations#non-nullable-assertions
while let Expr::TsAs(TsAsExpr { expr, .. })
| Expr::TsNonNull(TsNonNullExpr { expr, .. })
| Expr::TsTypeAssertion(TsTypeAssertion { expr, .. })
| Expr::TsConstAssertion(TsConstAssertion { expr, .. })
| Expr::TsInstantiation(TsInstantiation { expr, .. })
| Expr::TsSatisfies(TsSatisfiesExpr { expr, .. }) = n
{
*n = *expr.take();
}
n.visit_mut_children_with(self);
}
// https://github.com/tc39/proposal-type-annotations#this-parameters
fn visit_mut_params(&mut self, n: &mut Vec<Param>) {
if n.first()
.filter(|param| {
matches!(
&param.pat,
Pat::Ident(BindingIdent {
id: Ident { sym, .. },
..
}) if &**sym == "this"
)
})
.is_some()
{
n.drain(0..1);
}
fn visit_mut_auto_accessor(&mut self, n: &mut AutoAccessor) {
n.type_ann = None;
n.accessibility = None;
n.definite = false;
n.is_override = false;
n.visit_mut_children_with(self);
}
@ -130,11 +71,6 @@ impl VisitMut for StripType {
n.visit_mut_children_with(self);
}
fn visit_mut_constructor(&mut self, n: &mut Constructor) {
n.accessibility = None;
n.visit_mut_children_with(self);
}
fn visit_mut_class_method(&mut self, n: &mut ClassMethod) {
n.accessibility = None;
n.is_override = false;
@ -153,6 +89,73 @@ impl VisitMut for StripType {
prop.visit_mut_children_with(self);
}
fn visit_mut_constructor(&mut self, n: &mut Constructor) {
n.accessibility = None;
n.visit_mut_children_with(self);
}
fn visit_mut_export_specifiers(&mut self, n: &mut Vec<ExportSpecifier>) {
n.retain(|s| match s {
ExportSpecifier::Named(ExportNamedSpecifier { is_type_only, .. }) => !is_type_only,
_ => true,
})
}
fn visit_mut_expr(&mut self, n: &mut Expr) {
// https://github.com/tc39/proposal-type-annotations#type-assertions
// https://github.com/tc39/proposal-type-annotations#non-nullable-assertions
while let Expr::TsAs(TsAsExpr { expr, .. })
| Expr::TsNonNull(TsNonNullExpr { expr, .. })
| Expr::TsTypeAssertion(TsTypeAssertion { expr, .. })
| Expr::TsConstAssertion(TsConstAssertion { expr, .. })
| Expr::TsInstantiation(TsInstantiation { expr, .. })
| Expr::TsSatisfies(TsSatisfiesExpr { expr, .. }) = n
{
*n = *expr.take();
}
n.visit_mut_children_with(self);
}
// https://github.com/tc39/proposal-type-annotations#parameter-optionality
fn visit_mut_ident(&mut self, n: &mut Ident) {
n.optional = false;
}
fn visit_mut_import_specifiers(&mut self, n: &mut Vec<ImportSpecifier>) {
n.retain(|s| !matches!(s, ImportSpecifier::Named(named) if named.is_type_only));
}
fn visit_mut_module_items(&mut self, n: &mut Vec<ModuleItem>) {
n.retain(should_retain_module_item);
n.visit_mut_children_with(self);
}
fn visit_mut_object_pat(&mut self, pat: &mut ObjectPat) {
pat.visit_mut_children_with(self);
pat.optional = false;
}
// https://github.com/tc39/proposal-type-annotations#this-parameters
fn visit_mut_params(&mut self, n: &mut Vec<Param>) {
if n.first()
.filter(|param| {
matches!(
&param.pat,
Pat::Ident(BindingIdent {
id: Ident { sym, .. },
..
}) if &**sym == "this"
)
})
.is_some()
{
n.drain(0..1);
}
n.visit_mut_children_with(self);
}
fn visit_mut_private_prop(&mut self, prop: &mut PrivateProp) {
prop.readonly = false;
prop.is_override = false;
@ -162,11 +165,14 @@ impl VisitMut for StripType {
prop.visit_mut_children_with(self);
}
fn visit_mut_auto_accessor(&mut self, n: &mut AutoAccessor) {
n.type_ann = None;
n.accessibility = None;
n.definite = false;
n.is_override = false;
fn visit_mut_setter_prop(&mut self, n: &mut SetterProp) {
n.this_param = None;
n.visit_mut_children_with(self);
}
fn visit_mut_stmts(&mut self, n: &mut Vec<Stmt>) {
n.retain(should_retain_stmt);
n.visit_mut_children_with(self);
}

View File

@ -1379,6 +1379,7 @@ fn for_each_id_ref_in_expr(e: &Expr, op: &mut impl FnMut(&Ident)) {
}
Prop::Setter(p) => {
for_each_id_ref_in_prop_name(&p.key, op);
for_each_id_ref_in_pat(&p.param, op);
}
Prop::Method(p) => {

View File

@ -665,6 +665,7 @@ fn extend_super(
Prop::Setter(SetterProp {
span: DUMMY_SP,
key: PropName::Ident(quote_ident!("_")),
this_param: None,
param: value.clone().into(),
body: Some(BlockStmt {
span: DUMMY_SP,
@ -721,6 +722,7 @@ fn extend_super(
Prop::Setter(SetterProp {
span: DUMMY_SP,
key: PropName::Ident(quote_ident!("_")),
this_param: None,
param: value.clone().into(),
body: Some(BlockStmt {
span: DUMMY_SP,

View File

@ -1290,6 +1290,7 @@ define!({
pub struct SetterProp {
pub span: Span,
pub key: PropName,
pub this_param: Option<Pat>,
pub param: Box<Pat>,
pub body: Option<BlockStmt>,
}