Merge branch 'master' into 7.0

# Conflicts:
#	src/parser/index.js
This commit is contained in:
Daniel Tschinder 2017-02-12 13:32:06 +01:00
commit d88befdd30
No known key found for this signature in database
GPG Key ID: 46A883CAEC8A94BD
80 changed files with 5370 additions and 53 deletions

View File

@ -27,6 +27,12 @@ Significant diversions are expected to occur in the future such as streaming, EB
### `babylon.parse(code, [options])` ### `babylon.parse(code, [options])`
### `babylon.parseExpression(code, [options])`
`parse()` parses the provided `code` as an entire ECMAScript program, while
`parseExpression()` tries to parse a single Expression with performance in
mind. When in doubt, use `.parse()`.
### Options ### Options
- **allowImportExportEverywhere**: By default, `import` and `export` - **allowImportExportEverywhere**: By default, `import` and `export`
@ -37,15 +43,19 @@ Significant diversions are expected to occur in the future such as streaming, EB
the top level raises an error. Set this to `true` to accept such the top level raises an error. Set this to `true` to accept such
code. code.
- **allowSuperOutsideMethod** TODO - **allowSuperOutsideMethod**: TODO
- **sourceType**: Indicate the mode the code should be parsed in. Can be - **sourceType**: Indicate the mode the code should be parsed in. Can be
either `"script"` or `"module"`. either `"script"` or `"module"`.
- **sourceFilename**: Correlate output AST nodes with their source filename. Useful when generating code and source maps from the ASTs of multiple input files. - **sourceFilename**: Correlate output AST nodes with their source filename. Useful when generating code and source maps from the ASTs of multiple input files.
- **startLine**: By default, the first line of code parsed is treated as line 1. You can provide a line number to alternatively start with. Useful for integration with other source tools.
- **plugins**: Array containing the plugins that you want to enable. - **plugins**: Array containing the plugins that you want to enable.
- **strictMode**: TODO
### Output ### Output
Babylon generates AST according to [Babel AST format][]. Babylon generates AST according to [Babel AST format][].

View File

@ -11,8 +11,10 @@ import { types as tokTypes } from "./tokenizer/types";
import "./tokenizer"; import "./tokenizer";
import "./tokenizer/context"; import "./tokenizer/context";
import estreePlugin from "./plugins/estree";
import flowPlugin from "./plugins/flow"; import flowPlugin from "./plugins/flow";
import jsxPlugin from "./plugins/jsx"; import jsxPlugin from "./plugins/jsx";
plugins.estree = estreePlugin;
plugins.flow = flowPlugin; plugins.flow = flowPlugin;
plugins.jsx = jsxPlugin; plugins.jsx = jsxPlugin;

View File

