babel-core: add options for different parser/generator (#3561)
* babel-core: add options for different parser/generator * test for experiemental plugins, other babylon options * fix passing options into parser * Fix when no code is provided * fixup tests * fix tests again * use filename and fallback to cwd
This commit is contained in:
@@ -21,6 +21,8 @@ import * as util from "../../util";
|
|||||||
import path from "path";
|
import path from "path";
|
||||||
import * as t from "babel-types";
|
import * as t from "babel-types";
|
||||||
|
|
||||||
|
import resolve from "../../helpers/resolve";
|
||||||
|
|
||||||
import blockHoistPlugin from "../internal-plugins/block-hoist";
|
import blockHoistPlugin from "../internal-plugins/block-hoist";
|
||||||
import shadowFunctionsPlugin from "../internal-plugins/shadow-functions";
|
import shadowFunctionsPlugin from "../internal-plugins/shadow-functions";
|
||||||
|
|
||||||
@@ -411,8 +413,35 @@ export default class File extends Store {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parse(code: string) {
|
parse(code: string) {
|
||||||
|
let parseCode = parse;
|
||||||
|
let parserOpts = this.opts.parserOpts || this.parserOpts;
|
||||||
|
|
||||||
|
if (parserOpts) {
|
||||||
|
parserOpts = Object.assign({}, this.parserOpts, parserOpts);
|
||||||
|
|
||||||
|
if (parserOpts.parser) {
|
||||||
|
if (typeof parserOpts.parser === "string") {
|
||||||
|
let dirname = path.dirname(this.opts.filename) || process.cwd();
|
||||||
|
let parser = resolve(parserOpts.parser, dirname);
|
||||||
|
if (parser) {
|
||||||
|
parseCode = require(parser).parse;
|
||||||
|
} else {
|
||||||
|
throw new Error(`Couldn't find parser ${parserOpts.parser} with "parse" method relative to directory ${dirname}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
parseCode = parserOpts.parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
parserOpts.parser = {
|
||||||
|
parse(source) {
|
||||||
|
return parse(source, parserOpts);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.log.debug("Parse start");
|
this.log.debug("Parse start");
|
||||||
let ast = parse(code, this.parserOpts);
|
let ast = parseCode(code, parserOpts);
|
||||||
this.log.debug("Parse stop");
|
this.log.debug("Parse stop");
|
||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
@@ -573,9 +602,24 @@ export default class File extends Store {
|
|||||||
let result: BabelFileResult = { ast };
|
let result: BabelFileResult = { ast };
|
||||||
if (!opts.code) return this.makeResult(result);
|
if (!opts.code) return this.makeResult(result);
|
||||||
|
|
||||||
|
let gen = generate;
|
||||||
|
if (opts.generatorOpts.generator) {
|
||||||
|
gen = opts.generatorOpts.generator;
|
||||||
|
|
||||||
|
if (typeof gen === "string") {
|
||||||
|
let dirname = path.dirname(this.opts.filename) || process.cwd();
|
||||||
|
let generator = resolve(gen, dirname);
|
||||||
|
if (generator) {
|
||||||
|
gen = require(generator).print;
|
||||||
|
} else {
|
||||||
|
throw new Error(`Couldn't find generator ${gen} with "print" method relative to directory ${dirname}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.log.debug("Generation start");
|
this.log.debug("Generation start");
|
||||||
|
|
||||||
let _result = generate(ast, opts, this.code);
|
let _result = gen(ast, opts.generatorOpts ? Object.assign(opts, opts.generatorOpts) : opts, this.code);
|
||||||
result.code = _result.code;
|
result.code = _result.code;
|
||||||
result.map = _result.map;
|
result.map = _result.map;
|
||||||
|
|
||||||
|
|||||||
@@ -198,4 +198,16 @@ module.exports = {
|
|||||||
default: false,
|
default: false,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Deprecate top level parserOpts
|
||||||
|
parserOpts: {
|
||||||
|
description: "Options to pass into the parser, or to change parsers (parserOpts.parser)",
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
|
||||||
|
// Deprecate top level generatorOpts
|
||||||
|
generatorOpts: {
|
||||||
|
description: "Options to pass into the generator, or to change generators (generatorOpts.generator)",
|
||||||
|
default: false
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ var sourceMap = require("source-map");
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var File = require("../lib/transformation/file").default;
|
var File = require("../lib/transformation/file").default;
|
||||||
var Plugin = require("../lib/transformation/plugin");
|
var Plugin = require("../lib/transformation/plugin");
|
||||||
|
var generator = require("babel-generator").default;
|
||||||
|
|
||||||
function assertIgnored(result) {
|
function assertIgnored(result) {
|
||||||
assert.ok(result.ignored);
|
assert.ok(result.ignored);
|
||||||
@@ -23,6 +24,77 @@ function transformAsync(code, opts) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suite("parser and generator options", function() {
|
||||||
|
var recast = {
|
||||||
|
parse: function(code, opts) {
|
||||||
|
return opts.parser.parse(code);
|
||||||
|
},
|
||||||
|
print: function(ast) {
|
||||||
|
return generator(ast);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function newTransform(string) {
|
||||||
|
return babel.transform(string, {
|
||||||
|
parserOpts: {
|
||||||
|
parser: recast.parse,
|
||||||
|
plugins: ["flow"],
|
||||||
|
allowImportExportEverywhere: true
|
||||||
|
},
|
||||||
|
generatorOpts: {
|
||||||
|
generator: recast.print
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
test("options", function() {
|
||||||
|
var string = "original;";
|
||||||
|
assert.deepEqual(newTransform(string).ast, babel.transform(string).ast);
|
||||||
|
assert.equal(newTransform(string).code, string);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("experimental syntax", function() {
|
||||||
|
var experimental = "var a: number = 1;";
|
||||||
|
|
||||||
|
assert.deepEqual(newTransform(experimental).ast, babel.transform(experimental, {
|
||||||
|
parserOpts: {
|
||||||
|
plugins: ["flow"]
|
||||||
|
}
|
||||||
|
}).ast);
|
||||||
|
assert.equal(newTransform(experimental).code, experimental);
|
||||||
|
|
||||||
|
function newTransformWithPlugins(string) {
|
||||||
|
return babel.transform(string, {
|
||||||
|
plugins: [__dirname + "/../../babel-plugin-syntax-flow"],
|
||||||
|
parserOpts: {
|
||||||
|
parser: recast.parse
|
||||||
|
},
|
||||||
|
generatorOpts: {
|
||||||
|
generator: recast.print
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.deepEqual(newTransformWithPlugins(experimental).ast, babel.transform(experimental, {
|
||||||
|
parserOpts: {
|
||||||
|
plugins: ["flow"]
|
||||||
|
}
|
||||||
|
}).ast);
|
||||||
|
assert.equal(newTransformWithPlugins(experimental).code, experimental);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("other options", function() {
|
||||||
|
var experimental = "if (true) {\n import a from 'a';\n}";
|
||||||
|
|
||||||
|
assert.notEqual(newTransform(experimental).ast, babel.transform(experimental, {
|
||||||
|
parserOpts: {
|
||||||
|
allowImportExportEverywhere: true
|
||||||
|
}
|
||||||
|
}).ast);
|
||||||
|
assert.equal(newTransform(experimental).code, experimental);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
suite("api", function () {
|
suite("api", function () {
|
||||||
test("analyze", function () {
|
test("analyze", function () {
|
||||||
assert.equal(babel.analyse("foobar;").marked.length, 0);
|
assert.equal(babel.analyse("foobar;").marked.length, 0);
|
||||||
|
|||||||
@@ -93,6 +93,11 @@ function normalizeOptions(code, opts, tokens): Format {
|
|||||||
* Determine if input code uses more single or double quotes.
|
* Determine if input code uses more single or double quotes.
|
||||||
*/
|
*/
|
||||||
function findCommonStringDelimiter(code, tokens) {
|
function findCommonStringDelimiter(code, tokens) {
|
||||||
|
const DEFAULT_STRING_DELIMITER = "double";
|
||||||
|
if (!code) {
|
||||||
|
return DEFAULT_STRING_DELIMITER;
|
||||||
|
}
|
||||||
|
|
||||||
let occurences = {
|
let occurences = {
|
||||||
single: 0,
|
single: 0,
|
||||||
double: 0
|
double: 0
|
||||||
@@ -117,7 +122,7 @@ function findCommonStringDelimiter(code, tokens) {
|
|||||||
if (occurences.single > occurences.double) {
|
if (occurences.single > occurences.double) {
|
||||||
return "single";
|
return "single";
|
||||||
} else {
|
} else {
|
||||||
return "double";
|
return DEFAULT_STRING_DELIMITER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user