Skip to content

Commit

Permalink
[ts] Support private methods overloads (#13876)
Browse files Browse the repository at this point in the history
* [parser] Allow private methods overloads when parsing TS

* Add transform tests

* Fix estree

* Fix flow
  • Loading branch information
nicolo-ribaudo committed Oct 26, 2021
1 parent 290d52f commit fb7ddf4
Show file tree
Hide file tree
Showing 10 changed files with 316 additions and 1 deletion.
7 changes: 7 additions & 0 deletions packages/babel-parser/src/parser/statement.js
Expand Up @@ -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,
Expand Down
13 changes: 12 additions & 1 deletion packages/babel-parser/src/plugins/typescript/index.js
Expand Up @@ -2015,7 +2015,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
const bodilessType =
type === "FunctionDeclaration"
? "TSDeclareFunction"
: type === "ClassMethod"
: type === "ClassMethod" || type === "ClassPrivateMethod"
? "TSDeclareMethod"
: undefined;
if (bodilessType && !this.match(tt.braceL) && this.isLineTerminator()) {
Expand Down Expand Up @@ -2755,6 +2755,17 @@ export default (superClass: Class<Parser>): Class<Parser> =>
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("<")) {
Expand Down
@@ -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();
}
}
@@ -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": []
}
}
@@ -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();
}
}
@@ -0,0 +1,3 @@
{
"plugins": ["transform-typescript", "proposal-private-methods"]
}
@@ -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();
}
@@ -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();
}
}
@@ -0,0 +1,3 @@
{
"plugins": ["transform-typescript"]
}
@@ -0,0 +1,6 @@
class Test {
#f(x) {
return typeof x === 'string' ? parseInt(x) : x.toString();
}

}

0 comments on commit fb7ddf4

Please sign in to comment.