123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- 'use strict';
- Object.defineProperty(exports, '__esModule', { value: true });
- var core = require('@babel/core');
- var helperPluginUtils = require('@babel/helper-plugin-utils');
- function isNameOrLength(key) {
- if (core.types.isIdentifier(key)) {
- return key.name === "name" || key.name === "length";
- }
- if (core.types.isStringLiteral(key)) {
- return key.value === "name" || key.value === "length";
- }
- return false;
- }
- function isStaticFieldWithValue(node) {
- return (core.types.isClassProperty(node) || core.types.isClassPrivateProperty(node)) && node.static && !!node.value;
- }
- const hasReferenceVisitor = {
- ReferencedIdentifier(path, state) {
- if (path.node.name === state.name) {
- state.ref();
- path.stop();
- }
- },
- Scope(path, {
- name
- }) {
- if (path.scope.hasOwnBinding(name)) {
- path.skip();
- }
- }
- };
- function isReferenceOrThis(node, name) {
- return core.types.isThisExpression(node) || name && core.types.isIdentifier(node, {
- name
- });
- }
- const hasReferenceOrThisVisitor = {
- "ThisExpression|ReferencedIdentifier"(path, state) {
- if (isReferenceOrThis(path.node, state.name)) {
- state.ref();
- path.stop();
- }
- },
- FunctionParent(path, state) {
- if (path.isArrowFunctionExpression()) return;
- if (state.name && !path.scope.hasOwnBinding(state.name)) {
- path.traverse(hasReferenceVisitor, state);
- }
- path.skip();
- if (path.isMethod()) {
- if (path.requeueComputedKeyAndDecorators) {
- path.requeueComputedKeyAndDecorators();
- } else {
- require("@babel/traverse").NodePath.prototype.requeueComputedKeyAndDecorators.call(path);
- }
- }
- }
- };
- function getPotentiallyBuggyFieldsIndexes(path) {
- var _path$node$id;
- const buggyPublicStaticFieldsIndexes = [];
- let classReferenced = false;
- const className = (_path$node$id = path.node.id) == null ? void 0 : _path$node$id.name;
- const hasReferenceState = {
- name: className,
- ref: () => classReferenced = true
- };
- if (className) {
- for (const el of path.get("body.body")) {
- if (el.node.computed) {
- el.get("key").traverse(hasReferenceVisitor, hasReferenceState);
- if (classReferenced) break;
- }
- }
- }
- let nextPotentiallyBuggy = false;
- const {
- body
- } = path.node.body;
- for (let i = 0; i < body.length; i++) {
- const node = body[i];
- if (!nextPotentiallyBuggy) {
- if (core.types.isStaticBlock(node)) {
- classReferenced = true;
- nextPotentiallyBuggy = true;
- } else if (isStaticFieldWithValue(node)) {
- if (!classReferenced) {
- if (isReferenceOrThis(node.value, className)) {
- classReferenced = true;
- } else {
- path.get(`body.body.${i}.value`).traverse(hasReferenceOrThisVisitor, hasReferenceState);
- }
- }
- if (classReferenced) {
- nextPotentiallyBuggy = !path.scope.isPure(node.value);
- }
- }
- }
- if (core.types.isClassProperty(node, {
- static: true
- }) && (nextPotentiallyBuggy || node.computed || isNameOrLength(node.key))) {
- buggyPublicStaticFieldsIndexes.push(i);
- }
- }
- return buggyPublicStaticFieldsIndexes;
- }
- function getNameOrLengthStaticFieldsIndexes(path) {
- const indexes = [];
- const {
- body
- } = path.node.body;
- for (let i = 0; i < body.length; i++) {
- const node = body[i];
- if (core.types.isClassProperty(node, {
- static: true,
- computed: false
- }) && isNameOrLength(node.key)) {
- indexes.push(i);
- }
- }
- return indexes;
- }
- function toRanges(nums) {
- const ranges = [];
- if (nums.length === 0) return ranges;
- let start = nums[0];
- let end = start + 1;
- for (let i = 1; i < nums.length; i++) {
- if (nums[i] <= nums[i - 1]) {
- throw new Error("Internal Babel error: nums must be in ascending order");
- }
- if (nums[i] === end) {
- end++;
- } else {
- ranges.push([start, end]);
- start = nums[i];
- end = start + 1;
- }
- }
- ranges.push([start, end]);
- return ranges;
- }
- function buildFieldsReplacement(fields, scope, file) {
- return core.types.staticBlock(fields.map(field => {
- const key = field.computed || !core.types.isIdentifier(field.key) ? field.key : core.types.stringLiteral(field.key.name);
- return core.types.expressionStatement(core.types.callExpression(file.addHelper("defineProperty"), [core.types.thisExpression(), key, field.value || scope.buildUndefinedNode()]));
- }));
- }
- var index = helperPluginUtils.declare(api => {
- api.assertVersion("^7.0.0-0 || >8.0.0-alpha <8.0.0-beta");
- const setPublicClassFields = api.assumption("setPublicClassFields");
- return {
- name: "bugfix-v8-static-class-fields-redefine-readonly",
- visitor: {
- Class(path) {
- const ranges = toRanges(setPublicClassFields ? getNameOrLengthStaticFieldsIndexes(path) : getPotentiallyBuggyFieldsIndexes(path));
- for (let i = ranges.length - 1; i >= 0; i--) {
- const [start, end] = ranges[i];
- const startPath = path.get("body.body")[start];
- startPath.replaceWith(buildFieldsReplacement(path.node.body.body.slice(start, end), path.scope, this.file));
- for (let j = end - 1; j > start; j--) {
- path.get("body.body")[j].remove();
- }
- }
- }
- }
- };
- });
- exports.default = index;
- //# sourceMappingURL=index.js.map
|