Allow sourceType:unambiguous as a way to tell Babylon to guess the type. (#6789)

* Allow sourceType:unambiguous as a way to tell Babylon to guess the type.

* Update some docs.
This commit is contained in:
Logan Smyth 2017-11-10 15:00:06 -08:00 committed by GitHub
parent 330f9006a7
commit 432a9b5092
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 746 additions and 6 deletions

View File

@ -116,5 +116,5 @@ Following is a table of the options you can use:
| `sourceMaps` | `false` | If truthy, adds a `map` property to returned output. If set to `"inline"`, a comment with a sourceMappingURL directive is added to the bottom of the returned code. If set to `"both"` then a `map` property is returned as well as a source map comment appended. **This does not emit sourcemap files by itself!** To have sourcemaps emitted using the CLI, you must pass it the `--source-maps` option |
| `sourceMapTarget` | `(filenameRelative)` | Set `file` on returned source map |
| `sourceRoot` | `(moduleRoot)` | The root from which all sources are relative |
| `sourceType` | `"module"` | Indicate the mode the code should be parsed in. Can be either "script" or "module" |
| `sourceType` | `"module"` | Indicate the mode the code should be parsed in. Can be one of "script", "module", or "unambiguous". `"unambiguous"` will make Babel attempt to _guess_, based on the presence of ES6 `import` or `export` statements. Files with ES6 `import`s and `export`s are considered `"module"` and are otherwise `"script"`. |
| `wrapPluginVisitorMethod`| `null` | An optional callback that can be used to wrap visitor methods. **NOTE:** This is useful for things like introspection, and not really needed for implementing anything. Called as `wrapPluginVisitorMethod(pluginAlias, visitorType, callback)`.

View File

@ -46,8 +46,15 @@ export function assertSourceType(
key: string,
value: mixed,
): SourceTypeOption | void {
if (value !== undefined && value !== "module" && value !== "script") {
throw new Error(`.${key} must be "module", "script", or undefined`);
if (
value !== undefined &&
value !== "module" &&
value !== "script" &&
value !== "unambiguous"
) {
throw new Error(
`.${key} must be "module", "script", "unambiguous", or undefined`,
);
}
return value;
}

View File

@ -185,7 +185,7 @@ export type PluginItem = PluginTarget | [PluginTarget, {} | void];
export type PluginList = $ReadOnlyArray<PluginItem>;
export type SourceMapsOption = boolean | "inline" | "both";
export type SourceTypeOption = "module" | "script";
export type SourceTypeOption = "module" | "script" | "unambiguous";
export type CompactOption = boolean | "auto";
export type RootInputSourceMapOption = {} | boolean;

View File

@ -39,7 +39,7 @@ mind. When in doubt, use `.parse()`.
- **allowSuperOutsideMethod**: TODO
- **sourceType**: Indicate the mode the code should be parsed in. Can be
either `"script"` or `"module"`.
one of `"script"`, `"module"`, or `"unambiguous"`. Defaults to `"script"`. `"unambiguous"` will make Babylon attempt to _guess_, based on the presence of ES6 `import` or `export` statements. Files with ES6 `import`s and `export`s are considered `"module"` and are otherwise `"script"`.
- **sourceFilename**: Correlate output AST nodes with their source filename. Useful when generating code and source maps from the ASTs of multiple input files.

View File

@ -18,7 +18,27 @@ plugins.jsx = jsxPlugin;
plugins.typescript = typescriptPlugin;
export function parse(input: string, options?: Options): File {
return getParser(options, input).parse();
if (options && options.sourceType === "unambiguous") {
options = Object.assign({}, options);
try {
options.sourceType = "module";
const ast = getParser(options, input).parse();
// Rather than try to parse as a script first, we opt to parse as a module and convert back
// to a script where possible to avoid having to do a full re-parse of the input content.
if (!hasModuleSyntax(ast)) ast.program.sourceType = "script";
return ast;
} catch (moduleError) {
try {
options.sourceType = "script";
return getParser(options, input).parse();
} catch (scriptError) {}
throw moduleError;
}
} else {
return getParser(options, input).parse();
}
}
export function parseExpression(input: string, options?: Options): Expression {
@ -91,3 +111,16 @@ function getParserClass(
}
return cls;
}
function hasModuleSyntax(ast) {
return ast.program.body.some(
child =>
(child.type === "ImportDeclaration" &&
(!child.importKind || child.importKind === "value")) ||
(child.type === "ExportNamedDeclaration" &&
(!child.exportKind || child.exportKind === "value")) ||
(child.type === "ExportAllDeclaration" &&
(!child.exportKind || child.exportKind === "value")) ||
child.type === "ExportDefaultDeclaration",
);
}

View File

@ -0,0 +1 @@
var foo = require("foo");

View File

@ -0,0 +1,138 @@
{
"type": "File",
"start": 0,
"end": 25,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 25
}
},
"program": {
"type": "Program",
"start": 0,
"end": 25,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 25
}
},
"sourceType": "script",
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 25,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 25
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 4,
"end": 24,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 24
}
},
"id": {
"type": "Identifier",
"start": 4,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "foo"
},
"name": "foo"
},
"init": {
"type": "CallExpression",
"start": 10,
"end": 24,
"loc": {
"start": {
"line": 1,
"column": 10
},
"end": {
"line": 1,
"column": 24
}
},
"callee": {
"type": "Identifier",
"start": 10,
"end": 17,
"loc": {
"start": {
"line": 1,
"column": 10
},
"end": {
"line": 1,
"column": 17
},
"identifierName": "require"
},
"name": "require"
},
"arguments": [
{
"type": "StringLiteral",
"start": 18,
"end": 23,
"loc": {
"start": {
"line": 1,
"column": 18
},
"end": {
"line": 1,
"column": 23
}
},
"extra": {
"rawValue": "foo",
"raw": "\"foo\""
},
"value": "foo"
}
]
}
}
],
"kind": "var"
}
],
"directives": []
}
}

