inline-loops.macro
Advanced tools
Comparing version 2.0.0-beta.2 to 2.0.0-beta.3
@@ -12,3 +12,3 @@ ## CHANGELOG | ||
- Support for conditional usage in ternaries / logical expressions | ||
- Support for conditional and lazy scenarios (ternaries, logical expressions, default parameter assignments, etc.) | ||
- Better TS typing | ||
@@ -15,0 +15,0 @@ - Better inline handling of complex logic |
@@ -13,2 +13,3 @@ "use strict"; | ||
exports.isMacroHandlerName = isMacroHandlerName; | ||
exports.isPossiblyDynamic = isPossiblyDynamic; | ||
exports.processNestedInlineLoopMacros = processNestedInlineLoopMacros; | ||
@@ -144,2 +145,11 @@ exports.rename = rename; | ||
} | ||
function isPossiblyDynamic(path) { | ||
if (path.isPattern()) { | ||
return true; | ||
} | ||
if (path.isBinaryExpression() || path.isCallExpression() || path.isTemplateLiteral()) { | ||
return isPossiblyDynamic(path.parentPath); | ||
} | ||
return path.isExpression(); | ||
} | ||
function shouldWrapInClosure(path, local) { | ||
@@ -152,6 +162,6 @@ var _functionParent$get; | ||
var functionParent = path.getFunctionParent(); | ||
if (!functionParent) { | ||
return isPossiblyDynamic(parentPath); | ||
} | ||
var grandparentPath = parentPath.parentPath; | ||
if (!functionParent || !grandparentPath) { | ||
return false; | ||
} | ||
if (parentPath.isPattern() || local.contents.length > 1) { | ||
@@ -166,6 +176,6 @@ return true; | ||
} | ||
if (!parentPath.isExpression()) { | ||
if (!grandparentPath || !parentPath.isExpression()) { | ||
return false; | ||
} | ||
var maybeNestedConditional = grandparentPath.isPattern() || grandparentPath.isExpression() && !grandparentPath.isBinaryExpression(); | ||
var maybeNestedConditional = isPossiblyDynamic(grandparentPath); | ||
if (parentPath.isLogicalExpression()) { | ||
@@ -172,0 +182,0 @@ return !maybeNestedConditional && parentPath.get('right').node === path.node; |
@@ -61,3 +61,3 @@ { | ||
"typings": "./index.d.ts", | ||
"version": "2.0.0-beta.2" | ||
"version": "2.0.0-beta.3" | ||
} |
@@ -14,2 +14,3 @@ # inline-loops.macro | ||
- [Aggressive inlining](#aggressive-inlining) | ||
- [Conditional / lazy scenarios](#conditional--lazy-scenarios) | ||
- [Bailout scenarios](#bailout-scenarios) | ||
@@ -82,6 +83,4 @@ - [Gotchas](#gotchas) | ||
```js | ||
// this | ||
const foo = map(array, fn); | ||
// becomes this | ||
// transforms to | ||
const _length = array.length; | ||
@@ -103,6 +102,4 @@ const _results = Array(_length); | ||
```js | ||
// this | ||
const doubled = map(array, (value) => value * 2); | ||
// becomes this | ||
// transforms to | ||
const _length = array.length; | ||
@@ -120,8 +117,6 @@ const _results = Array(_length); | ||
```js | ||
// this | ||
const isAllTuples = every(array, (tuple) => | ||
every(tuple, (value) => Array.isArray(value) && value.length === 2), | ||
); | ||
// becomes this | ||
// transforms to | ||
let _determination = true; | ||
@@ -156,2 +151,47 @@ for ( | ||
### Conditional / lazy scenarios | ||
There are times where you want to perform the operation lazily, and there is support for this as well: | ||
```js | ||
foo === 'bar' ? array : map(array, (v) => v * 2); | ||
// transforms to | ||
foo === 'bar' | ||
? array | ||
: (() => { | ||
const _length = array.length; | ||
const _results = Array(_length); | ||
for (let _key = 0, _v; _key < _length; ++_key) { | ||
_v = array[_key]; | ||
_results[_key] = _v * 2; | ||
} | ||
return _results; | ||
})(); | ||
``` | ||
The wrapping in the IIFE (Immediately-Invoked Function Expression) allows for the lazy execution based on the condition, but if that condition is met then it eagerly executes and returns the value. This will work just as easily for default parameters: | ||
```js | ||
function getStuff(array, doubled = map(array, (v) => v * 2)) { | ||
return doubled; | ||
} | ||
// transforms to | ||
function getStuff( | ||
array, | ||
doubled = (() => { | ||
const _length = array.length; | ||
const _results = Array(_length); | ||
for (let _key = 0, _v; _key < _length; ++_key) { | ||
_v = array[_key]; | ||
_results[_key] = _v * 2; | ||
} | ||
return _results; | ||
})(), | ||
) { | ||
return doubled; | ||
} | ||
``` | ||
Because there is a small cost to parse, analyze, and execute the function compared to just have the logic in the same closure, the macro will only wrap the logic in an IIFE if such conditional or lazy execution is required. | ||
### Bailout scenarios | ||
@@ -196,3 +236,3 @@ | ||
// becomes this | ||
// transforms to this | ||
let _result = {}; | ||
@@ -199,0 +239,0 @@ |
67884
1273
286