babel-helper-evaluate-path
Advanced tools
Comparing version 0.5.0-alpha.7b176463 to 0.5.0-alpha.85c9b6d8
159
lib/index.js
"use strict"; | ||
function _sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } | ||
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } | ||
function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return _sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } } | ||
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } | ||
module.exports = function evaluate(path) { | ||
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, | ||
_ref$tdz = _ref.tdz, | ||
tdz = _ref$tdz === void 0 ? false : _ref$tdz; | ||
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } | ||
if (!tdz) { | ||
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } | ||
module.exports = function evaluate(path, { | ||
tdz = false | ||
} = {}) { | ||
if (!tdz && !path.isReferencedIdentifier()) { | ||
return baseEvaluate(path); | ||
@@ -20,3 +22,3 @@ } | ||
var state = { | ||
const state = { | ||
confident: true | ||
@@ -31,7 +33,7 @@ }; // prepare | ||
ReferencedIdentifier(idPath) { | ||
var binding = idPath.scope.getBinding(idPath.node.name); // don't deopt globals | ||
const binding = idPath.scope.getBinding(idPath.node.name); // don't deopt globals | ||
// let babel take care of it | ||
if (!binding) return; | ||
var evalResult = evaluateIdentifier(idPath); | ||
const evalResult = evaluateIdentifier(idPath); | ||
@@ -72,7 +74,34 @@ if (!evalResult.confident) { | ||
var node = path.node; | ||
var binding = path.scope.getBinding(node.name); | ||
const node = path.node; | ||
const binding = path.scope.getBinding(node.name); | ||
if (!binding) { | ||
return deopt(path); | ||
const name = node.name; | ||
if (!name) { | ||
return deopt(path); | ||
} | ||
switch (name) { | ||
case "undefined": | ||
return { | ||
confident: true, | ||
value: undefined | ||
}; | ||
case "NaN": | ||
return { | ||
confident: true, | ||
value: NaN | ||
}; | ||
case "Infinity": | ||
return { | ||
confident: true, | ||
value: Infinity | ||
}; | ||
default: | ||
return deopt(path); | ||
} | ||
} | ||
@@ -91,3 +120,3 @@ | ||
var flowEvalResult = evaluateBasedOnControlFlow(binding, path); | ||
const flowEvalResult = evaluateBasedOnControlFlow(binding, path); | ||
@@ -120,21 +149,35 @@ if (flowEvalResult.confident) { | ||
// early-exit | ||
var declaration = binding.path.parentPath; | ||
const declaration = binding.path.parentPath; | ||
if (declaration.parentPath.isIfStatement() || declaration.parentPath.isLoop() || declaration.parentPath.isSwitchCase()) { | ||
return { | ||
shouldDeopt: true | ||
}; | ||
if (declaration.parentPath) { | ||
/** | ||
* Handle when binding is created inside a parent block and | ||
* the corresponding parent is removed by other plugins | ||
* if (false) { var a } -> var a | ||
*/ | ||
if (declaration.parentPath.removed) { | ||
return { | ||
confident: true, | ||
value: void 0 | ||
}; | ||
} | ||
if (declaration.parentPath.isIfStatement() || declaration.parentPath.isLoop() || declaration.parentPath.isSwitchCase()) { | ||
return { | ||
shouldDeopt: true | ||
}; | ||
} | ||
} | ||
var blockParent = binding.path.scope.getBlockParent().path; | ||
var fnParent = binding.path.getFunctionParent(); | ||
const fnParent = (binding.path.scope.getFunctionParent() || binding.path.scope.getProgramParent()).path; | ||
let blockParent = binding.path.scope.getBlockParent().path; | ||
if (blockParent === fnParent) { | ||
if (!fnParent.isProgram()) blockParent = blockParent.get("body"); | ||
if (blockParent === fnParent && !fnParent.isProgram()) { | ||
blockParent = blockParent.get("body"); | ||
} // detect Usage Outside Init Scope | ||
if (!blockParent.get("body").some(function (stmt) { | ||
return stmt.isAncestor(refPath); | ||
})) { | ||
const blockBody = blockParent.get("body"); | ||
if (Array.isArray(blockBody) && !blockBody.some(stmt => stmt.isAncestor(refPath))) { | ||
return { | ||
@@ -146,4 +189,4 @@ shouldDeopt: true | ||
var stmts = fnParent.isProgram() ? fnParent.get("body") : fnParent.get("body").get("body"); | ||
var compareResult = compareBindingAndReference({ | ||
const stmts = fnParent.isProgram() ? fnParent.get("body") : fnParent.get("body").get("body"); | ||
const compareResult = compareBindingAndReference({ | ||
binding, | ||
@@ -161,13 +204,9 @@ refPath, | ||
} | ||
return { | ||
shouldDeopt: true | ||
}; | ||
} | ||
} else if (binding.kind === "let" || binding.kind === "const") { | ||
// binding.path is the declarator | ||
var declarator = binding.path; | ||
var _declaration = declarator.parentPath; | ||
const declarator = binding.path; | ||
const declaration = declarator.parentPath; | ||
if (_declaration.parentPath.isIfStatement() || _declaration.parentPath.isLoop() || _declaration.parentPath.isSwitchCase()) { | ||
if (declaration.parentPath && (declaration.parentPath.isIfStatement() || declaration.parentPath.isLoop() || declaration.parentPath.isSwitchCase())) { | ||
return { | ||
@@ -178,3 +217,3 @@ shouldDeopt: true | ||
var scopePath = declarator.scope.path; | ||
let scopePath = declarator.scope.path; | ||
@@ -186,16 +225,20 @@ if (scopePath.isFunction() || scopePath.isCatchClause()) { | ||
var _stmts = scopePath.get("body"); | ||
let stmts = scopePath.get("body"); | ||
var _compareResult = compareBindingAndReference({ | ||
if (!Array.isArray(stmts)) { | ||
stmts = [stmts]; | ||
} | ||
const compareResult = compareBindingAndReference({ | ||
binding, | ||
refPath, | ||
stmts: _stmts | ||
stmts | ||
}); | ||
if (_compareResult.reference && _compareResult.binding) { | ||
if (_compareResult.reference.scope === "current" && _compareResult.reference.idx < _compareResult.binding.idx) { | ||
if (compareResult.reference && compareResult.binding) { | ||
if (compareResult.reference.scope === "current" && compareResult.reference.idx < compareResult.binding.idx) { | ||
throw new Error(`ReferenceError: Used ${refPath.node.name}: ` + `${binding.kind} binding before declaration`); | ||
} | ||
if (_compareResult.reference.scope === "other") { | ||
if (compareResult.reference.scope === "other") { | ||
return { | ||
@@ -214,7 +257,8 @@ shouldDeopt: true | ||
function compareBindingAndReference(_ref2) { | ||
var binding = _ref2.binding, | ||
refPath = _ref2.refPath, | ||
stmts = _ref2.stmts; | ||
var state = { | ||
function compareBindingAndReference({ | ||
binding, | ||
refPath, | ||
stmts | ||
}) { | ||
const state = { | ||
binding: null, | ||
@@ -229,12 +273,9 @@ reference: null | ||
for (var _iterator = stmts.entries()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
var _ref5 = _step.value; | ||
const _step$value = _slicedToArray(_step.value, 2), | ||
idx = _step$value[0], | ||
stmt = _step$value[1]; | ||
var _ref4 = _slicedToArray(_ref5, 2); | ||
var _idx = _ref4[0]; | ||
var _stmt = _ref4[1]; | ||
if (_stmt.isAncestor(binding.path)) { | ||
if (stmt.isAncestor(binding.path)) { | ||
state.binding = { | ||
idx: _idx | ||
idx | ||
}; | ||
@@ -249,8 +290,8 @@ } | ||
for (var _iterator2 = binding.referencePaths[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { | ||
var _ref6 = _step2.value; | ||
const ref = _step2.value; | ||
if (_ref6 === refPath && _stmt.isAncestor(_ref6)) { | ||
if (ref === refPath && stmt.isAncestor(ref)) { | ||
state.reference = { | ||
idx: _idx, | ||
scope: binding.path.scope === _ref6.scope ? "current" : "other" | ||
idx, | ||
scope: binding.path.scope === ref.scope ? "current" : "other" | ||
}; | ||
@@ -257,0 +298,0 @@ break; |
{ | ||
"name": "babel-helper-evaluate-path", | ||
"version": "0.5.0-alpha.7b176463", | ||
"version": "0.5.0-alpha.85c9b6d8", | ||
"description": "path.evaluate wrapped in a try catch", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -34,3 +34,3 @@ # babel-helper-evaluate-path | ||
```sh | ||
npm install babel-helper-evaluate-path | ||
npm install babel-helper-evaluate-path --save-dev | ||
``` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
9524
263