mirror of https://github.com/status-im/metro.git
metro-bundler: ModuleGraph tests: @flow
Summary: Having types in tests ensure that we're testing what the API is supposed to process and not something else. In that case, adding type revealed that we were mistakenly passing strings instead of `Buffer` objects to the transform and optimize functions, but it would still work because `toString` was called over it. Passing proper `Buffer` objects as expected ensures that it doesn't just work with strings, and that the integration of these files in the rest of the application works as expected. This changeset fixes these callsites and add a few invariants here and there. We use `invariant` instead of `expect()` because Flow understands only the former as a type refinement, even though `expect` would also be a form of possible refinement. I don't think it's a big deal. Reviewed By: davidaurelio Differential Revision: D6160019 fbshipit-source-id: cbcbb05d7bccf9e1b9f6bb3ea30b0bb2925aef1b
This commit is contained in:
parent
c293f4bfab
commit
bada7f8684
|
@ -150,7 +150,7 @@ export type TransformResult = {|
|
||||||
|
|
||||||
export type TransformResults = {[string]: TransformResult};
|
export type TransformResults = {[string]: TransformResult};
|
||||||
|
|
||||||
export type TransformVariants = {+[name: string]: {}, +default: {}};
|
export type TransformVariants = {+[name: string]: {}};
|
||||||
|
|
||||||
export type TransformedCodeFile = {|
|
export type TransformedCodeFile = {|
|
||||||
+file: string,
|
+file: string,
|
||||||
|
|
|
@ -6,8 +6,9 @@
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* 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.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
*
|
*
|
||||||
* @format
|
|
||||||
* @emails oncall+javascript_foundation
|
* @emails oncall+javascript_foundation
|
||||||
|
* @flow
|
||||||
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
|
@ -6,17 +6,21 @@
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* 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.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
*
|
*
|
||||||
* @format
|
|
||||||
* @emails oncall+javascript_foundation
|
* @emails oncall+javascript_foundation
|
||||||
|
* @flow
|
||||||
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const invariant = require('fbjs/lib/invariant');
|
||||||
|
const nullthrows = require('fbjs/lib/nullthrows');
|
||||||
const optimizeModule = require('../optimize-module');
|
const optimizeModule = require('../optimize-module');
|
||||||
const transformModule = require('../transform-module');
|
const transformModule = require('../transform-module');
|
||||||
const transformer = require('../../../transformer.js');
|
const transformer = require('../../../transformer.js');
|
||||||
const {SourceMapConsumer} = require('source-map');
|
|
||||||
const {fn} = require('../../test-helpers');
|
const {fn} = require('../../test-helpers');
|
||||||
|
const {SourceMapConsumer} = require('source-map');
|
||||||
|
|
||||||
const {objectContaining} = jasmine;
|
const {objectContaining} = jasmine;
|
||||||
|
|
||||||
|
@ -27,21 +31,27 @@ describe('optimizing JS modules', () => {
|
||||||
platform: 'android',
|
platform: 'android',
|
||||||
postMinifyProcess: x => x,
|
postMinifyProcess: x => x,
|
||||||
};
|
};
|
||||||
const originalCode = `if (Platform.OS !== 'android') {
|
const originalCode = new Buffer(
|
||||||
|
`if (Platform.OS !== 'android') {
|
||||||
require('arbitrary-dev');
|
require('arbitrary-dev');
|
||||||
} else {
|
} else {
|
||||||
__DEV__ ? require('arbitrary-android-dev') : require('arbitrary-android-prod');
|
__DEV__ ? require('arbitrary-android-dev') : require('arbitrary-android-prod');
|
||||||
}`;
|
}`,
|
||||||
|
'utf8',
|
||||||
|
);
|
||||||
|
|
||||||
let transformResult;
|
let transformResult;
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
const result = transformModule(originalCode, {filename, transformer});
|
const result = transformModule(originalCode, {filename, transformer});
|
||||||
transformResult = JSON.stringify({type: 'code', details: result.details});
|
transformResult = new Buffer(
|
||||||
|
JSON.stringify({type: 'code', details: result.details}),
|
||||||
|
'utf8',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('copies everything from the transformed file, except for transform results', () => {
|
it('copies everything from the transformed file, except for transform results', () => {
|
||||||
const result = optimizeModule(transformResult, optimizationOptions);
|
const result = optimizeModule(transformResult, optimizationOptions);
|
||||||
const expected = JSON.parse(transformResult).details;
|
const expected = JSON.parse(transformResult.toString('utf8')).details;
|
||||||
delete expected.transformed;
|
delete expected.transformed;
|
||||||
expect(result.type).toBe('code');
|
expect(result.type).toBe('code');
|
||||||
expect(result.details).toEqual(objectContaining(expected));
|
expect(result.details).toEqual(objectContaining(expected));
|
||||||
|
@ -51,14 +61,19 @@ describe('optimizing JS modules', () => {
|
||||||
let dependencyMapName, injectedVars, optimized, requireName;
|
let dependencyMapName, injectedVars, optimized, requireName;
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
const result = optimizeModule(transformResult, optimizationOptions);
|
const result = optimizeModule(transformResult, optimizationOptions);
|
||||||
|
invariant(result.type === 'code', 'result must be code');
|
||||||
optimized = result.details.transformed.default;
|
optimized = result.details.transformed.default;
|
||||||
injectedVars = optimized.code.match(/function\(([^)]*)/)[1].split(',');
|
injectedVars = nullthrows(
|
||||||
|
optimized.code.match(/function\(([^)]*)/),
|
||||||
|
)[1].split(',');
|
||||||
[, requireName, , , dependencyMapName] = injectedVars;
|
[, requireName, , , dependencyMapName] = injectedVars;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('optimizes code', () => {
|
it('optimizes code', () => {
|
||||||
expect(optimized.code).toEqual(
|
expect(optimized.code).toEqual(
|
||||||
`__d(function(${injectedVars}){${requireName}(${dependencyMapName}[0])});`,
|
`__d(function(${injectedVars.join(
|
||||||
|
',',
|
||||||
|
)}){${requireName}(${dependencyMapName}[0])});`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -69,7 +84,9 @@ describe('optimizing JS modules', () => {
|
||||||
it('creates source maps', () => {
|
it('creates source maps', () => {
|
||||||
const consumer = new SourceMapConsumer(optimized.map);
|
const consumer = new SourceMapConsumer(optimized.map);
|
||||||
const column = optimized.code.lastIndexOf(requireName + '(');
|
const column = optimized.code.lastIndexOf(requireName + '(');
|
||||||
const loc = findLast(originalCode, 'require');
|
const loc = nullthrows(
|
||||||
|
findLast(originalCode.toString('utf8'), 'require'),
|
||||||
|
);
|
||||||
|
|
||||||
expect(consumer.originalPositionFor({line: 1, column})).toEqual(
|
expect(consumer.originalPositionFor({line: 1, column})).toEqual(
|
||||||
objectContaining(loc),
|
objectContaining(loc),
|
||||||
|
@ -80,8 +97,9 @@ describe('optimizing JS modules', () => {
|
||||||
const result = optimizeModule(transformResult, {
|
const result = optimizeModule(transformResult, {
|
||||||
...optimizationOptions,
|
...optimizationOptions,
|
||||||
isPolyfill: true,
|
isPolyfill: true,
|
||||||
}).details;
|
});
|
||||||
expect(result.transformed.default.dependencies).toEqual([]);
|
invariant(result.type === 'code', 'result must be code');
|
||||||
|
expect(result.details.transformed.default.dependencies).toEqual([]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -99,6 +117,7 @@ describe('optimizing JS modules', () => {
|
||||||
it('passes the result to the provided postprocessing function', () => {
|
it('passes the result to the provided postprocessing function', () => {
|
||||||
postMinifyProcess.stub.callsFake(x => x);
|
postMinifyProcess.stub.callsFake(x => x);
|
||||||
const result = optimize();
|
const result = optimize();
|
||||||
|
invariant(result.type === 'code', 'result must be code');
|
||||||
const {code, map} = result.details.transformed.default;
|
const {code, map} = result.details.transformed.default;
|
||||||
expect(postMinifyProcess).toBeCalledWith({code, map});
|
expect(postMinifyProcess).toBeCalledWith({code, map});
|
||||||
});
|
});
|
||||||
|
@ -107,7 +126,9 @@ describe('optimizing JS modules', () => {
|
||||||
const code = 'var postprocessed = "code";';
|
const code = 'var postprocessed = "code";';
|
||||||
const map = {version: 3, mappings: 'postprocessed'};
|
const map = {version: 3, mappings: 'postprocessed'};
|
||||||
postMinifyProcess.stub.returns({code, map});
|
postMinifyProcess.stub.returns({code, map});
|
||||||
expect(optimize().details.transformed.default).toEqual(
|
const result = optimize();
|
||||||
|
invariant(result.type === 'code', 'result must be code');
|
||||||
|
expect(result.details.transformed.default).toEqual(
|
||||||
objectContaining({code, map}),
|
objectContaining({code, map}),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -116,7 +137,11 @@ describe('optimizing JS modules', () => {
|
||||||
it('passes through non-code data unmodified', () => {
|
it('passes through non-code data unmodified', () => {
|
||||||
const data = {type: 'asset', details: {arbitrary: 'data'}};
|
const data = {type: 'asset', details: {arbitrary: 'data'}};
|
||||||
expect(
|
expect(
|
||||||
optimizeModule(JSON.stringify(data), {dev: true, platform: ''}),
|
optimizeModule(new Buffer(JSON.stringify(data), 'utf8'), {
|
||||||
|
dev: true,
|
||||||
|
platform: '',
|
||||||
|
postMinifyProcess: ({code, map}) => ({code, map}),
|
||||||
|
}),
|
||||||
).toEqual(data);
|
).toEqual(data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,21 +6,26 @@
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* 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.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
*
|
*
|
||||||
* @format
|
|
||||||
* @emails oncall+javascript_foundation
|
* @emails oncall+javascript_foundation
|
||||||
|
* @flow
|
||||||
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const invariant = require('fbjs/lib/invariant');
|
||||||
|
const nullthrows = require('fbjs/lib/nullthrows');
|
||||||
|
const t = require('babel-types');
|
||||||
const transformModule = require('../transform-module');
|
const transformModule = require('../transform-module');
|
||||||
|
|
||||||
const t = require('babel-types');
|
|
||||||
const {SourceMapConsumer} = require('source-map');
|
|
||||||
const {fn} = require('../../test-helpers');
|
const {fn} = require('../../test-helpers');
|
||||||
const {parse} = require('babylon');
|
const {parse} = require('babylon');
|
||||||
|
const {SourceMapConsumer} = require('source-map');
|
||||||
const generate = require('babel-generator').default;
|
const generate = require('babel-generator').default;
|
||||||
const {traverse} = require('babel-core');
|
const {traverse} = require('babel-core');
|
||||||
|
|
||||||
|
import type {TransformVariants} from '../../types.flow';
|
||||||
|
|
||||||
jest.mock('image-size', () => buffer => {
|
jest.mock('image-size', () => buffer => {
|
||||||
return JSON.parse(buffer.toString('utf8')).__size;
|
return JSON.parse(buffer.toString('utf8')).__size;
|
||||||
});
|
});
|
||||||
|
@ -33,13 +38,14 @@ describe('transforming JS modules:', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
transformer = {
|
transformer = {
|
||||||
transform: fn(),
|
transform: fn(),
|
||||||
|
getCacheKey: () => 'foo',
|
||||||
};
|
};
|
||||||
transformer.transform.stub.returns(transformResult());
|
transformer.transform.stub.returns(transformResult());
|
||||||
});
|
});
|
||||||
|
|
||||||
const {bodyAst, sourceCode, transformedCode} = createTestData();
|
const {bodyAst, sourceCode, transformedCode} = createTestData();
|
||||||
|
|
||||||
const options = variants => ({
|
const options = (variants?: TransformVariants) => ({
|
||||||
filename,
|
filename,
|
||||||
transformer,
|
transformer,
|
||||||
variants,
|
variants,
|
||||||
|
@ -61,7 +67,7 @@ describe('transforming JS modules:', () => {
|
||||||
|
|
||||||
it('exposes a haste ID if present', () => {
|
it('exposes a haste ID if present', () => {
|
||||||
const hasteID = 'TheModule';
|
const hasteID = 'TheModule';
|
||||||
const codeWithHasteID = `/** @providesModule ${hasteID} */`;
|
const codeWithHasteID = toBuffer(`/** @providesModule ${hasteID} */`);
|
||||||
const result = transformModule(codeWithHasteID, options());
|
const result = transformModule(codeWithHasteID, options());
|
||||||
expect(result.type).toBe('code');
|
expect(result.type).toBe('code');
|
||||||
expect(result.details).toEqual(expect.objectContaining({hasteID}));
|
expect(result.details).toEqual(expect.objectContaining({hasteID}));
|
||||||
|
@ -88,27 +94,23 @@ describe('transforming JS modules:', () => {
|
||||||
projectRoot: '',
|
projectRoot: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
it(
|
it('calls the passed-in transform function with code, file name, and options for all passed in variants', () => {
|
||||||
'calls the passed-in transform function with code, file name, and options ' +
|
const variants = {dev: {dev: true}, prod: {dev: false}};
|
||||||
'for all passed in variants',
|
|
||||||
() => {
|
|
||||||
const variants = {dev: {dev: true}, prod: {dev: false}};
|
|
||||||
|
|
||||||
transformModule(sourceCode, options(variants));
|
transformModule(sourceCode, options(variants));
|
||||||
expect(transformer.transform).toBeCalledWith({
|
expect(transformer.transform).toBeCalledWith({
|
||||||
filename,
|
filename,
|
||||||
localPath: filename,
|
localPath: filename,
|
||||||
options: {...defaults, ...variants.dev},
|
options: {...defaults, ...variants.dev},
|
||||||
src: sourceCode,
|
src: sourceCode.toString('utf8'),
|
||||||
});
|
});
|
||||||
expect(transformer.transform).toBeCalledWith({
|
expect(transformer.transform).toBeCalledWith({
|
||||||
filename,
|
filename,
|
||||||
localPath: filename,
|
localPath: filename,
|
||||||
options: {...defaults, ...variants.prod},
|
options: {...defaults, ...variants.prod},
|
||||||
src: sourceCode,
|
src: sourceCode.toString('utf8'),
|
||||||
});
|
});
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
it('calls back with any error yielded by the transform function', () => {
|
it('calls back with any error yielded by the transform function', () => {
|
||||||
const error = new Error();
|
const error = new Error();
|
||||||
|
@ -124,7 +126,9 @@ describe('transforming JS modules:', () => {
|
||||||
it('wraps the code produced by the transform function into a module factory', () => {
|
it('wraps the code produced by the transform function into a module factory', () => {
|
||||||
const result = transformModule(sourceCode, options());
|
const result = transformModule(sourceCode, options());
|
||||||
|
|
||||||
|
invariant(result.type === 'code', 'result must be code');
|
||||||
const {code, dependencyMapName} = result.details.transformed.default;
|
const {code, dependencyMapName} = result.details.transformed.default;
|
||||||
|
invariant(dependencyMapName != null, 'dependencyMapName cannot be null');
|
||||||
expect(code.replace(/\s+/g, '')).toEqual(
|
expect(code.replace(/\s+/g, '')).toEqual(
|
||||||
`__d(function(global,require,module,exports,${dependencyMapName}){${transformedCode}});`,
|
`__d(function(global,require,module,exports,${dependencyMapName}){${transformedCode}});`,
|
||||||
);
|
);
|
||||||
|
@ -132,6 +136,7 @@ describe('transforming JS modules:', () => {
|
||||||
|
|
||||||
it('wraps the code produced by the transform function into an IIFE for polyfills', () => {
|
it('wraps the code produced by the transform function into an IIFE for polyfills', () => {
|
||||||
const result = transformModule(sourceCode, {...options(), polyfill: true});
|
const result = transformModule(sourceCode, {...options(), polyfill: true});
|
||||||
|
invariant(result.type === 'code', 'result must be code');
|
||||||
const {code} = result.details.transformed.default;
|
const {code} = result.details.transformed.default;
|
||||||
expect(code.replace(/\s+/g, '')).toEqual(
|
expect(code.replace(/\s+/g, '')).toEqual(
|
||||||
`(function(global){${transformedCode}})(this);`,
|
`(function(global){${transformedCode}})(this);`,
|
||||||
|
@ -140,6 +145,7 @@ describe('transforming JS modules:', () => {
|
||||||
|
|
||||||
it('creates source maps', () => {
|
it('creates source maps', () => {
|
||||||
const result = transformModule(sourceCode, options());
|
const result = transformModule(sourceCode, options());
|
||||||
|
invariant(result.type === 'code', 'result must be code');
|
||||||
const {code, map} = result.details.transformed.default;
|
const {code, map} = result.details.transformed.default;
|
||||||
const position = findColumnAndLine(code, 'code');
|
const position = findColumnAndLine(code, 'code');
|
||||||
expect(position).not.toBeNull();
|
expect(position).not.toBeNull();
|
||||||
|
@ -157,7 +163,8 @@ describe('transforming JS modules:', () => {
|
||||||
const {body} = parse(code).program;
|
const {body} = parse(code).program;
|
||||||
transformer.transform.stub.returns(transformResult(body));
|
transformer.transform.stub.returns(transformResult(body));
|
||||||
|
|
||||||
const result = transformModule(code, options());
|
const result = transformModule(toBuffer(code), options());
|
||||||
|
invariant(result.type === 'code', 'result must be code');
|
||||||
expect(result.details.transformed.default).toEqual(
|
expect(result.details.transformed.default).toEqual(
|
||||||
expect.objectContaining({dependencies: [dep1, dep2]}),
|
expect.objectContaining({dependencies: [dep1, dep2]}),
|
||||||
);
|
);
|
||||||
|
@ -172,19 +179,28 @@ describe('transforming JS modules:', () => {
|
||||||
.returns(transformResult([]));
|
.returns(transformResult([]));
|
||||||
|
|
||||||
const result = transformModule(sourceCode, options(variants));
|
const result = transformModule(sourceCode, options(variants));
|
||||||
|
invariant(result.type === 'code', 'result must be code');
|
||||||
const {dev, prod} = result.details.transformed;
|
const {dev, prod} = result.details.transformed;
|
||||||
expect(dev.code.replace(/\s+/g, '')).toEqual(
|
expect(dev.code.replace(/\s+/g, '')).toEqual(
|
||||||
`__d(function(global,require,module,exports,${dev.dependencyMapName}){arbitrary(code);});`,
|
`__d(function(global,require,module,exports,${nullthrows(
|
||||||
|
dev.dependencyMapName,
|
||||||
|
)}){arbitrary(code);});`,
|
||||||
);
|
);
|
||||||
expect(prod.code.replace(/\s+/g, '')).toEqual(
|
expect(prod.code.replace(/\s+/g, '')).toEqual(
|
||||||
`__d(function(global,require,module,exports,${prod.dependencyMapName}){arbitrary(code);});`,
|
`__d(function(global,require,module,exports,${nullthrows(
|
||||||
|
prod.dependencyMapName,
|
||||||
|
)}){arbitrary(code);});`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('prefixes JSON files with `module.exports = `', () => {
|
it('prefixes JSON files with `module.exports = `', () => {
|
||||||
const json = '{"foo":"bar"}';
|
const json = '{"foo":"bar"}';
|
||||||
|
|
||||||
const result = transformModule(json, {...options(), filename: 'some.json'});
|
const result = transformModule(toBuffer(json), {
|
||||||
|
...options(),
|
||||||
|
filename: 'some.json',
|
||||||
|
});
|
||||||
|
invariant(result.type === 'code', 'result must be code');
|
||||||
const {code} = result.details.transformed.default;
|
const {code} = result.details.transformed.default;
|
||||||
expect(code.replace(/\s+/g, '')).toEqual(
|
expect(code.replace(/\s+/g, '')).toEqual(
|
||||||
'__d(function(global,require,module,exports){' +
|
'__d(function(global,require,module,exports){' +
|
||||||
|
@ -193,7 +209,11 @@ describe('transforming JS modules:', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not create source maps for JSON files', () => {
|
it('does not create source maps for JSON files', () => {
|
||||||
const result = transformModule('{}', {...options(), filename: 'some.json'});
|
const result = transformModule(toBuffer('{}'), {
|
||||||
|
...options(),
|
||||||
|
filename: 'some.json',
|
||||||
|
});
|
||||||
|
invariant(result.type === 'code', 'result must be code');
|
||||||
expect(result.details.transformed.default).toEqual(
|
expect(result.details.transformed.default).toEqual(
|
||||||
expect.objectContaining({map: null}),
|
expect.objectContaining({map: null}),
|
||||||
);
|
);
|
||||||
|
@ -207,10 +227,11 @@ describe('transforming JS modules:', () => {
|
||||||
'react-native': {'react-native': 'defs'},
|
'react-native': {'react-native': 'defs'},
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = transformModule(JSON.stringify(pkg), {
|
const result = transformModule(toBuffer(JSON.stringify(pkg)), {
|
||||||
...options(),
|
...options(),
|
||||||
filename: 'arbitrary/package.json',
|
filename: 'arbitrary/package.json',
|
||||||
});
|
});
|
||||||
|
invariant(result.type === 'code', 'result must be code');
|
||||||
expect(result.details.package).toEqual(pkg);
|
expect(result.details.package).toEqual(pkg);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -219,7 +240,7 @@ describe('transforming JS modules:', () => {
|
||||||
const image = {__size: {width: 30, height: 20}};
|
const image = {__size: {width: 30, height: 20}};
|
||||||
['foo.png', 'foo@2x.ios.png'].forEach(filePath => {
|
['foo.png', 'foo@2x.ios.png'].forEach(filePath => {
|
||||||
expect(
|
expect(
|
||||||
transformModule(new Buffer(JSON.stringify(image), 'utf8'), {
|
transformModule(toBuffer(JSON.stringify(image)), {
|
||||||
...options(),
|
...options(),
|
||||||
filename: filePath,
|
filename: filePath,
|
||||||
}),
|
}),
|
||||||
|
@ -249,7 +270,7 @@ function createTestData() {
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
bodyAst: fileAst.program.body,
|
bodyAst: fileAst.program.body,
|
||||||
sourceCode,
|
sourceCode: toBuffer(sourceCode),
|
||||||
transformedCode: generate(fileAst).code,
|
transformedCode: generate(fileAst).code,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -265,3 +286,7 @@ function findColumnAndLine(text, string) {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toBuffer(str) {
|
||||||
|
return new Buffer(str, 'utf8');
|
||||||
|
}
|
||||||
|
|
|
@ -6,8 +6,9 @@
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* 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.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
*
|
*
|
||||||
* @format
|
|
||||||
* @emails oncall+javascript_foundation
|
* @emails oncall+javascript_foundation
|
||||||
|
* @flow
|
||||||
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
Loading…
Reference in New Issue