@ -4,6 +4,7 @@
export const defaultOptions: { export const defaultOptions: {
sourceType: string, sourceType: string,
sourceFilename: any, sourceFilename: any,
startLine: number,
allowReturnOutsideFunction: boolean, allowReturnOutsideFunction: boolean,
allowImportExportEverywhere: boolean, allowImportExportEverywhere: boolean,
allowSuperOutsideMethod: boolean, allowSuperOutsideMethod: boolean,
@ -14,6 +15,9 @@ export const defaultOptions: {
sourceType: "script", sourceType: "script",
// Source filename. // Source filename.
sourceFilename: undefined, sourceFilename: undefined,
// Line from which to start counting source. Useful for
// integration with other tools.
startLine: 1,
// When enabled, a return at the top level is not considered an // When enabled, a return at the top level is not considered an
// error. // error.
allowReturnOutsideFunction: false, allowReturnOutsideFunction: false,

View File

@ -343,7 +343,7 @@ pp.parseCallExpressionArguments = function (close, possibleAsyncArrow) {
innerParenStart = this.state.start; innerParenStart = this.state.start;
} }
elts.push(this.parseExprListItem(undefined, possibleAsyncArrow ? { start: 0 } : undefined)); elts.push(this.parseExprListItem(false, possibleAsyncArrow ? { start: 0 } : undefined, possibleAsyncArrow ? { start: 0 } : undefined));
} }
// we found an async arrow function so let's not allow any inner parens // we found an async arrow function so let's not allow any inner parens
@ -735,8 +735,9 @@ pp.parseObj = function (isPattern, refShorthandDefaultPos) {
} }
if (this.hasPlugin("objectRestSpread") && this.match(tt.ellipsis)) { if (this.hasPlugin("objectRestSpread") && this.match(tt.ellipsis)) {
prop = this.parseSpread(); prop = this.parseSpread(isPattern ? { start: 0 } : undefined);
prop.type = isPattern ? "RestProperty" : "SpreadProperty"; prop.type = isPattern ? "RestProperty" : "SpreadProperty";
if (isPattern) this.toAssignable(prop.argument, true, "object pattern");
node.properties.push(prop); node.properties.push(prop);
if (isPattern) { if (isPattern) {
const position = this.state.start; const position = this.state.start;
@ -773,6 +774,7 @@ pp.parseObj = function (isPattern, refShorthandDefaultPos) {
const asyncId = this.parseIdentifier(); const asyncId = this.parseIdentifier();
if (this.match(tt.colon) || this.match(tt.parenL) || this.match(tt.braceR) || this.match(tt.eq) || this.match(tt.comma)) { if (this.match(tt.colon) || this.match(tt.parenL) || this.match(tt.braceR) || this.match(tt.eq) || this.match(tt.comma)) {
prop.key = asyncId; prop.key = asyncId;
prop.computed = false;
} else { } else {
isAsync = true; isAsync = true;
if (this.hasPlugin("asyncGenerators")) isGenerator = this.eat(tt.star); if (this.hasPlugin("asyncGenerators")) isGenerator = this.eat(tt.star);
@ -1019,14 +1021,14 @@ pp.parseExprList = function (close, allowEmpty, refShorthandDefaultPos) {
return elts; return elts;
}; };
pp.parseExprListItem = function (allowEmpty, refShorthandDefaultPos) { pp.parseExprListItem = function (allowEmpty, refShorthandDefaultPos, refNeedsArrowPos) {
let elt; let elt;
if (allowEmpty && this.match(tt.comma)) { if (allowEmpty && this.match(tt.comma)) {
elt = null; elt = null;
} else if (this.match(tt.ellipsis)) { } else if (this.match(tt.ellipsis)) {
elt = this.parseSpread(refShorthandDefaultPos); elt = this.parseSpread(refShorthandDefaultPos);
} else { } else {
elt = this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem); elt = this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem, refNeedsArrowPos);
} }
return elt; return elt;
}; };
@ -1037,14 +1039,13 @@ pp.parseExprListItem = function (allowEmpty, refShorthandDefaultPos) {
pp.parseIdentifier = function (liberal) { pp.parseIdentifier = function (liberal) {
const node = this.startNode(); const node = this.startNode();
if (!liberal) {
this.checkReservedWord(this.state.value, this.state.start, !!this.state.type.keyword, false);
}
if (this.match(tt.name)) { if (this.match(tt.name)) {
if (!liberal) {
this.checkReservedWord(this.state.value, this.state.start, false, false);
}
node.name = this.state.value; node.name = this.state.value;
} else if (liberal && this.state.type.keyword) { } else if (this.state.type.keyword) {
node.name = this.state.type.keyword; node.name = this.state.type.keyword;
} else { } else {
this.unexpected(); this.unexpected();

View File

@ -46,6 +46,12 @@ export default class Parser extends Tokenizer {
pluginList.push("flow"); pluginList.push("flow");
} }
if (pluginList.indexOf("estree") >= 0) {
// ensure estree plugin loads first
pluginList = pluginList.filter((plugin) => plugin !== "estree");
pluginList.unshift("estree");
}
for (const name of pluginList) { for (const name of pluginList) {
if (!pluginMap[name]) { if (!pluginMap[name]) {
pluginMap[name] = true; pluginMap[name] = true;

View File

@ -1059,7 +1059,12 @@ pp.parseImportSpecifiers = function (node) {
pp.parseImportSpecifier = function (node) { pp.parseImportSpecifier = function (node) {
const specifier = this.startNode(); const specifier = this.startNode();
specifier.imported = this.parseIdentifier(true); specifier.imported = this.parseIdentifier(true);
specifier.local = this.eatContextual("as") ? this.parseIdentifier() : specifier.imported.__clone(); if (this.eatContextual("as")) {
specifier.local = this.parseIdentifier();
} else {
this.checkReservedWord(specifier.imported.name, specifier.start, true, true);
specifier.local = specifier.imported.__clone();
}
this.checkLVal(specifier.local, true, undefined, "import specifier"); this.checkLVal(specifier.local, true, undefined, "import specifier");
node.specifiers.push(this.finishNode(specifier, "ImportSpecifier")); node.specifiers.push(this.finishNode(specifier, "ImportSpecifier"));
}; };

242
src/plugins/estree.js Normal file
View File

@ -0,0 +1,242 @@
import { types as tt } from "../tokenizer/types";
import Parser from "../parser";
const pp = Parser.prototype;
pp.estreeParseRegExpLiteral = function ({ pattern, flags }) {
let regex = null;
try {
regex = new RegExp(pattern, flags);
} catch (e) {
// In environments that don't support these flags value will
// be null as the regex can't be represented natively.
}
const node = this.estreeParseLiteral(regex);
node.regex = { pattern, flags };
return node;
};
pp.estreeParseLiteral = function (value) {
const node = this.parseLiteral(value, "Literal");
node.raw = node.extra.raw;
delete node.extra;
return node;
};
pp.directiveToStmt = function (directive) {
const directiveLiteral = directive.value;
const stmt = this.startNodeAt(directive.start, directive.loc.start);
const expression = this.startNodeAt(directiveLiteral.start, directiveLiteral.loc.start);
expression.value = directiveLiteral.value;
expression.raw = directiveLiteral.extra.raw;
stmt.expression = this.finishNodeAt(expression, "Literal", directiveLiteral.end, directiveLiteral.loc.end);
stmt.directive = directiveLiteral.extra.raw.slice(1, -1);
return this.finishNodeAt(stmt, "ExpressionStatement", directive.end, directive.loc.end);
};
function isSimpleProperty(node) {
return node &&
node.type === "Property" &&
node.kind === "init" &&
node.method === false;
}
export default function (instance) {
instance.extend("checkDeclaration", function(inner) {
return function (node) {
if (isSimpleProperty(node)) {
this.checkDeclaration(node.value);
} else {
inner.call(this, node);
}
};
});
instance.extend("checkGetterSetterParamCount", function() {
return function (prop) {
const paramCount = prop.kind === "get" ? 0 : 1;
if (prop.value.params.length !== paramCount) {
const start = prop.start;
if (prop.kind === "get") {
this.raise(start, "getter should have no params");
} else {
this.raise(start, "setter should have exactly one param");
}
}
};
});
instance.extend("checkLVal", function(inner) {
return function (expr, isBinding, checkClashes, ...args) {
switch (expr.type) {
case "ObjectPattern":
expr.properties.forEach((prop) => {
this.checkLVal(
prop.type === "Property" ? prop.value : prop,
isBinding,
checkClashes,
"object destructuring pattern"
);
});
break;
default:
inner.call(this, expr, isBinding, checkClashes, ...args);
}
};
});
instance.extend("checkPropClash", function () {
return function (prop, propHash) {
if (prop.computed || !isSimpleProperty(prop)) return;
const key = prop.key;
// It is either an Identifier or a String/NumericLiteral
const name = key.type === "Identifier" ? key.name : String(key.value);
if (name === "__proto__") {
if (propHash.proto) this.raise(key.start, "Redefinition of __proto__ property");
propHash.proto = true;
}
};
});
instance.extend("isStrictBody", function () {
return function (node, isExpression) {
if (!isExpression && node.body.body.length > 0) {
for (const directive of (node.body.body: Array<Object>)) {
if (directive.type === "ExpressionStatement" && directive.expression.type === "Literal") {
if (directive.expression.value === "use strict") return true;
} else {
// Break for the first non literal expression
break;
}
}
}
return false;
};
});
instance.extend("isValidDirective", function () {
return function (stmt) {
return stmt.type === "ExpressionStatement" &&
stmt.expression.type === "Literal" &&
typeof stmt.expression.value === "string" &&
(!stmt.expression.extra || !stmt.expression.extra.parenthesized);
};
});
instance.extend("parseBlockBody", function (inner) {
return function (node, ...args) {
inner.call(this, node, ...args);
node.directives.reverse().forEach((directive) => {
node.body.unshift(this.directiveToStmt(directive));
});
delete node.directives;
};
});
instance.extend("parseClassMethod", function (inner) {
return function (classBody, ...args) {
inner.call(this, classBody, ...args);
const body = classBody.body;
body[body.length - 1].type = "MethodDefinition";
};
});
instance.extend("parseExprAtom", function(inner) {
return function (...args) {
switch (this.state.type) {
case tt.regexp:
return this.estreeParseRegExpLiteral(this.state.value);
case tt.num:
case tt.string:
return this.estreeParseLiteral(this.state.value);
case tt._null:
return this.estreeParseLiteral(null);
case tt._true:
return this.estreeParseLiteral(true);
case tt._false:
return this.estreeParseLiteral(false);
default:
return inner.call(this, ...args);
}
};
});
instance.extend("parseMethod", function(inner) {
return function (node, ...args) {
let funcNode = this.startNode();
funcNode.kind = node.kind; // provide kind, so inner method correctly sets state
funcNode = inner.call(this, funcNode, ...args);
delete funcNode.kind;
node.value = this.finishNode(funcNode, "FunctionExpression");
return node;
};
});
instance.extend("parseObjectMethod", function(inner) {
return function (...args) {
const node = inner.call(this, ...args);
if (node) {
if (node.kind === "method") node.kind = "init";
node.type = "Property";
}
return node;
};
});
instance.extend("parseObjectProperty", function(inner) {
return function (...args) {
const node = inner.call(this, ...args);
if (node) {
node.kind = "init";
node.type = "Property";
}
return node;
};
});
instance.extend("toAssignable", function(inner) {
return function (node, isBinding, ...args) {
if (isSimpleProperty(node)) {
this.toAssignable(node.value, isBinding, ...args);
return node;
} else if (node.type === "ObjectExpression") {
node.type = "ObjectPattern";
for (const prop of (node.properties: Array<Object>)) {
if (prop.kind === "get" || prop.kind === "set") {
this.raise(prop.key.start, "Object pattern can't contain getter or setter");
} else if (prop.method) {
this.raise(prop.key.start, "Object pattern can't contain methods");
} else {
this.toAssignable(prop, isBinding, "object destructuring pattern");
}
}
return node;
}
return inner.call(this, node, isBinding, ...args);
};
});
}

View File

@ -28,6 +28,45 @@ pp.flowParseTypeInitialiser = function (tok) {
return type; return type;
}; };
pp.flowParsePredicate = function() {
const node = this.startNode();
const moduloLoc = this.state.startLoc;
const moduloPos = this.state.start;
this.expect(tt.modulo);
const checksLoc = this.state.startLoc;
this.expectContextual("checks");
// Force '%' and 'checks' to be adjacent
if (moduloLoc.line !== checksLoc.line || moduloLoc.column !== checksLoc.column - 1) {
this.raise(moduloPos, "Spaces between ´%´ and ´checks´ are not allowed here.");
}
if (this.eat(tt.parenL)) {
node.expression = this.parseExpression();
this.expect(tt.parenR);
return this.finishNode(node, "DeclaredPredicate");
} else {
return this.finishNode(node, "InferredPredicate");
}
};
pp.flowParseTypeAndPredicateInitialiser = function () {
const oldInType = this.state.inType;
this.state.inType = true;
this.expect(tt.colon);
let type = null;
let predicate = null;
if (this.match(tt.modulo)) {
this.state.inType = oldInType;
predicate = this.flowParsePredicate();
} else {
type = this.flowParseType();
this.state.inType = oldInType;
if (this.match(tt.modulo)) {
predicate = this.flowParsePredicate();
}
}
return [type, predicate];
};
pp.flowParseDeclareClass = function (node) { pp.flowParseDeclareClass = function (node) {
this.next(); this.next();
this.flowParseInterfaceish(node, true); this.flowParseInterfaceish(node, true);
@ -53,9 +92,10 @@ pp.flowParseDeclareFunction = function (node) {
typeNode.params = tmp.params; typeNode.params = tmp.params;
typeNode.rest = tmp.rest; typeNode.rest = tmp.rest;
this.expect(tt.parenR); this.expect(tt.parenR);
typeNode.returnType = this.flowParseTypeInitialiser(); let predicate = null;
[typeNode.returnType, predicate] = this.flowParseTypeAndPredicateInitialiser();
typeContainer.typeAnnotation = this.finishNode(typeNode, "FunctionTypeAnnotation"); typeContainer.typeAnnotation = this.finishNode(typeNode, "FunctionTypeAnnotation");
typeContainer.predicate = predicate;
id.typeAnnotation = this.finishNode(typeContainer, "TypeAnnotation"); id.typeAnnotation = this.finishNode(typeContainer, "TypeAnnotation");
this.finishNode(id, id.type); this.finishNode(id, id.type);
@ -531,7 +571,7 @@ pp.reinterpretTypeAsFunctionTypeParam = function (type) {
pp.flowParseFunctionTypeParams = function (params = []) { pp.flowParseFunctionTypeParams = function (params = []) {
const ret = { params, rest: null }; const ret = { params, rest: null };
while (this.match(tt.name)) { while (!this.match(tt.parenR) && !this.match(tt.ellipsis)) {
ret.params.push(this.flowParseFunctionTypeParam()); ret.params.push(this.flowParseFunctionTypeParam());
if (!this.match(tt.parenR)) { if (!this.match(tt.parenR)) {
this.expect(tt.comma); this.expect(tt.comma);
@ -791,6 +831,12 @@ pp.flowParseTypeAnnotation = function () {
return this.finishNode(node, "TypeAnnotation"); return this.finishNode(node, "TypeAnnotation");
}; };
pp.flowParseTypeAndPredicateAnnotation = function () {
const node = this.startNode();
[node.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser();
return this.finishNode(node, "TypeAnnotation");
};
pp.flowParseTypeAnnotatableIdentifier = function () { pp.flowParseTypeAnnotatableIdentifier = function () {
const ident = this.flowParseRestrictedIdentifier(); const ident = this.flowParseRestrictedIdentifier();
if (this.match(tt.colon)) { if (this.match(tt.colon)) {
@ -833,7 +879,7 @@ export default function (instance) {
if (this.match(tt.colon) && !allowExpression) { if (this.match(tt.colon) && !allowExpression) {
// if allowExpression is true then we're parsing an arrow function and if // if allowExpression is true then we're parsing an arrow function and if
// there's a return type then it's been handled elsewhere // there's a return type then it's been handled elsewhere
node.returnType = this.flowParseTypeAnnotation(); node.returnType = this.flowParseTypeAndPredicateAnnotation();
} }
return inner.call(this, node, allowExpression); return inner.call(this, node, allowExpression);
@ -1045,9 +1091,9 @@ export default function (instance) {
// parse an item inside a expression list eg. `(NODE, NODE)` where NODE represents // parse an item inside a expression list eg. `(NODE, NODE)` where NODE represents
// the position where this function is called // the position where this function is called
instance.extend("parseExprListItem", function (inner) { instance.extend("parseExprListItem", function (inner) {
return function (allowEmpty, refShorthandDefaultPos) { return function (...args) {
const container = this.startNode(); const container = this.startNode();
const node = inner.call(this, allowEmpty, refShorthandDefaultPos); const node = inner.call(this, ...args);
if (this.match(tt.colon)) { if (this.match(tt.colon)) {
container._exprListItem = true; container._exprListItem = true;
container.expression = node; container.expression = node;
@ -1220,9 +1266,10 @@ export default function (instance) {
specifierTypeKind = "typeof"; specifierTypeKind = "typeof";
} }
let isBinding = false;
if (this.isContextual("as")) { if (this.isContextual("as")) {
const as_ident = this.parseIdentifier(true); const as_ident = this.parseIdentifier(true);
if (specifierTypeKind !== null && !this.match(tt.name)) { if (specifierTypeKind !== null && !this.match(tt.name) && !this.state.type.keyword) {
// `import {type as ,` or `import {type as }` // `import {type as ,` or `import {type as }`
specifier.imported = as_ident; specifier.imported = as_ident;
specifier.importKind = specifierTypeKind; specifier.importKind = specifierTypeKind;
@ -1231,23 +1278,20 @@ export default function (instance) {
// `import {type as foo` // `import {type as foo`
specifier.imported = firstIdent; specifier.imported = firstIdent;
specifier.importKind = null; specifier.importKind = null;
specifier.local = this.parseIdentifier(false); specifier.local = this.parseIdentifier();
} }
} else if (specifierTypeKind !== null && this.match(tt.name)) { } else if (specifierTypeKind !== null && (this.match(tt.name) || this.state.type.keyword)) {
// `import {type foo` // `import {type foo`
specifier.imported = this.parseIdentifier(true); specifier.imported = this.parseIdentifier(true);
specifier.importKind = specifierTypeKind; specifier.importKind = specifierTypeKind;
specifier.local = if (this.eatContextual("as")) {
this.eatContextual("as") specifier.local = this.parseIdentifier();
? this.parseIdentifier(false) } else {
: specifier.imported.__clone(); isBinding = true;
} else { specifier.local = specifier.imported.__clone();
if (firstIdent.name === "typeof") {
this.unexpected(
firstIdentLoc,
"Cannot import a variable named `typeof`"
);
} }
} else {
isBinding = true;
specifier.imported = firstIdent; specifier.imported = firstIdent;
specifier.importKind = null; specifier.importKind = null;
specifier.local = specifier.imported.__clone(); specifier.local = specifier.imported.__clone();
@ -1260,6 +1304,8 @@ export default function (instance) {
this.raise(firstIdentLoc, "`The `type` and `typeof` keywords on named imports can only be used on regular `import` statements. It cannot be used with `import type` or `import typeof` statements`"); this.raise(firstIdentLoc, "`The `type` and `typeof` keywords on named imports can only be used on regular `import` statements. It cannot be used with `import type` or `import typeof` statements`");
} }
if (isBinding) this.checkReservedWord(specifier.local.name, specifier.start, true, true);
this.checkLVal(specifier.local, true, undefined, "import specifier"); this.checkLVal(specifier.local, true, undefined, "import specifier");
node.specifiers.push(this.finishNode(specifier, "ImportSpecifier")); node.specifiers.push(this.finishNode(specifier, "ImportSpecifier"));
}; };
@ -1377,7 +1423,7 @@ export default function (instance) {
try { try {
const oldNoAnonFunctionType = this.state.noAnonFunctionType; const oldNoAnonFunctionType = this.state.noAnonFunctionType;
this.state.noAnonFunctionType = true; this.state.noAnonFunctionType = true;
const returnType = this.flowParseTypeAnnotation(); const returnType = this.flowParseTypeAndPredicateAnnotation();
this.state.noAnonFunctionType = oldNoAnonFunctionType; this.state.noAnonFunctionType = oldNoAnonFunctionType;
if (this.canInsertSemicolon()) this.unexpected(); if (this.canInsertSemicolon()) this.unexpected();

View File

@ -34,7 +34,7 @@ export default class State {
this.commentStack = []; this.commentStack = [];
this.pos = this.lineStart = 0; this.pos = this.lineStart = 0;
this.curLine = 1; this.curLine = options.startLine;
this.type = tt.eof; this.type = tt.eof;
this.value = null; this.value = null;

5
test/estree-throws.js Normal file
View File

@ -0,0 +1,5 @@
import path from "path";
import { runThrowTestsWithEstree } from "./utils/runFixtureTests";
import { parse } from "../lib";
runThrowTestsWithEstree(path.join(__dirname, "fixtures"), parse);

View File

@ -0,0 +1,2 @@
call(1);
run(2);

View File

@ -0,0 +1,459 @@
{
"type": "File",
"start": 0,
"end": 16,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 4,
"column": 7
}
},
"program": {
"type": "Program",
"start": 0,
"end": 16,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 4,
"column": 7
}
},
"sourceType": "script",
"body": [
{
"type": "ExpressionStatement",
"start": 0,
"end": 8,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 8
}
},
"expression": {
"type": "CallExpression",
"start": 0,
"end": 7,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 7
}
},
"callee": {
"type": "Identifier",
"start": 0,
"end": 4,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 4
},
"identifierName": "call"
},
"name": "call"
},
"arguments": [
{
"type": "NumericLiteral",
"start": 5,
"end": 6,
"loc": {
"start": {
"line": 3,
"column": 5
},
"end": {
"line": 3,
"column": 6
}
},
"extra": {
"rawValue": 1,
"raw": "1"
},
"value": 1
}
]
}
},
{
"type": "ExpressionStatement",
"start": 9,
"end": 16,
"loc": {
"start": {
"line": 4,
"column": 0
},
"end": {
"line": 4,
"column": 7
}
},
"expression": {
"type": "CallExpression",
"start": 9,
"end": 15,
"loc": {
"start": {
"line": 4,
"column": 0
},
"end": {
"line": 4,
"column": 6
}
},
"callee": {
"type": "Identifier",
"start": 9,
"end": 12,
"loc": {
"start": {
"line": 4,
"column": 0
},
"end": {
"line": 4,
"column": 3
},
"identifierName": "run"
},
"name": "run"
},
"arguments": [
{
"type": "NumericLiteral",
"start": 13,
"end": 14,
"loc": {
"start": {
"line": 4,
"column": 4
},
"end": {
"line": 4,
"column": 5
}
},
"extra": {
"rawValue": 2,
"raw": "2"
},
"value": 2
}
]
}
}
],
"directives": []
},
"comments": [],
"tokens": [
{
"type": {
"label": "name",
"beforeExpr": false,
"startsExpr": true,
"rightAssociative": false,
"isLoop": false,
"isAssign": false,
"prefix": false,
"postfix": false,
"binop": null
},
"value": "call",
"start": 0,
"end": 4,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 4
}
}
},
{
"type": {
"label": "(",
"beforeExpr": true,
"startsExpr": true,
"rightAssociative": false,
"isLoop": false,
"isAssign": false,
"prefix": false,
"postfix": false,
"binop": null
},
"start": 4,
"end": 5,
"loc": {
"start": {
"line": 3,
"column": 4
},
"end": {
"line": 3,
"column": 5
}
}
},
{
"type": {
"label": "num",
"beforeExpr": false,
"startsExpr": true,
"rightAssociative": false,
"isLoop": false,
"isAssign": false,
"prefix": false,
"postfix": false,
"binop": null,
"updateContext": null
},
"value": 1,
"start": 5,
"end": 6,
"loc": {
"start": {
"line": 3,
"column": 5
},
"end": {
"line": 3,
"column": 6
}
}
},
{
"type": {
"label": ")",
"beforeExpr": false,
"startsExpr": false,
"rightAssociative": false,
"isLoop": false,
"isAssign": false,
"prefix": false,
"postfix": false,
"binop": null
},
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 3,
"column": 6
},
"end": {
"line": 3,
"column": 7
}
}
},
{
"type": {
"label": ";",
"beforeExpr": true,
"startsExpr": false,
"rightAssociative": false,
"isLoop": false,
"isAssign": false,
"prefix": false,
"postfix": false,
"binop": null,
"updateContext": null
},
"start": 7,
"end": 8,
"loc": {
"start": {
"line": 3,
"column": 7
},
"end": {
"line": 3,
"column": 8
}
}
},
{
"type": {
"label": "name",
"beforeExpr": false,
"startsExpr": true,
"rightAssociative": false,
"isLoop": false,
"isAssign": false,
"prefix": false,
"postfix": false,
"binop": null
},
"value": "run",
"start": 9,
"end": 12,
"loc": {
"start": {
"line": 4,
"column": 0
},
"end": {
"line": 4,
"column": 3
}
}
},
{
"type": {
"label": "(",
"beforeExpr": true,
"startsExpr": true,
"rightAssociative": false,
"isLoop": false,
"isAssign": false,
"prefix": false,
"postfix": false,
"binop": null
},
"start": 12,
"end": 13,
"loc": {
"start": {
"line": 4,
"column": 3
},
"end": {
"line": 4,
"column": 4
}
}
},
{
"type": {
"label": "num",
"beforeExpr": false,
"startsExpr": true,
"rightAssociative": false,
"isLoop": false,
"isAssign": false,
"prefix": false,
"postfix": false,
"binop": null,
"updateContext": null
},
"value": 2,
"start": 13,
"end": 14,
"loc": {
"start": {
"line": 4,
"column": 4
},
"end": {
"line": 4,
"column": 5
}
}
},
{
"type": {
"label": ")",
"beforeExpr": false,
"startsExpr": false,
"rightAssociative": false,
"isLoop": false,
"isAssign": false,
"prefix": false,
"postfix": false,
"binop": null
},
"start": 14,
"end": 15,
"loc": {
"start": {
"line": 4,
"column": 5
},
"end": {
"line": 4,
"column": 6
}
}
},
{
"type": {
"label": ";",
"beforeExpr": true,
"startsExpr": false,
"rightAssociative": false,
"isLoop": false,
"isAssign": false,
"prefix": false,
"postfix": false,
"binop": null,
"updateContext": null
},
"start": 15,
"end": 16,
"loc": {
"start": {
"line": 4,
"column": 6
},
"end": {
"line": 4,
"column": 7
}
}
},
{
"type": {
"label": "eof",
"beforeExpr": false,
"startsExpr": false,
"rightAssociative": false,
"isLoop": false,
"isAssign": false,
"prefix": false,
"postfix": false,
"binop": null,
"updateContext": null
},
"start": 16,
"end": 16,
"loc": {
"start": {
"line": 4,
"column": 7
},
"end": {
"line": 4,
"column": 7
}
}
}
]
}

View File

@ -0,0 +1,3 @@
{
"startLine": 3
}

View File

@ -0,0 +1 @@
import { default } from "foo";

View File

@ -0,0 +1,4 @@
{
"plugins": ["flow"],
"throws": "default is a reserved word (1:9)"
}

View File

@ -0,0 +1 @@
import { typeof } from "foo";

View File

@ -0,0 +1,4 @@
{
"plugins": ["flow"],
"throws": "typeof is a reserved word (1:9)"
}

View File

@ -0,0 +1 @@
import { typeof } from "foo";

View File

@ -0,0 +1,3 @@
{
"throws": "typeof is a reserved word (1:9)"
}

View File

@ -0,0 +1 @@
import { debugger } from "foo";

View File

@ -0,0 +1,3 @@
{
"throws": "debugger is a reserved word (1:9)"
}

View File

@ -1,3 +1,3 @@
{ {
"throws": "Unexpected token (1:26)" "throws": "yield is a reserved word (1:26)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "Unexpected token (1:25)" "throws": "yield is a reserved word (1:25)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "Unexpected token (1:46)" "throws": "yield is a reserved word (1:46)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "Unexpected token (1:29)" "throws": "yield is a reserved word (1:29)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "Unexpected token (1:28)" "throws": "yield is a reserved word (1:28)"
} }

View File

@ -0,0 +1,3 @@
class A {
foo() {}
}

View File

@ -0,0 +1,154 @@
{
"type": "File",
"start": 0,
"end": 22,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"program": {
"type": "Program",
"start": 0,
"end": 22,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"sourceType": "script",
"body": [
{
"type": "ClassDeclaration",
"start": 0,
"end": 22,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "A"
},
"name": "A"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 8,
"end": 22,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 3,
"column": 1
}
},
"body": [
{
"type": "MethodDefinition",
"start": 12,
"end": 20,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 10
}
},
"computed": false,
"key": {
"type": "Identifier",
"start": 12,
"end": 15,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 5
},
"identifierName": "foo"
},
"name": "foo"
},
"static": false,
"kind": "method",
"value": {
"type": "FunctionExpression",
"start": 15,
"end": 20,
"loc": {
"start": {
"line": 2,
"column": 5
},
"end": {
"line": 2,
"column": 10
}
},
"id": null,
"generator": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start": 18,
"end": 20,
"loc": {
"start": {
"line": 2,
"column": 8
},
"end": {
"line": 2,
"column": 10
}
},
"body": []
},
"expression": false
}
}
]
}
}
]
}
}

View File

@ -0,0 +1,5 @@
function foo() {
"use strict";
var a = 1;
"use strict";
}

View File

@ -0,0 +1,218 @@
{
"type": "File",
"start": 0,
"end": 63,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 5,
"column": 1
}
},
"program": {
"type": "Program",
"start": 0,
"end": 63,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 5,
"column": 1
}
},
"sourceType": "script",
"body": [
{
"type": "FunctionDeclaration",
"start": 0,
"end": 63,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 5,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 9,
"end": 12,
"loc": {
"start": {
"line": 1,
"column": 9
},
"end": {
"line": 1,
"column": 12
},
"identifierName": "foo"
},
"name": "foo"
},
"generator": false,
"expression": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start": 15,
"end": 63,
"loc": {
"start": {
"line": 1,
"column": 15
},
"end": {
"line": 5,
"column": 1
}
},
"body": [
{
"type": "ExpressionStatement",
"start": 19,
"end": 32,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 15
}
},
"expression": {
"type": "Literal",
"start": 19,
"end": 31,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 14
}
},
"value": "use strict",
"raw": "\"use strict\""
},
"directive": "use strict"
},
{
"type": "VariableDeclaration",
"start": 35,
"end": 45,
"loc": {
"start": {
"line": 3,
"column": 2
},
"end": {
"line": 3,
"column": 12
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 39,
"end": 44,
"loc": {
"start": {
"line": 3,
"column": 6
},
"end": {
"line": 3,
"column": 11
}
},
"id": {
"type": "Identifier",
"start": 39,
"end": 40,
"loc": {
"start": {
"line": 3,
"column": 6
},
"end": {
"line": 3,
"column": 7
},
"identifierName": "a"
},
"name": "a"
},
"init": {
"type": "Literal",
"start": 43,
"end": 44,
"loc": {
"start": {
"line": 3,
"column": 10
},
"end": {
"line": 3,
"column": 11
}
},
"value": 1,
"raw": "1"
}
}
],
"kind": "var"
},
{
"type": "ExpressionStatement",
"start": 48,
"end": 61,
"loc": {
"start": {
"line": 4,
"column": 2
},
"end": {
"line": 4,
"column": 15
}
},
"expression": {
"type": "Literal",
"start": 48,
"end": 60,
"loc": {
"start": {
"line": 4,
"column": 2
},
"end": {
"line": 4,
"column": 14
}
},
"value": "use strict",
"raw": "\"use strict\""
}
}
]
}
}
]
}
}

View File

@ -0,0 +1,4 @@
function foo () {
"use smth"
1+1;
}

View File

@ -0,0 +1,184 @@
{
"type": "File",
"start": 0,
"end": 39,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 4,
"column": 1
}
},
"program": {
"type": "Program",
"start": 0,
"end": 39,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 4,
"column": 1
}
},
"sourceType": "script",
"body": [
{
"type": "FunctionDeclaration",
"start": 0,
"end": 39,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 4,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 9,
"end": 12,
"loc": {
"start": {
"line": 1,
"column": 9
},
"end": {
"line": 1,
"column": 12
},
"identifierName": "foo"
},
"name": "foo"
},
"generator": false,
"expression": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start": 16,
"end": 39,
"loc": {
"start": {
"line": 1,
"column": 16
},
"end": {
"line": 4,
"column": 1
}
},
"body": [
{
"type": "ExpressionStatement",
"start": 20,
"end": 30,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 12
}
},
"expression": {
"type": "Literal",
"start": 20,
"end": 30,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 12
}
},
"value": "use smth",
"raw": "\"use smth\""
},
"directive": "use smth"
},
{
"type": "ExpressionStatement",
"start": 33,
"end": 37,
"loc": {
"start": {
"line": 3,
"column": 2
},
"end": {
"line": 3,
"column": 6
}
},
"expression": {
"type": "BinaryExpression",
"start": 33,
"end": 36,
"loc": {
"start": {
"line": 3,
"column": 2
},
"end": {
"line": 3,
"column": 5
}
},
"left": {
"type": "Literal",
"start": 33,
"end": 34,
"loc": {
"start": {
"line": 3,
"column": 2
},
"end": {
"line": 3,
"column": 3
}
},
"value": 1,
"raw": "1"
},
"operator": "+",
"right": {
"type": "Literal",
"start": 35,
"end": 36,
"loc": {
"start": {
"line": 3,
"column": 4
},
"end": {
"line": 3,
"column": 5
}
},
"value": 1,
"raw": "1"
}
}
}
]
}
}
]
}
}