View File

@ -0,0 +1,3 @@
{
"sourceType": "unambiguous"
}

View File

@ -0,0 +1,3 @@
import type { Foo } from "bar";
export type { Foo };
export type * from "bar";

View File

@ -0,0 +1,227 @@
{
"type": "File",
"start": 0,
"end": 78,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 25
}
},
"program": {
"type": "Program",
"start": 0,
"end": 78,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 25
}
},
"sourceType": "script",
"body": [
{
"type": "ImportDeclaration",
"start": 0,
"end": 31,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 31
}
},
"specifiers": [
{
"type": "ImportSpecifier",
"start": 14,
"end": 17,
"loc": {
"start": {
"line": 1,
"column": 14
},
"end": {
"line": 1,
"column": 17
}
},
"imported": {
"type": "Identifier",
"start": 14,
"end": 17,
"loc": {
"start": {
"line": 1,
"column": 14
},
"end": {
"line": 1,
"column": 17
},
"identifierName": "Foo"
},
"name": "Foo"
},
"importKind": null,
"local": {
"type": "Identifier",
"start": 14,
"end": 17,
"loc": {
"start": {
"line": 1,
"column": 14
},
"end": {
"line": 1,
"column": 17
},
"identifierName": "Foo"
},
"name": "Foo"
}
}
],
"importKind": "type",
"source": {
"type": "StringLiteral",
"start": 25,
"end": 30,
"loc": {
"start": {
"line": 1,
"column": 25
},
"end": {
"line": 1,
"column": 30
}
},
"extra": {
"rawValue": "bar",
"raw": "\"bar\""
},
"value": "bar"
}
},
{
"type": "ExportNamedDeclaration",
"start": 32,
"end": 52,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 20
}
},
"specifiers": [
{
"type": "ExportSpecifier",
"start": 46,
"end": 49,
"loc": {
"start": {
"line": 2,
"column": 14
},
"end": {
"line": 2,
"column": 17
}
},
"local": {
"type": "Identifier",
"start": 46,
"end": 49,
"loc": {
"start": {
"line": 2,
"column": 14
},
"end": {
"line": 2,
"column": 17
},
"identifierName": "Foo"
},
"name": "Foo"
},
"exported": {
"type": "Identifier",
"start": 46,
"end": 49,
"loc": {
"start": {
"line": 2,
"column": 14
},
"end": {
"line": 2,
"column": 17
},
"identifierName": "Foo"
},
"name": "Foo"
}
}
],
"source": null,
"exportKind": "type",
"declaration": null
},
{
"type": "ExportAllDeclaration",
"start": 53,
"end": 78,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 25
}
},
"exportKind": "type",
"source": {
"type": "StringLiteral",
"start": 72,
"end": 77,
"loc": {
"start": {
"line": 3,
"column": 19
},
"end": {
"line": 3,
"column": 24
}
},
"extra": {
"rawValue": "bar",
"raw": "\"bar\""
},
"value": "bar"
}
}
],
"directives": []
}
}

