mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
fix(ast/estree): fix Function.this_param (#9913)
`Function.this_param` is included in `Function.params` as an `Identifier` with `name: "this"` https://ast-explorer.dev/#eNolykEKwzAMRNGrmFm10F7AB+lKG2MU6uAoJlICwfjuUchiNu9PR0XEnI6keSvN8EFzsLPxA1/WWuT27D7tkq2sEqaX/YvG0Mfb53X12klCIHBe0o839R8hOtRkrEYgGRgXircmAw==
This commit is contained in:
1 parent
5631ebd2ec
commit
8228b74af2
9 files changed
+88
-530
No files matched your search
@@ -1658,7 +1658,7 @@ pub struct BindingRestElement<'a> {
|
||||
add_fields(expression = False),
|
||||
field_order(
|
||||
r#type, span, id, expression, generator, r#async, params, body,
|
||||
declare, type_parameters, this_param, return_type,
|
||||
declare, type_parameters, return_type,
|
||||
),
|
||||
)]
|
||||
pub struct Function<'a> {
|
||||
@@ -1695,10 +1695,12 @@ pub struct Function<'a> {
|
||||
/// });
|
||||
/// ```
|
||||
#[ts]
|
||||
#[estree(skip)]
|
||||
pub this_param: Option<Box<'a, TSThisParameter<'a>>>,
|
||||
/// Function parameters.
|
||||
///
|
||||
/// Does not include `this` parameters used by some TypeScript functions.
|
||||
#[estree(via = FunctionFormalParameters)]
|
||||
pub params: Box<'a, FormalParameters<'a>>,
|
||||
/// The TypeScript return type annotation.
|
||||
#[ts]
|
||||
|
||||
@@ -31,6 +31,10 @@ use super::{inherit_variants, js::*, literal::*};
|
||||
#[ast(visit)]
|
||||
#[derive(Debug)]
|
||||
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ESTree)]
|
||||
#[estree(
|
||||
rename = "Identifier",
|
||||
add_fields(decorators = TsEmptyArray, optional = TsFalse, name = This)
|
||||
)]
|
||||
pub struct TSThisParameter<'a> {
|
||||
pub span: Span,
|
||||
#[estree(skip)]
|
||||
|
||||
@@ -1345,11 +1345,10 @@ impl ESTree for Function<'_> {
|
||||
state.serialize_field("expression", &crate::serialize::False(self));
|
||||
state.serialize_field("generator", &self.generator);
|
||||
state.serialize_field("async", &self.r#async);
|
||||
state.serialize_field("params", &self.params);
|
||||
state.serialize_field("params", &crate::serialize::FunctionFormalParameters(self));
|
||||
state.serialize_field("body", &self.body);
|
||||
state.serialize_ts_field("declare", &self.declare);
|
||||
state.serialize_ts_field("typeParameters", &self.type_parameters);
|
||||
state.serialize_ts_field("thisParam", &self.this_param);
|
||||
state.serialize_ts_field("returnType", &self.return_type);
|
||||
state.end();
|
||||
}
|
||||
@@ -2278,10 +2277,13 @@ impl ESTree for JSXText<'_> {
|
||||
impl ESTree for TSThisParameter<'_> {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) {
|
||||
let mut state = serializer.serialize_struct();
|
||||
state.serialize_field("type", &JsonSafeString("TSThisParameter"));
|
||||
state.serialize_field("type", &JsonSafeString("Identifier"));
|
||||
state.serialize_field("start", &self.span.start);
|
||||
state.serialize_field("end", &self.span.end);
|
||||
state.serialize_field("typeAnnotation", &self.type_annotation);
|
||||
state.serialize_field("name", &crate::serialize::This(self));
|
||||
state.serialize_ts_field("decorators", &crate::serialize::TsEmptyArray(self));
|
||||
state.serialize_ts_field("optional", &crate::serialize::TsFalse(self));
|
||||
state.end();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,6 +150,17 @@ impl<T> ESTree for Init<'_, T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Serialized as `"this"`.
|
||||
#[ast_meta]
|
||||
#[estree(ts_type = "'this'", raw_deser = "'this'")]
|
||||
pub struct This<'b, T>(#[expect(dead_code)] pub &'b T);
|
||||
|
||||
impl<T> ESTree for This<'_, T> {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) {
|
||||
JsonSafeString("this").serialize(serializer);
|
||||
}
|
||||
}
|
||||
|
||||
#[ast_meta]
|
||||
#[estree(ts_type = "[]", raw_deser = "[]")]
|
||||
#[ts]
|
||||
@@ -642,6 +653,42 @@ impl ESTree for ExpressionStatementDirective<'_, '_> {
|
||||
}
|
||||
}
|
||||
|
||||
#[ast_meta]
|
||||
#[estree(
|
||||
ts_type = "ParamPattern[]",
|
||||
raw_deser = "
|
||||
const params = DESER[Box<FormalParameters>](POS_OFFSET.params);
|
||||
/* IF_TS */
|
||||
const thisParam = DESER[Option<Box<TSThisParameter>>](POS_OFFSET.this_param)
|
||||
if (thisParam !== null) {
|
||||
params.unshift(thisParam);
|
||||
}
|
||||
/* END_IF_TS */
|
||||
params
|
||||
"
|
||||
)]
|
||||
pub struct FunctionFormalParameters<'a, 'b>(pub &'b Function<'a>);
|
||||
|
||||
impl ESTree for FunctionFormalParameters<'_, '_> {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) {
|
||||
let mut seq = serializer.serialize_sequence();
|
||||
|
||||
if let Some(this_param) = &self.0.this_param {
|
||||
seq.serialize_ts_element(this_param);
|
||||
}
|
||||
|
||||
for item in &self.0.params.items {
|
||||
seq.serialize_element(item);
|
||||
}
|
||||
|
||||
if let Some(rest) = &self.0.params.rest {
|
||||
seq.serialize_element(&FormalParametersRest(rest));
|
||||
}
|
||||
|
||||
seq.end();
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------
|
||||
// Comments
|
||||
// --------------------
|
||||
|
||||
@@ -4,6 +4,7 @@ use super::{Config, ESTree, ESTreeSerializer, Formatter, Serializer, SerializerP
|
||||
pub trait SequenceSerializer {
|
||||
/// Serialize sequence entry.
|
||||
fn serialize_element<T: ESTree + ?Sized>(&mut self, value: &T);
|
||||
fn serialize_ts_element<T: ESTree + ?Sized>(&mut self, value: &T);
|
||||
|
||||
/// Finish serializing sequence.
|
||||
fn end(self);
|
||||
@@ -43,6 +44,12 @@ impl<C: Config, F: Formatter> SequenceSerializer for ESTreeSequenceSerializer<'_
|
||||
value.serialize(&mut *self.serializer);
|
||||
}
|
||||
|
||||
fn serialize_ts_element<T: ESTree + ?Sized>(&mut self, value: &T) {
|
||||
if C::INCLUDE_TS_FIELDS {
|
||||
self.serialize_element(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// Finish serializing sequence.
|
||||
fn end(mut self) {
|
||||
let (buffer, formatter) = self.serializer.buffer_and_formatter_mut();
|
||||
|
||||
@@ -749,6 +749,7 @@ function deserializeBindingRestElement(pos) {
|
||||
}
|
||||
|
||||
function deserializeFunction(pos) {
|
||||
const params = deserializeBoxFormalParameters(pos + 72);
|
||||
return {
|
||||
type: deserializeFunctionType(pos + 8),
|
||||
start: deserializeU32(pos),
|
||||
@@ -757,7 +758,7 @@ function deserializeFunction(pos) {
|
||||
expression: false,
|
||||
generator: deserializeBool(pos + 48),
|
||||
async: deserializeBool(pos + 49),
|
||||
params: deserializeBoxFormalParameters(pos + 72),
|
||||
params,
|
||||
body: deserializeOptionBoxFunctionBody(pos + 88),
|
||||
};
|
||||
}
|
||||
@@ -1262,10 +1263,11 @@ function deserializeJSXText(pos) {
|
||||
|
||||
function deserializeTSThisParameter(pos) {
|
||||
return {
|
||||
type: 'TSThisParameter',
|
||||
type: 'Identifier',
|
||||
start: deserializeU32(pos),
|
||||
end: deserializeU32(pos + 4),
|
||||
typeAnnotation: deserializeOptionBoxTSTypeAnnotation(pos + 16),
|
||||
name: 'this',
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -768,6 +768,11 @@ function deserializeBindingRestElement(pos) {
|
||||
}
|
||||
|
||||
function deserializeFunction(pos) {
|
||||
const params = deserializeBoxFormalParameters(pos + 72);
|
||||
const thisParam = deserializeOptionBoxTSThisParameter(pos + 64);
|
||||
if (thisParam !== null) {
|
||||
params.unshift(thisParam);
|
||||
}
|
||||
return {
|
||||
type: deserializeFunctionType(pos + 8),
|
||||
start: deserializeU32(pos),
|
||||
@@ -776,11 +781,10 @@ function deserializeFunction(pos) {
|
||||
expression: false,
|
||||
generator: deserializeBool(pos + 48),
|
||||
async: deserializeBool(pos + 49),
|
||||
params: deserializeBoxFormalParameters(pos + 72),
|
||||
params,
|
||||
body: deserializeOptionBoxFunctionBody(pos + 88),
|
||||
declare: deserializeBool(pos + 50),
|
||||
typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 56),
|
||||
thisParam: deserializeOptionBoxTSThisParameter(pos + 64),
|
||||
returnType: deserializeOptionBoxTSTypeAnnotation(pos + 80),
|
||||
};
|
||||
}
|
||||
@@ -1326,10 +1330,13 @@ function deserializeJSXText(pos) {
|
||||
|
||||
function deserializeTSThisParameter(pos) {
|
||||
return {
|
||||
type: 'TSThisParameter',
|
||||
type: 'Identifier',
|
||||
start: deserializeU32(pos),
|
||||
end: deserializeU32(pos + 4),
|
||||
typeAnnotation: deserializeOptionBoxTSTypeAnnotation(pos + 16),
|
||||
name: 'this',
|
||||
decorators: [],
|
||||
optional: false,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Vendored
+4
-2
@@ -553,7 +553,6 @@ export interface Function extends Span {
|
||||
body: FunctionBody | null;
|
||||
declare?: boolean;
|
||||
typeParameters?: TSTypeParameterDeclaration | null;
|
||||
thisParam?: TSThisParameter | null;
|
||||
returnType?: TSTypeAnnotation | null;
|
||||
}
|
||||
|
||||
@@ -918,8 +917,11 @@ export interface JSXText extends Span {
|
||||
}
|
||||
|
||||
export interface TSThisParameter extends Span {
|
||||
type: 'TSThisParameter';
|
||||
type: 'Identifier';
|
||||
typeAnnotation: TSTypeAnnotation | null;
|
||||
name: 'this';
|
||||
decorators?: [];
|
||||
optional?: false;
|
||||
}
|
||||
|
||||
export interface TSEnumDeclaration extends Span {
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user