From 227ed5638ae1269713df7cb9e0da317761b02a4b Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 23 Sep 2015 16:10:44 +0100 Subject: [PATCH] add flow type annotations --- packages/babel-core/src/api/browser.js | 14 +-- packages/babel-core/src/api/node.js | 7 +- packages/babel-core/src/api/register/node.js | 38 ++++---- packages/babel-core/src/helpers/merge.js | 8 +- .../babel-core/src/helpers/normalize-ast.js | 8 +- packages/babel-core/src/helpers/parse.js | 4 +- packages/babel-core/src/store.js | 15 +++- .../src/tools/build-external-helpers.js | 7 +- .../src/transformation/file/logger.js | 11 ++- .../src/transformation/file/options/index.js | 22 +---- .../file/options/option-manager.js | 31 ++++--- .../transformation/file/options/parsers.js | 10 ++- ...-binary-assignment-operator-transformer.js | 7 +- .../helpers/build-comprehension.js | 4 +- ...itional-assignment-operator-transformer.js | 10 ++- .../transformation/helpers/call-delegate.js | 5 +- .../src/transformation/helpers/define-map.js | 13 +-- .../helpers/explode-assignable-expression.js | 23 +++-- .../helpers/get-function-arity.js | 10 ++- .../helpers/memoise-decorators.js | 8 +- .../src/transformation/helpers/name-method.js | 14 +-- .../src/transformation/helpers/regex.js | 6 +- .../helpers/remap-async-to-generator.js | 10 ++- .../transformation/helpers/replace-supers.js | 27 +++++- .../babel-core/src/transformation/index.js | 2 + .../internal-plugins/block-hoist.js | 2 + .../internal-plugins/shadow-functions.js | 2 + .../src/transformation/modules/_default.js | 72 +++++++++------ .../src/transformation/modules/_strict.js | 8 +- .../src/transformation/modules/amd-strict.js | 2 + .../src/transformation/modules/amd.js | 2 + .../transformation/modules/common-strict.js | 2 + .../src/transformation/modules/ignore.js | 2 + .../src/transformation/modules/index.js | 2 + .../transformation/modules/lib/metadata.js | 2 + .../src/transformation/modules/lib/remaps.js | 2 + .../src/transformation/modules/system.js | 2 + .../src/transformation/modules/umd-strict.js | 2 + .../src/transformation/modules/umd.js | 2 + .../babel-core/src/transformation/pipeline.js | 4 +- .../src/transformation/plugin-pass.js | 10 ++- .../babel-core/src/transformation/plugin.js | 13 ++- .../transformers/es5/properties.mutators.js | 41 +-------- packages/babel-core/src/util.js | 16 ++-- packages/babel-generator/src/buffer.js | 47 +++++----- .../babel-generator/src/generators/base.js | 10 ++- .../babel-generator/src/generators/classes.js | 12 ++- .../src/generators/comprehensions.js | 8 +- .../src/generators/expressions.js | 44 +++++----- .../babel-generator/src/generators/flow.js | 59 +++++++------ .../babel-generator/src/generators/jsx.js | 26 +++--- .../babel-generator/src/generators/methods.js | 11 ++- .../babel-generator/src/generators/modules.js | 43 ++++----- .../src/generators/statements.js | 33 +++---- .../src/generators/template-literals.js | 10 ++- .../babel-generator/src/generators/types.js | 23 ++--- packages/babel-generator/src/index.js | 87 ++++++++++--------- packages/babel-generator/src/node/index.js | 47 ++-------- .../babel-generator/src/node/parentheses.js | 84 +++++++++++------- packages/babel-generator/src/node/printer.js | 2 + .../babel-generator/src/node/whitespace.js | 2 + packages/babel-generator/src/position.js | 2 + packages/babel-generator/src/source-map.js | 2 + packages/babel-generator/src/whitespace.js | 2 + 64 files changed, 616 insertions(+), 440 deletions(-) diff --git a/packages/babel-core/src/api/browser.js b/packages/babel-core/src/api/browser.js index 17d8883762..f166494c60 100644 --- a/packages/babel-core/src/api/browser.js +++ b/packages/babel-core/src/api/browser.js @@ -1,13 +1,15 @@ +/* @flow */ + /* eslint no-new-func: 0 */ import { transform } 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)(); } -export function load(url, callback, opts = {}, hold) { +export function load(url: string, callback: Function, opts: Object = {}, hold?: boolean) { opts.filename = opts.filename || url; let xhr = global.ActiveXObject ? new global.ActiveXObject("Microsoft.XMLHTTP") : new global.XMLHttpRequest(); @@ -31,7 +33,7 @@ export function load(url, callback, opts = {}, hold) { } function runScripts() { - let scripts = []; + let scripts: Array | Object> = []; let types = ["text/ecmascript-6", "text/6to5", "text/babel", "module"]; let index = 0; @@ -42,7 +44,7 @@ function runScripts() { function exec() { let param = scripts[index]; if (param instanceof Array) { - run(param); + run(param, index); index++; exec(); } @@ -52,7 +54,7 @@ function runScripts() { * Load, transform, and execute all scripts. */ - function run(script, i) { + function run(script: Object, i: number) { let opts = {}; if (script.src) { @@ -75,7 +77,7 @@ function runScripts() { if (types.indexOf(_script.type) >= 0) scripts.push(_script); } - for (i in scripts) { + for (let i = 0; i < scripts.length; i++) { run(scripts[i], i); } diff --git a/packages/babel-core/src/api/node.js b/packages/babel-core/src/api/node.js index a4630f6257..d2a34f9a61 100644 --- a/packages/babel-core/src/api/node.js +++ b/packages/babel-core/src/api/node.js @@ -1,3 +1,5 @@ +/* @flow */ + import isFunction from "lodash/lang/isFunction"; import transform from "../transformation"; import * as babylon from "babylon"; @@ -16,6 +18,9 @@ export { default as buildExternalHelpers } from "../tools/build-external-helpers export { default as template } from "babel-template"; export { version } from "../../package"; +import * as messages from "babel-messages"; +export { messages }; + import * as t from "babel-types"; export { t as types }; @@ -48,7 +53,7 @@ export function transformFile(filename: string, opts?: Object, callback: Functio }); } -export function transformFileSync(filename: string, opts?: Object = {}) { +export function transformFileSync(filename: string, opts?: Object = {}): string { opts.filename = filename; return transform(fs.readFileSync(filename, "utf8"), opts); } diff --git a/packages/babel-core/src/api/register/node.js b/packages/babel-core/src/api/register/node.js index f130596a3b..bd4e7a79b5 100644 --- a/packages/babel-core/src/api/register/node.js +++ b/packages/babel-core/src/api/register/node.js @@ -1,3 +1,5 @@ +/* @flow */ + import sourceMapSupport from "source-map-support"; import * as registerCache from "./cache"; import OptionManager from "../../transformation/file/options/option-manager"; @@ -52,23 +54,23 @@ let cwd = process.cwd(); * Get path from `filename` relative to the current working directory. */ -let getRelativePath = function (filename){ +function getRelativePath(filename){ return path.relative(cwd, filename); -}; +} /** * Get last modified time for a `filename`. */ -let mtime = function (filename) { +function mtime(filename) { return +fs.statSync(filename).mtime; -}; +} /** * Compile a `filename` with optional `opts`. */ -let compile = function (filename, opts = {}) { +function compile(filename, opts = {}) { let result; opts.filename = filename; @@ -97,26 +99,26 @@ let compile = function (filename, opts = {}) { } if (cache) { - result.mtime = mtime(filename); cache[cacheKey] = result; + result.mtime = mtime(filename); } maps[filename] = result.map; return result.code; -}; +} /** * Test if a `filename` should be ignored by Babel. */ -let shouldIgnore = function (filename) { +function shouldIgnore(filename) { if (!ignore && !only) { return getRelativePath(filename).split(path.sep).indexOf("node_modules") >= 0; } else { return util.shouldIgnore(filename, ignore || [], only); } -}; +} /** * Monkey patch istanbul if it is running so that it works properly. @@ -147,24 +149,24 @@ if (process.env.running_under_istanbul) { * Replacement for the loader for istanbul. */ -let istanbulLoader = function (m, filename, old) { +function istanbulLoader(m, filename, old) { istanbulMonkey[filename] = true; old(m, filename); -}; +} /** * Default loader. */ -let normalLoader = function (m, filename) { +function normalLoader(m, filename) { m._compile(compile(filename), filename); -}; +} /** * Register a loader for an extension. */ -let registerExtension = function (ext) { +function registerExtension(ext) { let old = oldHandlers[ext] || oldHandlers[".js"] || require.extensions[".js"]; let loader = normalLoader; @@ -177,13 +179,13 @@ let registerExtension = function (ext) { loader(m, filename, old); } }; -}; +} /** * Register loader for given extensions. */ -let hookExtensions = function (_exts) { +function hookExtensions(_exts) { each(oldHandlers, function (old, ext) { if (old === undefined) { delete require.extensions[ext]; @@ -198,7 +200,7 @@ let hookExtensions = function (_exts) { oldHandlers[ext] = require.extensions[ext]; registerExtension(ext); }); -}; +} /** * Register loader for default extensions. @@ -210,7 +212,7 @@ hookExtensions(util.canCompile.EXTENSIONS); * Update options at runtime. */ -export default function (opts = {}) { +export default function (opts?: Object = {}) { if (opts.only != null) only = util.arrayify(opts.only, util.regexify); if (opts.ignore != null) ignore = util.arrayify(opts.ignore, util.regexify); diff --git a/packages/babel-core/src/helpers/merge.js b/packages/babel-core/src/helpers/merge.js index dbbc07d35a..71eacdbf2c 100644 --- a/packages/babel-core/src/helpers/merge.js +++ b/packages/babel-core/src/helpers/merge.js @@ -1,10 +1,8 @@ +/* @flow */ + import merge from "lodash/object/merge"; -/** - * Merge options. - */ - -export default function (dest, src) { +export default function (dest?: Object, src?: Object): ?Object { if (!dest || !src) return; return merge(dest, src, function (a, b) { diff --git a/packages/babel-core/src/helpers/normalize-ast.js b/packages/babel-core/src/helpers/normalize-ast.js index dd295e6021..cd8881a9fd 100644 --- a/packages/babel-core/src/helpers/normalize-ast.js +++ b/packages/babel-core/src/helpers/normalize-ast.js @@ -1,3 +1,5 @@ +/* @flow */ + import * as t from "babel-types"; /** @@ -6,7 +8,11 @@ import * as t from "babel-types"; * - Wrap `Program` node with a `File` node. */ -export default function (ast, comments, tokens) { +export default function ( + ast: Object, + comments?: Array, + tokens?: Array, +) { if (ast) { if (ast.type === "Program") { return t.file(ast, comments || [], tokens || []); diff --git a/packages/babel-core/src/helpers/parse.js b/packages/babel-core/src/helpers/parse.js index 0e4595b551..e4ac6911f5 100644 --- a/packages/babel-core/src/helpers/parse.js +++ b/packages/babel-core/src/helpers/parse.js @@ -1,10 +1,12 @@ +/* @flow */ + import * as babylon from "babylon"; /** * Parse `code` with normalized options, collecting tokens and comments. */ -export default function (code, opts = {}) { +export default function (code: string, opts: BabelParserOptions = {}) { let parseOpts = { allowImportExportEverywhere: opts.looseModules, allowReturnOutsideFunction: opts.looseModules, diff --git a/packages/babel-core/src/store.js b/packages/babel-core/src/store.js index d83cdd71c2..d4c31300b2 100644 --- a/packages/babel-core/src/store.js +++ b/packages/babel-core/src/store.js @@ -1,8 +1,15 @@ -export default class Store { - dynamicData = {}; - data = {}; +/* @flow */ - set(key: string, val): any { +export default class Store { + constructor() { + this.dynamicData = {}; + this.data = {}; + } + + dynamicData: Object; + data: Object; + + set(key: string, val: any): any { return this.data[key] = val; } diff --git a/packages/babel-core/src/tools/build-external-helpers.js b/packages/babel-core/src/tools/build-external-helpers.js index d19971ac2e..03536fbc14 100644 --- a/packages/babel-core/src/tools/build-external-helpers.js +++ b/packages/babel-core/src/tools/build-external-helpers.js @@ -1,3 +1,5 @@ +/* @flow */ + import generator from "babel-generator"; import * as messages from "babel-messages"; import * as util from "../util"; @@ -61,7 +63,10 @@ function buildHelpers(body, namespace, whitelist) { }); } -export default function (whitelist, outputType = "global") { +export default function ( + whitelist?: Array, + outputType: "global" | "umd" | "var" = "global", +) { let namespace = t.identifier("babelHelpers"); let builder = function (body) { diff --git a/packages/babel-core/src/transformation/file/logger.js b/packages/babel-core/src/transformation/file/logger.js index 39a17ddf12..5655f67ca0 100644 --- a/packages/babel-core/src/transformation/file/logger.js +++ b/packages/babel-core/src/transformation/file/logger.js @@ -1,3 +1,5 @@ +/* @flow */ + import type File from "./index"; import buildDebug from "debug/node"; @@ -12,21 +14,24 @@ export default class Logger { this.file = file; } + filename: string; + file: File; + _buildMessage(msg: string): string { let parts = `[BABEL] ${this.filename}`; if (msg) parts += `: ${msg}`; return parts; } - warn(msg) { + warn(msg: string) { console.warn(this._buildMessage(msg)); } - error(msg: string, Constructor = Error) { + error(msg: string, Constructor: typeof Error = Error): Error { throw new Constructor(this._buildMessage(msg)); } - deprecate(msg) { + deprecate(msg: string) { if (this.file.opts && this.file.opts.suppressDeprecationMessages) return; msg = this._buildMessage(msg); diff --git a/packages/babel-core/src/transformation/file/options/index.js b/packages/babel-core/src/transformation/file/options/index.js index 2aeb85c41c..cbd3051618 100644 --- a/packages/babel-core/src/transformation/file/options/index.js +++ b/packages/babel-core/src/transformation/file/options/index.js @@ -1,27 +1,11 @@ +/* @flow */ + import * as parsers from "./parsers"; import config from "./config"; export { config }; -/** - * Validate an option. - */ - -export function validateOption(key, val, pipeline) { - let opt = config[key]; - let parser = opt && parsers[opt.type]; - if (parser && parser.validate) { - return parser.validate(key, val, pipeline); - } else { - return val; - } -} - -/** - * Normalize all options. - */ - -export function normaliseOptions(options = {}) { +export function normaliseOptions(options: Object = {}): Object { for (let key in options) { let val = options[key]; if (val == null) continue; diff --git a/packages/babel-core/src/transformation/file/options/option-manager.js b/packages/babel-core/src/transformation/file/options/option-manager.js index fd5cadc234..5151dd0901 100644 --- a/packages/babel-core/src/transformation/file/options/option-manager.js +++ b/packages/babel-core/src/transformation/file/options/option-manager.js @@ -1,3 +1,6 @@ +/* @flow */ + +import type Logger from "../logger"; import Plugin from "../../plugin"; import * as messages from "babel-messages"; import * as context from "../../../api/node"; @@ -29,17 +32,23 @@ function exists(filename) { } export default class OptionManager { - constructor(log, pipeline) { + constructor(log?: Logger) { this.resolvedConfigs = []; - this.options = OptionManager.createBareOptions(); - this.pipeline = pipeline; - this.log = log; + this.options = OptionManager.createBareOptions(); + this.log = log; } - static memoisedPlugins = []; + resolvedConfigs: Array; + options: Object; + log: ?Logger; + + static memoisedPlugins: Array<{ + container: Function; + plugin: Plugin; + }>; static memoisePluginContainer(fn, loc, i) { - for (let cache of (OptionManager.memoisedPlugins: Array)) { + for (let cache of (OptionManager.memoisedPlugins: Array)) { if (cache.container === fn) return cache.plugin; } @@ -103,7 +112,7 @@ export default class OptionManager { }); } - addConfig(loc, key?, json=json5) { + addConfig(loc: string, key?: string, json = json5) { if (this.resolvedConfigs.indexOf(loc) >= 0) return; let content = fs.readFileSync(loc, "utf8"); @@ -130,7 +139,7 @@ export default class OptionManager { * - `dirname` is used to resolve plugins relative to it. */ - mergeOptions(opts, alias = "foreign", loc, dirname) { + mergeOptions(opts?: Object, alias: string = "foreign", loc?: string, dirname?: string) { if (!opts) return; dirname = dirname || process.cwd(); @@ -177,7 +186,7 @@ export default class OptionManager { this.mergeOptions(envOpts, `${alias}.env.${envKey}`); } - mergePresets(presets: Array, dirname) { + mergePresets(presets: Array, dirname: string) { for (let val of presets) { if (typeof val === "string") { let presetLoc = resolve(`babel-preset-${val}`, dirname) || resolve(val, dirname); @@ -262,7 +271,7 @@ export default class OptionManager { } } - init(opts) { + init(opts: Object): Object { // resolve all .babelrc files if (opts.babelrc !== false) { this.findConfigs(opts.filename); @@ -277,3 +286,5 @@ export default class OptionManager { return this.options; } } + +OptionManager.memoisedPlugins = []; diff --git a/packages/babel-core/src/transformation/file/options/parsers.js b/packages/babel-core/src/transformation/file/options/parsers.js index 60d2752782..5b5c57faaa 100644 --- a/packages/babel-core/src/transformation/file/options/parsers.js +++ b/packages/babel-core/src/transformation/file/options/parsers.js @@ -1,20 +1,22 @@ +/* @flow */ + import slash from "slash"; import * as util from "../../../util"; -export function number(val) { +export function number(val: any): number { return +val; } export let filename = slash; -export function boolean(val) { +export function boolean(val: any): boolean { return !!val; } -export function booleanString(val) { +export function booleanString(val: any): boolean | any { return util.booleanify(val); } -export function list(val) { +export function list(val: any): Array { return util.list(val); } diff --git a/packages/babel-core/src/transformation/helpers/build-binary-assignment-operator-transformer.js b/packages/babel-core/src/transformation/helpers/build-binary-assignment-operator-transformer.js index 4772176e69..689d3467f8 100644 --- a/packages/babel-core/src/transformation/helpers/build-binary-assignment-operator-transformer.js +++ b/packages/babel-core/src/transformation/helpers/build-binary-assignment-operator-transformer.js @@ -1,7 +1,12 @@ +/* @flow */ + import explode from "./explode-assignable-expression"; import * as t from "babel-types"; -export default function (opts) { +export default function (opts: { + build: Function; + operator: string; +}): Object { let exports = {}; let isAssignment = function (node) { diff --git a/packages/babel-core/src/transformation/helpers/build-comprehension.js b/packages/babel-core/src/transformation/helpers/build-comprehension.js index 2903f5fec4..832b002204 100644 --- a/packages/babel-core/src/transformation/helpers/build-comprehension.js +++ b/packages/babel-core/src/transformation/helpers/build-comprehension.js @@ -1,6 +1,8 @@ +/* @flow */ + import * as t from "babel-types"; -export default function build(node, buildBody) { +export default function build(node: Object, buildBody: Function): ?Object { let self = node.blocks.shift(); if (!self) return; diff --git a/packages/babel-core/src/transformation/helpers/build-conditional-assignment-operator-transformer.js b/packages/babel-core/src/transformation/helpers/build-conditional-assignment-operator-transformer.js index 70275fa570..b8172ef5e3 100644 --- a/packages/babel-core/src/transformation/helpers/build-conditional-assignment-operator-transformer.js +++ b/packages/babel-core/src/transformation/helpers/build-conditional-assignment-operator-transformer.js @@ -1,7 +1,15 @@ +/* @flow */ + import explode from "./explode-assignable-expression"; import * as t from "babel-types"; -export default function (exports, opts) { +export default function ( + exports: Object, + opts: { + build: Function; + is: Function; + }, +) { let buildAssignment = function (left, right) { return t.assignmentExpression("=", left, right); }; diff --git a/packages/babel-core/src/transformation/helpers/call-delegate.js b/packages/babel-core/src/transformation/helpers/call-delegate.js index 6fc6009251..b12c9287c9 100644 --- a/packages/babel-core/src/transformation/helpers/call-delegate.js +++ b/packages/babel-core/src/transformation/helpers/call-delegate.js @@ -1,3 +1,6 @@ +/* @flow */ + +import type { Scope } from "babel-traverse"; import * as t from "babel-types"; let visitor = { @@ -13,7 +16,7 @@ let visitor = { } }; -export default function (node, scope) { +export default function (node: Object, scope: Scope) { let container = t.functionExpression(null, [], node.body, node.generator, node.async); let callee = container; diff --git a/packages/babel-core/src/transformation/helpers/define-map.js b/packages/babel-core/src/transformation/helpers/define-map.js index 4fc596a5d4..21b4536df0 100644 --- a/packages/babel-core/src/transformation/helpers/define-map.js +++ b/packages/babel-core/src/transformation/helpers/define-map.js @@ -1,8 +1,11 @@ +/* @flow */ + +import type File from "../file"; import each from "lodash/collection/each"; import has from "lodash/object/has"; import * as t from "babel-types"; -export function push(mutatorMap, node, kind, file) { +export function push(mutatorMap: Object, node: Object, kind: string, file: File): Object { let alias = t.toKeyAlias(node); // @@ -43,7 +46,7 @@ export function push(mutatorMap, node, kind, file) { return map; } -export function hasComputed(mutatorMap) { +export function hasComputed(mutatorMap: Object): boolean { for (let key in mutatorMap) { if (mutatorMap[key]._computed) { return true; @@ -52,7 +55,7 @@ export function hasComputed(mutatorMap) { return false; } -export function toComputedObjectFromClass(obj) { +export function toComputedObjectFromClass(obj: Object): Object { let objExpr = t.arrayExpression([]); for (let i = 0; i < obj.properties.length; i++) { @@ -65,7 +68,7 @@ export function toComputedObjectFromClass(obj) { return objExpr; } -export function toClassObject(mutatorMap) { +export function toClassObject(mutatorMap: Object): Object { let objExpr = t.objectExpression([]); each(mutatorMap, function (map) { @@ -92,7 +95,7 @@ export function toClassObject(mutatorMap) { return objExpr; } -export function toDefineObject(mutatorMap) { +export function toDefineObject(mutatorMap: Object): Object { each(mutatorMap, function (map) { if (map.value) map.writable = t.booleanLiteral(true); map.configurable = t.booleanLiteral(true); diff --git a/packages/babel-core/src/transformation/helpers/explode-assignable-expression.js b/packages/babel-core/src/transformation/helpers/explode-assignable-expression.js index eddcc5d4c8..5a97200499 100644 --- a/packages/babel-core/src/transformation/helpers/explode-assignable-expression.js +++ b/packages/babel-core/src/transformation/helpers/explode-assignable-expression.js @@ -1,6 +1,10 @@ +/* @flow */ + +import type { Scope } from "babel-traverse"; +import type File from "../file"; import * as t from "babel-types"; -let getObjRef = function (node, nodes, file, scope) { +function getObjRef(node, nodes, file, scope) { let ref; if (t.isIdentifier(node)) { if (scope.hasBinding(node.name)) { @@ -31,9 +35,9 @@ let getObjRef = function (node, nodes, file, scope) { t.variableDeclarator(temp, ref) ])); return temp; -}; +} -let getPropRef = function (node, nodes, file, scope) { +function getPropRef(node, nodes, file, scope) { let prop = node.property; let key = t.toComputedKey(node, prop); if (t.isLiteral(key)) return key; @@ -43,9 +47,18 @@ let getPropRef = function (node, nodes, file, scope) { t.variableDeclarator(temp, prop) ])); return temp; -}; +} -export default function (node, nodes, file, scope, allowedSingleIdent) { +export default function ( + node: Object, + nodes: Array, + file: File, + scope: Scope, + allowedSingleIdent?: boolean, +): { + uid: Object; + ref: Object; +} { let obj; if (t.isIdentifier(node) && allowedSingleIdent) { obj = node; diff --git a/packages/babel-core/src/transformation/helpers/get-function-arity.js b/packages/babel-core/src/transformation/helpers/get-function-arity.js index 756a102d9a..581e695c42 100644 --- a/packages/babel-core/src/transformation/helpers/get-function-arity.js +++ b/packages/babel-core/src/transformation/helpers/get-function-arity.js @@ -1,11 +1,13 @@ +/* @flow */ + import * as t from "babel-types"; -export default function (node) { - for (let i = 0; i < node.params.length; i++) { - let param = node.params[i]; +export default function ({ params }: { params: Array }): number { + for (let i = 0; i < params.length; i++) { + let param = params[i]; if (t.isAssignmentPattern(param) || t.isRestElement(param)) { return i; } } - return node.params.length; + return params.length; } diff --git a/packages/babel-core/src/transformation/helpers/memoise-decorators.js b/packages/babel-core/src/transformation/helpers/memoise-decorators.js index d05d4c4e33..18eaa0a498 100644 --- a/packages/babel-core/src/transformation/helpers/memoise-decorators.js +++ b/packages/babel-core/src/transformation/helpers/memoise-decorators.js @@ -1,8 +1,10 @@ +/* @flow */ + +import type { Scope } from "babel-traverse"; import * as t from "babel-types"; -export default function (decorators, scope) { - for (let i = 0; i < decorators.length; i++) { - let decorator = decorators[i]; +export default function (decorators: Array, scope: Scope): Array { + for (let decorator of decorators) { let expression = decorator.expression; if (!t.isMemberExpression(expression)) continue; diff --git a/packages/babel-core/src/transformation/helpers/name-method.js b/packages/babel-core/src/transformation/helpers/name-method.js index df1a25e88c..034a825605 100644 --- a/packages/babel-core/src/transformation/helpers/name-method.js +++ b/packages/babel-core/src/transformation/helpers/name-method.js @@ -1,3 +1,7 @@ +/* @flow */ + +import type { Scope } from "babel-traverse"; +import type File from "../file"; import getFunctionArity from "./get-function-arity"; import * as util from "../../util"; import * as t from "babel-types"; @@ -94,12 +98,12 @@ function visit(node, name, scope) { return state; } -export function custom(node, id, scope) { +export function custom(node: Object, id: Object, scope: Scope) { let state = visit(node, id.name, scope); return wrap(state, node, id, scope); } -export function property(node, file, scope) { +export function property(node: Object, file: File, scope: Scope) { let key = t.toComputedKey(node, node.key); if (!t.isLiteral(key)) return; // we can't set a function id with this @@ -111,7 +115,7 @@ export function property(node, file, scope) { node.value = wrap(state, method, id, scope) || method; } -export function bare(node, parent, scope) { +export function bare(node: Object, parent: Object, scope: Scope) { // has an `id` so we don't need to infer one if (node.id) return; @@ -136,9 +140,9 @@ export function bare(node, parent, scope) { } let name; - if (t.isLiteral(id)) { + if (id && t.isLiteral(id)) { name = id.value; - } else if (t.isIdentifier(id)) { + } else if (id && t.isIdentifier(id)) { name = id.name; } else { return; diff --git a/packages/babel-core/src/transformation/helpers/regex.js b/packages/babel-core/src/transformation/helpers/regex.js index c99a183760..8044207c37 100644 --- a/packages/babel-core/src/transformation/helpers/regex.js +++ b/packages/babel-core/src/transformation/helpers/regex.js @@ -1,11 +1,13 @@ +/* @flow */ + import pull from "lodash/array/pull"; import * as t from "babel-types"; -export function is(node, flag) { +export function is(node: Object, flag: string): boolean { return t.isRegexLiteral(node) && node.flags.indexOf(flag) >= 0; } -export function pullFlag(node, flag) { +export function pullFlag(node: Object, flag: string) { let flags = node.flags.split(""); if (node.flags.indexOf(flag) < 0) return; pull(flags, flag); diff --git a/packages/babel-core/src/transformation/helpers/remap-async-to-generator.js b/packages/babel-core/src/transformation/helpers/remap-async-to-generator.js index 561418e44f..2cd9a9aca5 100644 --- a/packages/babel-core/src/transformation/helpers/remap-async-to-generator.js +++ b/packages/babel-core/src/transformation/helpers/remap-async-to-generator.js @@ -1,3 +1,6 @@ +/* @flow */ + +import type { NodePath } from "babel-traverse"; import * as t from "babel-types"; let awaitVisitor = { @@ -25,13 +28,13 @@ let referenceVisitor = { } }; -export default function (path, callId) { +export default function (path: NodePath, callId: Object) { let node = path.node; node.async = false; node.generator = true; - path.traverse(awaitVisitor, state); + path.traverse(awaitVisitor); let call = t.callExpression(callId, [node]); @@ -48,7 +51,8 @@ export default function (path, callId) { node.type = "FunctionExpression"; if (id) { - let state = { id }; + let state = { id, ref: null }; + path.traverse(referenceVisitor, state); if (state.ref) { diff --git a/packages/babel-core/src/transformation/helpers/replace-supers.js b/packages/babel-core/src/transformation/helpers/replace-supers.js index 8239e9d481..11e6eab71f 100644 --- a/packages/babel-core/src/transformation/helpers/replace-supers.js +++ b/packages/babel-core/src/transformation/helpers/replace-supers.js @@ -1,4 +1,7 @@ -import type NodePath from "../../traversal/path"; +/* @flow */ + +import type File from "../file"; +import type { NodePath, Scope } from "babel-traverse"; import * as messages from "babel-messages"; import * as t from "babel-types"; @@ -59,6 +62,28 @@ export default class ReplaceSupers { this.opts = opts; } + topLevelThisReference: ?Object; + methodPath: NodePath; + methodNode: Object; + superRef: Object; + isStatic: boolean; + hasSuper: boolean; + inClass: boolean; + isLoose: boolean; + scope: Scope; + file: File; + opts: { + getObjetRef: Function; + topLevelThisReference: Object; + methodPath: NodePath; + methodNode: Object; + superRef: Object; + isStatic: boolean; + isLoose: boolean; + scope: Scope; + file: File; + }; + getObjectRef() { return this.opts.objectRef || this.opts.getObjectRef(); } diff --git a/packages/babel-core/src/transformation/index.js b/packages/babel-core/src/transformation/index.js index 3719de4bd0..daf3499a03 100644 --- a/packages/babel-core/src/transformation/index.js +++ b/packages/babel-core/src/transformation/index.js @@ -1,3 +1,5 @@ +/* @flow */ + import Pipeline from "./pipeline"; let pipeline = new Pipeline; diff --git a/packages/babel-core/src/transformation/internal-plugins/block-hoist.js b/packages/babel-core/src/transformation/internal-plugins/block-hoist.js index 014b9e7711..a0b5fab150 100644 --- a/packages/babel-core/src/transformation/internal-plugins/block-hoist.js +++ b/packages/babel-core/src/transformation/internal-plugins/block-hoist.js @@ -1,3 +1,5 @@ +/* @flow */ + import Plugin from "../plugin"; import sortBy from "lodash/collection/sortBy"; diff --git a/packages/babel-core/src/transformation/internal-plugins/shadow-functions.js b/packages/babel-core/src/transformation/internal-plugins/shadow-functions.js index 397b48b67a..3f13629329 100644 --- a/packages/babel-core/src/transformation/internal-plugins/shadow-functions.js +++ b/packages/babel-core/src/transformation/internal-plugins/shadow-functions.js @@ -1,3 +1,5 @@ +/* @flow */ + import Plugin from "../plugin"; import * as t from "babel-types"; diff --git a/packages/babel-core/src/transformation/modules/_default.js b/packages/babel-core/src/transformation/modules/_default.js index 48dd52bbd0..30b6549702 100644 --- a/packages/babel-core/src/transformation/modules/_default.js +++ b/packages/babel-core/src/transformation/modules/_default.js @@ -1,3 +1,7 @@ +/* @flow */ + +import type { File, FileModulesMetadata } from "../file"; +import type { Scope, NodePath } from "babel-traverse"; import * as metadataVisitor from "./lib/metadata"; import * as messages from "babel-messages"; import Remaps from "./lib/remaps"; @@ -5,7 +9,7 @@ import * as util from "../../util"; import * as t from "babel-types"; export default class DefaultFormatter { - constructor(file) { + constructor(file: File) { // object containg all module sources with the scope that they're contained in this.sourceScopes = Object.create(null); @@ -31,7 +35,20 @@ export default class DefaultFormatter { this.getMetadata(); } - addScope(path) { + sourceScopes: Object; + defaultIds: Object; + ids: Object; + remaps: Remaps; + scope: Scope; + file: File; + hasNonDefaultExports: boolean; + hasLocalExports: boolean; + hasLocalImports: boolean; + localExports: Object; + localImports: Object; + metadata: FileModulesMetadata; + + addScope(path: NodePath) { let source = path.node.source && path.node.source.value; if (!source) return; @@ -43,7 +60,7 @@ export default class DefaultFormatter { this.sourceScopes[source] = path.scope; } - isModuleType(node, type) { + isModuleType(node: Object, type: string): boolean { let modules = this.file.dynamicImportTypes[type]; return modules && modules.indexOf(node) >= 0; } @@ -52,19 +69,19 @@ export default class DefaultFormatter { this.remapAssignments(); } - doDefaultExportInterop(node) { + doDefaultExportInterop(node: Object): Object { return (t.isExportDefaultDeclaration(node) || t.isSpecifierDefault(node)) && !this.noInteropRequireExport && !this.hasNonDefaultExports; } getMetadata() { let has = false; - for (let node of (this.file.ast.program.body: Array)) { + for (let node of (this.file.ast.program.body: Array)) { if (t.isModuleDeclaration(node)) { has = true; break; } } - if (has || this.isLoose()) { + if (has) { this.file.path.traverse(metadataVisitor, this); } } @@ -75,13 +92,13 @@ export default class DefaultFormatter { } } - remapExportAssignment(node, exported) { + remapExportAssignment(node: Object, exported: Array) { let assign = node; - for (let i = 0; i < exported.length; i++) { + for (let prop of exported) { assign = t.assignmentExpression( "=", - t.memberExpression(t.identifier("exports"), exported[i]), + t.memberExpression(t.identifier("exports"), prop), assign ); } @@ -89,7 +106,7 @@ export default class DefaultFormatter { return assign; } - _addExport(name, exported) { + _addExport(name: string, exported: Array) { let info = this.localExports[name] = this.localExports[name] || { binding: this.scope.getBindingIdentifier(name), exported: [] @@ -97,7 +114,7 @@ export default class DefaultFormatter { info.exported.push(exported); } - getExport(node, scope) { + getExport(node: Object, scope: Scope) { if (!t.isIdentifier(node)) return; let local = this.localExports[node.name]; @@ -106,8 +123,9 @@ export default class DefaultFormatter { } } - getModuleName() { + getModuleName(): string { let opts = this.file.opts; + // moduleId is n/a if a `getModuleId()` is provided if (opts.moduleId != null && !opts.getModuleId) { return opts.moduleId; @@ -148,7 +166,7 @@ export default class DefaultFormatter { } } - _pushStatement(ref, nodes) { + _pushStatement(ref: Object, nodes: Array): Object { if (t.isClass(ref) || t.isFunction(ref)) { if (ref.id) { nodes.push(t.toStatement(ref)); @@ -159,7 +177,7 @@ export default class DefaultFormatter { return ref; } - _hoistExport(declar, assign, priority) { + _hoistExport(declar: Object, assign: Object, priority?: number): Object { if (t.isFunctionDeclaration(declar)) { assign._blockHoist = priority || 2; } @@ -167,7 +185,7 @@ export default class DefaultFormatter { return assign; } - getExternalReference(node, nodes) { + getExternalReference(node: Object, nodes: Array): Object { let ids = this.ids; let id = node.source.value; @@ -178,22 +196,22 @@ export default class DefaultFormatter { } } + _getExternalReference() { + throw new Error("Should be implemented"); + } + checkExportIdentifier(node) { if (t.isIdentifier(node, { name: "__esModule" })) { throw this.file.buildCodeFrameError(node, messages.get("modulesIllegalExportName", node.name)); } } - exportAllDeclaration(node, nodes) { + exportAllDeclaration(node: Object, nodes: Array) { let ref = this.getExternalReference(node, nodes); nodes.push(this.buildExportsWildcard(ref, node)); } - isLoose() { - return this.file.isLoose("es6.modules"); - } - - exportSpecifier(specifier, node, nodes) { + exportSpecifier(specifier: Object, node: Object, nodes: Array) { if (node.source) { let ref = this.getExternalReference(node, nodes); @@ -203,10 +221,8 @@ export default class DefaultFormatter { } else { ref = t.memberExpression(ref, specifier.local); - if (!this.isLoose()) { - nodes.push(this.buildExportsFromAssignment(specifier.exported, ref, node)); - return; - } + nodes.push(this.buildExportsFromAssignment(specifier.exported, ref, node)); + return; } // export { foo } from "test"; @@ -217,7 +233,7 @@ export default class DefaultFormatter { } } - buildExportsWildcard(objectIdentifier) { + buildExportsWildcard(objectIdentifier: Object) { return t.expressionStatement(t.callExpression(this.file.addHelper("defaults"), [ t.identifier("exports"), t.callExpression(this.file.addHelper("interop-export-wildcard"), [ @@ -227,7 +243,7 @@ export default class DefaultFormatter { ])); } - buildExportsFromAssignment(id, init) { + buildExportsFromAssignment(id: Object, init: Object) { this.checkExportIdentifier(id); return util.template("exports-from-assign", { INIT: init, @@ -243,7 +259,7 @@ export default class DefaultFormatter { }, true); } - exportDeclaration(node, nodes) { + exportDeclaration(node: Object, nodes: Array) { let declar = node.declaration; let id = declar.id; diff --git a/packages/babel-core/src/transformation/modules/_strict.js b/packages/babel-core/src/transformation/modules/_strict.js index 2a615dfc4a..fe705bc984 100644 --- a/packages/babel-core/src/transformation/modules/_strict.js +++ b/packages/babel-core/src/transformation/modules/_strict.js @@ -1,11 +1,13 @@ +/* @flow */ + import * as util from "../../util"; -export default function (Parent) { - let Constructor = function () { +export default function (Parent: Function): Function { + function Constructor() { this.noInteropRequireImport = true; this.noInteropRequireExport = true; Parent.apply(this, arguments); - }; + } util.inherits(Constructor, Parent); diff --git a/packages/babel-core/src/transformation/modules/amd-strict.js b/packages/babel-core/src/transformation/modules/amd-strict.js index d3dc3d6745..98422e148e 100644 --- a/packages/babel-core/src/transformation/modules/amd-strict.js +++ b/packages/babel-core/src/transformation/modules/amd-strict.js @@ -1,3 +1,5 @@ +/* @flow */ + import AMDFormatter from "./amd"; import buildStrict from "./_strict"; diff --git a/packages/babel-core/src/transformation/modules/amd.js b/packages/babel-core/src/transformation/modules/amd.js index 6f2a1319a4..646d98edc8 100644 --- a/packages/babel-core/src/transformation/modules/amd.js +++ b/packages/babel-core/src/transformation/modules/amd.js @@ -1,3 +1,5 @@ +/* @flow */ + import DefaultFormatter from "./_default"; import CommonFormatter from "./common"; import includes from "lodash/collection/includes"; diff --git a/packages/babel-core/src/transformation/modules/common-strict.js b/packages/babel-core/src/transformation/modules/common-strict.js index 19c2837aa1..c02ae2e75b 100644 --- a/packages/babel-core/src/transformation/modules/common-strict.js +++ b/packages/babel-core/src/transformation/modules/common-strict.js @@ -1,3 +1,5 @@ +/* @flow */ + import CommonFormatter from "./common"; import buildStrict from "./_strict"; diff --git a/packages/babel-core/src/transformation/modules/ignore.js b/packages/babel-core/src/transformation/modules/ignore.js index 98056791a7..b9c3ff627c 100644 --- a/packages/babel-core/src/transformation/modules/ignore.js +++ b/packages/babel-core/src/transformation/modules/ignore.js @@ -1,3 +1,5 @@ +/* @flow */ + import DefaultFormatter from "./_default"; import * as t from "babel-types"; diff --git a/packages/babel-core/src/transformation/modules/index.js b/packages/babel-core/src/transformation/modules/index.js index 82db428417..c7c7a598e7 100644 --- a/packages/babel-core/src/transformation/modules/index.js +++ b/packages/babel-core/src/transformation/modules/index.js @@ -1,3 +1,5 @@ +/* @flow */ + /** * [Please add a description.] */ diff --git a/packages/babel-core/src/transformation/modules/lib/metadata.js b/packages/babel-core/src/transformation/modules/lib/metadata.js index 4d248ada07..d733e80ee9 100644 --- a/packages/babel-core/src/transformation/modules/lib/metadata.js +++ b/packages/babel-core/src/transformation/modules/lib/metadata.js @@ -1,3 +1,5 @@ +/* @flow */ + import extend from "lodash/object/extend"; import * as t from "babel-types"; diff --git a/packages/babel-core/src/transformation/modules/lib/remaps.js b/packages/babel-core/src/transformation/modules/lib/remaps.js index 9e8ee531a3..3c7303428e 100644 --- a/packages/babel-core/src/transformation/modules/lib/remaps.js +++ b/packages/babel-core/src/transformation/modules/lib/remaps.js @@ -1,3 +1,5 @@ +/* @flow */ + import * as t from "babel-types"; let remapVisitor = { diff --git a/packages/babel-core/src/transformation/modules/system.js b/packages/babel-core/src/transformation/modules/system.js index 18817b5600..721e676e32 100644 --- a/packages/babel-core/src/transformation/modules/system.js +++ b/packages/babel-core/src/transformation/modules/system.js @@ -1,3 +1,5 @@ +/* @flow */ + import DefaultFormatter from "./_default"; import AMDFormatter from "./amd"; import * as util from "../../util"; diff --git a/packages/babel-core/src/transformation/modules/umd-strict.js b/packages/babel-core/src/transformation/modules/umd-strict.js index f929e475dc..831de7fc25 100644 --- a/packages/babel-core/src/transformation/modules/umd-strict.js +++ b/packages/babel-core/src/transformation/modules/umd-strict.js @@ -1,3 +1,5 @@ +/* @flow */ + import UMDFormatter from "./umd"; import buildStrict from "./_strict"; diff --git a/packages/babel-core/src/transformation/modules/umd.js b/packages/babel-core/src/transformation/modules/umd.js index 60244a8fb2..57955e82ed 100644 --- a/packages/babel-core/src/transformation/modules/umd.js +++ b/packages/babel-core/src/transformation/modules/umd.js @@ -1,3 +1,5 @@ +/* @flow */ + import DefaultFormatter from "./_default"; import AMDFormatter from "./amd"; import values from "lodash/object/values"; diff --git a/packages/babel-core/src/transformation/pipeline.js b/packages/babel-core/src/transformation/pipeline.js index 9b7abaf207..ea62e1b0a2 100644 --- a/packages/babel-core/src/transformation/pipeline.js +++ b/packages/babel-core/src/transformation/pipeline.js @@ -1,3 +1,5 @@ +/* @flow */ + import normalizeAst from "../helpers/normalize-ast"; import File from "./file"; @@ -26,7 +28,7 @@ export default class Pipeline { }); } - transformFromAst(ast, code, opts) { + transformFromAst(ast, code: string, opts: Object) { ast = normalizeAst(ast); let file = new File(opts, this); diff --git a/packages/babel-core/src/transformation/plugin-pass.js b/packages/babel-core/src/transformation/plugin-pass.js index 5ef78e0a69..93d86d84c0 100644 --- a/packages/babel-core/src/transformation/plugin-pass.js +++ b/packages/babel-core/src/transformation/plugin-pass.js @@ -1,14 +1,20 @@ -import type Transformer from "./transformer"; +/* @flow */ + +import type Plugin from "./plugin"; import traverse from "babel-traverse"; import File from "./file"; export default class PluginPass { - constructor(file: File, plugin: Transformer, options: Object = {}) { + constructor(file: File, plugin: Plugin, options: Object = {}) { this.plugin = plugin; this.file = file; this.opts = options; } + plugin: Plugin; + file: File; + opts: Object; + transform() { let file = this.file; file.log.debug(`Start transformer ${this.key}`); diff --git a/packages/babel-core/src/transformation/plugin.js b/packages/babel-core/src/transformation/plugin.js index 1ba7c3b135..81fe760cf4 100644 --- a/packages/babel-core/src/transformation/plugin.js +++ b/packages/babel-core/src/transformation/plugin.js @@ -1,3 +1,5 @@ +/* @flow */ + import * as messages from "babel-messages"; import traverse from "babel-traverse"; import assign from "lodash/object/assign"; @@ -16,11 +18,16 @@ export default class Plugin { this.manipulateOptions = take("manipulateOptions"); this.post = take("post"); this.pre = take("pre"); - - this.visitor = this.normalize(clone(take("visitor")) || {}); + this.visitor = this.normalize(clone(take("visitor")) || {}); } - validate(loc, i) { + raw: Object; + manipulateOptions: ?Function; + post: ?Function; + pre: ?Function; + visitor: Object; + + validate(loc: string, i: number) { for (let key in this.raw) { throw new Error(messages.get("pluginInvalidProperty", loc, i, key)); } diff --git a/packages/babel-core/src/transformation/transformers/es5/properties.mutators.js b/packages/babel-core/src/transformation/transformers/es5/properties.mutators.js index 344e1d081b..5c7379a5f4 100644 --- a/packages/babel-core/src/transformation/transformers/es5/properties.mutators.js +++ b/packages/babel-core/src/transformation/transformers/es5/properties.mutators.js @@ -1,45 +1,10 @@ import * as defineMap from "../../helpers/define-map"; import * as t from "babel-types"; -/** - * Turn [object initializer mutators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Method_definitions) - * into `Object.defineProperties`. - * - * **In** - * - * ```javascript - * let foo = { - * get bar() { - * return "bar"; - * } - * }; - * ``` - * - * **Out** - * - * ```javascript - * let foo = Object.defineProperties({}, { - * bar: { - * get: function () { - * return "bar"; - * }, - * enumerable: true, - * configurable: true - * } - * }); - * ``` - */ - export let visitor = { - /** - * Look for getters and setters on an object. - * Filter them out and wrap the object with an `Object.defineProperties` that - * defines the getters and setters. - */ - - ObjectExpression(node, parent, scope, file) { - let hasAny = false; - for (let prop of (node.properties: Array)) { + ObjectExpression({ node }, file) { + var hasAny = false; + for (var prop of (node.properties: Array)) { if (prop.kind === "get" || prop.kind === "set") { hasAny = true; break; diff --git a/packages/babel-core/src/util.js b/packages/babel-core/src/util.js index cc7fe4f303..e0a7d22fe6 100644 --- a/packages/babel-core/src/util.js +++ b/packages/babel-core/src/util.js @@ -81,7 +81,7 @@ export function regexify(val: any): RegExp { * Create an array from a boolean, string, or array, mapped by and optional function. */ -export function arrayify(val: any, mapFn?: Function): Array { +export function arrayify(val: any, mapFn?: Function): Array { if (!val) return []; if (isBoolean(val)) return arrayify([val], mapFn); if (isString(val)) return arrayify(list(val), mapFn); @@ -98,7 +98,7 @@ export function arrayify(val: any, mapFn?: Function): Array { * Makes boolean-like strings into booleans. */ -export function booleanify(val: any): boolean { +export function booleanify(val: any): boolean | any { if (val === "true") return true; if (val === "false") return false; return val; @@ -108,16 +108,20 @@ export function booleanify(val: any): boolean { * Tests if a filename should be ignored based on "ignore" and "only" options. */ -export function shouldIgnore(filename: string, ignore: Array, only): boolean { +export function shouldIgnore( + filename: string, + ignore: Array = [], + only?: Array, +): boolean { filename = slash(filename); if (only) { - for (let pattern of (only: Array)) { + for (let pattern of only) { if (_shouldIgnore(pattern, filename)) return false; } return true; } else if (ignore.length) { - for (let pattern of (ignore: Array)) { + for (let pattern of ignore) { if (_shouldIgnore(pattern, filename)) return true; } } @@ -130,7 +134,7 @@ export function shouldIgnore(filename: string, ignore: Array, only): boolean { * Otherwise returns result of matching pattern Regex with filename. */ -function _shouldIgnore(pattern, filename) { +function _shouldIgnore(pattern: Function | RegExp, filename: string) { if (typeof pattern === "function") { return pattern(filename); } else { diff --git a/packages/babel-generator/src/buffer.js b/packages/babel-generator/src/buffer.js index 8cc1760976..abd69f8006 100644 --- a/packages/babel-generator/src/buffer.js +++ b/packages/babel-generator/src/buffer.js @@ -1,23 +1,28 @@ +/* @flow */ + +import type Position from "./position"; import repeating from "repeating"; import trimRight from "trim-right"; -import isBoolean from "lodash/lang/isBoolean"; -import includes from "lodash/collection/includes"; -import isNumber from "lodash/lang/isNumber"; /** * Buffer for collecting generated output. */ export default class Buffer { - constructor(position, format) { + constructor(position: Position, format: Object) { this.parenPushNewlineState = null; - this.position = position; - this._indent = format.indent.base; - this.format = format; - this.buf = ""; + this._indent = format.indent.base; + this.format = format; + this.buf = ""; } + parenPushNewlineState: ?Object; + buf: string; + position: Position; + _indent: number; + format: Object; + /** * Get the current trimmed buffer. */ @@ -91,7 +96,7 @@ export default class Buffer { * Add a keyword to the buffer. */ - keyword(name) { + keyword(name: string) { this.push(name); this.space(); } @@ -100,7 +105,7 @@ export default class Buffer { * Add a space to the buffer unless it is compact (override with force). */ - space(force?) { + space(force?: boolean) { if (!force && this.format.compact) return; if (force || this.buf && !this.isLast(" ") && !this.isLast("\n")) { @@ -112,7 +117,7 @@ export default class Buffer { * Remove the last character. */ - removeLast(cha) { + removeLast(cha: string) { if (this.format.compact) return; if (!this.isLast(cha)) return; @@ -136,7 +141,7 @@ export default class Buffer { * `undefined` will be returned and not `foo` due to the terminator. */ - startTerminatorless() { + startTerminatorless(): Object { return this.parenPushNewlineState = { printed: false }; @@ -146,7 +151,7 @@ export default class Buffer { * Print an ending parentheses if a starting one has been printed. */ - endTerminatorless(state) { + endTerminatorless(state: Object) { if (state.printed) { this.dedent(); this.newline(); @@ -159,7 +164,7 @@ export default class Buffer { * Strips multiple newlines if removeLast is true. */ - newline(i, removeLast) { + newline(i?: boolean | number, removeLast?: boolean) { if (this.format.retainLines || this.format.compact) return; if (this.format.concise) { @@ -169,7 +174,7 @@ export default class Buffer { removeLast = removeLast || false; - if (isNumber(i)) { + if (typeof i === "number") { i = Math.min(2, i); if (this.endsWith("{\n") || this.endsWith(":\n")) i--; @@ -182,7 +187,7 @@ export default class Buffer { return; } - if (isBoolean(i)) { + if (typeof i === "boolean") { removeLast = i; } @@ -193,7 +198,7 @@ export default class Buffer { * Adds a newline unless there is already two previous newlines. */ - _newline(removeLast) { + _newline(removeLast?: boolean) { // never allow more than two lines if (this.endsWith("\n\n")) return; @@ -233,7 +238,7 @@ export default class Buffer { * Push a string to the buffer, maintaining indentation and newlines. */ - push(str, noIndent) { + push(str: string, noIndent?: boolean) { if (!this.format.compact && this._indent && !noIndent && str !== "\n") { // we have an indent level and we aren't pushing a newline let indent = this.getIndent(); @@ -284,7 +289,7 @@ export default class Buffer { * Test if the buffer ends with a string. */ - endsWith(str, buf = this.buf) { + endsWith(str: string, buf: string = this.buf): boolean { if (str.length === 1) { return buf[buf.length - 1] === str; } else { @@ -296,14 +301,14 @@ export default class Buffer { * Test if a character is last in the buffer. */ - isLast(cha) { + isLast(cha: string) { if (this.format.compact) return false; let buf = this.buf; let last = buf[buf.length - 1]; if (Array.isArray(cha)) { - return includes(cha, last); + return cha.indexOf(last) >= 0; } else { return cha === last; } diff --git a/packages/babel-generator/src/generators/base.js b/packages/babel-generator/src/generators/base.js index 344a9880f4..67fe2f580e 100644 --- a/packages/babel-generator/src/generators/base.js +++ b/packages/babel-generator/src/generators/base.js @@ -1,12 +1,16 @@ -export function File(node, print) { +/* @flow */ + +import type NodePrinter from "../node/printer"; + +export function File(node: Object, print: NodePrinter) { print.plain(node.program); } -export function Program(node, print) { +export function Program(node: Object, print: NodePrinter) { print.sequence(node.body); } -export function BlockStatement(node, print) { +export function BlockStatement(node: Object, print: NodePrinter) { this.push("{"); if (node.body.length) { this.newline(); diff --git a/packages/babel-generator/src/generators/classes.js b/packages/babel-generator/src/generators/classes.js index 769f43a80f..6222fa7924 100644 --- a/packages/babel-generator/src/generators/classes.js +++ b/packages/babel-generator/src/generators/classes.js @@ -1,4 +1,8 @@ -export function ClassDeclaration(node, print) { +/* @flow */ + +import type NodePrinter from "../node/printer"; + +export function ClassDeclaration(node: Object, print: NodePrinter) { print.list(node.decorators, { separator: "" }); this.push("class"); @@ -26,7 +30,7 @@ export function ClassDeclaration(node, print) { export { ClassDeclaration as ClassExpression }; -export function ClassBody(node, print) { +export function ClassBody(node: Object, print: NodePrinter) { this.push("{"); if (node.body.length === 0) { print.printInnerComments(); @@ -42,7 +46,7 @@ export function ClassBody(node, print) { } } -export function ClassProperty(node, print) { +export function ClassProperty(node: Object, print: NodePrinter) { print.list(node.decorators, { separator: "" }); if (node.static) this.push("static "); @@ -57,7 +61,7 @@ export function ClassProperty(node, print) { this.semicolon(); } -export function MethodDefinition(node, print) { +export function MethodDefinition(node: Object, print: NodePrinter) { print.list(node.decorators, { separator: "" }); if (node.static) { diff --git a/packages/babel-generator/src/generators/comprehensions.js b/packages/babel-generator/src/generators/comprehensions.js index 29b7029cb1..4128805dd4 100644 --- a/packages/babel-generator/src/generators/comprehensions.js +++ b/packages/babel-generator/src/generators/comprehensions.js @@ -1,4 +1,8 @@ -export function ComprehensionBlock(node, print) { +/* @flow */ + +import type NodePrinter from "../node/printer"; + +export function ComprehensionBlock(node: Object, print: NodePrinter) { this.keyword("for"); this.push("("); print.plain(node.left); @@ -7,7 +11,7 @@ export function ComprehensionBlock(node, print) { this.push(")"); } -export function ComprehensionExpression(node, print) { +export function ComprehensionExpression(node: Object, print: NodePrinter) { this.push(node.generator ? "(" : "["); print.join(node.blocks, { separator: " " }); diff --git a/packages/babel-generator/src/generators/expressions.js b/packages/babel-generator/src/generators/expressions.js index 598592c4c6..2df40bc43d 100644 --- a/packages/babel-generator/src/generators/expressions.js +++ b/packages/babel-generator/src/generators/expressions.js @@ -1,10 +1,13 @@ +/* @flow */ + +import type NodePrinter from "../node/printer"; import isInteger from "is-integer"; import isNumber from "lodash/lang/isNumber"; import * as t from "babel-types"; const SCIENTIFIC_NOTATION = /e/i; -export function UnaryExpression(node, print) { +export function UnaryExpression(node: Object, print: NodePrinter) { let needsSpace = /[a-z]$/.test(node.operator); let arg = node.argument; @@ -21,19 +24,19 @@ export function UnaryExpression(node, print) { print.plain(node.argument); } -export function DoExpression(node, print) { +export function DoExpression(node: Object, print: NodePrinter) { this.push("do"); this.space(); print.plain(node.body); } -export function ParenthesizedExpression(node, print) { +export function ParenthesizedExpression(node: Object, print: NodePrinter) { this.push("("); print.plain(node.expression); this.push(")"); } -export function UpdateExpression(node, print) { +export function UpdateExpression(node: Object, print: NodePrinter) { if (node.prefix) { this.push(node.operator); print.plain(node.argument); @@ -43,7 +46,7 @@ export function UpdateExpression(node, print) { } } -export function ConditionalExpression(node, print) { +export function ConditionalExpression(node: Object, print: NodePrinter) { print.plain(node.test); this.space(); this.push("?"); @@ -55,7 +58,7 @@ export function ConditionalExpression(node, print) { print.plain(node.alternate); } -export function NewExpression(node, print) { +export function NewExpression(node: Object, print: NodePrinter) { this.push("new "); print.plain(node.callee); this.push("("); @@ -63,7 +66,7 @@ export function NewExpression(node, print) { this.push(")"); } -export function SequenceExpression(node, print) { +export function SequenceExpression(node: Object, print: NodePrinter) { print.list(node.expressions); } @@ -75,13 +78,13 @@ export function Super() { this.push("super"); } -export function Decorator(node, print) { +export function Decorator(node: Object, print: NodePrinter) { this.push("@"); print.plain(node.expression); this.newline(); } -export function CallExpression(node, print) { +export function CallExpression(node: Object, print: NodePrinter) { print.plain(node.callee); this.push("("); @@ -106,7 +109,7 @@ export function CallExpression(node, print) { } function buildYieldAwait(keyword) { - return function (node, print) { + return function (node: Object, print: NodePrinter) { this.push(keyword); if (node.delegate || node.all) { @@ -129,24 +132,23 @@ export function EmptyStatement() { this.semicolon(); } -export function ExpressionStatement(node, print) { +export function ExpressionStatement(node: Object, print: NodePrinter) { print.plain(node.expression); this.semicolon(); } -export function AssignmentPattern(node, print) { +export function AssignmentPattern(node: Object, print: NodePrinter) { print.plain(node.left); this.push(" = "); print.plain(node.right); } -export function AssignmentExpression(node, print) { - // todo: add cases where the spaces can be dropped when in compact mode +export function AssignmentExpression(node: Object, print: NodePrinter) { print.plain(node.left); - let spaces = node.operator === "in" || node.operator === "instanceof"; + let spaces = !this.format.compact || node.operator === "in" || node.operator === "instanceof"; spaces = true; // todo: https://github.com/babel/babel/issues/1835 - this.space(spaces); + if (spaces) this.push(" "); this.push(node.operator); @@ -158,12 +160,12 @@ export function AssignmentExpression(node, print) { t.isUnaryExpression(node.right.argument, { prefix: true, operator: "--" }); } - this.space(spaces); + if (spaces) this.push(" "); print.plain(node.right); } -export function BindExpression(node, print) { +export function BindExpression(node: Object, print: NodePrinter) { print.plain(node.object); this.push("::"); print.plain(node.callee); @@ -174,7 +176,7 @@ export { AssignmentExpression as LogicalExpression }; -export function MemberExpression(node, print) { +export function MemberExpression(node: Object, print: NodePrinter) { let obj = node.object; print.plain(obj); @@ -193,7 +195,7 @@ export function MemberExpression(node, print) { this.push("]"); } else { if (t.isLiteral(node.object)) { - let val = this._Literal(node.object); + let val = this._stringLiteral(node.object); if (isInteger(+val) && !SCIENTIFIC_NOTATION.test(val) && !this.endsWith(".")) { this.push("."); } @@ -204,7 +206,7 @@ export function MemberExpression(node, print) { } } -export function MetaProperty(node, print) { +export function MetaProperty(node: Object, print: NodePrinter) { print.plain(node.meta); this.push("."); print.plain(node.property); diff --git a/packages/babel-generator/src/generators/flow.js b/packages/babel-generator/src/generators/flow.js index 4a42f81d04..190d6887b7 100644 --- a/packages/babel-generator/src/generators/flow.js +++ b/packages/babel-generator/src/generators/flow.js @@ -1,10 +1,13 @@ +/* @flow */ + +import type NodePrinter from "../node/printer"; import * as t from "babel-types"; export function AnyTypeAnnotation() { this.push("any"); } -export function ArrayTypeAnnotation(node, print) { +export function ArrayTypeAnnotation(node: Object, print: NodePrinter) { print.plain(node.elementType); this.push("["); this.push("]"); @@ -14,37 +17,37 @@ export function BooleanTypeAnnotation() { this.push("bool"); } -export function BooleanLiteralTypeAnnotation(node) { +export function BooleanLiteralTypeAnnotation(node: Object) { this.push(node.value ? "true" : "false"); } -export function DeclareClass(node, print) { +export function DeclareClass(node: Object, print: NodePrinter) { this.push("declare class "); this._interfaceish(node, print); } -export function DeclareFunction(node, print) { +export function DeclareFunction(node: Object, print: NodePrinter) { this.push("declare function "); print.plain(node.id); print.plain(node.id.typeAnnotation.typeAnnotation); this.semicolon(); } -export function DeclareModule(node, print) { +export function DeclareModule(node: Object, print: NodePrinter) { this.push("declare module "); print.plain(node.id); this.space(); print.plain(node.body); } -export function DeclareVariable(node, print) { +export function DeclareVariable(node: Object, print: NodePrinter) { this.push("declare let "); print.plain(node.id); print.plain(node.id.typeAnnotation); this.semicolon(); } -export function FunctionTypeAnnotation(node, print, parent) { +export function FunctionTypeAnnotation(node: Object, print: NodePrinter, parent: Object) { print.plain(node.typeParameters); this.push("("); print.list(node.params); @@ -72,7 +75,7 @@ export function FunctionTypeAnnotation(node, print, parent) { print.plain(node.returnType); } -export function FunctionTypeParam(node, print) { +export function FunctionTypeParam(node: Object, print: NodePrinter) { print.plain(node.name); if (node.optional) this.push("?"); this.push(":"); @@ -80,14 +83,14 @@ export function FunctionTypeParam(node, print) { print.plain(node.typeAnnotation); } -export function InterfaceExtends(node, print) { +export function InterfaceExtends(node: Object, print: NodePrinter) { print.plain(node.id); print.plain(node.typeParameters); } export { InterfaceExtends as ClassImplements, InterfaceExtends as GenericTypeAnnotation }; -export function _interfaceish(node, print) { +export function _interfaceish(node: Object, print: NodePrinter) { print.plain(node.id); print.plain(node.typeParameters); if (node.extends.length) { @@ -98,12 +101,12 @@ export function _interfaceish(node, print) { print.plain(node.body); } -export function InterfaceDeclaration(node, print) { +export function InterfaceDeclaration(node: Object, print: NodePrinter) { this.push("interface "); this._interfaceish(node, print); } -export function IntersectionTypeAnnotation(node, print) { +export function IntersectionTypeAnnotation(node: Object, print: NodePrinter) { print.join(node.types, { separator: " & " }); } @@ -111,18 +114,18 @@ export function MixedTypeAnnotation() { this.push("mixed"); } -export function NullableTypeAnnotation(node, print) { +export function NullableTypeAnnotation(node: Object, print: NodePrinter) { this.push("?"); print.plain(node.typeAnnotation); } -export { Literal as NumberLiteralTypeAnnotation } from "./types"; +export { NumberLiteral as NumberLiteralTypeAnnotation } from "./types"; export function NumberTypeAnnotation() { this.push("number"); } -export function StringLiteralTypeAnnotation(node) { +export function StringLiteralTypeAnnotation(node: Object) { this.push(this._stringLiteral(node.value)); } @@ -130,18 +133,18 @@ export function StringTypeAnnotation() { this.push("string"); } -export function TupleTypeAnnotation(node, print) { +export function TupleTypeAnnotation(node: Object, print: NodePrinter) { this.push("["); print.join(node.types, { separator: ", " }); this.push("]"); } -export function TypeofTypeAnnotation(node, print) { +export function TypeofTypeAnnotation(node: Object, print: NodePrinter) { this.push("typeof "); print.plain(node.argument); } -export function TypeAlias(node, print) { +export function TypeAlias(node: Object, print: NodePrinter) { this.push("type "); print.plain(node.id); print.plain(node.typeParameters); @@ -152,18 +155,18 @@ export function TypeAlias(node, print) { this.semicolon(); } -export function TypeAnnotation(node, print) { +export function TypeAnnotation(node: Object, print: NodePrinter) { this.push(":"); this.space(); if (node.optional) this.push("?"); print.plain(node.typeAnnotation); } -export function TypeParameterInstantiation(node, print) { +export function TypeParameterInstantiation(node: Object, print: NodePrinter) { this.push("<"); print.join(node.params, { separator: ", ", - iterator(node) { + iterator(node: Object) { print.plain(node.typeAnnotation); } }); @@ -172,7 +175,7 @@ export function TypeParameterInstantiation(node, print) { export { TypeParameterInstantiation as TypeParameterDeclaration }; -export function ObjectTypeAnnotation(node, print) { +export function ObjectTypeAnnotation(node: Object, print: NodePrinter) { this.push("{"); let props = node.properties.concat(node.callProperties, node.indexers); @@ -196,12 +199,12 @@ export function ObjectTypeAnnotation(node, print) { this.push("}"); } -export function ObjectTypeCallProperty(node, print) { +export function ObjectTypeCallProperty(node: Object, print: NodePrinter) { if (node.static) this.push("static "); print.plain(node.value); } -export function ObjectTypeIndexer(node, print) { +export function ObjectTypeIndexer(node: Object, print: NodePrinter) { if (node.static) this.push("static "); this.push("["); print.plain(node.id); @@ -214,7 +217,7 @@ export function ObjectTypeIndexer(node, print) { print.plain(node.value); } -export function ObjectTypeProperty(node, print) { +export function ObjectTypeProperty(node: Object, print: NodePrinter) { if (node.static) this.push("static "); print.plain(node.key); if (node.optional) this.push("?"); @@ -225,17 +228,17 @@ export function ObjectTypeProperty(node, print) { print.plain(node.value); } -export function QualifiedTypeIdentifier(node, print) { +export function QualifiedTypeIdentifier(node: Object, print: NodePrinter) { print.plain(node.qualification); this.push("."); print.plain(node.id); } -export function UnionTypeAnnotation(node, print) { +export function UnionTypeAnnotation(node: Object, print: NodePrinter) { print.join(node.types, { separator: " | " }); } -export function TypeCastExpression(node, print) { +export function TypeCastExpression(node: Object, print: NodePrinter) { this.push("("); print.plain(node.expression); print.plain(node.typeAnnotation); diff --git a/packages/babel-generator/src/generators/jsx.js b/packages/babel-generator/src/generators/jsx.js index a89061e540..54b881ca46 100644 --- a/packages/babel-generator/src/generators/jsx.js +++ b/packages/babel-generator/src/generators/jsx.js @@ -1,4 +1,8 @@ -export function JSXAttribute(node, print) { +/* @flow */ + +import type NodePrinter from "../node/printer"; + +export function JSXAttribute(node: Object, print: NodePrinter) { print.plain(node.name); if (node.value) { this.push("="); @@ -6,45 +10,45 @@ export function JSXAttribute(node, print) { } } -export function JSXIdentifier(node) { +export function JSXIdentifier(node: Object) { this.push(node.name); } -export function JSXNamespacedName(node, print) { +export function JSXNamespacedName(node: Object, print: NodePrinter) { print.plain(node.namespace); this.push(":"); print.plain(node.name); } -export function JSXMemberExpression(node, print) { +export function JSXMemberExpression(node: Object, print: NodePrinter) { print.plain(node.object); this.push("."); print.plain(node.property); } -export function JSXSpreadAttribute(node, print) { +export function JSXSpreadAttribute(node: Object, print: NodePrinter) { this.push("{..."); print.plain(node.argument); this.push("}"); } -export function JSXExpressionContainer(node, print) { +export function JSXExpressionContainer(node: Object, print: NodePrinter) { this.push("{"); print.plain(node.expression); this.push("}"); } -export function JSXText(node) { +export function JSXText(node: Object) { this.push(node.value, true); } -export function JSXElement(node, print) { +export function JSXElement(node: Object, print: NodePrinter) { let open = node.openingElement; print.plain(open); if (open.selfClosing) return; this.indent(); - for (let child of (node.children: Array)) { + for (let child of (node.children: Array)) { print.plain(child); } this.dedent(); @@ -52,7 +56,7 @@ export function JSXElement(node, print) { print.plain(node.closingElement); } -export function JSXOpeningElement(node, print) { +export function JSXOpeningElement(node: Object, print: NodePrinter) { this.push("<"); print.plain(node.name); if (node.attributes.length > 0) { @@ -62,7 +66,7 @@ export function JSXOpeningElement(node, print) { this.push(node.selfClosing ? " />" : ">"); } -export function JSXClosingElement(node, print) { +export function JSXClosingElement(node: Object, print: NodePrinter) { this.push(""); diff --git a/packages/babel-generator/src/generators/methods.js b/packages/babel-generator/src/generators/methods.js index 920235f05f..65c23a6312 100644 --- a/packages/babel-generator/src/generators/methods.js +++ b/packages/babel-generator/src/generators/methods.js @@ -1,6 +1,9 @@ +/* @flow */ + +import type NodePrinter from "../node/printer"; import * as t from "babel-types"; -export function _params(node, print) { +export function _params(node: Object, print: NodePrinter) { print.plain(node.typeParameters); this.push("("); print.list(node.params, { @@ -16,7 +19,7 @@ export function _params(node, print) { } } -export function _method(node, print) { +export function _method(node: Object, print: NodePrinter) { let value = node.value; let kind = node.kind; let key = node.key; @@ -46,7 +49,7 @@ export function _method(node, print) { print.plain(value.body); } -export function FunctionExpression(node, print) { +export function FunctionExpression(node: Object, print: NodePrinter) { if (node.async) this.push("async "); this.push("function"); if (node.generator) this.push("*"); @@ -65,7 +68,7 @@ export function FunctionExpression(node, print) { export { FunctionExpression as FunctionDeclaration }; -export function ArrowFunctionExpression(node, print) { +export function ArrowFunctionExpression(node: Object, print: NodePrinter) { if (node.async) this.push("async "); if (node.params.length === 1 && t.isIdentifier(node.params[0])) { diff --git a/packages/babel-generator/src/generators/modules.js b/packages/babel-generator/src/generators/modules.js index 0864dd58a6..7cd2106d50 100644 --- a/packages/babel-generator/src/generators/modules.js +++ b/packages/babel-generator/src/generators/modules.js @@ -1,6 +1,9 @@ +/* @flow */ + +import type NodePrinter from "../node/printer"; import * as t from "babel-types"; -export function ImportSpecifier(node, print) { +export function ImportSpecifier(node: Object, print: NodePrinter) { print.plain(node.imported); if (node.local && node.local.name !== node.imported.name) { this.push(" as "); @@ -8,15 +11,15 @@ export function ImportSpecifier(node, print) { } } -export function ImportDefaultSpecifier(node, print) { +export function ImportDefaultSpecifier(node: Object, print: NodePrinter) { print.plain(node.local); } -export function ExportDefaultSpecifier(node, print) { +export function ExportDefaultSpecifier(node: Object, print: NodePrinter) { print.plain(node.exported); } -export function ExportSpecifier(node, print) { +export function ExportSpecifier(node: Object, print: NodePrinter) { print.plain(node.local); if (node.exported && node.local.name !== node.exported.name) { this.push(" as "); @@ -24,12 +27,12 @@ export function ExportSpecifier(node, print) { } } -export function ExportNamespaceSpecifier(node, print) { +export function ExportNamespaceSpecifier(node: Object, print: NodePrinter) { this.push("* as "); print.plain(node.exported); } -export function ExportAllDeclaration(node, print) { +export function ExportAllDeclaration(node: Object, print: NodePrinter) { this.push("export *"); if (node.exported) { this.push(" as "); @@ -40,19 +43,17 @@ export function ExportAllDeclaration(node, print) { this.semicolon(); } -export function ExportNamedDeclaration(node, print) { +export function ExportNamedDeclaration(node: Object, print: NodePrinter) { this.push("export "); ExportDeclaration.call(this, node, print); } -export function ExportDefaultDeclaration(node, print) { +export function ExportDefaultDeclaration(node: Object, print: NodePrinter) { this.push("export default "); ExportDeclaration.call(this, node, print); } -function ExportDeclaration(node, print) { - let specifiers = node.specifiers; - +function ExportDeclaration(node: Object, print: NodePrinter) { if (node.declaration) { let declar = node.declaration; print.plain(declar); @@ -62,6 +63,8 @@ function ExportDeclaration(node, print) { this.push("type "); } + let specifiers = node.specifiers.slice(0); + let first = specifiers[0]; let hasSpecial = false; if (t.isExportDefaultSpecifier(first) || t.isExportNamespaceSpecifier(first)) { @@ -91,27 +94,27 @@ function ExportDeclaration(node, print) { this.ensureSemicolon(); } -export function ImportDeclaration(node, print) { +export function ImportDeclaration(node: Object, print: NodePrinter) { this.push("import "); if (node.importKind === "type" || node.importKind === "typeof") { this.push(node.importKind + " "); } - let specfiers = node.specifiers; - if (specfiers && specfiers.length) { - let first = node.specifiers[0]; + let specifiers = node.specifiers.slice(0); + if (specifiers && specifiers.length) { + let first = specifiers[0]; if (t.isImportDefaultSpecifier(first) || t.isImportNamespaceSpecifier(first)) { - print.plain(node.specifiers.shift()); - if (node.specifiers.length) { + print.plain(specifiers.shift()); + if (specifiers.length) { this.push(", "); } } - if (node.specifiers.length) { + if (specifiers.length) { this.push("{"); this.space(); - print.join(node.specifiers, { separator: ", " }); + print.join(specifiers, { separator: ", " }); this.space(); this.push("}"); } @@ -123,7 +126,7 @@ export function ImportDeclaration(node, print) { this.semicolon(); } -export function ImportNamespaceSpecifier(node, print) { +export function ImportNamespaceSpecifier(node: Object, print: NodePrinter) { this.push("* as "); print.plain(node.local); } diff --git a/packages/babel-generator/src/generators/statements.js b/packages/babel-generator/src/generators/statements.js index 7a67bfdc63..75ec354998 100644 --- a/packages/babel-generator/src/generators/statements.js +++ b/packages/babel-generator/src/generators/statements.js @@ -1,7 +1,10 @@ +/* @flow */ + +import type NodePrinter from "../node/printer"; import repeating from "repeating"; import * as t from "babel-types"; -export function WithStatement(node, print) { +export function WithStatement(node: Object, print: NodePrinter) { this.keyword("with"); this.push("("); print.plain(node.object); @@ -9,7 +12,7 @@ export function WithStatement(node, print) { print.block(node.body); } -export function IfStatement(node, print) { +export function IfStatement(node: Object, print: NodePrinter) { this.keyword("if"); this.push("("); print.plain(node.test); @@ -25,7 +28,7 @@ export function IfStatement(node, print) { } } -export function ForStatement(node, print) { +export function ForStatement(node: Object, print: NodePrinter) { this.keyword("for"); this.push("("); @@ -47,7 +50,7 @@ export function ForStatement(node, print) { print.block(node.body); } -export function WhileStatement(node, print) { +export function WhileStatement(node: Object, print: NodePrinter) { this.keyword("while"); this.push("("); print.plain(node.test); @@ -56,7 +59,7 @@ export function WhileStatement(node, print) { } let buildForXStatement = function (op) { - return function (node, print) { + return function (node: Object, print: NodePrinter) { this.keyword("for"); this.push("("); print.plain(node.left); @@ -70,7 +73,7 @@ let buildForXStatement = function (op) { export let ForInStatement = buildForXStatement("in"); export let ForOfStatement = buildForXStatement("of"); -export function DoWhileStatement(node, print) { +export function DoWhileStatement(node: Object, print: NodePrinter) { this.push("do "); print.plain(node.body); this.space(); @@ -81,7 +84,7 @@ export function DoWhileStatement(node, print) { } function buildLabelStatement(prefix, key = "label") { - return function (node, print) { + return function (node: Object, print: NodePrinter) { this.push(prefix); let label = node[key]; @@ -101,13 +104,13 @@ export let ReturnStatement = buildLabelStatement("return", "argument"); export let BreakStatement = buildLabelStatement("break"); export let ThrowStatement = buildLabelStatement("throw", "argument"); -export function LabeledStatement(node, print) { +export function LabeledStatement(node: Object, print: NodePrinter) { print.plain(node.label); this.push(": "); print.plain(node.body); } -export function TryStatement(node, print) { +export function TryStatement(node: Object, print: NodePrinter) { this.keyword("try"); print.plain(node.block); this.space(); @@ -128,7 +131,7 @@ export function TryStatement(node, print) { } } -export function CatchClause(node, print) { +export function CatchClause(node: Object, print: NodePrinter) { this.keyword("catch"); this.push("("); print.plain(node.param); @@ -136,7 +139,7 @@ export function CatchClause(node, print) { print.plain(node.body); } -export function SwitchStatement(node, print) { +export function SwitchStatement(node: Object, print: NodePrinter) { this.keyword("switch"); this.push("("); print.plain(node.discriminant); @@ -154,7 +157,7 @@ export function SwitchStatement(node, print) { this.push("}"); } -export function SwitchCase(node, print) { +export function SwitchCase(node: Object, print: NodePrinter) { if (node.test) { this.push("case "); print.plain(node.test); @@ -173,13 +176,13 @@ export function DebuggerStatement() { this.push("debugger;"); } -export function VariableDeclaration(node, print, parent) { +export function VariableDeclaration(node: Object, print: NodePrinter, parent: Object) { this.push(node.kind + " "); let hasInits = false; // don't add whitespace to loop heads if (!t.isFor(parent)) { - for (let declar of (node.declarations: Array)) { + for (let declar of (node.declarations: Array)) { if (declar.init) { // has an init so let's split it up over multiple lines hasInits = true; @@ -216,7 +219,7 @@ export function VariableDeclaration(node, print, parent) { this.semicolon(); } -export function VariableDeclarator(node, print) { +export function VariableDeclarator(node: Object, print: NodePrinter) { print.plain(node.id); print.plain(node.id.typeAnnotation); if (node.init) { diff --git a/packages/babel-generator/src/generators/template-literals.js b/packages/babel-generator/src/generators/template-literals.js index 9d0b4e694c..d10f0d461e 100644 --- a/packages/babel-generator/src/generators/template-literals.js +++ b/packages/babel-generator/src/generators/template-literals.js @@ -1,13 +1,17 @@ -export function TaggedTemplateExpression(node, print) { +/* @flow */ + +import type NodePrinter from "../node/printer"; + +export function TaggedTemplateExpression(node: Object, print: NodePrinter) { print.plain(node.tag); print.plain(node.quasi); } -export function TemplateElement(node) { +export function TemplateElement(node: Object) { this._push(node.value.raw); } -export function TemplateLiteral(node, print) { +export function TemplateLiteral(node: Object, print: NodePrinter) { this.push("`"); let quasis = node.quasis; diff --git a/packages/babel-generator/src/generators/types.js b/packages/babel-generator/src/generators/types.js index d1fcfac361..4310509baa 100644 --- a/packages/babel-generator/src/generators/types.js +++ b/packages/babel-generator/src/generators/types.js @@ -1,19 +1,22 @@ +/* @flow */ + /* eslint quotes: 0 */ +import type NodePrinter from "../node/printer"; import * as t from "babel-types"; -export function Identifier(node) { +export function Identifier(node: Object) { this.push(node.name); } -export function RestElement(node, print) { +export function RestElement(node: Object, print: NodePrinter) { this.push("..."); print.plain(node.argument); } export { RestElement as SpreadElement, RestElement as SpreadProperty }; -export function ObjectExpression(node, print) { +export function ObjectExpression(node: Object, print: NodePrinter) { let props = node.properties; this.push("{"); @@ -30,7 +33,7 @@ export function ObjectExpression(node, print) { export { ObjectExpression as ObjectPattern }; -export function Property(node, print) { +export function Property(node: Object, print: NodePrinter) { print.list(node.decorators, { separator: "" }); if (node.method || node.kind === "get" || node.kind === "set") { @@ -64,7 +67,7 @@ export function Property(node, print) { } } -export function ArrayExpression(node, print) { +export function ArrayExpression(node: Object, print: NodePrinter) { let elems = node.elements; let len = elems.length; @@ -92,11 +95,11 @@ export function ArrayExpression(node, print) { export { ArrayExpression as ArrayPattern }; -export function RegexLiteral(node) { +export function RegexLiteral(node: Object) { this.push(`/${node.pattern}/${node.flags}`); } -export function BooleanLiteral(node) { +export function BooleanLiteral(node: Object) { this.push(node.value ? "true" : "false"); } @@ -104,15 +107,15 @@ export function NullLiteral() { this.push("null"); } -export function NumberLiteral(node) { +export function NumberLiteral(node: Object) { this.push(node.value + ""); } -export function StringLiteral(node) { +export function StringLiteral(node: Object) { this.push(this._stringLiteral(node.value)); } -export function _stringLiteral(val) { +export function _stringLiteral(val: string): string { val = JSON.stringify(val); // escape illegal js but valid json unicode characters diff --git a/packages/babel-generator/src/index.js b/packages/babel-generator/src/index.js index b560b7e518..d6b14dbf0e 100644 --- a/packages/babel-generator/src/index.js +++ b/packages/babel-generator/src/index.js @@ -1,3 +1,5 @@ +/* @flow */ + import detectIndent from "detect-indent"; import Whitespace from "./whitespace"; import NodePrinter from "./node/printer"; @@ -32,6 +34,29 @@ class CodeGenerator { this.buffer = new Buffer(this.position, this.format); } + format: { + shouldPrintComment: boolean; + retainLines: boolean; + comments: boolean; + compact: boolean | "auto"; + quotes: "single" | "double"; + concise: boolean; + indent: { + adjustMultilineComment: boolean; + style: string; + base: number; + } + }; + + whitespace: Whitespace; + position: Position; + map: SourceMap; + buffer: Buffer; + comments: Array; + tokens: Array; + opts: Object; + ast: Object; + /** * Normalize generator options, setting defaults. * @@ -51,6 +76,7 @@ class CodeGenerator { retainLines: opts.retainLines, comments: opts.comments == null || opts.comments, compact: opts.compact, + concise: opts.concise, quotes: CodeGenerator.findCommonStringDelimiter(code, tokens), indent: { adjustMultilineComment: true, @@ -106,24 +132,6 @@ class CodeGenerator { } } - /** - * All node generators. - */ - - static generators = { - templateLiterals: require("./generators/template-literals"), - comprehensions: require("./generators/comprehensions"), - expressions: require("./generators/expressions"), - statements: require("./generators/statements"), - classes: require("./generators/classes"), - methods: require("./generators/methods"), - modules: require("./generators/modules"), - types: require("./generators/types"), - flow: require("./generators/flow"), - base: require("./generators/base"), - jsx: require("./generators/jsx") - }; - /** * Generate code and sourcemap from ast. * @@ -131,17 +139,7 @@ class CodeGenerator { */ generate() { - let ast = this.ast; - - this.print(ast); - - if (ast.comments) { - let comments = []; - for (let comment of (ast.comments: Array)) { - if (!comment._displayed) comments.push(comment); - } - this._printComments(comments); - } + this.print(this.ast); return { map: this.map.get(), @@ -238,10 +236,11 @@ class CodeGenerator { this.printTrailingComments(node, parent); } - printJoin(print, nodes, opts = {}) { + printJoin(print, nodes: ?Array, opts = {}) { if (!nodes || !nodes.length) return; let len = nodes.length; + let node, i; if (opts.indent) this.indent(); @@ -259,8 +258,8 @@ class CodeGenerator { } }; - for (let i = 0; i < nodes.length; i++) { - let node = nodes[i]; + for (i = 0; i < nodes.length; i++) { + node = nodes[i]; print.plain(node, printOpts); } @@ -307,13 +306,13 @@ class CodeGenerator { } let comments = []; - let nodes = [node]; + let nodes: Array = [node]; if (t.isExpressionStatement(node)) { nodes.push(node.argument); } - for (let node of (nodes: Array)) { + for (let node of nodes) { comments = comments.concat(this._getComments(key, node)); } @@ -394,13 +393,23 @@ each(Buffer.prototype, function (fn, key) { }; }); -each(CodeGenerator.generators, function (generator) { +each([ + require("./generators/template-literals"), + require("./generators/comprehensions"), + require("./generators/expressions"), + require("./generators/statements"), + require("./generators/classes"), + require("./generators/methods"), + require("./generators/modules"), + require("./generators/types"), + require("./generators/flow"), + require("./generators/base"), + require("./generators/jsx") +], function (generator) { extend(CodeGenerator.prototype, generator); }); -module.exports = function (ast, opts, code) { +export default function (ast: Object, opts: Object, code: string): Object { let gen = new CodeGenerator(ast, opts, code); return gen.generate(); -}; - -module.exports.CodeGenerator = CodeGenerator; +} diff --git a/packages/babel-generator/src/node/index.js b/packages/babel-generator/src/node/index.js index b6fecc1a9f..a477bde0e0 100644 --- a/packages/babel-generator/src/node/index.js +++ b/packages/babel-generator/src/node/index.js @@ -1,20 +1,12 @@ +/* @flow */ + import whitespace from "./whitespace"; import * as parens from "./parentheses"; import each from "lodash/collection/each"; import some from "lodash/collection/some"; import * as t from "babel-types"; -/** - * Test if node matches a set of type-matcher pairs. - * @example - * find({ - * VariableDeclaration(node, parent) { - * return true; - * } - * }, node, parent); - */ - -let find = function (obj, node, parent) { +function find(obj, node, parent) { if (!obj) return; let result; @@ -30,30 +22,21 @@ let find = function (obj, node, parent) { } return result; -}; - -/** - * Whitespace and Parenthesis related methods for nodes. - */ +} export default class Node { - constructor(node, parent) { + constructor(node: Object, parent: Object) { this.parent = parent; this.node = node; } - /** - * Test if `node` can have whitespace set by the user. - */ + parent: Object; + node: Object; static isUserWhitespacable(node) { return t.isUserWhitespacable(node); } - /** - * Test if a `node` requires whitespace. - */ - static needsWhitespace(node, parent, type) { if (!node) return 0; @@ -76,26 +59,14 @@ export default class Node { return (linesInfo && linesInfo[type]) || 0; } - /** - * Test if a `node` requires whitespace before it. - */ - static needsWhitespaceBefore(node, parent) { return Node.needsWhitespace(node, parent, "before"); } - /** - * Test if a `note` requires whitespace after it. - */ - static needsWhitespaceAfter(node, parent) { return Node.needsWhitespace(node, parent, "after"); } - /** - * Test if a `node` needs parentheses around it. - */ - static needsParens(node, parent) { if (!parent) return false; @@ -112,10 +83,6 @@ export default class Node { } } -/** - * Add all static methods from `Node` to `Node.prototype`. - */ - each(Node, function (fn, key) { Node.prototype[key] = function () { // Avoid leaking arguments to prevent deoptimization diff --git a/packages/babel-generator/src/node/parentheses.js b/packages/babel-generator/src/node/parentheses.js index 11c8eb3502..685ed247a2 100644 --- a/packages/babel-generator/src/node/parentheses.js +++ b/packages/babel-generator/src/node/parentheses.js @@ -1,40 +1,50 @@ -import each from "lodash/collection/each"; +/* @flow */ + import * as t from "babel-types"; -const PRECEDENCE = {}; +const PRECEDENCE = { + "||": 0, + "&&": 1, + "|": 2, + "^": 3, + "&": 4, + "==": 5, + "===": 5, + "!=": 5, + "!==": 5, + "<": 6, + ">": 6, + "<=": 6, + ">=": 6, + in: 6, + instanceof: 6, + ">>": 7, + "<<": 7, + ">>>": 7, + "+": 8, + "-": 8, + "*": 9, + "/": 9, + "%": 9, + "**": 10 +}; -each([ - ["||"], - ["&&"], - ["|"], - ["^"], - ["&"], - ["==", "===", "!=", "!=="], - ["<", ">", "<=", ">=", "in", "instanceof"], - [">>", "<<", ">>>"], - ["+", "-"], - ["*", "/", "%"], - ["**"] -], function (tier, i) { - each(tier, function (op) { - PRECEDENCE[op] = i; - }); -}); - -export function NullableTypeAnnotation(node, parent) { +export function NullableTypeAnnotation(node: Object, parent: Object): boolean { return t.isArrayTypeAnnotation(parent); } export { NullableTypeAnnotation as FunctionTypeAnnotation }; -export function UpdateExpression(node, parent) { +export function UpdateExpression(node: Object, parent: Object): boolean { if (t.isMemberExpression(parent) && parent.object === node) { // (foo++).test() return true; } + + return false; } -export function ObjectExpression(node, parent) { +export function ObjectExpression(node: Object, parent: Object): boolean { if (t.isExpressionStatement(parent)) { // ({ foo: "bar" }); return true; @@ -48,7 +58,7 @@ export function ObjectExpression(node, parent) { return false; } -export function Binary(node, parent) { +export function Binary(node: Object, parent: Object): boolean { if ((t.isCallExpression(parent) || t.isNewExpression(parent)) && parent.callee === node) { return true; } @@ -76,9 +86,11 @@ export function Binary(node, parent) { return true; } } + + return false; } -export function BinaryExpression(node, parent) { +export function BinaryExpression(node: Object, parent: Object): boolean { if (node.operator === "in") { // let i = (1 in []); if (t.isVariableDeclarator(parent)) { @@ -90,11 +102,13 @@ export function BinaryExpression(node, parent) { return true; } } + + return false; } -export function SequenceExpression(node, parent) { +export function SequenceExpression(node: Object, parent: Object): boolean { if (t.isForStatement(parent)) { - // Although parentheses wouldn't hurt around sequence + // Although parentheses wouldn"t hurt around sequence // expressions in the head of for loops, traditional style // dictates that e.g. i++, j++ should not be wrapped with // parentheses. @@ -110,7 +124,7 @@ export function SequenceExpression(node, parent) { return true; } -export function YieldExpression(node, parent) { +export function YieldExpression(node: Object, parent: Object): boolean { return t.isBinary(parent) || t.isUnaryLike(parent) || t.isCallExpression(parent) || @@ -120,7 +134,7 @@ export function YieldExpression(node, parent) { t.isYieldExpression(parent); } -export function ClassExpression(node, parent) { +export function ClassExpression(node: Object, parent: Object): boolean { // (class {}); if (t.isExpressionStatement(parent)) { return true; @@ -130,13 +144,15 @@ export function ClassExpression(node, parent) { if (t.isExportDeclaration(parent)) { return true; } + + return false; } -export function UnaryLike(node, parent) { +export function UnaryLike(node: Object, parent: Object): boolean { return t.isMemberExpression(parent) && parent.object === node; } -export function FunctionExpression(node, parent) { +export function FunctionExpression(node: Object, parent: Object): boolean { // (function () {}); if (t.isExpressionStatement(parent)) { return true; @@ -156,9 +172,11 @@ export function FunctionExpression(node, parent) { if (t.isCallExpression(parent) && parent.callee === node) { return true; } + + return false; } -export function ConditionalExpression(node, parent) { +export function ConditionalExpression(node: Object, parent: Object): boolean { if (t.isUnaryLike(parent)) { return true; } @@ -184,7 +202,7 @@ export function ConditionalExpression(node, parent) { return false; } -export function AssignmentExpression(node) { +export function AssignmentExpression(node: Object): boolean { if (t.isObjectPattern(node.left)) { return true; } else { diff --git a/packages/babel-generator/src/node/printer.js b/packages/babel-generator/src/node/printer.js index 5ee0f4a9a7..f672d167df 100644 --- a/packages/babel-generator/src/node/printer.js +++ b/packages/babel-generator/src/node/printer.js @@ -1,3 +1,5 @@ +/* @flow */ + /** * Printer for nodes, needs a `generator` and a `parent`. */ diff --git a/packages/babel-generator/src/node/whitespace.js b/packages/babel-generator/src/node/whitespace.js index 2623e1a273..b9ac11f2e8 100644 --- a/packages/babel-generator/src/node/whitespace.js +++ b/packages/babel-generator/src/node/whitespace.js @@ -1,3 +1,5 @@ +/* @flow */ + import isBoolean from "lodash/lang/isBoolean"; import each from "lodash/collection/each"; import map from "lodash/collection/map"; diff --git a/packages/babel-generator/src/position.js b/packages/babel-generator/src/position.js index a6787fd3b2..5810a90d6b 100644 --- a/packages/babel-generator/src/position.js +++ b/packages/babel-generator/src/position.js @@ -1,3 +1,5 @@ +/* @flow */ + /** * Track current position in code generation. */ diff --git a/packages/babel-generator/src/source-map.js b/packages/babel-generator/src/source-map.js index f1b3ee3727..75254843c9 100644 --- a/packages/babel-generator/src/source-map.js +++ b/packages/babel-generator/src/source-map.js @@ -1,3 +1,5 @@ +/* @flow */ + import sourceMap from "source-map"; import * as t from "babel-types"; diff --git a/packages/babel-generator/src/whitespace.js b/packages/babel-generator/src/whitespace.js index 05816b1b73..de8873d043 100644 --- a/packages/babel-generator/src/whitespace.js +++ b/packages/babel-generator/src/whitespace.js @@ -1,3 +1,5 @@ +/* @flow */ + /** * Returns `i`th number from `base`, continuing from 0 when `max` is reached. * Useful for shifting `for` loop by a fixed number but going over all items.