View File

@ -0,0 +1,3 @@
"use strict";
var a = 1;
"use strict";

View File

@ -0,0 +1,165 @@
{
"type": "File",
"start": 0,
"end": 38,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 13
}
},
"program": {
"type": "Program",
"start": 0,
"end": 38,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 13
}
},
"sourceType": "script",
"body": [
{
"type": "ExpressionStatement",
"start": 0,
"end": 13,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 13
}
},
"expression": {
"type": "Literal",
"start": 0,
"end": 12,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 12
}
},
"value": "use strict",
"raw": "\"use strict\""
},
"directive": "use strict"
},
{
"type": "VariableDeclaration",
"start": 14,
"end": 24,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 10
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 18,
"end": 23,
"loc": {
"start": {
"line": 2,
"column": 4
},
"end": {
"line": 2,
"column": 9
}
},
"id": {
"type": "Identifier",
"start": 18,
"end": 19,
"loc": {
"start": {
"line": 2,
"column": 4
},
"end": {
"line": 2,
"column": 5
},
"identifierName": "a"
},
"name": "a"
},
"init": {
"type": "Literal",
"start": 22,
"end": 23,
"loc": {
"start": {
"line": 2,
"column": 8
},
"end": {
"line": 2,
"column": 9
}
},
"value": 1,
"raw": "1"
}
}
],
"kind": "var"
},
{
"type": "ExpressionStatement",
"start": 25,
"end": 38,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 13
}
},
"expression": {
"type": "Literal",
"start": 25,
"end": 37,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 12
}
},
"value": "use strict",
"raw": "\"use strict\""
}
}
]
}
}

