start movement of core into plugins

This commit is contained in:
Sebastian McKenzie 2015-06-15 15:17:04 +01:00
parent e08d400b36
commit 8b096ac705
85 changed files with 1918 additions and 1685 deletions

View File

@ -30,6 +30,7 @@
"dependencies": { "dependencies": {
"acorn-jsx": "^1.0.0", "acorn-jsx": "^1.0.0",
"ast-types": "~0.7.0", "ast-types": "~0.7.0",
"babel-plugin-undefined-to-void": "^1.1.0",
"bluebird": "^2.9.25", "bluebird": "^2.9.25",
"chalk": "^1.0.0", "chalk": "^1.0.0",
"convert-source-map": "^1.1.0", "convert-source-map": "^1.1.0",

View File

@ -0,0 +1,117 @@
#!/usr/bin/env node
var readline = require("readline");
var child = require("child_process");
var path = require("path");
var fs = require("fs");
function spawn(cmd, args, callback) {
console.log(">", cmd, args);
var spawn = child.spawn(cmd, args, { stdio: "inherit" });
spawn.on("exit", function (code) {
if (code === 0) {
if (callback) callback();
} else {
console.log("Killing...");
process.exit(1);
}
});
}
function spawnMultiple(cmds) {
function next() {
var cmd = cmds.shift();
if (cmd) {
spawn(cmd.command, cmd.args, next);
} else {
process.exit();
}
}
next();
}
function write(filename, content) {
console.log(filename);
fs.writeFileSync(filename, content);
}
var BABEL_PLUGIN_PREFIX = "babel-plugin-";
var cmds = {
init: function () {
var name = path.basename(process.cwd());
if (name.indexOf(BABEL_PLUGIN_PREFIX) === 0) {
name = name.slice(BABEL_PLUGIN_PREFIX.length);
}
write("package.json", JSON.stringify({
name: BABEL_PLUGIN_PREFIX + name,
version: "1.0.0",
description: "",
license: "MIT",
main: "lib/index.js",
devDependencies: {
babel: "^5.6.0"
},
peerDependencies: {
babel: "^5.6.0"
},
scripts: {
build: "babel-plugin build",
push: "babel-plugin publish",
test: "babel-plugin test"
},
keywords: ["babel-plugin"]
}, null, " "));
write(".npmignore", "node_modules\n*.log\nsrc");
write(".gitignore", "node_modules\n*.log\nlib");
fs.mkdirSync("src");
write("src/index.js", "");
},
build: function () {
spawn("babel", ["src", "--out-dir", "lib"]);
},
publish: function () {
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
var pkg = require(process.cwd() + "/package.json");
console.log("Current verison:", pkg.version);
rl.question("New version (enter nothing for patch): ", function (newVersion) {
newVersion = newVersion || "patch";
spawnMultiple([
{ command: "git", args: ["pull"] },
{ command: "git", args: ["push"] },
{ command: "babel-plugin", args: ["build"] },
{ command: "npm", args: ["version", newVersion] },
{ command: "npm", args: ["publish"] },
{ command: "git", args: ["push", "--follow-tags"] }
]);
});
}
};
var cmd = cmds[process.argv[2]];
if (cmd) {
cmd();
} else {
console.error("Unknown command:", cmd);
process.exit(1);
}

View File

@ -23,6 +23,7 @@
"bin": { "bin": {
"babel": "./bin/babel/index.js", "babel": "./bin/babel/index.js",
"babel-node": "./bin/babel-node", "babel-node": "./bin/babel-node",
"babel-external-helpers": "./bin/babel-external-helpers" "babel-external-helpers": "./bin/babel-external-helpers",
"babel-plugin": "./bin/babel-plugin"
} }
} }

View File

@ -9,8 +9,9 @@ export { pipeline } from "../transformation";
export { canCompile } from "../util"; export { canCompile } from "../util";
export { default as options } from "../transformation/file/options/config"; export { default as options } from "../transformation/file/options/config";
export { default as Plugin } from "../transformation/plugin";
export { default as Transformer } from "../transformation/transformer"; export { default as Transformer } from "../transformation/transformer";
export { default as TransformerPipeline } from "../transformation/transformer-pipeline"; export { default as Pipeline } from "../transformation/pipeline";
export { default as traverse } from "../traversal"; export { default as traverse } from "../traversal";
export { default as buildExternalHelpers } from "../tools/build-external-helpers"; export { default as buildExternalHelpers } from "../tools/build-external-helpers";
export { version } from "../../../package"; export { version } from "../../../package";

View File

