diff --git a/packages/babel-core/src/transformation/file/index.js b/packages/babel-core/src/transformation/file/index.js index 01d5b7efc9d3..9c1867294f85 100644 --- a/packages/babel-core/src/transformation/file/index.js +++ b/packages/babel-core/src/transformation/file/index.js @@ -7,7 +7,8 @@ import convertSourceMap from "convert-source-map"; import OptionManager from "./options/option-manager"; import type Pipeline from "../pipeline"; import PluginPass from "../plugin-pass"; -import { NodePath, Hub, Scope } from "babel-traverse"; +import { NodePath, Scope } from "babel-traverse"; +import type { HubInterface } from "babel-traverse"; import sourceMap from "source-map"; import generate from "babel-generator"; import codeFrame from "babel-code-frame"; @@ -99,7 +100,21 @@ export default class File extends Store { this.code = ""; this.shebang = ""; - this.hub = new Hub(this); + this.hub = { + // keep it for the usage in babel-core, ex: path.hub.file.opts.filename + file: this, + mark: (type: string, message: string, loc: Object) => { + this.metadata.marked.push({ + type, + message, + loc + }); + }, + addHelper: this.addHelper.bind(this), + getCode: () => this.code, + getScope: () => this.scope, + buildError: this.buildCodeFrameError.bind(this) + }; } static helpers: Array; @@ -119,7 +134,7 @@ export default class File extends Store { ast: Object; scope: Scope; metadata: BabelFileMetadata; - hub: Hub; + hub: HubInterface; code: string; shebang: string; diff --git a/packages/babel-plugin-transform-react-jsx-source/src/index.js b/packages/babel-plugin-transform-react-jsx-source/src/index.js index cd296af979a0..c2a1ab909a4a 100644 --- a/packages/babel-plugin-transform-react-jsx-source/src/index.js +++ b/packages/babel-plugin-transform-react-jsx-source/src/index.js @@ -50,7 +50,10 @@ export default function ({ types: t }) { : null; const fileNameIdentifier = path.scope.generateUidIdentifier(FILE_NAME_VAR); - path.hub.file.scope.push({id: fileNameIdentifier, init: t.stringLiteral(fileName)}); + const scope = path.hub.getScope(); + if (scope) { + scope.push({id: fileNameIdentifier, init: t.stringLiteral(fileName)}); + } state.fileNameIdentifier = fileNameIdentifier; } diff --git a/packages/babel-traverse/src/hub.js b/packages/babel-traverse/src/hub.js index f05eaa813680..d4151a16ed59 100644 --- a/packages/babel-traverse/src/hub.js +++ b/packages/babel-traverse/src/hub.js @@ -1,6 +1,14 @@ +import Scope from "./scope"; +export interface HubInterface { + mark?: (type: string, message: string) => void; + addHelper?: (name: string) => Object; + getScope?: () => Scope; + getCode?: () => string; + buildError:(node: Object, msg: string, Error: Error) => Error; +} + export default class Hub { - constructor(file, options) { - this.file = file; - this.options = options; + buildError(node, msg, BuildError = TypeError): Error { + return new BuildError(msg); } } diff --git a/packages/babel-traverse/src/index.js b/packages/babel-traverse/src/index.js index 6a3d4660a4b7..a3f508f819f1 100644 --- a/packages/babel-traverse/src/index.js +++ b/packages/babel-traverse/src/index.js @@ -7,10 +7,12 @@ import includes from "lodash/includes"; import * as t from "babel-types"; import * as cache from "./cache"; -export { default as NodePath } from "./path"; -export { default as Scope } from "./scope"; -export { default as Hub } from "./hub"; -export { visitors }; +import NodePath from "./path"; +import Scope from "./scope"; +import Hub from "./hub"; + +export { visitors, NodePath, Scope, Hub }; +export type { HubInterface } from "./hub"; export default function traverse( parent: Object | Array, @@ -37,9 +39,9 @@ traverse.visitors = visitors; traverse.verify = visitors.verify; traverse.explode = visitors.explode; -traverse.NodePath = require("./path"); -traverse.Scope = require("./scope"); -traverse.Hub = require("./hub"); +traverse.NodePath = NodePath; +traverse.Scope = Scope; +traverse.Hub = Hub; traverse.cheap = function (node, enter) { return t.traverseFast(node, enter); diff --git a/packages/babel-traverse/src/path/index.js b/packages/babel-traverse/src/path/index.js index 1b5b58919018..a8ec5a6013e0 100644 --- a/packages/babel-traverse/src/path/index.js +++ b/packages/babel-traverse/src/path/index.js @@ -116,7 +116,7 @@ export default class NodePath { } buildCodeFrameError(msg: string, Error: typeof Error = SyntaxError): Error { - return this.hub.file.buildCodeFrameError(this.node, msg, Error); + return this.hub.buildError(this.node, msg, Error); } traverse(visitor: Object, state?: any) { @@ -124,11 +124,9 @@ export default class NodePath { } mark(type: string, message: string) { - this.hub.file.metadata.marked.push({ - type, - message, - loc: this.node.loc - }); + if (this.hub.mark) { + this.hub.mark(type, message, this.node.loc); + } } set(key: string, node: Object) { diff --git a/packages/babel-traverse/src/path/introspection.js b/packages/babel-traverse/src/path/introspection.js index be7a2755c537..93d7b36c6419 100644 --- a/packages/babel-traverse/src/path/introspection.js +++ b/packages/babel-traverse/src/path/introspection.js @@ -235,10 +235,12 @@ export function referencesImport(moduleSource, importName) { export function getSource() { let node = this.node; if (node.end) { - return this.hub.file.code.slice(node.start, node.end); - } else { - return ""; + const code = this.hub.getCode(); + if (code) { + return code.slice(node.start, node.end); + } } + return ""; } export function willIMaybeExecuteBefore(target) { diff --git a/packages/babel-traverse/src/scope/index.js b/packages/babel-traverse/src/scope/index.js index 83e80df926a8..3757a116cc42 100644 --- a/packages/babel-traverse/src/scope/index.js +++ b/packages/babel-traverse/src/scope/index.js @@ -350,7 +350,8 @@ export default class Scope { if (!duplicate) duplicate = local.kind === "param" && (kind === "let" || kind === "const"); if (duplicate) { - throw this.hub.file.buildCodeFrameError(id, messages.get("scopeDuplicateDeclaration", name), TypeError); + const errorMsg = messages.get("scopeDuplicateDeclaration", name); + throw this.hub.buildError ? this.hub.buildError(id, errorMsg, TypeError) : new TypeError(errorMsg); } } @@ -389,7 +390,6 @@ export default class Scope { } toArray(node: Object, i?: number) { - let file = this.hub.file; if (t.isIdentifier(node)) { let binding = this.getBinding(node.name); @@ -423,9 +423,9 @@ export default class Scope { } else if (i) { args.push(t.numericLiteral(i)); helperName = "slicedToArray"; - // TODO if (this.hub.file.isLoose("es6.forOf")) helperName += "-loose"; + // TODO if (this.hub.isLoose("es6.forOf")) helperName += "-loose"; } - return t.callExpression(file.addHelper(helperName), args); + return t.callExpression(this.hub.addHelper(helperName), args); } hasLabel(name: string) { diff --git a/packages/babel-traverse/test/hub.js b/packages/babel-traverse/test/hub.js new file mode 100644 index 000000000000..a3d67bb9d88c --- /dev/null +++ b/packages/babel-traverse/test/hub.js @@ -0,0 +1,13 @@ +const assert = require("assert"); +const Hub = require("../lib").default.Hub; + +describe("hub", function () { + it("default buildError should return TypeError", function () { + const hub = new Hub(); + const msg = "test_msg"; + assert.deepEqual( + hub.buildError(null, msg), + new TypeError(msg) + ); + }); +});