pax_global_header00006660000000000000000000000064130474122520014512gustar00rootroot0000000000000052 comment=96c102445b8ff8949d44aa2ba083b9aaacee5149 babel-plugin-transform-builtin-extend-96c102445b8ff8949d44aa2ba083b9aaacee5149/000077500000000000000000000000001304741225200261005ustar00rootroot00000000000000babel-plugin-transform-builtin-extend-96c102445b8ff8949d44aa2ba083b9aaacee5149/.gitignore000066400000000000000000000000231304741225200300630ustar00rootroot00000000000000/lib /node_modules babel-plugin-transform-builtin-extend-96c102445b8ff8949d44aa2ba083b9aaacee5149/.npmignore000066400000000000000000000000231304741225200300720ustar00rootroot00000000000000/src /node_modules babel-plugin-transform-builtin-extend-96c102445b8ff8949d44aa2ba083b9aaacee5149/LICENSE000066400000000000000000000021041304741225200271020ustar00rootroot00000000000000Copyright (c) 2015 Logan Smyth MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. babel-plugin-transform-builtin-extend-96c102445b8ff8949d44aa2ba083b9aaacee5149/README.md000066400000000000000000000023631304741225200273630ustar00rootroot00000000000000 # Babel Builtin Constructor extension plugin This is a Babel 6 plugin to enable extending builtin types like "Error" and "Array" and such, which require special treatment and require static analysis to detect. ## Usage In your Babel 6 configuration, for example in a `.babelrc` you might have ``` { "plugins": [ ["babel-plugin-transform-builtin-extend", { globals: ["Error", "Array"] }] ] } ``` which would enable the plugin and configure it to look for any class extending `Error` or `Array` globals. ## IE<=10 On older browsers that do not support reassigning the prototype of an existing object, you will need to enable the `approximate` mode, which will fall back to the Babel 5 behavior of using simple ES5 inheritance to approximate extending a class, though your results may vary depending on your goals. ``` { "plugins": [ ["babel-plugin-transform-builtin-extend", { globals: ["Error", "Array"], approximate: true }] ] } ``` ## Limitations This plugin will only reles on assigning `__proto__` for static property inheritance from parent constructors. If you are relying on this, it will not work on IE<=10 and any other browsers that don't support `__proto__`. babel-plugin-transform-builtin-extend-96c102445b8ff8949d44aa2ba083b9aaacee5149/package.json000066400000000000000000000020261304741225200303660ustar00rootroot00000000000000{ "name": "babel-plugin-transform-builtin-extend", "description": "A plugin for Babel 6 supports extending from builtin types based on static analysis.", "version": "1.1.2", "author": "Logan Smyth ", "main": "lib", "license": "MIT", "repository": { "type": "git", "url": "https://github.com/loganfsmyth/babel-plugin-transform-builtin-extend.git" }, "bugs": { "url": "https://github.com/loganfsmyth/babel-plugin-transform-builtin-extend/issues" }, "keywords": [ "babel", "babel-plugin", "es6", "classes" ], "devDependencies": { "babel-cli": "^6.2.0", "babel-plugin-transform-runtime": "^6.1.18", "babel-preset-es2015": "^6.1.18", "chai": "^3.4.1", "mocha": "^2.3.4" }, "dependencies": { "babel-runtime": "^6.2.0", "babel-template": "^6.3.0" }, "scripts": { "build": "babel src -d lib", "watch": "babel src -d lib -w", "prepublish": "npm run build", "test": "babel-node node_modules/.bin/_mocha --recursive test" } } babel-plugin-transform-builtin-extend-96c102445b8ff8949d44aa2ba083b9aaacee5149/src/000077500000000000000000000000001304741225200266675ustar00rootroot00000000000000babel-plugin-transform-builtin-extend-96c102445b8ff8949d44aa2ba083b9aaacee5149/src/.babelrc000066400000000000000000000001421304741225200302570ustar00rootroot00000000000000{ "presets": [ "es2015", ], "plugins": [ "transform-runtime", ] } babel-plugin-transform-builtin-extend-96c102445b8ff8949d44aa2ba083b9aaacee5149/src/index.js000066400000000000000000000062531304741225200303420ustar00rootroot00000000000000import template from 'babel-template'; /** * Generate a helper that will explicitly set up the prototype chain manually * for each constructed instance. */ const buildHelper = template(` function HELPER(cls){ function ExtendableBuiltin(){ // Not passing "newTarget" because core-js would fall back to non-exotic // object creation. var instance = Reflect.construct(cls, Array.from(arguments)); Object.setPrototypeOf(instance, Object.getPrototypeOf(this)); return instance; } ExtendableBuiltin.prototype = Object.create(cls.prototype, { constructor: { value: cls, enumerable: false, writable: true, configurable: true, }, }); if (Object.setPrototypeOf){ Object.setPrototypeOf(ExtendableBuiltin, cls); } else { ExtendableBuiltin.__proto__ = cls; } return ExtendableBuiltin; } `); /** * Generate a helper that will approximate extending builtins with simple * ES5-style inheritance. * * This is essentially the behavior that was the default in Babel 5. */ const buildHelperApproximate = template(` function HELPER(cls){ function ExtendableBuiltin(){ cls.apply(this, arguments); } ExtendableBuiltin.prototype = Object.create(cls.prototype, { constructor: { value: cls, enumerable: false, writable: true, configurable: true, }, }); if (Object.setPrototypeOf){ Object.setPrototypeOf(ExtendableBuiltin, cls); } else { ExtendableBuiltin.__proto__ = cls; } return ExtendableBuiltin; } `); export default function({types: t}){ return { visitor: { Class(path){ // Ensure we have globals to search for. const classes = this.opts.globals || []; if (classes.length === 0) return; // Ensure the class is extending something. const superClass = path.get('superClass'); if (!superClass.node) return; // Ensure that the class is extending a variable matching one of the options. const matches = classes.some(name => superClass.isIdentifier({name})); if (!matches) return; // Ensure that this isn't a locally declared variable with the same name. if (path.scope.hasBinding(superClass.node.name, true /* noGlobals */)) return; const name = this.name || path.scope.generateUidIdentifier('extendableBuiltin'); if (!this.name){ const helper = (this.opts.approximate ? buildHelperApproximate : buildHelper)({ HELPER: name, }); path.scope.getProgramParent().path.unshiftContainer('body', helper); } path.get('superClass').replaceWith(t.callExpression(name, [ path.get('superClass').node, ])); } } }; } babel-plugin-transform-builtin-extend-96c102445b8ff8949d44aa2ba083b9aaacee5149/test/000077500000000000000000000000001304741225200270575ustar00rootroot00000000000000babel-plugin-transform-builtin-extend-96c102445b8ff8949d44aa2ba083b9aaacee5149/test/approximate/000077500000000000000000000000001304741225200314105ustar00rootroot00000000000000.babelrc000066400000000000000000000003371304741225200327270ustar00rootroot00000000000000babel-plugin-transform-builtin-extend-96c102445b8ff8949d44aa2ba083b9aaacee5149/test/approximate{ "presets": [ "es2015", ], "plugins": [ ["../", { "approximate": true, "globals": [ "Error", "Array", ], }], ], } index.js000066400000000000000000000026351304741225200330040ustar00rootroot00000000000000babel-plugin-transform-builtin-extend-96c102445b8ff8949d44aa2ba083b9aaacee5149/test/approximateimport {expect} from 'chai'; describe('approximate extension', function(){ describe('Array', function(){ class MyArray extends Array { constructor(){ super(); Object.defineProperty(this, '_i', { writable: true, value: 0, }); } myPush(){ this.push(this._i++); } } it('should behave properly', function(){ const a = new MyArray(); expect(Array.isArray(a)).to.be.false; expect(a instanceof MyArray).to.be.true; a.myPush(); a.myPush(); expect(a).to.eql({0: 0, 1: 1, length: 2}); a[20] = 'foo'; expect(a.length).to.eql(2); }); }); describe('Error', function(){ class MyError extends Error { constructor(message){ super(message); this.otherMessage = message; } } it('should behave properly', function(){ const a = new MyError('a message'); expect(a instanceof MyError).to.be.true; expect(a).to.have.ownProperty('otherMessage'); expect(a).not.to.have.ownProperty('message'); expect(a).not.to.have.ownProperty('stack'); expect(a.otherMessage).to.eql('a message'); }); }); }); babel-plugin-transform-builtin-extend-96c102445b8ff8949d44aa2ba083b9aaacee5149/test/standard/000077500000000000000000000000001304741225200306575ustar00rootroot00000000000000.babelrc000066400000000000000000000002761304741225200322000ustar00rootroot00000000000000babel-plugin-transform-builtin-extend-96c102445b8ff8949d44aa2ba083b9aaacee5149/test/standard{ "presets": [ "es2015", ], "plugins": [ ["../", { "globals": [ "Error", "Array", ], }], ], } index.js000066400000000000000000000024231304741225200322460ustar00rootroot00000000000000babel-plugin-transform-builtin-extend-96c102445b8ff8949d44aa2ba083b9aaacee5149/test/standardimport {expect} from 'chai'; describe('standard extension', function(){ describe('Array', function(){ class MyArray extends Array { constructor(){ super(); Object.defineProperty(this, '_i', { writable: true, value: 0, }); } myPush(){ this.push(this._i++); } } it('should behave properly', function(){ const a = new MyArray(); expect(Array.isArray(a)).to.be.true; expect(a instanceof MyArray).to.be.true; a.myPush(); a.myPush(); expect(a).to.eql([0, 1]); a[20] = 'foo'; expect(a.length).to.eql(21); }); }); describe('Error', function(){ class MyError extends Error { constructor(message){ super(message); } } it('should behave properly', function(){ const a = new MyError('a message'); expect(a instanceof MyError).to.be.true; expect(a).to.have.ownProperty('message'); expect(a).to.have.ownProperty('stack'); expect(a.message).to.eql('a message'); }); }); });