mirror of https://github.com/status-im/metro.git
Make constant folding more powerful
Reviewed By: davidaurelio Differential Revision: D8038008 fbshipit-source-id: 06c81ccf4e816ceefeb6673f247fd0bac41429a6
This commit is contained in:
parent
54828cce35
commit
4a75826683
|
@ -20,6 +20,7 @@
|
|||
"@babel/plugin-proposal-class-properties": "7.0.0-beta.40",
|
||||
"@babel/plugin-proposal-object-rest-spread": "7.0.0-beta.40",
|
||||
"@babel/plugin-syntax-dynamic-import": "7.0.0-beta.40",
|
||||
"@babel/plugin-syntax-nullish-coalescing-operator": "7.0.0-beta.40",
|
||||
"@babel/plugin-transform-arrow-functions": "7.0.0-beta.40",
|
||||
"@babel/plugin-transform-async-to-generator": "7.0.0-beta.40",
|
||||
"@babel/plugin-transform-block-scoping": "7.0.0-beta.40",
|
||||
|
|
|
@ -38,6 +38,7 @@ function parse(code: string): TransformResult {
|
|||
code: false,
|
||||
babelrc: false,
|
||||
compact: true,
|
||||
plugins: [require('@babel/plugin-syntax-nullish-coalescing-operator')],
|
||||
sourceMaps: true,
|
||||
});
|
||||
}
|
||||
|
@ -107,6 +108,20 @@ describe('constant expressions', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('folds null coalescing operator', () => {
|
||||
const code = `
|
||||
var a = undefined ?? u();
|
||||
var b = null ?? v();
|
||||
var c = false ?? w();
|
||||
var d = 0 ?? x();
|
||||
var e = NaN ?? x();
|
||||
var f = "truthy" ?? z();
|
||||
`;
|
||||
expect(fold('arbitrary.js', code)).toEqual(
|
||||
'var a=u();var b=v();var c=false;var d=0;var e=NaN;var f="truthy";',
|
||||
);
|
||||
});
|
||||
|
||||
it('can remode an if statement with a falsy constant test', () => {
|
||||
const code = `
|
||||
if ('production' === 'development' || false) {
|
||||
|
@ -149,4 +164,26 @@ describe('constant expressions', () => {
|
|||
`;
|
||||
expect(fold('arbitrary.js', code)).toEqual("{{require('c');}}");
|
||||
});
|
||||
|
||||
it('folds if expressions with variables', () => {
|
||||
const code = `
|
||||
var x = 3;
|
||||
|
||||
if (x - 3) {
|
||||
require('a');
|
||||
}
|
||||
`;
|
||||
|
||||
expect(fold('arbitrary.js', code)).toEqual('var x=3;');
|
||||
});
|
||||
|
||||
it('folds logical expressions with variables', () => {
|
||||
const code = `
|
||||
var x = 3;
|
||||
var y = (x - 3) || 4;
|
||||
var z = (y - 4) && 4;
|
||||
`;
|
||||
|
||||
expect(fold('arbitrary.js', code)).toEqual('var x=3;var y=4;var z=0;');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -18,54 +18,60 @@ function constantFoldingPlugin(context: {types: BabelTypes}) {
|
|||
const Conditional = {
|
||||
exit(path: Object) {
|
||||
const node = path.node;
|
||||
const test = node.test;
|
||||
if (t.isLiteral(test)) {
|
||||
if (test.value || node.alternate) {
|
||||
path.replaceWith(test.value ? node.consequent : node.alternate);
|
||||
} else if (!test.value) {
|
||||
const result = path.get('test').evaluate();
|
||||
|
||||
if (result.confident) {
|
||||
if (result.value || node.alternate) {
|
||||
path.replaceWith(result.value ? node.consequent : node.alternate);
|
||||
} else if (!result.value) {
|
||||
path.remove();
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const Expression = {
|
||||
exit(path: Object) {
|
||||
const result = path.evaluate();
|
||||
|
||||
if (result.confident) {
|
||||
path.replaceWith(t.valueToNode(result.value));
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const LogicalExpression = {
|
||||
exit(path: Object) {
|
||||
const node = path.node;
|
||||
const result = path.get('left').evaluate();
|
||||
|
||||
if (result.confident) {
|
||||
const value = result.value;
|
||||
|
||||
switch (node.operator) {
|
||||
case '||':
|
||||
path.replaceWith(value ? node.left : node.right);
|
||||
break;
|
||||
|
||||
case '&&':
|
||||
path.replaceWith(value ? node.right : node.left);
|
||||
break;
|
||||
|
||||
case '??':
|
||||
path.replaceWith(value == null ? node.right : node.left);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
visitor: {
|
||||
BinaryExpression: {
|
||||
exit(path: Object) {
|
||||
const node = path.node;
|
||||
if (t.isLiteral(node.left) && t.isLiteral(node.right)) {
|
||||
const result = path.evaluate();
|
||||
if (result.confident) {
|
||||
path.replaceWith(t.valueToNode(result.value));
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
BinaryExpression: Expression,
|
||||
ConditionalExpression: Conditional,
|
||||
IfStatement: Conditional,
|
||||
LogicalExpression: {
|
||||
exit(path: Object) {
|
||||
const node = path.node;
|
||||
const left = node.left;
|
||||
if (t.isLiteral(left)) {
|
||||
const value = t.isNullLiteral(left) ? null : left.value;
|
||||
if (node.operator === '||') {
|
||||
path.replaceWith(value ? left : node.right);
|
||||
} else {
|
||||
path.replaceWith(value ? node.right : left);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
UnaryExpression: {
|
||||
exit(path: Object) {
|
||||
const node = path.node;
|
||||
if (node.operator === '!' && t.isLiteral(node.argument)) {
|
||||
path.replaceWith(t.valueToNode(!node.argument.value));
|
||||
}
|
||||
},
|
||||
},
|
||||
LogicalExpression,
|
||||
UnaryExpression: Expression,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -22,16 +22,6 @@ exports[`basic_bundle bundles package with polyfills 1`] = `
|
|||
hasError: false,
|
||||
isInitialized: false
|
||||
};
|
||||
|
||||
if (PRINT_REQUIRE_PATHS) {
|
||||
var _path = arguments[4];
|
||||
|
||||
if (_path) {
|
||||
modules[moduleId].path = _path;
|
||||
} else {
|
||||
throw new Error(\\"path not set on module with PRINT_REQUIRE_PATHS true. Make sure PASS_MODULE_PATHS_TO_DEFINE is true and restart Metro or rebuild bundle\\");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function metroRequire(moduleId) {
|
||||
|
@ -61,7 +51,7 @@ exports[`basic_bundle bundles package with polyfills 1`] = `
|
|||
}
|
||||
|
||||
var ID_MASK_SHIFT = 16;
|
||||
var LOCAL_ID_MASK = ~0 >>> ID_MASK_SHIFT;
|
||||
var LOCAL_ID_MASK = 65535;
|
||||
|
||||
function unpackModuleId(moduleId) {
|
||||
var segmentId = moduleId >>> ID_MASK_SHIFT;
|
||||
|
@ -107,10 +97,6 @@ exports[`basic_bundle bundles package with polyfills 1`] = `
|
|||
dependencyMap = _module.dependencyMap;
|
||||
|
||||
try {
|
||||
if (PRINT_REQUIRE_PATHS) {
|
||||
console.log(\\"require file path \\" + (module.path || 'unknown'));
|
||||
}
|
||||
|
||||
var _moduleObject = {
|
||||
exports: exports
|
||||
};
|
||||
|
@ -225,16 +211,6 @@ exports[`basic_bundle bundles package without polyfills 1`] = `
|
|||
hasError: false,
|
||||
isInitialized: false
|
||||
};
|
||||
|
||||
if (PRINT_REQUIRE_PATHS) {
|
||||
var _path = arguments[4];
|
||||
|
||||
if (_path) {
|
||||
modules[moduleId].path = _path;
|
||||
} else {
|
||||
throw new Error(\\"path not set on module with PRINT_REQUIRE_PATHS true. Make sure PASS_MODULE_PATHS_TO_DEFINE is true and restart Metro or rebuild bundle\\");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function metroRequire(moduleId) {
|
||||
|
@ -264,7 +240,7 @@ exports[`basic_bundle bundles package without polyfills 1`] = `
|
|||
}
|
||||
|
||||
var ID_MASK_SHIFT = 16;
|
||||
var LOCAL_ID_MASK = ~0 >>> ID_MASK_SHIFT;
|
||||
var LOCAL_ID_MASK = 65535;
|
||||
|
||||
function unpackModuleId(moduleId) {
|
||||
var segmentId = moduleId >>> ID_MASK_SHIFT;
|
||||
|
@ -310,10 +286,6 @@ exports[`basic_bundle bundles package without polyfills 1`] = `
|
|||
dependencyMap = _module.dependencyMap;
|
||||
|
||||
try {
|
||||
if (PRINT_REQUIRE_PATHS) {
|
||||
console.log(\\"require file path \\" + (module.path || 'unknown'));
|
||||
}
|
||||
|
||||
var _moduleObject = {
|
||||
exports: exports
|
||||
};
|
||||
|
|
|
@ -250,6 +250,10 @@
|
|||
version "7.0.0-beta.40"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.0.0-beta.40.tgz#db44d52ff06f784be22f2659e694cc2cf97f99f9"
|
||||
|
||||
"@babel/plugin-syntax-nullish-coalescing-operator@7.0.0-beta.40":
|
||||
version "7.0.0-beta.40"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.0.0-beta.40.tgz#1bd13137a2053b1bab0bb4e914e141fd67a10d7e"
|
||||
|
||||
"@babel/plugin-syntax-object-rest-spread@7.0.0-beta.40":
|
||||
version "7.0.0-beta.40"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0-beta.40.tgz#d5e04536062e4df685c203ae48bb19bfe2cf235c"
|
||||
|
|
Loading…
Reference in New Issue