View File

@ -0,0 +1 @@
"use\x20strict";

View File

@ -0,0 +1,66 @@
{
"type": "File",
"start": 0,
"end": 16,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 16
}
},
"program": {
"type": "Program",
"start": 0,
"end": 16,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 16
}
},
"sourceType": "script",
"body": [
{
"type": "ExpressionStatement",
"start": 0,
"end": 16,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 16
}
},
"expression": {
"type": "Literal",
"start": 0,
"end": 15,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 15
}
},
"value": "use\\x20strict",
"raw": "\"use\\x20strict\""
},
"directive": "use\\x20strict"
}
]
}
}

View File

@ -0,0 +1,2 @@
var a = true;
var b = false;

View File

@ -0,0 +1,167 @@
{
"type": "File",
"start": 0,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 14
}
},
"program": {
"type": "Program",
"start": 0,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 14
}
},
"sourceType": "script",
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 13,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 13
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 4,
"end": 12,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 12
}
},
"id": {
"type": "Identifier",
"start": 4,
"end": 5,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 5
},
"identifierName": "a"
},
"name": "a"
},
"init": {
"type": "Literal",
"start": 8,
"end": 12,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 1,
"column": 12
}
},
"value": true,
"raw": "true"
}
}
],
"kind": "var"
},
{
"type": "VariableDeclaration",
"start": 14,
"end": 28,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 14
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 18,
"end": 27,
"loc": {
"start": {
"line": 2,
"column": 4
},
"end": {
"line": 2,
"column": 13
}
},
"id": {
"type": "Identifier",
"start": 18,
"end": 19,
"loc": {
"start": {
"line": 2,
"column": 4
},
"end": {
"line": 2,
"column": 5
},
"identifierName": "b"
},
"name": "b"
},
"init": {
"type": "Literal",
"start": 22,
"end": 27,
"loc": {
"start": {
"line": 2,
"column": 8
},
"end": {
"line": 2,
"column": 13
}
},
"value": false,
"raw": "false"
}
}
],
"kind": "var"
}
]
}
}

View File

@ -0,0 +1 @@
var a = null;

View File

@ -0,0 +1,100 @@
{
"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": "script",
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 13,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 13
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 4,
"end": 12,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 12
}
},
"id": {
"type": "Identifier",
"start": 4,
"end": 5,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 5
},
"identifierName": "a"
},
"name": "a"
},
"init": {
"type": "Literal",
"start": 8,
"end": 12,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 1,
"column": 12
}
},
"value": null,
"raw": "null"
}
}
],
"kind": "var"
}
]
}
}

View File

@ -0,0 +1 @@
var a = 1;

View File

@ -0,0 +1,100 @@
{
"type": "File",
"start": 0,
"end": 10,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 10
}
},
"program": {
"type": "Program",
"start": 0,
"end": 10,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 10
}
},
"sourceType": "script",
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 10,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 10
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 4,
"end": 9,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 9
}
},
"id": {
"type": "Identifier",
"start": 4,
"end": 5,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 5
},
"identifierName": "a"
},
"name": "a"
},
"init": {
"type": "Literal",
"start": 8,
"end": 9,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 1,
"column": 9
}
},
"value": 1,
"raw": "1"
}
}
],
"kind": "var"
}
]
}
}

View File

@ -0,0 +1 @@
var a = /.*/i;

View File

@ -0,0 +1,104 @@
{
"type": "File",
"start": 0,
"end": 14,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 14
}
},
"program": {
"type": "Program",
"start": 0,
"end": 14,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 14
}
},
"sourceType": "script",
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 14,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 14
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 4,
"end": 13,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 13
}
},
"id": {
"type": "Identifier",
"start": 4,
"end": 5,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 5
},
"identifierName": "a"
},
"name": "a"
},
"init": {
"type": "Literal",
"start": 8,
"end": 13,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 1,
"column": 13
}
},
"value": "/.*/i",
"raw": "/.*/i",
"regex": {
"pattern": ".*",
"flags": "i"
}
}
}
],
"kind": "var"
}
]
}
}

View File

@ -0,0 +1 @@
var a = "string";

View File

