initial commit

This commit is contained in:
2026-03-22 03:21:45 +02:00
commit 897fea9f4e
15431 changed files with 2548840 additions and 0 deletions

View File

@@ -0,0 +1,473 @@
/**
* Copyright 2013-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.
* @emails jeffmo@fb.com
*/
require('mock-modules').autoMockOff();
describe('jstransform', function() {
var transformFn;
var Syntax = require('esprima-fb').Syntax;
beforeEach(function() {
require('mock-modules').dumpCache();
transformFn = require('../jstransform').transform;
});
function _runVisitor(source, nodeCount, visitor) {
var actualVisitationCount = 0;
function shimVisitor(traverse, node, path, state) {
actualVisitationCount++;
return visitor(traverse, node, path, state);
}
shimVisitor.test = visitor.test;
transformFn([shimVisitor], source);
expect(actualVisitationCount).toBe(nodeCount);
}
function testScopeBoundary(source, localIdents, nodeCount, visitorTest) {
function visitor(traverse, node, path, state) {
var actualLocalIdents = Object.keys(state.localScope.identifiers);
expect(actualLocalIdents.sort()).toEqual(localIdents.sort());
}
visitor.test = visitorTest;
_runVisitor(source, nodeCount, visitor);
}
function testParentScope(source, parentIdents, nodeCount, visitorTest) {
function visitor(traverse, node, path, state) {
parentIdents = parentIdents && parentIdents.sort();
var parentScope = state.localScope.parentScope;
var actualParentIdents =
parentScope && Object.keys(parentScope.identifiers).sort();
expect(actualParentIdents).toEqual(parentIdents);
}
visitor.test = visitorTest;
_runVisitor(source, nodeCount, visitor);
}
describe('closure scope boundaries', function() {
it('creates a scope boundary around Program scope', function() {
var source =
'var foo;' +
'var bar, baz;' +
'function blah() {}';
var idents = ['foo', 'bar', 'baz', 'blah'];
testScopeBoundary(source, idents, 3, function(node, path) {
return path[0] && path[0].type === Syntax.Program;
});
});
it('creates a scope boundary around FunctionDeclarations', function() {
var source =
'var foo;' +
'function blah() {' +
' var bar;' +
' function nested() {' +
' var baz;' +
' }' +
'}';
var programIdents = ['foo', 'blah'];
var blahIdents = ['arguments', 'bar', 'nested'];
var nestedIdents = ['arguments', 'baz'];
testScopeBoundary(source, programIdents, 2, function(node, path) {
return path[0] && path[0].type === Syntax.Program;
});
testScopeBoundary(source, blahIdents, 2, function(node, path) {
// All direct children of blah()
return path[0] && path[0].type === Syntax.BlockStatement &&
path[1] && path[1].type === Syntax.FunctionDeclaration &&
path[1].id.name === 'blah';
});
testScopeBoundary(source, nestedIdents, 1, function(node, path) {
// All direct children of nested()
return path[0] && path[0].type === Syntax.BlockStatement &&
path[1] && path[1].type === Syntax.FunctionDeclaration &&
path[1].id.name === 'nested';
});
});
it('creates a scope boundary around MethodDefinitions', function() {
var source =
'var foo;' +
'class ClassA {' +
' blah() {' +
' var bar;' +
' }' +
' another() {' +
' var baz;' +
' }' +
'}';
var programIdents = ['foo', 'ClassA'];
var blahIdents = ['arguments', 'bar'];
var anotherIdents = ['arguments', 'baz'];
testScopeBoundary(source, programIdents, 2, function(node, path) {
return path[0] && path[0].type === Syntax.Program;
});
testScopeBoundary(source, blahIdents, 1, function(node, path) {
// All direct children of blah()
return path[0] && path[0].type === Syntax.BlockStatement &&
path[1] && path[1].type === Syntax.FunctionExpression &&
path[2] && path[2].type === Syntax.MethodDefinition &&
path[2].key.name === 'blah';
});
testScopeBoundary(source, anotherIdents, 1, function(node, path) {
// All direct children of another()
return path[0] && path[0].type === Syntax.BlockStatement &&
path[1] && path[1].type === Syntax.FunctionExpression &&
path[2] && path[2].type === Syntax.MethodDefinition &&
path[2].key.name === 'another';
});
});
it('creates a scope boundary around concise ArrowFunc exprs', function() {
var source =
'var foo;' +
'var bar = baz => baz;';
var programIdents = ['foo', 'bar'];
var barIdents = ['arguments', 'baz'];
testScopeBoundary(source, programIdents, 2, function(node, path) {
return path[0] && path[0].type === Syntax.Program;
});
testScopeBoundary(source, barIdents, 1, function(node, path) {
return path[0] && path[0].type === Syntax.ArrowFunctionExpression
&& path[0].body === node;
});
});
it('uses VariableDeclarations to determine scope boundary', function() {
var source =
'var foo = 1;' +
'function bar() {' +
' foo++;' +
' function baz() {' +
' var foo = 2;' +
' }' +
'}';
var programIdents = ['foo', 'bar'];
var barIdents = ['arguments', 'baz'];
var bazIdents = ['arguments', 'foo'];
testScopeBoundary(source, programIdents, 2, function(node, path) {
return path[0] && path[0].type === Syntax.Program;
});
testScopeBoundary(source, barIdents, 2, function(node, path) {
// All direct children of blah()
return path[0] && path[0].type === Syntax.BlockStatement &&
path[1] && path[1].type === Syntax.FunctionDeclaration &&
path[1].id.name === 'bar';
});
testScopeBoundary(source, bazIdents, 1, function(node, path) {
// All direct children of baz()
return path[0] && path[0].type === Syntax.BlockStatement &&
path[1] && path[1].type === Syntax.FunctionDeclaration &&
path[1].id.name === 'baz';
});
});
it('includes function args in functions scope boundary', function() {
var source =
'var foo;' +
'function blah(bar) {' +
' var baz;' +
'}' +
'var blah2 = bar2 => {var baz;};' +
'var blah3 = bar3 => bar3;';
var programIdents = ['foo', 'blah', 'blah2', 'blah3'];
var blahIdents = ['arguments', 'bar', 'baz'];
var blah2Idents = ['arguments', 'bar2', 'baz'];
var blah3Idents = ['arguments', 'bar3'];
testScopeBoundary(source, programIdents, 4, function(node, path) {
return path[0] && path[0].type === Syntax.Program;
});
testScopeBoundary(source, blahIdents, 1, function(node, path) {
// All direct children of blah()
return path[0] && path[0].type === Syntax.BlockStatement &&
path[1] && path[1].type === Syntax.FunctionDeclaration &&
path[1].id.name === 'blah';
});
testScopeBoundary(source, blah2Idents, 1, function(node, path) {
// All direct children of blah2()
return path[0] && path[0].type === Syntax.BlockStatement &&
path[1] && path[1].type === Syntax.ArrowFunctionExpression &&
path[2].id.name === 'blah2';
});
testScopeBoundary(source, blah3Idents, 1, function(node, path) {
// All direct children of blah3()
return path[0] && path[0].type === Syntax.ArrowFunctionExpression &&
path[0].body === node &&
path[1].id.name === 'blah3';
});
});
it('includes rest param args in function scope boundaries', function() {
var source =
'var foo;' +
'function blah(...bar) {' +
' var baz;' +
'}' +
'var blah2 = (...bar2) => {var baz;};' +
'var blah3 = (...bar3) => bar3;';
var programIdents = ['foo', 'blah', 'blah2', 'blah3'];
var blahIdents = ['arguments', 'bar', 'baz'];
var blah2Idents = ['arguments', 'bar2', 'baz'];
var blah3Idents = ['arguments', 'bar3'];
testScopeBoundary(source, programIdents, 4, function(node, path) {
return path[0] && path[0].type === Syntax.Program;
});
testScopeBoundary(source, blahIdents, 1, function(node, path) {
// All direct children of blah()
return path[0] && path[0].type === Syntax.BlockStatement &&
path[1] && path[1].type === Syntax.FunctionDeclaration &&
path[1].id.name === 'blah';
});
testScopeBoundary(source, blah2Idents, 1, function(node, path) {
// All direct children of blah2()
return path[0] && path[0].type === Syntax.BlockStatement &&
path[1] && path[1].type === Syntax.ArrowFunctionExpression &&
path[2].id.name === 'blah2';
});
testScopeBoundary(source, blah3Idents, 1, function(node, path) {
// All direct children of blah3()
return path[0] && path[0].type === Syntax.ArrowFunctionExpression &&
path[0].body === node &&
path[1].id.name === 'blah3';
});
});
it('puts FunctionExpression names within function scope', function() {
var source =
'var foo;' +
'var bar = function baz() {' +
' var blah;' +
'};';
var programIdents = ['foo', 'bar'];
var bazIdents = ['arguments', 'baz', 'blah'];
testScopeBoundary(source, programIdents, 2, function(node, path) {
return path[0] && path[0].type === Syntax.Program;
});
testScopeBoundary(source, bazIdents, 1, function(node, path) {
// All direct children of baz()
return path[0] && path[0].type === Syntax.BlockStatement &&
path[1] && path[1].type === Syntax.FunctionExpression &&
path[1].id.name === 'baz';
});
});
});
describe('block scope boundaries', function() {
it('creates a scope boundary around CatchClauses with params', function() {
var source =
'var blah = 0;' +
'try {' +
'} catch (e) {' +
' blah++;' +
'}';
var programIdents = ['blah'];
var catchIdents = ['e'];
testScopeBoundary(source, programIdents, 2, function(node, path) {
return path[0] && path[0].type === Syntax.Program;
});
testScopeBoundary(source, catchIdents, 1, function(node, path) {
// All direct children of catch(e) block
return path[0] && path[0].type === Syntax.BlockStatement &&
path[1] && path[1].type === Syntax.CatchClause;
});
});
it('includes vars defined in CatchClauses in the parent scope', function() {
var source =
'try {' +
'} catch (e) {' +
' var blah;' +
'}';
var programIdents = ['blah'];
var catchIdents = ['e'];
testScopeBoundary(source, programIdents, 1, function(node, path) {
return path[0] && path[0].type === Syntax.Program;
});
testScopeBoundary(source, catchIdents, 1, function(node, path) {
// All direct children of catch(e) block
return path[0] && path[0].type === Syntax.BlockStatement &&
path[1] && path[1].type === Syntax.CatchClause;
});
});
});
describe('scope chain linking', function() {
it('links parent scope boundaries', function() {
var source =
'var foo;' +
'function blah() {' +
' var bar;' +
' function nested() {' +
' var baz;' +
' }' +
'}';
var programIdents = ['foo', 'blah'];
var blahIdents = ['arguments', 'bar', 'nested'];
testParentScope(source, programIdents, 2, function(node, path) {
// All direct children of blah()
return path[0] && path[0].type === Syntax.BlockStatement &&
path[1] && path[1].type === Syntax.FunctionDeclaration &&
path[1].id.name === 'blah';
});
testParentScope(source, blahIdents, 1, function(node, path) {
// All direct children of nested()
return path[0] && path[0].type === Syntax.BlockStatement &&
path[1] && path[1].type === Syntax.FunctionDeclaration &&
path[1].id.name === 'nested';
});
});
it('nests MethodDefinition boundaries under parent scope', function() {
var source =
'var foo;' +
'class ClassA {' +
' blah() {' +
' var bar;' +
' }' +
'}';
var programIdents = ['foo', 'ClassA'];
testParentScope(source, programIdents, 1, function(node, path) {
// All direct children of blah()
return path[0] && path[0].type === Syntax.BlockStatement &&
path[1] && path[1].type === Syntax.FunctionExpression &&
path[2] && path[2].type === Syntax.MethodDefinition &&
path[2].key.name === 'blah';
});
});
});
describe('"use strict" tracking', function() {
function testStrictness(expectedStrict, source) {
var visitedNodes = 0;
function visitor(traverse, node, path, state) {
visitedNodes++;
expect(state.scopeIsStrict).toBe(expectedStrict);
}
visitor.test = function(node, path, state) {
return node.type === Syntax.Literal
&& node.value === 'testStr';
};
transformFn([visitor], source);
expect(visitedNodes).toBe(1);
}
it('detects program-level strictness', function() {
testStrictness(false, '"testStr";');
testStrictness(true, '"use strict"; "testStr";');
});
it('detects non-inherited strictness', function() {
testStrictness(true, [
'function foo() {',
' "use strict";',
' "testStr";',
'}'
].join('\n'));
});
it('detects program-inherited strictness', function() {
testStrictness(true, [
'"use strict";',
'function foo() {',
' "testStr";',
'}'
].join('\n'));
});
it('detects function-inherited strictness', function() {
testStrictness(true, [
'function foo() {',
' "use strict";',
' function bar() {',
' "testStr";',
' }',
'}'
].join('\n'));
});
it('does not detect sibling strictness', function() {
testStrictness(false, [
'function foo() {',
' "use strict";',
'}',
'function bar() {',
' "testStr";',
'}'
].join('\n'));
});
});
describe('visitors', function() {
it('should visit nodes in order', function() {
var source = [
'// Foo comment',
'function foo() {}',
'',
'// Bar comment',
'function bar() {}'
].join('\n');
var actualNodes = [];
function visitFunction(traverse, node, path, state) {
actualNodes.push([node.id.name, node.range[0]]);
}
visitFunction.test = function(node, path, state) {
return node.type === Syntax.FunctionDeclaration;
};
function visitComments(traverse, node, path, state) {
actualNodes.push([node.value, node.range[0]]);
}
visitComments.test = function(node, path, state) {
return node.type === 'Line';
};
transformFn([visitComments, visitFunction], source);
expect(actualNodes).toEqual([
[' Foo comment', 0],
['foo', 15],
[' Bar comment', 34],
['bar', 49]
]);
});
});
});

