Skip to content

Commit 0825834

Browse files
committed
fix(ast/estree): correct this in TSTypeName in TS-ESTree AST (#10603)
Part of #9705. TS-ESTree presents a `TSTypeName` which is an identifier `this` as a `ThisExpression`. e.g. `type T = typeof this;` or `type T = typeof this.foo;`
1 parent dcf718f commit 0825834

File tree

7 files changed

+55
-29
lines changed

7 files changed

+55
-29
lines changed

crates/oxc_ast/src/ast/ts.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,7 @@ pub struct TSTypeReference<'a> {
770770
#[derive(Debug)]
771771
#[generate_derive(CloneIn, Dummy, TakeIn, GetSpan, GetSpanMut, GetAddress, ContentEq, ESTree)]
772772
pub enum TSTypeName<'a> {
773+
#[estree(via = TSTypeNameIdentifierReference)]
773774
IdentifierReference(Box<'a, IdentifierReference<'a>>) = 0,
774775
QualifiedName(Box<'a, TSQualifiedName<'a>>) = 1,
775776
}

crates/oxc_ast/src/generated/derive_estree.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2763,7 +2763,9 @@ impl ESTree for TSTypeReference<'_> {
27632763
impl ESTree for TSTypeName<'_> {
27642764
fn serialize<S: Serializer>(&self, serializer: S) {
27652765
match self {
2766-
Self::IdentifierReference(it) => it.serialize(serializer),
2766+
Self::IdentifierReference(it) => {
2767+
crate::serialize::TSTypeNameIdentifierReference(it).serialize(serializer)
2768+
}
27672769
Self::QualifiedName(it) => it.serialize(serializer),
27682770
}
27692771
}
@@ -3118,7 +3120,9 @@ impl ESTree for TSTypeQueryExprName<'_> {
31183120
fn serialize<S: Serializer>(&self, serializer: S) {
31193121
match self {
31203122
Self::TSImportType(it) => it.serialize(serializer),
3121-
Self::IdentifierReference(it) => it.serialize(serializer),
3123+
Self::IdentifierReference(it) => {
3124+
crate::serialize::TSTypeNameIdentifierReference(it).serialize(serializer)
3125+
}
31223126
Self::QualifiedName(it) => it.serialize(serializer),
31233127
}
31243128
}
@@ -3252,7 +3256,9 @@ impl ESTree for TSModuleReference<'_> {
32523256
fn serialize<S: Serializer>(&self, serializer: S) {
32533257
match self {
32543258
Self::ExternalModuleReference(it) => it.serialize(serializer),
3255-
Self::IdentifierReference(it) => it.serialize(serializer),
3259+
Self::IdentifierReference(it) => {
3260+
crate::serialize::TSTypeNameIdentifierReference(it).serialize(serializer)
3261+
}
32563262
Self::QualifiedName(it) => it.serialize(serializer),
32573263
}
32583264
}

crates/oxc_ast/src/serialize.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,6 +1317,31 @@ impl ESTree for TSMappedTypeModifierOperatorConverter<'_> {
13171317
}
13181318
}
13191319

1320+
/// Serializer for `IdentifierReference` variant of `TSTypeName`.
1321+
///
1322+
/// Where is an identifier called `this`, TS-ESTree presents it as a `ThisExpression`.
1323+
#[ast_meta]
1324+
#[estree(
1325+
ts_type = "IdentifierReference | ThisExpression",
1326+
raw_deser = "
1327+
let id = DESER[IdentifierReference](POS);
1328+
if (id.name === 'this') id = { type: 'ThisExpression', start: id.start, end: id.end };
1329+
id
1330+
"
1331+
)]
1332+
pub struct TSTypeNameIdentifierReference<'a, 'b>(pub &'b IdentifierReference<'a>);
1333+
1334+
impl ESTree for TSTypeNameIdentifierReference<'_, '_> {
1335+
fn serialize<S: Serializer>(&self, serializer: S) {
1336+
let ident = self.0;
1337+
if ident.name == "this" {
1338+
ThisExpression { span: ident.span }.serialize(serializer);
1339+
} else {
1340+
ident.serialize(serializer);
1341+
}
1342+
}
1343+
}
1344+
13201345
/// Serializer for `params` field of `TSCallSignatureDeclaration`.
13211346
///
13221347
/// These add `this_param` to start of the `params` array.