@ -0,0 +1,100 @@
{
"type": "File",
"start": 0,
"end": 17,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 17
}
},
"program": {
"type": "Program",
"start": 0,
"end": 17,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 17
}
},
"sourceType": "script",
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 17,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 17
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 4,
"end": 16,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 16
}
},
"id": {
"type": "Identifier",
"start": 4,
"end": 5,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 5
},
"identifierName": "a"
},
"name": "a"
},
"init": {
"type": "Literal",
"start": 8,
"end": 16,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 1,
"column": 16
}
},
"value": "string",
"raw": "\"string\""
}
}
],
"kind": "var"
}
]
}
}

View File

@ -0,0 +1,3 @@
var bar = {
foo() {}
};

View File

@ -0,0 +1,172 @@
{
"type": "File",
"start": 0,
"end": 25,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 2
}
},
"program": {
"type": "Program",
"start": 0,
"end": 25,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 2
}
},
"sourceType": "script",
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 25,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 2
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 4,
"end": 24,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 4,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "bar"
},
"name": "bar"
},
"init": {
"type": "ObjectExpression",
"start": 10,
"end": 24,
"loc": {
"start": {
"line": 1,
"column": 10
},
"end": {
"line": 3,
"column": 1
}
},
"properties": [
{
"type": "Property",
"start": 14,
"end": 22,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 10
}
},
"method": true,
"shorthand": false,
"computed": false,
"key": {
"type": "Identifier",
"start": 14,
"end": 17,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 5
},
"identifierName": "foo"
},
"name": "foo"
},
"kind": "init",
"value": {
"type": "FunctionExpression",
"start": 17,
"end": 22,
"loc": {
"start": {
"line": 2,
"column": 5
},
"end": {
"line": 2,
"column": 10
}
},
"id": null,
"generator": false,
"expression": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start": 20,
"end": 22,
"loc": {
"start": {
"line": 2,
"column": 8
},
"end": {
"line": 2,
"column": 10
}
},
"body": []
}
}
}
]
}
}
],
"kind": "var"
}
]
}
}

View File

@ -0,0 +1 @@
const a = { foo: 1 };

View File

@ -0,0 +1,153 @@
{
"type": "File",
"start": 0,
"end": 21,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 21
}
},
"program": {
"type": "Program",
"start": 0,
"end": 21,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 21
}
},
"sourceType": "script",
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 21,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 21
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 6,
"end": 20,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 20
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "a"
},
"name": "a"
},
"init": {
"type": "ObjectExpression",
"start": 10,
"end": 20,
"loc": {
"start": {
"line": 1,
"column": 10
},
"end": {
"line": 1,
"column": 20
}
},
"properties": [
{
"type": "Property",
"start": 12,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 12
},
"end": {
"line": 1,
"column": 18
}
},
"method": false,
"shorthand": false,
"computed": false,
"key": {
"type": "Identifier",
"start": 12,
"end": 15,
"loc": {
"start": {
"line": 1,
"column": 12
},
"end": {
"line": 1,
"column": 15
},
"identifierName": "foo"
},
"name": "foo"
},
"value": {
"type": "Literal",
"start": 17,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 17
},
"end": {
"line": 1,
"column": 18
}
},
"value": 1,
"raw": "1"
},
"kind": "init"
}
]
}
}
],
"kind": "const"
}
]
}
}

3
test/fixtures/estree/options.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"plugins": ["flow", "jsx", "estree"]
}

View File

@ -0,0 +1 @@
var {...{z}} = { z: 1};

View File

@ -0,0 +1,243 @@
{
"type": "File",
"start": 0,
"end": 23,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 23
}
},
"program": {
"type": "Program",
"start": 0,
"end": 23,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 23
}
},
"sourceType": "script",
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 23,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 23
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 4,
"end": 22,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 22
}
},
"id": {
"type": "ObjectPattern",
"start": 4,
"end": 12,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 12
}
},
"properties": [
{
"type": "RestProperty",
"start": 5,
"end": 11,
"loc": {
"start": {
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 11
}
},
"argument": {
"type": "ObjectPattern",
"start": 8,
"end": 11,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 1,
"column": 11
}
},
"properties": [
{
"type": "ObjectProperty",
"start": 9,
"end": 10,
"loc": {
"start": {
"line": 1,
"column": 9
},
"end": {
"line": 1,
"column": 10
}
},
"method": false,
"shorthand": true,
"computed": false,
"key": {
"type": "Identifier",
"start": 9,
"end": 10,
"loc": {
"start": {
"line": 1,
"column": 9
},
"end": {
"line": 1,
"column": 10
},
"identifierName": "z"
},
"name": "z"
},
"value": {
"type": "Identifier",
"start": 9,
"end": 10,
"loc": {
"start": {
"line": 1,
"column": 9
},
"end": {
"line": 1,
"column": 10
},
"identifierName": "z"
},
"name": "z"
},
"extra": {
"shorthand": true
}
}
]
}
}
]
},
"init": {
"type": "ObjectExpression",
"start": 15,
"end": 22,
"loc": {
"start": {
"line": 1,
"column": 15
},
"end": {
"line": 1,
"column": 22
}
},
"properties": [
{
"type": "ObjectProperty",
"start": 17,
"end": 21,
"loc": {
"start": {
"line": 1,
"column": 17
},
"end": {
"line": 1,
"column": 21
}
},
"method": false,
"shorthand": false,
"computed": false,
"key": {
"type": "Identifier",
"start": 17,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 17
},
"end": {
"line": 1,
"column": 18
},
"identifierName": "z"
},
"name": "z"
},
"value": {
"type": "NumericLiteral",
"start": 20,
"end": 21,
"loc": {
"start": {
"line": 1,
"column": 20
},
"end": {
"line": 1,
"column": 21
}
},
"extra": {
"rawValue": 1,
"raw": "1"
},
"value": 1
}
}
]
}
}
],
"kind": "var"
}
],
"directives": []
}
}

View File

@ -0,0 +1 @@
var { ...{ x = 5 } } = {x : 1};

View File

@ -0,0 +1,278 @@
{
"type": "File",
"start": 0,
"end": 31,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 31
}
},
"program": {
"type": "Program",
"start": 0,
"end": 31,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 31
}
},
"sourceType": "script",
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 31,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 31
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 4,
"end": 30,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 30
}
},
"id": {
"type": "ObjectPattern",
"start": 4,
"end": 20,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 20
}
},
"properties": [
{
"type": "RestProperty",
"start": 6,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 18
}
},
"argument": {
"type": "ObjectPattern",
"start": 9,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 9
},
"end": {
"line": 1,
"column": 18
}
},
"properties": [
{
"type": "ObjectProperty",
"start": 11,
"end": 16,
"loc": {
"start": {
"line": 1,
"column": 11
},
"end": {
"line": 1,
"column": 16
}
},
"method": false,
"shorthand": true,
"computed": false,
"key": {
"type": "Identifier",
"start": 11,
"end": 12,
"loc": {
"start": {
"line": 1,
"column": 11
},
"end": {
"line": 1,
"column": 12
},
"identifierName": "x"
},
"name": "x"
},
"value": {
"type": "AssignmentPattern",
"start": 11,
"end": 16,
"loc": {
"start": {
"line": 1,
"column": 11
},
"end": {
"line": 1,
"column": 16
}
},
"left": {
"type": "Identifier",
"start": 11,
"end": 12,
"loc": {
"start": {
"line": 1,
"column": 11
},
"end": {
"line": 1,
"column": 12
},
"identifierName": "x"
},
"name": "x"
},
"right": {
"type": "NumericLiteral",
"start": 15,
"end": 16,
"loc": {
"start": {
"line": 1,
"column": 15
},
"end": {
"line": 1,
"column": 16
}
},
"extra": {
"rawValue": 5,
"raw": "5"
},
"value": 5
}
},
"extra": {
"shorthand": true
}
}
]
}
}
]
},
"init": {
"type": "ObjectExpression",
"start": 23,
"end": 30,
"loc": {
"start": {
"line": 1,
"column": 23
},
"end": {
"line": 1,
"column": 30
}
},
"properties": [
{
"type": "ObjectProperty",
"start": 24,
"end": 29,
"loc": {
"start": {
"line": 1,
"column": 24
},
"end": {
"line": 1,
"column": 29
}
},
"method": false,
"shorthand": false,
"computed": false,
"key": {
"type": "Identifier",
"start": 24,
"end": 25,
"loc": {
"start": {
"line": 1,
"column": 24
},
"end": {
"line": 1,
"column": 25
},
"identifierName": "x"
},
"name": "x"
},
"value": {
"type": "NumericLiteral",
"start": 28,
"end": 29,
"loc": {
"start": {
"line": 1,
"column": 28
},
"end": {
"line": 1,
"column": 29
}
},
"extra": {
"rawValue": 1,
"raw": "1"
},
"value": 1
}
}
]
}
}
],
"kind": "var"
}
],
"directives": []
}
}

View File

@ -0,0 +1 @@
declare function foo(x: mixed): boolean %checks(x !== null);

View File

@ -0,0 +1,226 @@
{
"type": "File",
"start": 0,
"end": 60,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 60
}
},
"program": {
"type": "Program",
"start": 0,
"end": 60,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 60
}
},
"sourceType": "module",
"body": [
{
"type": "DeclareFunction",
"start": 0,
"end": 60,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 60
}
},
"id": {
"type": "Identifier",
"start": 17,
"end": 59,
"loc": {
"start": {
"line": 1,
"column": 17
},
"end": {
"line": 1,
"column": 59
},
"identifierName": "foo"
},
"name": "foo",
"typeAnnotation": {
"type": "TypeAnnotation",
"start": 20,
"end": 59,
"loc": {
"start": {
"line": 1,
"column": 20
},
"end": {
"line": 1,
"column": 59
}
},
"typeAnnotation": {
"type": "FunctionTypeAnnotation",
"start": 20,
"end": 59,
"loc": {
"start": {
"line": 1,
"column": 20
},
"end": {
"line": 1,
"column": 59
}
},
"typeParameters": null,
"params": [
{
"type": "FunctionTypeParam",
"start": 21,
"end": 29,
"loc": {
"start": {
"line": 1,
"column": 21
},
"end": {
"line": 1,
"column": 29
}
},
"name": {
"type": "Identifier",
"start": 21,
"end": 22,
"loc": {
"start": {
"line": 1,
"column": 21
},
"end": {
"line": 1,
"column": 22
},
"identifierName": "x"
},
"name": "x"
},
"optional": false,
"typeAnnotation": {
"type": "MixedTypeAnnotation",
"start": 24,
"end": 29,
"loc": {
"start": {
"line": 1,
"column": 24
},
"end": {
"line": 1,
"column": 29
}
}
}
}
],
"rest": null,
"returnType": {
"type": "BooleanTypeAnnotation",
"start": 32,
"end": 39,
"loc": {
"start": {
"line": 1,
"column": 32
},
"end": {
"line": 1,
"column": 39
}
}
}
},
"predicate": {
"type": "DeclaredPredicate",
"start": 40,
"end": 59,
"loc": {
"start": {
"line": 1,
"column": 40
},
"end": {
"line": 1,
"column": 59
}
},
"expression": {
"type": "BinaryExpression",
"start": 48,
"end": 58,
"loc": {
"start": {
"line": 1,
"column": 48
},
"end": {
"line": 1,
"column": 58
}
},
"left": {
"type": "Identifier",
"start": 48,
"end": 49,
"loc": {
"start": {
"line": 1,
"column": 48
},
"end": {
"line": 1,
"column": 49
},
"identifierName": "x"
},
"name": "x"
},
"operator": "!==",
"right": {
"type": "NullLiteral",
"start": 54,
"end": 58,
"loc": {
"start": {
"line": 1,
"column": 54
},
"end": {
"line": 1,
"column": 58
}
}
}
}
}
}
}
}
],
"directives": []
}
}