View File

@@ -0,0 +1,58 @@
/**
* Copyright 2013-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.
* @emails jeffmo@fb.com
*/
/*jshint evil:true*/
require('mock-modules').autoMockOff();
describe('jstransform-utils', function() {
var transform, utils;
var Syntax = require('esprima-fb').Syntax;
beforeEach(function() {
require('mock-modules').dumpCache();
transform = require('../jstransform').transform;
utils = require('../utils');
});
describe('temporary variables', function() {
it('should inject temporary variables at the start of functions', function() {
function visitFunctionBlock(traverse, node, path, state) {
utils.catchup(node.range[0] + 1, state);
var x = utils.injectTempVar(state);
var y = utils.injectTempVar(state);
traverse(node.body, path, state);
utils.append('return ' + x + ' + ' + y + ';', state);
utils.catchup(node.range[1], state);
return false;
}
visitFunctionBlock.test = function(node, path, state) {
var parentType = path.length && path[0].type;
return node.type === Syntax.BlockStatement && (
parentType === Syntax.FunctionDeclaration ||
parentType === Syntax.FunctionExpression
);
};
expect(transform(
[visitFunctionBlock],
'var x = function() {};'
).code).toEqual(
'var x = function() {var $__0, $__1;return $__0 + $__1;};'
);
expect(eval(transform(
[visitFunctionBlock],
'2 + (function sum(x, y)\t{ $__0 = x; $__1 = y; }(3, 5))'
).code)).toEqual(10);
});
});
});

