Skip to content

Commit

Permalink
Preserve declarations for private fields, static fields, and methods
Browse files Browse the repository at this point in the history
Fixes #560

Alternate approach to #570 where we emit the declarations as-is, e.g. `#foo = 3;`
in the class body. Note that this does *not* transpile these private fields, so
the underlying runtime still needs to support them and will give a syntax error
if it doesn't.
  • Loading branch information
alangpierce committed Dec 29, 2020
1 parent 4ff153c commit f8db417
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 4 deletions.
10 changes: 10 additions & 0 deletions src/util/getClassInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,26 @@ export default function getClassInfo(
// Either a method or a field. Skip to the identifier part.
const statementStartIndex = tokens.currentIndex();
let isStatic = false;
let isESPrivate = false;
while (isAccessModifier(tokens.currentToken())) {
if (tokens.matches1(tt._static)) {
isStatic = true;
}
if (tokens.matches1(tt.hash)) {
isESPrivate = true;
}
tokens.nextToken();
}
if (isStatic && tokens.matches1(tt.braceL)) {
// This is a static block, so don't process it in any special way.
skipToNextClassElement(tokens, classContextId);
continue;
}
if (isESPrivate) {
// Sucrase doesn't attempt to transpile private fields; just leave them as-is.
skipToNextClassElement(tokens, classContextId);
continue;
}
if (
tokens.matchesContextual(ContextualKeyword._constructor) &&
!tokens.currentToken().isType
Expand Down Expand Up @@ -280,6 +289,7 @@ function isAccessModifier(token: Token): boolean {
tt._abstract,
tt.star,
tt._declare,
tt.hash,
].includes(token.type);
}

Expand Down
6 changes: 3 additions & 3 deletions test/flow-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,9 @@ describe("transform flow", () => {
}
`,
`"use strict";
class A {constructor() { A.prototype.__init.call(this); }
__init() {this.prop2 = value}
class A {
#prop1;
#prop2 = value;
}
`,
);
Expand Down
42 changes: 42 additions & 0 deletions test/sucrase-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1233,4 +1233,46 @@ describe("sucrase", () => {
{transforms: ["typescript"]},
);
});

it("correctly preserves private fields, static fields, and methods", () => {
assertResult(
`
class A {
#x = 1;
y = 2;
static #privateStaticField = 3;
#privateMethod() {
return A.#privateStaticField;
}
printValues() {
console.log(this.#x);
console.log(this.y);
console.log(this.#privateMethod());
}
}
`,
`
class A {constructor() { A.prototype.__init.call(this); }
#x = 1;
__init() {this.y = 2}
static #privateStaticField = 3;
#privateMethod() {
return A.#privateStaticField;
}
printValues() {
console.log(this.#x);
console.log(this.y);
console.log(this.#privateMethod());
}
}
`,
{transforms: []},
);
});
});
4 changes: 3 additions & 1 deletion test/typescript-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1926,11 +1926,13 @@ describe("typescript transform", () => {
`
class Foo {
readonly #x: number;
readonly #y: number;
}
`,
`"use strict";
class Foo {
#x;
#y;
}
`,
);
Expand Down

0 comments on commit f8db417

Please sign in to comment.