You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
4.4 KiB
147 lines
4.4 KiB
"use strict"; |
|
|
|
Object.defineProperty(exports, "__esModule", { |
|
value: true |
|
}); |
|
exports.default = void 0; |
|
|
|
var _helperPluginUtils = require("@babel/helper-plugin-utils"); |
|
|
|
var _pluginSyntaxPrivatePropertyInObject = require("@babel/plugin-syntax-private-property-in-object"); |
|
|
|
var _helperCreateClassFeaturesPlugin = require("@babel/helper-create-class-features-plugin"); |
|
|
|
var _helperAnnotateAsPure = require("@babel/helper-annotate-as-pure"); |
|
|
|
var _default = (0, _helperPluginUtils.declare)((api, opt) => { |
|
api.assertVersion(7); |
|
const { |
|
types: t, |
|
template |
|
} = api; |
|
const { |
|
loose |
|
} = opt; |
|
const classWeakSets = new WeakMap(); |
|
const fieldsWeakSets = new WeakMap(); |
|
|
|
function unshadow(name, targetScope, scope) { |
|
while (scope !== targetScope) { |
|
if (scope.hasOwnBinding(name)) scope.rename(name); |
|
scope = scope.parent; |
|
} |
|
} |
|
|
|
function injectToFieldInit(fieldPath, expr, before = false) { |
|
if (fieldPath.node.value) { |
|
const value = fieldPath.get("value"); |
|
|
|
if (before) { |
|
value.insertBefore(expr); |
|
} else { |
|
value.insertAfter(expr); |
|
} |
|
} else { |
|
fieldPath.set("value", t.unaryExpression("void", expr)); |
|
} |
|
} |
|
|
|
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) { |
|
injectToFieldInit(firstFieldPath, init, true); |
|
} else { |
|
(0, _helperCreateClassFeaturesPlugin.injectInitialization)(classPath, consturctorPath, [t.expressionStatement(init)]); |
|
} |
|
} |
|
|
|
function getWeakSetId(weakSets, outerClass, reference, name = "", inject) { |
|
let id = weakSets.get(reference.node); |
|
|
|
if (!id) { |
|
id = outerClass.scope.generateUidIdentifier(`${name || ""} brandCheck`); |
|
weakSets.set(reference.node, id); |
|
inject(reference, template.expression.ast`${t.cloneNode(id)}.add(this)`); |
|
const newExpr = t.newExpression(t.identifier("WeakSet"), []); |
|
(0, _helperAnnotateAsPure.default)(newExpr); |
|
outerClass.insertBefore(template.ast`var ${id} = ${newExpr}`); |
|
} |
|
|
|
return t.cloneNode(id); |
|
} |
|
|
|
return { |
|
name: "proposal-private-property-in-object", |
|
inherits: _pluginSyntaxPrivatePropertyInObject.default, |
|
|
|
pre() { |
|
(0, _helperCreateClassFeaturesPlugin.enableFeature)(this.file, _helperCreateClassFeaturesPlugin.FEATURES.privateIn, loose); |
|
}, |
|
|
|
visitor: { |
|
BinaryExpression(path) { |
|
const { |
|
node |
|
} = path; |
|
if (node.operator !== "in") return; |
|
if (!t.isPrivateName(node.left)) return; |
|
const { |
|
name |
|
} = node.left.id; |
|
let privateElement; |
|
const outerClass = path.findParent(path => { |
|
if (!path.isClass()) return false; |
|
privateElement = path.get("body.body").find(({ |
|
node |
|
}) => t.isPrivate(node) && node.key.id.name === name); |
|
return !!privateElement; |
|
}); |
|
|
|
if (outerClass.parentPath.scope.path.isPattern()) { |
|
outerClass.replaceWith(template.ast`(() => ${outerClass.node})()`); |
|
return; |
|
} |
|
|
|
if (privateElement.node.type === "ClassPrivateMethod") { |
|
if (privateElement.node.static) { |
|
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} |
|
`); |
|
} else { |
|
var _outerClass$node$id; |
|
|
|
const id = getWeakSetId(classWeakSets, outerClass, outerClass, (_outerClass$node$id = outerClass.node.id) == null ? void 0 : _outerClass$node$id.name, injectInitialization); |
|
path.replaceWith(template.expression.ast`${id}.has(${path.node.right})`); |
|
} |
|
} else { |
|
const id = getWeakSetId(fieldsWeakSets, outerClass, privateElement, privateElement.node.key.id.name, injectToFieldInit); |
|
path.replaceWith(template.expression.ast`${id}.has(${path.node.right})`); |
|
} |
|
} |
|
|
|
} |
|
}; |
|
}); |
|
|
|
exports.default = _default; |