UNPKG

10.5 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6Object.defineProperty(exports, "FEATURES", {
7 enumerable: true,
8 get: function () {
9 return _features.FEATURES;
10 }
11});
12Object.defineProperty(exports, "buildCheckInRHS", {
13 enumerable: true,
14 get: function () {
15 return _fields.buildCheckInRHS;
16 }
17});
18exports.createClassFeaturePlugin = createClassFeaturePlugin;
19Object.defineProperty(exports, "enableFeature", {
20 enumerable: true,
21 get: function () {
22 return _features.enableFeature;
23 }
24});
25Object.defineProperty(exports, "injectInitialization", {
26 enumerable: true,
27 get: function () {
28 return _misc.injectInitialization;
29 }
30});
31var _core = require("@babel/core");
32var _decorators = require("./decorators.js");
33var _semver = require("semver");
34var _fields = require("./fields.js");
35var _decorators2 = require("./decorators-2018-09.js");
36var _misc = require("./misc.js");
37var _features = require("./features.js");
38var _typescript = require("./typescript.js");
39const versionKey = "@babel/plugin-class-features/version";
40function createClassFeaturePlugin({
41 name,
42 feature,
43 loose,
44 manipulateOptions,
45 api,
46 inherits,
47 decoratorVersion
48}) {
49 var _api$assumption;
50 if (feature & _features.FEATURES.decorators) {
51 {
52 if (decoratorVersion === "2023-11" || decoratorVersion === "2023-05" || decoratorVersion === "2023-01" || decoratorVersion === "2022-03" || decoratorVersion === "2021-12") {
53 return (0, _decorators.default)(api, {
54 loose
55 }, decoratorVersion, inherits);
56 }
57 }
58 }
59 {
60 var _api;
61 (_api = api) != null ? _api : api = {
62 assumption: () => void 0
63 };
64 }
65 const setPublicClassFields = api.assumption("setPublicClassFields");
66 const privateFieldsAsSymbols = api.assumption("privateFieldsAsSymbols");
67 const privateFieldsAsProperties = api.assumption("privateFieldsAsProperties");
68 const noUninitializedPrivateFieldAccess = (_api$assumption = api.assumption("noUninitializedPrivateFieldAccess")) != null ? _api$assumption : false;
69 const constantSuper = api.assumption("constantSuper");
70 const noDocumentAll = api.assumption("noDocumentAll");
71 if (privateFieldsAsProperties && privateFieldsAsSymbols) {
72 throw new Error(`Cannot enable both the "privateFieldsAsProperties" and ` + `"privateFieldsAsSymbols" assumptions as the same time.`);
73 }
74 const privateFieldsAsSymbolsOrProperties = privateFieldsAsProperties || privateFieldsAsSymbols;
75 if (loose === true) {
76 const explicit = [];
77 if (setPublicClassFields !== undefined) {
78 explicit.push(`"setPublicClassFields"`);
79 }
80 if (privateFieldsAsProperties !== undefined) {
81 explicit.push(`"privateFieldsAsProperties"`);
82 }
83 if (privateFieldsAsSymbols !== undefined) {
84 explicit.push(`"privateFieldsAsSymbols"`);
85 }
86 if (explicit.length !== 0) {
87 console.warn(`[${name}]: You are using the "loose: true" option and you are` + ` explicitly setting a value for the ${explicit.join(" and ")}` + ` assumption${explicit.length > 1 ? "s" : ""}. The "loose" option` + ` can cause incompatibilities with the other class features` + ` plugins, so it's recommended that you replace it with the` + ` following top-level option:\n` + `\t"assumptions": {\n` + `\t\t"setPublicClassFields": true,\n` + `\t\t"privateFieldsAsSymbols": true\n` + `\t}`);
88 }
89 }
90 return {
91 name,
92 manipulateOptions,
93 inherits,
94 pre(file) {
95 (0, _features.enableFeature)(file, feature, loose);
96 {
97 if (typeof file.get(versionKey) === "number") {
98 file.set(versionKey, "7.25.9");
99 return;
100 }
101 }
102 if (!file.get(versionKey) || _semver.lt(file.get(versionKey), "7.25.9")) {
103 file.set(versionKey, "7.25.9");
104 }
105 },
106 visitor: {
107 Class(path, {
108 file
109 }) {
110 var _ref;
111 if (file.get(versionKey) !== "7.25.9") return;
112 if (!(0, _features.shouldTransform)(path, file)) return;
113 const pathIsClassDeclaration = path.isClassDeclaration();
114 if (pathIsClassDeclaration) (0, _typescript.assertFieldTransformed)(path);
115 const loose = (0, _features.isLoose)(file, feature);
116 let constructor;
117 const isDecorated = (0, _decorators2.hasDecorators)(path.node);
118 const props = [];
119 const elements = [];
120 const computedPaths = [];
121 const privateNames = new Set();
122 const body = path.get("body");
123 for (const path of body.get("body")) {
124 if ((path.isClassProperty() || path.isClassMethod()) && path.node.computed) {
125 computedPaths.push(path);
126 }
127 if (path.isPrivate()) {
128 const {
129 name
130 } = path.node.key.id;
131 const getName = `get ${name}`;
132 const setName = `set ${name}`;
133 if (path.isClassPrivateMethod()) {
134 if (path.node.kind === "get") {
135 if (privateNames.has(getName) || privateNames.has(name) && !privateNames.has(setName)) {
136 throw path.buildCodeFrameError("Duplicate private field");
137 }
138 privateNames.add(getName).add(name);
139 } else if (path.node.kind === "set") {
140 if (privateNames.has(setName) || privateNames.has(name) && !privateNames.has(getName)) {
141 throw path.buildCodeFrameError("Duplicate private field");
142 }
143 privateNames.add(setName).add(name);
144 }
145 } else {
146 if (privateNames.has(name) && !privateNames.has(getName) && !privateNames.has(setName) || privateNames.has(name) && (privateNames.has(getName) || privateNames.has(setName))) {
147 throw path.buildCodeFrameError("Duplicate private field");
148 }
149 privateNames.add(name);
150 }
151 }
152 if (path.isClassMethod({
153 kind: "constructor"
154 })) {
155 constructor = path;
156 } else {
157 elements.push(path);
158 if (path.isProperty() || path.isPrivate() || path.isStaticBlock != null && path.isStaticBlock()) {
159 props.push(path);
160 }
161 }
162 }
163 {
164 if (!props.length && !isDecorated) return;
165 }
166 const innerBinding = path.node.id;
167 let ref;
168 if (!innerBinding || !pathIsClassDeclaration) {
169 {
170 var _path$ensureFunctionN;
171 (_path$ensureFunctionN = path.ensureFunctionName) != null ? _path$ensureFunctionN : path.ensureFunctionName = require("@babel/traverse").NodePath.prototype.ensureFunctionName;
172 }
173 path.ensureFunctionName(false);
174 ref = path.scope.generateUidIdentifier((innerBinding == null ? void 0 : innerBinding.name) || "Class");
175 }
176 const classRefForDefine = (_ref = ref) != null ? _ref : _core.types.cloneNode(innerBinding);
177 const privateNamesMap = (0, _fields.buildPrivateNamesMap)(classRefForDefine.name, privateFieldsAsSymbolsOrProperties != null ? privateFieldsAsSymbolsOrProperties : loose, props, file);
178 const privateNamesNodes = (0, _fields.buildPrivateNamesNodes)(privateNamesMap, privateFieldsAsProperties != null ? privateFieldsAsProperties : loose, privateFieldsAsSymbols != null ? privateFieldsAsSymbols : false, file);
179 (0, _fields.transformPrivateNamesUsage)(classRefForDefine, path, privateNamesMap, {
180 privateFieldsAsProperties: privateFieldsAsSymbolsOrProperties != null ? privateFieldsAsSymbolsOrProperties : loose,
181 noUninitializedPrivateFieldAccess,
182 noDocumentAll,
183 innerBinding
184 }, file);
185 let keysNodes, staticNodes, instanceNodes, lastInstanceNodeReturnsThis, pureStaticNodes, classBindingNode, wrapClass;
186 {
187 if (isDecorated) {
188 staticNodes = pureStaticNodes = keysNodes = [];
189 ({
190 instanceNodes,
191 wrapClass
192 } = (0, _decorators2.buildDecoratedClass)(classRefForDefine, path, elements, file));
193 } else {
194 keysNodes = (0, _misc.extractComputedKeys)(path, computedPaths, file);
195 ({
196 staticNodes,
197 pureStaticNodes,
198 instanceNodes,
199 lastInstanceNodeReturnsThis,
200 classBindingNode,
201 wrapClass
202 } = (0, _fields.buildFieldsInitNodes)(ref, path.node.superClass, props, privateNamesMap, file, setPublicClassFields != null ? setPublicClassFields : loose, privateFieldsAsSymbolsOrProperties != null ? privateFieldsAsSymbolsOrProperties : loose, noUninitializedPrivateFieldAccess, constantSuper != null ? constantSuper : loose, innerBinding));
203 }
204 }
205 if (instanceNodes.length > 0) {
206 (0, _misc.injectInitialization)(path, constructor, instanceNodes, (referenceVisitor, state) => {
207 {
208 if (isDecorated) return;
209 }
210 for (const prop of props) {
211 if (_core.types.isStaticBlock != null && _core.types.isStaticBlock(prop.node) || prop.node.static) continue;
212 prop.traverse(referenceVisitor, state);
213 }
214 }, lastInstanceNodeReturnsThis);
215 }
216 const wrappedPath = wrapClass(path);
217 wrappedPath.insertBefore([...privateNamesNodes, ...keysNodes]);
218 if (staticNodes.length > 0) {
219 wrappedPath.insertAfter(staticNodes);
220 }
221 if (pureStaticNodes.length > 0) {
222 wrappedPath.find(parent => parent.isStatement() || parent.isDeclaration()).insertAfter(pureStaticNodes);
223 }
224 if (classBindingNode != null && pathIsClassDeclaration) {
225 wrappedPath.insertAfter(classBindingNode);
226 }
227 },
228 ExportDefaultDeclaration(path, {
229 file
230 }) {
231 {
232 if (file.get(versionKey) !== "7.25.9") return;
233 const decl = path.get("declaration");
234 if (decl.isClassDeclaration() && (0, _decorators2.hasDecorators)(decl.node)) {
235 if (decl.node.id) {
236 {
237 var _path$splitExportDecl;
238 (_path$splitExportDecl = path.splitExportDeclaration) != null ? _path$splitExportDecl : path.splitExportDeclaration = require("@babel/traverse").NodePath.prototype.splitExportDeclaration;
239 }
240 path.splitExportDeclaration();
241 } else {
242 decl.node.type = "ClassExpression";
243 }
244 }
245 }
246 }
247 }
248 };
249}
250
251//# sourceMappingURL=index.js.map