72
node_modules/jstransform/src/cli.js generated vendored Normal file
View File

@@ -0,0 +1,72 @@
/**
* Copyright 2013-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.
*/
var assign = require('object-assign');
var transform = require('./simple').transform;
require('commoner').version(
require('../package.json').version
).resolve(function(id) {
return this.readModuleP(id);
}).option(
'--react',
'Turns on the React JSX and React displayName transforms'
).option(
'--es6',
'Turns on available ES6 transforms'
).option(
'--es7',
'Turns on available ES7 transforms'
).option(
'--harmony',
'Shorthand to enable all ES6 and ES7 transforms'
).option(
'--utility',
'Turns on available utility transforms'
).option(
'--target [version]',
'Specify your target version of ECMAScript. Valid values are "es3" and ' +
'"es5". The default is "es5". "es3" will avoid uses of defineProperty and ' +
'will quote reserved words. WARNING: "es5" is not properly supported, even ' +
'with the use of es5shim, es5sham. If you need to support IE8, use "es3".',
'es5'
).option(
'--strip-types',
'Strips out type annotations.'
).option(
'--es6module',
'Parses the file as a valid ES6 module. ' +
'(Note that this means implicit strict mode)'
).option(
'--non-strict-es6module',
'Parses the file as an ES6 module, except disables implicit strict-mode. ' +
'(This is useful if you\'re porting non-ES6 modules to ES6, but haven\'t ' +
'yet verified that they are strict-mode safe yet)'
).option(
'--source-map-inline',
'Embed inline sourcemap in transformed source'
).option(
'--source-filename',
'Filename to use when generating the inline sourcemap. Will default to ' +
'filename when processing files'
).process(function(id, source) {
// This is where JSX, ES6, etc. desugaring happens.
// We don't do any pre-processing of options so that the command line and the
// JS API both expose the same set of options. We will set the sourceFilename
// to something more correct than "source.js".
var options;
if (id !== '<stdin>') {
options = assign({sourceFilename: id + '.js'}, this.options);
} else {
options = this.options;
}
var result = transform(source, options);
return result.code;
});

79
node_modules/jstransform/src/docblock.js generated vendored Normal file
View File

