UNPKG

@storm-stack/core

Version:

A build toolkit and runtime used by Storm Software in TypeScript applications

1 lines 6.68 kB
{"version":3,"sources":["../../src/lib/babel/plugins/builtin-extend.ts"],"names":["buildHelper","template","buildHelperApproximate","BuiltinExtendPlugin","declare","api","options","name","visitor","Class","path","globals","toArray","includes","push","superClass","get","node","some","isIdentifier","scope","hasBinding","noGlobals","generateUidIdentifier","helper","opts","approximate","HELPER","getProgramParent","unshiftContainer","replaceWith","callExpression"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,IAAMA,cAAcC,yBAAAA,CAAS;;;;;;;;;;;;;;;;;;;;;;;;;AAyB5B,CAAA,CAAA;AAQD,IAAMC,yBAAyBD,yBAAAA,CAAS;;;;;;;;;;;;;;;;;;;;;AAqBvC,CAAA,CAAA;AAwBM,IAAME,mBAAAA,GAAsBC,yBAAAA,CAGjC,CAACC,GAAAA,EAAgBC,OAAAA,KAAAA;AACjB,EAAA,OAAO;IACLC,IAAAA,EAAM,4BAAA;IACNC,OAAAA,EAAS;AACPC,MAAAA,KAAAA,CAAMC,IAAAA,EAAsD;AAC1D,QAAA,MAAMC,OAAAA,GAAUC,eAAAA,CAAgBN,OAAAA,CAAQK,OAAO,CAAA;AAC/C,QAAA,IAAI,CAACA,OAAAA,CAAQE,QAAAA,CAAS,OAAA,CAAA,EAAU;AAC9BF,UAAAA,OAAAA,CAAQG,KAAK,OAAA,CAAA;AACf,QAAA;AAEA,QAAA,MAAMC,UAAAA,GAAaL,IAAAA,CAAKM,GAAAA,CAAI,YAAA,CAAA;AAC5B,QAAA,IACE,CAACD,WAAWE,IAAAA,IACZ,CAACN,QAAQO,IAAAA,CAAKX,CAAAA,KAAAA,KAAQQ,UAAAA,CAAWI,YAAAA,CAAa;UAAEZ,IAAAA,EAAAA;AAAK,SAAA,CAAA,CAAA,EACrD;AACA,UAAA;AACF,QAAA;AAEA,QAAA,IACEG,IAAAA,CAAKU,KAAAA,CAAMC,UAAAA,CAAYN,UAAAA,CAAWE,MAAuBV,IAAAA,EAAM;UAC7De,SAAAA,EAAW;AACb,SAAA,CAAA,EACA;AACA,UAAA;AACF,QAAA;AAEA,QAAA,MAAMf,IAAAA,GAAOG,IAAAA,CAAKU,KAAAA,CAAMG,qBAAAA,CAAsB,wBAAA,CAAA;AAE9C,QAAA,MAAMC,MAAAA,GAAAA,CACJ,IAAA,CAAKC,IAAAA,CAAKC,WAAAA,GAAcxB,yBAAyBF,WAAAA,EACjD;UACA2B,MAAAA,EAAQpB;SACV,CAAA;AAEEG,QAAAA,IAAAA,CAAKU,MAAMQ,gBAAAA,EAAgB,CAAGlB,IAAAA,CAC9BmB,gBAAAA,CAAiB,QAAQL,MAAAA,CAAAA;AAE3BT,QAAAA,UAAAA,CAAWe,WAAAA,CAAcC,4BAAexB,IAAAA,EAAM;UAACQ,UAAAA,CAAWE;SAAK,CAAA,CAAA;AACjE,MAAA;AACF;AACF,GAAA;AACF,CAAA","file":"chunk-J3ZPV7VA.cjs","sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Storm Stack\n\n This code was released as part of the Storm Stack project. Storm Stack\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/storm-stack.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/storm-stack\n Documentation: https://docs.stormsoftware.com/projects/storm-stack\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { NodePath, PluginAPI, PluginPass } from \"@babel/core\";\nimport { declare } from \"@babel/helper-plugin-utils\";\nimport template from \"@babel/template\";\nimport * as t from \"@babel/types\";\nimport { toArray } from \"@stryke/convert\";\nimport { BabelPluginOptions } from \"../../../types/babel\";\n\n/**\n * Generate a helper that will explicitly set up the prototype chain manually\n * for each constructed instance.\n */\nconst buildHelper = template(`\n function HELPER(cls){\n function ExtendableBuiltin(){\n // Not passing \"newTarget\" because core-js would fall back to non-exotic\n // object creation.\n var instance = Reflect.construct(cls, Array.from(arguments));\n Object.setPrototypeOf(instance, Object.getPrototypeOf(this));\n return instance;\n }\n ExtendableBuiltin.prototype = Object.create(cls.prototype, {\n constructor: {\n value: cls,\n enumerable: false,\n writable: true,\n configurable: true,\n },\n });\n if (Object.setPrototypeOf){\n Object.setPrototypeOf(ExtendableBuiltin, cls);\n } else {\n ExtendableBuiltin.__proto__ = cls;\n }\n\n return ExtendableBuiltin;\n }\n`);\n\n/**\n * Generate a helper that will approximate extending builtins with simple\n * ES5-style inheritance.\n *\n * This is essentially the behavior that was the default in Babel 5.\n */\nconst buildHelperApproximate = template(`\n function HELPER(cls){\n function ExtendableBuiltin(){\n cls.apply(this, arguments);\n }\n ExtendableBuiltin.prototype = Object.create(cls.prototype, {\n constructor: {\n value: cls,\n enumerable: false,\n writable: true,\n configurable: true,\n },\n });\n if (Object.setPrototypeOf){\n Object.setPrototypeOf(ExtendableBuiltin, cls);\n } else {\n ExtendableBuiltin.__proto__ = cls;\n }\n\n return ExtendableBuiltin;\n }\n`);\n\ntype BuiltinExtendPluginOptions = BabelPluginOptions & {\n /**\n * The names of the built-in classes that should be extended.\n *\n * @remarks\n * This is used to determine which classes should be transformed.\n *\n * @defaultValue [\"Error\"]\n */\n globals?: string[];\n\n /**\n * Whether to use the approximate behavior of extending built-ins.\n *\n * @remarks\n * This is used to determine whether to use the approximate helper or the full helper.\n *\n * @defaultValue true\n */\n approximate?: boolean;\n};\n\nexport const BuiltinExtendPlugin = declare<\n PluginPass<BuiltinExtendPluginOptions>,\n BuiltinExtendPluginOptions\n>((api: PluginAPI, options: BuiltinExtendPluginOptions) => {\n return {\n name: \"storm-stack:builtin-extend\",\n visitor: {\n Class(path: NodePath<t.ClassDeclaration | t.ClassExpression>) {\n const globals = toArray<string>(options.globals);\n if (!globals.includes(\"Error\")) {\n globals.push(\"Error\");\n }\n\n const superClass = path.get(\"superClass\");\n if (\n !superClass.node ||\n !globals.some(name => superClass.isIdentifier({ name }))\n ) {\n return;\n }\n\n if (\n path.scope.hasBinding((superClass.node as t.Identifier)?.name, {\n noGlobals: true\n })\n ) {\n return;\n }\n\n const name = path.scope.generateUidIdentifier(\"stormExtendableBuiltin\");\n\n const helper = (\n this.opts.approximate ? buildHelperApproximate : buildHelper\n )({\n HELPER: name\n });\n (\n path.scope.getProgramParent().path as NodePath<t.Program>\n ).unshiftContainer(\"body\", helper);\n\n superClass.replaceWith(t.callExpression(name, [superClass.node]));\n }\n }\n };\n});\n"]}