View File

@ -0,0 +1 @@
var f = (x: mixed): %checks => typeof x === "string";

View File

@ -0,0 +1,256 @@
{
"type": "File",
"start": 0,
"end": 53,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 53
}
},
"program": {
"type": "Program",
"start": 0,
"end": 53,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 53
}
},
"sourceType": "module",
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 53,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 53
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 4,
"end": 52,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 52
}
},
"id": {
"type": "Identifier",
"start": 4,
"end": 5,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 5
},
"identifierName": "f"
},
"name": "f"
},
"init": {
"type": "ArrowFunctionExpression",
"start": 8,
"end": 52,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 1,
"column": 52
}
},
"returnType": {
"type": "TypeAnnotation",
"start": 18,
"end": 27,
"loc": {
"start": {
"line": 1,
"column": 18
},
"end": {
"line": 1,
"column": 27
}
},
"typeAnnotation": null,
"predicate": {
"type": "InferredPredicate",
"start": 20,
"end": 27,
"loc": {
"start": {
"line": 1,
"column": 20
},
"end": {
"line": 1,
"column": 27
}
}
}
},
"id": null,
"generator": false,
"expression": true,
"async": false,
"params": [
{
"type": "Identifier",
"start": 9,
"end": 17,
"loc": {
"start": {
"line": 1,
"column": 9
},
"end": {
"line": 1,
"column": 17
},
"identifierName": "x"
},
"name": "x",
"typeAnnotation": {
"type": "TypeAnnotation",
"start": 10,
"end": 17,
"loc": {
"start": {
"line": 1,
"column": 10
},
"end": {
"line": 1,
"column": 17
}
},
"typeAnnotation": {
"type": "MixedTypeAnnotation",
"start": 12,
"end": 17,
"loc": {
"start": {
"line": 1,
"column": 12
},
"end": {
"line": 1,
"column": 17
}
}
}
}
}
],
"body": {
"type": "BinaryExpression",
"start": 31,
"end": 52,
"loc": {
"start": {
"line": 1,
"column": 31
},
"end": {
"line": 1,
"column": 52
}
},
"left": {
"type": "UnaryExpression",
"start": 31,
"end": 39,
"loc": {
"start": {
"line": 1,
"column": 31
},
"end": {
"line": 1,
"column": 39
}
},
"operator": "typeof",
"prefix": true,
"argument": {
"type": "Identifier",
"start": 38,
"end": 39,
"loc": {
"start": {
"line": 1,
"column": 38
},
"end": {
"line": 1,
"column": 39
},
"identifierName": "x"
},
"name": "x"
},
"extra": {
"parenthesizedArgument": false
}
},
"operator": "===",
"right": {
"type": "StringLiteral",
"start": 44,
"end": 52,
"loc": {
"start": {
"line": 1,
"column": 44
},
"end": {
"line": 1,
"column": 52
}
},
"extra": {
"rawValue": "string",
"raw": "\"string\""
},
"value": "string"
}
}
}
}
],
"kind": "var"
}
],
"directives": []
}
}

View File

@ -0,0 +1 @@
function foo(x: mixed): %checks { return typeof x === "string"; };

View File

@ -0,0 +1,270 @@
{
"type": "File",
"start": 0,
"end": 66,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 66
}
},
"program": {
"type": "Program",
"start": 0,
"end": 66,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 66
}
},
"sourceType": "module",
"body": [
{
"type": "FunctionDeclaration",
"start": 0,
"end": 65,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 65
}
},
"id": {
"type": "Identifier",
"start": 9,
"end": 12,
"loc": {
"start": {
"line": 1,
"column": 9
},
"end": {
"line": 1,
"column": 12
},
"identifierName": "foo"
},
"name": "foo"
},
"generator": false,
"expression": false,
"async": false,
"params": [
{
"type": "Identifier",
"start": 13,
"end": 21,
"loc": {
"start": {
"line": 1,
"column": 13
},
"end": {
"line": 1,
"column": 21
},
"identifierName": "x"
},
"name": "x",
"typeAnnotation": {
"type": "TypeAnnotation",
"start": 14,
"end": 21,
"loc": {
"start": {
"line": 1,
"column": 14
},
"end": {
"line": 1,
"column": 21
}
},
"typeAnnotation": {
"type": "MixedTypeAnnotation",
"start": 16,
"end": 21,
"loc": {
"start": {
"line": 1,
"column": 16
},
"end": {
"line": 1,
"column": 21
}
}
}
}
}
],
"returnType": {
"type": "TypeAnnotation",
"start": 22,
"end": 31,
"loc": {
"start": {
"line": 1,
"column": 22
},
"end": {
"line": 1,
"column": 31
}
},
"typeAnnotation": null,
"predicate": {
"type": "InferredPredicate",
"start": 24,
"end": 31,
"loc": {
"start": {
"line": 1,
"column": 24
},
"end": {
"line": 1,
"column": 31
}
}
}
},
"body": {
"type": "BlockStatement",
"start": 32,
"end": 65,
"loc": {
"start": {
"line": 1,
"column": 32
},
"end": {
"line": 1,
"column": 65
}
},
"body": [
{
"type": "ReturnStatement",
"start": 34,
"end": 63,
"loc": {
"start": {
"line": 1,
"column": 34
},
"end": {
"line": 1,
"column": 63
}
},
"argument": {
"type": "BinaryExpression",
"start": 41,
"end": 62,
"loc": {
"start": {
"line": 1,
"column": 41
},
"end": {
"line": 1,
"column": 62
}
},
"left": {
"type": "UnaryExpression",
"start": 41,
"end": 49,
"loc": {
"start": {
"line": 1,
"column": 41
},
"end": {
"line": 1,
"column": 49
}
},
"operator": "typeof",
"prefix": true,
"argument": {
"type": "Identifier",
"start": 48,
"end": 49,
"loc": {
"start": {
"line": 1,
"column": 48
},
"end": {
"line": 1,
"column": 49
},
"identifierName": "x"
},
"name": "x"
},
"extra": {
"parenthesizedArgument": false
}
},
"operator": "===",
"right": {
"type": "StringLiteral",
"start": 54,
"end": 62,
"loc": {
"start": {
"line": 1,
"column": 54
},
"end": {
"line": 1,
"column": 62
}
},
"extra": {
"rawValue": "string",
"raw": "\"string\""
},
"value": "string"
}
}
}
],
"directives": []
}
},
{
"type": "EmptyStatement",
"start": 65,
"end": 66,
"loc": {
"start": {
"line": 1,
"column": 65
},
"end": {
"line": 1,
"column": 66
}
}
}
],
"directives": []
}
}

View File

@ -0,0 +1 @@
var f = (x: mixed): % checks => typeof x === "string";

View File

@ -0,0 +1,3 @@
{
"throws": "Unexpected token, expected ; (1:18)"
}

View File

@ -0,0 +1,3 @@
function foo(x): % checks {
return typeof x === "string";
}

View File

@ -0,0 +1,3 @@
{
"throws": "Spaces between ´%´ and ´checks´ are not allowed here. (1:17)"
}

View File

@ -0,0 +1 @@
declare function my_filter<T, P: $Pred<1>>(v: Array<T>, cb: P): Array<$Refine<T,P,1>>;

View File

