I'm extremely stupid and didn't commit as I go. To anyone reading this
I'm extremely sorry. A lot of these changes are very broad and I plan on
releasing Babel 6.0.0 today live on stage at Ember Camp London so I'm
afraid I couldn't wait. If you're ever in London I'll buy you a beer
(or assorted beverage!) to make up for it, also I'll kiss your feet and
give you a back massage, maybe.
This commit is contained in:
Sebastian McKenzie
2015-10-29 17:51:24 +00:00
parent 3974dd762d
commit ae7d5367f1
1501 changed files with 16477 additions and 19786 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "babel-types",
"version": "5.8.22",
"version": "5.10.32",
"description": "",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
@@ -8,9 +8,10 @@
"repository": "babel/babel",
"main": "lib/index.js",
"dependencies": {
"babel-runtime": "^5.10.32",
"babel-traverse": "^5.10.32",
"esutils": "^2.0.2",
"lodash": "^3.10.1",
"to-fast-properties": "^1.0.1",
"babel-traverse": "^5.8.22"
"to-fast-properties": "^1.0.1"
}
}
}

View File

@@ -1,3 +1,5 @@
/* @flow */
import isPlainObject from "lodash/lang/isPlainObject";
import isNumber from "lodash/lang/isNumber";
import isRegExp from "lodash/lang/isRegExp";
@@ -22,13 +24,13 @@ export function toComputedKey(node: Object, key: Object = node.key || node.prope
* Expression statements are just resolved to their expression.
*/
export function toSequenceExpression(nodes: Array<Object>, scope: Scope): Object {
export function toSequenceExpression(nodes: Array<Object>, scope: Scope): ?Object {
if (!nodes || !nodes.length) return;
var declars = [];
var bailed = false;
let declars = [];
let bailed = false;
var result = convert(nodes);
let result = convert(nodes);
if (bailed) return;
for (let i = 0; i < declars.length; i++) {
@@ -38,8 +40,8 @@ export function toSequenceExpression(nodes: Array<Object>, scope: Scope): Object
return result;
function convert(nodes) {
var ensureLastUndefined = false;
var exprs = [];
let ensureLastUndefined = false;
let exprs = [];
for (let node of (nodes: Array)) {
if (t.isExpression(node)) {
@@ -49,9 +51,9 @@ export function toSequenceExpression(nodes: Array<Object>, scope: Scope): Object
} else if (t.isVariableDeclaration(node)) {
if (node.kind !== "var") return bailed = true; // bailed
for (var declar of (node.declarations: Array)) {
var bindings = t.getBindingIdentifiers(declar);
for (var key in bindings) {
for (let declar of (node.declarations: Array)) {
let bindings = t.getBindingIdentifiers(declar);
for (let key in bindings) {
declars.push({
kind: node.kind,
id: bindings[key]
@@ -66,8 +68,8 @@ export function toSequenceExpression(nodes: Array<Object>, scope: Scope): Object
ensureLastUndefined = true;
continue;
} else if (t.isIfStatement(node)) {
var consequent = node.consequent ? convert([node.consequent]) : t.identifier("undefined");
var alternate = node.alternate ? convert([node.alternate]) : t.identifier("undefined");
let consequent = node.consequent ? convert([node.consequent]) : scope.buildUndefinedNode();
let alternate = node.alternate ? convert([node.alternate]) : scope.buildUndefinedNode();
if (!consequent || !alternate) return bailed = true;
exprs.push(t.conditionalExpression(node.test, consequent, alternate));
@@ -85,8 +87,8 @@ export function toSequenceExpression(nodes: Array<Object>, scope: Scope): Object
ensureLastUndefined = false;
}
if (ensureLastUndefined) {
exprs.push(t.identifier("undefined"));
if (ensureLastUndefined || exprs.length === 0) {
exprs.push(scope.buildUndefinedNode());
}
//
@@ -99,11 +101,11 @@ export function toSequenceExpression(nodes: Array<Object>, scope: Scope): Object
}
}
export function toKeyAlias(node: Object, key: Object = node.key) {
var alias;
export function toKeyAlias(node: Object, key: Object = node.key): string {
let alias;
if (node.kind === "method") {
return toKeyAlias.uid++;
return toKeyAlias.increment() + "";
} else if (t.isIdentifier(key)) {
alias = key.name;
} else if (t.isStringLiteral(key)) {
@@ -116,14 +118,24 @@ export function toKeyAlias(node: Object, key: Object = node.key) {
alias = `[${alias}]`;
}
if (node.static) {
alias = `static:${alias}`;
}
return alias;
}
toKeyAlias.uid = 0;
export function toIdentifier(name: string): string {
if (t.isIdentifier(name)) return name.name;
toKeyAlias.increment = function () {
if (toKeyAlias.uid >= Number.MAX_SAFE_INTEGER) {
return toKeyAlias.uid = 0;
} else {
return toKeyAlias.uid++;
}
};
export function toIdentifier(name: string): string {
name = name + "";
// replace all non-valid identifiers with dashes
@@ -144,7 +156,7 @@ export function toIdentifier(name: string): string {
return name || "_";
}
export function toBindingIdentifierName(name) {
export function toBindingIdentifierName(name: string): string {
name = toIdentifier(name);
if (name === "eval" || name === "arguments") name = "_" + name;
return name;
@@ -160,8 +172,8 @@ export function toStatement(node: Object, ignore?: boolean) {
return node;
}
var mustHaveId = false;
var newType;
let mustHaveId = false;
let newType;
if (t.isClass(node)) {
mustHaveId = true;
@@ -208,7 +220,7 @@ export function toExpression(node: Object): Object {
}
}
export function toBlock(node: Object, parent: Object): Object {
export function toBlock(node, parent: Object): Object {
if (t.isBlockStatement(node)) {
return node;
}
@@ -260,8 +272,8 @@ export function valueToNode(value: any): Object {
// regexes
if (isRegExp(value)) {
var pattern = value.source;
var flags = value.toString().match(/\/([a-z]+|)$/)[1];
let pattern = value.source;
let flags = value.toString().match(/\/([a-z]+|)$/)[1];
return t.regexLiteral(pattern, flags);
}
@@ -272,15 +284,15 @@ export function valueToNode(value: any): Object {
// object
if (isPlainObject(value)) {
var props = [];
for (var key in value) {
var nodeKey;
let props = [];
for (let key in value) {
let nodeKey;
if (t.isValidIdentifier(key)) {
nodeKey = t.identifier(key);
} else {
nodeKey = t.literal(key);
}
props.push(t.property("init", nodeKey, t.valueToNode(value[key])));
props.push(t.objectProperty(nodeKey, t.valueToNode(value[key])));
}
return t.objectExpression(props);
}

View File

@@ -1,7 +1,15 @@
import * as t from "../index";
import define, { assertValueType, assertNodeType, assertEach, chain, assertOneOf } from "./index";
/* @flow */
define("ArrayExpression", {
import * as t from "../index";
import defineType, {
assertValueType,
assertNodeType,
assertEach,
chain,
assertOneOf,
} from "./index";
defineType("ArrayExpression", {
fields: {
elements: {
validate: assertValueType("array")
@@ -11,18 +19,16 @@ define("ArrayExpression", {
aliases: ["Expression"]
});
define("AssignmentExpression", {
defineType("AssignmentExpression", {
fields: {
elements: {
operator: {
validate: assertValueType("string")
},
left: {
validate: assertNodeType("LVal")
},
right: {
validate: assertNodeType("Expression")
}
operator: {
validate: assertValueType("string")
},
left: {
validate: assertNodeType("LVal")
},
right: {
validate: assertNodeType("Expression")
}
},
builder: ["operator", "left", "right"],
@@ -30,7 +36,7 @@ define("AssignmentExpression", {
aliases: ["Expression"]
});
define("BinaryExpression", {
defineType("BinaryExpression", {
builder: ["operator", "left", "right"],
fields: {
operator: {
@@ -47,7 +53,17 @@ define("BinaryExpression", {
aliases: ["Binary", "Expression"]
});
define("Directive", {
defineType("Directive", {
visitor: ["value"],
fields: {
value: {
validate: assertNodeType("DirectiveLiteral")
}
}
});
defineType("DirectiveLiteral", {
builder: ["value"],
fields: {
value: {
validate: assertValueType("string")
@@ -55,7 +71,7 @@ define("Directive", {
}
});
define("BlockStatement", {
defineType("BlockStatement", {
builder: ["body", "directives"],
visitor: ["directives", "body"],
fields: {
@@ -70,7 +86,7 @@ define("BlockStatement", {
aliases: ["Scopable", "BlockParent", "Block", "Statement"]
});
define("BreakStatement", {
defineType("BreakStatement", {
visitor: ["label"],
fields: {
label: {
@@ -81,7 +97,7 @@ define("BreakStatement", {
aliases: ["Statement", "Terminatorless", "CompletionStatement"]
});
define("CallExpression", {
defineType("CallExpression", {
visitor: ["callee", "arguments"],
fields: {
callee: {
@@ -94,7 +110,7 @@ define("CallExpression", {
aliases: ["Expression"]
});
define("CatchClause", {
defineType("CatchClause", {
visitor: ["param", "body"],
fields: {
param: {
@@ -107,7 +123,7 @@ define("CatchClause", {
aliases: ["Scopable"]
});
define("ConditionalExpression", {
defineType("ConditionalExpression", {
visitor: ["test", "consequent", "alternate"],
fields: {
test: {
@@ -120,10 +136,10 @@ define("ConditionalExpression", {
validate: assertNodeType("Expression")
}
},
aliases: ["Expression"]
aliases: ["Expression", "Conditional"]
});
define("ContinueStatement", {
defineType("ContinueStatement", {
visitor: ["label"],
fields: {
label: {
@@ -134,11 +150,11 @@ define("ContinueStatement", {
aliases: ["Statement", "Terminatorless", "CompletionStatement"]
});
define("DebuggerStatement", {
defineType("DebuggerStatement", {
aliases: ["Statement"]
});
define("DoWhileStatement", {
defineType("DoWhileStatement", {
visitor: ["test", "body"],
fields: {
test: {
@@ -151,21 +167,21 @@ define("DoWhileStatement", {
aliases: ["Statement", "BlockParent", "Loop", "While", "Scopable"]
});
define("EmptyStatement", {
defineType("EmptyStatement", {
aliases: ["Statement"]
});
define("ExpressionStatement", {
defineType("ExpressionStatement", {
visitor: ["expression"],
fields: {
expression: {
validate: assertNodeType("Expression")
}
},
aliases: ["Statement"]
aliases: ["Statement", "ExpressionWrapper"]
});
define("File", {
defineType("File", {
builder: ["program", "comments", "tokens"],
visitor: ["program"],
fields: {
@@ -175,7 +191,7 @@ define("File", {
}
});
define("ForInStatement", {
defineType("ForInStatement", {
visitor: ["left", "right", "body"],
aliases: ["Scopable", "Statement", "For", "BlockParent", "Loop", "ForXStatement"],
fields: {
@@ -191,7 +207,7 @@ define("ForInStatement", {
}
});
define("ForStatement", {
defineType("ForStatement", {
visitor: ["init", "test", "update", "body"],
aliases: ["Scopable", "Statement", "For", "BlockParent", "Loop"],
fields: {
@@ -210,7 +226,7 @@ define("ForStatement", {
}
});
define("FunctionDeclaration", {
defineType("FunctionDeclaration", {
builder: ["id", "params", "body", "generator", "async"],
visitor: ["id", "params", "body", "returnType", "typeParameters"],
fields: {
@@ -232,11 +248,20 @@ define("FunctionDeclaration", {
validate: assertValueType("boolean")
}
},
aliases: ["Scopable", "Function", "BlockParent", "FunctionParent", "Statement", "Pure", "Declaration"]
aliases: [
"Scopable",
"Function",
"BlockParent",
"FunctionParent",
"Statement",
"Pureish",
"Declaration"
]
});
define("FunctionExpression", {
builder: ["id", "params", "body", "generator", "async"],
defineType("FunctionExpression", {
inherits: "FunctionDeclaration",
aliases: ["Scopable", "Function", "BlockParent", "FunctionParent", "Expression", "Pureish"],
fields: {
id: {
validate: assertNodeType("Identifier"),
@@ -256,12 +281,10 @@ define("FunctionExpression", {
default: false,
validate: assertValueType("boolean")
}
},
visitor: ["id", "params", "body", "returnType", "typeParameters"],
aliases: ["Scopable", "Function", "BlockParent", "FunctionParent", "Expression", "Pure"]
}
});
define("Identifier", {
defineType("Identifier", {
builder: ["name"],
visitor: ["typeAnnotation"],
aliases: ["Expression", "LVal"],
@@ -276,9 +299,9 @@ define("Identifier", {
}
});
define("IfStatement", {
defineType("IfStatement", {
visitor: ["test", "consequent", "alternate"],
aliases: ["Statement"],
aliases: ["Statement", "Conditional"],
fields: {
test: {
validate: assertNodeType("Expression")
@@ -294,7 +317,7 @@ define("IfStatement", {
}
});
define("LabeledStatement", {
defineType("LabeledStatement", {
visitor: ["label", "body"],
aliases: ["Statement"],
fields: {
@@ -307,41 +330,41 @@ define("LabeledStatement", {
}
});
define("StringLiteral", {
defineType("StringLiteral", {
builder: ["value"],
fields: {
value: {
validate: assertValueType("string")
}
},
aliases: ["Expression", "Pure", "Literal", "Immutable"]
aliases: ["Expression", "Pureish", "Literal", "Immutable"]
});
define("NumberLiteral", {
defineType("NumberLiteral", {
builder: ["value"],
fields: {
value: {
validate: assertValueType("number")
}
},
aliases: ["Expression", "Pure", "Literal", "Immutable"]
aliases: ["Expression", "Pureish", "Literal", "Immutable"]
});
define("NullLiteral", {
aliases: ["Expression", "Pure", "Literal", "Immutable"]
defineType("NullLiteral", {
aliases: ["Expression", "Pureish", "Literal", "Immutable"]
});
define("BooleanLiteral", {
defineType("BooleanLiteral", {
builder: ["value"],
fields: {
value: {
validate: assertValueType("boolean")
}
},
aliases: ["Expression", "Pure", "Literal", "Immutable"]
aliases: ["Expression", "Pureish", "Literal", "Immutable"]
});
define("RegexLiteral", {
defineType("RegexLiteral", {
builder: ["pattern", "flags"],
aliases: ["Expression", "Literal"],
fields: {
@@ -355,7 +378,7 @@ define("RegexLiteral", {
}
});
define("LogicalExpression", {
defineType("LogicalExpression", {
builder: ["operator", "left", "right"],
visitor: ["left", "right"],
aliases: ["Binary", "Expression"],
@@ -372,7 +395,7 @@ define("LogicalExpression", {
}
});
define("MemberExpression", {
defineType("MemberExpression", {
builder: ["object", "property", "computed"],
visitor: ["object", "property"],
aliases: ["Expression", "LVal"],
@@ -382,7 +405,7 @@ define("MemberExpression", {
},
property: {
validate(node, key, val) {
var expectedType = node.computed ? "Expression" : "Identifier";
let expectedType = node.computed ? "Expression" : "Identifier";
assertNodeType(expectedType)(node, key, val);
}
},
@@ -392,7 +415,7 @@ define("MemberExpression", {
}
});
define("NewExpression", {
defineType("NewExpression", {
visitor: ["callee", "arguments"],
aliases: ["Expression"],
fields: {
@@ -405,17 +428,7 @@ define("NewExpression", {
}
});
define("ObjectExpression", {
visitor: ["properties"],
aliases: ["Expression"],
fields: {
properties: {
validate: chain(assertValueType("array"), assertEach(assertNodeType("Property", "SpreadProperty")))
}
}
});
define("Program", {
defineType("Program", {
visitor: ["directives", "body"],
builder: ["body", "directives"],
fields: {
@@ -430,12 +443,22 @@ define("Program", {
aliases: ["Scopable", "BlockParent", "Block", "FunctionParent"]
});
define("Property", {
builder: ["kind", "key", "value", "computed", "method", "shorthand"],
defineType("ObjectExpression", {
visitor: ["properties"],
aliases: ["Expression"],
fields: {
properties: {
validate: chain(assertValueType("array"), assertEach(assertNodeType("ObjectMethod", "ObjectProperty", "SpreadProperty")))
}
}
});
defineType("ObjectMethod", {
builder: ["kind", "key", "params", "body", "computed"],
fields: {
kind: {
validate: chain(assertValueType("string"), assertOneOf("init", "get", "set")),
default: "init"
validate: chain(assertValueType("string"), assertOneOf("method", "get", "set")),
default: "method"
},
computed: {
validate: assertValueType("boolean"),
@@ -443,37 +466,61 @@ define("Property", {
},
key: {
validate(node, key, val) {
var expectedTypes = node.computed ? "Expression" : ["Identifier", "Literal"];
let expectedTypes = node.computed ? ["Expression"] : ["Identifier", "Literal"];
assertNodeType(...expectedTypes)(node, key, val);
}
},
decorators: {
validate: chain(assertValueType("array"), assertEach(assertNodeType("Decorator")))
},
body: {
validate: assertNodeType("BlockStatement")
},
generator: {
default: false,
validate: assertValueType("boolean")
},
async: {
default: false,
validate: assertValueType("boolean")
}
},
visitor: ["key", "params", "body", "decorators", "returnType", "typeParameters"],
aliases: ["UserWhitespacable", "Function", "Scopable", "BlockParent", "FunctionParent", "Method"]
});
defineType("ObjectProperty", {
builder: ["key", "value", "computed", "shorthand", "decorators"],
fields: {
computed: {
validate: assertValueType("boolean"),
default: false
},
key: {
validate(node, key, val) {
let expectedTypes = node.computed ? ["Expression"] : ["Identifier", "Literal"];
assertNodeType(...expectedTypes)(node, key, val);
}
},
value: {
validate(node, key, val) {
var expectedType = "Expression";
if (node.kind === "get" || node.kind === "set" || node.method) {
expectedType = "FunctionExpression";
}
assertNodeType(expectedType)(node, key, val);
}
},
method: {
validate: assertValueType("boolean"),
default: false
validate: assertNodeType("Expression")
},
shorthand: {
validate: assertValueType("boolean"),
default: false
},
decorators: {
validate: chain(assertValueType("array"), assertEach(assertNodeType("Decorator")))
validate: chain(assertValueType("array"), assertEach(assertNodeType("Decorator"))),
optional: true
}
},
visitor: ["key", "value", "decorators"],
aliases: ["UserWhitespacable"]
aliases: ["UserWhitespacable", "Property"]
});
define("RestElement", {
defineType("RestElement", {
visitor: ["argument", "typeAnnotation"],
aliases: ["LVal"],
fields: {
argument: {
validate: assertNodeType("LVal")
@@ -481,17 +528,18 @@ define("RestElement", {
}
});
define("ReturnStatement", {
defineType("ReturnStatement", {
visitor: ["argument"],
aliases: ["Statement", "Terminatorless", "CompletionStatement"],
fields: {
argument: {
validate: assertNodeType("Expression")
validate: assertNodeType("Expression"),
optional: true
}
}
});
define("SequenceExpression", {
defineType("SequenceExpression", {
visitor: ["expressions"],
fields: {
expressions: { validate: assertValueType("array") }
@@ -499,14 +547,14 @@ define("SequenceExpression", {
aliases: ["Expression"]
});
define("SwitchCase", {
defineType("SwitchCase", {
visitor: ["test", "consequent"],
fields: {
// todo
}
});
define("SwitchStatement", {
defineType("SwitchStatement", {
visitor: ["discriminant", "cases"],
aliases: ["Statement", "BlockParent", "Scopable"],
fields: {
@@ -514,11 +562,11 @@ define("SwitchStatement", {
}
});
define("ThisExpression", {
defineType("ThisExpression", {
aliases: ["Expression"]
});
define("ThrowStatement", {
defineType("ThrowStatement", {
visitor: ["argument"],
aliases: ["Statement", "Terminatorless", "CompletionStatement"],
fields: {
@@ -529,7 +577,7 @@ define("ThrowStatement", {
});
// todo: at least handler or finalizer should be set to be valid
define("TryStatement", {
defineType("TryStatement", {
visitor: ["block", "handler", "finalizer"],
aliases: ["Statement"],
fields: {
@@ -547,7 +595,7 @@ define("TryStatement", {
}
});
define("UnaryExpression", {
defineType("UnaryExpression", {
builder: ["operator", "argument", "prefix"],
fields: {
prefix: {
@@ -564,7 +612,7 @@ define("UnaryExpression", {
aliases: ["UnaryLike", "Expression"]
});
define("UpdateExpression", {
defineType("UpdateExpression", {
builder: ["operator", "argument", "prefix"],
fields: {
prefix: {
@@ -581,7 +629,7 @@ define("UpdateExpression", {
aliases: ["Expression"]
});
define("VariableDeclaration", {
defineType("VariableDeclaration", {
builder: ["kind", "declarations"],
visitor: ["declarations"],
aliases: ["Statement", "Declaration"],
@@ -595,7 +643,7 @@ define("VariableDeclaration", {
}
});
define("VariableDeclarator", {
defineType("VariableDeclarator", {
visitor: ["id", "init"],
fields: {
id: {
@@ -608,7 +656,7 @@ define("VariableDeclarator", {
}
});
define("WhileStatement", {
defineType("WhileStatement", {
visitor: ["test", "body"],
aliases: ["Statement", "BlockParent", "Loop", "While", "Scopable"],
fields: {
@@ -621,7 +669,7 @@ define("WhileStatement", {
}
});
define("WithStatement", {
defineType("WithStatement", {
visitor: ["object", "body"],
aliases: ["Statement"],
fields: {

View File

@@ -1,6 +1,14 @@
import define, { assertNodeType, assertValueType, chain, assertEach, assertOneOf } from "./index";
/* @flow */
define("AssignmentPattern", {
import defineType, {
assertNodeType,
assertValueType,
chain,
assertEach,
assertOneOf,
} from "./index";
defineType("AssignmentPattern", {
visitor: ["left", "right"],
aliases: ["Pattern", "LVal"],
fields: {
@@ -13,7 +21,7 @@ define("AssignmentPattern", {
}
});
define("ArrayPattern", {
defineType("ArrayPattern", {
visitor: ["elements", "typeAnnotation"],
aliases: ["Pattern", "LVal"],
fields: {
@@ -23,10 +31,10 @@ define("ArrayPattern", {
}
});
define("ArrowFunctionExpression", {
defineType("ArrowFunctionExpression", {
builder: ["params", "body", "async"],
visitor: ["params", "body", "returnType"],
aliases: ["Scopable", "Function", "BlockParent", "FunctionParent", "Expression", "Pure"],
aliases: ["Scopable", "Function", "BlockParent", "FunctionParent", "Expression", "Pureish"],
fields: {
params: {
validate: chain(assertValueType("array"), assertEach(assertNodeType("LVal")))
@@ -41,19 +49,27 @@ define("ArrowFunctionExpression", {
}
});
define("ClassBody", {
defineType("ClassBody", {
visitor: ["body"],
fields: {
body: {
validate: chain(assertValueType("array"), assertEach(assertValueType("MethodDefinition", "ClassProperty")))
validate: chain(assertValueType("array"), assertEach(assertValueType("ClassMethod", "ClassProperty")))
}
}
});
define("ClassDeclaration", {
defineType("ClassDeclaration", {
builder: ["id", "superClass", "body", "decorators"],
visitor: ["id", "body", "superClass", "typeParameters", "superTypeParameters", "implements", "decorators"],
aliases: ["Scopable", "Class", "Statement", "Declaration"],
visitor: [
"id",
"body",
"superClass",
"typeParameters",
"superTypeParameters",
"implements",
"decorators"
],
aliases: ["Scopable", "Class", "Statement", "Declaration", "Pureish"],
fields: {
id: {
validate: assertNodeType("Identifier")
@@ -71,10 +87,9 @@ define("ClassDeclaration", {
}
});
define("ClassExpression", {
builder: ["id", "superClass", "body", "decorators"],
visitor: ["id", "body", "superClass", "typeParameters", "superTypeParameters", "implements", "decorators"],
aliases: ["Scopable", "Class", "Expression"],
defineType("ClassExpression", {
inherits: "ClassDeclaration",
aliases: ["Scopable", "Class", "Expression", "Pureish"],
fields: {
id: {
optional: true,
@@ -93,15 +108,15 @@ define("ClassExpression", {
}
});
define("ExportAllDeclaration", {
visitor: ["source", "exported"],
defineType("ExportAllDeclaration", {
visitor: ["source"],
aliases: ["Statement", "Declaration", "ModuleDeclaration", "ExportDeclaration"],
fields: {
// todo
}
});
define("ExportDefaultDeclaration", {
defineType("ExportDefaultDeclaration", {
visitor: ["declaration"],
aliases: ["Statement", "Declaration", "ModuleDeclaration", "ExportDeclaration"],
fields: {
@@ -109,7 +124,7 @@ define("ExportDefaultDeclaration", {
}
});
define("ExportNamedDeclaration", {
defineType("ExportNamedDeclaration", {
visitor: ["declaration", "specifiers", "source"],
aliases: ["Statement", "Declaration", "ModuleDeclaration", "ExportDeclaration"],
fields: {
@@ -117,7 +132,7 @@ define("ExportNamedDeclaration", {
}
});
define("ExportSpecifier", {
defineType("ExportSpecifier", {
visitor: ["local", "exported"],
aliases: ["ModuleSpecifier"],
fields: {
@@ -130,7 +145,7 @@ define("ExportSpecifier", {
}
});
define("ForOfStatement", {
defineType("ForOfStatement", {
visitor: ["left", "right", "body"],
aliases: ["Scopable", "Statement", "For", "BlockParent", "Loop", "ForXStatement"],
fields: {
@@ -146,12 +161,12 @@ define("ForOfStatement", {
}
});
define("ImportDeclaration", {
defineType("ImportDeclaration", {
visitor: ["specifiers", "source"],
aliases: ["Statement", "Declaration", "ModuleDeclaration"],
fields: {
specifiers: {
// todo
validate: chain(assertValueType("array"), assertEach(assertNodeType("ImportSpecifier", "ImportDefaultSpecifier", "ImportNamespaceSpecifier")))
},
source: {
validate: assertNodeType("StringLiteral")
@@ -159,7 +174,7 @@ define("ImportDeclaration", {
}
});
define("ImportDefaultSpecifier", {
defineType("ImportDefaultSpecifier", {
visitor: ["local"],
aliases: ["ModuleSpecifier"],
fields: {
@@ -169,7 +184,7 @@ define("ImportDefaultSpecifier", {
}
});
define("ImportNamespaceSpecifier", {
defineType("ImportNamespaceSpecifier", {
visitor: ["local"],
aliases: ["ModuleSpecifier"],
fields: {
@@ -179,7 +194,7 @@ define("ImportNamespaceSpecifier", {
}
});
define("ImportSpecifier", {
defineType("ImportSpecifier", {
visitor: ["local", "imported"],
aliases: ["ModuleSpecifier"],
fields: {
@@ -192,7 +207,7 @@ define("ImportSpecifier", {
}
});
define("MetaProperty", {
defineType("MetaProperty", {
visitor: ["meta", "property"],
aliases: ["Expression"],
fields: {
@@ -206,9 +221,10 @@ define("MetaProperty", {
}
});
define("MethodDefinition", {
builder: ["key", "value", "kind", "computed", "static"],
visitor: ["key", "value", "decorators"],
defineType("ClassMethod", {
aliases: ["Function", "Scopable", "BlockParent", "FunctionParent", "Method"],
builder: ["kind", "key", "params", "body", "computed", "static"],
visitor: ["key", "params", "body", "decorators", "returnType", "typeParameters"],
fields: {
kind: {
validate: chain(assertValueType("string"), assertOneOf("get", "set", "method", "constructor")),
@@ -221,11 +237,31 @@ define("MethodDefinition", {
static: {
default: false,
validate: assertValueType("boolean")
},
key: {
validate(node, key, val) {
let expectedTypes = node.computed ? ["Expression"] : ["Identifier", "Literal"];
assertNodeType(...expectedTypes)(node, key, val);
}
},
params: {
validate: chain(assertValueType("array"), assertEach(assertNodeType("LVal")))
},
body: {
validate: assertNodeType("BlockStatement")
},
generator: {
default: false,
validate: assertValueType("boolean")
},
async: {
default: false,
validate: assertValueType("boolean")
}
}
});
define("ObjectPattern", {
defineType("ObjectPattern", {
visitor: ["properties", "typeAnnotation"],
aliases: ["Pattern", "LVal"],
fields: {
@@ -235,7 +271,7 @@ define("ObjectPattern", {
}
});
define("SpreadElement", {
defineType("SpreadElement", {
visitor: ["argument"],
aliases: ["UnaryLike"],
fields: {
@@ -245,11 +281,11 @@ define("SpreadElement", {
}
});
define("Super", {
defineType("Super", {
aliases: ["Expression"]
});
define("TaggedTemplateExpression", {
defineType("TaggedTemplateExpression", {
visitor: ["tag", "quasi"],
aliases: ["Expression"],
fields: {
@@ -262,7 +298,7 @@ define("TaggedTemplateExpression", {
}
});
define("TemplateElement", {
defineType("TemplateElement", {
builder: ["value", "tail"],
fields: {
value: {
@@ -275,7 +311,7 @@ define("TemplateElement", {
}
});
define("TemplateLiteral", {
defineType("TemplateLiteral", {
visitor: ["quasis", "expressions"],
aliases: ["Expression", "Literal"],
fields: {
@@ -283,7 +319,7 @@ define("TemplateLiteral", {
}
});
define("YieldExpression", {
defineType("YieldExpression", {
builder: ["argument", "delegate"],
visitor: ["argument"],
aliases: ["Expression", "Terminatorless"],

View File

@@ -1,43 +1,26 @@
import define, { assertNodeType, assertValueType } from "./index";
/* @flow */
define("AwaitExpression", {
builder: ["argument", "all"],
import defineType, { assertNodeType } from "./index";
defineType("AwaitExpression", {
builder: ["argument"],
visitor: ["argument"],
aliases: ["Expression", "Terminatorless"],
fields: {
all: {
validate: assertValueType("boolean"),
default: false
},
argument: {
validate: assertNodeType("Expression"),
}
}
});
define("BindExpression", {
defineType("BindExpression", {
visitor: ["object", "callee"],
fields: {
// todo
}
});
define("ComprehensionBlock", {
visitor: ["left", "right"],
fields: {
// todo
}
});
define("ComprehensionExpression", {
visitor: ["filter", "blocks", "body"],
aliases: ["Expression", "Scopable"],
fields: {
// todo
}
});
define("Decorator", {
defineType("Decorator", {
visitor: ["expression"],
fields: {
expression: {
@@ -46,7 +29,7 @@ define("Decorator", {
}
});
define("DoExpression", {
defineType("DoExpression", {
visitor: ["body"],
aliases: ["Expression"],
fields: {
@@ -56,7 +39,7 @@ define("DoExpression", {
}
});
define("ExportDefaultSpecifier", {
defineType("ExportDefaultSpecifier", {
visitor: ["exported"],
aliases: ["ModuleSpecifier"],
fields: {
@@ -66,7 +49,7 @@ define("ExportDefaultSpecifier", {
}
});
define("ExportNamespaceSpecifier", {
defineType("ExportNamespaceSpecifier", {
visitor: ["exported"],
aliases: ["ModuleSpecifier"],
fields: {
@@ -76,7 +59,7 @@ define("ExportNamespaceSpecifier", {
}
});
define("RestProperty", {
defineType("RestProperty", {
visitor: ["argument"],
aliases: ["UnaryLike"],
fields: {
@@ -86,7 +69,7 @@ define("RestProperty", {
}
});
define("SpreadProperty", {
defineType("SpreadProperty", {
visitor: ["argument"],
aliases: ["UnaryLike"],
fields: {

View File

@@ -1,13 +1,15 @@
import define from "./index";
/* @flow */
define("AnyTypeAnnotation", {
import defineType from "./index";
defineType("AnyTypeAnnotation", {
aliases: ["Flow", "FlowBaseAnnotation"],
fields: {
// todo
}
});
define("ArrayTypeAnnotation", {
defineType("ArrayTypeAnnotation", {
visitor: ["elementType"],
aliases: ["Flow"],
fields: {
@@ -15,21 +17,21 @@ define("ArrayTypeAnnotation", {
}
});
define("BooleanTypeAnnotation", {
defineType("BooleanTypeAnnotation", {
aliases: ["Flow", "FlowBaseAnnotation"],
fields: {
// todo
}
});
define("BooleanLiteralTypeAnnotation", {
defineType("BooleanLiteralTypeAnnotation", {
aliases: ["Flow"],
fields: {
// todo
}
});
define("ClassImplements", {
defineType("ClassImplements", {
visitor: ["id", "typeParameters"],
aliases: ["Flow"],
fields: {
@@ -37,15 +39,15 @@ define("ClassImplements", {
}
});
define("ClassProperty", {
defineType("ClassProperty", {
visitor: ["key", "value", "typeAnnotation", "decorators"],
aliases: ["Flow"],
aliases: ["Flow", "Property"],
fields: {
// todo
}
});
define("DeclareClass", {
defineType("DeclareClass", {
visitor: ["id", "typeParameters", "extends", "body"],
aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"],
fields: {
@@ -53,7 +55,7 @@ define("DeclareClass", {
}
});
define("DeclareFunction", {
defineType("DeclareFunction", {
visitor: ["id"],
aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"],
fields: {
@@ -61,7 +63,7 @@ define("DeclareFunction", {
}
});
define("DeclareModule", {
defineType("DeclareModule", {
visitor: ["id", "body"],
aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"],
fields: {
@@ -69,7 +71,7 @@ define("DeclareModule", {
}
});
define("DeclareVariable", {
defineType("DeclareVariable", {
visitor: ["id"],
aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"],
fields: {
@@ -77,7 +79,7 @@ define("DeclareVariable", {
}
});
define("FunctionTypeAnnotation", {
defineType("FunctionTypeAnnotation", {
visitor: ["typeParameters", "params", "rest", "returnType"],
aliases: ["Flow"],
fields: {
@@ -85,7 +87,7 @@ define("FunctionTypeAnnotation", {
}
});
define("FunctionTypeParam", {
defineType("FunctionTypeParam", {
visitor: ["name", "typeAnnotation"],
aliases: ["Flow"],
fields: {
@@ -93,7 +95,7 @@ define("FunctionTypeParam", {
}
});
define("GenericTypeAnnotation", {
defineType("GenericTypeAnnotation", {
visitor: ["id", "typeParameters"],
aliases: ["Flow"],
fields: {
@@ -101,7 +103,7 @@ define("GenericTypeAnnotation", {
}
});
define("InterfaceExtends", {
defineType("InterfaceExtends", {
visitor: ["id", "typeParameters"],
aliases: ["Flow"],
fields: {
@@ -109,7 +111,7 @@ define("InterfaceExtends", {
}
});
define("InterfaceDeclaration", {
defineType("InterfaceDeclaration", {
visitor: ["id", "typeParameters", "extends", "body"],
aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"],
fields: {
@@ -117,7 +119,7 @@ define("InterfaceDeclaration", {
}
});
define("IntersectionTypeAnnotation", {
defineType("IntersectionTypeAnnotation", {
visitor: ["types"],
aliases: ["Flow"],
fields: {
@@ -125,11 +127,11 @@ define("IntersectionTypeAnnotation", {
}
});
define("MixedTypeAnnotation", {
defineType("MixedTypeAnnotation", {
aliases: ["Flow", "FlowBaseAnnotation"]
});
define("NullableTypeAnnotation", {
defineType("NullableTypeAnnotation", {
visitor: ["typeAnnotation"],
aliases: ["Flow"],
fields: {
@@ -137,35 +139,35 @@ define("NullableTypeAnnotation", {
}
});
define("NumberLiteralTypeAnnotation", {
defineType("NumberLiteralTypeAnnotation", {
aliases: ["Flow"],
fields: {
// todo
}
});
define("NumberTypeAnnotation", {
defineType("NumberTypeAnnotation", {
aliases: ["Flow", "FlowBaseAnnotation"],
fields: {
// todo
}
});
define("StringLiteralTypeAnnotation", {
defineType("StringLiteralTypeAnnotation", {
aliases: ["Flow"],
fields: {
// todo
}
});
define("StringTypeAnnotation", {
defineType("StringTypeAnnotation", {
aliases: ["Flow", "FlowBaseAnnotation"],
fields: {
// todo
}
});
define("TupleTypeAnnotation", {
defineType("TupleTypeAnnotation", {
visitor: ["types"],
aliases: ["Flow"],
fields: {
@@ -173,7 +175,7 @@ define("TupleTypeAnnotation", {
}
});
define("TypeofTypeAnnotation", {
defineType("TypeofTypeAnnotation", {
visitor: ["argument"],
aliases: ["Flow"],
fields: {
@@ -181,7 +183,7 @@ define("TypeofTypeAnnotation", {
}
});
define("TypeAlias", {
defineType("TypeAlias", {
visitor: ["id", "typeParameters", "right"],
aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"],
fields: {
@@ -189,7 +191,7 @@ define("TypeAlias", {
}
});
define("TypeAnnotation", {
defineType("TypeAnnotation", {
visitor: ["typeAnnotation"],
aliases: ["Flow"],
fields: {
@@ -197,15 +199,15 @@ define("TypeAnnotation", {
}
});
define("TypeCastExpression", {
defineType("TypeCastExpression", {
visitor: ["expression", "typeAnnotation"],
aliases: ["Flow"],
aliases: ["Flow", "ExpressionWrapper"],
fields: {
// todo
}
});
define("TypeParameterDeclaration", {
defineType("TypeParameterDeclaration", {
visitor: ["params"],
aliases: ["Flow"],
fields: {
@@ -213,7 +215,7 @@ define("TypeParameterDeclaration", {
}
});
define("TypeParameterInstantiation", {
defineType("TypeParameterInstantiation", {
visitor: ["params"],
aliases: ["Flow"],
fields: {
@@ -221,7 +223,7 @@ define("TypeParameterInstantiation", {
}
});
define("ObjectTypeAnnotation", {
defineType("ObjectTypeAnnotation", {
visitor: ["properties", "indexers", "callProperties"],
aliases: ["Flow"],
fields: {
@@ -229,7 +231,7 @@ define("ObjectTypeAnnotation", {
}
});
define("ObjectTypeCallProperty", {
defineType("ObjectTypeCallProperty", {
visitor: ["value"],
aliases: ["Flow", "UserWhitespacable"],
fields: {
@@ -237,7 +239,7 @@ define("ObjectTypeCallProperty", {
}
});
define("ObjectTypeIndexer", {
defineType("ObjectTypeIndexer", {
visitor: ["id", "key", "value"],
aliases: ["Flow", "UserWhitespacable"],
fields: {
@@ -245,7 +247,7 @@ define("ObjectTypeIndexer", {
}
});
define("ObjectTypeProperty", {
defineType("ObjectTypeProperty", {
visitor: ["key", "value"],
aliases: ["Flow", "UserWhitespacable"],
fields: {
@@ -253,7 +255,7 @@ define("ObjectTypeProperty", {
}
});
define("QualifiedTypeIdentifier", {
defineType("QualifiedTypeIdentifier", {
visitor: ["id", "qualification"],
aliases: ["Flow"],
fields: {
@@ -261,7 +263,7 @@ define("QualifiedTypeIdentifier", {
}
});
define("UnionTypeAnnotation", {
defineType("UnionTypeAnnotation", {
visitor: ["types"],
aliases: ["Flow"],
fields: {
@@ -269,7 +271,7 @@ define("UnionTypeAnnotation", {
}
});
define("VoidTypeAnnotation", {
defineType("VoidTypeAnnotation", {
aliases: ["Flow", "FlowBaseAnnotation"],
fields: {
// todo

View File

@@ -1,9 +1,11 @@
/* @flow */
import * as t from "../index";
export var VISITOR_KEYS = {};
export var ALIAS_KEYS = {};
export var NODE_FIELDS = {};
export var BUILDER_KEYS = {};
export let VISITOR_KEYS = {};
export let ALIAS_KEYS = {};
export let NODE_FIELDS = {};
export let BUILDER_KEYS = {};
function getType(val) {
if (Array.isArray(val)) {
@@ -17,37 +19,33 @@ function getType(val) {
}
}
export function assertContains(vals) {
return function (val, key) {
if (vals.indexOf(val) < 0) {
throw new TypeError(`Property ${key} with the value of ${JSON.stringify(val)} expected to be one of ${JSON.stringify(vals)}`);
}
};
}
export function assertEach(callback) {
export function assertEach(callback: Function): Function {
return function (node, key, val) {
if (!Array.isArray(val)) return;
for (var i = 0; i < val.length; i++) {
for (let i = 0; i < val.length; i++) {
callback(node, `${key}[${i}]`, val[i]);
}
};
}
export function assertOneOf(...vals) {
return function (node, key, val) {
export function assertOneOf(...vals): Function {
function validate(node, key, val) {
if (vals.indexOf(val) < 0) {
throw new TypeError(`Property ${key} expected value to be one of ${JSON.stringify(vals)} but got ${JSON.stringify(val)}`);
}
};
}
validate.oneOf = vals;
return validate;
}
export function assertNodeType(...types) {
return function (node, key, val) {
var valid = false;
export function assertNodeType(...types: Array<string>): Function {
function validate(node, key, val) {
let valid = false;
for (var type of types) {
for (let type of types) {
if (t.is(type, val)) {
valid = true;
break;
@@ -55,46 +53,66 @@ export function assertNodeType(...types) {
}
if (!valid) {
throw new TypeError(`Property ${key} expected node to be of a type ${JSON.stringify(types)} but instead got ${JSON.stringify(val && val.type)}`);
throw new TypeError(`Property ${key} of ${node.type} expected node to be of a type ${JSON.stringify(types)} but instead got ${JSON.stringify(val && val.type)}`);
}
};
}
validate.oneOfNodeTypes = types;
return validate;
}
export function assertValueType(type) {
return function (node, key, val) {
var valid = getType(val) === type;
export function assertValueType(type: string): Function {
function validate(node, key, val) {
let valid = getType(val) === type;
if (!valid) {
console.log(type, key, val);
throw new TypeError(`Property ${key} expected type of ${type} but got ${getType(val)}`);
}
};
}
validate.type = type;
return validate;
}
export function chain(...fns) {
export function chain(...fns: Array<Function>): Function {
return function (...args) {
for (var fn of fns) {
for (let fn of fns) {
fn(...args);
}
};
}
export default function define(type, opts = {}) {
opts.fields = opts.fields || {};
opts.visitor = opts.visitor || [];
opts.aliases = opts.aliases || [];
opts.builder = opts.builder || opts.visitor || [];
export default function defineType(
type: string,
opts: {
fields?: Object;
visitor?: Array<string>;
aliases?: Array<string>;
builder?: Array<string>;
inherits?: string;
} = {},
) {
let inherits = (opts.inherits && store[opts.inherits]) || {};
opts.fields = opts.fields || inherits.fields || {};
opts.visitor = opts.visitor || inherits.visitor || [];
opts.aliases = opts.aliases || inherits.aliases || [];
opts.builder = opts.builder || inherits.builder || opts.visitor || [];
// ensure all field keys are represented in `fields`
for (let key of (opts.visitor.concat(opts.builder): Array)) {
for (let key of (opts.visitor.concat(opts.builder): Array<string>)) {
opts.fields[key] = opts.fields[key] || {};
}
for (let key in opts.fields) {
var field = opts.fields[key];
let field = opts.fields[key];
if (field.default === undefined) {
field.default = null;
} else if (!field.validate) {
field.validate = assertValueType(getType(field.default));
}
}
@@ -102,4 +120,8 @@ export default function define(type, opts = {}) {
BUILDER_KEYS[type] = opts.builder;
NODE_FIELDS[type] = opts.fields;
ALIAS_KEYS[type] = opts.aliases;
store[type] = opts;
}
let store = {};

View File

@@ -1,6 +1,8 @@
import define, { assertNodeType, assertValueType, chain, assertEach } from "./index";
/* @flow */
define("JSXAttribute", {
import defineType, { assertNodeType, assertValueType, chain, assertEach } from "./index";
defineType("JSXAttribute", {
visitor: ["name", "value"],
aliases: ["JSX", "Immutable"],
fields: {
@@ -14,7 +16,7 @@ define("JSXAttribute", {
}
});
define("JSXClosingElement", {
defineType("JSXClosingElement", {
visitor: ["name"],
aliases: ["JSX", "Immutable"],
fields: {
@@ -24,7 +26,7 @@ define("JSXClosingElement", {
}
});
define("JSXElement", {
defineType("JSXElement", {
builder: ["openingElement", "closingElement", "children", "selfClosing"],
visitor: ["openingElement", "children", "closingElement"],
aliases: ["JSX", "Immutable", "Expression"],
@@ -42,11 +44,11 @@ define("JSXElement", {
}
});
define("JSXEmptyExpression", {
defineType("JSXEmptyExpression", {
aliases: ["JSX", "Expression"]
});
define("JSXExpressionContainer", {
defineType("JSXExpressionContainer", {
visitor: ["expression"],
aliases: ["JSX", "Immutable"],
fields: {
@@ -56,12 +58,17 @@ define("JSXExpressionContainer", {
}
});
define("JSXIdentifier", {
defineType("JSXIdentifier", {
builder: ["name"],
aliases: ["JSX", "Expression"]
aliases: ["JSX", "Expression"],
fields: {
name: {
validate: assertValueType("string")
}
}
});
define("JSXMemberExpression", {
defineType("JSXMemberExpression", {
visitor: ["object", "property"],
aliases: ["JSX", "Expression"],
fields: {
@@ -74,7 +81,7 @@ define("JSXMemberExpression", {
}
});
define("JSXNamespacedName", {
defineType("JSXNamespacedName", {
visitor: ["namespace", "name"],
aliases: ["JSX"],
fields: {
@@ -87,7 +94,7 @@ define("JSXNamespacedName", {
}
});
define("JSXOpeningElement", {
defineType("JSXOpeningElement", {
builder: ["name", "attributes", "selfClosing"],
visitor: ["name", "attributes"],
aliases: ["JSX", "Immutable"],
@@ -100,12 +107,15 @@ define("JSXOpeningElement", {
validate: assertValueType("boolean")
},
attributes: {
validate: chain(assertValueType("array"), assertEach(assertNodeType("JSXAttribute", "JSXSpreadAttribute")))
validate: chain(
assertValueType("array"),
assertEach(assertNodeType("JSXAttribute", "JSXSpreadAttribute"))
)
}
}
});
define("JSXSpreadAttribute", {
defineType("JSXSpreadAttribute", {
visitor: ["argument"],
aliases: ["JSX"],
fields: {
@@ -115,7 +125,7 @@ define("JSXSpreadAttribute", {
}
});
define("JSXText", {
defineType("JSXText", {
aliases: ["JSX"],
builder: ["value"],
fields: {

View File

@@ -1,15 +1,17 @@
import define, { assertNodeType } from "./index";
/* @flow */
define("Noop", {
import defineType, { assertNodeType } from "./index";
defineType("Noop", {
visitor: []
});
define("ParenthesizedExpression", {
defineType("ParenthesizedExpression", {
visitor: ["expression"],
aliases: ["Expression"],
aliases: ["Expression", "ExpressionWrapper"],
fields: {
expression: {
validate: assertNodeType("expression")
validate: assertNodeType("Expression")
}
}
});

View File

@@ -1,3 +1,5 @@
/* @flow */
import * as t from "./index";
/**
@@ -5,8 +7,8 @@ import * as t from "./index";
* returns a `UnionTypeAnnotation` node containg them.
*/
export function createUnionTypeAnnotation(types) {
var flattened = removeTypeDuplicates(types);
export function createUnionTypeAnnotation(types: Array<Object>) {
let flattened = removeTypeDuplicates(types);
if (flattened.length === 1) {
return flattened[0];
@@ -19,17 +21,17 @@ export function createUnionTypeAnnotation(types) {
* Dedupe type annotations.
*/
export function removeTypeDuplicates(nodes) {
var generics = {};
var bases = {};
export function removeTypeDuplicates(nodes: Array<Object>) {
let generics = {};
let bases = {};
// store union type groups to circular references
var typeGroups = [];
let typeGroups = [];
var types = [];
let types = [];
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i];
for (let i = 0; i < nodes.length; i++) {
let node = nodes[i];
if (!node) continue;
// detect duplicates
@@ -62,7 +64,7 @@ export function removeTypeDuplicates(nodes) {
let name = node.id.name;
if (generics[name]) {
var existing = generics[name];
let existing = generics[name];
if (existing.typeParameters) {
if (node.typeParameters) {
existing.typeParameters.params = removeTypeDuplicates(
@@ -83,7 +85,7 @@ export function removeTypeDuplicates(nodes) {
}
// add back in bases
for (var type in bases) {
for (let type in bases) {
types.push(bases[type]);
}
@@ -99,7 +101,7 @@ export function removeTypeDuplicates(nodes) {
* Create a type anotation based on typeof expression.
*/
export function createTypeAnnotationBasedOnTypeof(type) {
export function createTypeAnnotationBasedOnTypeof(type: string) {
if (type === "string") {
return t.stringTypeAnnotation();
} else if (type === "number") {

View File

@@ -1,11 +1,12 @@
/* @flow */
import toFastProperties from "to-fast-properties";
import compact from "lodash/array/compact";
import assign from "lodash/object/assign";
import loClone from "lodash/lang/clone";
import each from "lodash/collection/each";
import uniq from "lodash/array/uniq";
var t = exports;
let t = exports;
/**
* Registers `is[Type]` and `assert[Type]` generated functions for a given `type`.
@@ -13,7 +14,7 @@ var t = exports;
*/
function registerType(type: string, skipAliasCheck?: boolean) {
var is = t[`is${type}`] = function (node, opts) {
let is = t[`is${type}`] = function (node, opts) {
return t.is(type, node, opts, skipAliasCheck);
};
@@ -25,10 +26,6 @@ function registerType(type: string, skipAliasCheck?: boolean) {
};
}
/**
* Constants.
*/
export const STATEMENT_OR_BLOCK_KEYS = ["consequent", "body", "alternate"];
export const FLATTENABLE_KEYS = ["body", "expressions"];
export const FOR_INIT_KEYS = ["left", "init"];
@@ -52,15 +49,17 @@ export const STRING_UNARY_OPERATORS = ["typeof"];
import "./definitions/init";
import { VISITOR_KEYS, ALIAS_KEYS, NODE_FIELDS, BUILDER_KEYS } from "./definitions";
export { VISITOR_KEYS, ALIAS_KEYS, NODE_FIELDS, BUILDER_KEYS };
export * as react from "./react";
import * as _react from "./react";
export { _react as react };
/**
* Registers `is[Type]` and `assert[Type]` for all types.
*/
each(t.VISITOR_KEYS, function (keys, type) {
for (let type in t.VISITOR_KEYS) {
registerType(type, true);
});
}
/**
* Flip `ALIAS_KEYS` for faster access in the reverse direction.
@@ -70,7 +69,7 @@ t.FLIPPED_ALIAS_KEYS = {};
each(t.ALIAS_KEYS, function (aliases, type) {
each(aliases, function (alias) {
var types = t.FLIPPED_ALIAS_KEYS[alias] = t.FLIPPED_ALIAS_KEYS[alias] || [];
let types = t.FLIPPED_ALIAS_KEYS[alias] = t.FLIPPED_ALIAS_KEYS[alias] || [];
types.push(type);
});
});
@@ -93,12 +92,10 @@ export const TYPES = Object.keys(t.VISITOR_KEYS).concat(Object.keys(t.FLIPPED_AL
* Optionally, pass `skipAliasCheck` to directly compare `node.type` with `type`.
*/
// @TODO should `skipAliasCheck` be removed?
/*eslint-disable no-unused-vars */
export function is(type: string, node: Object, opts?: Object, skipAliasCheck?: boolean): boolean {
export function is(type: string, node: Object, opts?: Object): boolean {
if (!node) return false;
var matches = isType(node.type, type);
let matches = isType(node.type, type);
if (!matches) return false;
if (typeof opts === "undefined") {
@@ -107,7 +104,6 @@ export function is(type: string, node: Object, opts?: Object, skipAliasCheck?: b
return t.shallowEqual(node, opts);
}
}
/*eslint-enable no-unused-vars */
/**
* Test if a `nodeType` is a `targetType` or if `targetType` is an alias of `nodeType`.
@@ -116,11 +112,11 @@ export function is(type: string, node: Object, opts?: Object, skipAliasCheck?: b
export function isType(nodeType: string, targetType: string): boolean {
if (nodeType === targetType) return true;
var aliases = t.FLIPPED_ALIAS_KEYS[targetType];
let aliases = t.FLIPPED_ALIAS_KEYS[targetType];
if (aliases) {
if (aliases[0] === nodeType) return true;
for (var alias of (aliases: Array)) {
for (let alias of (aliases: Array<string>)) {
if (nodeType === alias) return true;
}
}
@@ -134,15 +130,15 @@ each(t.BUILDER_KEYS, function (keys, type) {
// todo: error
}
var node = {};
let node = {};
node.type = type;
var i = 0;
let i = 0;
for (let key of (keys: Array)) {
var field = t.NODE_FIELDS[type][key];
for (let key of (keys: Array<string>)) {
let field = t.NODE_FIELDS[type][key];
var arg = arguments[i++];
let arg = arguments[i++];
if (arg === undefined) arg = loClone(field.default);
node[key] = arg;
@@ -163,13 +159,13 @@ each(t.BUILDER_KEYS, function (keys, type) {
* Description
*/
export function validate(node, key, val) {
export function validate(node?: Object, key: string, val: any) {
if (!node) return;
var fields = t.NODE_FIELDS[node.type];
let fields = t.NODE_FIELDS[node.type];
if (!fields) return;
var field = fields[key];
let field = fields[key];
if (!field || !field.validate) return;
if (field.optional && val == null) return;
@@ -181,9 +177,9 @@ export function validate(node, key, val) {
*/
export function shallowEqual(actual: Object, expected: Object): boolean {
var keys = Object.keys(expected);
let keys = Object.keys(expected);
for (var key of (keys: Array)) {
for (let key of (keys: Array<string>)) {
if (actual[key] !== expected[key]) {
return false;
}
@@ -217,7 +213,7 @@ export function prependToMemberExpression(member: Object, prepend: Object): Obje
* Casting it to a block if it is not.
*/
export function ensureBlock(node: Object, key: string = "body") {
export function ensureBlock(node: Object, key: string = "body"): Object {
return node[key] = t.toBlock(node[key], node);
}
@@ -226,8 +222,8 @@ export function ensureBlock(node: Object, key: string = "body") {
*/
export function clone(node: Object): Object {
var newNode = {};
for (var key in node) {
let newNode = {};
for (let key in node) {
if (key[0] === "_") continue;
newNode[key] = node[key];
}
@@ -240,12 +236,12 @@ export function clone(node: Object): Object {
*/
export function cloneDeep(node: Object): Object {
var newNode = {};
let newNode = {};
for (var key in node) {
for (let key in node) {
if (key[0] === "_") continue;
var val = node[key];
let val = node[key];
if (val) {
if (val.type) {
@@ -270,17 +266,17 @@ export function cloneDeep(node: Object): Object {
*/
export function buildMatchMemberExpression(match:string, allowPartial?: boolean): Function {
var parts = match.split(".");
let parts = match.split(".");
return function (member) {
// not a member expression
if (!t.isMemberExpression(member)) return false;
var search = [member];
var i = 0;
let search = [member];
let i = 0;
while (search.length) {
var node = search.shift();
let node = search.shift();
if (allowPartial && i === parts.length) {
return true;
@@ -321,7 +317,7 @@ export function buildMatchMemberExpression(match:string, allowPartial?: boolean)
*/
export function removeComments(node: Object): Object {
for (var key of (COMMENT_KEYS: Array)) {
for (let key of COMMENT_KEYS) {
delete node[key];
}
return node;
@@ -338,15 +334,15 @@ export function inheritsComments(child: Object, parent: Object): Object {
return child;
}
export function inheritTrailingComments(child, parent) {
export function inheritTrailingComments(child: Object, parent: Object) {
_inheritComments("trailingComments", child, parent);
}
export function inheritLeadingComments(child, parent) {
export function inheritLeadingComments(child: Object, parent: Object) {
_inheritComments("leadingComments", child, parent);
}
export function inheritInnerComments(child, parent) {
export function inheritInnerComments(child: Object, parent: Object) {
_inheritComments("innerComments", child, parent);
}
@@ -363,13 +359,13 @@ function _inheritComments(key, child, parent) {
export function inherits(child: Object, parent: Object): Object {
if (!child || !parent) return child;
for (let key of (t.INHERIT_KEYS.optional: Array)) {
for (let key of (t.INHERIT_KEYS.optional: Array<string>)) {
if (child[key] == null) {
child[key] = parent[key];
}
}
for (let key of (t.INHERIT_KEYS.force: Array)) {
for (let key of (t.INHERIT_KEYS.force: Array<string>)) {
child[key] = parent[key];
}
@@ -379,19 +375,29 @@ export function inherits(child: Object, parent: Object): Object {
}
/**
* Description
* TODO
*/
export function directive(value) {
return t.expressionStatement(t.literal(value));
export function assertNode(node?) {
if (!isNode(node)) {
throw new TypeError("Not a valid node " + (node && node.type));
}
}
/**
* TODO
*/
export function isNode(node?): boolean {
return !!(node && VISITOR_KEYS[node.type]);
}
// Optimize property access.
toFastProperties(t);
toFastProperties(t.VISITOR_KEYS);
// Export all type checkers from other files.
assign(t, require("./retrievers"));
assign(t, require("./validators"));
assign(t, require("./converters"));
assign(t, require("./flow"));
//
export * from "./retrievers";
export * from "./validators";
export * from "./converters";
export * from "./flow";

View File

@@ -1,15 +1,20 @@
/* @flow */
import * as t from "./index";
export var isReactComponent = t.buildMatchMemberExpression("React.Component");
export let isReactComponent = t.buildMatchMemberExpression("React.Component");
export function isCompatTag(tagName) {
return tagName && /^[a-z]|\-/.test(tagName);
export function isCompatTag(tagName?: string): boolean {
return !!tagName && /^[a-z]|\-/.test(tagName);
}
function cleanJSXElementLiteralChild(child, args) {
var lines = child.value.split(/\r\n|\n|\r/);
function cleanJSXElementLiteralChild(
child: { value: string },
args: Array<Object>,
) {
let lines = child.value.split(/\r\n|\n|\r/);
var lastNonEmptyLine = 0;
let lastNonEmptyLine = 0;
for (let i = 0; i < lines.length; i++) {
if (lines[i].match(/[^ \t]/)) {
@@ -17,17 +22,17 @@ function cleanJSXElementLiteralChild(child, args) {
}
}
var str = "";
let str = "";
for (let i = 0; i < lines.length; i++) {
var line = lines[i];
let line = lines[i];
var isFirstLine = i === 0;
var isLastLine = i === lines.length - 1;
var isLastNonEmptyLine = i === lastNonEmptyLine;
let isFirstLine = i === 0;
let isLastLine = i === lines.length - 1;
let isLastNonEmptyLine = i === lastNonEmptyLine;
// replace rendered whitespace tabs with spaces
var trimmedLine = line.replace(/\t/g, " ");
let trimmedLine = line.replace(/\t/g, " ");
// trim whitespace touching a newline
if (!isFirstLine) {
@@ -51,11 +56,11 @@ function cleanJSXElementLiteralChild(child, args) {
if (str) args.push(t.stringLiteral(str));
}
export function buildChildren(node) {
var elems = [];
export function buildChildren(node: Object): Array<Object> {
let elems = [];
for (var i = 0; i < node.children.length; i++) {
var child = node.children[i];
for (let i = 0; i < node.children.length; i++) {
let child = node.children[i];
if (t.isJSXText(child)) {
cleanJSXElementLiteralChild(child, elems);

View File

@@ -1,22 +1,27 @@
/* @flow */
import * as t from "./index";
/**
* Return a list of binding identifiers associated with the input `node`.
*/
export function getBindingIdentifiers(node: Object, duplicates?): Object {
var search = [].concat(node);
var ids = Object.create(null);
export function getBindingIdentifiers(
node: Object,
duplicates?: boolean,
): Object {
let search = [].concat(node);
let ids = Object.create(null);
while (search.length) {
var id = search.shift();
let id = search.shift();
if (!id) continue;
var keys = t.getBindingIdentifiers.keys[id.type];
let keys = t.getBindingIdentifiers.keys[id.type];
if (t.isIdentifier(id)) {
if (duplicates) {
var _ids = ids[id.name] = ids[id.name] || [];
let _ids = ids[id.name] = ids[id.name] || [];
_ids.push(id);
} else {
ids[id.name] = id;
@@ -26,8 +31,8 @@ export function getBindingIdentifiers(node: Object, duplicates?): Object {
search.push(node.declaration);
}
} else if (keys) {
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
if (id[key]) {
search = search.concat(id[key]);
}
@@ -63,6 +68,10 @@ getBindingIdentifiers.keys = {
ImportDefaultSpecifier: ["local"],
ImportDeclaration: ["specifiers"],
ExportSpecifier: ["exported"],
ExportNamespaceSpecifier: ["exported"],
ExportDefaultSpecifier: ["exported"],
FunctionDeclaration: ["id", "params"],
FunctionExpression: ["id", "params"],
@@ -73,7 +82,7 @@ getBindingIdentifiers.keys = {
UpdateExpression: ["argument"],
SpreadProperty: ["argument"],
Property: ["value"],
ObjectProperty: ["value"],
AssignmentPattern: ["left"],
ArrayPattern: ["elements"],

View File

@@ -1,3 +1,5 @@
/* @flow */
import { getBindingIdentifiers } from "./retrievers";
import esutils from "esutils";
import * as t from "./index";
@@ -7,11 +9,11 @@ import * as t from "./index";
*/
export function isBinding(node: Object, parent: Object): boolean {
var keys = getBindingIdentifiers.keys[parent.type];
let keys = getBindingIdentifiers.keys[parent.type];
if (keys) {
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
var val = parent[key];
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
let val = parent[key];
if (Array.isArray(val)) {
if (val.indexOf(node) >= 0) return true;
} else {
@@ -51,13 +53,13 @@ export function isReferenced(node: Object, parent: Object): boolean {
// yes: { [NODE]: "" }
// yes: { NODE }
// no: { NODE: "" }
case "Property":
case "ObjectProperty":
if (parent.key === node) {
return parent.computed;
}
// no: var NODE = init;
// yes: var id = NODE;
// no: let NODE = init;
// yes: let id = NODE;
case "VariableDeclarator":
return parent.id !== node;
@@ -66,7 +68,7 @@ export function isReferenced(node: Object, parent: Object): boolean {
case "ArrowFunctionExpression":
case "FunctionDeclaration":
case "FunctionExpression":
for (var param of (parent.params: Array)) {
for (let param of (parent.params: Array)) {
if (param === node) return false;
}
@@ -113,7 +115,7 @@ export function isReferenced(node: Object, parent: Object): boolean {
return parent.id !== node;
// yes: class { [NODE](){} }
case "MethodDefinition":
case "ClassMethod":
return parent.key === node && parent.computed;
// no: NODE: for (;;) {}
@@ -134,9 +136,9 @@ export function isReferenced(node: Object, parent: Object): boolean {
return parent.right === node;
// no: [NODE = foo] = [];
// no: [foo = NODE] = [];
// yes: [foo = NODE] = [];
case "AssignmentPattern":
return false;
return parent.right === node;
// no: [NODE] = [];
// no: ({ NODE }) = [];