diff --git a/packages/babel-parser/src/parser/statement.js b/packages/babel-parser/src/parser/statement.js index d07690d075c4..23036e0a3ca1 100644 --- a/packages/babel-parser/src/parser/statement.js +++ b/packages/babel-parser/src/parser/statement.js @@ -1714,6 +1714,13 @@ export default class StatementParser extends ExpressionParser { ? CLASS_ELEMENT_STATIC_SETTER : CLASS_ELEMENT_INSTANCE_SETTER : CLASS_ELEMENT_OTHER; + this.declareClassPrivateMethodInScope(node, kind); + } + + declareClassPrivateMethodInScope( + node: N.ClassPrivateMethod | N.EstreeMethodDefinition | N.TSDeclareMethod, + kind: number, + ) { this.classScope.declarePrivateName( this.getPrivateNameSV(node.key), kind, diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index 6d90951f0672..7824e5b37052 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -2015,7 +2015,7 @@ export default (superClass: Class): Class => const bodilessType = type === "FunctionDeclaration" ? "TSDeclareFunction" - : type === "ClassMethod" + : type === "ClassMethod" || type === "ClassPrivateMethod" ? "TSDeclareMethod" : undefined; if (bodilessType && !this.match(tt.braceL) && this.isLineTerminator()) { @@ -2755,6 +2755,17 @@ export default (superClass: Class): Class => super.pushClassPrivateMethod(classBody, method, isGenerator, isAsync); } + declareClassPrivateMethodInScope( + node: N.ClassPrivateMethod | N.EstreeMethodDefinition | N.TSDeclareMethod, + kind: number, + ) { + if (node.type === "TSDeclareMethod") return; + // This happens when using the "estree" plugin. + if (node.type === "MethodDefinition" && !node.value.body) return; + + super.declareClassPrivateMethodInScope(node, kind); + } + parseClassSuper(node: N.Class): void { super.parseClassSuper(node); if (node.superClass && this.isRelational("<")) { diff --git a/packages/babel-parser/test/fixtures/typescript/class/private-method-overload/input.ts b/packages/babel-parser/test/fixtures/typescript/class/private-method-overload/input.ts new file mode 100644 index 000000000000..95b006c86e70 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/class/private-method-overload/input.ts @@ -0,0 +1,7 @@ +class Test { + #f(x: string): number; + #f(x: number): string; + #f(x: string | number): string | number { + return (typeof x === 'string') ? parseInt(x) : x.toString(); + } +} diff --git a/packages/babel-parser/test/fixtures/typescript/class/private-method-overload/output.json b/packages/babel-parser/test/fixtures/typescript/class/private-method-overload/output.json new file mode 100644 index 000000000000..a19d46fe6d78 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/class/private-method-overload/output.json @@ -0,0 +1,252 @@ +{ + "type": "File", + "start":0,"end":177,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"column":1}}, + "program": { + "type": "Program", + "start":0,"end":177,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"column":1}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ClassDeclaration", + "start":0,"end":177,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"column":1}}, + "id": { + "type": "Identifier", + "start":6,"end":10,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":10},"identifierName":"Test"}, + "name": "Test" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start":11,"end":177,"loc":{"start":{"line":1,"column":11},"end":{"line":7,"column":1}}, + "body": [ + { + "type": "TSDeclareMethod", + "start":15,"end":37,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":24}}, + "static": false, + "key": { + "type": "PrivateName", + "start":15,"end":17,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":4}}, + "id": { + "type": "Identifier", + "start":16,"end":17,"loc":{"start":{"line":2,"column":3},"end":{"line":2,"column":4},"identifierName":"f"}, + "name": "f" + } + }, + "kind": "method", + "id": null, + "generator": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start":18,"end":27,"loc":{"start":{"line":2,"column":5},"end":{"line":2,"column":14},"identifierName":"x"}, + "name": "x", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":19,"end":27,"loc":{"start":{"line":2,"column":6},"end":{"line":2,"column":14}}, + "typeAnnotation": { + "type": "TSStringKeyword", + "start":21,"end":27,"loc":{"start":{"line":2,"column":8},"end":{"line":2,"column":14}} + } + } + } + ], + "returnType": { + "type": "TSTypeAnnotation", + "start":28,"end":36,"loc":{"start":{"line":2,"column":15},"end":{"line":2,"column":23}}, + "typeAnnotation": { + "type": "TSNumberKeyword", + "start":30,"end":36,"loc":{"start":{"line":2,"column":17},"end":{"line":2,"column":23}} + } + } + }, + { + "type": "TSDeclareMethod", + "start":40,"end":62,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":24}}, + "static": false, + "key": { + "type": "PrivateName", + "start":40,"end":42,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":4}}, + "id": { + "type": "Identifier", + "start":41,"end":42,"loc":{"start":{"line":3,"column":3},"end":{"line":3,"column":4},"identifierName":"f"}, + "name": "f" + } + }, + "kind": "method", + "id": null, + "generator": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start":43,"end":52,"loc":{"start":{"line":3,"column":5},"end":{"line":3,"column":14},"identifierName":"x"}, + "name": "x", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":44,"end":52,"loc":{"start":{"line":3,"column":6},"end":{"line":3,"column":14}}, + "typeAnnotation": { + "type": "TSNumberKeyword", + "start":46,"end":52,"loc":{"start":{"line":3,"column":8},"end":{"line":3,"column":14}} + } + } + } + ], + "returnType": { + "type": "TSTypeAnnotation", + "start":53,"end":61,"loc":{"start":{"line":3,"column":15},"end":{"line":3,"column":23}}, + "typeAnnotation": { + "type": "TSStringKeyword", + "start":55,"end":61,"loc":{"start":{"line":3,"column":17},"end":{"line":3,"column":23}} + } + } + }, + { + "type": "ClassPrivateMethod", + "start":65,"end":175,"loc":{"start":{"line":4,"column":2},"end":{"line":6,"column":3}}, + "static": false, + "key": { + "type": "PrivateName", + "start":65,"end":67,"loc":{"start":{"line":4,"column":2},"end":{"line":4,"column":4}}, + "id": { + "type": "Identifier", + "start":66,"end":67,"loc":{"start":{"line":4,"column":3},"end":{"line":4,"column":4},"identifierName":"f"}, + "name": "f" + } + }, + "kind": "method", + "id": null, + "generator": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start":68,"end":86,"loc":{"start":{"line":4,"column":5},"end":{"line":4,"column":23},"identifierName":"x"}, + "name": "x", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":69,"end":86,"loc":{"start":{"line":4,"column":6},"end":{"line":4,"column":23}}, + "typeAnnotation": { + "type": "TSUnionType", + "start":71,"end":86,"loc":{"start":{"line":4,"column":8},"end":{"line":4,"column":23}}, + "types": [ + { + "type": "TSStringKeyword", + "start":71,"end":77,"loc":{"start":{"line":4,"column":8},"end":{"line":4,"column":14}} + }, + { + "type": "TSNumberKeyword", + "start":80,"end":86,"loc":{"start":{"line":4,"column":17},"end":{"line":4,"column":23}} + } + ] + } + } + } + ], + "returnType": { + "type": "TSTypeAnnotation", + "start":87,"end":104,"loc":{"start":{"line":4,"column":24},"end":{"line":4,"column":41}}, + "typeAnnotation": { + "type": "TSUnionType", + "start":89,"end":104,"loc":{"start":{"line":4,"column":26},"end":{"line":4,"column":41}}, + "types": [ + { + "type": "TSStringKeyword", + "start":89,"end":95,"loc":{"start":{"line":4,"column":26},"end":{"line":4,"column":32}} + }, + { + "type": "TSNumberKeyword", + "start":98,"end":104,"loc":{"start":{"line":4,"column":35},"end":{"line":4,"column":41}} + } + ] + } + }, + "body": { + "type": "BlockStatement", + "start":105,"end":175,"loc":{"start":{"line":4,"column":42},"end":{"line":6,"column":3}}, + "body": [ + { + "type": "ReturnStatement", + "start":111,"end":171,"loc":{"start":{"line":5,"column":4},"end":{"line":5,"column":64}}, + "argument": { + "type": "ConditionalExpression", + "start":118,"end":170,"loc":{"start":{"line":5,"column":11},"end":{"line":5,"column":63}}, + "test": { + "type": "BinaryExpression", + "start":119,"end":140,"loc":{"start":{"line":5,"column":12},"end":{"line":5,"column":33}}, + "left": { + "type": "UnaryExpression", + "start":119,"end":127,"loc":{"start":{"line":5,"column":12},"end":{"line":5,"column":20}}, + "operator": "typeof", + "prefix": true, + "argument": { + "type": "Identifier", + "start":126,"end":127,"loc":{"start":{"line":5,"column":19},"end":{"line":5,"column":20},"identifierName":"x"}, + "name": "x" + } + }, + "operator": "===", + "right": { + "type": "StringLiteral", + "start":132,"end":140,"loc":{"start":{"line":5,"column":25},"end":{"line":5,"column":33}}, + "extra": { + "rawValue": "string", + "raw": "'string'" + }, + "value": "string" + }, + "extra": { + "parenthesized": true, + "parenStart": 118 + } + }, + "consequent": { + "type": "CallExpression", + "start":144,"end":155,"loc":{"start":{"line":5,"column":37},"end":{"line":5,"column":48}}, + "callee": { + "type": "Identifier", + "start":144,"end":152,"loc":{"start":{"line":5,"column":37},"end":{"line":5,"column":45},"identifierName":"parseInt"}, + "name": "parseInt" + }, + "arguments": [ + { + "type": "Identifier", + "start":153,"end":154,"loc":{"start":{"line":5,"column":46},"end":{"line":5,"column":47},"identifierName":"x"}, + "name": "x" + } + ] + }, + "alternate": { + "type": "CallExpression", + "start":158,"end":170,"loc":{"start":{"line":5,"column":51},"end":{"line":5,"column":63}}, + "callee": { + "type": "MemberExpression", + "start":158,"end":168,"loc":{"start":{"line":5,"column":51},"end":{"line":5,"column":61}}, + "object": { + "type": "Identifier", + "start":158,"end":159,"loc":{"start":{"line":5,"column":51},"end":{"line":5,"column":52},"identifierName":"x"}, + "name": "x" + }, + "computed": false, + "property": { + "type": "Identifier", + "start":160,"end":168,"loc":{"start":{"line":5,"column":53},"end":{"line":5,"column":61},"identifierName":"toString"}, + "name": "toString" + } + }, + "arguments": [] + } + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/class/private-method-override-transform-private/input.ts b/packages/babel-plugin-transform-typescript/test/fixtures/class/private-method-override-transform-private/input.ts new file mode 100644 index 000000000000..95b006c86e70 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/class/private-method-override-transform-private/input.ts @@ -0,0 +1,7 @@ +class Test { + #f(x: string): number; + #f(x: number): string; + #f(x: string | number): string | number { + return (typeof x === 'string') ? parseInt(x) : x.toString(); + } +} diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/class/private-method-override-transform-private/options.json b/packages/babel-plugin-transform-typescript/test/fixtures/class/private-method-override-transform-private/options.json new file mode 100644 index 000000000000..f61cb6622ec3 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/class/private-method-override-transform-private/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["transform-typescript", "proposal-private-methods"] +} diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/class/private-method-override-transform-private/output.js b/packages/babel-plugin-transform-typescript/test/fixtures/class/private-method-override-transform-private/output.js new file mode 100644 index 000000000000..26c37f767bd9 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/class/private-method-override-transform-private/output.js @@ -0,0 +1,12 @@ +var _f = /*#__PURE__*/new WeakSet(); + +class Test { + constructor() { + babelHelpers.classPrivateMethodInitSpec(this, _f); + } + +} + +function _f2(x) { + return typeof x === 'string' ? parseInt(x) : x.toString(); +} diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/class/private-method-override/input.ts b/packages/babel-plugin-transform-typescript/test/fixtures/class/private-method-override/input.ts new file mode 100644 index 000000000000..95b006c86e70 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/class/private-method-override/input.ts @@ -0,0 +1,7 @@ +class Test { + #f(x: string): number; + #f(x: number): string; + #f(x: string | number): string | number { + return (typeof x === 'string') ? parseInt(x) : x.toString(); + } +} diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/class/private-method-override/options.json b/packages/babel-plugin-transform-typescript/test/fixtures/class/private-method-override/options.json new file mode 100644 index 000000000000..5c79172a6082 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/class/private-method-override/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["transform-typescript"] +} diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/class/private-method-override/output.js b/packages/babel-plugin-transform-typescript/test/fixtures/class/private-method-override/output.js new file mode 100644 index 000000000000..bd17692d9fab --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/class/private-method-override/output.js @@ -0,0 +1,6 @@ +class Test { + #f(x) { + return typeof x === 'string' ? parseInt(x) : x.toString(); + } + +}