@ -0,0 +1,599 @@
{
"type": "File",
"start": 0,
"end": 86,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 86
}
},
"program": {
"type": "Program",
"start": 0,
"end": 86,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 86
}
},
"sourceType": "module",
"body": [
{
"type": "DeclareFunction",
"start": 0,
"end": 86,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 86
}
},
"id": {
"type": "Identifier",
"start": 17,
"end": 85,
"loc": {
"start": {
"line": 1,
"column": 17
},
"end": {
"line": 1,
"column": 85
},
"identifierName": "my_filter"
},
"name": "my_filter",
"typeAnnotation": {
"type": "TypeAnnotation",
"start": 26,
"end": 85,
"loc": {
"start": {
"line": 1,
"column": 26
},
"end": {
"line": 1,
"column": 85
}
},
"typeAnnotation": {
"type": "FunctionTypeAnnotation",
"start": 26,
"end": 85,
"loc": {
"start": {
"line": 1,
"column": 26
},
"end": {
"line": 1,
"column": 85
}
},
"typeParameters": {
"type": "TypeParameterDeclaration",
"start": 26,
"end": 42,
"loc": {
"start": {
"line": 1,
"column": 26
},
"end": {
"line": 1,
"column": 42
}
},
"params": [
{
"type": "TypeParameter",
"start": 27,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 27
},
"end": {
"line": 1,
"column": 28
}
},
"name": "T",
"variance": null
},
{
"type": "TypeParameter",
"start": 30,
"end": 41,
"loc": {
"start": {
"line": 1,
"column": 30
},
"end": {
"line": 1,
"column": 41
}
},
"name": "P",
"variance": null,
"bound": {
"type": "TypeAnnotation",
"start": 31,
"end": 41,
"loc": {
"start": {
"line": 1,
"column": 31
},
"end": {
"line": 1,
"column": 41
}
},
"typeAnnotation": {
"type": "GenericTypeAnnotation",
"start": 33,
"end": 41,
"loc": {
"start": {
"line": 1,
"column": 33
},
"end": {
"line": 1,
"column": 41
}
},
"typeParameters": {
"type": "TypeParameterInstantiation",
"start": 38,
"end": 41,
"loc": {
"start": {
"line": 1,
"column": 38
},
"end": {
"line": 1,
"column": 41
}
},
"params": [
{
"type": "NumericLiteralTypeAnnotation",
"start": 39,
"end": 40,
"loc": {
"start": {
"line": 1,
"column": 39
},
"end": {
"line": 1,
"column": 40
}
},
"value": 1,
"extra": {
"rawValue": 1,
"raw": "1"
}
}
]
},
"id": {
"type": "Identifier",
"start": 33,
"end": 38,
"loc": {
"start": {
"line": 1,
"column": 33
},
"end": {
"line": 1,
"column": 38
},
"identifierName": "$Pred"
},
"name": "$Pred"
}
}
}
}
]
},
"params": [
{
"type": "FunctionTypeParam",
"start": 43,
"end": 54,
"loc": {
"start": {
"line": 1,
"column": 43
},
"end": {
"line": 1,
"column": 54
}
},
"name": {
"type": "Identifier",
"start": 43,
"end": 44,
"loc": {
"start": {
"line": 1,
"column": 43
},
"end": {
"line": 1,
"column": 44
},
"identifierName": "v"
},
"name": "v"
},
"optional": false,
"typeAnnotation": {
"type": "GenericTypeAnnotation",
"start": 46,
"end": 54,
"loc": {
"start": {
"line": 1,
"column": 46
},
"end": {
"line": 1,
"column": 54
}
},
"typeParameters": {
"type": "TypeParameterInstantiation",
"start": 51,
"end": 54,
"loc": {
"start": {
"line": 1,
"column": 51
},
"end": {
"line": 1,
"column": 54
}
},
"params": [
{
"type": "GenericTypeAnnotation",
"start": 52,
"end": 53,
"loc": {
"start": {
"line": 1,
"column": 52
},
"end": {
"line": 1,
"column": 53
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 52,
"end": 53,
"loc": {
"start": {
"line": 1,
"column": 52
},
"end": {
"line": 1,
"column": 53
},
"identifierName": "T"
},
"name": "T"
}
}
]
},
"id": {
"type": "Identifier",
"start": 46,
"end": 51,
"loc": {
"start": {
"line": 1,
"column": 46
},
"end": {
"line": 1,
"column": 51
},
"identifierName": "Array"
},
"name": "Array"
}
}
},
{
"type": "FunctionTypeParam",
"start": 56,
"end": 61,
"loc": {
"start": {
"line": 1,
"column": 56
},
"end": {
"line": 1,
"column": 61
}
},
"name": {
"type": "Identifier",
"start": 56,
"end": 58,
"loc": {
"start": {
"line": 1,
"column": 56
},
"end": {
"line": 1,
"column": 58
},
"identifierName": "cb"
},
"name": "cb"
},
"optional": false,
"typeAnnotation": {
"type": "GenericTypeAnnotation",
"start": 60,
"end": 61,
"loc": {
"start": {
"line": 1,
"column": 60
},
"end": {
"line": 1,
"column": 61
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 60,
"end": 61,
"loc": {
"start": {
"line": 1,
"column": 60
},
"end": {
"line": 1,
"column": 61
},
"identifierName": "P"
},
"name": "P"
}
}
}
],
"rest": null,
"returnType": {
"type": "GenericTypeAnnotation",
"start": 64,
"end": 85,
"loc": {
"start": {
"line": 1,
"column": 64
},
"end": {
"line": 1,
"column": 85
}
},
"typeParameters": {
"type": "TypeParameterInstantiation",
"start": 69,
"end": 85,
"loc": {
"start": {
"line": 1,
"column": 69
},
"end": {
"line": 1,
"column": 85
}
},
"params": [
{
"type": "GenericTypeAnnotation",
"start": 70,
"end": 84,
"loc": {
"start": {
"line": 1,
"column": 70
},
"end": {
"line": 1,
"column": 84
}
},
"typeParameters": {
"type": "TypeParameterInstantiation",
"start": 77,
"end": 84,
"loc": {
"start": {
"line": 1,
"column": 77
},
"end": {
"line": 1,
"column": 84
}
},
"params": [
{
"type": "GenericTypeAnnotation",
"start": 78,
"end": 79,
"loc": {
"start": {
"line": 1,
"column": 78
},
"end": {
"line": 1,
"column": 79
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 78,
"end": 79,
"loc": {
"start": {
"line": 1,
"column": 78
},
"end": {
"line": 1,
"column": 79
},
"identifierName": "T"
},
"name": "T"
}
},
{
"type": "GenericTypeAnnotation",
"start": 80,
"end": 81,
"loc": {
"start": {
"line": 1,
"column": 80
},
"end": {
"line": 1,
"column": 81
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 80,
"end": 81,
"loc": {
"start": {
"line": 1,
"column": 80
},
"end": {
"line": 1,
"column": 81
},
"identifierName": "P"
},
"name": "P"
}
},
{
"type": "NumericLiteralTypeAnnotation",
"start": 82,
"end": 83,
"loc": {
"start": {
"line": 1,
"column": 82
},
"end": {
"line": 1,
"column": 83
}
},
"value": 1,
"extra": {
"rawValue": 1,
"raw": "1"
}
}
]
},
"id": {
"type": "Identifier",
"start": 70,
"end": 77,
"loc": {
"start": {
"line": 1,
"column": 70
},
"end": {
"line": 1,
"column": 77
},
"identifierName": "$Refine"
},
"name": "$Refine"
}
}
]
},
"id": {
"type": "Identifier",
"start": 64,
"end": 69,
"loc": {
"start": {
"line": 1,
"column": 64
},
"end": {
"line": 1,
"column": 69
},
"identifierName": "Array"
},
"name": "Array"
}
}
}
}
}
}
],
"directives": []
}
}

View File

@ -0,0 +1 @@
const fn: ( Object, Object Object ) => void = ( o1, o2, ) => o1;

View File

@ -0,0 +1,3 @@
{
"throws": "Unexpected token, expected , (1:27)"
}

View File

@ -0,0 +1,2 @@
const fn: ( Object, ?Object ) => void = ( o1, o2 ) => o1;
const fn: ( Object, ?Object, ) => void = ( o1, o2, ) => o1;

View File

@ -0,0 +1,618 @@
{
"type": "File",
"start": 0,
"end": 117,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 59
}
},
"program": {
"type": "Program",
"start": 0,
"end": 117,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 59
}
},
"sourceType": "module",
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 57,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 57
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 6,
"end": 56,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 56
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 37,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 37
},
"identifierName": "fn"
},
"name": "fn",
"typeAnnotation": {
"type": "TypeAnnotation",
"start": 8,
"end": 37,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 1,
"column": 37
}
},
"typeAnnotation": {
"type": "FunctionTypeAnnotation",
"start": 10,
"end": 37,
"loc": {
"start": {
"line": 1,
"column": 10
},
"end": {
"line": 1,
"column": 37
}
},
"params": [
{
"type": "FunctionTypeParam",
"start": 12,
"end": 19,
"loc": {
"start": {
"start": {
"line": 1,
"column": 12
},
"end": {
"line": 1,
"column": 18
}
},
"end": {
"line": 1,
"column": 19
}
},
"name": null,
"optional": false,
"typeAnnotation": {
"type": "GenericTypeAnnotation",
"start": 12,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 12
},
"end": {
"line": 1,
"column": 18
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 12,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 12
},
"end": {
"line": 1,
"column": 18
},
"identifierName": "Object"
},
"name": "Object"
}
}
},
{
"type": "FunctionTypeParam",
"start": 20,
"end": 27,
"loc": {
"start": {
"line": 1,
"column": 20
},
"end": {
"line": 1,
"column": 27
}
},
"name": null,
"optional": false,
"typeAnnotation": {
"type": "NullableTypeAnnotation",
"start": 20,
"end": 27,
"loc": {
"start": {
"line": 1,
"column": 20
},
"end": {
"line": 1,
"column": 27
}
},
"typeAnnotation": {
"type": "GenericTypeAnnotation",
"start": 21,
"end": 27,
"loc": {
"start": {
"line": 1,
"column": 21
},
"end": {
"line": 1,
"column": 27
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 21,
"end": 27,
"loc": {
"start": {
"line": 1,
"column": 21
},
"end": {
"line": 1,
"column": 27
},
"identifierName": "Object"
},
"name": "Object"
}
}
}
}
],
"rest": null,
"returnType": {
"type": "VoidTypeAnnotation",
"start": 33,
"end": 37,
"loc": {
"start": {
"line": 1,
"column": 33
},
"end": {
"line": 1,
"column": 37
}
}
},
"typeParameters": null
}
}
},
"init": {
"type": "ArrowFunctionExpression",
"start": 40,
"end": 56,
"loc": {
"start": {
"line": 1,
"column": 40
},
"end": {
"line": 1,
"column": 56
}
},
"id": null,
"generator": false,
"expression": true,
"async": false,
"params": [
{
"type": "Identifier",
"start": 42,
"end": 44,
"loc": {
"start": {
"line": 1,
"column": 42
},
"end": {
"line": 1,
"column": 44
},
"identifierName": "o1"
},
"name": "o1"
},
{
"type": "Identifier",
"start": 46,
"end": 48,
"loc": {
"start": {
"line": 1,
"column": 46
},
"end": {
"line": 1,
"column": 48
},
"identifierName": "o2"
},
"name": "o2"
}
],
"body": {
"type": "Identifier",
"start": 54,
"end": 56,
"loc": {
"start": {
"line": 1,
"column": 54
},
"end": {
"line": 1,
"column": 56
},
"identifierName": "o1"
},
"name": "o1"
}
}
}
],
"kind": "const"
},
{
"type": "VariableDeclaration",
"start": 58,
"end": 117,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 59
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 64,
"end": 116,
"loc": {
"start": {
"line": 2,
"column": 6
},
"end": {
"line": 2,
"column": 58
}
},
"id": {
"type": "Identifier",
"start": 64,
"end": 96,
"loc": {
"start": {
"line": 2,
"column": 6
},
"end": {
"line": 2,
"column": 38
},
"identifierName": "fn"
},
"name": "fn",
"typeAnnotation": {
"type": "TypeAnnotation",
"start": 66,
"end": 96,
"loc": {
"start": {
"line": 2,
"column": 8
},
"end": {
"line": 2,
"column": 38
}
},
"typeAnnotation": {
"type": "FunctionTypeAnnotation",
"start": 68,
"end": 96,
"loc": {
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 2,
"column": 38
}
},
"params": [
{
"type": "FunctionTypeParam",
"start": 70,
"end": 77,
"loc": {
"start": {
"start": {
"line": 2,
"column": 12
},
"end": {
"line": 2,
"column": 18
}
},
"end": {
"line": 2,
"column": 19
}
},
"name": null,
"optional": false,
"typeAnnotation": {
"type": "GenericTypeAnnotation",
"start": 70,
"end": 76,
"loc": {
"start": {
"line": 2,
"column": 12
},
"end": {
"line": 2,
"column": 18
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 70,
"end": 76,
"loc": {
"start": {
"line": 2,
"column": 12
},
"end": {
"line": 2,
"column": 18
},
"identifierName": "Object"
},
"name": "Object"
}
}
},
{
"type": "FunctionTypeParam",
"start": 78,
"end": 85,
"loc": {
"start": {
"line": 2,
"column": 20
},
"end": {
"line": 2,
"column": 27
}
},
"name": null,
"optional": false,
"typeAnnotation": {
"type": "NullableTypeAnnotation",
"start": 78,
"end": 85,
"loc": {
"start": {
"line": 2,
"column": 20
},
"end": {
"line": 2,
"column": 27
}
},
"typeAnnotation": {
"type": "GenericTypeAnnotation",
"start": 79,
"end": 85,
"loc": {
"start": {
"line": 2,
"column": 21
},
"end": {
"line": 2,
"column": 27
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 79,
"end": 85,
"loc": {
"start": {
"line": 2,
"column": 21
},
"end": {
"line": 2,
"column": 27
},
"identifierName": "Object"
},
"name": "Object"
}
}
}
}
],
"rest": null,
"returnType": {
"type": "VoidTypeAnnotation",
"start": 92,
"end": 96,
"loc": {
"start": {
"line": 2,
"column": 34
},
"end": {
"line": 2,
"column": 38
}
}
},
"typeParameters": null
}
}
},
"init": {
"type": "ArrowFunctionExpression",
"start": 99,
"end": 116,
"loc": {
"start": {
"line": 2,
"column": 41
},
"end": {
"line": 2,
"column": 58
}
},
"id": null,
"generator": false,
"expression": true,
"async": false,
"params": [
{
"type": "Identifier",
"start": 101,
"end": 103,
"loc": {
"start": {
"line": 2,
"column": 43
},
"end": {
"line": 2,
"column": 45
},
"identifierName": "o1"
},
"name": "o1"
},
{
"type": "Identifier",
"start": 105,
"end": 107,
"loc": {
"start": {
"line": 2,
"column": 47
},
"end": {
"line": 2,
"column": 49
},
"identifierName": "o2"
},
"name": "o2"
}
],
"body": {
"type": "Identifier",
"start": 114,
"end": 116,
"loc": {
"start": {
"line": 2,
"column": 56
},
"end": {
"line": 2,
"column": 58
},
"identifierName": "o1"
},
"name": "o1"
}
}
}
],
"kind": "const"
}
],
"directives": []
}
}

