Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow compiling
#foo in obj
without compiling private fields
- Loading branch information
1 parent
838211b
commit 4901045
Showing
35 changed files
with
490 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
112 changes: 112 additions & 0 deletions
112
packages/babel-plugin-proposal-private-property-in-object/src/native-private-fields.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import syntaxPlugin from "@babel/plugin-syntax-private-property-in-object"; | ||
import { injectInitialization as injectConstructorInit } from "@babel/helper-create-class-features-plugin"; | ||
|
||
export default function pluginPrivateIn({ types: t, template }) { | ||
const ids = new WeakMap(); | ||
|
||
function unshadow(name, targetScope, scope) { | ||
while (scope !== targetScope) { | ||
if (scope.hasOwnBinding(name)) scope.rename(name); | ||
scope = scope.parent; | ||
} | ||
} | ||
|
||
function injectInitialization(classPath, init) { | ||
let firstFieldPath; | ||
let consturctorPath; | ||
|
||
for (const el of classPath.get("body.body")) { | ||
if ( | ||
(el.isClassProperty() || el.isClassPrivateProperty()) && | ||
!el.node.static | ||
) { | ||
firstFieldPath = el; | ||
break; | ||
} | ||
if (!consturctorPath && el.isClassMethod({ kind: "constructor" })) { | ||
consturctorPath = el; | ||
} | ||
} | ||
|
||
if (firstFieldPath) { | ||
if (firstFieldPath.node.value) { | ||
firstFieldPath.set( | ||
"value", | ||
t.sequenceExpression([init, firstFieldPath.node.value]), | ||
); | ||
} else { | ||
firstFieldPath.set("value", t.unaryExpression("void", init)); | ||
} | ||
} else { | ||
injectConstructorInit(classPath, consturctorPath, [ | ||
t.expressionStatement(init), | ||
]); | ||
} | ||
} | ||
|
||
return { | ||
name: "proposal-private-property-in-object", | ||
inherits: syntaxPlugin, | ||
visitor: { | ||
BinaryExpression(path) { | ||
const { node } = path; | ||
if (node.operator !== "in") return; | ||
if (!t.isPrivateName(node.left)) return; | ||
|
||
const { name } = node.left.id; | ||
|
||
let isStatic; | ||
const outerClass = path.findParent(path => { | ||
if (!path.isClass()) return false; | ||
|
||
const privateElement = path.node.body.body.find( | ||
node => t.isPrivate(node) && node.key.id.name === name, | ||
); | ||
if (!privateElement) return false; | ||
|
||
isStatic = privateElement.static; | ||
return true; | ||
}); | ||
|
||
if (outerClass.parentPath.scope.path.isPattern()) { | ||
outerClass.replaceWith(template.ast`(() => ${outerClass.node})()`); | ||
// The injected class will be queued and eventually transformed when visited | ||
return; | ||
} | ||
|
||
if (isStatic) { | ||
if (outerClass.node.id) { | ||
unshadow(outerClass.node.id.name, outerClass.scope, path.scope); | ||
} else { | ||
outerClass.set("id", path.scope.generateUidIdentifier("class")); | ||
} | ||
path.replaceWith( | ||
template.expression.ast` | ||
${t.cloneNode(outerClass.node.id)} === ${path.node.right} | ||
`, | ||
); | ||
return; | ||
} | ||
|
||
let id = ids.get(outerClass.node); | ||
if (!id) { | ||
id = outerClass.scope.generateUidIdentifier( | ||
`${outerClass.node.id?.name || ""} brandCheck`, | ||
); | ||
ids.set(outerClass.node, id); | ||
|
||
injectInitialization( | ||
outerClass, | ||
template.expression.ast`${t.cloneNode(id)}.add(this)`, | ||
); | ||
|
||
outerClass.insertBefore(template.ast`var ${id} = new WeakSet()`); | ||
} | ||
|
||
path.replaceWith( | ||
template.expression.ast`${t.cloneNode(id)}.has(${path.node.right})`, | ||
); | ||
}, | ||
}, | ||
}; | ||
} |
7 changes: 7 additions & 0 deletions
7
...ugin-proposal-private-property-in-object/test/fixtures/to-native-fields/accessor/input.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
class Foo { | ||
get #foo() {} | ||
|
||
test(other) { | ||
return #foo in other; | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
...gin-proposal-private-property-in-object/test/fixtures/to-native-fields/accessor/output.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
var _FooBrandCheck = new WeakSet(); | ||
|
||
class Foo { | ||
constructor() { | ||
_FooBrandCheck.add(this); | ||
} | ||
|
||
get #foo() {} | ||
|
||
test(other) { | ||
return _FooBrandCheck.has(other); | ||
} | ||
|
||
} |
4 changes: 4 additions & 0 deletions
4
...perty-in-object/test/fixtures/to-native-fields/class-expression-in-default-param/input.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
(x = class { | ||
#foo; | ||
test(other) { return #foo in other } | ||
}) => {} |
12 changes: 12 additions & 0 deletions
12
...erty-in-object/test/fixtures/to-native-fields/class-expression-in-default-param/output.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
(x = (() => { | ||
var _brandCheck; | ||
|
||
return _brandCheck = new WeakSet(), class { | ||
#foo = void _brandCheck.add(this); | ||
|
||
test(other) { | ||
return _brandCheck.has(other); | ||
} | ||
|
||
}; | ||
})()) => {}; |
9 changes: 9 additions & 0 deletions
9
...vate-property-in-object/test/fixtures/to-native-fields/class-expression-instance/input.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
function fn() { | ||
return new class { | ||
#priv; | ||
|
||
method(obj) { | ||
return #priv in obj; | ||
} | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
...ate-property-in-object/test/fixtures/to-native-fields/class-expression-instance/output.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
function fn() { | ||
var _brandCheck; | ||
|
||
return new (_brandCheck = new WeakSet(), class { | ||
#priv = void _brandCheck.add(this); | ||
|
||
method(obj) { | ||
return _brandCheck.has(obj); | ||
} | ||
|
||
})(); | ||
} |
9 changes: 9 additions & 0 deletions
9
...rivate-property-in-object/test/fixtures/to-native-fields/class-expression-static/input.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
function fn() { | ||
return new class { | ||
static #priv; | ||
|
||
method(obj) { | ||
return #priv in obj; | ||
} | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
...ivate-property-in-object/test/fixtures/to-native-fields/class-expression-static/output.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
function fn() { | ||
return new class _class { | ||
static #priv; | ||
|
||
method(obj) { | ||
return _class === obj; | ||
} | ||
|
||
}(); | ||
} |
7 changes: 7 additions & 0 deletions
7
...-plugin-proposal-private-property-in-object/test/fixtures/to-native-fields/field/input.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
class Foo { | ||
#foo = 1; | ||
|
||
test(other) { | ||
return #foo in other; | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
...plugin-proposal-private-property-in-object/test/fixtures/to-native-fields/field/output.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
var _FooBrandCheck = new WeakSet(); | ||
|
||
class Foo { | ||
#foo = (_FooBrandCheck.add(this), 1); | ||
|
||
test(other) { | ||
return _FooBrandCheck.has(other); | ||
} | ||
|
||
} |
7 changes: 7 additions & 0 deletions
7
...plugin-proposal-private-property-in-object/test/fixtures/to-native-fields/method/input.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
class Foo { | ||
#foo() {} | ||
|
||
test(other) { | ||
return #foo in other; | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
...lugin-proposal-private-property-in-object/test/fixtures/to-native-fields/method/output.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
var _FooBrandCheck = new WeakSet(); | ||
|
||
class Foo { | ||
constructor() { | ||
_FooBrandCheck.add(this); | ||
} | ||
|
||
#foo() {} | ||
|
||
test(other) { | ||
return _FooBrandCheck.has(other); | ||
} | ||
|
||
} |
18 changes: 18 additions & 0 deletions
18
...-property-in-object/test/fixtures/to-native-fields/nested-class-other-redeclared/input.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
class Foo { | ||
#foo = 1; | ||
#bar = 1; | ||
|
||
test() { | ||
class Nested { | ||
#bar = 2; | ||
|
||
test() { | ||
#foo in this; | ||
#bar in this; | ||
} | ||
} | ||
|
||
#foo in this; | ||
#bar in this; | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
...property-in-object/test/fixtures/to-native-fields/nested-class-other-redeclared/output.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
var _FooBrandCheck = new WeakSet(); | ||
|
||
class Foo { | ||
#foo = (_FooBrandCheck.add(this), 1); | ||
#bar = 1; | ||
|
||
test() { | ||
var _NestedBrandCheck = new WeakSet(); | ||
|
||
class Nested { | ||
#bar = (_NestedBrandCheck.add(this), 2); | ||
|
||
test() { | ||
_FooBrandCheck.has(this); | ||
|
||
_NestedBrandCheck.has(this); | ||
} | ||
|
||
} | ||
|
||
_FooBrandCheck.has(this); | ||
|
||
_FooBrandCheck.has(this); | ||
} | ||
|
||
} |
15 changes: 15 additions & 0 deletions
15
...rivate-property-in-object/test/fixtures/to-native-fields/nested-class-redeclared/input.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
class Foo { | ||
#foo = 1; | ||
|
||
test() { | ||
class Nested { | ||
#foo = 2; | ||
|
||
test() { | ||
#foo in this; | ||
} | ||
} | ||
|
||
#foo in this; | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
...ivate-property-in-object/test/fixtures/to-native-fields/nested-class-redeclared/output.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
var _FooBrandCheck = new WeakSet(); | ||
|
||
class Foo { | ||
#foo = (_FooBrandCheck.add(this), 1); | ||
|
||
test() { | ||
var _NestedBrandCheck = new WeakSet(); | ||
|
||
class Nested { | ||
#foo = (_NestedBrandCheck.add(this), 2); | ||
|
||
test() { | ||
_NestedBrandCheck.has(this); | ||
} | ||
|
||
} | ||
|
||
_FooBrandCheck.has(this); | ||
} | ||
|
||
} |
13 changes: 13 additions & 0 deletions
13
...-proposal-private-property-in-object/test/fixtures/to-native-fields/nested-class/input.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
class Foo { | ||
#foo = 1; | ||
|
||
test() { | ||
class Nested { | ||
test() { | ||
#foo in this; | ||
} | ||
} | ||
|
||
#foo in this; | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
...proposal-private-property-in-object/test/fixtures/to-native-fields/nested-class/output.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
var _FooBrandCheck = new WeakSet(); | ||
|
||
class Foo { | ||
#foo = (_FooBrandCheck.add(this), 1); | ||
|
||
test() { | ||
class Nested { | ||
test() { | ||
_FooBrandCheck.has(this); | ||
} | ||
|
||
} | ||
|
||
_FooBrandCheck.has(this); | ||
} | ||
|
||
} |
6 changes: 6 additions & 0 deletions
6
...el-plugin-proposal-private-property-in-object/test/fixtures/to-native-fields/options.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"plugins": [ | ||
["proposal-private-property-in-object", { "nativePrivateFields": true }], | ||
"syntax-class-properties" | ||
] | ||
} |
Oops, something went wrong.