From 9a1b8ea4436c0fc42ec5d93cf1f87d116c270291 Mon Sep 17 00:00:00 2001 From: Brian Ng Date: Tue, 25 Jul 2017 10:38:17 -0500 Subject: [PATCH] Add support for flow predicates in babel-generator (#5984) --- .../babel-generator/src/generators/flow.js | 19 ++++++++++++++ .../babel-generator/src/generators/methods.js | 14 +++++++++++ .../test/fixtures/flow/predicates/actual.js | 17 +++++++++++++ .../test/fixtures/flow/predicates/expected.js | 17 +++++++++++++ .../src/index.js | 2 ++ .../actual.js | 1 + .../actual.js | 5 ++++ .../expected.js | 7 ++++++ packages/babel-types/README.md | 25 +++++++++++++++++++ packages/babel-types/src/definitions/flow.js | 15 +++++++++++ 10 files changed, 122 insertions(+) create mode 100644 packages/babel-generator/test/fixtures/flow/predicates/actual.js create mode 100644 packages/babel-generator/test/fixtures/flow/predicates/expected.js create mode 100644 packages/babel-plugin-transform-flow-strip-types/test/fixtures/strip-types/strip-declared-checks-annotation/actual.js create mode 100644 packages/babel-plugin-transform-flow-strip-types/test/fixtures/strip-types/strip-inferred-checks-annotation/actual.js create mode 100644 packages/babel-plugin-transform-flow-strip-types/test/fixtures/strip-types/strip-inferred-checks-annotation/expected.js diff --git a/packages/babel-generator/src/generators/flow.js b/packages/babel-generator/src/generators/flow.js index af69950849..6532f18f79 100644 --- a/packages/babel-generator/src/generators/flow.js +++ b/packages/babel-generator/src/generators/flow.js @@ -42,9 +42,28 @@ export function DeclareFunction(node: Object, parent: Object) { this.space(); this.print(node.id, node); this.print(node.id.typeAnnotation.typeAnnotation, node); + + if (node.predicate) { + this.space(); + this.print(node.predicate, node); + } + this.semicolon(); } +export function InferredPredicate(/*node: Object*/) { + this.token("%"); + this.word("checks"); +} + +export function DeclaredPredicate(node: Object) { + this.token("%"); + this.word("checks"); + this.token("("); + this.print(node.value, node); + this.token(")"); +} + export function DeclareInterface(node: Object) { this.word("declare"); this.space(); diff --git a/packages/babel-generator/src/generators/methods.js b/packages/babel-generator/src/generators/methods.js index 48903511db..f235e30420 100644 --- a/packages/babel-generator/src/generators/methods.js +++ b/packages/babel-generator/src/generators/methods.js @@ -49,6 +49,16 @@ export function _method(node: Object) { this.print(node.body, node); } +export function _predicate(node: Object) { + if (node.predicate) { + if (!node.returnType) { + this.token(":"); + } + this.space(); + this.print(node.predicate, node); + } +} + export function FunctionExpression(node: Object) { if (node.async) { this.word("async"); @@ -65,6 +75,8 @@ export function FunctionExpression(node: Object) { } this._params(node); + this._predicate(node); + this.space(); this.print(node.body, node); } @@ -89,6 +101,8 @@ export function ArrowFunctionExpression(node: Object) { this._params(node); } + this._predicate(node); + this.space(); this.token("=>"); this.space(); diff --git a/packages/babel-generator/test/fixtures/flow/predicates/actual.js b/packages/babel-generator/test/fixtures/flow/predicates/actual.js new file mode 100644 index 0000000000..bbbbe2c8f2 --- /dev/null +++ b/packages/babel-generator/test/fixtures/flow/predicates/actual.js @@ -0,0 +1,17 @@ +declare function foo(x: mixed): boolean %checks(x !== null); + +declare function my_filter>(v: Array, cb: P): Array<$Refine>; + +declare function f2(x: mixed): string %checks(Array.isArray(x)); + +function foo(x: mixed): %checks { return typeof x === "string"; } + +function is_string(x): boolean %checks { + return typeof x === "string"; +} + +var f = (x: mixed): %checks => typeof x === "string"; + +const foo = (x: mixed): boolean %checks => typeof x === "string"; + +(x): %checks => x !== null; diff --git a/packages/babel-generator/test/fixtures/flow/predicates/expected.js b/packages/babel-generator/test/fixtures/flow/predicates/expected.js new file mode 100644 index 0000000000..d8e384a5ef --- /dev/null +++ b/packages/babel-generator/test/fixtures/flow/predicates/expected.js @@ -0,0 +1,17 @@ +declare function foo(x: mixed): boolean %checks(x !== null); +declare function my_filter>(v: Array, cb: P): Array<$Refine>; +declare function f2(x: mixed): string %checks(Array.isArray(x)); + +function foo(x: mixed): %checks { + return typeof x === "string"; +} + +function is_string(x): boolean %checks { + return typeof x === "string"; +} + +var f = (x: mixed): %checks => typeof x === "string"; + +const foo = (x: mixed): boolean %checks => typeof x === "string"; + +x: %checks => x !== null; diff --git a/packages/babel-plugin-transform-flow-strip-types/src/index.js b/packages/babel-plugin-transform-flow-strip-types/src/index.js index 5c5d73d828..ace6a92e3e 100644 --- a/packages/babel-plugin-transform-flow-strip-types/src/index.js +++ b/packages/babel-plugin-transform-flow-strip-types/src/index.js @@ -67,6 +67,8 @@ export default function({ types: t }) { const param = node.params[i]; param.optional = false; } + + node.predicate = null; }, TypeCastExpression(path) { diff --git a/packages/babel-plugin-transform-flow-strip-types/test/fixtures/strip-types/strip-declared-checks-annotation/actual.js b/packages/babel-plugin-transform-flow-strip-types/test/fixtures/strip-types/strip-declared-checks-annotation/actual.js new file mode 100644 index 0000000000..5c3782b340 --- /dev/null +++ b/packages/babel-plugin-transform-flow-strip-types/test/fixtures/strip-types/strip-declared-checks-annotation/actual.js @@ -0,0 +1 @@ +declare function foo(x: mixed): boolean %checks(typeof x === "string"); diff --git a/packages/babel-plugin-transform-flow-strip-types/test/fixtures/strip-types/strip-inferred-checks-annotation/actual.js b/packages/babel-plugin-transform-flow-strip-types/test/fixtures/strip-types/strip-inferred-checks-annotation/actual.js new file mode 100644 index 0000000000..77f598e966 --- /dev/null +++ b/packages/babel-plugin-transform-flow-strip-types/test/fixtures/strip-types/strip-inferred-checks-annotation/actual.js @@ -0,0 +1,5 @@ +var f = (x): %checks => typeof x === "string"; +var g = (x: mixed): boolean %checks => typeof x === "string"; +function h(x: mixed): %checks { + return typeof x === "string"; +} diff --git a/packages/babel-plugin-transform-flow-strip-types/test/fixtures/strip-types/strip-inferred-checks-annotation/expected.js b/packages/babel-plugin-transform-flow-strip-types/test/fixtures/strip-types/strip-inferred-checks-annotation/expected.js new file mode 100644 index 0000000000..da702adbff --- /dev/null +++ b/packages/babel-plugin-transform-flow-strip-types/test/fixtures/strip-types/strip-inferred-checks-annotation/expected.js @@ -0,0 +1,7 @@ +var f = x => typeof x === "string"; + +var g = x => typeof x === "string"; + +function h(x) { + return typeof x === "string"; +} \ No newline at end of file diff --git a/packages/babel-types/README.md b/packages/babel-types/README.md index fe30b311ab..1e727e8759 100644 --- a/packages/babel-types/README.md +++ b/packages/babel-types/README.md @@ -520,6 +520,19 @@ Aliases: `Flow`, `FlowDeclaration`, `Statement`, `Declaration` --- +### declaredPredicate +```javascript +t.declaredPredicate(value) +``` + +See also `t.isDeclaredPredicate(node, opts)` and `t.assertDeclaredPredicate(node, opts)`. + +Aliases: `Flow`, `FlowPredicate` + + - `value` (required) + +--- + ### decorator ```javascript t.decorator(expression) @@ -947,6 +960,18 @@ Aliases: `ModuleSpecifier` - `imported`: `Identifier` (required) - `importKind`: `null | 'type' | 'typeof'` (default: `null`) +--- + +### inferredPredicate +```javascript +t.inferredPredicate() +``` + +See also `t.isInferredPredicate(node, opts)` and `t.assertInferredPredicate(node, opts)`. + +Aliases: `Flow`, `FlowPredicate` + + --- ### interfaceDeclaration diff --git a/packages/babel-types/src/definitions/flow.js b/packages/babel-types/src/definitions/flow.js index 81640c6ec6..1ef3c72248 100644 --- a/packages/babel-types/src/definitions/flow.js +++ b/packages/babel-types/src/definitions/flow.js @@ -125,6 +125,14 @@ defineType("DeclareExportAllDeclaration", { }, }); +defineType("DeclaredPredicate", { + visitor: ["value"], + aliases: ["Flow", "FlowPredicate"], + fields: { + // todo + }, +}); + defineType("ExistsTypeAnnotation", { aliases: ["Flow"], }); @@ -153,6 +161,13 @@ defineType("GenericTypeAnnotation", { }, }); +defineType("InferredPredicate", { + aliases: ["Flow", "FlowPredicate"], + fields: { + // todo + }, +}); + defineType("InterfaceExtends", { visitor: ["id", "typeParameters"], aliases: ["Flow"],