babel-plugin-transform-jsbi-to-bigint
Version:
Compile JSBI code to native BigInt code.
191 lines (186 loc) • 9.64 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = _default;
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
function _toArray(r) { return _arrayWithHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
// Copyright 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// <https://apache.org/licenses/LICENSE-2.0>.
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// https://github.com/GoogleChromeLabs/jsbi#how
var binaryFunctionToExpression = new Map([['add', '+'], ['subtract', '-'], ['multiply', '*'], ['divide', '/'], ['remainder', '%'], ['exponentiate', '**'], ['leftShift', '<<'], ['signedRightShift', '>>'], ['bitwiseAnd', '&'], ['bitwiseOr', '|'], ['bitwiseXor', '^'], ['equal', '==='], ['notEqual', '!=='], ['lessThan', '<'], ['lessThanOrEqual', '<='], ['greaterThan', '>'], ['greaterThanOrEqual', '>='], ['EQ', '=='], ['NE', '!='], ['LT', '<'], ['LE', '<='], ['GT', '>'], ['GE', '>='], ['ADD', '+']]);
// https://github.com/GoogleChromeLabs/jsbi#how
var unaryFunctionToExpression = new Map([['unaryMinus', '-'], ['bitwiseNot', '~']]);
// https://github.com/GoogleChromeLabs/jsbi#how
var staticMethods = new Set(['asIntN', 'asUintN']);
// https://github.com/GoogleChromeLabs/jsbi#how
var dataViewMethods = new Map([['DataViewGetBigInt64', 'getBigInt64'], ['DataViewSetBigInt64', 'setBigInt64'], ['DataViewGetBigUint64', 'getBigUint64'], ['DataViewSetBigUint64', 'setBigUint64']]);
var DATA_IDENTIFIER = 'JSBI';
function _default(babel) {
var t = babel.types;
var createExpression = function createExpression(path, name, args) {
if (name === 'BigInt') {
return createBigIntConstructor(path);
}
if (binaryFunctionToExpression.has(name)) {
if (args.length !== 2) {
throw path.buildCodeFrameError('Binary operators must have exactly two arguments');
}
return t.binaryExpression(binaryFunctionToExpression.get(name), args[0], args[1]);
}
if (unaryFunctionToExpression.has(name)) {
if (args.length !== 1) {
throw path.buildCodeFrameError('Unary operators must have exactly one argument');
}
return t.unaryExpression(unaryFunctionToExpression.get(name), args[0]);
}
if (staticMethods.has(name)) {
if (args.length !== 2) {
throw path.buildCodeFrameError('Static methods must have exactly two arguments');
}
return t.callExpression(t.memberExpression(t.identifier('BigInt'), t.identifier(name)), args);
}
if (dataViewMethods.has(name)) {
if (!(2 <= args.length && args.length <= 4)) {
throw path.buildCodeFrameError("".concat(name, ": incorrect number of arguments"));
}
var _args = _toArray(args),
view = _args[0],
rest = _args.slice(1);
return t.callExpression(t.memberExpression(view, t.identifier(dataViewMethods.get(name))), rest);
}
if (name === 'toNumber') {
if (args.length !== 1) {
throw path.buildCodeFrameError('toNumber must have exactly one argument');
}
return t.callExpression(t.identifier('Number'), args);
}
throw path.buildCodeFrameError("Unknown JSBI function '".concat(name, "'"));
};
var createBigIntConstructor = function createBigIntConstructor(path) {
var reInteger = /^(?:0|[1-9][0-9]*)$/;
var arg = path.node.arguments[0];
if (t.isNumericLiteral(arg) || t.isStringLiteral(arg) && reInteger.test(arg.value)) {
return t.bigIntLiteral("".concat(arg.value));
}
return t.callExpression(t.identifier('BigInt'), [arg]);
};
var getPropertyName = function getPropertyName(path) {
var node = path.node;
if (t.isIdentifier(node)) return node.name;
if (t.isStringLiteral(node)) return node.value;
throw path.buildCodeFrameError('Only .BigInt or [\'BigInt\'] allowed here.');
};
var _resolveBinding = function resolveBinding(_path, name) {
var binding = _path.scope.getBinding(name);
if (binding === undefined) return;
var path = binding.path;
if (path.getData(DATA_IDENTIFIER)) return binding;
var init = path.node.init;
if (t.isVariableDeclarator(path) && t.isMemberExpression(init)) {
return _resolveBinding(path.get('init'), init.object.name);
}
return binding;
};
var getJSBIProperty = function getJSBIProperty(path, name) {
var binding = _resolveBinding(path, name);
return binding && binding.path.getData(DATA_IDENTIFIER);
};
var setJSBIProperty = function setJSBIProperty(path, data) {
return path.setData(DATA_IDENTIFIER, data);
};
var hasJSBIProperty = function hasJSBIProperty(path, name) {
return getJSBIProperty(path, name) !== undefined;
};
return {
pre: function pre() {
this.remove = new Set();
},
visitor: {
Program: {
exit: function exit() {
var _iterator = _createForOfIteratorHelper(this.remove),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var path = _step.value;
path.remove();
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
}
},
ImportDeclaration: function ImportDeclaration(path) {
var source = path.node.source;
if (t.isStringLiteral(source) && (
// Match exact "jsbi" or ".../jsbi.mjs" paths.
/^jsbi$/i.test(source.value) || /[/\\]jsbi\.mjs$/i.test(source.value))) {
var _iterator2 = _createForOfIteratorHelper(path.get('specifiers')),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var specifier = _step2.value;
if (t.isImportDefaultSpecifier(specifier)) {
setJSBIProperty(specifier, '');
}
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
this.remove.add(path);
}
},
VariableDeclarator: function VariableDeclarator(path) {
var init = path.node.init;
if (t.isMemberExpression(init)) {
if (hasJSBIProperty(path, init.object.name)) {
setJSBIProperty(path, getPropertyName(path.get('init.property')));
this.remove.add(path);
}
}
},
CallExpression: function CallExpression(path) {
var callee = path.node.callee;
if (t.isMemberExpression(callee) && hasJSBIProperty(path, callee.object.name)) {
// Handle usage via `JSBI.foo(bar)`.
path.replaceWith(createExpression(path, getPropertyName(path.get('callee.property')), path.node.arguments));
} else {
// Handle usage via `JSBigInt = JSBI.BigInt; JSBigInt(foo)`.
var jsbiProp = getJSBIProperty(path, callee.name);
if (jsbiProp) {
path.replaceWith(createExpression(path, jsbiProp, path.node.arguments));
}
}
},
BinaryExpression: function BinaryExpression(path) {
var _path$node = path.node,
operator = _path$node.operator,
left = _path$node.left,
right = _path$node.right;
if (operator === 'instanceof' && t.isIdentifier(right) && hasJSBIProperty(path, right.name)) {
path.replaceWith(t.binaryExpression('===', t.unaryExpression('typeof', left), t.stringLiteral('bigint')));
}
}
}
};
}
;