View File

@ -0,0 +1 @@
const fn = async (a?: any): Promise<void> => {};

View File

@ -0,0 +1,249 @@
{
"type": "File",
"start": 0,
"end": 48,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 48
}
},
"program": {
"type": "Program",
"start": 0,
"end": 48,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 48
}
},
"sourceType": "module",
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 48,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 48
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 6,
"end": 47,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 47
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 8,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 8
},
"identifierName": "fn"
},
"name": "fn"
},
"init": {
"type": "ArrowFunctionExpression",
"start": 11,
"end": 47,
"loc": {
"start": {
"line": 1,
"column": 11
},
"end": {
"line": 1,
"column": 47
}
},
"returnType": {
"type": "TypeAnnotation",
"start": 26,
"end": 41,
"loc": {
"start": {
"line": 1,
"column": 26
},
"end": {
"line": 1,
"column": 41
}
},
"typeAnnotation": {
"type": "GenericTypeAnnotation",
"start": 28,
"end": 41,
"loc": {
"start": {
"line": 1,
"column": 28
},
"end": {
"line": 1,
"column": 41
}
},
"typeParameters": {
"type": "TypeParameterInstantiation",
"start": 35,
"end": 41,
"loc": {
"start": {
"line": 1,
"column": 35
},
"end": {
"line": 1,
"column": 41
}
},
"params": [
{
"type": "VoidTypeAnnotation",
"start": 36,
"end": 40,
"loc": {
"start": {
"line": 1,
"column": 36
},
"end": {
"line": 1,
"column": 40
}
}
}
]
},
"id": {
"type": "Identifier",
"start": 28,
"end": 35,
"loc": {
"start": {
"line": 1,
"column": 28
},
"end": {
"line": 1,
"column": 35
},
"identifierName": "Promise"
},
"name": "Promise"
}
}
},
"id": null,
"generator": false,
"expression": false,
"async": true,
"params": [
{
"type": "Identifier",
"start": 18,
"end": 25,
"loc": {
"start": {
"line": 1,
"column": 18
},
"end": {
"line": 1,
"column": 25
},
"identifierName": "a"
},
"name": "a",
"optional": true,
"typeAnnotation": {
"type": "TypeAnnotation",
"start": 20,
"end": 25,
"loc": {
"start": {
"line": 1,
"column": 20
},
"end": {
"line": 1,
"column": 25
}
},
"typeAnnotation": {
"type": "AnyTypeAnnotation",
"start": 22,
"end": 25,
"loc": {
"start": {
"line": 1,
"column": 22
},
"end": {
"line": 1,
"column": 25
}
}
}
}
}
],
"body": {
"type": "BlockStatement",
"start": 45,
"end": 47,
"loc": {
"start": {
"line": 1,
"column": 45
},
"end": {
"line": 1,
"column": 47
}
},
"body": [],
"directives": []
}
}
}
],
"kind": "const"
}
],
"directives": []
}
}

View File

@ -0,0 +1 @@
import { type as debugger } from "foo";

View File

@ -0,0 +1,3 @@
{
"throws": "debugger is a reserved word (1:17)"
}

View File

@ -0,0 +1 @@
import { type debugger } from "foo";

View File

@ -0,0 +1,3 @@
{
"throws": "debugger is a reserved word (1:9)"
}

View File

@ -1,4 +1,4 @@
{ {
"throws": "Unexpected token (1:14)", "throws": "delete is a reserved word (1:14)",
"plugins": ["flow", "jsx"] "plugins": ["flow", "jsx"]
} }

View File

@ -1,5 +1,5 @@
import path from "path"; import path from "path";
import runFixtureTests from "./utils/runFixtureTests"; import { runFixtureTests } from "./utils/runFixtureTests";
import { parse, parseExpression } from "../lib"; import { parse, parseExpression } from "../lib";
runFixtureTests(path.join(__dirname, "fixtures"), parse); runFixtureTests(path.join(__dirname, "fixtures"), parse);

View File

@ -1,13 +1,13 @@
var test = require("ava"); var test = require("ava");
var getFixtures = require("babel-helper-fixtures").multiple; var getFixtures = require("babel-helper-fixtures").multiple;
module.exports = function runFixtureTests(fixturesPath, parseFunction) { exports.runFixtureTests = function runFixtureTests(fixturesPath, parseFunction) {
var fixtures = getFixtures(fixturesPath); var fixtures = getFixtures(fixturesPath);
Object.keys(fixtures).forEach(function (name) { Object.keys(fixtures).forEach(function (name) {
fixtures[name].forEach(function (testSuite) { fixtures[name].forEach(function (testSuite) {
testSuite.tests.forEach(function (task) { testSuite.tests.forEach(function (task) {
var testFn = task.disabled ? test.skip : test; var testFn = task.disabled ? test.skip : task.options.only ? test.only : test;
testFn(name + "/" + testSuite.title + "/" + task.title, function () { testFn(name + "/" + testSuite.title + "/" + task.title, function () {
try { try {
@ -22,10 +22,41 @@ module.exports = function runFixtureTests(fixturesPath, parseFunction) {
}); });
}; };
exports.runThrowTestsWithEstree = function runThrowTestsWithEstree(fixturesPath, parseFunction) {
var fixtures = getFixtures(fixturesPath);
Object.keys(fixtures).forEach(function (name) {
fixtures[name].forEach(function (testSuite) {
testSuite.tests.forEach(function (task) {
if (!task.options.throws) return;
task.options.plugins = task.options.plugins || [];
task.options.plugins.push("estree");
var testFn = task.disabled ? test.skip : task.options.only ? test.only : test;
testFn(name + "/" + testSuite.title + "/" + task.title, function () {
try {
return runTest(task, parseFunction);
} catch (err) {
err.message = task.actual.loc + ": " + err.message;
throw err;
}
});
});
});
});
};
function save(test, ast) { function save(test, ast) {
delete ast.tokens; delete ast.tokens;
if (ast.comments && !ast.comments.length) delete ast.comments; if (ast.comments && !ast.comments.length) delete ast.comments;
// Ensure that RegExp are serialized as strings
const toJSON = RegExp.prototype.toJSON;
RegExp.prototype.toJSON = RegExp.prototype.toString;
require("fs").writeFileSync(test.expect.loc, JSON.stringify(ast, null, " ")); require("fs").writeFileSync(test.expect.loc, JSON.stringify(ast, null, " "));
RegExp.prototype.toJSON = toJSON;
} }
function runTest(test, parseFunction) { function runTest(test, parseFunction) {
@ -69,7 +100,8 @@ function runTest(test, parseFunction) {
} }
function ppJSON(v) { function ppJSON(v) {
return v instanceof RegExp ? v.toString() : JSON.stringify(v, null, 2); v = v instanceof RegExp ? v.toString() : v;
return JSON.stringify(v, null, 2);
} }
function addPath(str, pt) { function addPath(str, pt) {
@ -81,20 +113,20 @@ function addPath(str, pt) {
} }
function misMatch(exp, act) { function misMatch(exp, act) {
if (!exp || !act || (typeof exp != "object") || (typeof act != "object")) { if (exp instanceof RegExp || act instanceof RegExp) {
if (exp !== act && typeof exp != "function")
return ppJSON(exp) + " !== " + ppJSON(act);
} else if (exp instanceof RegExp || act instanceof RegExp) {
var left = ppJSON(exp), right = ppJSON(act); var left = ppJSON(exp), right = ppJSON(act);
if (left !== right) return left + " !== " + right; if (left !== right) return left + " !== " + right;
} else if (exp.splice) { } else if (Array.isArray(exp)) {
if (!act.slice) return ppJSON(exp) + " != " + ppJSON(act); if (!Array.isArray(act)) return ppJSON(exp) + " != " + ppJSON(act);
if (act.length != exp.length) return "array length mismatch " + exp.length + " != " + act.length; if (act.length != exp.length) return "array length mismatch " + exp.length + " != " + act.length;
for (var i = 0; i < act.length; ++i) { for (var i = 0; i < act.length; ++i) {
var mis = misMatch(exp[i], act[i]); var mis = misMatch(exp[i], act[i]);
if (mis) return addPath(mis, i); if (mis) return addPath(mis, i);
} }
} else { } else if (!exp || !act || (typeof exp != "object") || (typeof act != "object")) {
if (exp !== act && typeof exp != "function")
return ppJSON(exp) + " !== " + ppJSON(act);
} else {
for (var prop in exp) { for (var prop in exp) {
var mis = misMatch(exp[prop], act[prop]); var mis = misMatch(exp[prop], act[prop]);
if (mis) return addPath(mis, prop); if (mis) return addPath(mis, prop);