View File

@ -0,0 +1,4 @@
{
"sourceType": "unambiguous",
"plugins": ["flow"]
}

View File

@ -0,0 +1 @@
export * from "foo";

View File

@ -0,0 +1,69 @@
{
"type": "File",
"start": 0,
"end": 20,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 20
}
},
"program": {
"type": "Program",
"start": 0,
"end": 20,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 20
}
},
"sourceType": "module",
"body": [
{
"type": "ExportAllDeclaration",
"start": 0,
"end": 20,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 20
}
},
"source": {
"type": "StringLiteral",
"start": 14,
"end": 19,
"loc": {
"start": {
"line": 1,
"column": 14
},
"end": {
"line": 1,
"column": 19
}
},
"extra": {
"rawValue": "foo",
"raw": "\"foo\""
},
"value": "foo"
}
}
],
"directives": []
}
}

View File

@ -0,0 +1,3 @@
{
"sourceType": "unambiguous"
}

View File

@ -0,0 +1 @@
export default {};

View File

@ -0,0 +1,65 @@
{
"type": "File",
"start": 0,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 18
}
},
"program": {
"type": "Program",
"start": 0,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 18
}
},
"sourceType": "module",
"body": [
{
"type": "ExportDefaultDeclaration",
"start": 0,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 18
}
},
"declaration": {
"type": "ObjectExpression",
"start": 15,
"end": 17,
"loc": {
"start": {
"line": 1,
"column": 15
},
"end": {
"line": 1,
"column": 17
}
},
"properties": []
}
}
],
"directives": []
}
}

View File

@ -0,0 +1,3 @@
{
"sourceType": "unambiguous"
}

View File

@ -0,0 +1 @@
export function fn(){}

View File

@ -0,0 +1,104 @@
{
"type": "File",
"start": 0,
"end": 22,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 22
}
},
"program": {
"type": "Program",
"start": 0,
"end": 22,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 22
}
},
"sourceType": "module",
"body": [
{
"type": "ExportNamedDeclaration",
"start": 0,
"end": 22,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 22
}
},
"specifiers": [],
"source": null,
"declaration": {
"type": "FunctionDeclaration",
"start": 7,
"end": 22,
"loc": {
"start": {
"line": 1,
"column": 7
},
"end": {
"line": 1,
"column": 22
}
},
"id": {
"type": "Identifier",
"start": 16,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 16
},
"end": {
"line": 1,
"column": 18
},
"identifierName": "fn"
},
"name": "fn"
},
"generator": false,
"expression": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start": 20,
"end": 22,
"loc": {
"start": {
"line": 1,
"column": 20
},
"end": {
"line": 1,
"column": 22
}
},
"body": [],
"directives": []
}
}
}
],
"directives": []
}
}

View File

@ -0,0 +1,3 @@
{
"sourceType": "unambiguous"
}

View File

@ -0,0 +1 @@
import "foo";

View File

@ -0,0 +1,70 @@
{
"type": "File",
"start": 0,
"end": 13,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 13
}
},
"program": {
"type": "Program",
"start": 0,
"end": 13,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 13
}
},
"sourceType": "module",
"body": [
{
"type": "ImportDeclaration",
"start": 0,
"end": 13,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 13
}
},
"specifiers": [],
"source": {
"type": "StringLiteral",
"start": 7,
"end": 12,
"loc": {
"start": {
"line": 1,
"column": 7
},
"end": {
"line": 1,
"column": 12
}
},
"extra": {
"rawValue": "foo",
"raw": "\"foo\""
},
"value": "foo"
}
}
],
"directives": []
}
}

View File

@ -0,0 +1,3 @@
{
"sourceType": "unambiguous"
}