@ -105,7 +105,7 @@ if (process.env.running_under_istanbul) {
if (istanbulMonkey[filename]) { if (istanbulMonkey[filename]) {
delete istanbulMonkey[filename]; delete istanbulMonkey[filename];
var code = compile(filename, { var code = compile(filename, {
auxiliaryComment: "istanbul ignore next" auxiliaryCommentBefore: "istanbul ignore next"
}); });
istanbulMonkey[filename] = true; istanbulMonkey[filename] = true;
return code; return code;

View File

@ -34,10 +34,10 @@ export const MESSAGES = {
pluginIllegalKind: "Illegal kind $1 for plugin $2", pluginIllegalKind: "Illegal kind $1 for plugin $2",
pluginIllegalPosition: "Illegal position $1 for plugin $2", pluginIllegalPosition: "Illegal position $1 for plugin $2",
pluginKeyCollision: "The plugin $1 collides with another of the same name", pluginKeyCollision: "The plugin $1 collides with another of the same name",
pluginNotTransformer: "The plugin $1 didn't export a Transformer instance", pluginNotTransformer: "The plugin $1 didn't export a Plugin instance",
pluginUnknown: "Unknown plugin $1", pluginUnknown: "Unknown plugin $1",
transformerNotFile: "Transformer $1 is resolving to a different Babel version to what is doing the actual transformation..." pluginNotFile: "Plugin $1 is resolving to a different Babel version to what is doing the actual transformation..."
}; };
export function get(key: String, ...args) { export function get(key: String, ...args) {

View File

@ -4,7 +4,6 @@ import moduleFormatters from "../modules";
import PluginManager from "./plugin-manager"; import PluginManager from "./plugin-manager";
import shebangRegex from "shebang-regex"; import shebangRegex from "shebang-regex";
import NodePath from "../../traversal/path"; import NodePath from "../../traversal/path";
import Transformer from "../transformer";
import isFunction from "lodash/lang/isFunction"; import isFunction from "lodash/lang/isFunction";
import isAbsolute from "path-is-absolute"; import isAbsolute from "path-is-absolute";
import resolveRc from "./options/resolve-rc"; import resolveRc from "./options/resolve-rc";
@ -14,13 +13,14 @@ import codeFrame from "../../helpers/code-frame";
import defaults from "lodash/object/defaults"; import defaults from "lodash/object/defaults";
import includes from "lodash/collection/includes"; import includes from "lodash/collection/includes";
import traverse from "../../traversal"; import traverse from "../../traversal";
import Hub from "../../traversal/hub";
import assign from "lodash/object/assign"; import assign from "lodash/object/assign";
import Logger from "./logger"; import Logger from "./logger";
import Plugin from "../plugin";
import parse from "../../helpers/parse"; import parse from "../../helpers/parse";
import merge from "../../helpers/merge"; import merge from "../../helpers/merge";
import slash from "slash"; import slash from "slash";
import clone from "lodash/lang/clone"; import clone from "lodash/lang/clone";
import Hub from "../../traversal/hub";
import * as util from "../../util"; import * as util from "../../util";
import path from "path"; import path from "path";
import * as t from "../../types"; import * as t from "../../types";
@ -246,7 +246,7 @@ export default class File {
// build dependency graph // build dependency graph
for (let pass of (stack: Array)) { for (let pass of (stack: Array)) {
for (var dep of (pass.transformer.dependencies: Array)) { for (var dep of (pass.plugin.dependencies: Array)) {
this.transformerDependencies[dep] = pass.key; this.transformerDependencies[dep] = pass.key;
} }
} }
@ -263,7 +263,7 @@ export default class File {
// been merged // been merged
if (ignore.indexOf(pass) >= 0) continue; if (ignore.indexOf(pass) >= 0) continue;
var group = pass.transformer.metadata.group; var group = pass.plugin.metadata.group;
// can't merge // can't merge
if (!pass.canTransform() || !group) { if (!pass.canTransform() || !group) {
@ -273,7 +273,7 @@ export default class File {
var mergeStack = []; var mergeStack = [];
for (let pass of (_stack: Array)) { for (let pass of (_stack: Array)) {
if (pass.transformer.metadata.group === group) { if (pass.plugin.metadata.group === group) {
mergeStack.push(pass); mergeStack.push(pass);
ignore.push(pass); ignore.push(pass);
} }
@ -281,11 +281,11 @@ export default class File {
var visitors = []; var visitors = [];
for (let pass of (mergeStack: Array)) { for (let pass of (mergeStack: Array)) {
visitors.push(pass.handlers); visitors.push(pass.plugin.visitor);
} }
var visitor = traverse.visitors.merge(visitors); var visitor = traverse.visitors.merge(visitors);
var mergeTransformer = new Transformer(group, visitor); var mergePlugin = new Plugin(group, { visitor });
stack.push(mergeTransformer.buildPass(this)); stack.push(mergePlugin.buildPass(this));
} }
return stack; return stack;
@ -586,7 +586,7 @@ export default class File {
call(key: string) { call(key: string) {
for (var pass of (this.uncollapsedTransformerStack: Array)) { for (var pass of (this.uncollapsedTransformerStack: Array)) {
var fn = pass.transformer[key]; var fn = pass.plugin[key];
if (fn) fn(this); if (fn) fn(this);
} }
} }

View File

@ -1,4 +1,13 @@
import * as node from "../../api/node"; import Transformer from "../transformer";
import Plugin from "../plugin";
import * as types from "../../types";
var context = {
Transformer,
Plugin,
types
};
import * as messages from "../../messages"; import * as messages from "../../messages";
import * as util from "../../util"; import * as util from "../../util";
@ -11,7 +20,7 @@ export default class PluginManager {
if (plugin.container === fn) return plugin.transformer; if (plugin.container === fn) return plugin.transformer;
} }
var transformer = fn(node); var transformer = fn(context);
PluginManager.memoisedPlugins.push({ PluginManager.memoisedPlugins.push({
container: fn, container: fn,
transformer: transformer transformer: transformer
@ -55,7 +64,7 @@ export default class PluginManager {
} }
// validate Transformer instance // validate Transformer instance
if (!plugin.buildPass || plugin.constructor.name !== "Transformer") { if (!plugin.buildPass || plugin.constructor.name !== "Plugin") {
throw new TypeError(messages.get("pluginNotTransformer", name)); throw new TypeError(messages.get("pluginNotTransformer", name));
} }

View File

@ -9,8 +9,10 @@ import esutils from "esutils";
import * as react from "./react"; import * as react from "./react";
import * as t from "../../types"; import * as t from "../../types";
export default function (exports, opts) { export default function (opts) {
exports.JSXIdentifier = function (node) { var visitor = {};
visitor.JSXIdentifier = function (node) {
if (node.name === "this" && this.isReferenced()) { if (node.name === "this" && this.isReferenced()) {
return t.thisExpression(); return t.thisExpression();
} else if (esutils.keyword.isIdentifierNameES6(node.name)) { } else if (esutils.keyword.isIdentifierNameES6(node.name)) {
@ -20,22 +22,22 @@ export default function (exports, opts) {
} }
}; };
exports.JSXNamespacedName = function () { visitor.JSXNamespacedName = function () {
throw this.errorWithNode(messages.get("JSXNamespacedTags")); throw this.errorWithNode(messages.get("JSXNamespacedTags"));
}; };
exports.JSXMemberExpression = { visitor.JSXMemberExpression = {
exit(node) { exit(node) {
node.computed = t.isLiteral(node.property); node.computed = t.isLiteral(node.property);
node.type = "MemberExpression"; node.type = "MemberExpression";
} }
}; };
exports.JSXExpressionContainer = function (node) { visitor.JSXExpressionContainer = function (node) {
return node.expression; return node.expression;
}; };
exports.JSXAttribute = { visitor.JSXAttribute = {
enter(node) { enter(node) {
var value = node.value; var value = node.value;
if (t.isLiteral(value) && isString(value.value)) { if (t.isLiteral(value) && isString(value.value)) {
@ -49,7 +51,7 @@ export default function (exports, opts) {
} }
}; };
exports.JSXOpeningElement = { visitor.JSXOpeningElement = {
exit(node, parent, scope, file) { exit(node, parent, scope, file) {
parent.children = react.buildChildren(parent); parent.children = react.buildChildren(parent);
@ -139,7 +141,7 @@ export default function (exports, opts) {
return attribs; return attribs;
}; };
exports.JSXElement = { visitor.JSXElement = {
exit(node) { exit(node) {
var callExpr = node.openingElement; var callExpr = node.openingElement;
@ -173,15 +175,15 @@ export default function (exports, opts) {
} }
}; };
exports.ExportDefaultDeclaration = function (node, parent, scope, file) { visitor.ExportDefaultDeclaration = function (node, parent, scope, file) {
if (react.isCreateClass(node.declaration)) { if (react.isCreateClass(node.declaration)) {
addDisplayName(file.opts.basename, node.declaration); addDisplayName(file.opts.basename, node.declaration);
} }
}; };
exports.AssignmentExpression = visitor.AssignmentExpression =
exports.Property = visitor.Property =
exports.VariableDeclarator = function (node) { visitor.VariableDeclarator = function (node) {
var left, right; var left, right;
if (t.isAssignmentExpression(node)) { if (t.isAssignmentExpression(node)) {
@ -203,4 +205,6 @@ export default function (exports, opts) {
addDisplayName(left.name, right); addDisplayName(left.name, right);
} }
}; };
return visitor;
} }

View File

@ -68,10 +68,10 @@ var visit = function (node, name, scope) {
// check to see if we have a local binding of the id we're setting inside of // check to see if we have a local binding of the id we're setting inside of
// the function, this is important as there are caveats associated // the function, this is important as there are caveats associated
var bindingInfo = scope.getOwnBinding(name); var binding = scope.getOwnBinding(name);
if (bindingInfo) { if (binding) {
if (bindingInfo.kind === "param") { if (binding.kind === "param") {
// safari will blow up in strict mode with code like: // safari will blow up in strict mode with code like:
// //
// var t = function t(t) {}; // var t = function t(t) {};
@ -133,8 +133,8 @@ export function bare(node, parent, scope) {
id = parent.id; id = parent.id;
if (t.isIdentifier(id)) { if (t.isIdentifier(id)) {
var bindingInfo = scope.parent.getBinding(id.name); var binding = scope.parent.getBinding(id.name);
if (bindingInfo && bindingInfo.constant && scope.getBinding(id.name) === bindingInfo) { if (binding && binding.constant && scope.getBinding(id.name) === binding) {
// always going to reference this method // always going to reference this method
node.id = id; node.id = id;
return; return;

View File

@ -1,4 +1,4 @@
import Pipeline from "./transformer-pipeline"; import Pipeline from "./pipeline";
var pipeline = new Pipeline; var pipeline = new Pipeline;
@ -8,8 +8,11 @@ import transformers from "./transformers";
for (var key in transformers) { for (var key in transformers) {
var transformer = transformers[key]; var transformer = transformers[key];
if (typeof transformer === "object") {
var metadata = transformer.metadata = transformer.metadata || {}; var metadata = transformer.metadata = transformer.metadata || {};
metadata.group = metadata.group || "builtin-basic"; metadata.group = metadata.group || "builtin-basic";
}
} }
pipeline.addTransformers(transformers); pipeline.addTransformers(transformers);

View File

@ -1,10 +1,11 @@
import Transformer from "./transformer"; import PluginManager from "./file/plugin-manager";
import normalizeAst from "../helpers/normalize-ast"; import normalizeAst from "../helpers/normalize-ast";
import Plugin from "./plugin";
import assign from "lodash/object/assign"; import assign from "lodash/object/assign";
import object from "../helpers/object"; import object from "../helpers/object";
import File from "./file"; import File from "./file";
export default class TransformerPipeline { export default class Pipeline {
constructor() { constructor() {
this.transformers = object(); this.transformers = object();
this.namespaces = object(); this.namespaces = object();
@ -20,7 +21,7 @@ export default class TransformerPipeline {
return this; return this;
} }
addTransformer(key, transformer) { addTransformer(key, plugin) {
if (this.transformers[key]) throw new Error(); // todo: error if (this.transformers[key]) throw new Error(); // todo: error
var namespace = key.split(".")[0]; var namespace = key.split(".")[0];
@ -28,7 +29,15 @@ export default class TransformerPipeline {
this.namespaces[namespace].push(key); this.namespaces[namespace].push(key);
this.namespaces[key] = namespace; this.namespaces[key] = namespace;
this.transformers[key] = new Transformer(key, transformer); if (typeof plugin === "function") {
plugin = PluginManager.memoisePluginContainer(plugin);
plugin.key = key;
plugin.metadata.optional = true;
} else {
plugin = new Plugin(key, plugin);
}
this.transformers[key] = plugin;
} }
addAliases(names) { addAliases(names) {
@ -46,17 +55,24 @@ export default class TransformerPipeline {
return this; return this;
} }
canTransform(transformer, fileOpts) { canTransform(plugin, fileOpts) {
if (transformer.metadata.plugin) return true; if (plugin.metadata.plugin) {
return true;
}
for (var filter of (this.filters: Array)) { for (var filter of (this.filters: Array)) {
var result = filter(transformer, fileOpts); var result = filter(plugin, fileOpts);
if (result != null) return result; if (result != null) return result;
} }
return true; return true;
} }
analyze(code: string, opts?: Object = {}) {
opts.code = false;
return this.transform(code, opts);
}
pretransform(code: string, opts?: Object) { pretransform(code: string, opts?: Object) {
var file = new File(opts, this); var file = new File(opts, this);
return file.wrap(code, function () { return file.wrap(code, function () {

View File

@ -7,14 +7,13 @@ import type File from "./file";
* AST and running it's parent transformers handlers over it. * AST and running it's parent transformers handlers over it.
*/ */
export default class TransformerPass { export default class PluginPass {
constructor(file: File, transformer: Transformer) { constructor(file: File, plugin: Transformer) {
this.transformer = transformer; this.plugin = plugin;
this.handlers = transformer.handlers;
this.file = file; this.file = file;
this.key = transformer.key; this.key = plugin.key;
if (this.canTransform() && transformer.metadata.experimental && !file.opts.experimental) { if (this.canTransform() && plugin.metadata.experimental && !file.opts.experimental) {
file.log.warn(`THE TRANSFORMER ${this.key} HAS BEEN MARKED AS EXPERIMENTAL AND IS WIP. USE AT YOUR OWN RISK. ` + file.log.warn(`THE TRANSFORMER ${this.key} HAS BEEN MARKED AS EXPERIMENTAL AND IS WIP. USE AT YOUR OWN RISK. ` +
"THIS WILL HIGHLY LIKELY BREAK YOUR CODE SO USE WITH **EXTREME** CAUTION. ENABLE THE " + "THIS WILL HIGHLY LIKELY BREAK YOUR CODE SO USE WITH **EXTREME** CAUTION. ENABLE THE " +
"`experimental` OPTION TO IGNORE THIS WARNING."); "`experimental` OPTION TO IGNORE THIS WARNING.");
@ -23,13 +22,13 @@ export default class TransformerPass {
canTransform(): boolean { canTransform(): boolean {
return this.file.transformerDependencies[this.key] || return this.file.transformerDependencies[this.key] ||
this.file.pipeline.canTransform(this.transformer, this.file.opts); this.file.pipeline.canTransform(this.plugin, this.file.opts);
} }
transform() { transform() {
var file = this.file; var file = this.file;
file.log.debug(`Start transformer ${this.key}`); file.log.debug(`Start transformer ${this.key}`);
traverse(file.ast, this.handlers, file.scope, file); traverse(file.ast, this.plugin.visitor, file.scope, file);
file.log.debug(`Finish transformer ${this.key}`); file.log.debug(`Finish transformer ${this.key}`);
} }
} }

View File

@ -0,0 +1,55 @@
import PluginPass from "./plugin-pass";
import * as messages from "../messages";
import isFunction from "lodash/lang/isFunction";
import traverse from "../traversal";
import assign from "lodash/object/assign";
import clone from "lodash/lang/clone";
import File from "./file";
export default class Plugin {
constructor(key: string, plugin: Object) {
plugin = assign({}, plugin);
var take = function (key) {
var val = plugin[key];
delete plugin[key];
return val;
};
this.manipulateOptions = take("manipulateOptions");
this.metadata = take("metadata") || {};
this.dependencies = this.metadata.dependencies || [];
this.post = take("post");
this.pre = take("pre");
//
if (this.metadata.stage != null) {
this.metadata.optional = true;
}
//
this.visitor = this.normalize(clone(take("visitor")) || {});
this.key = key;
}
normalize(visitor: Object): Object {
if (isFunction(visitor)) {
visitor = { ast: visitor };
}
traverse.explode(visitor);
return visitor;
}
buildPass(file: File): PluginPass {
// validate Transformer instance
if (!(file instanceof File)) {
throw new TypeError(messages.get("pluginNotFile", this.key));
}
return new PluginPass(file, this);
}
}

View File

@ -1,82 +1,14 @@
import TransformerPass from "./transformer-pass"; import Plugin from "./plugin";
import * as messages from "../messages";
import isFunction from "lodash/lang/isFunction";
import traverse from "../traversal";
import isObject from "lodash/lang/isObject";
import assign from "lodash/object/assign";
import File from "./file";
import each from "lodash/collection/each";
/**
* This is the class responsible for normalising a transformers handlers
* as well as constructing a `TransformerPass` that is responsible for
* actually running the transformer over the provided `File`.
*/
export default class Transformer { export default class Transformer {
constructor(transformerKey: string, transformer: Object) { constructor(key, obj) {
transformer = assign({}, transformer); var plugin = {};
var take = function (key) { plugin.metadata = obj.metadata;
var val = transformer[key]; delete obj.metadata;
delete transformer[key];
return val;
};
this.manipulateOptions = take("manipulateOptions"); plugin.visitor = obj;
this.metadata = take("metadata") || {};
this.dependencies = this.metadata.dependencies || [];
this.parser = take("parser");
this.post = take("post");
this.pre = take("pre");
// return new Plugin(key, plugin);
if (this.metadata.stage != null) {
this.metadata.optional = true;
}
//
this.handlers = this.normalize(transformer);
this.key = transformerKey;
}
normalize(transformer: Object): Object {
if (isFunction(transformer)) {
transformer = { ast: transformer };
}
traverse.explode(transformer);
each(transformer, (fns, type) => {
// hidden property
if (type[0] === "_") {
this[type] = fns;
return;
}
if (type === "enter" || type === "exit") return;
if (isFunction(fns)) fns = { enter: fns };
if (!isObject(fns)) return;
if (!fns.enter) fns.enter = function () { };
if (!fns.exit) fns.exit = function () { };
transformer[type] = fns;
});
return transformer;
}
buildPass(file: File): TransformerPass {
// validate Transformer instance
if (!(file instanceof File)) {
throw new TypeError(messages.get("transformerNotFile", this.key));
}
return new TransformerPass(file, this);
} }
} }

View File

@ -4,7 +4,8 @@ export var metadata = {
group: "builtin-trailing" group: "builtin-trailing"
}; };
export var MemberExpression = { export var visitor = {
MemberExpression: {
exit(node) { exit(node) {
var prop = node.property; var prop = node.property;
if (!node.computed && t.isIdentifier(prop) && !t.isValidIdentifier(prop.name)) { if (!node.computed && t.isIdentifier(prop) && !t.isValidIdentifier(prop.name)) {
@ -13,4 +14,5 @@ export var MemberExpression = {
node.computed = true; node.computed = true;
} }
} }
}
}; };

View File

@ -4,7 +4,8 @@ export var metadata = {
group: "builtin-trailing" group: "builtin-trailing"
}; };
export var Property = { export var visitor = {
Property: {
exit(node) { exit(node) {
var key = node.key; var key = node.key;
if (!node.computed && t.isIdentifier(key) && !t.isValidIdentifier(key.name)) { if (!node.computed && t.isIdentifier(key) && !t.isValidIdentifier(key.name)) {
@ -12,4 +13,5 @@ export var Property = {
node.key = t.literal(key.name); node.key = t.literal(key.name);
} }
} }
}
}; };

View File

@ -1,7 +1,8 @@
import * as defineMap from "../../helpers/define-map"; import * as defineMap from "../../helpers/define-map";
import * as t from "../../../types"; import * as t from "../../../types";
export function ObjectExpression(node, parent, scope, file) { export var visitor = {
ObjectExpression(node, parent, scope, file) {
var hasAny = false; var hasAny = false;
for (var prop of (node.properties: Array)) { for (var prop of (node.properties: Array)) {
if (prop.kind === "get" || prop.kind === "set") { if (prop.kind === "get" || prop.kind === "set") {
@ -26,4 +27,5 @@ export function ObjectExpression(node, parent, scope, file) {
t.memberExpression(t.identifier("Object"), t.identifier("defineProperties")), t.memberExpression(t.identifier("Object"), t.identifier("defineProperties")),
[node, defineMap.toDefineObject(mutatorMap)] [node, defineMap.toDefineObject(mutatorMap)]
); );
} }
};

View File

@ -1,9 +1,11 @@
import * as t from "../../../types"; import * as t from "../../../types";
export function ArrowFunctionExpression(node) { export var visitor = {
ArrowFunctionExpression(node) {
t.ensureBlock(node); t.ensureBlock(node);
node.expression = false; node.expression = false;
node.type = "FunctionExpression"; node.type = "FunctionExpression";
node.shadow = true; node.shadow = true;
} }
};

View File

@ -44,7 +44,8 @@ export var metadata = {
group: "builtin-advanced" group: "builtin-advanced"
}; };
export function VariableDeclaration(node, parent, scope, file) { export var visitor = {
VariableDeclaration(node, parent, scope, file) {
if (!isLet(node, parent)) return; if (!isLet(node, parent)) return;
if (isLetInitable(node) && file.transformers["es6.spec.blockScoping"].canTransform()) { if (isLetInitable(node) && file.transformers["es6.spec.blockScoping"].canTransform()) {
@ -64,9 +65,9 @@ export function VariableDeclaration(node, parent, scope, file) {
return nodes; return nodes;
} }
} },
export function Loop(node, parent, scope, file) { Loop(node, parent, scope, file) {
var init = node.left || node.init; var init = node.left || node.init;
if (isLet(init, node)) { if (isLet(init, node)) {
t.ensureBlock(node); t.ensureBlock(node);
@ -75,16 +76,15 @@ export function Loop(node, parent, scope, file) {
var blockScoping = new BlockScoping(this, this.get("body"), parent, scope, file); var blockScoping = new BlockScoping(this, this.get("body"), parent, scope, file);
return blockScoping.run(); return blockScoping.run();
} },
export function BlockStatement(block, parent, scope, file) { "BlockStatement|Program"(block, parent, scope, file) {
if (!t.isLoop(parent)) { if (!t.isLoop(parent)) {
var blockScoping = new BlockScoping(null, this, parent, scope, file); var blockScoping = new BlockScoping(null, this, parent, scope, file);
blockScoping.run(); blockScoping.run();
} }
} }
};
export { BlockStatement as Program };
function replace(node, parent, scope, remaps) { function replace(node, parent, scope, remaps) {
var remap = remaps[node.name]; var remap = remaps[node.name];

View File

@ -10,15 +10,17 @@ import * as t from "../../../types";
const PROPERTY_COLLISION_METHOD_NAME = "__initializeProperties"; const PROPERTY_COLLISION_METHOD_NAME = "__initializeProperties";
export function ClassDeclaration(node, parent, scope, file) { export var visitor = {
ClassDeclaration(node) {
return t.variableDeclaration("let", [ return t.variableDeclaration("let", [
t.variableDeclarator(node.id, t.toExpression(node)) t.variableDeclarator(node.id, t.toExpression(node))
]); ]);
} },
export function ClassExpression(node, parent, scope, file) { ClassExpression(node, parent, scope, file) {
return new ClassTransformer(this, file).run(); return new ClassTransformer(this, file).run();
} }
};
var collectPropertyReferencesVisitor = { var collectPropertyReferencesVisitor = {
Identifier: { Identifier: {

View File

@ -1,6 +1,7 @@
import * as messages from "../../../messages"; import * as messages from "../../../messages";
export function Scope(node, parent, scope) { export var visitor = {
Scope(node, parent, scope) {
for (var name in scope.bindings) { for (var name in scope.bindings) {
var binding = scope.bindings[name]; var binding = scope.bindings[name];
@ -11,8 +12,9 @@ export function Scope(node, parent, scope) {
throw violation.errorWithNode(messages.get("readOnly", name)); throw violation.errorWithNode(messages.get("readOnly", name));
} }
} }
} },
export function VariableDeclaration(node) { VariableDeclaration(node) {
if (node.kind === "const") node.kind = "let"; if (node.kind === "const") node.kind = "let";
} }
};

View File

@ -5,7 +5,8 @@ export var metadata = {
group: "builtin-advanced" group: "builtin-advanced"
}; };
export function ForOfStatement(node, parent, scope, file) { export var visitor = {
ForXStatement(node, parent, scope, file) {
var left = node.left; var left = node.left;
if (t.isPattern(left)) { if (t.isPattern(left)) {
@ -51,11 +52,9 @@ export function ForOfStatement(node, parent, scope, file) {
var block = node.body; var block = node.body;
block.body = nodes.concat(block.body); block.body = nodes.concat(block.body);
} },
export { ForOfStatement as ForInStatement }; Function(node, parent, scope, file) {
export function Func/*tion*/(node, parent, scope, file) {
var hasDestructuring = false; var hasDestructuring = false;
for (let pattern of (node.params: Array)) { for (let pattern of (node.params: Array)) {
if (t.isPattern(pattern)) { if (t.isPattern(pattern)) {
@ -89,9 +88,9 @@ export function Func/*tion*/(node, parent, scope, file) {
var block = node.body; var block = node.body;
block.body = nodes.concat(block.body); block.body = nodes.concat(block.body);
} },
export function CatchClause(node, parent, scope, file) { CatchClause(node, parent, scope, file) {
var pattern = node.param; var pattern = node.param;
if (!t.isPattern(pattern)) return; if (!t.isPattern(pattern)) return;
@ -109,9 +108,9 @@ export function CatchClause(node, parent, scope, file) {
destructuring.init(pattern, ref); destructuring.init(pattern, ref);
node.body.body = nodes.concat(node.body.body); node.body.body = nodes.concat(node.body.body);
} },
export function AssignmentExpression(node, parent, scope, file) { AssignmentExpression(node, parent, scope, file) {
if (!t.isPattern(node.left)) return; if (!t.isPattern(node.left)) return;
var nodes = []; var nodes = [];
@ -143,18 +142,9 @@ export function AssignmentExpression(node, parent, scope, file) {
} }
return nodes; return nodes;
} },
function variableDeclarationHasPattern(node) { VariableDeclaration(node, parent, scope, file) {
for (var i = 0; i < node.declarations.length; i++) {
if (t.isPattern(node.declarations[i].id)) {
return true;
}
}
return false;
}
export function VariableDeclaration(node, parent, scope, file) {
if (t.isForXStatement(parent)) return; if (t.isForXStatement(parent)) return;
if (!variableDeclarationHasPattern(node)) return; if (!variableDeclarationHasPattern(node)) return;
@ -208,6 +198,16 @@ export function VariableDeclaration(node, parent, scope, file) {
} }
return nodes; return nodes;
}
};
function variableDeclarationHasPattern(node) {
for (var i = 0; i < node.declarations.length; i++) {
if (t.isPattern(node.declarations[i].id)) {
return true;
}
}
return false;
} }
function hasRest(pattern) { function hasRest(pattern) {

View File

@ -2,7 +2,8 @@ import * as messages from "../../../messages";
import * as util from "../../../util"; import * as util from "../../../util";
import * as t from "../../../types"; import * as t from "../../../types";
export function ForOfStatement(node, parent, scope, file) { export var visitor = {
ForOfStatement(node, parent, scope, file) {
if (this.get("right").isArrayExpression()) { if (this.get("right").isArrayExpression()) {
return _ForOfStatementArray.call(this, node, scope, file); return _ForOfStatementArray.call(this, node, scope, file);
} }
@ -35,7 +36,8 @@ export function ForOfStatement(node, parent, scope, file) {
} else { } else {
return build.node; return build.node;
} }
} }
};
export function _ForOfStatementArray(node, scope, file) { export function _ForOfStatementArray(node, scope, file) {
var nodes = []; var nodes = [];

View File

@ -12,7 +12,8 @@ export var metadata = {
group: "builtin-modules" group: "builtin-modules"
}; };
export function ImportDeclaration(node, parent, scope, file) { export var visitor = {
ImportDeclaration(node, parent, scope, file) {
// flow type // flow type
if (node.isType) return; if (node.isType) return;
@ -32,23 +33,23 @@ export function ImportDeclaration(node, parent, scope, file) {
} }
return nodes; return nodes;
} },
export function ExportAllDeclaration(node, parent, scope, file) { ExportAllDeclaration(node, parent, scope, file) {
var nodes = []; var nodes = [];
file.moduleFormatter.exportAllDeclaration(node, nodes, parent); file.moduleFormatter.exportAllDeclaration(node, nodes, parent);
keepBlockHoist(node, nodes); keepBlockHoist(node, nodes);
return nodes; return nodes;
} },
export function ExportDefaultDeclaration(node, parent, scope, file) { ExportDefaultDeclaration(node, parent, scope, file) {
var nodes = []; var nodes = [];
file.moduleFormatter.exportDeclaration(node, nodes, parent); file.moduleFormatter.exportDeclaration(node, nodes, parent);
keepBlockHoist(node, nodes); keepBlockHoist(node, nodes);
return nodes; return nodes;
} },
export function ExportNamedDeclaration(node, parent, scope, file) { ExportNamedDeclaration(node, parent, scope, file) {
// flow type // flow type
if (this.get("declaration").isTypeAlias()) return; if (this.get("declaration").isTypeAlias()) return;
@ -72,4 +73,5 @@ export function ExportNamedDeclaration(node, parent, scope, file) {
keepBlockHoist(node, nodes); keepBlockHoist(node, nodes);
return nodes; return nodes;
} }
};

View File

@ -17,7 +17,8 @@ function Property(path, node, scope, getObjectRef, file) {
replaceSupers.replace(); replaceSupers.replace();
} }
export function ObjectExpression(node, parent, scope, file) { export var visitor = {
ObjectExpression(node, parent, scope, file) {
var objectRef; var objectRef;
var getObjectRef = () => objectRef = objectRef || scope.generateUidIdentifier("obj"); var getObjectRef = () => objectRef = objectRef || scope.generateUidIdentifier("obj");
@ -30,4 +31,5 @@ export function ObjectExpression(node, parent, scope, file) {
scope.push({ id: objectRef }); scope.push({ id: objectRef });
return t.assignmentExpression("=", objectRef, node); return t.assignmentExpression("=", objectRef, node);
} }
} }
};

View File

@ -22,7 +22,8 @@ var iifeVisitor = {
} }
}; };
export function Func/*tion*/(node, parent, scope, file) { export var visitor = {
Function(node, parent, scope, file) {
if (!hasDefaults(node)) return; if (!hasDefaults(node)) return;
// ensure it's a block, useful for arrow functions // ensure it's a block, useful for arrow functions
@ -115,4 +116,5 @@ export function Func/*tion*/(node, parent, scope, file) {
} else { } else {
node.body.body = body.concat(node.body.body); node.body.body = body.concat(node.body.body);
} }
} }
};

View File

@ -58,11 +58,12 @@ function optimizeMemberExpression(parent, offset) {
} }
} }
var hasRest = function (node) { function hasRest(node) {
return t.isRestElement(node.params[node.params.length - 1]); return t.isRestElement(node.params[node.params.length - 1]);
}; }
export function Func/*tion*/(node, parent, scope, file) { export var visitor = {
Function(node, parent, scope) {
if (!hasRest(node)) return; if (!hasRest(node)) return;
var restParam = node.params.pop(); var restParam = node.params.pop();
@ -145,4 +146,5 @@ export function Func/*tion*/(node, parent, scope, file) {
}); });
loop._blockHoist = node.params.length + 1; loop._blockHoist = node.params.length + 1;
node.body.body.unshift(loop); node.body.body.unshift(loop);
} }
};

View File

@ -63,7 +63,8 @@ function spec(node, body, objId, initProps, file) {
} }
} }
export var ObjectExpression = { export var visitor = {
ObjectExpression: {
exit(node, parent, scope, file) { exit(node, parent, scope, file) {
var hasComputed = false; var hasComputed = false;
@ -99,4 +100,5 @@ export var ObjectExpression = {
return body; return body;
} }
}
}; };

View File

@ -1,4 +1,5 @@
export function Property(node) { export var visitor = {
Property(node) {
if (node.method) { if (node.method) {
node.method = false; node.method = false;
} }
@ -6,4 +7,5 @@ export function Property(node) {
if (node.shorthand) { if (node.shorthand) {
node.shorthand = false; node.shorthand = false;
} }
} }
};

View File

@ -1,10 +1,12 @@
import * as regex from "../../helpers/regex"; import * as regex from "../../helpers/regex";
import * as t from "../../../types"; import * as t from "../../../types";
export function Literal(node) { export var visitor = {
Literal(node) {
if (!regex.is(node, "y")) return; if (!regex.is(node, "y")) return;
return t.newExpression(t.identifier("RegExp"), [ return t.newExpression(t.identifier("RegExp"), [
t.literal(node.regex.pattern), t.literal(node.regex.pattern),
t.literal(node.regex.flags) t.literal(node.regex.flags)
]); ]);
} }
};

View File

@ -1,8 +1,10 @@
import rewritePattern from "regexpu/rewrite-pattern"; import rewritePattern from "regexpu/rewrite-pattern";
import * as regex from "../../helpers/regex"; import * as regex from "../../helpers/regex";
export function Literal(node) { export var visitor = {
Literal(node) {
if (!regex.is(node, "u")) return; if (!regex.is(node, "u")) return;
node.regex.pattern = rewritePattern(node.regex.pattern, node.regex.flags); node.regex.pattern = rewritePattern(node.regex.pattern, node.regex.flags);
regex.pullFlag(node, "u"); regex.pullFlag(node, "u");
} }
};

View File

@ -15,7 +15,7 @@ function references(node, scope, state) {
return scope.getBindingIdentifier(node.name) === declared; return scope.getBindingIdentifier(node.name) === declared;
} }
var visitor = { var refVisitor = {
ReferencedIdentifier(node, parent, scope, state) { ReferencedIdentifier(node, parent, scope, state) {
if (t.isFor(parent) && parent.left === node) return; if (t.isFor(parent) && parent.left === node) return;
@ -62,16 +62,16 @@ export var metadata = {
group: "builtin-advanced" group: "builtin-advanced"
}; };
export var BlockStatement = { export var visitor = {
"Program|Loop|BlockStatement": {
exit(node, parent, scope, file) { exit(node, parent, scope, file) {
var letRefs = node._letReferences; var letRefs = node._letReferences;
if (!letRefs) return; if (!letRefs) return;
this.traverse(visitor, { this.traverse(refVisitor, {
letRefs: letRefs, letRefs: letRefs,
file: file file: file
}); });
} }
}
}; };
export { BlockStatement as Program, BlockStatement as Loop };

View File

@ -4,7 +4,8 @@ export var metadata = {
optional: true optional: true
}; };
export function UnaryExpression(node, parent, scope, file) { export var visitor = {
UnaryExpression(node, parent, scope, file) {
if (node._ignoreSpecSymbols) return; if (node._ignoreSpecSymbols) return;
if (node.operator === "typeof") { if (node.operator === "typeof") {
@ -22,16 +23,15 @@ export function UnaryExpression(node, parent, scope, file) {
return call; return call;
} }
} }
} },
export function BinaryExpression(node, parent, scope, file) { BinaryExpression(node, parent, scope, file) {
if (node.operator === "instanceof") { if (node.operator === "instanceof") {
return t.callExpression(file.addHelper("instanceof"), [node.left, node.right]); return t.callExpression(file.addHelper("instanceof"), [node.left, node.right]);
} }
} },
export function VariableDeclaration(node) { "VariableDeclaration|FunctionDeclaration"(node) {
if (node._generated) this.skip(); if (node._generated) this.skip();
} }
};
export { VariableDeclaration as FunctionDeclaration };

View File

@ -5,10 +5,12 @@ export var metadata = {
group: "builtin-pre" group: "builtin-pre"
}; };
export function TemplateLiteral(node, parent, scope, file) { export var visitor = {
TemplateLiteral(node, parent) {
if (t.isTaggedTemplateExpression(parent)) return; if (t.isTaggedTemplateExpression(parent)) return;
for (var i = 0; i < node.expressions.length; i++) { for (var i = 0; i < node.expressions.length; i++) {
node.expressions[i] = t.callExpression(t.identifier("String"), [node.expressions[i]]); node.expressions[i] = t.callExpression(t.identifier("String"), [node.expressions[i]]);
} }
} }
};

View File

@ -43,7 +43,8 @@ function build(props, scope) {
return nodes; return nodes;
} }
export function ArrayExpression(node, parent, scope) { export var visitor = {
ArrayExpression(node, parent, scope) {
var elements = node.elements; var elements = node.elements;
if (!hasSpread(elements)) return; if (!hasSpread(elements)) return;
@ -56,9 +57,9 @@ export function ArrayExpression(node, parent, scope) {
} }
return t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes); return t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes);
} },
export function CallExpression(node, parent, scope) { CallExpression(node, parent, scope) {
var args = node.arguments; var args = node.arguments;
if (!hasSpread(args)) return; if (!hasSpread(args)) return;
@ -96,9 +97,9 @@ export function CallExpression(node, parent, scope) {
} }
node.arguments.unshift(contextLiteral); node.arguments.unshift(contextLiteral);
} },
export function NewExpression(node, parent, scope, file) { NewExpression(node, parent, scope, file) {
var args = node.arguments; var args = node.arguments;
if (!hasSpread(args)) return; if (!hasSpread(args)) return;
@ -115,4 +116,5 @@ export function NewExpression(node, parent, scope, file) {
), ),
[] []
); );
} }
};

View File

@ -9,11 +9,13 @@ export var metadata = {
group: "builtin-trailing" group: "builtin-trailing"
}; };
export function Func/*tion*/(node, parent, scope, file) { export var visitor = {
Function(node, parent, scope, file) {
if (node.generator || node.async) return; if (node.generator || node.async) return;
var tailCall = new TailCallTransformer(this, scope, file); var tailCall = new TailCallTransformer(this, scope, file);
tailCall.run(); tailCall.run();
} }
};
function returnBlock(expr) { function returnBlock(expr) {
return t.blockStatement([t.returnStatement(expr)]); return t.blockStatement([t.returnStatement(expr)]);

View File

@ -6,6 +6,10 @@ export var metadata = {
group: "builtin-pre" group: "builtin-pre"
}; };
function isString(node) {
return t.isLiteral(node) && typeof node.value === "string";
}
function buildBinaryExpression(left, right) { function buildBinaryExpression(left, right) {
var node = t.binaryExpression("+", left, right); var node = t.binaryExpression("+", left, right);
node._templateLiteralProduced = true; node._templateLiteralProduced = true;
@ -21,7 +25,8 @@ function crawl(path) {
} }
} }
export function TaggedTemplateExpression(node, parent, scope, file) { export var visitor = {
TaggedTemplateExpression(node, parent, scope, file) {
var quasi = node.quasi; var quasi = node.quasi;
var args = []; var args = [];
@ -43,13 +48,9 @@ export function TaggedTemplateExpression(node, parent, scope, file) {
args = args.concat(quasi.expressions); args = args.concat(quasi.expressions);
return t.callExpression(node.tag, args); return t.callExpression(node.tag, args);
} },
function isString(node) { TemplateLiteral(node, parent, scope, file) {
return t.isLiteral(node) && typeof node.value === "string";
}
export function TemplateLiteral(node, parent, scope, file) {
var nodes = []; var nodes = [];
for (let elem of (node.quasis: Array)) { for (let elem of (node.quasis: Array)) {
@ -84,4 +85,5 @@ export function TemplateLiteral(node, parent, scope, file) {
} else { } else {
return nodes[0]; return nodes[0];
} }
} }
};

View File

@ -7,11 +7,13 @@ export var metadata = {
stage: 0 stage: 0
}; };
export function ComprehensionExpression(node, parent, scope, file) { export var visitor = {
ComprehensionExpression(node, parent, scope) {
var callback = array; var callback = array;
if (node.generator) callback = generator; if (node.generator) callback = generator;
return callback(node, parent, scope); return callback(node, parent, scope);
} }
};
function generator(node) { function generator(node) {
var body = []; var body = [];

View File

@ -8,7 +8,8 @@ export var metadata = {
stage: 1 stage: 1
}; };
export function ObjectExpression(node, parent, scope, file) { export var visitor = {
ObjectExpression(node, parent, scope, file) {
var hasDecorators = false; var hasDecorators = false;
for (let i = 0; i < node.properties.length; i++) { for (let i = 0; i < node.properties.length; i++) {
let prop = node.properties[i]; let prop = node.properties[i];
@ -39,4 +40,5 @@ export function ObjectExpression(node, parent, scope, file) {
var obj = defineMap.toClassObject(mutatorMap); var obj = defineMap.toClassObject(mutatorMap);
obj = defineMap.toComputedObjectFromClass(obj); obj = defineMap.toComputedObjectFromClass(obj);
return t.callExpression(file.addHelper("create-decorated-object"), [obj]); return t.callExpression(file.addHelper("create-decorated-object"), [obj]);
} }
};

View File

@ -5,11 +5,13 @@ export var metadata = {
stage: 0 stage: 0
}; };
export function DoExpression(node) { export var visitor = {
DoExpression(node) {
var body = node.body.body; var body = node.body.body;
if (body.length) { if (body.length) {
return body; return body;
} else { } else {
return t.identifier("undefined"); return t.identifier("undefined");
} }
} }
};

View File

@ -9,20 +9,10 @@ export var metadata = {
var MATH_POW = t.memberExpression(t.identifier("Math"), t.identifier("pow")); var MATH_POW = t.memberExpression(t.identifier("Math"), t.identifier("pow"));
var { export var visitor = build({
ExpressionStatement,
AssignmentExpression,
BinaryExpression
} = build({
operator: "**", operator: "**",
build(left, right) { build(left, right) {
return t.callExpression(MATH_POW, [left, right]); return t.callExpression(MATH_POW, [left, right]);
} }
}); });
export {
ExpressionStatement,
AssignmentExpression,
BinaryExpression
};

View File

@ -26,7 +26,8 @@ function build(node, nodes, scope) {
build(node, nodes, scope); build(node, nodes, scope);
} }
export function ExportNamedDeclaration(node, parent, scope) { export var visitor = {
ExportNamedDeclaration(node, parent, scope) {
var nodes = []; var nodes = [];
build(node, nodes, scope); build(node, nodes, scope);
if (!nodes.length) return; if (!nodes.length) return;
@ -36,4 +37,5 @@ export function ExportNamedDeclaration(node, parent, scope) {
} }
return nodes; return nodes;
} }
};

View File

@ -36,16 +36,18 @@ function inferBindContext(bind, scope) {
return tempId; return tempId;
} }
export function CallExpression(node, parent, scope, file) { export var visitor = {
CallExpression(node, parent, scope) {
var bind = node.callee; var bind = node.callee;
if (!t.isBindExpression(bind)) return; if (!t.isBindExpression(bind)) return;
var context = inferBindContext(bind, scope); var context = inferBindContext(bind, scope);
node.callee = t.memberExpression(bind.callee, t.identifier("call")); node.callee = t.memberExpression(bind.callee, t.identifier("call"));
node.arguments.unshift(context); node.arguments.unshift(context);
} },
export function BindExpression(node, parent, scope, file) { BindExpression(node, parent, scope) {
var context = inferBindContext(node, scope); var context = inferBindContext(node, scope);
return t.callExpression(t.memberExpression(node.callee, t.identifier("bind")), [context]); return t.callExpression(t.memberExpression(node.callee, t.identifier("bind")), [context]);
} }
};

View File

@ -16,7 +16,8 @@ var hasSpread = function (node) {
return false; return false;
}; };
export function ObjectExpression(node, parent, scope, file) { export var visitor = {
ObjectExpression(node, parent, scope, file) {
if (!hasSpread(node)) return; if (!hasSpread(node)) return;
var args = []; var args = [];
@ -45,4 +46,5 @@ export function ObjectExpression(node, parent, scope, file) {
} }
return t.callExpression(file.addHelper("extends"), args); return t.callExpression(file.addHelper("extends"), args);
} }
};

View File

@ -53,7 +53,7 @@ export default {
"es7.doExpressions": require("./es7/do-expressions"), "es7.doExpressions": require("./es7/do-expressions"),
"es6.spec.symbols": require("./es6/spec.symbols"), "es6.spec.symbols": require("./es6/spec.symbols"),
"es7.functionBind": require("./es7/function-bind"), "es7.functionBind": require("./es7/function-bind"),
"spec.undefinedToVoid": require("./spec/undefined-to-void"), "spec.undefinedToVoid": require("babel-plugin-undefined-to-void"),
//- builtin-advanced //- builtin-advanced
"es6.destructuring": require("./es6/destructuring"), "es6.destructuring": require("./es6/destructuring"),

View File

@ -11,7 +11,8 @@ export var metadata = {
// - 2 Priority over normal nodes // - 2 Priority over normal nodes
// - 3 We want this to be at the **very** top // - 3 We want this to be at the **very** top
export var BlockStatement = { export var visitor = {
Block: {
exit(node) { exit(node) {
var hasChange = false; var hasChange = false;
for (var i = 0; i < node.body.length; i++) { for (var i = 0; i < node.body.length; i++) {
@ -29,6 +30,5 @@ export var BlockStatement = {
return -1 * priority; return -1 * priority;
}); });
} }
}
}; };
export { BlockStatement as Program };

View File

@ -25,9 +25,10 @@ function buildListClone(listKey, bindingKey, refKey) {
}; };
} }
export var Property = buildClone("value", "key", function (node) { export var visitor = {
Property: buildClone("value", "key", function (node) {
return t.isAssignmentPattern(node.value) && node.value.left === node.key; return t.isAssignmentPattern(node.value) && node.value.left === node.key;
}); }),
ExportDeclaration: buildListClone("specifiers", "local", "exported"),
export var ExportDeclaration = buildListClone("specifiers", "local", "exported"); ImportDeclaration: buildListClone("specifiers", "local", "imported")
export var ImportDeclaration = buildListClone("specifiers", "local", "imported"); };

View File

@ -4,7 +4,8 @@ export var metadata = {
group: "builtin-pre" group: "builtin-pre"
}; };
export var BlockStatement = { export var visitor = {
Block: {
exit(node) { exit(node) {
for (var i = 0; i < node.body.length; i++) { for (var i = 0; i < node.body.length; i++) {
var bodyNode = node.body[i]; var bodyNode = node.body[i];
@ -15,6 +16,5 @@ export var BlockStatement = {
} }
} }
} }
}
}; };
export { BlockStatement as Program };

View File

@ -2,7 +2,8 @@ export var metadata = {
group: "builtin-modules" group: "builtin-modules"
}; };
export var Program = { export var visitor = {
Program: {
exit(program, parent, scope, file) { exit(program, parent, scope, file) {
// ensure that these are at the top, just like normal imports // ensure that these are at the top, just like normal imports
for (var node of (file.dynamicImports: Array)) { for (var node of (file.dynamicImports: Array)) {
@ -17,4 +18,5 @@ export var Program = {
file.moduleFormatter.transform(program); file.moduleFormatter.transform(program);
} }
} }
}
}; };

View File

@ -15,11 +15,16 @@ function getDeclar(node) {
return declar; return declar;
} }
function buildExportSpecifier(id) {
return t.exportSpecifier(clone(id), clone(id));
}
export var metadata = { export var metadata = {
group: "builtin-pre" group: "builtin-pre"
}; };
export function ExportDefaultDeclaration(node, parent, scope) { export var visitor = {
ExportDefaultDeclaration(node, parent, scope) {
var declar = node.declaration; var declar = node.declaration;
if (t.isClassDeclaration(declar)) { if (t.isClassDeclaration(declar)) {
@ -45,13 +50,9 @@ export function ExportDefaultDeclaration(node, parent, scope) {
node.declaration = declar.id; node.declaration = declar.id;
return nodes; return nodes;
} }
} },
function buildExportSpecifier(id) { ExportNamedDeclaration(node) {
return t.exportSpecifier(clone(id), clone(id));
}
export function ExportNamedDeclaration(node, parent, scope) {
var declar = node.declaration; var declar = node.declaration;
if (t.isClassDeclaration(declar)) { if (t.isClassDeclaration(declar)) {
@ -78,9 +79,9 @@ export function ExportNamedDeclaration(node, parent, scope) {
} }
return [declar, t.exportNamedDeclaration(null, specifiers)]; return [declar, t.exportNamedDeclaration(null, specifiers)];
} }
} },
export var Program = { Program: {
enter(node) { enter(node) {
var imports = []; var imports = [];
var rest = []; var rest = [];
@ -104,4 +105,5 @@ export var Program = {
file.moduleFormatter.setup(); file.moduleFormatter.setup();
} }
} }
}
}; };

View File

@ -22,12 +22,14 @@ function remap(path, key, create) {
return id; return id;
} }
export function ThisExpression() { export var visitor = {
ThisExpression() {
return remap(this, "this", () => t.thisExpression()); return remap(this, "this", () => t.thisExpression());
} },
export function ReferencedIdentifier(node) { ReferencedIdentifier(node) {
if (node.name === "arguments" && !node._shadowedFunctionLiteral) { if (node.name === "arguments" && !node._shadowedFunctionLiteral) {
return remap(this, "arguments", () => t.identifier("arguments")); return remap(this, "arguments", () => t.identifier("arguments"));
} }
} }
};

View File

@ -5,17 +5,16 @@ export var metadata = {
group: "builtin-pre" group: "builtin-pre"
}; };
export function ForOfStatement(node, parent, scope, file) { export var visitor = {
ForXStatement(node, parent, scope, file) {
var left = node.left; var left = node.left;
if (t.isVariableDeclaration(left)) { if (t.isVariableDeclaration(left)) {
var declar = left.declarations[0]; var declar = left.declarations[0];
if (declar.init) throw file.errorWithNode(declar, messages.get("noAssignmentsInForHead")); if (declar.init) throw file.errorWithNode(declar, messages.get("noAssignmentsInForHead"));
} }
} },
export { ForOfStatement as ForInStatement }; MethodDefinition(node) {
export function MethodDefinition(node) {
if (node.kind !== "constructor") { if (node.kind !== "constructor") {
// get constructor() {} // get constructor() {}
var isConstructor = !node.computed && t.isIdentifier(node.key, { name: "constructor" }); var isConstructor = !node.computed && t.isIdentifier(node.key, { name: "constructor" });
@ -28,10 +27,10 @@ export function MethodDefinition(node) {
} }
} }
Property.apply(this, arguments); visitor.Property.apply(this, arguments);
} },
export function Property(node, parent, scope, file) { Property(node, parent, scope, file) {
if (node.kind === "set") { if (node.kind === "set") {
if (node.value.params.length !== 1) { if (node.value.params.length !== 1) {
throw file.errorWithNode(node.value, messages.get("settersInvalidParamLength")); throw file.errorWithNode(node.value, messages.get("settersInvalidParamLength"));
@ -42,4 +41,5 @@ export function Property(node, parent, scope, file) {
throw file.errorWithNode(first, messages.get("settersNoRest")); throw file.errorWithNode(first, messages.get("settersNoRest"));
} }
} }
} }
};

View File

@ -6,7 +6,8 @@ export var metadata = {
experimental: true experimental: true
}; };
export function AssignmentExpression() { export var visitor = {
AssignmentExpression() {
var left = this.get("left"); var left = this.get("left");
if (!left.isIdentifier()) return; if (!left.isIdentifier()) return;
@ -19,9 +20,9 @@ export function AssignmentExpression() {
} else { } else {
binding.deoptValue(); binding.deoptValue();
} }
} },
export function IfStatement() { IfStatement() {
var evaluated = this.get("test").evaluate(); var evaluated = this.get("test").evaluate();
if (!evaluated.confident) { if (!evaluated.confident) {
// todo: deopt binding values for constant violations inside // todo: deopt binding values for constant violations inside
@ -33,9 +34,9 @@ export function IfStatement() {
} else { } else {
this.skipKey("consequent"); this.skipKey("consequent");
} }
} },
export var Scopable = { Scopable: {
enter() { enter() {
var funcScope = this.scope.getFunctionParent(); var funcScope = this.scope.getFunctionParent();
@ -61,11 +62,12 @@ export var Scopable = {
binding.clearValue(); binding.clearValue();
} }
} }
}; },
export var Expression = { Expression: {
exit() { exit() {
var res = this.evaluate(); var res = this.evaluate();
if (res.confident) return t.valueToNode(res.value); if (res.confident) return t.valueToNode(res.value);
} }
}
}; };

View File

@ -23,7 +23,8 @@ export var metadata = {
experimental: true experimental: true
}; };
export function ReferencedIdentifier(node, parent, scope) { export var visitor = {
ReferencedIdentifier(node, parent, scope) {
var binding = scope.getBinding(node.name); var binding = scope.getBinding(node.name);
if (!binding || binding.references > 1 || !binding.constant) return; if (!binding || binding.references > 1 || !binding.constant) return;
if (binding.kind === "param" || binding.kind === "module") return; if (binding.kind === "param" || binding.kind === "module") return;
@ -52,32 +53,30 @@ export function ReferencedIdentifier(node, parent, scope) {
scope.removeBinding(node.name); scope.removeBinding(node.name);
binding.path.dangerouslyRemove(); binding.path.dangerouslyRemove();
return replacement; return replacement;
} },
export function FunctionDeclaration(node, parent, scope) { "ClassDeclaration|FunctionDeclaration"(node, parent, scope) {
var bindingInfo = scope.getBinding(node.id.name); var binding = scope.getBinding(node.id.name);
if (bindingInfo && !bindingInfo.referenced) { if (binding && !binding.referenced) {
this.dangerouslyRemove(); this.dangerouslyRemove();
} }
} },
export { FunctionDeclaration as ClassDeclaration }; VariableDeclarator(node, parent, scope) {
export function VariableDeclarator(node, parent, scope) {
if (!t.isIdentifier(node.id) || !scope.isPure(node.init, true)) return; if (!t.isIdentifier(node.id) || !scope.isPure(node.init, true)) return;
FunctionDeclaration.apply(this, arguments); visitor["ClassDeclaration|FunctionDeclaration"].apply(this, arguments);
} },
export function ConditionalExpression(node, parent, scope) { ConditionalExpression(node) {
var evaluateTest = this.get("test").evaluateTruthy(); var evaluateTest = this.get("test").evaluateTruthy();
if (evaluateTest === true) { if (evaluateTest === true) {
return node.consequent; return node.consequent;
} else if (evaluateTest === false) { } else if (evaluateTest === false) {
return node.alternate; return node.alternate;
} }
} },
export function BlockStatement(node) { BlockStatement() {
var paths = this.get("body"); var paths = this.get("body");
var purge = false; var purge = false;
@ -94,9 +93,9 @@ export function BlockStatement(node) {
path.dangerouslyRemove(); path.dangerouslyRemove();
} }
} }
} },
export var IfStatement = { IfStatement: {
exit(node) { exit(node) {
var consequent = node.consequent; var consequent = node.consequent;
var alternate = node.alternate; var alternate = node.alternate;
@ -151,4 +150,5 @@ export var IfStatement = {
node.test = t.unaryExpression("!", test, true); node.test = t.unaryExpression("!", test, true);
} }
} }
}
}; };

View File

@ -5,7 +5,8 @@ export var metadata = {
group: "builtin-trailing" group: "builtin-trailing"
}; };
export var MemberExpression = { export var visitor = {
MemberExpression: {
exit(node) { exit(node) {
var prop = node.property; var prop = node.property;
if (node.computed && t.isLiteral(prop) && t.isValidIdentifier(prop.value)) { if (node.computed && t.isLiteral(prop) && t.isValidIdentifier(prop.value)) {
@ -14,4 +15,5 @@ export var MemberExpression = {
node.computed = false; node.computed = false;
} }
} }
}
}; };

View File

@ -5,7 +5,8 @@ export var metadata = {
group: "builtin-trailing" group: "builtin-trailing"
}; };
export var Property = { export var visitor = {
Property: {
exit(node) { exit(node) {
var key = node.key; var key = node.key;
if (t.isLiteral(key) && t.isValidIdentifier(key.value)) { if (t.isLiteral(key) && t.isValidIdentifier(key.value)) {
@ -14,4 +15,5 @@ export var Property = {
node.computed = false; node.computed = false;
} }
} }
}
}; };

View File

@ -3,8 +3,10 @@ export var metadata = {
group: "builtin-pre" group: "builtin-pre"
}; };
export function CallExpression(node, parent) { export var visitor = {
CallExpression() {
if (this.get("callee").matchesPattern("console", true)) { if (this.get("callee").matchesPattern("console", true)) {
this.dangerouslyRemove(); this.dangerouslyRemove();
} }
} }
};

View File

@ -3,6 +3,8 @@ export var metadata = {
group: "builtin-pre" group: "builtin-pre"
}; };
export function DebuggerStatement(node) { export var visitor = {
DebuggerStatement() {
this.dangerouslyRemove(); this.dangerouslyRemove();
} }
};

View File

@ -4,8 +4,10 @@ export var metadata = {
optional: true optional: true
}; };
export function ForOfStatement(node, parent, scope, file) { export var visitor = {
ForOfStatement(node, parent, scope, file) {
if (this.get("right").isGenericType("Array")) { if (this.get("right").isGenericType("Array")) {
return _ForOfStatementArray.call(this, node, scope, file); return _ForOfStatementArray.call(this, node, scope, file);
} }
} }
};

View File

@ -26,7 +26,8 @@ var immutabilityVisitor = {
} }
}; };
export function JSXElement(node, parent, scope, file) { export var visitor = {
JSXElement(node) {
if (node._hoisted) return; if (node._hoisted) return;
var state = { isImmutable: true }; var state = { isImmutable: true };
@ -37,4 +38,5 @@ export function JSXElement(node, parent, scope, file) {
} else { } else {
node._hoisted = true; node._hoisted = true;
} }
} }
};

View File

@ -18,7 +18,8 @@ function isJSXAttributeOfName(attr, name) {
return t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name, { name: name }); return t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name, { name: name });
} }
export function JSXElement(node, parent, scope, file) { export var visitor = {
JSXElement(node, parent, scope, file) {
// filter // filter
var open = node.openingElement; var open = node.openingElement;
if (hasRefOrSpread(open.attributes)) return; if (hasRefOrSpread(open.attributes)) return;
@ -71,4 +72,5 @@ export function JSXElement(node, parent, scope, file) {
pushElemProp("key", key); pushElemProp("key", key);
return obj; return obj;
} }
};

View File

@ -7,8 +7,10 @@ export var metadata = {
dependencies: ["es7.asyncFunctions", "es6.classes"] dependencies: ["es7.asyncFunctions", "es6.classes"]
}; };
export function Func/*tion*/(node, parent, scope, file) { export var visitor = {
Function(node, parent, scope, file) {
if (!node.async || node.generator) return; if (!node.async || node.generator) return;
return remapAsyncToGenerator(this, file.addHelper("async-to-generator")); return remapAsyncToGenerator(this, file.addHelper("async-to-generator"));
} }
};

View File

@ -10,11 +10,13 @@ export var metadata = {
dependencies: ["es7.asyncFunctions", "es6.classes"] dependencies: ["es7.asyncFunctions", "es6.classes"]
}; };
export function Func/*tion*/(node, parent, scope, file) { export var visitor = {
Function(node, parent, scope, file) {
if (!node.async || node.generator) return; if (!node.async || node.generator) return;
return remapAsyncToGenerator( return remapAsyncToGenerator(
this, this,
t.memberExpression(file.addImport("bluebird", null, "absolute"), t.identifier("coroutine")) t.memberExpression(file.addImport("bluebird", null, "absolute"), t.identifier("coroutine"))
); );
} }
};

View File

@ -6,7 +6,8 @@ export var metadata = {
optional: true optional: true
}; };
export function CallExpression(node) { export var visitor = {
CallExpression(node) {
if (this.get("callee").isIdentifier({ name: "eval" }) && node.arguments.length === 1) { if (this.get("callee").isIdentifier({ name: "eval" }) && node.arguments.length === 1) {
var evaluate = this.get("arguments")[0].evaluate(); var evaluate = this.get("arguments")[0].evaluate();
if (!evaluate.confident) return; if (!evaluate.confident) return;
@ -18,4 +19,5 @@ export function CallExpression(node) {
traverse.removeProperties(ast); traverse.removeProperties(ast);
return ast.program; return ast.program;
} }
} }
};

View File

@ -4,37 +4,39 @@ export var metadata = {
group: "builtin-trailing" group: "builtin-trailing"
}; };
export function Flow(node) { export var visitor = {
Flow() {
this.dangerouslyRemove(); this.dangerouslyRemove();
} },
export function ClassProperty(node) { ClassProperty(node) {
node.typeAnnotation = null; node.typeAnnotation = null;
if (!node.value) this.dangerouslyRemove(); if (!node.value) this.dangerouslyRemove();
} },
export function Class(node) { Class(node) {
node.implements = null; node.implements = null;
} },
export function Func/*tion*/(node) { Function(node) {
for (var i = 0; i < node.params.length; i++) { for (var i = 0; i < node.params.length; i++) {
var param = node.params[i]; var param = node.params[i];
param.optional = false; param.optional = false;
} }
} },
export function TypeCastExpression(node) { TypeCastExpression(node) {
do { do {
node = node.expression; node = node.expression;
} while(t.isTypeCastExpression(node)); } while(t.isTypeCastExpression(node));
return node; return node;
} },
export function ImportDeclaration(node) { ImportDeclaration(node) {
if (node.isType) this.dangerouslyRemove(); if (node.isType) this.dangerouslyRemove();
} },
export function ExportDeclaration(node) { ExportDeclaration() {
if (this.get("declaration").isTypeAlias()) this.dangerouslyRemove(); if (this.get("declaration").isTypeAlias()) this.dangerouslyRemove();
} }
};

View File

@ -5,7 +5,8 @@ export var metadata = {
optional: true optional: true
}; };
export var FunctionExpression = { export var visitor = {
FunctionExpression: {
exit(node) { exit(node) {
if (!node.id) return; if (!node.id) return;
node._ignoreUserWhitespace = true; node._ignoreUserWhitespace = true;
@ -18,4 +19,5 @@ export var FunctionExpression = {
[] []
); );
} }
}
}; };

View File

@ -10,7 +10,7 @@ export var metadata = {
group: "builtin-advanced" group: "builtin-advanced"
}; };
require("../../helpers/build-react-transformer")(exports, { export var visitor = require("../../helpers/build-react-transformer")({
pre(state) { pre(state) {
state.callee = state.tagExpr; state.callee = state.tagExpr;
}, },

View File

@ -7,7 +7,24 @@ export var metadata = {
group: "builtin-advanced" group: "builtin-advanced"
}; };
export function Program(node, parent, scope, file) { export var visitor = require("../../helpers/build-react-transformer")({
pre(state) {
var tagName = state.tagName;
var args = state.args;
if (react.isCompatTag(tagName)) {
args.push(t.literal(tagName));
} else {
args.push(state.tagExpr);
}
},
post(state, file) {
state.callee = file.get("jsxIdentifier");
}
});
visitor.Program = function (node, parent, scope, file) {
var id = file.opts.jsxPragma; var id = file.opts.jsxPragma;
for (var i = 0; i < file.ast.comments.length; i++) { for (var i = 0; i < file.ast.comments.length; i++) {
@ -26,20 +43,4 @@ export function Program(node, parent, scope, file) {
file.set("jsxIdentifier", id.split(".").map(t.identifier).reduce(function (object, property) { file.set("jsxIdentifier", id.split(".").map(t.identifier).reduce(function (object, property) {
return t.memberExpression(object, property); return t.memberExpression(object, property);
})); }));
} };
require("../../helpers/build-react-transformer")(exports, {
pre(state) {
var tagName = state.tagName;
var args = state.args;
if (react.isCompatTag(tagName)) {
args.push(t.literal(tagName));
} else {
args.push(state.tagExpr);
}
},
post(state, file) {
state.callee = file.get("jsxIdentifier");
}
});

View File

@ -6,7 +6,8 @@ export var metadata = {
group: "builtin-advanced" group: "builtin-advanced"
}; };
export var Func/*tion*/ = { export var visitor = {
Function: {
exit(node) { exit(node) {
if (node.async || node.generator) { if (node.async || node.generator) {
// Although this code transforms only the subtree rooted at the given // Although this code transforms only the subtree rooted at the given
@ -19,6 +20,7 @@ export var Func/*tion*/ = {
regenerator.transform(convertNodePath(this)); regenerator.transform(convertNodePath(this));
} }
} }
}
}; };
// Given a Babel NodePath, return an ast-types NodePath that includes full // Given a Babel NodePath, return an ast-types NodePath that includes full

View File

@ -19,7 +19,8 @@ export function pre(file) {
}); });
} }
export function ReferencedIdentifier(node, parent, scope, file) { export var visitor = {
ReferencedIdentifier(node, parent, scope, file) {
if (node.name === "regeneratorRuntime") { if (node.name === "regeneratorRuntime") {
return file.get("regeneratorIdentifier"); return file.get("regeneratorIdentifier");
} }
@ -31,9 +32,9 @@ export function ReferencedIdentifier(node, parent, scope, file) {
// Symbol() -> _core.Symbol(); new Promise -> new _core.Promise // Symbol() -> _core.Symbol(); new Promise -> new _core.Promise
var modulePath = definitions.builtins[node.name]; var modulePath = definitions.builtins[node.name];
return file.addImport(`${RUNTIME_MODULE_NAME}/core-js/${modulePath}`, node.name, "absoluteDefault"); return file.addImport(`${RUNTIME_MODULE_NAME}/core-js/${modulePath}`, node.name, "absoluteDefault");
} },
export function CallExpression(node, parent, scope, file) { CallExpression(node, parent, scope, file) {
// arr[Symbol.iterator]() -> _core.$for.getIterator(arr) // arr[Symbol.iterator]() -> _core.$for.getIterator(arr)
if (node.arguments.length) return; if (node.arguments.length) return;
@ -44,9 +45,9 @@ export function CallExpression(node, parent, scope, file) {
if (!this.get("callee.property").matchesPattern("Symbol.iterator")) return; if (!this.get("callee.property").matchesPattern("Symbol.iterator")) return;
return t.callExpression(file.addImport(`${RUNTIME_MODULE_NAME}/core-js/get-iterator`, "getIterator", "absoluteDefault"), [callee.object]); return t.callExpression(file.addImport(`${RUNTIME_MODULE_NAME}/core-js/get-iterator`, "getIterator", "absoluteDefault"), [callee.object]);
} },
export function BinaryExpression(node, parent, scope, file) { BinaryExpression(node, parent, scope, file) {
// Symbol.iterator in arr -> core.$for.isIterable(arr) // Symbol.iterator in arr -> core.$for.isIterable(arr)
if (node.operator !== "in") return; if (node.operator !== "in") return;
@ -56,9 +57,9 @@ export function BinaryExpression(node, parent, scope, file) {
file.addImport(`${RUNTIME_MODULE_NAME}/core-js/is-iterable`, "isIterable", "absoluteDefault"), file.addImport(`${RUNTIME_MODULE_NAME}/core-js/is-iterable`, "isIterable", "absoluteDefault"),
[node.right] [node.right]
); );
} },
export var MemberExpression = { MemberExpression: {
enter(node, parent, scope, file) { enter(node, parent, scope, file) {
// Array.from -> _core.Array.from // Array.from -> _core.Array.from
@ -97,4 +98,5 @@ export var MemberExpression = {
prop prop
); );
} }
}
}; };

View File

@ -6,7 +6,8 @@ export var metadata = {
const THIS_BREAK_KEYS = ["FunctionExpression", "FunctionDeclaration", "ClassExpression", "ClassDeclaration"]; const THIS_BREAK_KEYS = ["FunctionExpression", "FunctionDeclaration", "ClassExpression", "ClassDeclaration"];
export var Program = { export var visitor = {
Program: {
enter(program) { enter(program) {
var first = program.body[0]; var first = program.body[0];
@ -23,10 +24,11 @@ export var Program = {
} }
directive._blockHoist = Infinity; directive._blockHoist = Infinity;
} }
}; },
export function ThisExpression() { ThisExpression() {
if (!this.findParent((path) => !path.is("shadow") && THIS_BREAK_KEYS.indexOf(path.type) >= 0)) { if (!this.findParent((path) => !path.is("shadow") && THIS_BREAK_KEYS.indexOf(path.type) >= 0)) {
return t.identifier("undefined"); return t.identifier("undefined");
} }
} }
};

View File

@ -23,14 +23,16 @@ function statementList(key, path) {
} }
} }
export function BlockStatement(node, parent) { export var visitor = {
BlockStatement(node, parent) {
if ((t.isFunction(parent) && parent.body === node) || t.isExportDeclaration(parent)) { if ((t.isFunction(parent) && parent.body === node) || t.isExportDeclaration(parent)) {
return; return;
} }
statementList("body", this); statementList("body", this);
} },
export function SwitchCase() { SwitchCase() {
statementList("consequent", this); statementList("consequent", this);
} }
};

View File

@ -4,8 +4,8 @@ export var metadata = {
group: "builtin-pre" group: "builtin-pre"
}; };
export var FunctionExpression = { export var visitor = {
"ArrowFunctionExpression|FunctionExpression": {
exit: bare exit: bare
}
}; };
export { FunctionExpression as ArrowFunctionExpression };

View File

@ -19,7 +19,8 @@ export var metadata = {
optional: true optional: true
}; };
export function AssignmentExpression(node, parent, scope, file) { export var visitor = {
AssignmentExpression(node, parent, scope, file) {
if (!isProtoAssignmentExpression(node)) return; if (!isProtoAssignmentExpression(node)) return;
var nodes = []; var nodes = [];
@ -31,18 +32,18 @@ export function AssignmentExpression(node, parent, scope, file) {
if (temp) nodes.push(temp); if (temp) nodes.push(temp);
return nodes; return nodes;
} },
export function ExpressionStatement(node, parent, scope, file) { ExpressionStatement(node, parent, scope, file) {
var expr = node.expression; var expr = node.expression;
if (!t.isAssignmentExpression(expr, { operator: "=" })) return; if (!t.isAssignmentExpression(expr, { operator: "=" })) return;
if (isProtoAssignmentExpression(expr)) { if (isProtoAssignmentExpression(expr)) {
return buildDefaultsCallExpression(expr, expr.left.object, file); return buildDefaultsCallExpression(expr, expr.left.object, file);
} }
} },
export function ObjectExpression(node, parent, scope, file) { ObjectExpression(node, parent, scope, file) {
var proto; var proto;
for (var i = 0; i < node.properties.length; i++) { for (var i = 0; i < node.properties.length; i++) {
@ -59,4 +60,5 @@ export function ObjectExpression(node, parent, scope, file) {
if (node.properties.length) args.push(node); if (node.properties.length) args.push(node);
return t.callExpression(file.addHelper("extends"), args); return t.callExpression(file.addHelper("extends"), args);
} }
} }
};

View File

@ -1,12 +0,0 @@
import * as t from "../../../types";
export var metadata = {
optional: true,
react: true
};
export function Identifier(node, parent) {
if (node.name === "undefined" && this.isReferenced()) {
return t.unaryExpression("void", t.literal(0), true);
}
}

View File

@ -7,11 +7,13 @@ export var metadata = {
var match = t.buildMatchMemberExpression("process.env"); var match = t.buildMatchMemberExpression("process.env");
export function MemberExpression(node) { export var visitor = {
MemberExpression(node) {
if (match(node.object)) { if (match(node.object)) {
var key = this.toComputedKey(); var key = this.toComputedKey();
if (t.isLiteral(key)) { if (t.isLiteral(key)) {
return t.valueToNode(process.env[key.value]); return t.valueToNode(process.env[key.value]);
} }
} }
} }
};

View File

@ -13,12 +13,14 @@ function check(source, file) {
} }
} }
export function CallExpression(node, parent, scope, file) { export var visitor = {
CallExpression(node, parent, scope, file) {
if (this.get("callee").isIdentifier({ name: "require" }) && node.arguments.length === 1) { if (this.get("callee").isIdentifier({ name: "require" }) && node.arguments.length === 1) {
check(node.arguments[0], file); check(node.arguments[0], file);
} }
} },
export function ModuleDeclaration(node, parent, scope, file) { ModuleDeclaration(node, parent, scope, file) {
check(node.source, file); check(node.source, file);
} }
};

View File

@ -5,7 +5,8 @@ export var metadata = {
optional: true optional: true
}; };
export function ReferencedIdentifier(node, parent, scope, file) { export var visitor = {
ReferencedIdentifier(node, parent, scope) {
var binding = scope.getBinding(node.name); var binding = scope.getBinding(node.name);
if (binding && binding.kind === "type" && !this.parentPath.isFlow()) { if (binding && binding.kind === "type" && !this.parentPath.isFlow()) {
throw this.errorWithNode(messages.get("undeclaredVariableType", node.name), ReferenceError); throw this.errorWithNode(messages.get("undeclaredVariableType", node.name), ReferenceError);
@ -40,4 +41,5 @@ export function ReferencedIdentifier(node, parent, scope, file) {
// //
throw this.errorWithNode(msg, ReferenceError); throw this.errorWithNode(msg, ReferenceError);
} }
};

View File

@ -15,7 +15,6 @@ export default function traverse(parent, opts, scope, state, parentPath) {
if (!opts) opts = {}; if (!opts) opts = {};
visitors.verify(opts);
visitors.explode(opts); visitors.explode(opts);
// array of nodes // array of nodes

View File

@ -8,17 +8,17 @@ var referenceVisitor = {
} }
// direct references that we need to track to hoist this to the highest scope we can // direct references that we need to track to hoist this to the highest scope we can
var bindingInfo = scope.getBinding(node.name); var binding = scope.getBinding(node.name);
if (!bindingInfo) return; if (!binding) return;
// this binding isn't accessible from the parent scope so we can safely ignore it // this binding isn't accessible from the parent scope so we can safely ignore it
// eg. it's in a closure etc // eg. it's in a closure etc
if (bindingInfo !== state.scope.getBinding(node.name)) return; if (binding !== state.scope.getBinding(node.name)) return;
if (bindingInfo.constant) { if (binding.constant) {
state.bindings[node.name] = bindingInfo; state.bindings[node.name] = binding;
} else { } else {
for (var violationPath of (bindingInfo.constantViolations: Array)) { for (var violationPath of (binding.constantViolations: Array)) {
state.breakOnScopePaths.push(violationPath.scope.path); state.breakOnScopePaths.push(violationPath.scope.path);
} }
} }

View File

@ -31,9 +31,9 @@ var collectorVisitor = {
}, },
ReferencedIdentifier(node) { ReferencedIdentifier(node) {
var bindingInfo = this.scope.getBinding(node.name); var binding = this.scope.getBinding(node.name);
if (bindingInfo) { if (binding) {
bindingInfo.reference(); binding.reference(this);
} else { } else {
this.scope.getProgramParent().addGlobal(node); this.scope.getProgramParent().addGlobal(node);
} }

View File

@ -8,6 +8,24 @@ export function explode(visitor) {
if (visitor._exploded) return visitor; if (visitor._exploded) return visitor;
visitor._exploded = true; visitor._exploded = true;
// normalise pipes
for (let nodeType in visitor) {
if (shouldIgnoreKey(nodeType)) continue;
let parts = nodeType.split("|");
if (parts.length === 1) continue;
let fns = visitor[nodeType];
delete visitor[nodeType];
for (let part of (parts: Array)) {
visitor[part] = fns;
}
}
// verify data structure
verify(visitor);
// make sure there's no __esModule type since this is because we're using loose mode // make sure there's no __esModule type since this is because we're using loose mode
// and it sets __esModule to be enumerable on all modules :( // and it sets __esModule to be enumerable on all modules :(
delete visitor.__esModule; delete visitor.__esModule;
@ -21,6 +39,7 @@ export function explode(visitor) {
// ensure visitors are objects // ensure visitors are objects
ensureEntranceObjects(visitor); ensureEntranceObjects(visitor);
// ensure enter/exit callbacks are arrays
ensureCallbackArrays(visitor); ensureCallbackArrays(visitor);
// add type wrappers // add type wrappers

View File

@ -312,7 +312,6 @@ export function inherits(child: Object, parent: Object): Object {
toFastProperties(t); toFastProperties(t);
toFastProperties(t.VISITOR_KEYS); toFastProperties(t.VISITOR_KEYS);
exports.__esModule = true;
assign(t, require("./retrievers")); assign(t, require("./retrievers"));
assign(t, require("./validators")); assign(t, require("./validators"));
assign(t, require("./converters")); assign(t, require("./converters"));

View File

@ -1,5 +1,5 @@
var Transformer = require("../../lib/babel/transformation/transformer");
var transform = require("../../lib/babel/transformation"); var transform = require("../../lib/babel/transformation");
var Plugin = require("../../lib/babel/transformation/plugin");
var babel = require("../../lib/babel/api/node"); var babel = require("../../lib/babel/api/node");
var chai = require("chai"); var chai = require("chai");
@ -9,7 +9,7 @@ suite("traversal path", function () {
var actualCode = transform(expectCode, { var actualCode = transform(expectCode, {
blacklist: "strict", blacklist: "strict",
plugins: [new Transformer("foobar", { plugins: [new Plugin("foobar", {
FunctionDeclaration: function () { FunctionDeclaration: function () {
return "console.whatever()"; return "console.whatever()";
} }