From e945f0d10f57151fa776f4aff3a1618bcd7be20c Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 1 Mar 2015 00:32:36 +1100 Subject: [PATCH] add support for outputting flow types - fixes #665 --- package.json | 2 +- src/babel/generation/generators/classes.js | 15 +- src/babel/generation/generators/flow.js | 260 +++++++++++++++--- src/babel/generation/generators/methods.js | 12 +- src/babel/generation/generators/statements.js | 5 +- src/babel/generation/generators/types.js | 20 +- src/babel/generation/index.js | 2 +- src/babel/generation/node/parentheses.js | 13 +- .../transformers/internal/cleanup.js | 18 +- .../transformation/transformers/other/flow.js | 13 + src/babel/traversal/context.js | 2 +- src/babel/traversal/index.js | 2 +- src/babel/traversal/scope.js | 2 +- src/babel/types/alias-keys.json | 33 +++ src/babel/types/index.js | 4 + src/babel/types/visitor-keys.json | 69 ++--- src/babel/util.js | 2 +- test/_helper.js | 2 +- test/_transformation-helper.js | 2 +- .../generation/flow/array-types/actual.js | 6 + .../generation/flow/array-types/expected.js | 6 + .../generation/flow/call-properties/actual.js | 5 + .../flow/call-properties/expected.js | 5 + .../generation/flow/declare-module/actual.js | 5 + .../flow/declare-module/expected.js | 11 + .../flow/declare-statements/actual.js | 11 + .../flow/declare-statements/expected.js | 11 + .../interfaces-module-and-script/actual.js | 9 + .../interfaces-module-and-script/expected.js | 9 + .../flow/qualified-generic-type/actual.js | 4 + .../flow/qualified-generic-type/expected.js | 4 + .../flow/string-literal-types/actual.js | 2 + .../flow/string-literal-types/expected.js | 2 + .../fixtures/generation/flow/tuples/actual.js | 4 + .../generation/flow/tuples/expected.js | 4 + .../generation/flow/type-alias/actual.js | 3 + .../generation/flow/type-alias/expected.js | 3 + .../flow/type-annotations/actual.js | 97 +++++++ .../flow/type-annotations/expected.js | 101 +++++++ .../generation/flow/typecasts/actual.js | 4 + .../generation/flow/typecasts/expected.js | 4 + .../fixtures/transformation/flow/options.json | 5 + .../flow/strip-array-types/actual.js | 6 + .../flow/strip-array-types/expected.js | 6 + .../flow/strip-call-properties/actual.js | 5 + .../flow/strip-call-properties/expected.js | 4 + .../flow/strip-declare-module/actual.js | 5 + .../flow/strip-declare-statements/actual.js | 11 + .../actual.js | 9 + .../expected.js | 4 + .../strip-qualified-generic-type/actual.js | 4 + .../strip-qualified-generic-type/expected.js | 4 + .../flow/strip-string-literal-types/actual.js | 2 + .../strip-string-literal-types/expected.js | 2 + .../flow/strip-tuples/actual.js | 4 + .../flow/strip-tuples/expected.js | 4 + .../flow/strip-type-alias/actual.js | 3 + .../flow/strip-type-annotations/actual.js | 97 +++++++ .../flow/strip-type-annotations/expected.js | 92 +++++++ .../flow/strip-typecasts/actual.js | 4 + .../flow/strip-typecasts/expected.js | 4 + 61 files changed, 965 insertions(+), 98 deletions(-) create mode 100644 test/fixtures/generation/flow/array-types/actual.js create mode 100644 test/fixtures/generation/flow/array-types/expected.js create mode 100644 test/fixtures/generation/flow/call-properties/actual.js create mode 100644 test/fixtures/generation/flow/call-properties/expected.js create mode 100644 test/fixtures/generation/flow/declare-module/actual.js create mode 100644 test/fixtures/generation/flow/declare-module/expected.js create mode 100644 test/fixtures/generation/flow/declare-statements/actual.js create mode 100644 test/fixtures/generation/flow/declare-statements/expected.js create mode 100644 test/fixtures/generation/flow/interfaces-module-and-script/actual.js create mode 100644 test/fixtures/generation/flow/interfaces-module-and-script/expected.js create mode 100644 test/fixtures/generation/flow/qualified-generic-type/actual.js create mode 100644 test/fixtures/generation/flow/qualified-generic-type/expected.js create mode 100644 test/fixtures/generation/flow/string-literal-types/actual.js create mode 100644 test/fixtures/generation/flow/string-literal-types/expected.js create mode 100644 test/fixtures/generation/flow/tuples/actual.js create mode 100644 test/fixtures/generation/flow/tuples/expected.js create mode 100644 test/fixtures/generation/flow/type-alias/actual.js create mode 100644 test/fixtures/generation/flow/type-alias/expected.js create mode 100644 test/fixtures/generation/flow/type-annotations/actual.js create mode 100644 test/fixtures/generation/flow/type-annotations/expected.js create mode 100644 test/fixtures/generation/flow/typecasts/actual.js create mode 100644 test/fixtures/generation/flow/typecasts/expected.js create mode 100644 test/fixtures/transformation/flow/options.json create mode 100644 test/fixtures/transformation/flow/strip-array-types/actual.js create mode 100644 test/fixtures/transformation/flow/strip-array-types/expected.js create mode 100644 test/fixtures/transformation/flow/strip-call-properties/actual.js create mode 100644 test/fixtures/transformation/flow/strip-call-properties/expected.js create mode 100644 test/fixtures/transformation/flow/strip-declare-module/actual.js create mode 100644 test/fixtures/transformation/flow/strip-declare-statements/actual.js create mode 100644 test/fixtures/transformation/flow/strip-interfaces-module-and-script/actual.js create mode 100644 test/fixtures/transformation/flow/strip-interfaces-module-and-script/expected.js create mode 100644 test/fixtures/transformation/flow/strip-qualified-generic-type/actual.js create mode 100644 test/fixtures/transformation/flow/strip-qualified-generic-type/expected.js create mode 100644 test/fixtures/transformation/flow/strip-string-literal-types/actual.js create mode 100644 test/fixtures/transformation/flow/strip-string-literal-types/expected.js create mode 100644 test/fixtures/transformation/flow/strip-tuples/actual.js create mode 100644 test/fixtures/transformation/flow/strip-tuples/expected.js create mode 100644 test/fixtures/transformation/flow/strip-type-alias/actual.js create mode 100644 test/fixtures/transformation/flow/strip-type-annotations/actual.js create mode 100644 test/fixtures/transformation/flow/strip-type-annotations/expected.js create mode 100644 test/fixtures/transformation/flow/strip-typecasts/actual.js create mode 100644 test/fixtures/transformation/flow/strip-typecasts/expected.js diff --git a/package.json b/package.json index 1e0ec5e746..e3c6a951ac 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "test": "make test" }, "dependencies": { - "acorn-babel": "0.11.1-35", + "acorn-babel": "0.11.1-37", "ast-types": "~0.6.1", "chalk": "^1.0.0", "chokidar": "^0.12.6", diff --git a/src/babel/generation/generators/classes.js b/src/babel/generation/generators/classes.js index 3f106eb216..4dbedb4152 100644 --- a/src/babel/generation/generators/classes.js +++ b/src/babel/generation/generators/classes.js @@ -1,5 +1,4 @@ -exports.ClassExpression = -exports.ClassDeclaration = function (node, print) { +export function ClassDeclaration(node, print) { this.push("class"); if (node.id) { @@ -7,14 +6,24 @@ exports.ClassDeclaration = function (node, print) { print(node.id); } + print(node.typeParameters); + if (node.superClass) { this.push(" extends "); print(node.superClass); + print(node.superTypeParameters); + } + + if (node.implements) { + this.push(" implements "); + print.join(node.implements, { separator: ", " }); } this.space(); print(node.body); -}; +} + +export { ClassDeclaration as ClassExpression }; export function ClassBody(node, print) { if (node.body.length === 0) { diff --git a/src/babel/generation/generators/flow.js b/src/babel/generation/generators/flow.js index 61a7abfb23..661fd1c740 100644 --- a/src/babel/generation/generators/flow.js +++ b/src/babel/generation/generators/flow.js @@ -1,34 +1,226 @@ -exports.AnyTypeAnnotation = -exports.ArrayTypeAnnotation = -exports.BooleanTypeAnnotation = -exports.ClassProperty = -exports.DeclareClass = -exports.DeclareFunction = -exports.DeclareModule = -exports.DeclareVariable = -exports.FunctionTypeAnnotation = -exports.FunctionTypeParam = -exports.GenericTypeAnnotation = -exports.InterfaceExtends = -exports.InterfaceDeclaration = -exports.IntersectionTypeAnnotation = -exports.NullableTypeAnnotation = -exports.NumberTypeAnnotation = -exports.StringLiteralTypeAnnotation = -exports.StringTypeAnnotation = -exports.TupleTypeAnnotation = -exports.TypeofTypeAnnotation = -exports.TypeAlias = -exports.TypeAnnotation = -exports.TypeParameterDeclaration = -exports.TypeParameterInstantiation = -exports.ObjectTypeAnnotation = -exports.ObjectTypeCallProperty = -exports.ObjectTypeIndexer = -exports.ObjectTypeProperty = -exports.QualifiedTypeIdentifier = -exports.UnionTypeAnnotation = -exports.TypeCastExpression = -exports.VoidTypeAnnotation = function () { - // todo: implement these once we have a `--keep-types` option -}; +import t from "../../types"; + +export function AnyTypeAnnotation() { + this.push("any"); +} + +export function ArrayTypeAnnotation(node, print) { + print(node.elementType); + this.push("["); + this.push("]"); +} + +export function BooleanTypeAnnotation(node) { + this.push("bool"); +} + +export function ClassProperty(node, print) { + if (node.static) this.push("static "); + print(node.key); + print(node.typeAnnotation); + this.semicolon(); +} + +export function DeclareClass(node, print) { + this.push("declare class "); + this._interfaceish(node, print); +} + +export function DeclareFunction(node, print) { + this.push("declare function "); + print(node.id); + print(node.id.typeAnnotation.typeAnnotation); + this.semicolon(); +} + +export function DeclareModule(node, print) { + this.push("declare module "); + print(node.id); + this.space(); + print(node.body); +} + +export function DeclareVariable(node, print) { + this.push("declare var "); + print(node.id); + print(node.id.typeAnnotation); + this.semicolon(); +} + +export function FunctionTypeAnnotation(node, print, parent) { + print(node.typeParameters); + this.push("("); + print.list(node.params); + + if (node.rest) { + if (node.params.length) { + this.push(","); + this.space(); + } + this.push("..."); + print(node.rest); + } + + this.push(")"); + + // this node type is overloaded, not sure why but it makes it EXTREMELY annoying + if (parent.type === "ObjectTypeProperty" || parent.type === "ObjectTypeCallProperty" || parent.type === "DeclareFunction") { + this.push(":"); + } else { + this.space(); + this.push("=>"); + } + + this.space(); + print(node.returnType); +} + +export function FunctionTypeParam(node, print) { + print(node.name); + if (node.optional) this.push("?"); + this.push(":"); + this.space(); + print(node.typeAnnotation); +} + +export function InterfaceExtends(node, print) { + print(node.id); + print(node.typeParameters); +} + +export { InterfaceExtends as ClassImplements, InterfaceExtends as GenericTypeAnnotation }; + +export function _interfaceish(node, print) { + print(node.id); + print(node.typeParameters); + if (node.extends.length) { + this.push(" extends "); + print.join(node.extends, { separator: ", " }); + } + this.space(); + print(node.body); +} + +export function InterfaceDeclaration(node, print) { + this.push("interface "); + this._interfaceish(node, print); +} + +export function IntersectionTypeAnnotation(node, print) { + print.join(node.types, { separator: " & " }); +} + +export function NullableTypeAnnotation(node, print) { + this.push("?"); + print(node.typeAnnotation); +} + +export function NumberTypeAnnotation() { + this.push("number"); +} + +export function StringLiteralTypeAnnotation(node) { + this._stringLiteral(node.value); +} + +export function StringTypeAnnotation() { + this.push("string"); +} + +export function TupleTypeAnnotation(node, print) { + this.push("["); + print.join(node.types, { separator: ", " }); + this.push("]"); +} + +export function TypeofTypeAnnotation(node, print) { + this.push("typeof "); + print(node.argument); +} + +export function TypeAlias(node, print) { + this.push("type "); + print(node.id); + print(node.typeParameters); + this.space(); + this.push("="); + this.space(); + print(node.right); + this.semicolon(); +} + +export function TypeAnnotation(node, print) { + this.push(":"); + this.space(); + if (node.optional) this.push("?"); + print(node.typeAnnotation); +} + +export function TypeParameterInstantiation(node, print) { + this.push("<"); + print.join(node.params, { separator: ", " }); + this.push(">"); +} + +export { TypeParameterInstantiation as TypeParameterDeclaration }; + +export function ObjectTypeAnnotation(node, print) { + this.push("{"); + var props = node.properties.concat(node.callProperties, node.indexers); + if (props.length) { + this.space(); + print.list(props, { indent: true, separator: "; " }); + this.space(); + } + this.push("}"); +} + +export function ObjectTypeCallProperty(node, print) { + if (node.static) this.push("static "); + print(node.value); +} + +export function ObjectTypeIndexer(node, print) { + if (node.static) this.push("static "); + this.push("["); + print(node.id); + this.push(":"); + this.space(); + print(node.key); + this.push("]"); + this.push(":"); + this.space(); + print(node.value); +} + +export function ObjectTypeProperty(node, print) { + if (node.static) this.push("static "); + print(node.key); + if (node.optional) this.push("?"); + if (!t.isFunctionTypeAnnotation(node.value)) { + this.push(":"); + this.space(); + } + print(node.value); +} + +export function QualifiedTypeIdentifier(node, print) { + print(node.qualification); + this.push("."); + print(node.id); +} + +export function UnionTypeAnnotation(node, print) { + print.join(node.types, { separator: " | " }); +} + +export function TypeCastExpression(node, print) { + this.push("("); + print(node.expression); + print(node.typeAnnotation); + this.push(")"); +} + +export function VoidTypeAnnotation(node) { + this.push("void"); +} diff --git a/src/babel/generation/generators/methods.js b/src/babel/generation/generators/methods.js index 6c12ff8b71..3c170ab785 100644 --- a/src/babel/generation/generators/methods.js +++ b/src/babel/generation/generators/methods.js @@ -1,9 +1,19 @@ import t from "../../types"; export function _params(node, print) { + print(node.typeParameters); this.push("("); - print.list(node.params); + print.list(node.params, { + iterator: (node) =>{ + if (node.optional) this.push("?"); + print(node.typeAnnotation); + } + }); this.push(")"); + + if (node.returnType) { + print(node.returnType); + } } export function _method(node, print) { diff --git a/src/babel/generation/generators/statements.js b/src/babel/generation/generators/statements.js index 7c621031a3..7ffdbd015f 100644 --- a/src/babel/generation/generators/statements.js +++ b/src/babel/generation/generators/statements.js @@ -211,13 +211,12 @@ export function PrivateDeclaration(node, print) { } export function VariableDeclarator(node, print) { + print(node.id); + print(node.id.typeAnnotation); if (node.init) { - print(node.id); this.space(); this.push("="); this.space(); print(node.init); - } else { - print(node.id); } } diff --git a/src/babel/generation/generators/types.js b/src/babel/generation/generators/types.js index ca7d0e0461..87b6d5da4a 100644 --- a/src/babel/generation/generators/types.js +++ b/src/babel/generation/generators/types.js @@ -83,14 +83,7 @@ export function Literal(node) { var type = typeof val; if (type === "string") { - val = JSON.stringify(val); - - // escape illegal js but valid json unicode characters - val = val.replace(/[\u000A\u000D\u2028\u2029]/g, function (c) { - return "\\u" + ("0000" + c.charCodeAt(0).toString(16)).slice(-4); - }); - - this.push(val); + this._stringLiteral(val); } else if (type === "number") { this.push(val + ""); } else if (type === "boolean") { @@ -101,3 +94,14 @@ export function Literal(node) { this.push("null"); } } + +export function _stringLiteral(val) { + val = JSON.stringify(val); + + // escape illegal js but valid json unicode characters + val = val.replace(/[\u000A\u000D\u2028\u2029]/g, function (c) { + return "\\u" + ("0000" + c.charCodeAt(0).toString(16)).slice(-4); + }); + + this.push(val); +} diff --git a/src/babel/generation/index.js b/src/babel/generation/index.js index 707434510f..6fdadfe589 100644 --- a/src/babel/generation/index.js +++ b/src/babel/generation/index.js @@ -117,7 +117,7 @@ class CodeGenerator { } print(node, parent, opts = {}) { - if (!node) return ""; + if (!node) return; if (parent && parent._compact) { node._compact = true; diff --git a/src/babel/generation/node/parentheses.js b/src/babel/generation/node/parentheses.js index 34d7589117..3645a2b089 100644 --- a/src/babel/generation/node/parentheses.js +++ b/src/babel/generation/node/parentheses.js @@ -21,6 +21,12 @@ each([ }); }); +export function NullableTypeAnnotation(node, parent) { + return t.isArrayTypeAnnotation(parent); +} + +export { NullableTypeAnnotation as FunctionTypeAnnotation }; + export function UpdateExpression(node, parent) { if (t.isMemberExpression(parent) && parent.object === node) { // (foo++).test() @@ -139,8 +145,7 @@ export function FunctionExpression(node, parent) { } } -exports.AssignmentExpression = -exports.ConditionalExpression = function (node, parent) { +export function ConditionalExpression(node, parent) { if (t.isUnaryLike(parent)) { return true; } @@ -164,4 +169,6 @@ exports.ConditionalExpression = function (node, parent) { } return false; -}; +} + +export { ConditionalExpression as AssignmentExpression }; diff --git a/src/babel/transformation/transformers/internal/cleanup.js b/src/babel/transformation/transformers/internal/cleanup.js index 9c0108fcd3..3fa88bf811 100644 --- a/src/babel/transformation/transformers/internal/cleanup.js +++ b/src/babel/transformation/transformers/internal/cleanup.js @@ -1,5 +1,15 @@ -export function SequenceExpression(node) { - if (node.expressions.length === 1) { - return node.expressions[0]; +export var SequenceExpression = { + exit(node) { + if (node.expressions.length === 1) { + return node.expressions[0]; + } else if (!node.expressions.length) { + this.remove(); + } } -} +}; + +export var ExpressionStatement = { + exit(node) { + if (!node.expression) this.remove(); + } +}; diff --git a/src/babel/transformation/transformers/other/flow.js b/src/babel/transformation/transformers/other/flow.js index 886ff8743d..821336f65b 100644 --- a/src/babel/transformation/transformers/other/flow.js +++ b/src/babel/transformation/transformers/other/flow.js @@ -1,5 +1,18 @@ import t from "../../../types"; +export function Flow(node) { + this.remove(); +} + +export function ClassProperty(node) { + node.typeAnnotation = null; + if (!node.value) this.remove(); +} + +export function Class(node) { + node.implements = null; +} + export function TypeCastExpression(node) { return node.expression; } diff --git a/src/babel/traversal/context.js b/src/babel/traversal/context.js index 7a2d6e0449..c431fd3c4d 100644 --- a/src/babel/traversal/context.js +++ b/src/babel/traversal/context.js @@ -43,7 +43,7 @@ export default class TraversalConext { if (this.shouldFlatten) { node[key] = flatten(node[key]); - if (key === "body") { + if (key === "body" || key === "expressions") { // we can safely compact this node[key] = compact(node[key]); } diff --git a/src/babel/traversal/index.js b/src/babel/traversal/index.js index bc8bb8d33b..31a45c6462 100644 --- a/src/babel/traversal/index.js +++ b/src/babel/traversal/index.js @@ -84,7 +84,7 @@ traverse.explode = function (obj) { var aliases = t.FLIPPED_ALIAS_KEYS[type]; if (aliases) { for (var i = 0; i < aliases.length; i++) { - obj[aliases[i]] = fns; + obj[aliases[i]] ||= fns; } } } diff --git a/src/babel/traversal/scope.js b/src/babel/traversal/scope.js index 3b0df2f911..e24dbc5f27 100644 --- a/src/babel/traversal/scope.js +++ b/src/babel/traversal/scope.js @@ -299,7 +299,7 @@ export default class Scope { var info = this.getBindingInfo(name); if (!info) return; - info.identifier.typeAnnotation = info.typeAnnotation = type; + info.typeAnnotation = type; } getTypeAnnotation(name, id, node) { diff --git a/src/babel/types/alias-keys.json b/src/babel/types/alias-keys.json index 059f50e156..05d265b7dd 100644 --- a/src/babel/types/alias-keys.json +++ b/src/babel/types/alias-keys.json @@ -71,6 +71,39 @@ "JSXMemberExpression": ["Expression"], "YieldExpression": ["Expression"], + "AnyTypeAnnotation": ["Flow"], + "ArrayTypeAnnotation": ["Flow"], + "BooleanTypeAnnotation": ["Flow"], + "ClassImplements": ["Flow"], + "DeclareClass": ["Flow"], + "DeclareFunction": ["Flow"], + "DeclareModule": ["Flow"], + "DeclareVariable": ["Flow"], + "FunctionTypeAnnotation": ["Flow"], + "FunctionTypeParam": ["Flow"], + "GenericTypeAnnotation": ["Flow"], + "InterfaceExtends": ["Flow"], + "InterfaceDeclaration": ["Flow"], + "IntersectionTypeAnnotation": ["Flow"], + "NullableTypeAnnotation": ["Flow"], + "NumberTypeAnnotation": ["Flow"], + "StringLiteralTypeAnnotation": ["Flow"], + "StringTypeAnnotation": ["Flow"], + "TupleTypeAnnotation": ["Flow"], + "TypeofTypeAnnotation": ["Flow"], + "TypeAlias": ["Flow"], + "TypeAnnotation": ["Flow"], + "TypeCastExpression": ["Flow"], + "TypeParameterDeclaration": ["Flow"], + "TypeParameterInstantiation": ["Flow"], + "ObjectTypeAnnotation": ["Flow"], + "ObjectTypeCallProperty": ["Flow"], + "ObjectTypeIndexer": ["Flow"], + "ObjectTypeProperty": ["Flow"], + "QualifiedTypeIdentifier": ["Flow"], + "UnionTypeAnnotation": ["Flow"], + "VoidTypeAnnotation": ["Flow"], + "JSXAttribute": ["JSX"], "JSXClosingElement": ["JSX"], "JSXElement": ["JSX", "Expression"], diff --git a/src/babel/types/index.js b/src/babel/types/index.js index 98d8a8d1d9..7cca6db416 100644 --- a/src/babel/types/index.js +++ b/src/babel/types/index.js @@ -709,6 +709,10 @@ t.inherits = function (child, parent) { child.start = parent.start; child.loc = parent.loc; child.end = parent.end; + + child.typeAnnotation = parent.typeAnnotation; + child.returnType = parent.returnType; + t.inheritsComments(child, parent); return child; }; diff --git a/src/babel/types/visitor-keys.json b/src/babel/types/visitor-keys.json index dd3a0f41ea..e3ad4a629e 100644 --- a/src/babel/types/visitor-keys.json +++ b/src/babel/types/visitor-keys.json @@ -1,7 +1,7 @@ { "ArrayExpression": ["elements"], - "ArrayPattern": ["elements"], - "ArrowFunctionExpression": ["params", "defaults", "rest", "body"], + "ArrayPattern": ["elements", "typeAnnotation"], + "ArrowFunctionExpression": ["params", "defaults", "rest", "body", "returnType"], "AssignmentExpression": ["left", "right"], "AssignmentPattern": ["left", "right"], "AwaitExpression": ["argument"], @@ -13,8 +13,8 @@ "CallExpression": ["callee", "arguments"], "CatchClause": ["param", "body"], "ClassBody": ["body"], - "ClassDeclaration": ["id", "body", "superClass"], - "ClassExpression": ["id", "body", "superClass"], + "ClassDeclaration": ["id", "body", "superClass", "typeParameters", "superTypeParameters", "implements"], + "ClassExpression": ["id", "body", "superClass", "typeParameters", "superTypeParameters", "implements"], "ComprehensionBlock": ["left", "right", "body"], "ComprehensionExpression": ["filter", "blocks", "body"], "ConditionalExpression": ["test", "consequent", "alternate"], @@ -30,9 +30,9 @@ "ForInStatement": ["left", "right", "body"], "ForOfStatement": ["left", "right", "body"], "ForStatement": ["init", "test", "update", "body"], - "FunctionDeclaration": ["id", "params", "defaults", "rest", "body"], - "FunctionExpression": ["id", "params", "defaults", "rest", "body"], - "Identifier": [], + "FunctionDeclaration": ["id", "params", "defaults", "rest", "body", "returnType", "typeParameters"], + "FunctionExpression": ["id", "params", "defaults", "rest", "body", "returnType", "typeParameters"], + "Identifier": ["typeAnnotation"], "IfStatement": ["test", "consequent", "alternate"], "ImportBatchSpecifier": ["id"], "ImportDeclaration": ["specifiers", "source"], @@ -44,11 +44,11 @@ "MethodDefinition": ["key", "value"], "NewExpression": ["callee", "arguments"], "ObjectExpression": ["properties"], - "ObjectPattern": ["properties"], + "ObjectPattern": ["properties", "typeAnnotation"], "PrivateDeclaration": ["declarations"], "Program": ["body"], "Property": ["key", "value"], - "RestElement": ["argument"], + "RestElement": ["argument", "typeAnnotation"], "ReturnStatement": ["argument"], "SequenceExpression": ["expressions"], "SpreadElement": ["argument"], @@ -71,36 +71,37 @@ "YieldExpression": ["argument"], "AnyTypeAnnotation": [], - "ArrayTypeAnnotation": [], + "ArrayTypeAnnotation": ["elementType"], "BooleanTypeAnnotation": [], - "ClassProperty": ["key", "value"], - "DeclareClass": [], - "DeclareFunction": [], - "DeclareModule": [], - "DeclareVariable": [], - "FunctionTypeAnnotation": [], - "FunctionTypeParam": [], - "GenericTypeAnnotation": [], - "InterfaceExtends": [], - "InterfaceDeclaration": [], - "IntersectionTypeAnnotation": [], - "NullableTypeAnnotation": [], + "ClassImplements": ["id", "typeParameters"], + "ClassProperty": ["key", "value", "typeAnnotation"], + "DeclareClass": ["id", "typeParameters", "extends", "body"], + "DeclareFunction": ["id"], + "DeclareModule": ["id", "body"], + "DeclareVariable": ["id"], + "FunctionTypeAnnotation": ["typeParameters", "params", "rest", "returnType"], + "FunctionTypeParam": ["name", "typeAnnotation"], + "GenericTypeAnnotation": ["id", "typeParameters"], + "InterfaceExtends": ["id", "typeParameters"], + "InterfaceDeclaration": ["id", "typeParameters", "extends", "body"], + "IntersectionTypeAnnotation": ["types"], + "NullableTypeAnnotation": ["typeAnnotation"], "NumberTypeAnnotation": [], "StringLiteralTypeAnnotation": [], "StringTypeAnnotation": [], - "TupleTypeAnnotation": [], - "TypeofTypeAnnotation": [], - "TypeAlias": [], - "TypeAnnotation": [], + "TupleTypeAnnotation": ["types"], + "TypeofTypeAnnotation": ["argument"], + "TypeAlias": ["id", "typeParameters", "right"], + "TypeAnnotation": ["typeAnnotation"], "TypeCastExpression": ["expression"], - "TypeParameterDeclaration": [], - "TypeParameterInstantiation": [], - "ObjectTypeAnnotation": [], - "ObjectTypeCallProperty": [], - "ObjectTypeIndexer": [], - "ObjectTypeProperty": [], - "QualifiedTypeIdentifier": [], - "UnionTypeAnnotation": [], + "TypeParameterDeclaration": ["params"], + "TypeParameterInstantiation": ["params"], + "ObjectTypeAnnotation": ["key", "value"], + "ObjectTypeCallProperty": ["value"], + "ObjectTypeIndexer": ["id", "key", "value"], + "ObjectTypeProperty": ["key", "value"], + "QualifiedTypeIdentifier": ["id", "qualification"], + "UnionTypeAnnotation": ["types"], "VoidTypeAnnotation": [], "JSXAttribute": ["name", "value"], diff --git a/src/babel/util.js b/src/babel/util.js index d26dc8555a..d6140bd490 100644 --- a/src/babel/util.js +++ b/src/babel/util.js @@ -15,7 +15,7 @@ import has from "lodash/object/has"; import fs from "fs"; import t from "./types"; -export { inherits } from "util"; +export { inherits, inspect } from "util"; export var debug = buildDebug("babel"); diff --git a/test/_helper.js b/test/_helper.js index a60c8fda87..4cc048a23b 100644 --- a/test/_helper.js +++ b/test/_helper.js @@ -24,7 +24,7 @@ exports.esvalid = function (ast, code, loc) { if (errors.length) { var msg = []; _.each(errors, function (err) { - msg.push(err.message + " - " + JSON.stringify(err.node)); + msg.push(err.message + " - " + util.inspect(err.node)); }); throw new Error(loc + ": " + msg.join(". ") + "\n" + code); } diff --git a/test/_transformation-helper.js b/test/_transformation-helper.js index c3e5cd19f4..bd1610ef0e 100644 --- a/test/_transformation-helper.js +++ b/test/_transformation-helper.js @@ -97,7 +97,7 @@ var run = function (task, done) { if (!execCode || actualCode) { result = transform(actualCode, getOpts(actual)); checkAst(result, actual); - actualCode = result.code; + actualCode = result.code.trim(); try { chai.expect(actualCode).to.be.equal(expectCode, actual.loc + " !== " + expect.loc); diff --git a/test/fixtures/generation/flow/array-types/actual.js b/test/fixtures/generation/flow/array-types/actual.js new file mode 100644 index 0000000000..39f1c281a2 --- /dev/null +++ b/test/fixtures/generation/flow/array-types/actual.js @@ -0,0 +1,6 @@ +var a: number[]; +var a: ?number[]; +var a: (?number)[]; +var a: () => number[]; +var a: (() => number)[]; +var a: typeof A[]; diff --git a/test/fixtures/generation/flow/array-types/expected.js b/test/fixtures/generation/flow/array-types/expected.js new file mode 100644 index 0000000000..39f1c281a2 --- /dev/null +++ b/test/fixtures/generation/flow/array-types/expected.js @@ -0,0 +1,6 @@ +var a: number[]; +var a: ?number[]; +var a: (?number)[]; +var a: () => number[]; +var a: (() => number)[]; +var a: typeof A[]; diff --git a/test/fixtures/generation/flow/call-properties/actual.js b/test/fixtures/generation/flow/call-properties/actual.js new file mode 100644 index 0000000000..62f0a1b259 --- /dev/null +++ b/test/fixtures/generation/flow/call-properties/actual.js @@ -0,0 +1,5 @@ +var a: { (): number }; +var a: { (): number; }; +var a: { (): number; y: string; (x: string): string }; +var a: { (x: T): number; }; +interface A { (): number; }; diff --git a/test/fixtures/generation/flow/call-properties/expected.js b/test/fixtures/generation/flow/call-properties/expected.js new file mode 100644 index 0000000000..de9b3990f4 --- /dev/null +++ b/test/fixtures/generation/flow/call-properties/expected.js @@ -0,0 +1,5 @@ +var a: { (): number }; +var a: { (): number }; +var a: { y: string; (): number; (x: string): string }; +var a: { (x: T): number }; +interface A { (): number }; diff --git a/test/fixtures/generation/flow/declare-module/actual.js b/test/fixtures/generation/flow/declare-module/actual.js new file mode 100644 index 0000000000..7612b7dc0d --- /dev/null +++ b/test/fixtures/generation/flow/declare-module/actual.js @@ -0,0 +1,5 @@ +declare module A {} +declare module "./a/b.js" {} +declare module A { declare var x: number; } +declare module A { declare function foo(): number; } +declare module A { declare class B { foo(): number; } } diff --git a/test/fixtures/generation/flow/declare-module/expected.js b/test/fixtures/generation/flow/declare-module/expected.js new file mode 100644 index 0000000000..0b6fbd09e0 --- /dev/null +++ b/test/fixtures/generation/flow/declare-module/expected.js @@ -0,0 +1,11 @@ +declare module A {} +declare module "./a/b.js" {} +declare module A { + declare var x: number; +} +declare module A { + declare function foo(): number; +} +declare module A { + declare class B { foo(): number } +} diff --git a/test/fixtures/generation/flow/declare-statements/actual.js b/test/fixtures/generation/flow/declare-statements/actual.js new file mode 100644 index 0000000000..369f608fa2 --- /dev/null +++ b/test/fixtures/generation/flow/declare-statements/actual.js @@ -0,0 +1,11 @@ +declare var foo +declare var foo; +declare function foo(): void +declare function foo(): void; +declare function foo(): void; +declare function foo(x: number, y: string): void; +declare class A {} +declare class A extends B { x: number } +declare class A { static foo(): number; static x : string } +declare class A { static [ indexer: number]: string } +declare class A { static () : number } diff --git a/test/fixtures/generation/flow/declare-statements/expected.js b/test/fixtures/generation/flow/declare-statements/expected.js new file mode 100644 index 0000000000..35dd159647 --- /dev/null +++ b/test/fixtures/generation/flow/declare-statements/expected.js @@ -0,0 +1,11 @@ +declare var foo; +declare var foo; +declare function foo(): void; +declare function foo(): void; +declare function foo(): void; +declare function foo(x: number, y: string): void; +declare class A {} +declare class A extends B { x: number } +declare class A { static foo(): number; static x: string } +declare class A { static [indexer: number]: string } +declare class A { static (): number } diff --git a/test/fixtures/generation/flow/interfaces-module-and-script/actual.js b/test/fixtures/generation/flow/interfaces-module-and-script/actual.js new file mode 100644 index 0000000000..f55148215c --- /dev/null +++ b/test/fixtures/generation/flow/interfaces-module-and-script/actual.js @@ -0,0 +1,9 @@ +interface A {}; +interface A extends B {}; +interface A extends B, C {}; +interface A { foo: () => number; }; +interface Dictionary { [index: string]: string; length: number; }; +class Foo implements Bar {} +class Foo extends Bar implements Bat, Man {} +class Foo extends class Bar implements Bat {} {} +class Foo extends class Bar implements Bat {} implements Man {} diff --git a/test/fixtures/generation/flow/interfaces-module-and-script/expected.js b/test/fixtures/generation/flow/interfaces-module-and-script/expected.js new file mode 100644 index 0000000000..898993197d --- /dev/null +++ b/test/fixtures/generation/flow/interfaces-module-and-script/expected.js @@ -0,0 +1,9 @@ +interface A {}; +interface A extends B {}; +interface A extends B, C {}; +interface A { foo(): number }; +interface Dictionary { length: number; [index: string]: string }; +class Foo implements Bar {} +class Foo extends Bar implements Bat, Man {} +class Foo extends class Bar implements Bat {} {} +class Foo extends class Bar implements Bat {} implements Man {} diff --git a/test/fixtures/generation/flow/qualified-generic-type/actual.js b/test/fixtures/generation/flow/qualified-generic-type/actual.js new file mode 100644 index 0000000000..040a63c165 --- /dev/null +++ b/test/fixtures/generation/flow/qualified-generic-type/actual.js @@ -0,0 +1,4 @@ +var a: A.B; +var a: A.B.C; +var a: A.B; +var a: typeof A.B; diff --git a/test/fixtures/generation/flow/qualified-generic-type/expected.js b/test/fixtures/generation/flow/qualified-generic-type/expected.js new file mode 100644 index 0000000000..040a63c165 --- /dev/null +++ b/test/fixtures/generation/flow/qualified-generic-type/expected.js @@ -0,0 +1,4 @@ +var a: A.B; +var a: A.B.C; +var a: A.B; +var a: typeof A.B; diff --git a/test/fixtures/generation/flow/string-literal-types/actual.js b/test/fixtures/generation/flow/string-literal-types/actual.js new file mode 100644 index 0000000000..6acd7f1342 --- /dev/null +++ b/test/fixtures/generation/flow/string-literal-types/actual.js @@ -0,0 +1,2 @@ +function createElement(tagName: "div"): HTMLDivElement {} +function createElement(tagName: 'div'): HTMLDivElement {} diff --git a/test/fixtures/generation/flow/string-literal-types/expected.js b/test/fixtures/generation/flow/string-literal-types/expected.js new file mode 100644 index 0000000000..08c1053621 --- /dev/null +++ b/test/fixtures/generation/flow/string-literal-types/expected.js @@ -0,0 +1,2 @@ +function createElement(tagName: "div"): HTMLDivElement {} +function createElement(tagName: "div"): HTMLDivElement {} diff --git a/test/fixtures/generation/flow/tuples/actual.js b/test/fixtures/generation/flow/tuples/actual.js new file mode 100644 index 0000000000..4c4291e8b2 --- /dev/null +++ b/test/fixtures/generation/flow/tuples/actual.js @@ -0,0 +1,4 @@ +var a: [] = []; +var a: [Foo] = [foo]; +var a: [number,] = [123,]; +var a: [number, string] = [123, "duck"]; diff --git a/test/fixtures/generation/flow/tuples/expected.js b/test/fixtures/generation/flow/tuples/expected.js new file mode 100644 index 0000000000..2fb1a921e0 --- /dev/null +++ b/test/fixtures/generation/flow/tuples/expected.js @@ -0,0 +1,4 @@ +var a: [] = []; +var a: [Foo] = [foo]; +var a: [number] = [123]; +var a: [number, string] = [123, "duck"]; diff --git a/test/fixtures/generation/flow/type-alias/actual.js b/test/fixtures/generation/flow/type-alias/actual.js new file mode 100644 index 0000000000..a56fa1a17b --- /dev/null +++ b/test/fixtures/generation/flow/type-alias/actual.js @@ -0,0 +1,3 @@ +type FBID = number; +type Foo = Bar +export type Foo = number; diff --git a/test/fixtures/generation/flow/type-alias/expected.js b/test/fixtures/generation/flow/type-alias/expected.js new file mode 100644 index 0000000000..f0a50c1904 --- /dev/null +++ b/test/fixtures/generation/flow/type-alias/expected.js @@ -0,0 +1,3 @@ +type FBID = number; +type Foo = Bar; +export type Foo = number; diff --git a/test/fixtures/generation/flow/type-annotations/actual.js b/test/fixtures/generation/flow/type-annotations/actual.js new file mode 100644 index 0000000000..8faee26e1d --- /dev/null +++ b/test/fixtures/generation/flow/type-annotations/actual.js @@ -0,0 +1,97 @@ +function foo(numVal: any) {} +function foo(numVal: number) {} +function foo(numVal: number, strVal: string) {} +function foo(numVal: number, untypedVal) {} +function foo(untypedVal, numVal: number) {} +function foo(nullableNum: ?number) {} +function foo(callback: () => void) {} +function foo(callback: () => number) {} +function foo(callback: (_: bool) => number) {} +function foo(callback: (_1: bool, _2: string) => number) {} +function foo(callback: (_1: bool, ...foo: Array) => number) {} +function foo(): number{} +function foo():() => void {} +function foo():(_:bool) => number{} +function foo():(_?:bool) => number{} +function foo(): {} {} +function foo() {} +function foo() {} +a = function() {}; +a = { set fooProp(value: number) {} }; +a = { set fooProp(value: number): void {} }; +a = { get fooProp():number{} }; +a = { id(x: T): T {} }; +a = { *id(x: T): T {} }; +a = { async id(x: T): T {} }; +a = { 123(x: T): T {} }; +class Foo { + set fooProp(value: number) {} +} +class Foo { + set fooProp(value: number): void {} +} +class Foo { + get fooProp(): number {} +} +var numVal: number; +var numVal: number = otherNumVal; +var a: { numVal: number }; +var a: { numVal: number; }; +var a: { numVal: number; [indexer: string]: number }; +var a: ?{ numVal: number }; +var a: { numVal: number; strVal: string } +var a: { subObj: {strVal: string} } +var a: { subObj: ?{strVal: string} } +var a: { param1: number; param2: string } +var a: { param1: number; param2?: string } +var a: { [a: number]: string; [b: number]: string; }; +var a: { add(x: number, ...y: Array): void }; +var a: { id(x: T): T; }; +var a:Array = [1, 2, 3] +a = class Foo {} +a = class Foo extends Bar {} +class Foo {} +class Foo extends Bar {} +class Foo extends mixin(Bar) {} +class Foo { + bar():number { return 42; } +} +class Foo { + "bar"() {} +} +function foo(requiredParam, optParam?) {} +class Foo { + prop1: string; + prop2: number; +} +class Foo { + static prop1: string; + prop2: number; +} +var x: number | string = 4; +class Array { concat(items:number | string) {}; } +var x: () => number | () => string = fn; +var x: typeof Y = Y; +var x: typeof Y | number = Y; +var {x}: {x: string; } = { x: "hello" }; +var {x}: {x: string } = { x: "hello" }; +var [x]: Array = [ "hello" ]; +function foo({x}: { x: string; }) {} +function foo([x]: Array) {} +function foo(...rest: Array) {} +(function (...rest: Array) {}); +((...rest: Array) => rest); +var a: Map > +var a: Map> +var a: number[] +var a: ?string[] +var a: Promise[] +var a:(...rest:Array) => number +var identity: (x: T) => T +var identity: (x: T, ...y:T[]) => T +import type foo from "bar"; +import type { foo, bar } from "baz"; +import type { foo as bar } from "baz"; +import type from "foo"; +import type, { foo } from "bar"; +import type * as namespace from "bar"; diff --git a/test/fixtures/generation/flow/type-annotations/expected.js b/test/fixtures/generation/flow/type-annotations/expected.js new file mode 100644 index 0000000000..cf88fc2c4b --- /dev/null +++ b/test/fixtures/generation/flow/type-annotations/expected.js @@ -0,0 +1,101 @@ +function foo(numVal: any) {} +function foo(numVal: number) {} +function foo(numVal: number, strVal: string) {} +function foo(numVal: number, untypedVal) {} +function foo(untypedVal, numVal: number) {} +function foo(nullableNum: ?number) {} +function foo(callback: () => void) {} +function foo(callback: () => number) {} +function foo(callback: (_: bool) => number) {} +function foo(callback: (_1: bool, _2: string) => number) {} +function foo(callback: (_1: bool, ...foo: Array) => number) {} +function foo(): number {} +function foo(): () => void {} +function foo(): (_: bool) => number {} +function foo(): (_?: bool) => number {} +function foo(): {} {} +function foo() {} +function foo() {} +a = function () {}; +a = { set fooProp(value: number) {} }; +a = { set fooProp(value: number): void {} }; +a = { get fooProp(): number {} }; +a = { id(x: T): T {} }; +a = { *id(x: T): T {} }; +a = { async id(x: T): T {} }; +a = { 123(x: T): T {} }; +class Foo { + set fooProp(value: number) {} +} +class Foo { + set fooProp(value: number): void {} +} +class Foo { + get fooProp(): number {} +} +var numVal: number; +var numVal: number = otherNumVal; +var a: { numVal: number }; +var a: { numVal: number }; +var a: { numVal: number; [indexer: string]: number }; +var a: ?{ numVal: number }; +var a: { numVal: number; strVal: string }; +var a: { subObj: { strVal: string } }; +var a: { subObj: ?{ strVal: string } }; +var a: { param1: number; param2: string }; +var a: { param1: number; param2?: string }; +var a: { [a: number]: string; [b: number]: string }; +var a: { add(x: number, ...y: Array): void }; +var a: { id(x: T): T }; +var a: Array = [1, 2, 3]; +a = class Foo {}; +a = class Foo extends Bar {}; +class Foo {} +class Foo extends Bar {} +class Foo extends mixin(Bar) {} +class Foo { + bar(): number { + return 42; + } +} +class Foo { + "bar"() {} +} +function foo(requiredParam, optParam?) {} +class Foo { + prop1: string; + prop2: number; +} +class Foo { + static prop1: string; + prop2: number; +} +var x: number | string = 4; +class Array { + concat(items: number | string) {} +} +var x: () => number | () => string = fn; +var x: typeof Y = Y; +var x: typeof Y | number = Y; +var { x }: { x: string } = { x: "hello" }; +var { x }: { x: string } = { x: "hello" }; +var [x]: Array = ["hello"]; +function foo({ x }: { x: string }) {} +function foo([x]: Array) {} +function foo(...rest: Array) {} +(function (...rest: Array) {}); +(...rest: Array) => rest; +var a: Map>; +var a: Map>; +var a: number[]; +var a: ?string[]; +var a: Promise[]; +var a: (...rest: Array) => number; +var identity: (x: T) => T; +var identity: (x: T, ...y: T[]) => T; +import type foo from "bar"; +import type { foo, bar } from "baz"; +import type { foo as bar } from "baz"; +import type from "foo"; +import type, { foo } from "bar"; +import type * as namespace from "bar"; diff --git a/test/fixtures/generation/flow/typecasts/actual.js b/test/fixtures/generation/flow/typecasts/actual.js new file mode 100644 index 0000000000..aa691e87d2 --- /dev/null +++ b/test/fixtures/generation/flow/typecasts/actual.js @@ -0,0 +1,4 @@ +(xxx: number); +({ xxx: 0, yyy: "hey" }: { xxx: number; yyy: string }); +(xxx => xxx + 1: (xxx: number) => number); +((xxx: number), (yyy: string)); diff --git a/test/fixtures/generation/flow/typecasts/expected.js b/test/fixtures/generation/flow/typecasts/expected.js new file mode 100644 index 0000000000..893c96f51f --- /dev/null +++ b/test/fixtures/generation/flow/typecasts/expected.js @@ -0,0 +1,4 @@ +(xxx: number); +({ xxx: 0, yyy: "hey" }: { xxx: number; yyy: string }); +(xxx => xxx + 1: (xxx: number) => number); +(xxx: number), (yyy: string); diff --git a/test/fixtures/transformation/flow/options.json b/test/fixtures/transformation/flow/options.json new file mode 100644 index 0000000000..8b2cc18046 --- /dev/null +++ b/test/fixtures/transformation/flow/options.json @@ -0,0 +1,5 @@ +{ + "experimental": true, + "whitelist": ["flow"], + "noCheckAst": true +} diff --git a/test/fixtures/transformation/flow/strip-array-types/actual.js b/test/fixtures/transformation/flow/strip-array-types/actual.js new file mode 100644 index 0000000000..39f1c281a2 --- /dev/null +++ b/test/fixtures/transformation/flow/strip-array-types/actual.js @@ -0,0 +1,6 @@ +var a: number[]; +var a: ?number[]; +var a: (?number)[]; +var a: () => number[]; +var a: (() => number)[]; +var a: typeof A[]; diff --git a/test/fixtures/transformation/flow/strip-array-types/expected.js b/test/fixtures/transformation/flow/strip-array-types/expected.js new file mode 100644 index 0000000000..a241a0e78b --- /dev/null +++ b/test/fixtures/transformation/flow/strip-array-types/expected.js @@ -0,0 +1,6 @@ +var a; +var a; +var a; +var a; +var a; +var a; diff --git a/test/fixtures/transformation/flow/strip-call-properties/actual.js b/test/fixtures/transformation/flow/strip-call-properties/actual.js new file mode 100644 index 0000000000..204e5f9ae5 --- /dev/null +++ b/test/fixtures/transformation/flow/strip-call-properties/actual.js @@ -0,0 +1,5 @@ +var a: { (): number }; +var a: { (): number; }; +var a: { (): number; y: string; (x: string): string }; +var a: { (x: T): number; }; +interface A { (): number; } diff --git a/test/fixtures/transformation/flow/strip-call-properties/expected.js b/test/fixtures/transformation/flow/strip-call-properties/expected.js new file mode 100644 index 0000000000..8e94fcfbd6 --- /dev/null +++ b/test/fixtures/transformation/flow/strip-call-properties/expected.js @@ -0,0 +1,4 @@ +var a; +var a; +var a; +var a; diff --git a/test/fixtures/transformation/flow/strip-declare-module/actual.js b/test/fixtures/transformation/flow/strip-declare-module/actual.js new file mode 100644 index 0000000000..7612b7dc0d --- /dev/null +++ b/test/fixtures/transformation/flow/strip-declare-module/actual.js @@ -0,0 +1,5 @@ +declare module A {} +declare module "./a/b.js" {} +declare module A { declare var x: number; } +declare module A { declare function foo(): number; } +declare module A { declare class B { foo(): number; } } diff --git a/test/fixtures/transformation/flow/strip-declare-statements/actual.js b/test/fixtures/transformation/flow/strip-declare-statements/actual.js new file mode 100644 index 0000000000..369f608fa2 --- /dev/null +++ b/test/fixtures/transformation/flow/strip-declare-statements/actual.js @@ -0,0 +1,11 @@ +declare var foo +declare var foo; +declare function foo(): void +declare function foo(): void; +declare function foo(): void; +declare function foo(x: number, y: string): void; +declare class A {} +declare class A extends B { x: number } +declare class A { static foo(): number; static x : string } +declare class A { static [ indexer: number]: string } +declare class A { static () : number } diff --git a/test/fixtures/transformation/flow/strip-interfaces-module-and-script/actual.js b/test/fixtures/transformation/flow/strip-interfaces-module-and-script/actual.js new file mode 100644 index 0000000000..2e37dfaf61 --- /dev/null +++ b/test/fixtures/transformation/flow/strip-interfaces-module-and-script/actual.js @@ -0,0 +1,9 @@ +interface A {} +interface A extends B {} +interface A extends B, C {} +interface A { foo: () => number; } +interface Dictionary { [index: string]: string; length: number; } +class Foo implements Bar {} +class Foo2 extends Bar implements Bat, Man {} +class Foo3 extends class Bar implements Bat {} {} +class Foo4 extends class Bar implements Bat {} implements Man {} diff --git a/test/fixtures/transformation/flow/strip-interfaces-module-and-script/expected.js b/test/fixtures/transformation/flow/strip-interfaces-module-and-script/expected.js new file mode 100644 index 0000000000..fe37f9c24b --- /dev/null +++ b/test/fixtures/transformation/flow/strip-interfaces-module-and-script/expected.js @@ -0,0 +1,4 @@ +class Foo {} +class Foo2 extends Bar {} +class Foo3 extends class Bar {} {} +class Foo4 extends class Bar {} {} diff --git a/test/fixtures/transformation/flow/strip-qualified-generic-type/actual.js b/test/fixtures/transformation/flow/strip-qualified-generic-type/actual.js new file mode 100644 index 0000000000..040a63c165 --- /dev/null +++ b/test/fixtures/transformation/flow/strip-qualified-generic-type/actual.js @@ -0,0 +1,4 @@ +var a: A.B; +var a: A.B.C; +var a: A.B; +var a: typeof A.B; diff --git a/test/fixtures/transformation/flow/strip-qualified-generic-type/expected.js b/test/fixtures/transformation/flow/strip-qualified-generic-type/expected.js new file mode 100644 index 0000000000..8e94fcfbd6 --- /dev/null +++ b/test/fixtures/transformation/flow/strip-qualified-generic-type/expected.js @@ -0,0 +1,4 @@ +var a; +var a; +var a; +var a; diff --git a/test/fixtures/transformation/flow/strip-string-literal-types/actual.js b/test/fixtures/transformation/flow/strip-string-literal-types/actual.js new file mode 100644 index 0000000000..6acd7f1342 --- /dev/null +++ b/test/fixtures/transformation/flow/strip-string-literal-types/actual.js @@ -0,0 +1,2 @@ +function createElement(tagName: "div"): HTMLDivElement {} +function createElement(tagName: 'div'): HTMLDivElement {} diff --git a/test/fixtures/transformation/flow/strip-string-literal-types/expected.js b/test/fixtures/transformation/flow/strip-string-literal-types/expected.js new file mode 100644 index 0000000000..aa8ff06291 --- /dev/null +++ b/test/fixtures/transformation/flow/strip-string-literal-types/expected.js @@ -0,0 +1,2 @@ +function createElement(tagName) {} +function createElement(tagName) {} diff --git a/test/fixtures/transformation/flow/strip-tuples/actual.js b/test/fixtures/transformation/flow/strip-tuples/actual.js new file mode 100644 index 0000000000..4c4291e8b2 --- /dev/null +++ b/test/fixtures/transformation/flow/strip-tuples/actual.js @@ -0,0 +1,4 @@ +var a: [] = []; +var a: [Foo] = [foo]; +var a: [number,] = [123,]; +var a: [number, string] = [123, "duck"]; diff --git a/test/fixtures/transformation/flow/strip-tuples/expected.js b/test/fixtures/transformation/flow/strip-tuples/expected.js new file mode 100644 index 0000000000..f7d9c8773c --- /dev/null +++ b/test/fixtures/transformation/flow/strip-tuples/expected.js @@ -0,0 +1,4 @@ +var a = []; +var a = [foo]; +var a = [123]; +var a = [123, "duck"]; diff --git a/test/fixtures/transformation/flow/strip-type-alias/actual.js b/test/fixtures/transformation/flow/strip-type-alias/actual.js new file mode 100644 index 0000000000..a56fa1a17b --- /dev/null +++ b/test/fixtures/transformation/flow/strip-type-alias/actual.js @@ -0,0 +1,3 @@ +type FBID = number; +type Foo = Bar +export type Foo = number; diff --git a/test/fixtures/transformation/flow/strip-type-annotations/actual.js b/test/fixtures/transformation/flow/strip-type-annotations/actual.js new file mode 100644 index 0000000000..d86c13e840 --- /dev/null +++ b/test/fixtures/transformation/flow/strip-type-annotations/actual.js @@ -0,0 +1,97 @@ +function foo(numVal: any) {} +function foo(numVal: number) {} +function foo(numVal: number, strVal: string) {} +function foo(numVal: number, untypedVal) {} +function foo(untypedVal, numVal: number) {} +function foo(nullableNum: ?number) {} +function foo(callback: () => void) {} +function foo(callback: () => number) {} +function foo(callback: (_: bool) => number) {} +function foo(callback: (_1: bool, _2: string) => number) {} +function foo(callback: (_1: bool, ...foo: Array) => number) {} +function foo(): number{} +function foo():() => void {} +function foo():(_:bool) => number{} +function foo():(_?:bool) => number{} +function foo(): {} {} +function foo() {} +function foo() {} +a = function() {}; +a = { set fooProp(value: number) {} }; +a = { set fooProp(value: number): void {} }; +a = { get fooProp():number{} }; +a = { id(x: T): T {} }; +a = { *id(x: T): T {} }; +a = { async id(x: T): T {} }; +a = { 123(x: T): T {} }; +class Foo { + set fooProp(value: number) {} +} +class Foo2 { + set fooProp(value: number): void {} +} +class Foo3 { + get fooProp(): number {} +} +var numVal: number; +var numVal: number = otherNumVal; +var a: { numVal: number }; +var a: { numVal: number; }; +var a: { numVal: number; [indexer: string]: number }; +var a: ?{ numVal: number }; +var a: { numVal: number; strVal: string } +var a: { subObj: {strVal: string} } +var a: { subObj: ?{strVal: string} } +var a: { param1: number; param2: string } +var a: { param1: number; param2?: string } +var a: { [a: number]: string; [b: number]: string; }; +var a: { add(x: number, ...y: Array): void }; +var a: { id(x: T): T; }; +var a:Array = [1, 2, 3] +a = class Foo {} +a = class Foo extends Bar {} +class Foo4 {} +class Foo5 extends Bar {} +class Foo6 extends mixin(Bar) {} +class Foo7 { + bar():number { return 42; } +} +class Foo8 { + "bar"() {} +} +function foo(requiredParam, optParam?) {} +class Foo9 { + prop1: string; + prop2: number; +} +class Foo10 { + static prop1: string; + prop2: number; +} +var x: number | string = 4; +class Array { concat(items:number | string) {}; } +var x: () => number | () => string = fn; +var x: typeof Y = Y; +var x: typeof Y | number = Y; +var {x}: {x: string; } = { x: "hello" }; +var {x}: {x: string } = { x: "hello" }; +var [x]: Array = [ "hello" ]; +function foo({x}: { x: string; }) {} +function foo([x]: Array) {} +function foo(...rest: Array) {} +(function (...rest: Array) {}); +((...rest: Array) => rest); +var a: Map > +var a: Map> +var a: number[] +var a: ?string[] +var a: Promise[] +var a:(...rest:Array) => number +var identity: (x: T) => T +var identity: (x: T, ...y:T[]) => T +import type foo from "bar"; +import type { foo2, bar } from "baz"; +import type { foo as bar2 } from "baz"; +import type from "foo"; +import type2, { foo3 } from "bar"; +import type * as namespace from "bar"; diff --git a/test/fixtures/transformation/flow/strip-type-annotations/expected.js b/test/fixtures/transformation/flow/strip-type-annotations/expected.js new file mode 100644 index 0000000000..91f40a7778 --- /dev/null +++ b/test/fixtures/transformation/flow/strip-type-annotations/expected.js @@ -0,0 +1,92 @@ +function foo(numVal) {} +function foo(numVal) {} +function foo(numVal, strVal) {} +function foo(numVal, untypedVal) {} +function foo(untypedVal, numVal) {} +function foo(nullableNum) {} +function foo(callback) {} +function foo(callback) {} +function foo(callback) {} +function foo(callback) {} +function foo(callback) {} +function foo() {} +function foo() {} +function foo() {} +function foo() {} +function foo() {} +function foo() {} +function foo() {} +a = function () {}; +a = { set fooProp(value) {} }; +a = { set fooProp(value) {} }; +a = { get fooProp() {} }; +a = { id(x) {} }; +a = { *id(x) {} }; +a = { async id(x) {} }; +a = { 123(x) {} }; +class Foo { + set fooProp(value) {} +} +class Foo2 { + set fooProp(value) {} +} +class Foo3 { + get fooProp() {} +} +var numVal; +var numVal = otherNumVal; +var a; +var a; +var a; +var a; +var a; +var a; +var a; +var a; +var a; +var a; +var a; +var a; +var a = [1, 2, 3]; +a = class Foo {}; +a = class Foo extends Bar {}; +class Foo4 {} +class Foo5 extends Bar {} +class Foo6 extends mixin(Bar) {} +class Foo7 { + bar() { + return 42; + } +} +class Foo8 { + "bar"() {} +} +function foo(requiredParam, optParam?) {} +class Foo9 {} +class Foo10 {} +var x = 4; +class Array { + concat(items) {} +} +var x = fn; +var x = Y; +var x = Y; +var { x } = { x: "hello" }; +var { x } = { x: "hello" }; +var [x] = ["hello"]; +function foo({ x }) {} +function foo([x]) {} +function foo(...rest) {} +(function (...rest) {}); +(...rest) => rest; +var a; +var a; +var a; +var a; +var a; +var a; +var identity; +var identity; + +import type from "foo"; +import type2, { foo3 } from "bar"; diff --git a/test/fixtures/transformation/flow/strip-typecasts/actual.js b/test/fixtures/transformation/flow/strip-typecasts/actual.js new file mode 100644 index 0000000000..aa691e87d2 --- /dev/null +++ b/test/fixtures/transformation/flow/strip-typecasts/actual.js @@ -0,0 +1,4 @@ +(xxx: number); +({ xxx: 0, yyy: "hey" }: { xxx: number; yyy: string }); +(xxx => xxx + 1: (xxx: number) => number); +((xxx: number), (yyy: string)); diff --git a/test/fixtures/transformation/flow/strip-typecasts/expected.js b/test/fixtures/transformation/flow/strip-typecasts/expected.js new file mode 100644 index 0000000000..b302ec2530 --- /dev/null +++ b/test/fixtures/transformation/flow/strip-typecasts/expected.js @@ -0,0 +1,4 @@ +xxx; +({ xxx: 0, yyy: "hey" }); +xxx => xxx + 1; +xxx, yyy;