@@ -0,0 +1,79 @@
/**
* Copyright 2013-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.
*/
var docblockRe = /^\s*(\/\*\*(.|\r?\n)*?\*\/)/;
var ltrimRe = /^\s*/;
/**
* @param {String} contents
* @return {String}
*/
function extract(contents) {
var match = contents.match(docblockRe);
if (match) {
return match[0].replace(ltrimRe, '') || '';
}
return '';
}
var commentStartRe = /^\/\*\*?/;
var commentEndRe = /\*+\/$/;
var wsRe = /[\t ]+/g;
var stringStartRe = /(\r?\n|^) *\*/g;
var multilineRe = /(?:^|\r?\n) *(@[^\r\n]*?) *\r?\n *([^@\r\n\s][^@\r\n]+?) *\r?\n/g;
var propertyRe = /(?:^|\r?\n) *@(\S+) *([^\r\n]*)/g;
/**
* @param {String} contents
* @return {Array}
*/
function parse(docblock) {
docblock = docblock
.replace(commentStartRe, '')
.replace(commentEndRe, '')
.replace(wsRe, ' ')
.replace(stringStartRe, '$1');
// Normalize multi-line directives
var prev = '';
while (prev != docblock) {
prev = docblock;
docblock = docblock.replace(multilineRe, "\n$1 $2\n");
}
docblock = docblock.trim();
var result = [];
var match;
while (match = propertyRe.exec(docblock)) {
result.push([match[1], match[2]]);
}
return result;
}
/**
* Same as parse but returns an object of prop: value instead of array of paris
* If a property appers more than once the last one will be returned
*
* @param {String} contents
* @return {Object}
*/
function parseAsObject(docblock) {
var pairs = parse(docblock);
var result = {};
for (var i = 0; i < pairs.length; i++) {
result[pairs[i][0]] = pairs[i][1];
}
return result;
}
exports.extract = extract;
exports.parse = parse;
exports.parseAsObject = parseAsObject;

27
node_modules/jstransform/src/inline-source-map.js generated vendored Normal file
View File

@@ -0,0 +1,27 @@
/**
* Copyright 2013-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.
*/
'use strict';
/*eslint-disable no-undef*/
var Buffer = require('buffer').Buffer;
function inlineSourceMap(sourceMap, sourceCode, sourceFilename) {
// This can be used with a sourcemap that has already has toJSON called on it.
// Check first.
var json = sourceMap;
if (typeof sourceMap.toJSON === 'function') {
json = sourceMap.toJSON();
}
json.sources = [sourceFilename];
json.sourcesContent = [sourceCode];
var base64 = new Buffer(JSON.stringify(json)).toString('base64');
return '//# sourceMappingURL=data:application/json;base64,' + base64;
}
module.exports = inlineSourceMap;

292
node_modules/jstransform/src/jstransform.js generated vendored Normal file
View File

@@ -0,0 +1,292 @@
/**
* Copyright 2013-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.
*/
/*jslint node: true*/
"use strict";
var esprima = require('esprima-fb');
var utils = require('./utils');
var getBoundaryNode = utils.getBoundaryNode;
var declareIdentInScope = utils.declareIdentInLocalScope;
var initScopeMetadata = utils.initScopeMetadata;
var Syntax = esprima.Syntax;
/**
* @param {object} node
* @param {object} parentNode
* @return {boolean}
*/
function _nodeIsClosureScopeBoundary(node, parentNode) {
if (node.type === Syntax.Program) {
return true;
}
var parentIsFunction =
parentNode.type === Syntax.FunctionDeclaration
|| parentNode.type === Syntax.FunctionExpression
|| parentNode.type === Syntax.ArrowFunctionExpression;
var parentIsCurlylessArrowFunc =
parentNode.type === Syntax.ArrowFunctionExpression
&& node === parentNode.body;
return parentIsFunction
&& (node.type === Syntax.BlockStatement || parentIsCurlylessArrowFunc);
}
function _nodeIsBlockScopeBoundary(node, parentNode) {
if (node.type === Syntax.Program) {
return false;
}
return node.type === Syntax.BlockStatement
&& parentNode.type === Syntax.CatchClause;
}
/**
* @param {object} node
* @param {array} path
* @param {object} state
*/
function traverse(node, path, state) {
/*jshint -W004*/
// Create a scope stack entry if this is the first node we've encountered in
// its local scope
var startIndex = null;
var parentNode = path[0];
if (!Array.isArray(node) && state.localScope.parentNode !== parentNode) {
if (_nodeIsClosureScopeBoundary(node, parentNode)) {
var scopeIsStrict = state.scopeIsStrict;
if (!scopeIsStrict
&& (node.type === Syntax.BlockStatement
|| node.type === Syntax.Program)) {
scopeIsStrict =
node.body.length > 0
&& node.body[0].type === Syntax.ExpressionStatement
&& node.body[0].expression.type === Syntax.Literal
&& node.body[0].expression.value === 'use strict';
}
if (node.type === Syntax.Program) {
startIndex = state.g.buffer.length;
state = utils.updateState(state, {
scopeIsStrict: scopeIsStrict
});
} else {
startIndex = state.g.buffer.length + 1;
state = utils.updateState(state, {
localScope: {
parentNode: parentNode,
parentScope: state.localScope,
identifiers: {},
tempVarIndex: 0,
tempVars: []
},
scopeIsStrict: scopeIsStrict
});
// All functions have an implicit 'arguments' object in scope
declareIdentInScope('arguments', initScopeMetadata(node), state);
// Include function arg identifiers in the scope boundaries of the
// function
if (parentNode.params.length > 0) {
var param;
var metadata = initScopeMetadata(parentNode, path.slice(1), path[0]);
for (var i = 0; i < parentNode.params.length; i++) {
param = parentNode.params[i];
if (param.type === Syntax.Identifier) {
declareIdentInScope(param.name, metadata, state);
}
}
}
// Include rest arg identifiers in the scope boundaries of their
// functions
if (parentNode.rest) {
var metadata = initScopeMetadata(
parentNode,
path.slice(1),
path[0]
);
declareIdentInScope(parentNode.rest.name, metadata, state);
}
// Named FunctionExpressions scope their name within the body block of
// themselves only
if (parentNode.type === Syntax.FunctionExpression && parentNode.id) {
var metaData =
initScopeMetadata(parentNode, path.parentNodeslice, parentNode);
declareIdentInScope(parentNode.id.name, metaData, state);
}
}
// Traverse and find all local identifiers in this closure first to
// account for function/variable declaration hoisting
collectClosureIdentsAndTraverse(node, path, state);
}
if (_nodeIsBlockScopeBoundary(node, parentNode)) {
startIndex = state.g.buffer.length;
state = utils.updateState(state, {
localScope: {
parentNode: parentNode,
parentScope: state.localScope,
identifiers: {},
tempVarIndex: 0,
tempVars: []
}
});
if (parentNode.type === Syntax.CatchClause) {
var metadata = initScopeMetadata(
parentNode,
path.slice(1),
parentNode
);
declareIdentInScope(parentNode.param.name, metadata, state);
}
collectBlockIdentsAndTraverse(node, path, state);
}
}
// Only catchup() before and after traversing a child node
function traverser(node, path, state) {
node.range && utils.catchup(node.range[0], state);
traverse(node, path, state);
node.range && utils.catchup(node.range[1], state);
}
utils.analyzeAndTraverse(walker, traverser, node, path, state);
// Inject temp variables into the scope.
if (startIndex !== null) {
utils.injectTempVarDeclarations(state, startIndex);
}
}
function collectClosureIdentsAndTraverse(node, path, state) {
utils.analyzeAndTraverse(
visitLocalClosureIdentifiers,
collectClosureIdentsAndTraverse,
node,
path,
state
);
}
function collectBlockIdentsAndTraverse(node, path, state) {
utils.analyzeAndTraverse(
visitLocalBlockIdentifiers,
collectBlockIdentsAndTraverse,
node,
path,
state
);
}
function visitLocalClosureIdentifiers(node, path, state) {
var metaData;
switch (node.type) {
case Syntax.ArrowFunctionExpression:
case Syntax.FunctionExpression:
// Function expressions don't get their names (if there is one) added to
// the closure scope they're defined in
return false;
case Syntax.ClassDeclaration:
case Syntax.ClassExpression:
case Syntax.FunctionDeclaration:
if (node.id) {
metaData = initScopeMetadata(getBoundaryNode(path), path.slice(), node);
declareIdentInScope(node.id.name, metaData, state);
}
return false;
case Syntax.VariableDeclarator:
// Variables have function-local scope
if (path[0].kind === 'var') {
metaData = initScopeMetadata(getBoundaryNode(path), path.slice(), node);
declareIdentInScope(node.id.name, metaData, state);
}
break;
}
}
function visitLocalBlockIdentifiers(node, path, state) {
// TODO: Support 'let' here...maybe...one day...or something...
if (node.type === Syntax.CatchClause) {
return false;
}
}
function walker(node, path, state) {
var visitors = state.g.visitors;
for (var i = 0; i < visitors.length; i++) {
if (visitors[i].test(node, path, state)) {
return visitors[i](traverse, node, path, state);
}
}
}
var _astCache = {};
function getAstForSource(source, options) {
if (_astCache[source] && !options.disableAstCache) {
return _astCache[source];
}
var ast = esprima.parse(source, {
comment: true,
loc: true,
range: true,
sourceType: options.sourceType
});
if (!options.disableAstCache) {
_astCache[source] = ast;
}
return ast;
}
/**
* Applies all available transformations to the source
* @param {array} visitors
* @param {string} source
* @param {?object} options
* @return {object}
*/
function transform(visitors, source, options) {
options = options || {};
var ast;
try {
ast = getAstForSource(source, options);
} catch (e) {
e.message = 'Parse Error: ' + e.message;
throw e;
}
var state = utils.createState(source, ast, options);
state.g.visitors = visitors;
if (options.sourceMap) {
var SourceMapGenerator = require('source-map').SourceMapGenerator;
state.g.sourceMap = new SourceMapGenerator({file: options.filename || 'transformed.js'});
}
traverse(ast, [], state);
utils.catchup(source.length, state);
var ret = {code: state.g.buffer, extra: state.g.extra};
if (options.sourceMap) {
ret.sourceMap = state.g.sourceMap;
ret.sourceMapFilename = options.filename || 'source.js';
}
return ret;
}
exports.transform = transform;
exports.Syntax = Syntax;

