diff --git a/README.md b/README.md index 873f034253..c17f861d8a 100644 --- a/README.md +++ b/README.md @@ -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/littledan/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` | diff --git a/ast/spec.md b/ast/spec.md index e3cbaab936..2f6c86b80b 100644 --- a/ast/spec.md +++ b/ast/spec.md @@ -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) @@ -1032,7 +1033,7 @@ interface Class <: Node { ```js interface ClassBody <: Node { type: "ClassBody"; - body: [ ClassMethod | ClassProperty | ClassPrivateProperty ]; + body: [ ClassMethod | ClassPrivateMethod | ClassProperty | ClassPrivateProperty ]; } ``` @@ -1049,6 +1050,18 @@ interface ClassMethod <: Function { } ``` +## ClassPrivateMethod + +```js +interface ClassPrivateMethod <: Function { + type: "ClassPrivateMethod"; + key: Identifier; + kind: "method" | "get" | "set"; + static: boolean; + decorators: [ Decorator ]; +} +``` + ## ClassProperty ```js diff --git a/src/parser/expression.js b/src/parser/expression.js index 642bffa83c..407b7c1ef1 100644 --- a/src/parser/expression.js +++ b/src/parser/expression.js @@ -1418,6 +1418,19 @@ export default class ExpressionParser extends LValParser { return prop.key; } + // FIXME: does this make sense separate? + parseClassPrivateName( + prop: N.ClassPrivateProperty | N.ClassPrivateMethod, + ): N.Expression { + prop.computed = false; + const oldInPropertyName = this.state.inPropertyName; + this.state.inPropertyName = true; + prop.key = this.parseIdentifier(true); + this.state.inPropertyName = oldInPropertyName; + + return prop.key; + } + // Initialize empty function node. initFunction(node: N.BodilessFunctionOrMethodBase, isAsync: ?boolean): void { diff --git a/src/parser/statement.js b/src/parser/statement.js index 76b5ffcc57..f97c561672 100644 --- a/src/parser/statement.js +++ b/src/parser/statement.js @@ -955,17 +955,6 @@ export default class StatementParser extends ExpressionParser { isStatic = true; } - if (this.match(tt.hash)) { - // Private property - this.expectPlugin("classPrivateProperties"); - this.next(); - const privateProp: N.ClassPrivateProperty = memberAny; - privateProp.key = this.parseIdentifier(true); - privateProp.static = isStatic; - classBody.body.push(this.parsePrivateClassProperty(privateProp)); - return; - } - this.parseClassMemberWithIsStatic(classBody, member, state, isStatic); } @@ -976,16 +965,37 @@ export default class StatementParser extends ExpressionParser { isStatic: boolean, ) { const memberAny: any = member; - const methodOrProp: N.ClassMethod | N.ClassProperty = memberAny; - const method: N.ClassMethod = memberAny; - const prop: N.ClassProperty = memberAny; + const methodOrProp: + | N.ClassMethod + | N.ClassPrivateMethod + | N.ClassProperty + | N.ClassPrivateProperty = memberAny; + const method: N.ClassMethod | N.ClassPrivateMethod = memberAny; + const prop: N.ClassProperty | N.ClassPrivateProperty = memberAny; methodOrProp.static = isStatic; if (this.eat(tt.star)) { // a generator method.kind = "method"; + + if (this.match(tt.hash)) { + this.expectPlugin("classPrivateMethods"); + this.next(); + // Private generator method + this.parseClassPrivateName(method); + this.parseClassPrivateMethod( + classBody, + method, + true, + false, + /* isConstructor */ false, + ); + return; + } + this.parsePropertyName(method); + if (this.isNonstaticConstructor(method)) { this.raise(method.key.start, "Constructor can't be a generator"); } @@ -1009,21 +1019,43 @@ export default class StatementParser extends ExpressionParser { return; } + const isPrivate = this.match(tt.hash); + if (isPrivate) { + this.expectOnePlugin(["classPrivateProperties", "classPrivateMethods"]); + // Skip over the hash. + this.next(); + } + const isSimple = this.match(tt.name); - const key = this.parseClassPropertyName(methodOrProp); + const key = isPrivate + ? this.parseClassPrivateName(methodOrProp) + : this.parseClassPropertyName(methodOrProp); this.parsePostMemberNameModifiers(methodOrProp); if (this.isClassMethod()) { + method.kind = "method"; + + if (isPrivate) { + // TODO: seems a bit inconsistent error throwing: in some cases we've already + // eaten the #, but in other cases we haven't. How to solve? + this.expectPlugin("classPrivateMethods"); + this.parseClassPrivateMethod( + classBody, + method, + false, + false, + isConstructor, + ); + return; + } + // a normal method const isConstructor = this.isNonstaticConstructor(method); + if (isConstructor) { method.kind = "constructor"; - } else { - method.kind = "method"; - } - if (isConstructor) { if (method.decorators) { this.raise( method.start, @@ -1040,7 +1072,13 @@ export default class StatementParser extends ExpressionParser { this.parseClassMethod(classBody, method, false, false, isConstructor); } else if (this.isClassProperty()) { - this.pushClassProperty(classBody, prop); + if (isPrivate) { + this.expectPlugin("classPrivateProperties"); + // Private property + classBody.body.push(this.parseClassPrivateProperty(prop)); + } else { + this.pushClassProperty(classBody, prop); + } } else if (isSimple && key.name === "async" && !this.isLineTerminator()) { // an async method let isGenerator = false; @@ -1050,17 +1088,37 @@ export default class StatementParser extends ExpressionParser { isGenerator = true; } method.kind = "method"; - this.parsePropertyName(method); - if (this.isNonstaticConstructor(method)) { - this.raise(method.key.start, "Constructor can't be an async function"); + + if (this.match(tt.hash)) { + // private async method + this.expectPlugin("classPrivateMethods"); + // The private # wouldn't have been eaten yet as the "async" was in front of it. + this.next(); + // The so-called parsed name would have been "async": get the real name. + this.parseClassPrivateName(method); + this.parseClassPrivateMethod( + classBody, + method, + isGenerator, + true, + /* isConstructor */ false, + ); + } else { + this.parsePropertyName(method); + if (this.isNonstaticConstructor(method)) { + this.raise( + method.key.start, + "Constructor can't be an async function", + ); + } + this.parseClassMethod( + classBody, + method, + isGenerator, + true, + /* isConstructor */ false, + ); } - this.parseClassMethod( - classBody, - method, - isGenerator, - true, - /* isConstructor */ false, - ); } else if ( isSimple && (key.name === "get" || key.name === "set") && @@ -1069,27 +1127,54 @@ export default class StatementParser extends ExpressionParser { // `get\n*` is an uninitialized property named 'get' followed by a generator. // a getter or setter method.kind = key.name; - this.parsePropertyName(method); - if (this.isNonstaticConstructor(method)) { - this.raise(method.key.start, "Constructor can't have get/set modifier"); + + if (this.match(tt.hash)) { + // private getter/setter + this.expectPlugin("classPrivateMethods"); + // The private # wouldn't have been eaten yet as the "get/set" was in front of it. + this.next(); + // The so-called parsed name would have been "get/set": get the real name. + this.parseClassPrivateName(method); + this.parseClassPrivateMethod( + classBody, + method, + false, + false, + /* isConstructor */ false, + ); + } else { + this.parsePropertyName(method); + if (this.isNonstaticConstructor(method)) { + this.raise( + method.key.start, + "Constructor can't have get/set modifier", + ); + } + this.parseClassMethod( + classBody, + method, + false, + false, + /* isConstructor */ false, + ); } - this.parseClassMethod( - classBody, - method, - false, - false, - /* isConstructor */ false, - ); + this.checkGetterSetterParamCount(method); } else if (this.isLineTerminator()) { // an uninitialized class property (due to ASI, since we don't otherwise recognize the next token) - if (this.isNonstaticConstructor(prop)) { - this.raise( - prop.key.start, - "Classes may not have a non-static field named 'constructor'", - ); + if (isPrivate) { + this.expectPlugin("classPrivateProperties"); + // Private property + classBody.body.push(this.parseClassPrivateProperty(prop)); + } else { + if (this.isNonstaticConstructor(prop)) { + this.raise( + prop.key.start, + "Classes may not have a non-static field named 'constructor'", + ); + } + classBody.body.push(this.parseClassProperty(prop)); } - classBody.body.push(this.parseClassProperty(prop)); } else { this.unexpected(); } @@ -1134,17 +1219,14 @@ export default class StatementParser extends ExpressionParser { return undefined; } - parsePrivateClassProperty( + parseClassPrivateProperty( node: N.ClassPrivateProperty, ): N.ClassPrivateProperty { this.state.inClassProperty = true; - if (this.match(tt.eq)) { - this.next(); - node.value = this.parseMaybeAssign(); - } else { - node.value = null; - } + if (node.computed !== undefined) node.computed = undefined; + node.value = this.eat(tt.eq) ? this.parseMaybeAssign() : null; + this.semicolon(); this.state.inClassProperty = false; return this.finishNode(node, "ClassPrivateProperty"); @@ -1188,6 +1270,24 @@ export default class StatementParser extends ExpressionParser { ); } + parseClassPrivateMethod( + classBody: N.ClassBody, + method: N.ClassMethod, + isGenerator: boolean, + isAsync: boolean, + isConstructor: boolean, + ): void { + classBody.body.push( + this.parseMethod( + method, + isGenerator, + isAsync, + isConstructor, + "ClassPrivateMethod", + ), + ); + } + parseClassId( node: N.Class, isStatement: boolean, diff --git a/src/tokenizer/index.js b/src/tokenizer/index.js index f9ece03f80..aa0058e2f3 100644 --- a/src/tokenizer/index.js +++ b/src/tokenizer/index.js @@ -521,7 +521,8 @@ export default class Tokenizer extends LocationParser { switch (code) { case 35: // '#' if ( - this.hasPlugin("classPrivateProperties") && + (this.hasPlugin("classPrivateProperties") || + this.hasPlugin("classPrivateMethods")) && this.state.classLevel > 0 ) { ++this.state.pos; diff --git a/src/types.js b/src/types.js index cf6fec8c3c..d98a2382f1 100644 --- a/src/types.js +++ b/src/types.js @@ -635,6 +635,7 @@ export type ClassMemberBase = NodeBase & export type ClassMember = | ClassMethod + | ClassPrivateMethod | ClassProperty | ClassPrivateProperty | TsIndexSignature; @@ -643,6 +644,7 @@ export type MethodLike = | ObjectMethod | FunctionExpression | ClassMethod + | ClassPrivateMethod | TSDeclareMethod; export type MethodBase = FunctionBase & { @@ -664,6 +666,12 @@ export type ClassMethod = MethodBase & variance?: ?FlowVariance, // TODO: Not in spec }; +export type ClassPrivateMethod = NodeBase & + ClassMethodOrDeclareMethodCommon & { + type: "ClassPrivateMethod", + key: Identifier, + }; + export type ClassProperty = ClassMemberBase & { type: "ClassProperty", key: Expression, diff --git a/test/fixtures/experimental/class-private-methods/async-generator/actual.js b/test/fixtures/experimental/class-private-methods/async-generator/actual.js new file mode 100644 index 0000000000..c04e90e7a3 --- /dev/null +++ b/test/fixtures/experimental/class-private-methods/async-generator/actual.js @@ -0,0 +1,13 @@ +class Foo { + async* #readLines(path) { + let file = await fileOpen(path); + + try { + while (!file.EOF) { + yield await file.readLine(); + } + } finally { + await file.close(); + } + } +} diff --git a/test/fixtures/experimental/class-private-methods/async-generator/expected.json b/test/fixtures/experimental/class-private-methods/async-generator/expected.json new file mode 100644 index 0000000000..eb4c865fb7 --- /dev/null +++ b/test/fixtures/experimental/class-private-methods/async-generator/expected.json @@ -0,0 +1,640 @@ +{ + "type": "File", + "start": 0, + "end": 212, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 13, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 212, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 13, + "column": 1 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 212, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 13, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 9 + }, + "identifierName": "Foo" + }, + "name": "Foo" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 10, + "end": 212, + "loc": { + "start": { + "line": 1, + "column": 10 + }, + "end": { + "line": 13, + "column": 1 + } + }, + "body": [ + { + "type": "ClassPrivateMethod", + "start": 14, + "end": 210, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 12, + "column": 3 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 22, + "end": 31, + "loc": { + "start": { + "line": 2, + "column": 10 + }, + "end": { + "line": 2, + "column": 19 + }, + "identifierName": "readLines" + }, + "name": "readLines" + }, + "kind": "method", + "id": null, + "generator": true, + "expression": false, + "async": true, + "params": [ + { + "type": "Identifier", + "start": 32, + "end": 36, + "loc": { + "start": { + "line": 2, + "column": 20 + }, + "end": { + "line": 2, + "column": 24 + }, + "identifierName": "path" + }, + "name": "path" + } + ], + "body": { + "type": "BlockStatement", + "start": 38, + "end": 210, + "loc": { + "start": { + "line": 2, + "column": 26 + }, + "end": { + "line": 12, + "column": 3 + } + }, + "body": [ + { + "type": "VariableDeclaration", + "start": 44, + "end": 76, + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 36 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 48, + "end": 75, + "loc": { + "start": { + "line": 3, + "column": 8 + }, + "end": { + "line": 3, + "column": 35 + } + }, + "id": { + "type": "Identifier", + "start": 48, + "end": 52, + "loc": { + "start": { + "line": 3, + "column": 8 + }, + "end": { + "line": 3, + "column": 12 + }, + "identifierName": "file" + }, + "name": "file" + }, + "init": { + "type": "AwaitExpression", + "start": 55, + "end": 75, + "loc": { + "start": { + "line": 3, + "column": 15 + }, + "end": { + "line": 3, + "column": 35 + } + }, + "argument": { + "type": "CallExpression", + "start": 61, + "end": 75, + "loc": { + "start": { + "line": 3, + "column": 21 + }, + "end": { + "line": 3, + "column": 35 + } + }, + "callee": { + "type": "Identifier", + "start": 61, + "end": 69, + "loc": { + "start": { + "line": 3, + "column": 21 + }, + "end": { + "line": 3, + "column": 29 + }, + "identifierName": "fileOpen" + }, + "name": "fileOpen" + }, + "arguments": [ + { + "type": "Identifier", + "start": 70, + "end": 74, + "loc": { + "start": { + "line": 3, + "column": 30 + }, + "end": { + "line": 3, + "column": 34 + }, + "identifierName": "path" + }, + "name": "path" + } + ] + } + } + } + ], + "kind": "let" + }, + { + "type": "TryStatement", + "start": 82, + "end": 206, + "loc": { + "start": { + "line": 5, + "column": 4 + }, + "end": { + "line": 11, + "column": 5 + } + }, + "block": { + "type": "BlockStatement", + "start": 86, + "end": 164, + "loc": { + "start": { + "line": 5, + "column": 8 + }, + "end": { + "line": 9, + "column": 5 + } + }, + "body": [ + { + "type": "WhileStatement", + "start": 94, + "end": 158, + "loc": { + "start": { + "line": 6, + "column": 6 + }, + "end": { + "line": 8, + "column": 7 + } + }, + "test": { + "type": "UnaryExpression", + "start": 101, + "end": 110, + "loc": { + "start": { + "line": 6, + "column": 13 + }, + "end": { + "line": 6, + "column": 22 + } + }, + "operator": "!", + "prefix": true, + "argument": { + "type": "MemberExpression", + "start": 102, + "end": 110, + "loc": { + "start": { + "line": 6, + "column": 14 + }, + "end": { + "line": 6, + "column": 22 + } + }, + "object": { + "type": "Identifier", + "start": 102, + "end": 106, + "loc": { + "start": { + "line": 6, + "column": 14 + }, + "end": { + "line": 6, + "column": 18 + }, + "identifierName": "file" + }, + "name": "file" + }, + "property": { + "type": "Identifier", + "start": 107, + "end": 110, + "loc": { + "start": { + "line": 6, + "column": 19 + }, + "end": { + "line": 6, + "column": 22 + }, + "identifierName": "EOF" + }, + "name": "EOF" + }, + "computed": false + }, + "extra": { + "parenthesizedArgument": false + } + }, + "body": { + "type": "BlockStatement", + "start": 112, + "end": 158, + "loc": { + "start": { + "line": 6, + "column": 24 + }, + "end": { + "line": 8, + "column": 7 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 122, + "end": 150, + "loc": { + "start": { + "line": 7, + "column": 8 + }, + "end": { + "line": 7, + "column": 36 + } + }, + "expression": { + "type": "YieldExpression", + "start": 122, + "end": 149, + "loc": { + "start": { + "line": 7, + "column": 8 + }, + "end": { + "line": 7, + "column": 35 + } + }, + "delegate": false, + "argument": { + "type": "AwaitExpression", + "start": 128, + "end": 149, + "loc": { + "start": { + "line": 7, + "column": 14 + }, + "end": { + "line": 7, + "column": 35 + } + }, + "argument": { + "type": "CallExpression", + "start": 134, + "end": 149, + "loc": { + "start": { + "line": 7, + "column": 20 + }, + "end": { + "line": 7, + "column": 35 + } + }, + "callee": { + "type": "MemberExpression", + "start": 134, + "end": 147, + "loc": { + "start": { + "line": 7, + "column": 20 + }, + "end": { + "line": 7, + "column": 33 + } + }, + "object": { + "type": "Identifier", + "start": 134, + "end": 138, + "loc": { + "start": { + "line": 7, + "column": 20 + }, + "end": { + "line": 7, + "column": 24 + }, + "identifierName": "file" + }, + "name": "file" + }, + "property": { + "type": "Identifier", + "start": 139, + "end": 147, + "loc": { + "start": { + "line": 7, + "column": 25 + }, + "end": { + "line": 7, + "column": 33 + }, + "identifierName": "readLine" + }, + "name": "readLine" + }, + "computed": false + }, + "arguments": [] + } + } + } + } + ], + "directives": [] + } + } + ], + "directives": [] + }, + "handler": null, + "guardedHandlers": [], + "finalizer": { + "type": "BlockStatement", + "start": 173, + "end": 206, + "loc": { + "start": { + "line": 9, + "column": 14 + }, + "end": { + "line": 11, + "column": 5 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 181, + "end": 200, + "loc": { + "start": { + "line": 10, + "column": 6 + }, + "end": { + "line": 10, + "column": 25 + } + }, + "expression": { + "type": "AwaitExpression", + "start": 181, + "end": 199, + "loc": { + "start": { + "line": 10, + "column": 6 + }, + "end": { + "line": 10, + "column": 24 + } + }, + "argument": { + "type": "CallExpression", + "start": 187, + "end": 199, + "loc": { + "start": { + "line": 10, + "column": 12 + }, + "end": { + "line": 10, + "column": 24 + } + }, + "callee": { + "type": "MemberExpression", + "start": 187, + "end": 197, + "loc": { + "start": { + "line": 10, + "column": 12 + }, + "end": { + "line": 10, + "column": 22 + } + }, + "object": { + "type": "Identifier", + "start": 187, + "end": 191, + "loc": { + "start": { + "line": 10, + "column": 12 + }, + "end": { + "line": 10, + "column": 16 + }, + "identifierName": "file" + }, + "name": "file" + }, + "property": { + "type": "Identifier", + "start": 192, + "end": 197, + "loc": { + "start": { + "line": 10, + "column": 17 + }, + "end": { + "line": 10, + "column": 22 + }, + "identifierName": "close" + }, + "name": "close" + }, + "computed": false + }, + "arguments": [] + } + } + } + ], + "directives": [] + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/experimental/class-private-methods/async-generator/options.json b/test/fixtures/experimental/class-private-methods/async-generator/options.json new file mode 100644 index 0000000000..14952c9423 --- /dev/null +++ b/test/fixtures/experimental/class-private-methods/async-generator/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["classProperties", "classPrivateMethods", "asyncGenerators"] +} diff --git a/test/fixtures/experimental/class-private-methods/async/actual.js b/test/fixtures/experimental/class-private-methods/async/actual.js new file mode 100644 index 0000000000..4d4bc0cb2a --- /dev/null +++ b/test/fixtures/experimental/class-private-methods/async/actual.js @@ -0,0 +1,5 @@ +class Hotel { + async #evil() { + await notReally(); + } +} diff --git a/test/fixtures/experimental/class-private-methods/async/expected.json b/test/fixtures/experimental/class-private-methods/async/expected.json new file mode 100644 index 0000000000..e4abcf4800 --- /dev/null +++ b/test/fixtures/experimental/class-private-methods/async/expected.json @@ -0,0 +1,205 @@ +{ + "type": "File", + "start": 0, + "end": 60, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 60, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 60, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 11 + }, + "identifierName": "Hotel" + }, + "name": "Hotel" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 12, + "end": 60, + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "body": [ + { + "type": "ClassPrivateMethod", + "start": 16, + "end": 58, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 4, + "column": 3 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 23, + "end": 27, + "loc": { + "start": { + "line": 2, + "column": 9 + }, + "end": { + "line": 2, + "column": 13 + }, + "identifierName": "evil" + }, + "name": "evil" + }, + "kind": "method", + "id": null, + "generator": false, + "expression": false, + "async": true, + "params": [], + "body": { + "type": "BlockStatement", + "start": 30, + "end": 58, + "loc": { + "start": { + "line": 2, + "column": 16 + }, + "end": { + "line": 4, + "column": 3 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 36, + "end": 54, + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 22 + } + }, + "expression": { + "type": "AwaitExpression", + "start": 36, + "end": 53, + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 21 + } + }, + "argument": { + "type": "CallExpression", + "start": 42, + "end": 53, + "loc": { + "start": { + "line": 3, + "column": 10 + }, + "end": { + "line": 3, + "column": 21 + } + }, + "callee": { + "type": "Identifier", + "start": 42, + "end": 51, + "loc": { + "start": { + "line": 3, + "column": 10 + }, + "end": { + "line": 3, + "column": 19 + }, + "identifierName": "notReally" + }, + "name": "notReally" + }, + "arguments": [] + } + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/experimental/class-private-methods/async/options.json b/test/fixtures/experimental/class-private-methods/async/options.json new file mode 100644 index 0000000000..aedb66f739 --- /dev/null +++ b/test/fixtures/experimental/class-private-methods/async/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["classProperties", "classPrivateMethods"] +} diff --git a/test/fixtures/experimental/class-private-methods/combined/actual.js b/test/fixtures/experimental/class-private-methods/combined/actual.js new file mode 100644 index 0000000000..41843455f5 --- /dev/null +++ b/test/fixtures/experimental/class-private-methods/combined/actual.js @@ -0,0 +1,16 @@ +class Foo { + a = 1; + + *#a() { + yield bar(); + } + + #b = 2; + + get b() { return 9999; } + set #c(x) { return x; } + + #d() { + return Math.random(); + } +} diff --git a/test/fixtures/experimental/class-private-methods/combined/expected.json b/test/fixtures/experimental/class-private-methods/combined/expected.json new file mode 100644 index 0000000000..14830f2dde --- /dev/null +++ b/test/fixtures/experimental/class-private-methods/combined/expected.json @@ -0,0 +1,653 @@ +{ + "type": "File", + "start": 0, + "end": 159, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 16, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 159, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 16, + "column": 1 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 159, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 16, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 9 + }, + "identifierName": "Foo" + }, + "name": "Foo" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 10, + "end": 159, + "loc": { + "start": { + "line": 1, + "column": 10 + }, + "end": { + "line": 16, + "column": 1 + } + }, + "body": [ + { + "type": "ClassProperty", + "start": 14, + "end": 20, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 8 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 14, + "end": 15, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 3 + }, + "identifierName": "a" + }, + "name": "a" + }, + "value": { + "type": "NumericLiteral", + "start": 18, + "end": 19, + "loc": { + "start": { + "line": 2, + "column": 6 + }, + "end": { + "line": 2, + "column": 7 + } + }, + "extra": { + "rawValue": 1, + "raw": "1" + }, + "value": 1 + } + }, + { + "type": "ClassPrivateMethod", + "start": 24, + "end": 52, + "loc": { + "start": { + "line": 4, + "column": 2 + }, + "end": { + "line": 6, + "column": 3 + } + }, + "static": false, + "kind": "method", + "computed": false, + "key": { + "type": "Identifier", + "start": 26, + "end": 27, + "loc": { + "start": { + "line": 4, + "column": 4 + }, + "end": { + "line": 4, + "column": 5 + }, + "identifierName": "a" + }, + "name": "a" + }, + "id": null, + "generator": true, + "expression": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 30, + "end": 52, + "loc": { + "start": { + "line": 4, + "column": 8 + }, + "end": { + "line": 6, + "column": 3 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 36, + "end": 48, + "loc": { + "start": { + "line": 5, + "column": 4 + }, + "end": { + "line": 5, + "column": 16 + } + }, + "expression": { + "type": "YieldExpression", + "start": 36, + "end": 47, + "loc": { + "start": { + "line": 5, + "column": 4 + }, + "end": { + "line": 5, + "column": 15 + } + }, + "delegate": false, + "argument": { + "type": "CallExpression", + "start": 42, + "end": 47, + "loc": { + "start": { + "line": 5, + "column": 10 + }, + "end": { + "line": 5, + "column": 15 + } + }, + "callee": { + "type": "Identifier", + "start": 42, + "end": 45, + "loc": { + "start": { + "line": 5, + "column": 10 + }, + "end": { + "line": 5, + "column": 13 + }, + "identifierName": "bar" + }, + "name": "bar" + }, + "arguments": [] + } + } + } + ], + "directives": [] + } + }, + { + "type": "ClassPrivateProperty", + "start": 56, + "end": 63, + "loc": { + "start": { + "line": 8, + "column": 2 + }, + "end": { + "line": 8, + "column": 9 + } + }, + "static": false, + "key": { + "type": "Identifier", + "start": 57, + "end": 58, + "loc": { + "start": { + "line": 8, + "column": 3 + }, + "end": { + "line": 8, + "column": 4 + }, + "identifierName": "b" + }, + "name": "b" + }, + "value": { + "type": "NumericLiteral", + "start": 61, + "end": 62, + "loc": { + "start": { + "line": 8, + "column": 7 + }, + "end": { + "line": 8, + "column": 8 + } + }, + "extra": { + "rawValue": 2, + "raw": "2" + }, + "value": 2 + } + }, + { + "type": "ClassMethod", + "start": 67, + "end": 91, + "loc": { + "start": { + "line": 10, + "column": 2 + }, + "end": { + "line": 10, + "column": 26 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 71, + "end": 72, + "loc": { + "start": { + "line": 10, + "column": 6 + }, + "end": { + "line": 10, + "column": 7 + }, + "identifierName": "b" + }, + "name": "b" + }, + "kind": "get", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 75, + "end": 91, + "loc": { + "start": { + "line": 10, + "column": 10 + }, + "end": { + "line": 10, + "column": 26 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 77, + "end": 89, + "loc": { + "start": { + "line": 10, + "column": 12 + }, + "end": { + "line": 10, + "column": 24 + } + }, + "argument": { + "type": "NumericLiteral", + "start": 84, + "end": 88, + "loc": { + "start": { + "line": 10, + "column": 19 + }, + "end": { + "line": 10, + "column": 23 + } + }, + "extra": { + "rawValue": 9999, + "raw": "9999" + }, + "value": 9999 + } + } + ], + "directives": [] + } + }, + { + "type": "ClassPrivateMethod", + "start": 94, + "end": 117, + "loc": { + "start": { + "line": 11, + "column": 2 + }, + "end": { + "line": 11, + "column": 25 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 99, + "end": 100, + "loc": { + "start": { + "line": 11, + "column": 7 + }, + "end": { + "line": 11, + "column": 8 + }, + "identifierName": "c" + }, + "name": "c" + }, + "kind": "set", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 101, + "end": 102, + "loc": { + "start": { + "line": 11, + "column": 9 + }, + "end": { + "line": 11, + "column": 10 + }, + "identifierName": "x" + }, + "name": "x" + } + ], + "body": { + "type": "BlockStatement", + "start": 104, + "end": 117, + "loc": { + "start": { + "line": 11, + "column": 12 + }, + "end": { + "line": 11, + "column": 25 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 106, + "end": 115, + "loc": { + "start": { + "line": 11, + "column": 14 + }, + "end": { + "line": 11, + "column": 23 + } + }, + "argument": { + "type": "Identifier", + "start": 113, + "end": 114, + "loc": { + "start": { + "line": 11, + "column": 21 + }, + "end": { + "line": 11, + "column": 22 + }, + "identifierName": "x" + }, + "name": "x" + } + } + ], + "directives": [] + } + }, + { + "type": "ClassPrivateMethod", + "start": 121, + "end": 157, + "loc": { + "start": { + "line": 13, + "column": 2 + }, + "end": { + "line": 15, + "column": 3 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 122, + "end": 123, + "loc": { + "start": { + "line": 13, + "column": 3 + }, + "end": { + "line": 13, + "column": 4 + }, + "identifierName": "d" + }, + "name": "d" + }, + "kind": "method", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 126, + "end": 157, + "loc": { + "start": { + "line": 13, + "column": 7 + }, + "end": { + "line": 15, + "column": 3 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 132, + "end": 153, + "loc": { + "start": { + "line": 14, + "column": 4 + }, + "end": { + "line": 14, + "column": 25 + } + }, + "argument": { + "type": "CallExpression", + "start": 139, + "end": 152, + "loc": { + "start": { + "line": 14, + "column": 11 + }, + "end": { + "line": 14, + "column": 24 + } + }, + "callee": { + "type": "MemberExpression", + "start": 139, + "end": 150, + "loc": { + "start": { + "line": 14, + "column": 11 + }, + "end": { + "line": 14, + "column": 22 + } + }, + "object": { + "type": "Identifier", + "start": 139, + "end": 143, + "loc": { + "start": { + "line": 14, + "column": 11 + }, + "end": { + "line": 14, + "column": 15 + }, + "identifierName": "Math" + }, + "name": "Math" + }, + "property": { + "type": "Identifier", + "start": 144, + "end": 150, + "loc": { + "start": { + "line": 14, + "column": 16 + }, + "end": { + "line": 14, + "column": 22 + }, + "identifierName": "random" + }, + "name": "random" + }, + "computed": false + }, + "arguments": [] + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/experimental/class-private-methods/combined/options.json b/test/fixtures/experimental/class-private-methods/combined/options.json new file mode 100644 index 0000000000..55a2c821d7 --- /dev/null +++ b/test/fixtures/experimental/class-private-methods/combined/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["classProperties", "classPrivateProperties", "classPrivateMethods"] +} diff --git a/test/fixtures/experimental/class-private-properties/failure-method/actual.js b/test/fixtures/experimental/class-private-methods/failure-no-plugin/actual.js similarity index 100% rename from test/fixtures/experimental/class-private-properties/failure-method/actual.js rename to test/fixtures/experimental/class-private-methods/failure-no-plugin/actual.js diff --git a/test/fixtures/experimental/class-private-methods/failure-no-plugin/options.json b/test/fixtures/experimental/class-private-methods/failure-no-plugin/options.json new file mode 100644 index 0000000000..d58523e2f6 --- /dev/null +++ b/test/fixtures/experimental/class-private-methods/failure-no-plugin/options.json @@ -0,0 +1,4 @@ +{ + "throws": "This experimental syntax requires enabling the parser plugin: 'classPrivateMethods' (3:5)", + "plugins": ["classProperties", "classPrivateProperties"] +} diff --git a/test/fixtures/experimental/class-private-methods/generator/actual.js b/test/fixtures/experimental/class-private-methods/generator/actual.js new file mode 100644 index 0000000000..e0c6218884 --- /dev/null +++ b/test/fixtures/experimental/class-private-methods/generator/actual.js @@ -0,0 +1,5 @@ +class Hotel { + *#evil() { + yield notReally(); + } +} diff --git a/test/fixtures/experimental/class-private-methods/generator/expected.json b/test/fixtures/experimental/class-private-methods/generator/expected.json new file mode 100644 index 0000000000..16b9237c1d --- /dev/null +++ b/test/fixtures/experimental/class-private-methods/generator/expected.json @@ -0,0 +1,206 @@ +{ + "type": "File", + "start": 0, + "end": 55, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 55, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 55, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 11 + }, + "identifierName": "Hotel" + }, + "name": "Hotel" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 12, + "end": 55, + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "body": [ + { + "type": "ClassPrivateMethod", + "start": 16, + "end": 53, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 4, + "column": 3 + } + }, + "static": false, + "kind": "method", + "computed": false, + "key": { + "type": "Identifier", + "start": 18, + "end": 22, + "loc": { + "start": { + "line": 2, + "column": 4 + }, + "end": { + "line": 2, + "column": 8 + }, + "identifierName": "evil" + }, + "name": "evil" + }, + "id": null, + "generator": true, + "expression": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 25, + "end": 53, + "loc": { + "start": { + "line": 2, + "column": 11 + }, + "end": { + "line": 4, + "column": 3 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 31, + "end": 49, + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 22 + } + }, + "expression": { + "type": "YieldExpression", + "start": 31, + "end": 48, + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 21 + } + }, + "delegate": false, + "argument": { + "type": "CallExpression", + "start": 37, + "end": 48, + "loc": { + "start": { + "line": 3, + "column": 10 + }, + "end": { + "line": 3, + "column": 21 + } + }, + "callee": { + "type": "Identifier", + "start": 37, + "end": 46, + "loc": { + "start": { + "line": 3, + "column": 10 + }, + "end": { + "line": 3, + "column": 19 + }, + "identifierName": "notReally" + }, + "name": "notReally" + }, + "arguments": [] + } + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/experimental/class-private-methods/generator/options.json b/test/fixtures/experimental/class-private-methods/generator/options.json new file mode 100644 index 0000000000..aedb66f739 --- /dev/null +++ b/test/fixtures/experimental/class-private-methods/generator/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["classProperties", "classPrivateMethods"] +} diff --git a/test/fixtures/experimental/class-private-methods/get-set/actual.js b/test/fixtures/experimental/class-private-methods/get-set/actual.js new file mode 100644 index 0000000000..be4be51d20 --- /dev/null +++ b/test/fixtures/experimental/class-private-methods/get-set/actual.js @@ -0,0 +1,8 @@ +class Hotel { + get #evil() { + return ohNo(); + } + set #evil(x) { + return makeEvil(x); + } +} diff --git a/test/fixtures/experimental/class-private-methods/get-set/expected.json b/test/fixtures/experimental/class-private-methods/get-set/expected.json new file mode 100644 index 0000000000..fa89661094 --- /dev/null +++ b/test/fixtures/experimental/class-private-methods/get-set/expected.json @@ -0,0 +1,332 @@ +{ + "type": "File", + "start": 0, + "end": 99, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 8, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 99, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 8, + "column": 1 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 99, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 8, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 11 + }, + "identifierName": "Hotel" + }, + "name": "Hotel" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 12, + "end": 99, + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 8, + "column": 1 + } + }, + "body": [ + { + "type": "ClassPrivateMethod", + "start": 16, + "end": 52, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 4, + "column": 3 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 21, + "end": 25, + "loc": { + "start": { + "line": 2, + "column": 7 + }, + "end": { + "line": 2, + "column": 11 + }, + "identifierName": "evil" + }, + "name": "evil" + }, + "kind": "get", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 28, + "end": 52, + "loc": { + "start": { + "line": 2, + "column": 14 + }, + "end": { + "line": 4, + "column": 3 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 34, + "end": 48, + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 18 + } + }, + "argument": { + "type": "CallExpression", + "start": 41, + "end": 47, + "loc": { + "start": { + "line": 3, + "column": 11 + }, + "end": { + "line": 3, + "column": 17 + } + }, + "callee": { + "type": "Identifier", + "start": 41, + "end": 45, + "loc": { + "start": { + "line": 3, + "column": 11 + }, + "end": { + "line": 3, + "column": 15 + }, + "identifierName": "ohNo" + }, + "name": "ohNo" + }, + "arguments": [] + } + } + ], + "directives": [] + } + }, + { + "type": "ClassPrivateMethod", + "start": 55, + "end": 97, + "loc": { + "start": { + "line": 5, + "column": 2 + }, + "end": { + "line": 7, + "column": 3 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 60, + "end": 64, + "loc": { + "start": { + "line": 5, + "column": 7 + }, + "end": { + "line": 5, + "column": 11 + }, + "identifierName": "evil" + }, + "name": "evil" + }, + "kind": "set", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 65, + "end": 66, + "loc": { + "start": { + "line": 5, + "column": 12 + }, + "end": { + "line": 5, + "column": 13 + }, + "identifierName": "x" + }, + "name": "x" + } + ], + "body": { + "type": "BlockStatement", + "start": 68, + "end": 97, + "loc": { + "start": { + "line": 5, + "column": 15 + }, + "end": { + "line": 7, + "column": 3 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 74, + "end": 93, + "loc": { + "start": { + "line": 6, + "column": 4 + }, + "end": { + "line": 6, + "column": 23 + } + }, + "argument": { + "type": "CallExpression", + "start": 81, + "end": 92, + "loc": { + "start": { + "line": 6, + "column": 11 + }, + "end": { + "line": 6, + "column": 22 + } + }, + "callee": { + "type": "Identifier", + "start": 81, + "end": 89, + "loc": { + "start": { + "line": 6, + "column": 11 + }, + "end": { + "line": 6, + "column": 19 + }, + "identifierName": "makeEvil" + }, + "name": "makeEvil" + }, + "arguments": [ + { + "type": "Identifier", + "start": 90, + "end": 91, + "loc": { + "start": { + "line": 6, + "column": 20 + }, + "end": { + "line": 6, + "column": 21 + }, + "identifierName": "x" + }, + "name": "x" + } + ] + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/experimental/class-private-methods/get-set/options.json b/test/fixtures/experimental/class-private-methods/get-set/options.json new file mode 100644 index 0000000000..aedb66f739 --- /dev/null +++ b/test/fixtures/experimental/class-private-methods/get-set/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["classProperties", "classPrivateMethods"] +} diff --git a/test/fixtures/experimental/class-private-methods/method/actual.js b/test/fixtures/experimental/class-private-methods/method/actual.js new file mode 100644 index 0000000000..cd42046085 --- /dev/null +++ b/test/fixtures/experimental/class-private-methods/method/actual.js @@ -0,0 +1,5 @@ +class Hotel { + #getBanned() { + return violentPeople(); + } +} diff --git a/test/fixtures/experimental/class-private-methods/method/expected.json b/test/fixtures/experimental/class-private-methods/method/expected.json new file mode 100644 index 0000000000..d08ac3d90b --- /dev/null +++ b/test/fixtures/experimental/class-private-methods/method/expected.json @@ -0,0 +1,190 @@ +{ + "type": "File", + "start": 0, + "end": 64, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 64, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 64, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 11 + }, + "identifierName": "Hotel" + }, + "name": "Hotel" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 12, + "end": 64, + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "body": [ + { + "type": "ClassPrivateMethod", + "start": 16, + "end": 62, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 4, + "column": 3 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 17, + "end": 26, + "loc": { + "start": { + "line": 2, + "column": 3 + }, + "end": { + "line": 2, + "column": 12 + }, + "identifierName": "getBanned" + }, + "name": "getBanned" + }, + "kind": "method", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 29, + "end": 62, + "loc": { + "start": { + "line": 2, + "column": 15 + }, + "end": { + "line": 4, + "column": 3 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 35, + "end": 58, + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 27 + } + }, + "argument": { + "type": "CallExpression", + "start": 42, + "end": 57, + "loc": { + "start": { + "line": 3, + "column": 11 + }, + "end": { + "line": 3, + "column": 26 + } + }, + "callee": { + "type": "Identifier", + "start": 42, + "end": 55, + "loc": { + "start": { + "line": 3, + "column": 11 + }, + "end": { + "line": 3, + "column": 24 + }, + "identifierName": "violentPeople" + }, + "name": "violentPeople" + }, + "arguments": [] + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/experimental/class-private-methods/method/options.json b/test/fixtures/experimental/class-private-methods/method/options.json new file mode 100644 index 0000000000..aedb66f739 --- /dev/null +++ b/test/fixtures/experimental/class-private-methods/method/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["classProperties", "classPrivateMethods"] +} diff --git a/test/fixtures/experimental/class-private-properties/failure-method/options.json b/test/fixtures/experimental/class-private-properties/failure-method/options.json deleted file mode 100644 index 6110b91af1..0000000000 --- a/test/fixtures/experimental/class-private-properties/failure-method/options.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "throws": "Unexpected token, expected ; (3:5)", - "plugins": ["classProperties", "classPrivateProperties"] -}