154 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			154 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| "use strict";
 | |
| 
 | |
| Object.defineProperty(exports, "__esModule", {
 | |
|   value: true
 | |
| });
 | |
| exports.default = void 0;
 | |
| var _helperPluginUtils = require("@babel/helper-plugin-utils");
 | |
| var _helperCreateClassFeaturesPlugin = require("@babel/helper-create-class-features-plugin");
 | |
| function generateUid(scope, denyList) {
 | |
|   const name = "";
 | |
|   let uid;
 | |
|   let i = 1;
 | |
|   do {
 | |
|     uid = `_${name}`;
 | |
|     if (i > 1) uid += i;
 | |
|     i++;
 | |
|   } while (denyList.has(uid));
 | |
|   return uid;
 | |
| }
 | |
| function mapLast(arr, fn) {
 | |
|   if (arr.length === 0) return arr;
 | |
|   return [...arr.slice(0, -1), fn(arr[arr.length - 1])];
 | |
| }
 | |
| var _default = exports.default = (0, _helperPluginUtils.declare)(({
 | |
|   types: t,
 | |
|   template,
 | |
|   traverse,
 | |
|   assertVersion
 | |
| }) => {
 | |
|   assertVersion("^7.12.0 || >8.0.0-alpha <8.0.0-beta");
 | |
|   const rawNamedEvaluationVisitor = (0, _helperCreateClassFeaturesPlugin.buildNamedEvaluationVisitor)(path => {
 | |
|     if (!path.isClassExpression()) return false;
 | |
|     for (let i = path.node.body.body.length - 1; i >= 0; i--) {
 | |
|       const el = path.node.body.body[i];
 | |
|       if (t.isStaticBlock(el)) {
 | |
|         return true;
 | |
|       }
 | |
|       if ((t.isClassProperty(el) || t.isClassPrivateProperty(el)) && el.static) {
 | |
|         break;
 | |
|       }
 | |
|     }
 | |
|     return false;
 | |
|   }, (classPath, state, name) => {
 | |
|     const nameNode = typeof name === "string" ? t.stringLiteral(name) : name;
 | |
|     classPath.get("body").unshiftContainer("body", t.staticBlock([template.statement.ast`
 | |
|             ${state.addHelper("setFunctionName")}(this, ${nameNode});
 | |
|           `]));
 | |
|   });
 | |
|   if (!t.classAccessorProperty) {
 | |
|     delete rawNamedEvaluationVisitor.ClassAccessorProperty;
 | |
|   }
 | |
|   const namedEvaluationVisitor = traverse.visitors.explode(rawNamedEvaluationVisitor);
 | |
|   const maybeSequenceExpression = expressions => {
 | |
|     if (expressions.length === 1) {
 | |
|       return expressions[0];
 | |
|     } else {
 | |
|       return t.sequenceExpression(expressions);
 | |
|     }
 | |
|   };
 | |
|   const blocksToExpressions = blocks => blocks.map(block => {
 | |
|     const {
 | |
|       body
 | |
|     } = block;
 | |
|     if (body.length === 1 && t.isExpressionStatement(body[0])) {
 | |
|       return t.inheritsComments(t.inheritsComments(body[0].expression, body[0]), block);
 | |
|     }
 | |
|     return t.inheritsComments(template.expression.ast`(() => { ${body} })()`, block);
 | |
|   });
 | |
|   const prependToInitializer = (prop, expressions) => {
 | |
|     prop.value = prop.value ? t.sequenceExpression([...expressions, prop.value]) : maybeSequenceExpression(mapLast(expressions, expr => t.unaryExpression("void", expr)));
 | |
|   };
 | |
|   return {
 | |
|     name: "transform-class-static-block",
 | |
|     manipulateOptions: (_, parser) => parser.plugins.push("classStaticBlock"),
 | |
|     pre() {
 | |
|       (0, _helperCreateClassFeaturesPlugin.enableFeature)(this.file, _helperCreateClassFeaturesPlugin.FEATURES.staticBlocks, false);
 | |
|     },
 | |
|     visitor: {
 | |
|       ClassBody(classBody) {
 | |
|         const {
 | |
|           scope
 | |
|         } = classBody;
 | |
|         let parentPath = classBody.parentPath;
 | |
|         if (parentPath.isClassExpression() && !parentPath.node.id) {
 | |
|           do ({
 | |
|             parentPath
 | |
|           } = parentPath); while (parentPath && !namedEvaluationVisitor[parentPath.type] && !parentPath.isStatement());
 | |
|           if (parentPath) {
 | |
|             var _namedEvaluationVisit;
 | |
|             (_namedEvaluationVisit = namedEvaluationVisitor[parentPath.type]) == null || _namedEvaluationVisit.enter.forEach(f => f.call(this, parentPath, this));
 | |
|           }
 | |
|         }
 | |
|         const pendingStaticBlocks = [];
 | |
|         let lastStaticProp = null;
 | |
|         for (const path of classBody.get("body")) {
 | |
|           if (path.isStaticBlock()) {
 | |
|             pendingStaticBlocks.push(path.node);
 | |
|             path.remove();
 | |
|           } else if (path.isClassProperty({
 | |
|             static: true
 | |
|           }) || path.isClassPrivateProperty({
 | |
|             static: true
 | |
|           })) {
 | |
|             lastStaticProp = path;
 | |
|             if (pendingStaticBlocks.length > 0) {
 | |
|               prependToInitializer(path.node, blocksToExpressions(pendingStaticBlocks));
 | |
|               pendingStaticBlocks.length = 0;
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|         if (pendingStaticBlocks.length > 0) {
 | |
|           const tmp = scope.generateDeclaredUidIdentifier("staticBlock");
 | |
|           let arrowBody;
 | |
|           const needsCompletionValue = classBody.parentPath.isExpression();
 | |
|           if (pendingStaticBlocks.length > 1 || pendingStaticBlocks[0].body.length === 1 && t.isExpressionStatement(pendingStaticBlocks[0].body[0])) {
 | |
|             const expressions = blocksToExpressions(pendingStaticBlocks);
 | |
|             if (needsCompletionValue) {
 | |
|               expressions.push(t.thisExpression());
 | |
|             }
 | |
|             arrowBody = maybeSequenceExpression(expressions);
 | |
|           } else {
 | |
|             arrowBody = t.blockStatement(pendingStaticBlocks[0].body);
 | |
|             if (needsCompletionValue) {
 | |
|               arrowBody.body.push(t.returnStatement(t.thisExpression()));
 | |
|             }
 | |
|           }
 | |
|           const init = template.expression.ast`${tmp} = () => ${arrowBody}`;
 | |
|           if (lastStaticProp) {
 | |
|             prependToInitializer(lastStaticProp.node, [init]);
 | |
|           } else {
 | |
|             const privateNames = new Set();
 | |
|             for (const path of classBody.get("body")) {
 | |
|               if (path.isPrivate()) {
 | |
|                 privateNames.add(path.get("key.id").node.name);
 | |
|               }
 | |
|             }
 | |
|             const staticBlockPrivateId = generateUid(scope, privateNames);
 | |
|             const staticBlockRef = t.privateName(t.identifier(staticBlockPrivateId));
 | |
|             classBody.pushContainer("body", [t.classPrivateProperty(staticBlockRef, init, [], true)]);
 | |
|           }
 | |
|           const staticBlockClosureCall = t.callExpression(t.cloneNode(tmp), []);
 | |
|           if (classBody.parentPath.isClassExpression()) {
 | |
|             classBody.parentPath.replaceWith(t.sequenceExpression([classBody.parent, staticBlockClosureCall]));
 | |
|           } else {
 | |
|             classBody.parentPath.insertAfter(t.expressionStatement(staticBlockClosureCall));
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   };
 | |
| });
 | |
| 
 | |
| //# sourceMappingURL=index.js.map
 |