165
node_modules/jstransform/src/simple.js generated vendored Normal file
View File

@@ -0,0 +1,165 @@
/**
* Copyright 2013-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.
*/
'use strict';
/*eslint-disable no-undef*/
var assign = require('object-assign');
var visitors = require('../visitors');
var jstransform = require('./jstransform');
var typesSyntax = require('../visitors/type-syntax');
var inlineSourceMap = require('./inline-source-map');
var fs = require('fs');
var DEFAULT_OPTIONS = {
react: false,
es6: false,
es7: false,
harmony: false,
utility: false,
target: 'es5',
stripTypes: false,
sourceMap: false,
sourceMapInline: false,
sourceFilename: 'source.js',
es6module: false,
nonStrictEs6module: false
};
/**
* Transforms the given code with the given options.
*
* @param {string} code
* @param {object} options
* @return {object}
*/
function transform(code, options) {
options = assign({}, DEFAULT_OPTIONS, options);
// Process options
var transformOptions = {};
if (options.sourceMap || options.sourceMapInline) {
transformOptions.sourceMap = true;
transformOptions.filename = options.sourceFilename || 'source.js';
}
if (options.es6module) {
transformOptions.sourceType = 'module';
}
if (options.nonStrictEs6module) {
transformOptions.sourceType = 'nonStrictModule';
}
// Instead of doing any fancy validation, only look for 'es3'. If we have
// that, then use it. Otherwise use 'es5'.
transformOptions.es3 = options.target === 'es3';
transformOptions.es5 = !transformOptions.es3;
// Determine visitors to use
var visitorSets = [];
if (options.react) {
visitorSets.push('react');
}
if (options.harmony) {
visitorSets.push('harmony');
}
if (options.es6) {
visitorSets.push('es6');
}
if (options.es7) {
visitorSets.push('es7');
}
if (options.utility) {
visitorSets.push('utility');
}
if (options.target === 'es3') {
visitorSets.push('target:es3');
}
if (options.stripTypes) {
// Stripping types needs to happen before the other transforms
// unfortunately, due to bad interactions. For example,
// es6-rest-param-visitors conflict with stripping rest param type
// annotation
code = jstransform.transform(
typesSyntax.visitorList,
code,
transformOptions
).code;
}
var visitorList = visitors.getVisitorsBySet(visitorSets);
var result = jstransform.transform(visitorList, code, transformOptions);
// Only copy some things off.
var output = {
code: result.code,
sourceMap: null
};
// Convert sourceMap to JSON.
var sourceMap;
if (result.sourceMap) {
sourceMap = result.sourceMap.toJSON();
sourceMap.sources = [transformOptions.filename];
sourceMap.sourcesContent = [code];
}
// This differentiates options.sourceMap from options.sourceMapInline.
if (options.sourceMap) {
output.sourceMap = sourceMap;
}
if (options.sourceMapInline) {
var map = inlineSourceMap(
result.sourceMap,
code,
transformOptions.filename
);
output.code = output.code + '\n' + map;
}
return output;
}
function transformFile(file, options, callback) {
if (typeof options === 'function') {
callback = options;
options = {};
}
options = assign({sourceFilename: file}, options);
fs.readFile(file, 'utf-8', function(err, contents) {
if (err) {
return callback(err, null);
}
var result = transform(contents, options);
callback(null, result);
});
}
function transformFileSync(file, options) {
options = assign({sourceFilename: file}, options);
var contents = fs.readFileSync(file, 'utf-8');
return transform(contents, options);
}
module.exports = {
transform: transform,
transformFile: transformFile,
transformFileSync: transformFileSync
};

