Revert "Remove flow"

This reverts commit 2827ff6b01dcce69e9d3c0402e96b52b3a2a47ee.
This commit is contained in:
Amjad Masad 2016-03-03 14:49:20 -08:00
parent b88182cacf
commit 3667527d04
75 changed files with 542 additions and 278 deletions

View File

@ -36,7 +36,7 @@ while (nodeModulesDirectories.length) {
let loc = nodeModulesDirectories.shift(); let loc = nodeModulesDirectories.shift();
if (!fs.existsSync(loc)) continue; if (!fs.existsSync(loc)) continue;
let packagesNames = fs.readdirSync(loc); let packagesNames: Array<string> = fs.readdirSync(loc);
for (let packageName of packagesNames) { for (let packageName of packagesNames) {
if (packageName[0] === ".") continue; if (packageName[0] === ".") continue;

View File

@ -4,11 +4,11 @@
import { transform } from "./node"; import { transform } from "./node";
export * from "./node"; export * from "./node";
export function run(code, opts = {}) { export function run(code: string, opts: Object = {}): any {
return new Function(transform(code, opts).code)(); return new Function(transform(code, opts).code)();
} }
export function load(url, callback, opts = {}, hold) { export function load(url: string, callback: Function, opts: Object = {}, hold?: boolean) {
opts.filename = opts.filename || url; opts.filename = opts.filename || url;
let xhr = global.ActiveXObject ? new global.ActiveXObject("Microsoft.XMLHTTP") : new global.XMLHttpRequest(); let xhr = global.ActiveXObject ? new global.ActiveXObject("Microsoft.XMLHTTP") : new global.XMLHttpRequest();
@ -32,7 +32,7 @@ export function load(url, callback, opts = {}, hold) {
} }
function runScripts() { function runScripts() {
let scripts = []; let scripts: Array<Array<any> | Object> = [];
let types = ["text/ecmascript-6", "text/6to5", "text/babel", "module"]; let types = ["text/ecmascript-6", "text/6to5", "text/babel", "module"];
let index = 0; let index = 0;
@ -53,7 +53,7 @@ function runScripts() {
* Load, transform, and execute all scripts. * Load, transform, and execute all scripts.
*/ */
function run(script, i) { function run(script: Object, i: number) {
let opts = {}; let opts = {};
if (script.src) { if (script.src) {

View File

@ -42,7 +42,7 @@ export let transformFromAst = pipeline.transformFromAst.bind(pipeline);
// //
export function transformFile(filename, opts, callback) { export function transformFile(filename: string, opts?: Object, callback: Function) {
if (isFunction(opts)) { if (isFunction(opts)) {
callback = opts; callback = opts;
opts = {}; opts = {};
@ -69,7 +69,7 @@ export function transformFile(filename, opts, callback) {
}); });
} }
export function transformFileSync(filename, opts = {}) { export function transformFileSync(filename: string, opts?: Object = {}): string {
opts.filename = filename; opts.filename = filename;
return transform(fs.readFileSync(filename, "utf8"), opts); return transform(fs.readFileSync(filename, "utf8"), opts);
} }

View File

@ -3,7 +3,7 @@ import path from "path";
let relativeModules = {}; let relativeModules = {};
export default function (loc, relative = process.cwd()) { export default function (loc: string, relative: string = process.cwd()): ?string {
// we're in the browser, probably // we're in the browser, probably
if (typeof Module === "object") return null; if (typeof Module === "object") return null;

View File

@ -4,11 +4,13 @@ export default class Store extends Map {
this.dynamicData = {}; this.dynamicData = {};
} }
dynamicData: Object;
setDynamic(key, fn) { setDynamic(key, fn) {
this.dynamicData[key] = fn; this.dynamicData[key] = fn;
} }
get(key) { get(key: string): any {
if (this.has(key)) { if (this.has(key)) {
return super.get(key); return super.get(key);
} else { } else {

View File

@ -82,7 +82,10 @@ function buildHelpers(body, namespace, whitelist) {
)); ));
}); });
} }
export default function (whitelist, outputType = "global") { export default function (
whitelist?: Array<string>,
outputType: "global" | "umd" | "var" = "global",
) {
let namespace = t.identifier("babelHelpers"); let namespace = t.identifier("babelHelpers");
let builder = function (body) { let builder = function (body) {

View File

@ -1,3 +1,4 @@
import type File from "./index";
import buildDebug from "debug/node"; import buildDebug from "debug/node";
let verboseDebug = buildDebug("babel:verbose"); let verboseDebug = buildDebug("babel:verbose");
@ -6,26 +7,29 @@ let generalDebug = buildDebug("babel");
let seenDeprecatedMessages = []; let seenDeprecatedMessages = [];
export default class Logger { export default class Logger {
constructor(file, filename) { constructor(file: File, filename: string) {
this.filename = filename; this.filename = filename;
this.file = file; this.file = file;
} }
_buildMessage(msg) { filename: string;
file: File;
_buildMessage(msg: string): string {
let parts = `[BABEL] ${this.filename}`; let parts = `[BABEL] ${this.filename}`;
if (msg) parts += `: ${msg}`; if (msg) parts += `: ${msg}`;
return parts; return parts;
} }
warn(msg) { warn(msg: string) {
console.warn(this._buildMessage(msg)); console.warn(this._buildMessage(msg));
} }
error(msg, Constructor = Error) { error(msg: string, Constructor: typeof Error = Error): Error {
throw new Constructor(this._buildMessage(msg)); throw new Constructor(this._buildMessage(msg));
} }
deprecate(msg) { deprecate(msg: string) {
if (this.file.opts && this.file.opts.suppressDeprecationMessages) return; if (this.file.opts && this.file.opts.suppressDeprecationMessages) return;
msg = this._buildMessage(msg); msg = this._buildMessage(msg);
@ -39,15 +43,15 @@ export default class Logger {
console.error(msg); console.error(msg);
} }
verbose(msg) { verbose(msg: string) {
if (verboseDebug.enabled) verboseDebug(this._buildMessage(msg)); if (verboseDebug.enabled) verboseDebug(this._buildMessage(msg));
} }
debug(msg) { debug(msg: string) {
if (generalDebug.enabled) generalDebug(this._buildMessage(msg)); if (generalDebug.enabled) generalDebug(this._buildMessage(msg));
} }
deopt(node, msg) { deopt(node: Object, msg: string) {
this.debug(msg); this.debug(msg);
} }
} }

View File

@ -21,7 +21,7 @@ export let ImportDeclaration = {
specifiers specifiers
}); });
for (let specifier of path.get("specifiers")) { for (let specifier of (path.get("specifiers"): Array<Object>)) {
let local = specifier.node.local.name; let local = specifier.node.local.name;
if (specifier.isImportDefaultSpecifier()) { if (specifier.isImportDefaultSpecifier()) {
@ -77,7 +77,7 @@ export function ExportDeclaration(path, file) {
} }
if (path.isExportNamedDeclaration() && node.specifiers) { if (path.isExportNamedDeclaration() && node.specifiers) {
for (let specifier of node.specifiers) { for (let specifier of (node.specifiers: Array<Object>)) {
let exported = specifier.exported.name; let exported = specifier.exported.name;
exports.exported.push(exported); exports.exported.push(exported);

View File

@ -1,6 +1,7 @@
/* eslint max-len: 0 */ /* eslint max-len: 0 */
import * as context from "../../../api/node"; import * as context from "../../../api/node";
import type Logger from "../logger";
import Plugin from "../../plugin"; import Plugin from "../../plugin";
import * as messages from "babel-messages"; import * as messages from "babel-messages";
import { normaliseOptions } from "./index"; import { normaliseOptions } from "./index";
@ -32,19 +33,49 @@ function exists(filename) {
} }
} }
type PluginObject = {
pre?: Function;
post?: Function;
manipulateOptions?: Function;
visitor: ?{
[key: string]: Function | {
enter?: Function | Array<Function>;
exit?: Function | Array<Function>;
}
};
};
type MergeOptions = {
options?: Object,
extending?: Object,
alias: string,
loc?: string,
dirname?: string
};
export default class OptionManager { export default class OptionManager {
constructor(log) { constructor(log?: Logger) {
this.resolvedConfigs = []; this.resolvedConfigs = [];
this.options = OptionManager.createBareOptions(); this.options = OptionManager.createBareOptions();
this.log = log; this.log = log;
} }
resolvedConfigs: Array<string>;
options: Object;
log: ?Logger;
static memoisedPlugins: Array<{
container: Function;
plugin: Plugin;
}>;
static memoisePluginContainer(fn, loc, i, alias) { static memoisePluginContainer(fn, loc, i, alias) {
for (let cache of OptionManager.memoisedPlugins) { for (let cache of (OptionManager.memoisedPlugins: Array<Object>)) {
if (cache.container === fn) return cache.plugin; if (cache.container === fn) return cache.plugin;
} }
let obj; let obj: ?PluginObject;
if (typeof fn === "function") { if (typeof fn === "function") {
obj = fn(context); obj = fn(context);
@ -125,7 +156,7 @@ export default class OptionManager {
}); });
} }
addConfig(loc, key, json = json5) { addConfig(loc: string, key?: string, json = json5): boolean {
if (this.resolvedConfigs.indexOf(loc) >= 0) { if (this.resolvedConfigs.indexOf(loc) >= 0) {
return false; return false;
} }
@ -167,7 +198,7 @@ export default class OptionManager {
alias, alias,
loc, loc,
dirname dirname
}) { }: MergeOptions) {
alias = alias || "foreign"; alias = alias || "foreign";
if (!rawOpts) return; if (!rawOpts) return;
@ -272,7 +303,7 @@ export default class OptionManager {
* Merges all presets into the main options in case we are not in the * Merges all presets into the main options in case we are not in the
* "pass per preset" mode. Otherwise, options are calculated per preset. * "pass per preset" mode. Otherwise, options are calculated per preset.
*/ */
mergePresets(presets, dirname) { mergePresets(presets: Array<string | Object>, dirname: string) {
this.resolvePresets(presets, dirname, (presetOpts, presetLoc) => { this.resolvePresets(presets, dirname, (presetOpts, presetLoc) => {
this.mergeOptions({ this.mergeOptions({
options: presetOpts, options: presetOpts,
@ -287,7 +318,7 @@ export default class OptionManager {
* Resolves presets options which can be either direct object data, * Resolves presets options which can be either direct object data,
* or a module name to require. * or a module name to require.
*/ */
resolvePresets(presets, dirname, onResolve) { resolvePresets(presets: Array<string | Object>, dirname: string, onResolve?) {
return presets.map((val) => { return presets.map((val) => {
if (typeof val === "string") { if (typeof val === "string") {
let presetLoc = resolve(`babel-preset-${val}`, dirname) || resolve(val, dirname); let presetLoc = resolve(`babel-preset-${val}`, dirname) || resolve(val, dirname);
@ -376,7 +407,7 @@ export default class OptionManager {
} }
} }
init(opts = {}) { init(opts: Object = {}): Object {
let filename = opts.filename; let filename = opts.filename;
// resolve all .babelrc files // resolve all .babelrc files

View File

@ -1,14 +1,20 @@
import type Plugin from "./plugin";
import Store from "../store"; import Store from "../store";
import traverse from "babel-traverse"; import traverse from "babel-traverse";
import File from "./file";
export default class PluginPass extends Store { export default class PluginPass extends Store {
constructor(file, plugin, options = {}) { constructor(file: File, plugin: Plugin, options: Object = {}) {
super(); super();
this.plugin = plugin; this.plugin = plugin;
this.file = file; this.file = file;
this.opts = options; this.opts = options;
} }
plugin: Plugin;
file: File;
opts: Object;
transform() { transform() {
let file = this.file; let file = this.file;
file.log.debug(`Start transformer ${this.key}`); file.log.debug(`Start transformer ${this.key}`);

View File

@ -34,6 +34,33 @@ export class CodeGenerator extends Printer {
this.map = new SourceMap(position, opts, code); this.map = new SourceMap(position, opts, code);
} }
format: {
shouldPrintComment: (comment: string) => boolean;
retainLines: boolean;
comments: boolean;
auxiliaryCommentBefore: string;
auxiliaryCommentAfter: string;
compact: boolean | "auto";
minified: boolean;
quotes: "single" | "double";
concise: boolean;
indent: {
adjustMultilineComment: boolean;
style: string;
base: number;
}
};
auxiliaryCommentBefore: string;
auxiliaryCommentAfter: string;
whitespace: Whitespace;
position: Position;
map: SourceMap;
comments: Array<Object>;
tokens: Array<Object>;
opts: Object;
ast: Object;
/** /**
* Normalize generator options, setting defaults. * Normalize generator options, setting defaults.
* *
@ -134,7 +161,7 @@ export class CodeGenerator extends Printer {
} }
} }
export default function (ast, opts, code) { export default function (ast: Object, opts: Object, code: string): Object {
let gen = new CodeGenerator(ast, opts, code); let gen = new CodeGenerator(ast, opts, code);
return gen.generate(); return gen.generate();
} }

View File

@ -120,7 +120,7 @@ export default class Printer extends Buffer {
printMethod.call(this, node, parent); printMethod.call(this, node, parent);
} }
printJoin(nodes, parent, opts = {}) { printJoin(nodes: ?Array, parent: Object, opts = {}) {
if (!nodes || !nodes.length) return; if (!nodes || !nodes.length) return;
let len = nodes.length; let len = nodes.length;
@ -310,7 +310,7 @@ export default class Printer extends Buffer {
this.newline(this.whitespace.getNewlinesAfter(comment)); this.newline(this.whitespace.getNewlinesAfter(comment));
} }
printComments(comments) { printComments(comments?: Array<Object>) {
if (!comments || !comments.length) return; if (!comments || !comments.length) return;
for (let comment of comments) { for (let comment of comments) {

View File

@ -82,10 +82,10 @@ export default class Whitespace {
* Find a token between start and end. * Find a token between start and end.
*/ */
_findToken(test, start, end) { _findToken(test: Function, start: number, end: number): number {
if (start >= end) return -1; if (start >= end) return -1;
const middle = (start + end) >>> 1; const middle = (start + end) >>> 1;
const match = test(this.tokens[middle]); const match: number = test(this.tokens[middle]);
if (match < 0) { if (match < 0) {
return this._findToken(test, middle + 1, end); return this._findToken(test, middle + 1, end);
} else if (match > 0) { } else if (match > 0) {

View File

@ -1,6 +1,7 @@
import type { NodePath } from "babel-traverse";
import * as t from "babel-types"; import * as t from "babel-types";
export default function bindifyDecorators(decorators) { export default function bindifyDecorators(decorators: Array<NodePath>): Array<NodePath> {
for (let decoratorPath of decorators) { for (let decoratorPath of decorators) {
let decorator = decoratorPath.node; let decorator = decoratorPath.node;
let expression = decorator.expression; let expression = decorator.expression;

View File

@ -1,6 +1,14 @@
import esutils from "esutils"; import esutils from "esutils";
import * as t from "babel-types"; import * as t from "babel-types";
type ElementState = {
tagExpr: Object; // tag node
tagName: string; // raw string tag name
args: Array<Object>; // array of call arguments
call?: Object; // optional call property that can be set to override the call expression returned
pre?: Function; // function called with (state: ElementState) before building attribs
post?: Function; // function called with (state: ElementState) after building attribs
};
export default function (opts) { export default function (opts) {
let visitor = {}; let visitor = {};
@ -81,7 +89,7 @@ export default function (opts) {
tagName = tagExpr.value; tagName = tagExpr.value;
} }
let state = { let state: ElementState = {
tagExpr: tagExpr, tagExpr: tagExpr,
tagName: tagName, tagName: tagName,
args: args args: args

View File

@ -1,4 +1,5 @@
import hoistVariables from "babel-helper-hoist-variables"; import hoistVariables from "babel-helper-hoist-variables";
import type { NodePath } from "babel-traverse";
import * as t from "babel-types"; import * as t from "babel-types";
let visitor = { let visitor = {
@ -17,7 +18,7 @@ let visitor = {
} }
}; };
export default function (path, scope = path.scope) { export default function (path: NodePath, scope = path.scope) {
let { node } = path; let { node } = path;
let container = t.functionExpression(null, [], node.body, node.generator, node.async); let container = t.functionExpression(null, [], node.body, node.generator, node.async);

View File

@ -5,7 +5,7 @@ import each from "lodash/collection/each";
import has from "lodash/object/has"; import has from "lodash/object/has";
import * as t from "babel-types"; import * as t from "babel-types";
function toKind(node) { function toKind(node: Object) {
if (t.isClassMethod(node) || t.isObjectMethod(node)) { if (t.isClassMethod(node) || t.isObjectMethod(node)) {
if (node.kind === "get" || node.kind === "set") { if (node.kind === "get" || node.kind === "set") {
return node.kind; return node.kind;
@ -15,7 +15,7 @@ function toKind(node) {
return "value"; return "value";
} }
export function push(mutatorMap, node, kind, file, scope) { export function push(mutatorMap: Object, node: Object, kind: string, file, scope?): Object {
let alias = t.toKeyAlias(node); let alias = t.toKeyAlias(node);
// //
@ -75,7 +75,7 @@ export function push(mutatorMap, node, kind, file, scope) {
return map; return map;
} }
export function hasComputed(mutatorMap) { export function hasComputed(mutatorMap: Object): boolean {
for (let key in mutatorMap) { for (let key in mutatorMap) {
if (mutatorMap[key]._computed) { if (mutatorMap[key]._computed) {
return true; return true;
@ -84,7 +84,7 @@ export function hasComputed(mutatorMap) {
return false; return false;
} }
export function toComputedObjectFromClass(obj) { export function toComputedObjectFromClass(obj: Object): Object {
let objExpr = t.arrayExpression([]); let objExpr = t.arrayExpression([]);
for (let i = 0; i < obj.properties.length; i++) { for (let i = 0; i < obj.properties.length; i++) {
@ -97,7 +97,7 @@ export function toComputedObjectFromClass(obj) {
return objExpr; return objExpr;
} }
export function toClassObject(mutatorMap) { export function toClassObject(mutatorMap: Object): Object {
let objExpr = t.objectExpression([]); let objExpr = t.objectExpression([]);
each(mutatorMap, function (map) { each(mutatorMap, function (map) {
@ -124,7 +124,7 @@ export function toClassObject(mutatorMap) {
return objExpr; return objExpr;
} }
export function toDefineObject(mutatorMap) { export function toDefineObject(mutatorMap: Object): Object {
each(mutatorMap, function (map) { each(mutatorMap, function (map) {
if (map.value) map.writable = t.booleanLiteral(true); if (map.value) map.writable = t.booleanLiteral(true);
map.configurable = t.booleanLiteral(true); map.configurable = t.booleanLiteral(true);

View File

@ -1,3 +1,4 @@
import type { Scope } from "babel-traverse";
import * as t from "babel-types"; import * as t from "babel-types";
function getObjRef(node, nodes, file, scope) { function getObjRef(node, nodes, file, scope) {
@ -45,7 +46,16 @@ function getPropRef(node, nodes, file, scope) {
return temp; return temp;
} }
export default function (node, nodes, file, scope, allowedSingleIdent) { export default function (
node: Object,
nodes: Array<Object>,
file,
scope: Scope,
allowedSingleIdent?: boolean,
): {
uid: Object;
ref: Object;
} {
let obj; let obj;
if (t.isIdentifier(node) && allowedSingleIdent) { if (t.isIdentifier(node) && allowedSingleIdent) {
obj = node; obj = node;

View File

@ -1,4 +1,5 @@
import bindifyDecorators from "babel-helper-bindify-decorators"; import bindifyDecorators from "babel-helper-bindify-decorators";
import type { NodePath } from "babel-traverse";
import * as t from "babel-types"; import * as t from "babel-types";
export default function (classPath) { export default function (classPath) {
@ -14,7 +15,7 @@ export default function (classPath) {
path.replaceWith(uid); path.replaceWith(uid);
} }
function memoiseDecorators(paths) { function memoiseDecorators(paths: Array<NodePath>) {
if (!Array.isArray(paths) || !paths.length) return; if (!Array.isArray(paths) || !paths.length) return;
// ensure correct evaluation order of decorators // ensure correct evaluation order of decorators
@ -31,7 +32,7 @@ export default function (classPath) {
maybeMemoise(classPath.get("superClass")); maybeMemoise(classPath.get("superClass"));
memoiseDecorators(classPath.get("decorators"), true); memoiseDecorators(classPath.get("decorators"), true);
let methods = classPath.get("body.body"); let methods: Array<NodePath> = classPath.get("body.body");
for (let methodPath of methods) { for (let methodPath of methods) {
if (methodPath.is("computed")) { if (methodPath.is("computed")) {
maybeMemoise(methodPath.get("key")); maybeMemoise(methodPath.get("key"));

View File

@ -10,13 +10,35 @@ function humanize(val, noext) {
return val.replace(/-/g, " "); return val.replace(/-/g, " ");
} }
type TestFile = {
loc: string;
code: string;
filename: string;
};
type Test = {
title: string;
disabled: boolean;
options: Object;
exec: TestFile;
actual: TestFile;
expected: TestFile;
};
type Suite = {
options: Object;
tests: Array<Test>;
title: string;
filename: string;
};
function assertDirectory(loc) { function assertDirectory(loc) {
if (!fs.statSync(loc).isDirectory()) { if (!fs.statSync(loc).isDirectory()) {
throw new Error(`Expected ${loc} to be a directory.`); throw new Error(`Expected ${loc} to be a directory.`);
} }
} }
function shouldIgnore(name, blacklist) { function shouldIgnore(name, blacklist?: Array<string>) {
if (blacklist && blacklist.indexOf(name) >= 0) { if (blacklist && blacklist.indexOf(name) >= 0) {
return true; return true;
} }
@ -27,7 +49,7 @@ function shouldIgnore(name, blacklist) {
return name[0] === "." || ext === ".md" || base === "LICENSE" || base === "options"; return name[0] === "." || ext === ".md" || base === "LICENSE" || base === "options";
} }
export default function get(entryLoc) { export default function get(entryLoc): Array<Suite> {
let suites = []; let suites = [];
let rootOpts = {}; let rootOpts = {};
@ -125,7 +147,7 @@ export default function get(entryLoc) {
return suites; return suites;
} }
export function multiple(entryLoc, ignore) { export function multiple(entryLoc, ignore?: Array<string>) {
let categories = {}; let categories = {};
for (let name of fs.readdirSync(entryLoc)) { for (let name of fs.readdirSync(entryLoc)) {

View File

@ -1,7 +1,7 @@
import * as t from "babel-types"; import * as t from "babel-types";
export default function (node) { export default function (node): number {
let params = node.params; let params: Array<Object> = node.params;
for (let i = 0; i < params.length; i++) { for (let i = 0; i < params.length; i++) {
let param = params[i]; let param = params[i];
if (t.isAssignmentPattern(param) || t.isRestElement(param)) { if (t.isAssignmentPattern(param) || t.isRestElement(param)) {

View File

@ -14,7 +14,7 @@ let visitor = {
let nodes = []; let nodes = [];
let declarations = path.get("declarations"); let declarations: Array<Object> = path.get("declarations");
let firstId; let firstId;
for (let declar of declarations) { for (let declar of declarations) {
@ -40,6 +40,6 @@ let visitor = {
} }
}; };
export default function (path, emit, kind = "var") { export default function (path, emit: Function, kind: "var" | "let" = "var") {
path.traverse(visitor, { kind, emit }); path.traverse(visitor, { kind, emit });
} }

View File

@ -1,5 +1,6 @@
/* eslint max-len: 0 */ /* eslint max-len: 0 */
import type { NodePath, Scope } from "babel-traverse";
import optimiseCall from "babel-helper-optimise-call-expression"; import optimiseCall from "babel-helper-optimise-call-expression";
import * as messages from "babel-messages"; import * as messages from "babel-messages";
import * as t from "babel-types"; import * as t from "babel-types";
@ -72,7 +73,7 @@ let visitor = {
}; };
export default class ReplaceSupers { export default class ReplaceSupers {
constructor(opts, inClass = false) { constructor(opts: Object, inClass?: boolean = false) {
this.forceSuperMemoisation = opts.forceSuperMemoisation; this.forceSuperMemoisation = opts.forceSuperMemoisation;
this.methodPath = opts.methodPath; this.methodPath = opts.methodPath;
this.methodNode = opts.methodNode; this.methodNode = opts.methodNode;
@ -90,6 +91,27 @@ export default class ReplaceSupers {
this.thises = []; this.thises = [];
} }
forceSuperMemoisation: boolean;
methodPath: NodePath;
methodNode: Object;
superRef: Object;
isStatic: boolean;
hasSuper: boolean;
inClass: boolean;
isLoose: boolean;
scope: Scope;
file;
opts: {
forceSuperMemoisation: boolean;
getObjetRef: Function;
methodPath: NodePath;
methodNode: Object;
superRef: Object;
isStatic: boolean;
isLoose: boolean;
file: any;
};
getObjectRef() { getObjectRef() {
return this.opts.objectRef || this.opts.getObjectRef(); return this.opts.objectRef || this.opts.getObjectRef();
} }
@ -103,7 +125,7 @@ export default class ReplaceSupers {
* *
*/ */
setSuperProperty(property, value, isComputed) { setSuperProperty(property: Object, value: Object, isComputed: boolean): Object {
return t.callExpression( return t.callExpression(
this.file.addHelper("set"), this.file.addHelper("set"),
[ [
@ -129,7 +151,7 @@ export default class ReplaceSupers {
* *
*/ */
getSuperProperty(property, isComputed) { getSuperProperty(property: Object, isComputed: boolean): Object {
return t.callExpression( return t.callExpression(
this.file.addHelper("get"), this.file.addHelper("get"),
[ [
@ -149,7 +171,7 @@ export default class ReplaceSupers {
this.methodPath.traverse(visitor, this); this.methodPath.traverse(visitor, this);
} }
getLooseSuperProperty(id, parent) { getLooseSuperProperty(id: Object, parent: Object) {
let methodNode = this.methodNode; let methodNode = this.methodNode;
let superRef = this.superRef || t.identifier("Function"); let superRef = this.superRef || t.identifier("Function");
@ -165,7 +187,7 @@ export default class ReplaceSupers {
} }
} }
looseHandle(path) { looseHandle(path: NodePath) {
let node = path.node; let node = path.node;
if (path.isSuper()) { if (path.isSuper()) {
return this.getLooseSuperProperty(node, path.parent); return this.getLooseSuperProperty(node, path.parent);
@ -199,7 +221,7 @@ export default class ReplaceSupers {
} }
} }
specHandle(path) { specHandle(path: NodePath) {
let property; let property;
let computed; let computed;
let args; let args;

View File

@ -111,7 +111,13 @@ function runExec(opts, execCode) {
return fn.apply(null, Object.values(sandbox)); return fn.apply(null, Object.values(sandbox));
} }
export default function (fixturesLoc, name, suiteOpts = {}, taskOpts = {}, dynamicOpts) { export default function (
fixturesLoc: string,
name: string,
suiteOpts = {},
taskOpts = {},
dynamicOpts?: Function,
) {
let suites = getFixtures(fixturesLoc); let suites = getFixtures(fixturesLoc);
for (let testSuite of suites) { for (let testSuite of suites) {

View File

@ -6,11 +6,11 @@ export default function ({ messages }) {
let binding = scope.bindings[name]; let binding = scope.bindings[name];
if (binding.kind !== "const" && binding.kind !== "module") continue; if (binding.kind !== "const" && binding.kind !== "module") continue;
for (let violation of binding.constantViolations) { for (let violation of (binding.constantViolations: Array)) {
throw violation.buildCodeFrameError(messages.get("readOnly", name)); throw violation.buildCodeFrameError(messages.get("readOnly", name));
} }
} }
} },
} }
}; };
} }

View File

@ -17,8 +17,8 @@ let buildWrapper = template(`
export default function ({ types: t }) { export default function ({ types: t }) {
let ALREADY_VISITED = Symbol(); let ALREADY_VISITED = Symbol();
function findConstructorCall(path) { function findConstructorCall(path): ?Object {
let methods = path.get("body.body"); let methods: Array<Object> = path.get("body.body");
for (let method of methods) { for (let method of methods) {
if (method.node.kind === "constructorCall") { if (method.node.kind === "constructorCall") {

View File

@ -54,13 +54,13 @@ export default function ({ types: t }) {
if (path.isClass()) { if (path.isClass()) {
if (path.node.decorators) return true; if (path.node.decorators) return true;
for (let method of path.node.body.body) { for (let method of (path.node.body.body: Array<Object>)) {
if (method.decorators) { if (method.decorators) {
return true; return true;
} }
} }
} else if (path.isObjectExpression()) { } else if (path.isObjectExpression()) {
for (let prop of path.node.properties) { for (let prop of (path.node.properties: Array<Object>)) {
if (prop.decorators) { if (prop.decorators) {
return true; return true;
} }

View File

@ -1,6 +1,6 @@
export default function ({ types: t }) { export default function ({ types: t }) {
function statementList(key, path) { function statementList(key, path) {
let paths = path.get(key); let paths: Array = path.get(key);
for (let path of paths) { for (let path of paths) {
let func = path.node; let func = path.node;

View File

@ -1,5 +1,8 @@
/* eslint max-len: 0 */ /* eslint max-len: 0 */
import type NodePath from "babel-traverse";
import type Scope from "babel-traverse";
import type File from "../../../file";
import traverse from "babel-traverse"; import traverse from "babel-traverse";
import { visitor as tdzVisitor } from "./tdz"; import { visitor as tdzVisitor } from "./tdz";
import * as t from "babel-types"; import * as t from "babel-types";
@ -288,7 +291,7 @@ let loopVisitor = {
}; };
class BlockScoping { class BlockScoping {
constructor(loopPath, blockPath, parent, scope, file) { constructor(loopPath?: NodePath, blockPath: NodePath, parent: Object, scope: Scope, file: File) {
this.parent = parent; this.parent = parent;
this.scope = scope; this.scope = scope;
this.file = file; this.file = file;
@ -472,7 +475,7 @@ class BlockScoping {
* Push the closure to the body. * Push the closure to the body.
*/ */
buildClosure(ret, call) { buildClosure(ret: { type: "Identifier" }, call: { type: "CallExpression" }) {
let has = this.has; let has = this.has;
if (has.hasReturn || has.hasBreakContinue) { if (has.hasReturn || has.hasBreakContinue) {
this.buildHas(ret, call); this.buildHas(ret, call);
@ -570,7 +573,7 @@ class BlockScoping {
* later on. * later on.
*/ */
checkLoop() { checkLoop(): Object {
let state = { let state = {
hasBreakContinue: false, hasBreakContinue: false,
ignoreLabeless: false, ignoreLabeless: false,
@ -602,7 +605,7 @@ class BlockScoping {
* their declarations hoisted to before the closure wrapper. * their declarations hoisted to before the closure wrapper.
*/ */
pushDeclar(node) { pushDeclar(node: { type: "VariableDeclaration" }): Array<Object> {
let declars = []; let declars = [];
let names = t.getBindingIdentifiers(node); let names = t.getBindingIdentifiers(node);
for (let name in names) { for (let name in names) {
@ -624,7 +627,7 @@ class BlockScoping {
return replace; return replace;
} }
buildHas(ret, call) { buildHas(ret: { type: "Identifier" }, call: { type: "CallExpression" }) {
let body = this.body; let body = this.body;
body.push(t.variableDeclaration("var", [ body.push(t.variableDeclaration("var", [

View File

@ -1,5 +1,6 @@
/* eslint max-len: 0 */ /* eslint max-len: 0 */
import type { NodePath } from "babel-traverse";
import { visitors } from "babel-traverse"; import { visitors } from "babel-traverse";
import ReplaceSupers from "babel-helper-replace-supers"; import ReplaceSupers from "babel-helper-replace-supers";
import optimiseCall from "babel-helper-optimise-call-expression"; import optimiseCall from "babel-helper-optimise-call-expression";
@ -60,7 +61,7 @@ let findThisesVisitor = visitors.merge([noMethodVisitor, {
}]); }]);
export default class ClassTransformer { export default class ClassTransformer {
constructor(path, file) { constructor(path: NodePath, file) {
this.parent = path.parent; this.parent = path.parent;
this.scope = path.scope; this.scope = path.scope;
this.node = path.node; this.node = path.node;
@ -148,7 +149,7 @@ export default class ClassTransformer {
return func; return func;
} }
pushToMap(node, enumerable, kind = "value", scope) { pushToMap(node, enumerable, kind = "value", scope?) {
let mutatorMap; let mutatorMap;
if (node.static) { if (node.static) {
this.hasStaticDescriptors = true; this.hasStaticDescriptors = true;
@ -175,7 +176,7 @@ export default class ClassTransformer {
constructorMeMaybe() { constructorMeMaybe() {
let hasConstructor = false; let hasConstructor = false;
let paths = this.path.get("body.body"); let paths = this.path.get("body.body");
for (let path of paths) { for (let path of (paths: Array)) {
hasConstructor = path.equals("kind", "constructor"); hasConstructor = path.equals("kind", "constructor");
if (hasConstructor) break; if (hasConstructor) break;
} }
@ -216,7 +217,7 @@ export default class ClassTransformer {
} }
pushBody() { pushBody() {
let classBodyPaths = this.path.get("body.body"); let classBodyPaths: Array<Object> = this.path.get("body.body");
for (let path of classBodyPaths) { for (let path of classBodyPaths) {
let node = path.node; let node = path.node;
@ -450,7 +451,7 @@ export default class ClassTransformer {
* Push a method to its respective mutatorMap. * Push a method to its respective mutatorMap.
*/ */
pushMethod(node, path) { pushMethod(node: { type: "ClassMethod" }, path?: NodePath) {
let scope = path ? path.scope : this.scope; let scope = path ? path.scope : this.scope;
if (node.kind === "method") { if (node.kind === "method") {
@ -468,7 +469,7 @@ export default class ClassTransformer {
* Replace the constructor body of our class. * Replace the constructor body of our class.
*/ */
pushConstructor(replaceSupers, method, path) { pushConstructor(replaceSupers, method: { type: "ClassMethod" }, path: NodePath) {
this.bareSupers = replaceSupers.bareSupers; this.bareSupers = replaceSupers.bareSupers;
this.superReturns = replaceSupers.returns; this.superReturns = replaceSupers.returns;

View File

@ -89,7 +89,7 @@ export default function ({ types: t, template }) {
exit(path, state) { exit(path, state) {
let { node, parent, scope } = path; let { node, parent, scope } = path;
let hasComputed = false; let hasComputed = false;
for (let prop of node.properties) { for (let prop of (node.properties: Array<Object>)) {
hasComputed = prop.computed === true; hasComputed = prop.computed === true;
if (hasComputed) break; if (hasComputed) break;
} }

View File

@ -7,7 +7,7 @@ export default function ({ types: t }) {
*/ */
function variableDeclarationHasPattern(node) { function variableDeclarationHasPattern(node) {
for (let declar of node.declarations) { for (let declar of (node.declarations: Array)) {
if (t.isPattern(declar.id)) { if (t.isPattern(declar.id)) {
return true; return true;
} }
@ -20,7 +20,7 @@ export default function ({ types: t }) {
*/ */
function hasRest(pattern) { function hasRest(pattern) {
for (let elem of pattern.elements) { for (let elem of (pattern.elements: Array)) {
if (t.isRestElement(elem)) { if (t.isRestElement(elem)) {
return true; return true;
} }
@ -210,7 +210,7 @@ export default function ({ types: t }) {
if (pattern.elements.length > arr.elements.length) return; if (pattern.elements.length > arr.elements.length) return;
if (pattern.elements.length < arr.elements.length && !hasRest(pattern)) return false; if (pattern.elements.length < arr.elements.length && !hasRest(pattern)) return false;
for (let elem of pattern.elements) { for (let elem of (pattern.elements: Array)) {
// deopt on holes // deopt on holes
if (!elem) return false; if (!elem) return false;
@ -218,7 +218,7 @@ export default function ({ types: t }) {
if (t.isMemberExpression(elem)) return false; if (t.isMemberExpression(elem)) return false;
} }
for (let elem of arr.elements) { for (let elem of (arr.elements: Array)) {
// deopt on spread elements // deopt on spread elements
if (t.isSpreadElement(elem)) return false; if (t.isSpreadElement(elem)) return false;
} }

View File

@ -159,7 +159,7 @@ export default function () {
let hasExports = false; let hasExports = false;
let hasImports = false; let hasImports = false;
let body = path.get("body"); let body: Array<Object> = path.get("body");
let imports = Object.create(null); let imports = Object.create(null);
let exports = Object.create(null); let exports = Object.create(null);

View File

@ -92,7 +92,7 @@ export default function ({ types: t }) {
); );
} }
let body = path.get("body"); let body: Array<Object> = path.get("body");
let canHoist = true; let canHoist = true;
for (let path of body) { for (let path of body) {

View File

@ -30,7 +30,7 @@ export default function ({ types: t }) {
let objectRef; let objectRef;
let getObjectRef = () => objectRef = objectRef || path.scope.generateUidIdentifier("obj"); let getObjectRef = () => objectRef = objectRef || path.scope.generateUidIdentifier("obj");
let propPaths = path.get("properties"); let propPaths: Array = path.get("properties");
for (let propPath of propPaths) { for (let propPath of propPaths) {
if (propPath.isObjectProperty()) propPath = propPath.get("value"); if (propPath.isObjectProperty()) propPath = propPath.get("value");
Property(propPath, propPath.node, path.scope, getObjectRef, file); Property(propPath, propPath.node, path.scope, getObjectRef, file);

View File

@ -22,7 +22,7 @@ let buildCutOff = template(`
`); `);
function hasDefaults(node) { function hasDefaults(node) {
for (let param of node.params) { for (let param of (node.params: Array<Object>)) {
if (!t.isIdentifier(param)) return true; if (!t.isIdentifier(param)) return true;
} }
return false; return false;

View File

@ -2,7 +2,7 @@ import * as t from "babel-types";
export let visitor = { export let visitor = {
Function(path) { Function(path) {
let params = path.get("params"); let params: Array = path.get("params");
// If there's a rest param, no need to loop through it. Also, we need to // If there's a rest param, no need to loop through it. Also, we need to
// hoist one more level to get `declar` at the right spot. // hoist one more level to get `declar` at the right spot.

View File

@ -1,3 +1,4 @@
import type { NodePath } from "babel-traverse";
import { visitors } from "babel-traverse"; import { visitors } from "babel-traverse";
import * as destructuring from "./destructuring"; import * as destructuring from "./destructuring";
@ -9,7 +10,7 @@ export default function () {
visitor: visitors.merge([{ visitor: visitors.merge([{
ArrowFunctionExpression(path) { ArrowFunctionExpression(path) {
// default/rest visitors require access to `arguments` // default/rest visitors require access to `arguments`
let params = path.get("params"); let params: Array<NodePath> = path.get("params");
for (let param of params) { for (let param of params) {
if (param.isRestElement() || param.isAssignmentPattern()) { if (param.isRestElement() || param.isAssignmentPattern()) {
path.arrowFunctionToShadowed(); path.arrowFunctionToShadowed();

View File

@ -198,7 +198,7 @@ export let visitor = {
// There are only "shorthand" references // There are only "shorthand" references
if (!state.deopted && !state.references.length) { if (!state.deopted && !state.references.length) {
for (let {path, cause} of state.candidates) { for (let {path, cause} of (state.candidates: Array)) {
switch (cause) { switch (cause) {
case "indexGetter": case "indexGetter":
optimiseIndexGetter(path, argsId, state.offset); optimiseIndexGetter(path, argsId, state.offset);

View File

@ -16,7 +16,7 @@ export default function ({ types: t }) {
return false; return false;
} }
function build(props, scope, state) { function build(props: Array, scope, state) {
let nodes = []; let nodes = [];
let _props = []; let _props = [];

View File

@ -17,7 +17,7 @@ export default function ({ types: t }) {
let strings = []; let strings = [];
let raw = []; let raw = [];
for (let elem of quasi.quasis) { for (let elem of (quasi.quasis: Array)) {
strings.push(t.stringLiteral(elem.value.cooked)); strings.push(t.stringLiteral(elem.value.cooked));
raw.push(t.stringLiteral(elem.value.raw)); raw.push(t.stringLiteral(elem.value.raw));
} }
@ -37,11 +37,11 @@ export default function ({ types: t }) {
}, },
TemplateLiteral(path, state) { TemplateLiteral(path, state) {
let nodes = []; let nodes: Array<Object> = [];
let expressions = path.get("expressions"); let expressions = path.get("expressions");
for (let elem of path.node.quasis) { for (let elem of (path.node.quasis: Array)) {
nodes.push(t.stringLiteral(elem.value.cooked)); nodes.push(t.stringLiteral(elem.value.cooked));
let expr = expressions.shift(); let expr = expressions.shift();

View File

@ -6,7 +6,7 @@ export default function ({ types: t }) {
ObjectExpression(path, file) { ObjectExpression(path, file) {
let { node } = path; let { node } = path;
let hasAny = false; let hasAny = false;
for (let prop of node.properties) { for (let prop of (node.properties: Array)) {
if (prop.kind === "get" || prop.kind === "set") { if (prop.kind === "get" || prop.kind === "set") {
hasAny = true; hasAny = true;
break; break;

View File

@ -6,7 +6,7 @@ export default function ({ types: t }) {
visitor: { visitor: {
Program(path, { file: { ast: { comments } } }) { Program(path, { file: { ast: { comments } } }) {
for (let comment of comments) { for (let comment of (comments: Array<Object>)) {
if (comment.value.indexOf(FLOW_DIRECTIVE) >= 0) { if (comment.value.indexOf(FLOW_DIRECTIVE) >= 0) {
// remove flow directive // remove flow directive
comment.value = comment.value.replace(FLOW_DIRECTIVE, ""); comment.value = comment.value.replace(FLOW_DIRECTIVE, "");

View File

@ -1,6 +1,6 @@
export default function ({ types: t }) { export default function ({ types: t }) {
function hasSpread(node) { function hasSpread(node) {
for (let prop of node.properties) { for (let prop of (node.properties: Array<Object>)) {
if (t.isSpreadProperty(prop)) { if (t.isSpreadProperty(prop)) {
return true; return true;
} }
@ -24,7 +24,7 @@ export default function ({ types: t }) {
props = []; props = [];
} }
for (let prop of path.node.properties) { for (let prop of (path.node.properties: Array)) {
if (t.isSpreadProperty(prop)) { if (t.isSpreadProperty(prop)) {
push(); push();
args.push(prop.argument); args.push(prop.argument);

View File

@ -45,7 +45,7 @@ export default function ({ types: t }) {
let proto; let proto;
let { node } = path; let { node } = path;
for (let prop of node.properties) { for (let prop of (node.properties: Array)) {
if (isProtoKey(prop)) { if (isProtoKey(prop)) {
proto = prop.value; proto = prop.value;
pull(node.properties, prop); pull(node.properties, prop);

View File

@ -42,7 +42,7 @@ export default function ({ types: t }) {
} }
// props // props
for (let attr of open.attributes) { for (let attr of (open.attributes: Array<Object>)) {
if (isJSXAttributeOfName(attr, "key")) { if (isJSXAttributeOfName(attr, "key")) {
key = getAttributeValue(attr); key = getAttributeValue(attr);
} else { } else {

View File

@ -23,7 +23,7 @@ export default function ({ types: t }) {
let { file } = state; let { file } = state;
let id = state.opts.pragma || "React.createElement"; let id = state.opts.pragma || "React.createElement";
for (let comment of file.ast.comments) { for (let comment of (file.ast.comments: Array<Object>)) {
let matches = JSX_ANNOTATION_REGEX.exec(comment.value); let matches = JSX_ANNOTATION_REGEX.exec(comment.value);
if (matches) { if (matches) {
id = matches[1]; id = matches[1];

View File

@ -8,7 +8,7 @@ export default function () {
let { node } = path; let { node } = path;
for (let directive of node.directives) { for (let directive of (node.directives: Array<Object>)) {
if (directive.value.value === "use strict") return; if (directive.value.value === "use strict") return;
} }

View File

@ -10,7 +10,7 @@ import * as t from "babel-types";
let FROM_TEMPLATE = "_fromTemplate"; //Symbol(); // todo: probably wont get copied over let FROM_TEMPLATE = "_fromTemplate"; //Symbol(); // todo: probably wont get copied over
let TEMPLATE_SKIP = Symbol(); let TEMPLATE_SKIP = Symbol();
export default function (code, opts) { export default function (code: string, opts?: Object): Function {
// since we lazy parse the template, we get the current stack so we have the // since we lazy parse the template, we get the current stack so we have the
// original stack to append if it errors when parsing // original stack to append if it errors when parsing
let stack; let stack;
@ -52,7 +52,7 @@ export default function (code, opts) {
}; };
} }
function useTemplate(ast, nodes) { function useTemplate(ast, nodes?: Array<Object>) {
ast = cloneDeep(ast); ast = cloneDeep(ast);
let { program } = ast; let { program } = ast;

View File

@ -11,12 +11,18 @@ export default class TraversalContext {
this.opts = opts; this.opts = opts;
} }
parentPath: NodePath;
scope;
state;
opts;
queue: ?Array<NodePath> = null;
/** /**
* This method does a simple check to determine whether or not we really need to attempt * This method does a simple check to determine whether or not we really need to attempt
* visit a node. This will prevent us from constructing a NodePath. * visit a node. This will prevent us from constructing a NodePath.
*/ */
shouldVisit(node) { shouldVisit(node): boolean {
let opts = this.opts; let opts = this.opts;
if (opts.enter || opts.exit) return true; if (opts.enter || opts.exit) return true;
@ -24,7 +30,7 @@ export default class TraversalContext {
if (opts[node.type]) return true; if (opts[node.type]) return true;
// check if we're going to traverse into this node // check if we're going to traverse into this node
let keys = t.VISITOR_KEYS[node.type]; let keys: ?Array<string> = t.VISITOR_KEYS[node.type];
if (!keys || !keys.length) return false; if (!keys || !keys.length) return false;
// we need to traverse into this node so ensure that it has children to traverse into! // we need to traverse into this node so ensure that it has children to traverse into!
@ -35,7 +41,7 @@ export default class TraversalContext {
return false; return false;
} }
create(node, obj, key, listKey) { create(node, obj, key, listKey): NodePath {
return NodePath.get({ return NodePath.get({
parentPath: this.parentPath, parentPath: this.parentPath,
parent: node, parent: node,
@ -45,7 +51,7 @@ export default class TraversalContext {
}); });
} }
maybeQueue(path, notPriority) { maybeQueue(path, notPriority?: boolean) {
if (this.trap) { if (this.trap) {
throw new Error("Infinite cycle detected"); throw new Error("Infinite cycle detected");
} }
@ -76,7 +82,7 @@ export default class TraversalContext {
return this.visitQueue(queue); return this.visitQueue(queue);
} }
visitSingle(node, key) { visitSingle(node, key): boolean {
if (this.shouldVisit(node[key])) { if (this.shouldVisit(node[key])) {
return this.visitQueue([ return this.visitQueue([
this.create(node, node, key) this.create(node, node, key)
@ -86,7 +92,7 @@ export default class TraversalContext {
} }
} }
visitQueue(queue) { visitQueue(queue: Array<NodePath>) {
// set queue // set queue
this.queue = queue; this.queue = queue;
this.priorityQueue = []; this.priorityQueue = [];

View File

@ -11,7 +11,13 @@ export { default as Scope } from "./scope";
export { default as Hub } from "./hub"; export { default as Hub } from "./hub";
export { visitors }; export { visitors };
export default function traverse(parent, opts, scope, state, parentPath) { export default function traverse(
parent: Object | Array<Object>,
opts?: Object,
scope?: Object,
state: Object,
parentPath: Object,
) {
if (!parent) return; if (!parent) return;
if (!opts) opts = {}; if (!opts) opts = {};
@ -55,8 +61,8 @@ traverse.cheap = function (node, enter) {
} }
}; };
traverse.node = function (node, opts, scope, state, parentPath, skipKeys) { traverse.node = function (node: Object, opts: Object, scope: Object, state: Object, parentPath: Object, skipKeys?) {
let keys = t.VISITOR_KEYS[node.type]; let keys: Array = t.VISITOR_KEYS[node.type];
if (!keys) return; if (!keys) return;
let context = new TraversalContext(scope, opts, state, parentPath); let context = new TraversalContext(scope, opts, state, parentPath);
@ -66,7 +72,7 @@ traverse.node = function (node, opts, scope, state, parentPath, skipKeys) {
} }
}; };
const CLEAR_KEYS = t.COMMENT_KEYS.concat([ const CLEAR_KEYS: Array = t.COMMENT_KEYS.concat([
"tokens", "comments", "tokens", "comments",
"start", "end", "loc", "start", "end", "loc",
"raw", "rawValue" "raw", "rawValue"
@ -81,7 +87,7 @@ traverse.clearNode = function (node) {
if (key[0] === "_" && node[key] != null) node[key] = undefined; if (key[0] === "_" && node[key] != null) node[key] = undefined;
} }
let syms = Object.getOwnPropertySymbols(node); let syms: Array<Symbol> = Object.getOwnPropertySymbols(node);
for (let sym of syms) { for (let sym of syms) {
node[sym] = null; node[sym] = null;
} }
@ -99,7 +105,7 @@ function hasBlacklistedType(path, state) {
} }
} }
traverse.hasType = function (tree, scope, type, blacklistTypes) { traverse.hasType = function (tree: Object, scope: Object, type: Object, blacklistTypes: Array<string>): boolean {
// the node we're searching in is blacklisted // the node we're searching in is blacklisted
if (includes(blacklistTypes, tree.type)) return false; if (includes(blacklistTypes, tree.type)) return false;

View File

@ -1,6 +1,7 @@
// This file contains that retrieve or validate anything related to the current paths ancestry. // This file contains that retrieve or validate anything related to the current paths ancestry.
import * as t from "babel-types"; import * as t from "babel-types";
import NodePath from "./index";
/** /**
* Call the provided `callback` with the `NodePath`s of all the parents. * Call the provided `callback` with the `NodePath`s of all the parents.
@ -56,12 +57,12 @@ export function getStatementParent() {
* position and visiting key. * position and visiting key.
*/ */
export function getEarliestCommonAncestorFrom(paths) { export function getEarliestCommonAncestorFrom(paths: Array<NodePath>): NodePath {
return this.getDeepestCommonAncestorFrom(paths, function (deepest, i, ancestries) { return this.getDeepestCommonAncestorFrom(paths, function (deepest, i, ancestries) {
let earliest; let earliest;
let keys = t.VISITOR_KEYS[deepest.type]; let keys = t.VISITOR_KEYS[deepest.type];
for (let ancestry of ancestries) { for (let ancestry of (ancestries: Array)) {
let path = ancestry[i + 1]; let path = ancestry[i + 1];
// first path // first path
@ -98,7 +99,7 @@ export function getEarliestCommonAncestorFrom(paths) {
* TODO: Possible optimisation target. * TODO: Possible optimisation target.
*/ */
export function getDeepestCommonAncestorFrom(paths, filter) { export function getDeepestCommonAncestorFrom(paths: Array<NodePath>, filter?: Function): NodePath {
if (!paths.length) { if (!paths.length) {
return this; return this;
} }
@ -136,7 +137,7 @@ export function getDeepestCommonAncestorFrom(paths, filter) {
depthLoop: for (let i = 0; i < minDepth; i++) { depthLoop: for (let i = 0; i < minDepth; i++) {
let shouldMatch = first[i]; let shouldMatch = first[i];
for (let ancestry of ancestries) { for (let ancestry of (ancestries: Array)) {
if (ancestry[i] !== shouldMatch) { if (ancestry[i] !== shouldMatch) {
// we've hit a snag // we've hit a snag
break depthLoop; break depthLoop;
@ -177,7 +178,7 @@ export function getAncestry() {
export function inType() { export function inType() {
let path = this; let path = this;
while (path) { while (path) {
for (let type of arguments) { for (let type of (arguments: Array)) {
if (path.node.type === type) return true; if (path.node.type === type) return true;
} }
path = path.parentPath; path = path.parentPath;
@ -190,7 +191,7 @@ export function inType() {
* Check if we're inside a shadowed function. * Check if we're inside a shadowed function.
*/ */
export function inShadow(key) { export function inShadow(key?) {
let path = this; let path = this;
do { do {
if (path.isFunction()) { if (path.isFunction()) {

View File

@ -22,7 +22,7 @@ export function shareCommentsWithSiblings() {
next.addComments("leading", trailing); next.addComments("leading", trailing);
} }
export function addComment(type, content, line) { export function addComment(type, content, line?) {
this.addComments(type, [{ this.addComments(type, [{
type: line ? "CommentLine" : "CommentBlock", type: line ? "CommentLine" : "CommentBlock",
value: content value: content
@ -33,7 +33,7 @@ export function addComment(type, content, line) {
* Give node `comments` of the specified `type`. * Give node `comments` of the specified `type`.
*/ */
export function addComments(type, comments) { export function addComments(type: string, comments: Array) {
if (!comments) return; if (!comments) return;
let node = this.node; let node = this.node;

View File

@ -2,7 +2,7 @@
import traverse from "../index"; import traverse from "../index";
export function call(key) { export function call(key): boolean {
let opts = this.opts; let opts = this.opts;
this.debug(() => key); this.debug(() => key);
@ -18,7 +18,7 @@ export function call(key) {
return false; return false;
} }
export function _call(fns) { export function _call(fns?: Array<Function>): boolean {
if (!fns) return false; if (!fns) return false;
for (let fn of fns) { for (let fn of fns) {
@ -39,12 +39,12 @@ export function _call(fns) {
return false; return false;
} }
export function isBlacklisted() { export function isBlacklisted(): boolean {
let blacklist = this.opts.blacklist; let blacklist = this.opts.blacklist;
return blacklist && blacklist.indexOf(this.node.type) > -1; return blacklist && blacklist.indexOf(this.node.type) > -1;
} }
export function visit() { export function visit(): boolean {
if (!this.node) { if (!this.node) {
return false; return false;
} }

View File

@ -2,7 +2,7 @@
import * as t from "babel-types"; import * as t from "babel-types";
export function toComputedKey() { export function toComputedKey(): Object {
let node = this.node; let node = this.node;
let key; let key;

View File

@ -1,6 +1,8 @@
/* eslint indent: 0 */ /* eslint indent: 0 */
/* eslint max-len: 0 */ /* eslint max-len: 0 */
import type NodePath from "./index";
// This file contains Babels metainterpreter that can evaluate static code. // This file contains Babels metainterpreter that can evaluate static code.
/* eslint eqeqeq: 0 */ /* eslint eqeqeq: 0 */
@ -26,7 +28,7 @@ const INVALID_METHODS = ["random"];
* *
*/ */
export function evaluateTruthy() { export function evaluateTruthy(): boolean {
let res = this.evaluate(); let res = this.evaluate();
if (res.confident) return !!res.value; if (res.confident) return !!res.value;
} }
@ -46,9 +48,9 @@ export function evaluateTruthy() {
* *
*/ */
export function evaluate() { export function evaluate(): { confident: boolean; value: any } {
let confident = true; let confident = true;
let deoptPath; let deoptPath: ?NodePath;
function deopt(path) { function deopt(path) {
if (!confident) return; if (!confident) return;
@ -88,7 +90,7 @@ export function evaluate() {
let i = 0; let i = 0;
let exprs = path.get("expressions"); let exprs = path.get("expressions");
for (let elem of node.quasis) { for (let elem of (node.quasis: Array<Object>)) {
// not confident, evaluated an expression we don't like // not confident, evaluated an expression we don't like
if (!confident) break; if (!confident) break;
@ -178,7 +180,7 @@ export function evaluate() {
if (path.isArrayExpression()) { if (path.isArrayExpression()) {
let arr = []; let arr = [];
let elems = path.get("elements"); let elems: Array<NodePath> = path.get("elements");
for (let elem of elems) { for (let elem of elems) {
elem = elem.evaluate(); elem = elem.evaluate();

View File

@ -1,9 +1,10 @@
// This file contains methods responsible for dealing with/retrieving children or siblings. // This file contains methods responsible for dealing with/retrieving children or siblings.
import type TraversalContext from "../index";
import NodePath from "./index"; import NodePath from "./index";
import * as t from "babel-types"; import * as t from "babel-types";
export function getStatementParent() { export function getStatementParent(): ?NodePath {
let path = this; let path = this;
do { do {
@ -29,7 +30,7 @@ export function getOpposite() {
} }
} }
export function getCompletionRecords() { export function getCompletionRecords(): Array {
let paths = []; let paths = [];
let add = function (path) { let add = function (path) {
@ -66,7 +67,7 @@ export function getSibling(key) {
}); });
} }
export function get(key, context) { export function get(key: string, context?: boolean | TraversalContext): NodePath {
if (context === true) context = this.context; if (context === true) context = this.context;
let parts = key.split("."); let parts = key.split(".");
if (parts.length === 1) { // "foo" if (parts.length === 1) { // "foo"
@ -76,7 +77,7 @@ export function get(key, context) {
} }
} }
export function _getKey(key, context) { export function _getKey(key, context?) {
let node = this.node; let node = this.node;
let container = node[key]; let container = node[key];
@ -103,7 +104,7 @@ export function _getKey(key, context) {
export function _getPattern(parts, context) { export function _getPattern(parts, context) {
let path = this; let path = this;
for (let part of parts) { for (let part of (parts: Array)) {
if (part === ".") { if (part === ".") {
path = path.parentPath; path = path.parentPath;
} else { } else {
@ -117,10 +118,10 @@ export function _getPattern(parts, context) {
return path; return path;
} }
export function getBindingIdentifiers(duplicates) { export function getBindingIdentifiers(duplicates?) {
return t.getBindingIdentifiers(this.node, duplicates); return t.getBindingIdentifiers(this.node, duplicates);
} }
export function getOuterBindingIdentifiers(duplicates) { export function getOuterBindingIdentifiers(duplicates?) {
return t.getOuterBindingIdentifiers(this.node, duplicates); return t.getOuterBindingIdentifiers(this.node, duplicates);
} }

View File

@ -1,5 +1,7 @@
/* eslint max-len: 0 */ /* eslint max-len: 0 */
import type Hub from "../hub";
import type TraversalContext from "../context";
import * as virtualTypes from "./lib/virtual-types"; import * as virtualTypes from "./lib/virtual-types";
import buildDebug from "debug"; import buildDebug from "debug";
import { PATH_CACHE_KEY } from "./constants"; import { PATH_CACHE_KEY } from "./constants";
@ -12,7 +14,7 @@ import * as t from "babel-types";
let debug = buildDebug("babel"); let debug = buildDebug("babel");
export default class NodePath { export default class NodePath {
constructor(hub, parent) { constructor(hub: Hub, parent: Object) {
this.parent = parent; this.parent = parent;
this.hub = hub; this.hub = hub;
this.contexts = []; this.contexts = [];
@ -36,7 +38,29 @@ export default class NodePath {
this.typeAnnotation = null; this.typeAnnotation = null;
} }
static get({ hub, parentPath, parent, container, listKey, key }) { parent: Object;
hub: Hub;
contexts: Array<TraversalContext>;
data: Object;
shouldSkip: boolean;
shouldStop: boolean;
removed: boolean;
state: any;
opts: ?Object;
skipKeys: ?Object;
parentPath: ?NodePath;
context: TraversalContext;
container: ?Object | Array<Object>;
listKey: ?string;
inList: boolean;
parentKey: ?string;
key: ?string;
node: ?Object;
scope: Scope;
type: ?string;
typeAnnotation: ?Object;
static get({ hub, parentPath, parent, container, listKey, key }): NodePath {
if (!hub && parentPath) { if (!hub && parentPath) {
hub = parentPath.hub; hub = parentPath.hub;
} }
@ -78,7 +102,7 @@ export default class NodePath {
return path; return path;
} }
getScope(scope) { getScope(scope: Scope) {
let ourScope = scope; let ourScope = scope;
// we're entering a new scope so let's construct it! // we're entering a new scope so let's construct it!
@ -89,25 +113,25 @@ export default class NodePath {
return ourScope; return ourScope;
} }
setData(key, val) { setData(key: string, val: any): any {
return this.data[key] = val; return this.data[key] = val;
} }
getData(key, def) { getData(key: string, def?: any): any {
let val = this.data[key]; let val = this.data[key];
if (!val && def) val = this.data[key] = def; if (!val && def) val = this.data[key] = def;
return val; return val;
} }
buildCodeFrameError(msg, Error = SyntaxError) { buildCodeFrameError(msg: string, Error: typeof Error = SyntaxError): Error {
return this.hub.file.buildCodeFrameError(this.node, msg, Error); return this.hub.file.buildCodeFrameError(this.node, msg, Error);
} }
traverse(visitor, state) { traverse(visitor: Object, state?: any) {
traverse(this.node, visitor, this.scope, state, this); traverse(this.node, visitor, this.scope, state, this);
} }
mark(type, message) { mark(type: string, message: string) {
this.hub.file.metadata.marked.push({ this.hub.file.metadata.marked.push({
type, type,
message, message,
@ -115,12 +139,12 @@ export default class NodePath {
}); });
} }
set(key, node) { set(key: string, node: Object) {
t.validate(this.node, key, node); t.validate(this.node, key, node);
this.node[key] = node; this.node[key] = node;
} }
getPathLocation() { getPathLocation(): string {
let parts = []; let parts = [];
let path = this; let path = this;
do { do {
@ -131,7 +155,7 @@ export default class NodePath {
return parts.join("."); return parts.join(".");
} }
debug(buildMessage) { debug(buildMessage: Function) {
if (!debug.enabled) return; if (!debug.enabled) return;
debug(`${this.getPathLocation()} ${this.type}: ${buildMessage()}`); debug(`${this.getPathLocation()} ${this.type}: ${buildMessage()}`);
} }
@ -149,7 +173,7 @@ assign(NodePath.prototype, require("./modification"));
assign(NodePath.prototype, require("./family")); assign(NodePath.prototype, require("./family"));
assign(NodePath.prototype, require("./comments")); assign(NodePath.prototype, require("./comments"));
for (let type of t.TYPES) { for (let type of (t.TYPES: Array<string>)) {
let typeKey = `is${type}`; let typeKey = `is${type}`;
NodePath.prototype[typeKey] = function (opts) { NodePath.prototype[typeKey] = function (opts) {
return t[typeKey](this.node, opts); return t[typeKey](this.node, opts);

View File

@ -1,3 +1,4 @@
import type NodePath from "./index";
import * as inferers from "./inferers"; import * as inferers from "./inferers";
import * as t from "babel-types"; import * as t from "babel-types";
@ -5,7 +6,7 @@ import * as t from "babel-types";
* Infer the type of the current `NodePath`. * Infer the type of the current `NodePath`.
*/ */
export function getTypeAnnotation() { export function getTypeAnnotation(): Object {
if (this.typeAnnotation) return this.typeAnnotation; if (this.typeAnnotation) return this.typeAnnotation;
let type = this._getTypeAnnotation() || t.anyTypeAnnotation(); let type = this._getTypeAnnotation() || t.anyTypeAnnotation();
@ -17,7 +18,7 @@ export function getTypeAnnotation() {
* todo: split up this method * todo: split up this method
*/ */
export function _getTypeAnnotation() { export function _getTypeAnnotation(): ?Object {
let node = this.node; let node = this.node;
if (!node) { if (!node) {
@ -57,11 +58,11 @@ export function _getTypeAnnotation() {
} }
} }
export function isBaseType(baseName, soft) { export function isBaseType(baseName: string, soft?: boolean): boolean {
return _isBaseType(baseName, this.getTypeAnnotation(), soft); return _isBaseType(baseName, this.getTypeAnnotation(), soft);
} }
function _isBaseType(baseName, type, soft) { function _isBaseType(baseName: string, type?, soft?): boolean {
if (baseName === "string") { if (baseName === "string") {
return t.isStringTypeAnnotation(type); return t.isStringTypeAnnotation(type);
} else if (baseName === "number") { } else if (baseName === "number") {
@ -83,12 +84,12 @@ function _isBaseType(baseName, type, soft) {
} }
} }
export function couldBeBaseType(name) { export function couldBeBaseType(name: string): boolean {
let type = this.getTypeAnnotation(); let type = this.getTypeAnnotation();
if (t.isAnyTypeAnnotation(type)) return true; if (t.isAnyTypeAnnotation(type)) return true;
if (t.isUnionTypeAnnotation(type)) { if (t.isUnionTypeAnnotation(type)) {
for (let type2 of type.types) { for (let type2 of (type.types: Array<Object>)) {
if (t.isAnyTypeAnnotation(type2) || _isBaseType(name, type2, true)) { if (t.isAnyTypeAnnotation(type2) || _isBaseType(name, type2, true)) {
return true; return true;
} }
@ -99,7 +100,7 @@ export function couldBeBaseType(name) {
} }
} }
export function baseTypeStrictlyMatches(right) { export function baseTypeStrictlyMatches(right: NodePath) {
let left = this.getTypeAnnotation(); let left = this.getTypeAnnotation();
right = right.getTypeAnnotation(); right = right.getTypeAnnotation();
@ -108,7 +109,7 @@ export function baseTypeStrictlyMatches(right) {
} }
} }
export function isGenericType(genericName) { export function isGenericType(genericName: string): boolean {
let type = this.getTypeAnnotation(); let type = this.getTypeAnnotation();
return t.isGenericTypeAnnotation(type) && t.isIdentifier(type.id, { name: genericName }); return t.isGenericTypeAnnotation(type) && t.isIdentifier(type.id, { name: genericName });
} }

View File

@ -1,6 +1,7 @@
import type NodePath from "../index";
import * as t from "babel-types"; import * as t from "babel-types";
export default function (node) { export default function (node: Object) {
if (!this.isReferenced()) return; if (!this.isReferenced()) return;
// check if a binding exists of this value and if so then return a union type of all // check if a binding exists of this value and if so then return a union type of all
@ -75,7 +76,7 @@ function getTypeAnnotationBindingConstantViolations(path, name) {
constantViolations = constantViolations.concat(functionConstantViolations); constantViolations = constantViolations.concat(functionConstantViolations);
// push on inferred types of violated paths // push on inferred types of violated paths
for (let violation of constantViolations) { for (let violation of (constantViolations: Array<NodePath>)) {
types.push(violation.getTypeAnnotation()); types.push(violation.getTypeAnnotation());
} }
} }

View File

@ -1,5 +1,6 @@
// This file contains methods responsible for introspecting the current path for certain values. // This file contains methods responsible for introspecting the current path for certain values.
import type NodePath from "./index";
import includes from "lodash/collection/includes"; import includes from "lodash/collection/includes";
import * as t from "babel-types"; import * as t from "babel-types";
@ -10,7 +11,7 @@ import * as t from "babel-types";
* parsed nodes of `React.createClass` and `React["createClass"]`. * parsed nodes of `React.createClass` and `React["createClass"]`.
*/ */
export function matchesPattern(pattern, allowPartial) { export function matchesPattern(pattern: string, allowPartial?: boolean): boolean {
// not a member expression // not a member expression
if (!this.isMemberExpression()) return false; if (!this.isMemberExpression()) return false;
@ -66,7 +67,7 @@ export function matchesPattern(pattern, allowPartial) {
* if the array has any items, otherwise we just check if it's falsy. * if the array has any items, otherwise we just check if it's falsy.
*/ */
export function has(key) { export function has(key): boolean {
let val = this.node && this.node[key]; let val = this.node && this.node[key];
if (val && Array.isArray(val)) { if (val && Array.isArray(val)) {
return !!val.length; return !!val.length;
@ -93,7 +94,7 @@ export let is = has;
* Opposite of `has`. * Opposite of `has`.
*/ */
export function isnt(key) { export function isnt(key): boolean {
return !this.has(key); return !this.has(key);
} }
@ -101,7 +102,7 @@ export function isnt(key) {
* Check whether the path node `key` strict equals `value`. * Check whether the path node `key` strict equals `value`.
*/ */
export function equals(key, value) { export function equals(key, value): boolean {
return this.node[key] === value; return this.node[key] === value;
} }
@ -110,7 +111,7 @@ export function equals(key, value) {
* been removed yet we still internally know the type and need it to calculate node replacement. * been removed yet we still internally know the type and need it to calculate node replacement.
*/ */
export function isNodeType(type) { export function isNodeType(type: string): boolean {
return t.isType(this.type, type); return t.isType(this.type, type);
} }
@ -154,7 +155,7 @@ export function canSwapBetweenExpressionAndStatement(replacement) {
* Check whether the current path references a completion record * Check whether the current path references a completion record
*/ */
export function isCompletionRecord(allowInsideFunction) { export function isCompletionRecord(allowInsideFunction?) {
let path = this; let path = this;
let first = true; let first = true;
@ -319,7 +320,7 @@ export function _guessExecutionStatusRelativeToDifferentFunctions(targetFuncPare
// no references! // no references!
if (!binding.references) return "before"; if (!binding.references) return "before";
let referencePaths = binding.referencePaths; let referencePaths: Array<NodePath> = binding.referencePaths;
// verify that all of the references are calls // verify that all of the references are calls
for (let path of referencePaths) { for (let path of referencePaths) {
@ -357,7 +358,7 @@ export function resolve(dangerous, resolved) {
return this._resolve(dangerous, resolved) || this; return this._resolve(dangerous, resolved) || this;
} }
export function _resolve(dangerous, resolved) { export function _resolve(dangerous?, resolved?): ?NodePath {
// detect infinite recursion // detect infinite recursion
// todo: possibly have a max length on this just to be safe // todo: possibly have a max length on this just to be safe
if (resolved && resolved.indexOf(this) >= 0) return; if (resolved && resolved.indexOf(this) >= 0) return;
@ -403,7 +404,7 @@ export function _resolve(dangerous, resolved) {
if (target.isObjectExpression()) { if (target.isObjectExpression()) {
let props = target.get("properties"); let props = target.get("properties");
for (let prop of props) { for (let prop of (props: Array)) {
if (!prop.isProperty()) continue; if (!prop.isProperty()) continue;
let key = prop.get("key"); let key = prop.get("key");

View File

@ -18,7 +18,7 @@ export function remove() {
} }
export function _callRemovalHooks() { export function _callRemovalHooks() {
for (let fn of hooks) { for (let fn of (hooks: Array<Function>)) {
if (fn(this, this.parentPath)) return true; if (fn(this, this.parentPath)) return true;
} }
} }

View File

@ -22,7 +22,7 @@ let hoistVariablesVisitor = {
let exprs = []; let exprs = [];
for (let declar of path.node.declarations) { for (let declar of (path.node.declarations: Array<Object>)) {
if (declar.init) { if (declar.init) {
exprs.push(t.expressionStatement( exprs.push(t.expressionStatement(
t.assignmentExpression("=", declar.id, declar.init) t.assignmentExpression("=", declar.id, declar.init)
@ -42,7 +42,7 @@ let hoistVariablesVisitor = {
* - Remove the current node. * - Remove the current node.
*/ */
export function replaceWithMultiple(nodes) { export function replaceWithMultiple(nodes: Array<Object>) {
this.resync(); this.resync();
nodes = this._verifyNodeList(nodes); nodes = this._verifyNodeList(nodes);
@ -178,7 +178,7 @@ export function _replaceWith(node) {
* extremely important to retain original semantics. * extremely important to retain original semantics.
*/ */
export function replaceExpressionWithStatements(nodes) { export function replaceExpressionWithStatements(nodes: Array<Object>) {
this.resync(); this.resync();
let toSequenceExpression = t.toSequenceExpression(nodes, this.scope); let toSequenceExpression = t.toSequenceExpression(nodes, this.scope);
@ -206,7 +206,7 @@ export function replaceExpressionWithStatements(nodes) {
this.traverse(hoistVariablesVisitor); this.traverse(hoistVariablesVisitor);
// add implicit returns to all ending expression statements // add implicit returns to all ending expression statements
let completionRecords = this.get("callee").getCompletionRecords(); let completionRecords: Array<NodePath> = this.get("callee").getCompletionRecords();
for (let path of completionRecords) { for (let path of completionRecords) {
if (!path.isExpressionStatement()) continue; if (!path.isExpressionStatement()) continue;
@ -229,7 +229,7 @@ export function replaceExpressionWithStatements(nodes) {
} }
} }
export function replaceInline(nodes) { export function replaceInline(nodes: Object | Array<Object>) {
this.resync(); this.resync();
if (Array.isArray(nodes)) { if (Array.isArray(nodes)) {

View File

@ -1,3 +1,4 @@
import type NodePath from "../path";
/** /**
* This class is responsible for a binding inside of a scope. * This class is responsible for a binding inside of a scope.
@ -35,12 +36,24 @@ export default class Binding {
} }
} }
constantViolations: Array<NodePath>;
constant: boolean;
referencePaths: Array<NodePath>;
referenced: boolean;
references: number;
hasDeoptedValue: boolean;
hasValue: boolean;
value: any;
deoptValue() { deoptValue() {
this.clearValue(); this.clearValue();
this.hasDeoptedValue = true; this.hasDeoptedValue = true;
} }
setValue(value) { setValue(value: any) {
if (this.hasDeoptedValue) return; if (this.hasDeoptedValue) return;
this.hasValue = true; this.hasValue = true;
this.value = value; this.value = value;
@ -56,7 +69,7 @@ export default class Binding {
* Register a constant violation with the provided `path`. * Register a constant violation with the provided `path`.
*/ */
reassign(path) { reassign(path: Object) {
this.constant = false; this.constant = false;
this.constantViolations.push(path); this.constantViolations.push(path);
} }
@ -65,7 +78,7 @@ export default class Binding {
* Increment the amount of references to this binding. * Increment the amount of references to this binding.
*/ */
reference(path) { reference(path: NodePath) {
this.referenced = true; this.referenced = true;
this.references++; this.references++;
this.referencePaths.push(path); this.referencePaths.push(path);

View File

@ -3,6 +3,7 @@
import includes from "lodash/collection/includes"; import includes from "lodash/collection/includes";
import repeating from "repeating"; import repeating from "repeating";
import Renamer from "./lib/renamer"; import Renamer from "./lib/renamer";
import type NodePath from "../path";
import traverse from "../index"; import traverse from "../index";
import defaults from "lodash/object/defaults"; import defaults from "lodash/object/defaults";
import * as messages from "babel-messages"; import * as messages from "babel-messages";
@ -48,7 +49,7 @@ function matchesParent(scope, parentScope) {
} }
function getCacheMultiple(node, parentScope, self, singleCache) { function getCacheMultiple(node, parentScope, self, singleCache) {
let scopes = node[CACHE_MULTIPLE_KEY] = node[CACHE_MULTIPLE_KEY] || []; let scopes: Array<Scope> = node[CACHE_MULTIPLE_KEY] = node[CACHE_MULTIPLE_KEY] || [];
if (singleCache) { if (singleCache) {
// we have a scope assocation miss so push it onto our scopes // we have a scope assocation miss so push it onto our scopes
@ -68,7 +69,7 @@ function getCacheMultiple(node, parentScope, self, singleCache) {
let collectorVisitor = { let collectorVisitor = {
For(path) { For(path) {
for (let key of t.FOR_INIT_KEYS) { for (let key of (t.FOR_INIT_KEYS: Array)) {
let declar = path.get(key); let declar = path.get(key);
if (declar.isVar()) path.scope.getFunctionParent().registerBinding("var", declar); if (declar.isVar()) path.scope.getFunctionParent().registerBinding("var", declar);
} }
@ -106,7 +107,7 @@ let collectorVisitor = {
let binding = scope.getBinding(id.name); let binding = scope.getBinding(id.name);
if (binding) binding.reference(); if (binding) binding.reference();
} else if (t.isVariableDeclaration(declar)) { } else if (t.isVariableDeclaration(declar)) {
for (let decl of declar.declarations) { for (let decl of (declar.declarations: Array<Object>)) {
let ids = t.getBindingIdentifiers(decl); let ids = t.getBindingIdentifiers(decl);
for (let name in ids) { for (let name in ids) {
let binding = scope.getBinding(name); let binding = scope.getBinding(name);
@ -152,7 +153,7 @@ let collectorVisitor = {
Block(path) { Block(path) {
let paths = path.get("body"); let paths = path.get("body");
for (let bodyPath of paths) { for (let bodyPath of (paths: Array)) {
if (bodyPath.isFunctionDeclaration()) { if (bodyPath.isFunctionDeclaration()) {
path.scope.getBlockParent().registerDeclaration(bodyPath); path.scope.getBlockParent().registerDeclaration(bodyPath);
} }
@ -169,7 +170,7 @@ export default class Scope {
* within. * within.
*/ */
constructor(path, parentScope) { constructor(path: NodePath, parentScope?: Scope) {
if (parentScope && parentScope.block === path.node) { if (parentScope && parentScope.block === path.node) {
return parentScope; return parentScope;
} }
@ -207,7 +208,7 @@ export default class Scope {
* Traverse node with current scope and path. * Traverse node with current scope and path.
*/ */
traverse(node, opts, state) { traverse(node: Object, opts: Object, state?) {
traverse(node, opts, this, state, this.path); traverse(node, opts, this, state, this.path);
} }
@ -215,7 +216,7 @@ export default class Scope {
* Generate a unique identifier and add it to the current scope. * Generate a unique identifier and add it to the current scope.
*/ */
generateDeclaredUidIdentifier(name = "temp") { generateDeclaredUidIdentifier(name: string = "temp") {
let id = this.generateUidIdentifier(name); let id = this.generateUidIdentifier(name);
this.push({ id }); this.push({ id });
return id; return id;
@ -225,7 +226,7 @@ export default class Scope {
* Generate a unique identifier. * Generate a unique identifier.
*/ */
generateUidIdentifier(name = "temp") { generateUidIdentifier(name: string = "temp") {
return t.identifier(this.generateUid(name)); return t.identifier(this.generateUid(name));
} }
@ -233,7 +234,7 @@ export default class Scope {
* Generate a unique `_id1` binding. * Generate a unique `_id1` binding.
*/ */
generateUid(name = "temp") { generateUid(name: string = "temp") {
name = t.toIdentifier(name).replace(/^_+/, "").replace(/[0-9]+$/g, ""); name = t.toIdentifier(name).replace(/^_+/, "").replace(/[0-9]+$/g, "");
let uid; let uid;
@ -264,7 +265,7 @@ export default class Scope {
* Generate a unique identifier based on a node. * Generate a unique identifier based on a node.
*/ */
generateUidIdentifierBasedOnNode(parent, defaultName) { generateUidIdentifierBasedOnNode(parent: Object, defaultName?: String): Object {
let node = parent; let node = parent;
if (t.isAssignmentExpression(parent)) { if (t.isAssignmentExpression(parent)) {
@ -282,7 +283,7 @@ export default class Scope {
if (node.source) { if (node.source) {
add(node.source); add(node.source);
} else if (node.specifiers && node.specifiers.length) { } else if (node.specifiers && node.specifiers.length) {
for (let specifier of node.specifiers) { for (let specifier of (node.specifiers: Array)) {
add(specifier); add(specifier);
} }
} else if (node.declaration) { } else if (node.declaration) {
@ -300,7 +301,7 @@ export default class Scope {
} else if (t.isCallExpression(node)) { } else if (t.isCallExpression(node)) {
add(node.callee); add(node.callee);
} else if (t.isObjectExpression(node) || t.isObjectPattern(node)) { } else if (t.isObjectExpression(node) || t.isObjectPattern(node)) {
for (let prop of node.properties) { for (let prop of (node.properties: Array)) {
add(prop.key || prop.argument); add(prop.key || prop.argument);
} }
} }
@ -324,7 +325,7 @@ export default class Scope {
* - Bound identifiers * - Bound identifiers
*/ */
isStatic(node) { isStatic(node: Object): boolean {
if (t.isThisExpression(node) || t.isSuper(node)) { if (t.isThisExpression(node) || t.isSuper(node)) {
return true; return true;
} }
@ -345,7 +346,7 @@ export default class Scope {
* Possibly generate a memoised identifier if it is not static and has consequences. * Possibly generate a memoised identifier if it is not static and has consequences.
*/ */
maybeGenerateMemoised(node, dontPush) { maybeGenerateMemoised(node: Object, dontPush?: boolean): ?Object {
if (this.isStatic(node)) { if (this.isStatic(node)) {
return null; return null;
} else { } else {
@ -355,7 +356,7 @@ export default class Scope {
} }
} }
checkBlockScopedCollisions(local, kind, name, id) { checkBlockScopedCollisions(local, kind: string, name: string, id: Object) {
// ignore parameters // ignore parameters
if (kind === "param") return; if (kind === "param") return;
@ -375,7 +376,7 @@ export default class Scope {
} }
} }
rename(oldName, newName, block) { rename(oldName: string, newName: string, block?) {
let binding = this.getBinding(oldName); let binding = this.getBinding(oldName);
if (binding) { if (binding) {
newName = newName || this.generateUidIdentifier(oldName).name; newName = newName || this.generateUidIdentifier(oldName).name;
@ -409,7 +410,7 @@ export default class Scope {
console.log(sep); console.log(sep);
} }
toArray(node, i) { toArray(node: Object, i?: number) {
let file = this.hub.file; let file = this.hub.file;
if (t.isIdentifier(node)) { if (t.isIdentifier(node)) {
@ -449,21 +450,21 @@ export default class Scope {
return t.callExpression(file.addHelper(helperName), args); return t.callExpression(file.addHelper(helperName), args);
} }
registerDeclaration(path) { registerDeclaration(path: NodePath) {
if (path.isLabeledStatement()) { if (path.isLabeledStatement()) {
this.registerBinding("label", path); this.registerBinding("label", path);
} else if (path.isFunctionDeclaration()) { } else if (path.isFunctionDeclaration()) {
this.registerBinding("hoisted", path.get("id"), path); this.registerBinding("hoisted", path.get("id"), path);
} else if (path.isVariableDeclaration()) { } else if (path.isVariableDeclaration()) {
let declarations = path.get("declarations"); let declarations = path.get("declarations");
for (let declar of declarations) { for (let declar of (declarations: Array)) {
this.registerBinding(path.node.kind, declar); this.registerBinding(path.node.kind, declar);
} }
} else if (path.isClassDeclaration()) { } else if (path.isClassDeclaration()) {
this.registerBinding("let", path); this.registerBinding("let", path);
} else if (path.isImportDeclaration()) { } else if (path.isImportDeclaration()) {
let specifiers = path.get("specifiers"); let specifiers = path.get("specifiers");
for (let specifier of specifiers) { for (let specifier of (specifiers: Array)) {
this.registerBinding("module", specifier); this.registerBinding("module", specifier);
} }
} else if (path.isExportDeclaration()) { } else if (path.isExportDeclaration()) {
@ -484,7 +485,7 @@ export default class Scope {
} }
} }
registerConstantViolation(path) { registerConstantViolation(path: NodePath) {
let ids = path.getBindingIdentifiers(); let ids = path.getBindingIdentifiers();
for (let name in ids) { for (let name in ids) {
let binding = this.getBinding(name); let binding = this.getBinding(name);
@ -492,11 +493,11 @@ export default class Scope {
} }
} }
registerBinding(kind, path, bindingPath = path) { registerBinding(kind: string, path: NodePath, bindingPath = path) {
if (!kind) throw new ReferenceError("no `kind`"); if (!kind) throw new ReferenceError("no `kind`");
if (path.isVariableDeclaration()) { if (path.isVariableDeclaration()) {
let declarators = path.get("declarations"); let declarators: Array<NodePath> = path.get("declarations");
for (let declar of declarators) { for (let declar of declarators) {
this.registerBinding(kind, declar); this.registerBinding(kind, declar);
} }
@ -507,7 +508,7 @@ export default class Scope {
let ids = path.getBindingIdentifiers(true); let ids = path.getBindingIdentifiers(true);
for (let name in ids) { for (let name in ids) {
for (let id of ids[name]) { for (let id of (ids[name]: Array<Object>)) {
let local = this.getOwnBinding(name); let local = this.getOwnBinding(name);
if (local) { if (local) {
// same identifier so continue safely as we're likely trying to register it // same identifier so continue safely as we're likely trying to register it
@ -530,11 +531,11 @@ export default class Scope {
} }
} }
addGlobal(node) { addGlobal(node: Object) {
this.globals[node.name] = node; this.globals[node.name] = node;
} }
hasUid(name) { hasUid(name): boolean {
let scope = this; let scope = this;
do { do {
@ -544,7 +545,7 @@ export default class Scope {
return false; return false;
} }
hasGlobal(name) { hasGlobal(name: string): boolean {
let scope = this; let scope = this;
do { do {
@ -554,7 +555,7 @@ export default class Scope {
return false; return false;
} }
hasReference(name) { hasReference(name: string): boolean {
let scope = this; let scope = this;
do { do {
@ -564,7 +565,7 @@ export default class Scope {
return false; return false;
} }
isPure(node, constantsOnly) { isPure(node, constantsOnly?: boolean) {
if (t.isIdentifier(node)) { if (t.isIdentifier(node)) {
let binding = this.getBinding(node.name); let binding = this.getBinding(node.name);
if (!binding) return false; if (!binding) return false;
@ -581,12 +582,12 @@ export default class Scope {
} else if (t.isBinary(node)) { } else if (t.isBinary(node)) {
return this.isPure(node.left, constantsOnly) && this.isPure(node.right, constantsOnly); return this.isPure(node.left, constantsOnly) && this.isPure(node.right, constantsOnly);
} else if (t.isArrayExpression(node)) { } else if (t.isArrayExpression(node)) {
for (let elem of node.elements) { for (let elem of (node.elements: Array<Object>)) {
if (!this.isPure(elem, constantsOnly)) return false; if (!this.isPure(elem, constantsOnly)) return false;
} }
return true; return true;
} else if (t.isObjectExpression(node)) { } else if (t.isObjectExpression(node)) {
for (let prop of node.properties) { for (let prop of (node.properties: Array<Object>)) {
if (!this.isPure(prop, constantsOnly)) return false; if (!this.isPure(prop, constantsOnly)) return false;
} }
return true; return true;
@ -655,7 +656,7 @@ export default class Scope {
// ForStatement - left, init // ForStatement - left, init
if (path.isLoop()) { if (path.isLoop()) {
for (let key of t.FOR_INIT_KEYS) { for (let key of (t.FOR_INIT_KEYS: Array<string>)) {
let node = path.get(key); let node = path.get(key);
if (node.isBlockScoped()) this.registerBinding(node.node.kind, node); if (node.isBlockScoped()) this.registerBinding(node.node.kind, node);
} }
@ -680,7 +681,7 @@ export default class Scope {
// Function - params, rest // Function - params, rest
if (path.isFunction()) { if (path.isFunction()) {
let params = path.get("params"); let params: Array<NodePath> = path.get("params");
for (let param of params) { for (let param of params) {
this.registerBinding("param", param); this.registerBinding("param", param);
} }
@ -739,7 +740,13 @@ export default class Scope {
} }
} }
push(opts) { push(opts: {
id: Object;
init: ?Object;
unique: ?boolean;
_blockHoist: ?number;
kind: "var" | "let";
}) {
let path = this.path; let path = this.path;
if (!path.isBlockStatement() && !path.isProgram()) { if (!path.isBlockStatement() && !path.isProgram()) {
@ -824,7 +831,7 @@ export default class Scope {
* Walks the scope tree and gathers **all** bindings. * Walks the scope tree and gathers **all** bindings.
*/ */
getAllBindings() { getAllBindings(): Object {
let ids = Object.create(null); let ids = Object.create(null);
let scope = this; let scope = this;
@ -840,10 +847,10 @@ export default class Scope {
* Walks the scope tree and gathers all declarations of `kind`. * Walks the scope tree and gathers all declarations of `kind`.
*/ */
getAllBindingsOfKind() { getAllBindingsOfKind(): Object {
let ids = Object.create(null); let ids = Object.create(null);
for (let kind of arguments) { for (let kind of (arguments: Array)) {
let scope = this; let scope = this;
do { do {
for (let name in scope.bindings) { for (let name in scope.bindings) {
@ -857,11 +864,11 @@ export default class Scope {
return ids; return ids;
} }
bindingIdentifierEquals(name, node) { bindingIdentifierEquals(name: string, node: Object): boolean {
return this.getBindingIdentifier(name) === node; return this.getBindingIdentifier(name) === node;
} }
getBinding(name) { getBinding(name: string) {
let scope = this; let scope = this;
do { do {
@ -870,25 +877,25 @@ export default class Scope {
} while (scope = scope.parent); } while (scope = scope.parent);
} }
getOwnBinding(name) { getOwnBinding(name: string) {
return this.bindings[name]; return this.bindings[name];
} }
getBindingIdentifier(name) { getBindingIdentifier(name: string) {
let info = this.getBinding(name); let info = this.getBinding(name);
return info && info.identifier; return info && info.identifier;
} }
getOwnBindingIdentifier(name) { getOwnBindingIdentifier(name: string) {
let binding = this.bindings[name]; let binding = this.bindings[name];
return binding && binding.identifier; return binding && binding.identifier;
} }
hasOwnBinding(name) { hasOwnBinding(name: string) {
return !!this.getOwnBinding(name); return !!this.getOwnBinding(name);
} }
hasBinding(name, noGlobals) { hasBinding(name: string, noGlobals?) {
if (!name) return false; if (!name) return false;
if (this.hasOwnBinding(name)) return true; if (this.hasOwnBinding(name)) return true;
if (this.parentHasBinding(name, noGlobals)) return true; if (this.parentHasBinding(name, noGlobals)) return true;
@ -898,7 +905,7 @@ export default class Scope {
return false; return false;
} }
parentHasBinding(name, noGlobals) { parentHasBinding(name: string, noGlobals?) {
return this.parent && this.parent.hasBinding(name, noGlobals); return this.parent && this.parent.hasBinding(name, noGlobals);
} }
@ -915,11 +922,11 @@ export default class Scope {
} }
} }
removeOwnBinding(name) { removeOwnBinding(name: string) {
delete this.bindings[name]; delete this.bindings[name];
} }
removeBinding(name) { removeBinding(name: string) {
// clear literal binding // clear literal binding
let info = this.getBinding(name); let info = this.getBinding(name);
if (info) { if (info) {

View File

@ -27,7 +27,7 @@ export function explode(visitor) {
for (let nodeType in visitor) { for (let nodeType in visitor) {
if (shouldIgnoreKey(nodeType)) continue; if (shouldIgnoreKey(nodeType)) continue;
let parts = nodeType.split("|"); let parts: Array<string> = nodeType.split("|");
if (parts.length === 1) continue; if (parts.length === 1) continue;
let fns = visitor[nodeType]; let fns = visitor[nodeType];
@ -52,7 +52,7 @@ export function explode(visitor) {
ensureCallbackArrays(visitor); ensureCallbackArrays(visitor);
// add type wrappers // add type wrappers
for (let nodeType of Object.keys(visitor)) { for (let nodeType of (Object.keys(visitor): Array)) {
if (shouldIgnoreKey(nodeType)) continue; if (shouldIgnoreKey(nodeType)) continue;
let wrapper = virtualTypes[nodeType]; let wrapper = virtualTypes[nodeType];
@ -68,7 +68,7 @@ export function explode(visitor) {
delete visitor[nodeType]; delete visitor[nodeType];
if (wrapper.types) { if (wrapper.types) {
for (let type of wrapper.types) { for (let type of (wrapper.types: Array<string>)) {
// merge the visitor if necessary or just put it back in // merge the visitor if necessary or just put it back in
if (visitor[type]) { if (visitor[type]) {
mergePair(visitor[type], fns); mergePair(visitor[type], fns);
@ -87,7 +87,7 @@ export function explode(visitor) {
let fns = visitor[nodeType]; let fns = visitor[nodeType];
let aliases = t.FLIPPED_ALIAS_KEYS[nodeType]; let aliases: ?Array<string> = t.FLIPPED_ALIAS_KEYS[nodeType];
let deprecratedKey = t.DEPRECATED_KEYS[nodeType]; let deprecratedKey = t.DEPRECATED_KEYS[nodeType];
if (deprecratedKey) { if (deprecratedKey) {
@ -162,7 +162,7 @@ function validateVisitorMethods(path, val) {
} }
} }
export function merge(visitors, states = []) { export function merge(visitors: Array, states: Array = []) {
let rootVisitor = {}; let rootVisitor = {};
for (let i = 0; i < visitors.length; i++) { for (let i = 0; i < visitors.length; i++) {

View File

@ -1,3 +1,4 @@
/* @flow */
/* eslint max-len: 0 */ /* eslint max-len: 0 */
import * as t from "../index"; import * as t from "../index";

View File

@ -97,7 +97,7 @@ export function is(type, node, opts) {
export function isType(nodeType, targetType) { export function isType(nodeType, targetType) {
if (nodeType === targetType) return true; if (nodeType === targetType) return true;
let aliases = t.FLIPPED_ALIAS_KEYS[targetType]; let aliases: ?Array<string> = t.FLIPPED_ALIAS_KEYS[targetType];
if (aliases) { if (aliases) {
if (aliases[0] === nodeType) return true; if (aliases[0] === nodeType) return true;

View File

@ -197,7 +197,7 @@ export function isVar(node) {
* Check if the input `specifier` is a `default` import or export. * Check if the input `specifier` is a `default` import or export.
*/ */
export function isSpecifierDefault(specifier) { export function isSpecifierDefault(specifier: Object): boolean {
return t.isImportDefaultSpecifier(specifier) || return t.isImportDefaultSpecifier(specifier) ||
t.isIdentifier(specifier.imported || specifier.exported, { name: "default" }); t.isIdentifier(specifier.imported || specifier.exported, { name: "default" });
} }

View File

@ -873,7 +873,7 @@ pp.parseFunctionBody = function (node, allowExpression) {
// normal function // normal function
if (!isExpression && node.body.directives.length) { if (!isExpression && node.body.directives.length) {
for (let directive of node.body.directives) { for (let directive of (node.body.directives: Array<Object>)) {
if (directive.value.value === "use strict") { if (directive.value.value === "use strict") {
isStrict = true; isStrict = true;
checkLVal = true; checkLVal = true;
@ -895,7 +895,7 @@ pp.parseFunctionBody = function (node, allowExpression) {
if (node.id) { if (node.id) {
this.checkLVal(node.id, true); this.checkLVal(node.id, true);
} }
for (let param of node.params) { for (let param of (node.params: Array<Object>)) {
this.checkLVal(param, true, nameHash); this.checkLVal(param, true, nameHash);
} }
this.state.strict = oldStrict; this.state.strict = oldStrict;

View File

@ -20,7 +20,7 @@ pp.toAssignable = function (node, isBinding) {
case "ObjectExpression": case "ObjectExpression":
node.type = "ObjectPattern"; node.type = "ObjectPattern";
for (let prop of node.properties) { for (let prop of (node.properties: Array<Object>)) {
if (prop.type === "ObjectMethod") { if (prop.type === "ObjectMethod") {
if (prop.kind === "get" || prop.kind === "set") { if (prop.kind === "get" || prop.kind === "set") {
this.raise(prop.key.start, "Object pattern can't contain getter or setter"); this.raise(prop.key.start, "Object pattern can't contain getter or setter");
@ -225,14 +225,14 @@ pp.checkLVal = function (expr, isBinding, checkClashes) {
break; break;
case "ObjectPattern": case "ObjectPattern":
for (let prop of expr.properties) { for (let prop of (expr.properties: Array<Object>)) {
if (prop.type === "ObjectProperty") prop = prop.value; if (prop.type === "ObjectProperty") prop = prop.value;
this.checkLVal(prop, isBinding, checkClashes); this.checkLVal(prop, isBinding, checkClashes);
} }
break; break;
case "ArrayPattern": case "ArrayPattern":
for (let elem of expr.elements) { for (let elem of (expr.elements: Array<Object>)) {
if (elem) this.checkLVal(elem, isBinding, checkClashes); if (elem) this.checkLVal(elem, isBinding, checkClashes);
} }
break; break;

View File

@ -6,14 +6,19 @@ import { SourceLocation } from "../util/location";
const pp = Parser.prototype; const pp = Parser.prototype;
class Node { class Node {
constructor(pos, loc) { constructor(pos?: number, loc?: SourceLocation) {
this.type = ""; this.type = "";
this.start = pos; this.start = pos;
this.end = 0; this.end = 0;
this.loc = new SourceLocation(loc); this.loc = new SourceLocation(loc);
} }
__clone() { type: string;
start: ?number;
end: number;
loc: SourceLocation;
__clone(): Node {
let node2 = new Node; let node2 = new Node;
for (let key in this) node2[key] = this[key]; for (let key in this) node2[key] = this[key];
return node2; return node2;

View File

@ -404,7 +404,7 @@ pp.parseEmptyStatement = function (node) {
}; };
pp.parseLabeledStatement = function (node, maybeName, expr) { pp.parseLabeledStatement = function (node, maybeName, expr) {
for (let label of this.state.labels) { for (let label of (this.state.labels: Array<Object>)){
if (label.name === maybeName) { if (label.name === maybeName) {
this.raise(expr.start, `Label '${maybeName}' is already declared`); this.raise(expr.start, `Label '${maybeName}' is already declared`);
} }
@ -438,7 +438,7 @@ pp.parseExpressionStatement = function (node, expr) {
// strict"` declarations when `allowStrict` is true (used for // strict"` declarations when `allowStrict` is true (used for
// function bodies). // function bodies).
pp.parseBlock = function (allowDirectives) { pp.parseBlock = function (allowDirectives?) {
let node = this.startNode(); let node = this.startNode();
this.expect(tt.braceL); this.expect(tt.braceL);
this.parseBlockBody(node, allowDirectives, false, tt.braceR); this.parseBlockBody(node, allowDirectives, false, tt.braceR);
@ -860,7 +860,7 @@ pp.parseExportSpecifiersMaybe = function (node) {
} }
}; };
pp.parseExportFrom = function (node, expect) { pp.parseExportFrom = function (node, expect?) {
if (this.eatContextual("from")) { if (this.eatContextual("from")) {
node.source = this.match(tt.string) ? this.parseExprAtom() : this.unexpected(); node.source = this.match(tt.string) ? this.parseExprAtom() : this.unexpected();
this.checkExport(node); this.checkExport(node);

View File

@ -704,7 +704,7 @@ export default function (instance) {
}); });
instance.extend("parseParenItem", function () { instance.extend("parseParenItem", function () {
return function (node, startLoc, startPos, forceArrow) { return function (node, startLoc, startPos, forceArrow?) {
let canBeArrow = this.state.potentialArrowAt = startPos; let canBeArrow = this.state.potentialArrowAt = startPos;
if (this.match(tt.colon)) { if (this.match(tt.colon)) {
let typeCastNode = this.startNodeAt(startLoc, startPos); let typeCastNode = this.startNodeAt(startLoc, startPos);

View File

@ -1,83 +1,129 @@
import type { TokContext } from "./context";
import type { Token } from "./index";
import { Position } from "../util/location"; import { Position } from "../util/location";
import { types as ct } from "./context"; import { types as ct } from "./context";
import { types as tt } from "./types"; import { types as tt } from "./types";
export default class State { export default class State {
init(options, input) { init(options: Object, input: string) {
// TODO
this.strict = options.strictMode === false ? false : options.sourceType === "module"; this.strict = options.strictMode === false ? false : options.sourceType === "module";
// TODO
this.input = input; this.input = input;
// Used to signify the start of a potential arrow function
this.potentialArrowAt = -1; this.potentialArrowAt = -1;
// Flags to track whether we are in a function, a generator.
this.inMethod = this.inFunction = this.inGenerator = this.inAsync = false; this.inMethod = this.inFunction = this.inGenerator = this.inAsync = false;
// Labels in scope.
this.labels = []; this.labels = [];
// Leading decorators.
this.decorators = []; this.decorators = [];
// Token store.
this.tokens = []; this.tokens = [];
// Comment store.
this.comments = []; this.comments = [];
// Comment attachment store
this.trailingComments = []; this.trailingComments = [];
this.leadingComments = []; this.leadingComments = [];
this.commentStack = []; this.commentStack = [];
// The current position of the tokenizer in the input.
this.pos = this.lineStart = 0; this.pos = this.lineStart = 0;
this.curLine = 1; this.curLine = 1;
// Properties of the current token:
// Its type
this.type = tt.eof; this.type = tt.eof;
// For tokens that include more information than their type, the value
this.value = null; this.value = null;
// Its start and end offset
this.start = this.end = this.pos; this.start = this.end = this.pos;
// And, if locations are used, the {line, column} object
// corresponding to those offsets
this.startLoc = this.endLoc = this.curPosition(); this.startLoc = this.endLoc = this.curPosition();
// Position information for the previous token
this.lastTokEndLoc = this.lastTokStartLoc = null; this.lastTokEndLoc = this.lastTokStartLoc = null;
this.lastTokStart = this.lastTokEnd = this.pos; this.lastTokStart = this.lastTokEnd = this.pos;
// The context stack is used to superficially track syntactic
// context to predict whether a regular expression is allowed in a
// given position.
this.context = [ct.b_stat]; this.context = [ct.b_stat];
this.exprAllowed = true; this.exprAllowed = true;
// Used to signal to callers of `readWord1` whether the word this.containsEsc = this.containsOctal = false;
// contained any escape sequences. This is needed because words with
// escape sequences must not be interpreted as keywords.
this.containsEsc = false;
// TODO
this.containsOctal = false;
this.octalPosition = null; this.octalPosition = null;
return this; return this;
} }
// TODO
strict: boolean;
// TODO
input: string;
// Used to signify the start of a potential arrow function
potentialArrowAt: number;
// Flags to track whether we are in a function, a generator.
inFunction: boolean;
inGenerator: boolean;
inMethod: boolean;
// Labels in scope.
labels: Array<Object>;
// Leading decorators.
decorators: Array<Object>;
// Token store.
tokens: Array<Object>;
// Comment store.
comments: Array<Object>;
// Comment attachment store
trailingComments: Array<Object>;
leadingComments: Array<Object>;
commentStack: Array<Object>;
// The current position of the tokenizer in the input.
pos: number;
lineStart: number;
curLine: number;
// Properties of the current token:
// Its type
type: Token;
// For tokens that include more information than their type, the value
value: any;
// Its start and end offset
start: number;
end: number;
// And, if locations are used, the {line, column} object
// corresponding to those offsets
startLoc: Position;
endLoc: Position;
// Position information for the previous token
lastTokEndLoc: ?Position;
lastTokStartLoc: ?Position;
lastTokStart: number;
lastTokEnd: number;
// The context stack is used to superficially track syntactic
// context to predict whether a regular expression is allowed in a
// given position.
context: Array<TokContext>;
exprAllowed: boolean;
// Used to signal to callers of `readWord1` whether the word
// contained any escape sequences. This is needed because words with
// escape sequences must not be interpreted as keywords.
containsEsc: boolean;
// TODO
containsOctal: boolean;
octalPosition: ?number;
curPosition() { curPosition() {
return new Position(this.curLine, this.pos - this.lineStart); return new Position(this.curLine, this.pos - this.lineStart);
} }
clone(skipArrays) { clone(skipArrays?) {
let state = new State; let state = new State;
for (let key in this) { for (let key in this) {
let val = this[key]; let val = this[key];