add support for replacing nodes with expression source strings
This commit is contained in:
parent
f24b5164d4
commit
0fc02f2cf0
@ -14,6 +14,7 @@ export { default as TransformerPipeline } from "../transformation/transformer-pi
|
||||
export { default as traverse } from "../traversal";
|
||||
export { default as buildExternalHelpers } from "../tools/build-external-helpers";
|
||||
export { version } from "../../../package";
|
||||
export { all as parse } from "../helpers/parse";
|
||||
|
||||
import * as t from "../types";
|
||||
export { t as types };
|
||||
@ -55,19 +56,3 @@ export function transformFileSync(filename: string, opts?: Object = {}) {
|
||||
opts.filename = filename;
|
||||
return transform(fs.readFileSync(filename), opts);
|
||||
}
|
||||
|
||||
export function parse(code, opts = {}) {
|
||||
opts.sourceType = "module";
|
||||
opts.ecmaVersion = Infinity;
|
||||
opts.plugins = {
|
||||
flow: true,
|
||||
jsx: true
|
||||
};
|
||||
opts.features = {};
|
||||
|
||||
for (var key in transform.pipeline.transformers) {
|
||||
opts.features[key] = true;
|
||||
}
|
||||
|
||||
return acorn.parse(code, opts);
|
||||
}
|
||||
|
||||
@ -3,63 +3,86 @@ import estraverse from "estraverse";
|
||||
import codeFrame from "./code-frame";
|
||||
import * as acorn from "../../acorn";
|
||||
|
||||
export default function (opts, code, callback) {
|
||||
function parseCatch(code, opts) {
|
||||
var comments = opts.onComment = [];
|
||||
var tokens = opts.onToken = [];
|
||||
|
||||
try {
|
||||
var comments = [];
|
||||
var tokens = [];
|
||||
|
||||
var parseOpts = {
|
||||
allowImportExportEverywhere: opts.looseModules,
|
||||
allowReturnOutsideFunction: opts.looseModules,
|
||||
ecmaVersion: 6,
|
||||
strictMode: opts.strictMode,
|
||||
sourceType: opts.sourceType,
|
||||
onComment: comments,
|
||||
locations: true,
|
||||
features: opts.features || {},
|
||||
plugins: opts.plugins || {},
|
||||
onToken: tokens,
|
||||
ranges: true
|
||||
};
|
||||
|
||||
if (opts.nonStandard) {
|
||||
parseOpts.plugins.jsx = true;
|
||||
parseOpts.plugins.flow = true;
|
||||
}
|
||||
|
||||
var ast = acorn.parse(code, parseOpts);
|
||||
|
||||
estraverse.attachComments(ast, comments, tokens);
|
||||
|
||||
ast = normalizeAst(ast, comments, tokens);
|
||||
|
||||
if (callback) {
|
||||
return callback(ast);
|
||||
} else {
|
||||
return ast;
|
||||
}
|
||||
return acorn.parse(code, opts);
|
||||
} catch (err) {
|
||||
if (!err._babel) {
|
||||
if (err._babel) {
|
||||
throw err;
|
||||
} else {
|
||||
err._babel = true;
|
||||
}
|
||||
|
||||
var message = err.message = `${opts.filename}: ${err.message}`;
|
||||
if (opts.errorMessage) {
|
||||
err.message += ` - ${opts.errorMessage}`;
|
||||
}
|
||||
|
||||
var loc = err.loc;
|
||||
if (loc) {
|
||||
err.codeFrame = codeFrame(code, loc.line, loc.column + 1, opts);
|
||||
message += "\n" + err.codeFrame;
|
||||
}
|
||||
var message = err.message = `${opts.filename || "unknown"}: ${err.message}`;
|
||||
|
||||
if (err.stack) {
|
||||
var newStack = err.stack.replace(err.message, message);
|
||||
try {
|
||||
err.stack = newStack;
|
||||
} catch (e) {
|
||||
// `err.stack` may be a readonly property in some environments
|
||||
}
|
||||
var loc = err.loc;
|
||||
if (loc) {
|
||||
err.codeFrame = codeFrame(code, loc.line, loc.column + 1, opts);
|
||||
message += "\n" + err.codeFrame;
|
||||
}
|
||||
|
||||
if (err.stack) {
|
||||
var newStack = err.stack.replace(err.message, message);
|
||||
try {
|
||||
err.stack = newStack;
|
||||
} catch (e) {
|
||||
// `err.stack` may be a readonly property in some environments
|
||||
}
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default function (opts, code, callback) {
|
||||
var parseOpts = {
|
||||
allowImportExportEverywhere: opts.looseModules,
|
||||
allowReturnOutsideFunction: opts.looseModules,
|
||||
ecmaVersion: 6,
|
||||
strictMode: opts.strictMode,
|
||||
sourceType: opts.sourceType,
|
||||
locations: true,
|
||||
features: opts.features || {},
|
||||
plugins: opts.plugins || {},
|
||||
ranges: true
|
||||
};
|
||||
|
||||
if (opts.nonStandard) {
|
||||
parseOpts.plugins.jsx = true;
|
||||
parseOpts.plugins.flow = true;
|
||||
}
|
||||
|
||||
var ast = parseCatch(code, parseOpts);
|
||||
|
||||
estraverse.attachComments(ast, parseOpts.onComment, parseOpts.onToken);
|
||||
ast = normalizeAst(ast, parseOpts.onComment, parseOpts.onToken);
|
||||
|
||||
if (callback) {
|
||||
return callback(ast);
|
||||
} else {
|
||||
return ast;
|
||||
}
|
||||
}
|
||||
|
||||
export function all(code, opts = {}) {
|
||||
opts.sourceType = "module";
|
||||
opts.ecmaVersion = Infinity;
|
||||
opts.plugins = {
|
||||
flow: true,
|
||||
jsx: true
|
||||
};
|
||||
opts.features = {};
|
||||
|
||||
for (var key in transform.pipeline.transformers) {
|
||||
opts.features[key] = true;
|
||||
}
|
||||
|
||||
return parseCatch(code, opts);
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ import isBoolean from "lodash/lang/isBoolean";
|
||||
import isNumber from "lodash/lang/isNumber";
|
||||
import isRegExp from "lodash/lang/isRegExp";
|
||||
import isString from "lodash/lang/isString";
|
||||
import * as parse from "../../helpers/parse";
|
||||
import traverse from "../index";
|
||||
import includes from "lodash/collection/includes";
|
||||
import assign from "lodash/object/assign";
|
||||
@ -476,7 +477,21 @@ export default class TraversalPath {
|
||||
* Description
|
||||
*/
|
||||
|
||||
replaceWith(replacement, arraysAllowed) {
|
||||
replaceWithSourceString(replacement) {
|
||||
replacement = parse.all(`(${replacement})`, {
|
||||
filename: "custom string",
|
||||
errorMessage: "make sure this is an expression"
|
||||
}).body[0].expression;
|
||||
|
||||
traverse.removeProperties(replacement);
|
||||
return this.replaceWith(replacement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
replaceWith(replacement, whateverAllowed) {
|
||||
if (this.removed) {
|
||||
throw new Error("You can't replace this node, we've already removed it");
|
||||
}
|
||||
@ -486,13 +501,27 @@ export default class TraversalPath {
|
||||
}
|
||||
|
||||
if (Array.isArray(replacement)) {
|
||||
if (arraysAllowed) {
|
||||
if (whateverAllowed) {
|
||||
return this.replaceWithMultiple(replacement);
|
||||
} else {
|
||||
throw new Error("Don't use `path.replaceWith()` with an array of nodes, use `path.replaceWithMultiple()`");
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof replacement === "string") {
|
||||
if (whateverAllowed) {
|
||||
return this.replaceWithSourceString(replacement);
|
||||
} else {
|
||||
throw new Error("Don't use `path.replaceWith()` with a string, use `path.replaceWithSourceString()`");
|
||||
}
|
||||
}
|
||||
|
||||
// replacing a statement with an expression so wrap it in an expression statement
|
||||
if (this.isPreviousType("Statement") && t.isExpression(replacement)) {
|
||||
replacement = t.expressionStatement(replacement);
|
||||
}
|
||||
|
||||
// replacing an expression with a statement so let's explode it
|
||||
if (this.isPreviousType("Expression") && t.isStatement(replacement)) {
|
||||
return this.replaceExpressionWithStatements([replacement]);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user