Skip to content

Commit b42bbf4

Browse files
committed
feat(es/parser): typeof on #private Fields
1 parent 14ab63b commit b42bbf4

File tree

15 files changed

+810
-16
lines changed

15 files changed

+810
-16
lines changed

crates/swc_ecma_ast/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ pub use self::{
5858
typescript::{
5959
Accessibility, TruePlusMinus, TsArrayType, TsAsExpr, TsCallSignatureDecl,
6060
TsConditionalType, TsConstAssertion, TsConstructSignatureDecl, TsConstructorType,
61-
TsEntityName, TsEnumDecl, TsEnumMember, TsEnumMemberId, TsExportAssignment,
61+
TsEntityMember, TsEntityName, TsEnumDecl, TsEnumMember, TsEnumMemberId, TsExportAssignment,
6262
TsExprWithTypeArgs, TsExternalModuleRef, TsFnOrConstructorType, TsFnParam, TsFnType,
6363
TsGetterSignature, TsImportEqualsDecl, TsImportType, TsIndexSignature, TsIndexedAccessType,
6464
TsInferType, TsInstantiation, TsInterfaceBody, TsInterfaceDecl, TsIntersectionType,

crates/swc_ecma_ast/src/typescript.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::{
1818
lit::{Bool, Number, Str},
1919
module::ModuleItem,
2020
pat::{ArrayPat, AssignPat, ObjectPat, Pat, RestPat},
21-
BigInt, BindingIdent, TplElement,
21+
BigInt, BindingIdent, PrivateName, TplElement,
2222
};
2323

2424
#[ast_node("TsTypeAnnotation")]
@@ -101,7 +101,7 @@ pub struct TsQualifiedName {
101101
#[span(lo)]
102102
pub left: TsEntityName,
103103
#[span(hi)]
104-
pub right: Ident,
104+
pub right: TsEntityMember,
105105
}
106106

107107
#[ast_node]
@@ -116,6 +116,18 @@ pub enum TsEntityName {
116116
Ident(Ident),
117117
}
118118

119+
#[ast_node]
120+
#[derive(Eq, Hash, Is, EqIgnoreSpan)]
121+
#[allow(variant_size_differences)]
122+
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
123+
pub enum TsEntityMember {
124+
#[tag("Identifier")]
125+
Ident(Ident),
126+
127+
#[tag("PrivateName")]
128+
PrivateName(PrivateName),
129+
}
130+
119131
// ================
120132
// TypeScript type members (for type literal / interface / class)
121133
// ================

crates/swc_ecma_codegen/src/typescript.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,16 @@ where
137137
}
138138
}
139139

140+
#[emitter]
141+
fn emit_ts_entity_member(&mut self, n: &TsEntityMember) -> Result {
142+
self.emit_leading_comments_of_span(n.span(), false)?;
143+
144+
match n {
145+
TsEntityMember::Ident(n) => emit!(n),
146+
TsEntityMember::PrivateName(n) => emit!(n),
147+
}
148+
}
149+
140150
#[emitter]
141151
fn emit_ts_enum_decl(&mut self, n: &TsEnumDecl) -> Result {
142152
self.emit_leading_comments_of_span(n.span(), false)?;

crates/swc_ecma_parser/src/parser/typescript.rs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,11 @@ impl<I: Tokens> Parser<I> {
178178
}
179179

180180
/// `tsParseEntityName`
181-
fn parse_ts_entity_name(&mut self, allow_reserved_words: bool) -> PResult<TsEntityName> {
181+
fn parse_ts_entity_name(
182+
&mut self,
183+
allow_reserved_words: bool,
184+
allow_private_identifiers: bool,
185+
) -> PResult<TsEntityName> {
182186
debug_assert!(self.input.syntax().typescript());
183187

184188
let init = self.parse_ident_name()?;
@@ -194,7 +198,7 @@ impl<I: Tokens> Parser<I> {
194198
let mut entity = TsEntityName::Ident(init);
195199
while eat!(self, '.') {
196200
let dot_start = cur_pos!(self);
197-
if !is!(self, '#') && !is!(self, IdentName) {
201+
if !allow_private_identifiers && !is!(self, '#') && !is!(self, IdentName) {
198202
self.emit_err(
199203
Span::new(dot_start, dot_start, Default::default()),
200204
SyntaxError::TS1003,
@@ -203,10 +207,13 @@ impl<I: Tokens> Parser<I> {
203207
}
204208

205209
let left = entity;
206-
let right = if allow_reserved_words {
207-
self.parse_ident_name()?
210+
let right = if allow_private_identifiers {
211+
self.parse_maybe_private_name()?
212+
.either(Into::into, Into::into)
213+
} else if allow_reserved_words {
214+
self.parse_ident_name()?.into()
208215
} else {
209-
self.parse_ident(false, false)?
216+
self.parse_ident(false, false)?.into()
210217
};
211218
entity = TsEntityName::TsQualifiedName(Box::new(TsQualifiedName { left, right }));
212219
}
@@ -223,7 +230,9 @@ impl<I: Tokens> Parser<I> {
223230

224231
let has_modifier = self.eat_any_ts_modifier()?;
225232

226-
let type_name = self.parse_ts_entity_name(/* allow_reserved_words */ true)?;
233+
let type_name = self.parse_ts_entity_name(
234+
/* allow_reserved_words */ true, /* allow_private_identifiers */ false,
235+
)?;
227236
trace_cur!(self, parse_ts_type_ref__type_args);
228237
let type_params = if !self.input.had_line_break_before_cur() && is!(self, '<') {
229238
Some(self.parse_ts_type_args()?)
@@ -315,7 +324,7 @@ impl<I: Tokens> Parser<I> {
315324
expect!(self, ')');
316325

317326
let qualifier = if eat!(self, '.') {
318-
self.parse_ts_entity_name(false).map(Some)?
327+
self.parse_ts_entity_name(false, false).map(Some)?
319328
} else {
320329
None
321330
};
@@ -345,7 +354,7 @@ impl<I: Tokens> Parser<I> {
345354
} else {
346355
self.parse_ts_entity_name(
347356
// allow_reserved_word
348-
true,
357+
true, true,
349358
)
350359
.map(From::from)?
351360
};
@@ -1124,8 +1133,10 @@ impl<I: Tokens> Parser<I> {
11241133
if self.is_ts_external_module_ref()? {
11251134
self.parse_ts_external_module_ref().map(From::from)
11261135
} else {
1127-
self.parse_ts_entity_name(/* allow_reserved_words */ false)
1128-
.map(From::from)
1136+
self.parse_ts_entity_name(
1137+
/* allow_reserved_words */ false, /* allow_private_identifiers */ false,
1138+
)
1139+
.map(From::from)
11291140
}
11301141
}
11311142

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class C {
2+
#a = 'a';
3+
4+
constructor() {
5+
const a: typeof this.#a = ''; // Ok
6+
const b: typeof this.#a = 1; // Error
7+
}
8+
}

0 commit comments

Comments
 (0)