701
node_modules/jstransform/src/utils.js generated vendored Normal file
View File

@@ -0,0 +1,701 @@
/**
* Copyright 2013-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.
*/
/*jslint node: true*/
var Syntax = require('esprima-fb').Syntax;
var leadingIndentRegexp = /(^|\n)( {2}|\t)/g;
var nonWhiteRegexp = /(\S)/g;
/**
* A `state` object represents the state of the parser. It has "local" and
* "global" parts. Global contains parser position, source, etc. Local contains
* scope based properties like current class name. State should contain all the
* info required for transformation. It's the only mandatory object that is
* being passed to every function in transform chain.
*
* @param {string} source
* @param {object} transformOptions
* @return {object}
*/
function createState(source, rootNode, transformOptions) {
return {
/**
* A tree representing the current local scope (and its lexical scope chain)
* Useful for tracking identifiers from parent scopes, etc.
* @type {Object}
*/
localScope: {
parentNode: rootNode,
parentScope: null,
identifiers: {},
tempVarIndex: 0,
tempVars: []
},
/**
* The name (and, if applicable, expression) of the super class
* @type {Object}
*/
superClass: null,
/**
* The namespace to use when munging identifiers
* @type {String}
*/
mungeNamespace: '',
/**
* Ref to the node for the current MethodDefinition
* @type {Object}
*/
methodNode: null,
/**
* Ref to the node for the FunctionExpression of the enclosing
* MethodDefinition
* @type {Object}
*/
methodFuncNode: null,
/**
* Name of the enclosing class
* @type {String}
*/
className: null,
/**
* Whether we're currently within a `strict` scope
* @type {Bool}
*/
scopeIsStrict: null,
/**
* Indentation offset
* @type {Number}
*/
indentBy: 0,
/**
* Global state (not affected by updateState)
* @type {Object}
*/
g: {
/**
* A set of general options that transformations can consider while doing
* a transformation:
*
* - minify
* Specifies that transformation steps should do their best to minify
* the output source when possible. This is useful for places where
* minification optimizations are possible with higher-level context
* info than what jsxmin can provide.
*
* For example, the ES6 class transform will minify munged private
* variables if this flag is set.
*/
opts: transformOptions,
/**
* Current position in the source code
* @type {Number}
*/
position: 0,
/**
* Auxiliary data to be returned by transforms
* @type {Object}
*/
extra: {},
/**
* Buffer containing the result
* @type {String}
*/
buffer: '',
/**
* Source that is being transformed
* @type {String}
*/
source: source,
/**
* Cached parsed docblock (see getDocblock)
* @type {object}
*/
docblock: null,
/**
* Whether the thing was used
* @type {Boolean}
*/
tagNamespaceUsed: false,
/**
* If using bolt xjs transformation
* @type {Boolean}
*/
isBolt: undefined,
/**
* Whether to record source map (expensive) or not
* @type {SourceMapGenerator|null}
*/
sourceMap: null,
/**
* Filename of the file being processed. Will be returned as a source
* attribute in the source map
*/
sourceMapFilename: 'source.js',
/**
* Only when source map is used: last line in the source for which
* source map was generated
* @type {Number}
*/
sourceLine: 1,
/**
* Only when source map is used: last line in the buffer for which
* source map was generated
* @type {Number}
*/
bufferLine: 1,
/**
* The top-level Program AST for the original file.
*/
originalProgramAST: null,
sourceColumn: 0,
bufferColumn: 0
}
};
}
/**
* Updates a copy of a given state with "update" and returns an updated state.
*
* @param {object} state
* @param {object} update
* @return {object}
*/
function updateState(state, update) {
var ret = Object.create(state);
Object.keys(update).forEach(function(updatedKey) {
ret[updatedKey] = update[updatedKey];
});
return ret;
}
/**
* Given a state fill the resulting buffer from the original source up to
* the end
*
* @param {number} end
* @param {object} state
* @param {?function} contentTransformer Optional callback to transform newly
* added content.
*/
function catchup(end, state, contentTransformer) {
if (end < state.g.position) {
// cannot move backwards
return;
}
var source = state.g.source.substring(state.g.position, end);
var transformed = updateIndent(source, state);
if (state.g.sourceMap && transformed) {
// record where we are
state.g.sourceMap.addMapping({
generated: { line: state.g.bufferLine, column: state.g.bufferColumn },
original: { line: state.g.sourceLine, column: state.g.sourceColumn },
source: state.g.sourceMapFilename
});
// record line breaks in transformed source
var sourceLines = source.split('\n');
var transformedLines = transformed.split('\n');
// Add line break mappings between last known mapping and the end of the
// added piece. So for the code piece
// (foo, bar);
// > var x = 2;
// > var b = 3;
// var c =
// only add lines marked with ">": 2, 3.
for (var i = 1; i < sourceLines.length - 1; i++) {
state.g.sourceMap.addMapping({
generated: { line: state.g.bufferLine, column: 0 },
original: { line: state.g.sourceLine, column: 0 },
source: state.g.sourceMapFilename
});
state.g.sourceLine++;
state.g.bufferLine++;
}
// offset for the last piece
if (sourceLines.length > 1) {
state.g.sourceLine++;
state.g.bufferLine++;
state.g.sourceColumn = 0;
state.g.bufferColumn = 0;
}
state.g.sourceColumn += sourceLines[sourceLines.length - 1].length;
state.g.bufferColumn +=
transformedLines[transformedLines.length - 1].length;
}
state.g.buffer +=
contentTransformer ? contentTransformer(transformed) : transformed;
state.g.position = end;
}
/**
* Returns original source for an AST node.
* @param {object} node
* @param {object} state
* @return {string}
*/
function getNodeSourceText(node, state) {
return state.g.source.substring(node.range[0], node.range[1]);
}
function _replaceNonWhite(value) {
return value.replace(nonWhiteRegexp, ' ');
}
/**
* Removes all non-whitespace characters
*/
function _stripNonWhite(value) {
return value.replace(nonWhiteRegexp, '');
}
/**
* Finds the position of the next instance of the specified syntactic char in
* the pending source.
*
* NOTE: This will skip instances of the specified char if they sit inside a
* comment body.
*
* NOTE: This function also assumes that the buffer's current position is not
* already within a comment or a string. This is rarely the case since all
* of the buffer-advancement utility methods tend to be used on syntactic
* nodes' range values -- but it's a small gotcha that's worth mentioning.
*/
function getNextSyntacticCharOffset(char, state) {
var pendingSource = state.g.source.substring(state.g.position);
var pendingSourceLines = pendingSource.split('\n');
var charOffset = 0;
var line;
var withinBlockComment = false;
var withinString = false;
lineLoop: while ((line = pendingSourceLines.shift()) !== undefined) {
var lineEndPos = charOffset + line.length;
charLoop: for (; charOffset < lineEndPos; charOffset++) {
var currChar = pendingSource[charOffset];
if (currChar === '"' || currChar === '\'') {
withinString = !withinString;
continue charLoop;
} else if (withinString) {
continue charLoop;
} else if (charOffset + 1 < lineEndPos) {
var nextTwoChars = currChar + line[charOffset + 1];
if (nextTwoChars === '//') {
charOffset = lineEndPos + 1;
continue lineLoop;
} else if (nextTwoChars === '/*') {
withinBlockComment = true;
charOffset += 1;
continue charLoop;
} else if (nextTwoChars === '*/') {
withinBlockComment = false;
charOffset += 1;
continue charLoop;
}
}
if (!withinBlockComment && currChar === char) {
return charOffset + state.g.position;
}
}
// Account for '\n'
charOffset++;
withinString = false;
}
throw new Error('`' + char + '` not found!');
}
/**
* Catches up as `catchup` but replaces non-whitespace chars with spaces.
*/
function catchupWhiteOut(end, state) {
catchup(end, state, _replaceNonWhite);
}
/**
* Catches up as `catchup` but removes all non-whitespace characters.
*/
function catchupWhiteSpace(end, state) {
catchup(end, state, _stripNonWhite);
}
/**
* Removes all non-newline characters
*/
var reNonNewline = /[^\n]/g;
function stripNonNewline(value) {
return value.replace(reNonNewline, function() {
return '';
});
}
/**
* Catches up as `catchup` but removes all non-newline characters.
*
* Equivalent to appending as many newlines as there are in the original source
* between the current position and `end`.
*/
function catchupNewlines(end, state) {
catchup(end, state, stripNonNewline);
}
/**
* Same as catchup but does not touch the buffer
*
* @param {number} end
* @param {object} state
*/
function move(end, state) {
// move the internal cursors
if (state.g.sourceMap) {
if (end < state.g.position) {
state.g.position = 0;
state.g.sourceLine = 1;
state.g.sourceColumn = 0;
}
var source = state.g.source.substring(state.g.position, end);
var sourceLines = source.split('\n');
if (sourceLines.length > 1) {
state.g.sourceLine += sourceLines.length - 1;
state.g.sourceColumn = 0;
}
state.g.sourceColumn += sourceLines[sourceLines.length - 1].length;
}
state.g.position = end;
}
/**
* Appends a string of text to the buffer
*
* @param {string} str
* @param {object} state
*/
function append(str, state) {
if (state.g.sourceMap && str) {
state.g.sourceMap.addMapping({
generated: { line: state.g.bufferLine, column: state.g.bufferColumn },
original: { line: state.g.sourceLine, column: state.g.sourceColumn },
source: state.g.sourceMapFilename
});
var transformedLines = str.split('\n');
if (transformedLines.length > 1) {
state.g.bufferLine += transformedLines.length - 1;
state.g.bufferColumn = 0;
}
state.g.bufferColumn +=
transformedLines[transformedLines.length - 1].length;
}
state.g.buffer += str;
}
/**
* Update indent using state.indentBy property. Indent is measured in
* double spaces. Updates a single line only.
*
* @param {string} str
* @param {object} state
* @return {string}
*/
function updateIndent(str, state) {
/*jshint -W004*/
var indentBy = state.indentBy;
if (indentBy < 0) {
for (var i = 0; i < -indentBy; i++) {
str = str.replace(leadingIndentRegexp, '$1');
}
} else {
for (var i = 0; i < indentBy; i++) {
str = str.replace(leadingIndentRegexp, '$1$2$2');
}
}
return str;
}
/**
* Calculates indent from the beginning of the line until "start" or the first
* character before start.
* @example
* " foo.bar()"
* ^
* start
* indent will be " "
*
* @param {number} start
* @param {object} state
* @return {string}
*/
function indentBefore(start, state) {
var end = start;
start = start - 1;
while (start > 0 && state.g.source[start] != '\n') {
if (!state.g.source[start].match(/[ \t]/)) {
end = start;
}
start--;
}
return state.g.source.substring(start + 1, end);
}
function getDocblock(state) {
if (!state.g.docblock) {
var docblock = require('./docblock');
state.g.docblock =
docblock.parseAsObject(docblock.extract(state.g.source));
}
return state.g.docblock;
}
function identWithinLexicalScope(identName, state, stopBeforeNode) {
var currScope = state.localScope;
while (currScope) {
if (currScope.identifiers[identName] !== undefined) {
return true;
}
if (stopBeforeNode && currScope.parentNode === stopBeforeNode) {
break;
}
currScope = currScope.parentScope;
}
return false;
}
function identInLocalScope(identName, state) {
return state.localScope.identifiers[identName] !== undefined;
}
/**
* @param {object} boundaryNode
* @param {?array} path
* @return {?object} node
*/
function initScopeMetadata(boundaryNode, path, node) {
return {
boundaryNode: boundaryNode,
bindingPath: path,
bindingNode: node
};
}
function declareIdentInLocalScope(identName, metaData, state) {
state.localScope.identifiers[identName] = {
boundaryNode: metaData.boundaryNode,
path: metaData.bindingPath,
node: metaData.bindingNode,
state: Object.create(state)
};
}
function getLexicalBindingMetadata(identName, state) {
var currScope = state.localScope;
while (currScope) {
if (currScope.identifiers[identName] !== undefined) {
return currScope.identifiers[identName];
}
currScope = currScope.parentScope;
}
}
function getLocalBindingMetadata(identName, state) {
return state.localScope.identifiers[identName];
}
/**
* Apply the given analyzer function to the current node. If the analyzer
* doesn't return false, traverse each child of the current node using the given
* traverser function.
*
* @param {function} analyzer
* @param {function} traverser
* @param {object} node
* @param {array} path
* @param {object} state
*/
function analyzeAndTraverse(analyzer, traverser, node, path, state) {
if (node.type) {
if (analyzer(node, path, state) === false) {
return;
}
path.unshift(node);
}
getOrderedChildren(node).forEach(function(child) {
traverser(child, path, state);
});
node.type && path.shift();
}
/**
* It is crucial that we traverse in order, or else catchup() on a later
* node that is processed out of order can move the buffer past a node
* that we haven't handled yet, preventing us from modifying that node.
*
* This can happen when a node has multiple properties containing children.
* For example, XJSElement nodes have `openingElement`, `closingElement` and
* `children`. If we traverse `openingElement`, then `closingElement`, then
* when we get to `children`, the buffer has already caught up to the end of
* the closing element, after the children.
*
* This is basically a Schwartzian transform. Collects an array of children,
* each one represented as [child, startIndex]; sorts the array by start
* index; then traverses the children in that order.
*/
function getOrderedChildren(node) {
var queue = [];
for (var key in node) {
if (node.hasOwnProperty(key)) {
enqueueNodeWithStartIndex(queue, node[key]);
}
}
queue.sort(function(a, b) { return a[1] - b[1]; });
return queue.map(function(pair) { return pair[0]; });
}
/**
* Helper function for analyzeAndTraverse which queues up all of the children
* of the given node.
*
* Children can also be found in arrays, so we basically want to merge all of
* those arrays together so we can sort them and then traverse the children
* in order.
*
* One example is the Program node. It contains `body` and `comments`, both
* arrays. Lexographically, comments are interspersed throughout the body
* nodes, but esprima's AST groups them together.
*/
function enqueueNodeWithStartIndex(queue, node) {
if (typeof node !== 'object' || node === null) {
return;
}
if (node.range) {
queue.push([node, node.range[0]]);
} else if (Array.isArray(node)) {
for (var ii = 0; ii < node.length; ii++) {
enqueueNodeWithStartIndex(queue, node[ii]);
}
}
}
/**
* Checks whether a node or any of its sub-nodes contains
* a syntactic construct of the passed type.
* @param {object} node - AST node to test.
* @param {string} type - node type to lookup.
*/
function containsChildOfType(node, type) {
return containsChildMatching(node, function(node) {
return node.type === type;
});
}
function containsChildMatching(node, matcher) {
var foundMatchingChild = false;
function nodeTypeAnalyzer(node) {
if (matcher(node) === true) {
foundMatchingChild = true;
return false;
}
}
function nodeTypeTraverser(child, path, state) {
if (!foundMatchingChild) {
foundMatchingChild = containsChildMatching(child, matcher);
}
}
analyzeAndTraverse(
nodeTypeAnalyzer,
nodeTypeTraverser,
node,
[]
);
return foundMatchingChild;
}
var scopeTypes = {};
scopeTypes[Syntax.ArrowFunctionExpression] = true;
scopeTypes[Syntax.FunctionExpression] = true;
scopeTypes[Syntax.FunctionDeclaration] = true;
scopeTypes[Syntax.Program] = true;
function getBoundaryNode(path) {
for (var ii = 0; ii < path.length; ++ii) {
if (scopeTypes[path[ii].type]) {
return path[ii];
}
}
throw new Error(
'Expected to find a node with one of the following types in path:\n' +
JSON.stringify(Object.keys(scopeTypes))
);
}
function getTempVar(tempVarIndex) {
return '$__' + tempVarIndex;
}
function injectTempVar(state) {
var tempVar = '$__' + (state.localScope.tempVarIndex++);
state.localScope.tempVars.push(tempVar);
return tempVar;
}
function injectTempVarDeclarations(state, index) {
if (state.localScope.tempVars.length) {
state.g.buffer =
state.g.buffer.slice(0, index) +
'var ' + state.localScope.tempVars.join(', ') + ';' +
state.g.buffer.slice(index);
state.localScope.tempVars = [];
}
}
exports.analyzeAndTraverse = analyzeAndTraverse;
exports.append = append;
exports.catchup = catchup;
exports.catchupNewlines = catchupNewlines;
exports.catchupWhiteOut = catchupWhiteOut;
exports.catchupWhiteSpace = catchupWhiteSpace;
exports.containsChildMatching = containsChildMatching;
exports.containsChildOfType = containsChildOfType;
exports.createState = createState;
exports.declareIdentInLocalScope = declareIdentInLocalScope;
exports.getBoundaryNode = getBoundaryNode;
exports.getDocblock = getDocblock;
exports.getLexicalBindingMetadata = getLexicalBindingMetadata;
exports.getLocalBindingMetadata = getLocalBindingMetadata;
exports.getNextSyntacticCharOffset = getNextSyntacticCharOffset;
exports.getNodeSourceText = getNodeSourceText;
exports.getOrderedChildren = getOrderedChildren;
exports.getTempVar = getTempVar;
exports.identInLocalScope = identInLocalScope;
exports.identWithinLexicalScope = identWithinLexicalScope;
exports.indentBefore = indentBefore;
exports.initScopeMetadata = initScopeMetadata;
exports.injectTempVar = injectTempVar;
exports.injectTempVarDeclarations = injectTempVarDeclarations;
exports.move = move;
exports.scopeTypes = scopeTypes;
exports.updateIndent = updateIndent;
exports.updateState = updateState;