From b26b048c78f83f800b1251739da292eaea4b8e88 Mon Sep 17 00:00:00 2001 From: Christoph Nakazawa Date: Fri, 7 Jul 2017 10:35:45 -0700 Subject: [PATCH] Revert D5321193: BREAKING: Add regenerator-runtime on demand, based on the files Differential Revision: D5321193 fbshipit-source-id: 9113ed78e59ae9e9f3f86ca2fda2db3bd8c0dd7c --- .../worker/__tests__/constant-folding-test.js | 134 +++++------------- .../worker/__tests__/worker-test.js | 67 +++------ .../JSTransformer/worker/constant-folding.js | 34 ++--- .../src/JSTransformer/worker/index.js | 31 ++-- .../src/JSTransformer/worker/inline.js | 34 +++-- .../src/JSTransformer/worker/types.flow.js | 21 --- 6 files changed, 100 insertions(+), 221 deletions(-) delete mode 100644 packages/metro-bundler/src/JSTransformer/worker/types.flow.js diff --git a/packages/metro-bundler/src/JSTransformer/worker/__tests__/constant-folding-test.js b/packages/metro-bundler/src/JSTransformer/worker/__tests__/constant-folding-test.js index e289b379..bd15a1c6 100644 --- a/packages/metro-bundler/src/JSTransformer/worker/__tests__/constant-folding-test.js +++ b/packages/metro-bundler/src/JSTransformer/worker/__tests__/constant-folding-test.js @@ -10,28 +10,26 @@ */ 'use strict'; -/* eslint-disable max-len */ - +const babel = require('babel-core'); const constantFolding = require('../constant-folding'); -const {transform, transformFromAst} = require('babel-core'); +function parse(code) { + return babel.transform(code, {code: false, babelrc: false, compact: true}); +} const babelOptions = { babelrc: false, compact: true, + retainLines: false, }; -function toString(ast) { - return normalize(transformFromAst(ast, babelOptions).code); -} - -function normalize(code) { - return transform(code, babelOptions).code; +function normalize({code}) { + return babel.transform(code, babelOptions).code; } describe('constant expressions', () => { it('can optimize conditional expressions with constant conditions', () => { - const before = ` + const code = ` a( 'production'=="production", 'production'!=='development', @@ -41,97 +39,56 @@ describe('constant expressions', () => { 'android'==='android' ? {a:1} : {a:0}, 'foo'==='bar' ? b : c, f() ? g() : h() - ); - `; - - const after = ` - a( - true, - true, - 2, - true, - {}, - {a:1}, - c, - f() ? g() : h() - ); - `; - - const {ast} = constantFolding('arbitrary.js', {code: before}); - expect(toString(ast)).toEqual(normalize(after)); + );`; + expect(normalize(constantFolding('arbitrary.js', parse(code)))).toEqual( + 'a(true,true,2,true,{},{a:1},c,f()?g():h());', + ); }); it('can optimize ternary expressions with constant conditions', () => { - const before = ` - var a = true ? 1 : 2; - var b = 'android' == 'android' - ? ('production' != 'production' ? 'a' : 'A') - : 'i'; - `; - - const after = ` - var a = 1; - var b = 'A'; - `; - - const {ast} = constantFolding('arbitrary.js', {code: before}); - expect(toString(ast)).toEqual(normalize(after)); + const code = `var a = true ? 1 : 2; + var b = 'android' == 'android' + ? ('production' != 'production' ? 'a' : 'A') + : 'i';`; + expect(normalize(constantFolding('arbitrary.js', parse(code)))).toEqual( + "var a=1;var b='A';", + ); }); it('can optimize logical operator expressions with constant conditions', () => { - const before = ` + const code = ` var a = true || 1; var b = 'android' == 'android' && - 'production' != 'production' || null || "A"; - `; - - const after = ` - var a = true; - var b = "A"; - `; - - const {ast} = constantFolding('arbitrary.js', {code: before}); - expect(toString(ast)).toEqual(normalize(after)); + 'production' != 'production' || null || "A";`; + expect(normalize(constantFolding('arbitrary.js', parse(code)))).toEqual( + 'var a=true;var b="A";', + ); }); it('can optimize logical operators with partly constant operands', () => { - const before = ` + const code = ` var a = "truthy" || z(); var b = "truthy" && z(); var c = null && z(); var d = null || z(); var e = !1 && z(); `; - - const after = ` - var a = "truthy"; - var b = z(); - var c = null; - var d = z(); - var e = false; - `; - - const {ast} = constantFolding('arbitrary.js', {code: before}); - expect(toString(ast)).toEqual(normalize(after)); + expect(normalize(constantFolding('arbitrary.js', parse(code)))).toEqual( + 'var a="truthy";var b=z();var c=null;var d=z();var e=false;', + ); }); it('can remode an if statement with a falsy constant test', () => { - const before = ` + const code = ` if ('production' === 'development' || false) { var a = 1; } `; - - // Intentionally empty: all dead code. - const after = ` - `; - - const {ast} = constantFolding('arbitrary.js', {code: before}); - expect(toString(ast)).toEqual(normalize(after)); + expect(normalize(constantFolding('arbitrary.js', parse(code)))).toEqual(''); }); it('can optimize if-else-branches with constant conditions', () => { - const before = ` + const code = ` if ('production' == 'development') { var a = 1; var b = a + 2; @@ -142,20 +99,13 @@ describe('constant expressions', () => { var a = 'b'; } `; - - const after = ` - { - var a = 3; - var b = a + 4; - } - `; - - const {ast} = constantFolding('arbitrary.js', {code: before}); - expect(toString(ast)).toEqual(normalize(after)); + expect(normalize(constantFolding('arbitrary.js', parse(code)))).toEqual( + '{var a=3;var b=a+4;}', + ); }); it('can optimize nested if-else constructs', () => { - const before = ` + const code = ` if ('ios' === "android") { if (true) { require('a'); @@ -170,16 +120,8 @@ describe('constant expressions', () => { } } `; - - const after = ` - { - { - require('c'); - } - } - `; - - const {ast} = constantFolding('arbitrary.js', {code: before}); - expect(toString(ast)).toEqual(normalize(after)); + expect(normalize(constantFolding('arbitrary.js', parse(code)))).toEqual( + "{{require('c');}}", + ); }); }); diff --git a/packages/metro-bundler/src/JSTransformer/worker/__tests__/worker-test.js b/packages/metro-bundler/src/JSTransformer/worker/__tests__/worker-test.js index a021c4d7..da0aa494 100644 --- a/packages/metro-bundler/src/JSTransformer/worker/__tests__/worker-test.js +++ b/packages/metro-bundler/src/JSTransformer/worker/__tests__/worker-test.js @@ -14,8 +14,7 @@ jest .mock('../constant-folding') .mock('../extract-dependencies') .mock('../inline') - .mock('../minify') - .mock('../regenerator-insertion'); + .mock('../minify'); const {objectContaining} = jasmine; @@ -235,28 +234,19 @@ describe('code transformation worker:', () => { }); describe('Minifications:', () => { - let constantFolding, inline, regeneratorInsertion; - let options; + let constantFolding, inline, options; let transformResult, dependencyData; - const filename = 'arbitrary/file.js'; - const resultCode = 'arbitrary(result(code));'; - const resultMap = {version: 3, sources: ['abritrary/file.js']}; - - const result = { - ast: {}, - code: resultCode, - map: resultMap, - }; + const foldedCode = 'arbitrary(folded(code));'; + const foldedMap = {version: 3, sources: ['fold.js']}; beforeEach(() => { + constantFolding = require('../constant-folding').mockReturnValue({ + code: foldedCode, + map: foldedMap, + }); extractDependencies = require('../extract-dependencies'); - - constantFolding = require('../constant-folding').mockReturnValue(result); - inline = require('../inline').mockReturnValue(result); - regeneratorInsertion = require('../regenerator-insertion').mockReturnValue( - result, - ); + inline = require('../inline'); options = {minify: true, transform: {generateSourceMaps: true}}; dependencyData = { @@ -265,32 +255,18 @@ describe('code transformation worker:', () => { }; extractDependencies.mockImplementation( - code => (code === resultCode ? dependencyData : {}), + code => (code === foldedCode ? dependencyData : {}), ); - transformer.transform.mockImplementation((src, fileName, _) => result); + transformer.transform.mockImplementation( + (src, fileName, _) => transformResult, + ); }); - it('passes the transform result to `regenerator-insertion` for adding regeneratorRuntime', done => { + it('passes the transform result to `inline` for constant inlining', done => { + transformResult = {map: {version: 3}, code: 'arbitrary(code)'}; transformCode(transformer, filename, filename, 'code', options, () => { - expect(regeneratorInsertion).toBeCalledWith(filename, result, options); - done(); - }); - }); - - it('passes the result obtained from `regenerator-insertion` on to `inline`', done => { - const regeneratorInsertionResult = { - map: {version: 3, sources: []}, - ast: {}, - }; - regeneratorInsertion.mockReturnValue(regeneratorInsertionResult); - - transformCode(transformer, filename, filename, 'code', options, () => { - expect(inline).toBeCalledWith( - filename, - regeneratorInsertionResult, - options, - ); + expect(inline).toBeCalledWith(filename, transformResult, options); done(); }); }); @@ -298,16 +274,15 @@ describe('code transformation worker:', () => { it('passes the result obtained from `inline` on to `constant-folding`', done => { const inlineResult = {map: {version: 3, sources: []}, ast: {}}; inline.mockReturnValue(inlineResult); - transformCode(transformer, filename, filename, 'code', options, () => { - expect(constantFolding).toBeCalledWith(filename, inlineResult, options); + expect(constantFolding).toBeCalledWith(filename, inlineResult); done(); }); }); - it('Uses the code obtained from the last plugin to extract dependencies', done => { + it('Uses the code obtained from `constant-folding` to extract dependencies', done => { transformCode(transformer, filename, filename, 'code', options, () => { - expect(extractDependencies).toBeCalledWith(resultCode); + expect(extractDependencies).toBeCalledWith(foldedCode); done(); }); }); @@ -327,7 +302,7 @@ describe('code transformation worker:', () => { ); }); - it('uses data produced by the last plugin for the result', done => { + it('uses data produced by `constant-folding` for the result', done => { transformCode( transformer, 'filename', @@ -336,7 +311,7 @@ describe('code transformation worker:', () => { options, (_, data) => { expect(data.result).toEqual( - objectContaining({code: resultCode, map: resultMap}), + objectContaining({code: foldedCode, map: foldedMap}), ); done(); }, diff --git a/packages/metro-bundler/src/JSTransformer/worker/constant-folding.js b/packages/metro-bundler/src/JSTransformer/worker/constant-folding.js index d1b473c0..46597935 100644 --- a/packages/metro-bundler/src/JSTransformer/worker/constant-folding.js +++ b/packages/metro-bundler/src/JSTransformer/worker/constant-folding.js @@ -13,9 +13,8 @@ 'use strict'; const babel = require('babel-core'); -const invariant = require('fbjs/lib/invariant'); -import type {IntermediateTransformResult} from './types.flow'; +import type {Ast, SourceMap as MappingsMap} from 'babel-core'; const t = babel.types; const Conditional = { @@ -32,7 +31,7 @@ const Conditional = { }, }; -const constantFoldingPlugin = { +const plugin = { visitor: { BinaryExpression: { exit(path) { @@ -72,32 +71,25 @@ const constantFoldingPlugin = { }, }; -const plugin = () => constantFoldingPlugin; - function constantFolding( filename: string, - transformResult: IntermediateTransformResult, - options: {+dev: boolean, +platform: ?string}, -): IntermediateTransformResult { - const code = transformResult.code; - const babelOptions = { + transformResult: { + ast: Ast, + code?: ?string, + map: ?MappingsMap, + }, +) { + return babel.transformFromAst(transformResult.ast, transformResult.code, { filename, - plugins: [[plugin, options]], + plugins: [plugin], inputSourceMap: transformResult.map, sourceMaps: true, sourceFileName: filename, - code: true, babelrc: false, compact: true, - }; - - const result = transformResult.ast - ? babel.transformFromAst(transformResult.ast, code, babelOptions) - : (code && babel.transform(code, babelOptions)) || {}; - const {ast} = result; - invariant(ast != null, 'Missing AST in babel transform results.'); - return {ast, code: result.code, map: result.map}; + retainLines: true, + }); } -constantFolding.plugin = constantFoldingPlugin; +constantFolding.plugin = plugin; module.exports = constantFolding; diff --git a/packages/metro-bundler/src/JSTransformer/worker/index.js b/packages/metro-bundler/src/JSTransformer/worker/index.js index 478fa952..914e7b0d 100644 --- a/packages/metro-bundler/src/JSTransformer/worker/index.js +++ b/packages/metro-bundler/src/JSTransformer/worker/index.js @@ -22,8 +22,7 @@ const minify = require('./minify'); import type {LogEntry} from '../../Logger/Types'; import type {MappingsMap} from '../../lib/SourceMap'; import type {LocalPath} from '../../node-haste/lib/toLocalPath'; -import type {IntermediateTransformResult} from './types.flow'; -import type {Plugins as BabelPlugins} from 'babel-core'; +import type {Ast, Plugins as BabelPlugins} from 'babel-core'; export type TransformedCode = { code: string, @@ -39,7 +38,7 @@ export type Transformer = { options: ExtraOptions & TransformOptions, plugins?: BabelPlugins, src: string, - |}) => IntermediateTransformResult, + |}) => {ast: ?Ast, code: string, map: ?MappingsMap}, getCacheKey: () => string, }; @@ -84,8 +83,6 @@ type TransformCode = ( Callback, ) => void; -const transformers = [inline, constantFolding]; - const transformCode: TransformCode = asyncify( ( transformer: Transformer<*>, @@ -124,29 +121,17 @@ const transformCode: TransformCode = asyncify( 'Missing transform results despite having no error.', ); - let code; - let map; - + var code, map; if (options.minify) { - let result = transformed; - const length = transformers.length; - - for (let i = 0; i < length; i++) { - result = transformers[i](filename, result, options); - } - - ({code, map} = result); + ({code, map} = constantFolding( + filename, + inline(filename, transformed, options), + )); + invariant(code != null, 'Missing code from constant-folding transform.'); } else { ({code, map} = transformed); } - invariant( - code != null, - 'The last transformer on the list (' + - transformers[transformers.length - 1].name + - ') has to output code', - ); - if (isJson) { code = code.replace(/^\w+\.exports=/, ''); } else { diff --git a/packages/metro-bundler/src/JSTransformer/worker/inline.js b/packages/metro-bundler/src/JSTransformer/worker/inline.js index 6ea73726..57ce5f01 100644 --- a/packages/metro-bundler/src/JSTransformer/worker/inline.js +++ b/packages/metro-bundler/src/JSTransformer/worker/inline.js @@ -15,7 +15,7 @@ const babel = require('babel-core'); const invariant = require('fbjs/lib/invariant'); -import type {IntermediateTransformResult} from './types.flow'; +import type {Ast, SourceMap as MappingsMap} from 'babel-core'; const t = babel.types; const React = {name: 'React'}; @@ -115,16 +115,6 @@ function findProperty(objectExpression, key, fallback) { return property ? property.value : fallback(); } -function checkRequireArgs(args, dependencyId) { - const pattern = t.stringLiteral(dependencyId); - return ( - t.isStringLiteral(args[0], pattern) || - (t.isMemberExpression(args[0]) && - t.isNumericLiteral(args[0].property) && - t.isStringLiteral(args[1], pattern)) - ); -} - const inlinePlugin = { visitor: { Identifier(path, state) { @@ -172,11 +162,27 @@ const inlinePlugin = { const plugin = () => inlinePlugin; +function checkRequireArgs(args, dependencyId) { + const pattern = t.stringLiteral(dependencyId); + return ( + t.isStringLiteral(args[0], pattern) || + (t.isMemberExpression(args[0]) && + t.isNumericLiteral(args[0].property) && + t.isStringLiteral(args[1], pattern)) + ); +} + +type AstResult = { + ast: Ast, + code: ?string, + map: ?MappingsMap, +}; + function inline( filename: string, - transformResult: IntermediateTransformResult, + transformResult: {ast?: ?Ast, code: string, map: ?MappingsMap}, options: {+dev: boolean, +platform: ?string}, -): IntermediateTransformResult { +): AstResult { const code = transformResult.code; const babelOptions = { filename, @@ -191,7 +197,7 @@ function inline( const result = transformResult.ast ? babel.transformFromAst(transformResult.ast, code, babelOptions) - : (code && babel.transform(code, babelOptions)) || {}; + : babel.transform(code, babelOptions); const {ast} = result; invariant(ast != null, 'Missing AST in babel transform results.'); return {ast, code: result.code, map: result.map}; diff --git a/packages/metro-bundler/src/JSTransformer/worker/types.flow.js b/packages/metro-bundler/src/JSTransformer/worker/types.flow.js deleted file mode 100644 index 2fe73d85..00000000 --- a/packages/metro-bundler/src/JSTransformer/worker/types.flow.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @flow - * @format - */ - -'use strict'; - -import type {Ast, SourceMap as MappingsMap} from 'babel-core'; - -export type IntermediateTransformResult = { - ast: ?Ast, - code: ?string, - map: ?MappingsMap, -};