napi/parser/deserialize-js.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3796,7 +3796,9 @@ function deserializeTSTupleElement(pos) {
37963796
function deserializeTSTypeName(pos) {
37973797
switch (uint8[pos]) {
37983798
case 0:
3799-
return deserializeBoxIdentifierReference(pos + 8);
3799+
let id = deserializeIdentifierReference(pos + 8);
3800+
if (id.name === 'this') id = { type: 'ThisExpression', start: id.start, end: id.end };
3801+
return id;
38003802
case 1:
38013803
return deserializeBoxTSQualifiedName(pos + 8);
38023804
default:
@@ -3896,7 +3898,9 @@ function deserializeTSModuleDeclarationBody(pos) {
38963898
function deserializeTSTypeQueryExprName(pos) {
38973899
switch (uint8[pos]) {
38983900
case 0:
3899-
return deserializeBoxIdentifierReference(pos + 8);
3901+
let id = deserializeIdentifierReference(pos + 8);
3902+
if (id.name === 'this') id = { type: 'ThisExpression', start: id.start, end: id.end };
3903+
return id;
39003904
case 1:
39013905
return deserializeBoxTSQualifiedName(pos + 8);
39023906
case 2:
@@ -3914,7 +3918,9 @@ function deserializeTSMappedTypeModifierOperator(pos) {
39143918
function deserializeTSModuleReference(pos) {
39153919
switch (uint8[pos]) {
39163920
case 0:
3917-
return deserializeBoxIdentifierReference(pos + 8);
3921+
let id = deserializeIdentifierReference(pos + 8);
3922+
if (id.name === 'this') id = { type: 'ThisExpression', start: id.start, end: id.end };
3923+
return id;
39183924
case 1:
39193925
return deserializeBoxTSQualifiedName(pos + 8);
39203926
case 2:

napi/parser/deserialize-ts.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3948,7 +3948,9 @@ function deserializeTSTupleElement(pos) {
39483948
function deserializeTSTypeName(pos) {
39493949
switch (uint8[pos]) {
39503950
case 0:
3951-
return deserializeBoxIdentifierReference(pos + 8);
3951+
let id = deserializeIdentifierReference(pos + 8);
3952+
if (id.name === 'this') id = { type: 'ThisExpression', start: id.start, end: id.end };
3953+
return id;
39523954
case 1:
39533955
return deserializeBoxTSQualifiedName(pos + 8);
39543956
default:
@@ -4048,7 +4050,9 @@ function deserializeTSModuleDeclarationBody(pos) {
40484050
function deserializeTSTypeQueryExprName(pos) {
40494051
switch (uint8[pos]) {
40504052
case 0:
4051-
return deserializeBoxIdentifierReference(pos + 8);
4053+
let id = deserializeIdentifierReference(pos + 8);
4054+
if (id.name === 'this') id = { type: 'ThisExpression', start: id.start, end: id.end };
4055+
return id;
40524056
case 1:
40534057
return deserializeBoxTSQualifiedName(pos + 8);
40544058
case 2:
@@ -4066,7 +4070,9 @@ function deserializeTSMappedTypeModifierOperator(pos) {
40664070
function deserializeTSModuleReference(pos) {
40674071
switch (uint8[pos]) {
40684072
case 0:
4069-
return deserializeBoxIdentifierReference(pos + 8);
4073+
let id = deserializeIdentifierReference(pos + 8);
4074+
if (id.name === 'this') id = { type: 'ThisExpression', start: id.start, end: id.end };
4075+
return id;
40704076
case 1:
40714077
return deserializeBoxTSQualifiedName(pos + 8);
40724078
case 2:

npm/oxc-types/types.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1176,7 +1176,7 @@ export interface TSTypeReference extends Span {
11761176
typeArguments: TSTypeParameterInstantiation | null;
11771177
}
11781178

1179-
export type TSTypeName = IdentifierReference | TSQualifiedName;
1179+
export type TSTypeName = IdentifierReference | ThisExpression | TSQualifiedName;
11801180

11811181
export interface TSQualifiedName extends Span {
11821182
type: 'TSQualifiedName';

tasks/coverage/snapshots/estree_typescript.snap

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ commit: 15392346
22

33
estree_typescript Summary:
44
AST Parsed : 11245/11404 (98.61%)
5-
Positive Passed: 11065/11404 (97.03%)
5+
Positive Passed: 11074/11404 (97.11%)
66
Expect to Parse: tasks/coverage/typescript/tests/cases/compiler/ClassDeclarationWithInvalidConstOnPropertyDeclaration.ts
77
A class member cannot have the 'const' keyword.
88

@@ -48,8 +48,6 @@ Mismatch: tasks/coverage/typescript/tests/cases/compiler/bigintWithoutLib.ts
4848

4949
Mismatch: tasks/coverage/typescript/tests/cases/compiler/bluebirdStaticThis.ts
5050

51-
Mismatch: tasks/coverage/typescript/tests/cases/compiler/circularGetAccessor.ts
52-
5351
Expect to Parse: tasks/coverage/typescript/tests/cases/compiler/classExpressionPropertyModifiers.ts
5452
Expected a semicolon or an implicit semicolon after a statement, but found none
5553

@@ -92,8 +90,6 @@ Mismatch: tasks/coverage/typescript/tests/cases/compiler/declFileWithInternalMod
9290
9391
Mismatch: tasks/coverage/typescript/tests/cases/compiler/declarationEmitHasTypesRefOnNamespaceUse.ts
9492
95-
Mismatch: tasks/coverage/typescript/tests/cases/compiler/declarationEmitTypeofThisInClass.ts
96-
9793
Expect to Parse: tasks/coverage/typescript/tests/cases/compiler/declareAlreadySeen.ts
9894
declare' modifier already seen.
9995
@@ -405,10 +401,6 @@ Mismatch: tasks/coverage/typescript/tests/cases/compiler/strictModeReservedWordI
405401
Expect to Parse: tasks/coverage/typescript/tests/cases/compiler/thisAssignmentInNamespaceDeclaration1.ts
406402
Expected a semicolon or an implicit semicolon after a statement, but found none
407403
408-
Mismatch: tasks/coverage/typescript/tests/cases/compiler/thisInTypeQuery.ts
409-
410-
Mismatch: tasks/coverage/typescript/tests/cases/compiler/typeofThisInMethodSignature.ts
411-
412404
Expect to Parse: tasks/coverage/typescript/tests/cases/compiler/unusedLocalsInMethod4.ts
413405
Missing initializer in const declaration
414406
@@ -484,10 +476,6 @@ Unexpected token
484476
Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/classes/members/privateNames/privateNameJsBadDeclaration.ts
485477
Unexpected token
486478

487-
Mismatch: tasks/coverage/typescript/tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts
488-
489-
Mismatch: tasks/coverage/typescript/tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts
490-
491479
Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/classes/propertyMemberDeclarations/propertyNamedConstructor.ts
492480
Classes can't have a field named 'constructor'
493481
@@ -951,17 +939,11 @@ A rest element must be last in a destructuring pattern
951939
Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/types/rest/restElementMustBeLast.ts
952940
A rest element must be last in a destructuring pattern
953941
954-
Mismatch: tasks/coverage/typescript/tests/cases/conformance/types/specifyingTypes/typeQueries/typeofThis.ts
955-
956-
Mismatch: tasks/coverage/typescript/tests/cases/conformance/types/specifyingTypes/typeQueries/typeofThisWithImplicitThis.ts
957-
958942
Mismatch: tasks/coverage/typescript/tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags02.ts
959943
960944
Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/types/stringLiteral/stringLiteralTypesInVariableDeclarations01.ts
961945
Missing initializer in const declaration
962946
963-
Mismatch: tasks/coverage/typescript/tests/cases/conformance/types/thisType/thisTypeInFunctions4.ts
964-
965947
Mismatch: tasks/coverage/typescript/tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts
966948
967949
Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts

0 commit comments

Comments
 (0)