Skip to content
This repository has been archived by the owner on May 19, 2018. It is now read-only.

Commit

Permalink
Add support for class private methods (#703)
Browse files Browse the repository at this point in the history
* Add support for class private methods

This commit adds parser support for the TC39 Stage 2 Private Methods
proposal.

This commit also changes "key" in ClassPrivateProperty from an
Identifier to a PrivateName, as well as disallowing #constructor as a
valid private field name.

* Add tests for string literal get/set/async

These should be treated as regular methods and not special get/set/async
behaviour.

* Add tests for class private methods

This also removes a test from the Test262 whitelist that failed before
the changes for private methods support and now passes.

* Modify class private prop tests for PrivateName

* Add class private prop tests for #constructor

* Fix existing ASI test case failure
  • Loading branch information
Qantas94Heavy authored and jridgewell committed Sep 6, 2017
1 parent b65b5a2 commit 65bea96
Show file tree
Hide file tree
Showing 54 changed files with 3,321 additions and 316 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ require("babylon").parse("code", {
| `decorators` (Stage 1) and `decorators2` (Stage 2 [proposal](https://github.com/tc39/proposal-decorators)) | `@a class A {}` |
| `classProperties` ([proposal](https://github.com/tc39/proposal-class-public-fields)) | `class A { b = 1; }` |
| `classPrivateProperties` ([proposal](https://github.com/tc39/proposal-private-fields)) | `class A { #b = 1; }` |
| `classPrivateMethods` ([proposal](https://github.com/tc39/proposal-private-methods)) | `class A { #c() {} }` |
| `exportExtensions` ([proposal 1](https://github.com/leebyron/ecmascript-export-default-from)), ([proposal 2](https://github.com/leebyron/ecmascript-export-ns-from)) | Proposal 1: `export v from "mod"` Proposal 2: `export * as ns from "mod"` |
| `asyncGenerators` ([proposal](https://github.com/tc39/proposal-async-iteration)) | `async function*() {}`, `for await (let a of b) {}` |
| `functionBind` ([proposal](https://github.com/zenparsing/es-function-bind)) | `a::b`, `::console.log` |
Expand Down
17 changes: 15 additions & 2 deletions ast/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ These are the core Babylon AST node types.
- [Classes](#classes)
- [ClassBody](#classbody)
- [ClassMethod](#classmethod)
- [ClassPrivateMethod](#classprivatemethod)
- [ClassProperty](#classproperty)
- [ClassPrivateProperty](#classprivateproperty)
- [ClassDeclaration](#classdeclaration)
Expand Down Expand Up @@ -1032,7 +1033,7 @@ interface Class <: Node {
```js
interface ClassBody <: Node {
type: "ClassBody";
body: [ ClassMethod | ClassProperty | ClassPrivateProperty ];
body: [ ClassMethod | ClassPrivateMethod | ClassProperty | ClassPrivateProperty ];
}
```

Expand All @@ -1049,6 +1050,18 @@ interface ClassMethod <: Function {
}
```

## ClassPrivateMethod

```js
interface ClassPrivateMethod <: Function {
type: "ClassPrivateMethod";
key: PrivateName;
kind: "method" | "get" | "set";
static: boolean;
decorators: [ Decorator ];
}
```

## ClassProperty

```js
Expand All @@ -1066,7 +1079,7 @@ interface ClassProperty <: Node {
```js
interface ClassPrivateProperty <: Node {
type: "ClassPrivateProperty";
key: Identifier;
key: PrivateName;
value: Expression;
static: boolean;
}
Expand Down
4 changes: 1 addition & 3 deletions scripts/test262_whitelist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,6 @@ language/statements/class/definition/early-errors-class-method-await-in-formals.
language/statements/class/strict-mode/with.js(default)
language/statements/class/syntax/early-errors/class-body-has-direct-super-missing-class-heritage.js(default)
language/statements/class/syntax/early-errors/class-body-has-direct-super-missing-class-heritage.js(strict mode)
language/statements/class/syntax/early-errors/class-body-static-method-get-propname-prototype.js(default)
language/statements/class/syntax/early-errors/class-body-static-method-get-propname-prototype.js(strict mode)
language/statements/class/syntax/early-errors/class-definition-evaluation-block-duplicate-binding.js(default)
language/statements/class/syntax/early-errors/class-definition-evaluation-block-duplicate-binding.js(strict mode)
language/statements/class/syntax/early-errors/class-definition-evaluation-scriptbody-duplicate-binding.js(default)
Expand Down Expand Up @@ -1305,4 +1303,4 @@ language/statements/class/fields-wrapped-in-sc-string-literal-names.js(strict mo

language/statements/labeled/let-identifier-with-newline.js(default)
language/statements/labeled/value-yield-non-strict-escaped.js(default)
language/statements/let/syntax/escaped-let.js(default)
language/statements/let/syntax/escaped-let.js(default)
18 changes: 14 additions & 4 deletions src/parser/expression.js
Original file line number Diff line number Diff line change
Expand Up @@ -1398,20 +1398,30 @@ export default class ExpressionParser extends LValParser {
}

parsePropertyName(
prop: N.ObjectOrClassMember | N.TsNamedTypeElementBase,
): N.Expression {
prop:
| N.ObjectOrClassMember
| N.ClassPrivateProperty
| N.ClassPrivateMethod
| N.TsNamedTypeElementBase,
): N.Expression | N.Identifier {
if (this.eat(tt.bracketL)) {
prop.computed = true;
prop.key = this.parseMaybeAssign();
this.expect(tt.bracketR);
} else {
prop.computed = false;
const oldInPropertyName = this.state.inPropertyName;
this.state.inPropertyName = true;
// We check if it's valid for it to be a private name when we push it.
prop.key =
this.match(tt.num) || this.match(tt.string)
? this.parseExprAtom()
: this.parseIdentifier(true);
: this.parseMaybePrivateName();

if (prop.key.type !== "PrivateName") {
// ClassPrivateProperty is never computed, so we don't assign in that case.
prop.computed = false;
}

this.state.inPropertyName = oldInPropertyName;
}

Expand Down
Loading

0 comments on commit 65bea96

Please sign in to comment.