From c6d2c48f8f4d9bab4749ae8f80b00e44fae715b6 Mon Sep 17 00:00:00 2001 From: Greg Price Date: Sat, 7 May 2022 12:12:30 -0700 Subject: [PATCH 1/2] test [nfc]: Factor out parser object in Flow tests --- test/flow.ts | 80 ++++++---------------------------------------------- 1 file changed, 8 insertions(+), 72 deletions(-) diff --git a/test/flow.ts b/test/flow.ts index daa6bd3c..94aa91ee 100644 --- a/test/flow.ts +++ b/test/flow.ts @@ -11,16 +11,16 @@ var types = forkFn([ flowDef, ]); +const parser = { + parse(code: string) { + return flowParser.parse(code, { + types: true, + }); + }, +}; + describe("flow types", function () { it("issue #242", function () { - const parser = { - parse(code: string) { - return flowParser.parse(code, { - types: true - }); - } - }; - const program = parser.parse([ "class A extends C {}", "function f() {}", @@ -46,14 +46,6 @@ describe("flow types", function () { }); it("issue #261", function () { - const parser = { - parse(code: string) { - return flowParser.parse(code, { - types: true - }); - } - }; - const program = parser.parse('declare module.exports: {};'); assert.strictEqual(program.body[0].type, 'DeclareModuleExports'); @@ -62,14 +54,6 @@ describe("flow types", function () { }); it("Explicit type arguments", function () { - const parser = { - parse(code: string) { - return flowParser.parse(code, { - types: true - }); - } - }; - const program = parser.parse([ 'test();', 'test();', @@ -128,14 +112,6 @@ describe("flow types", function () { } it("issue #294 - function declarations", function () { - const parser = { - parse(code: string) { - return require('flow-parser').parse(code, { - types: true - }); - } - }; - const program = parser.parse([ "function foo(): T { }", "let bar: T", @@ -154,14 +130,6 @@ describe("flow types", function () { }); it("issue #294 - function expressions", function () { - const parser = { - parse(code: string) { - return require('flow-parser').parse(code, { - types: true - }); - } - }; - const program = parser.parse([ "const foo = function (): T { }", "let bar: T", @@ -182,14 +150,6 @@ describe("flow types", function () { }); it("issue #294 - arrow function expressions", function () { - const parser = { - parse(code: string) { - return require('flow-parser').parse(code, { - types: true - }); - } - }; - const program = parser.parse([ "const foo = (): T => { }", "let bar: T" @@ -208,14 +168,6 @@ describe("flow types", function () { }); it("issue #294 - class declarations", function () { - const parser = { - parse(code: string) { - return require('flow-parser').parse(code, { - types: true - }); - } - }; - const program = parser.parse([ "class Foo extends Bar> { }", "let bar: T" @@ -234,14 +186,6 @@ describe("flow types", function () { }); it("issue #294 - class expressions", function () { - const parser = { - parse(code: string) { - return require('flow-parser').parse(code, { - types: true - }); - } - }; - const program = parser.parse([ "const foo = class Foo extends Bar> { }", "let bar: T" @@ -263,14 +207,6 @@ describe("flow types", function () { }); it("issue #296 - interface declarations", function () { - const parser = { - parse(code: string) { - return require('flow-parser').parse(code, { - types: true - }); - } - }; - const program = parser.parse([ "interface Foo extends Bar> { }", "let bar: T" From 607c3a9b342622d6fca2beb1b6c0864d1614909a Mon Sep 17 00:00:00 2001 From: Greg Price Date: Sat, 7 May 2022 12:33:59 -0700 Subject: [PATCH 2/2] =?UTF-8?q?flow:=20Let=20`interface=20=E2=80=A6=20exte?= =?UTF-8?q?nds`=20take=20`Foo.Bar`,=20not=20just=20`Foo`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the test shows, this is necessary in order to model the ASTs that the parser already emits. --- def/flow.ts | 2 +- gen/builders.ts | 4 ++-- gen/namedTypes.ts | 2 +- test/flow.ts | 18 ++++++++++++++++++ 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/def/flow.ts b/def/flow.ts index 7df97cf8..94d44825 100644 --- a/def/flow.ts +++ b/def/flow.ts @@ -305,7 +305,7 @@ export default function (fork: Fork) { def("InterfaceExtends") .bases("Node") .build("id") - .field("id", def("Identifier")) + .field("id", or(def("Identifier"), def("QualifiedTypeIdentifier"))) .field("typeParameters", or(def("TypeParameterInstantiation"), null), defaults["null"]); diff --git a/gen/builders.ts b/gen/builders.ts index 3f5254ba..c2bca0c7 100644 --- a/gen/builders.ts +++ b/gen/builders.ts @@ -2122,11 +2122,11 @@ export interface InterfaceTypeAnnotationBuilder { } export interface InterfaceExtendsBuilder { - (id: K.IdentifierKind): namedTypes.InterfaceExtends; + (id: K.IdentifierKind | K.QualifiedTypeIdentifierKind): namedTypes.InterfaceExtends; from( params: { comments?: K.CommentKind[] | null, - id: K.IdentifierKind, + id: K.IdentifierKind | K.QualifiedTypeIdentifierKind, loc?: K.SourceLocationKind | null, typeParameters?: K.TypeParameterInstantiationKind | null } diff --git a/gen/namedTypes.ts b/gen/namedTypes.ts index a520ef45..7a3b5c3a 100644 --- a/gen/namedTypes.ts +++ b/gen/namedTypes.ts @@ -989,7 +989,7 @@ export namespace namedTypes { export interface InterfaceExtends extends Omit { type: "InterfaceExtends"; - id: K.IdentifierKind; + id: K.IdentifierKind | K.QualifiedTypeIdentifierKind; typeParameters?: K.TypeParameterInstantiationKind | null; } diff --git a/test/flow.ts b/test/flow.ts index 94aa91ee..6d2170cd 100644 --- a/test/flow.ts +++ b/test/flow.ts @@ -224,4 +224,22 @@ describe("flow types", function () { } }); }); + + it("interface extends qualified name", function () { + const program = parser.parse([ + "interface I extends Module.J { }", + "declare interface I extends Module.J { }", + // Plain `class C extends A.B` gets a ClassDeclaration with superClass + // a MemberExpression. But with `declare`, it's a DeclareClass with + // `extends` containing an InterfaceExtends, much like on `interface`. + "declare class C extends React.Component<{||}> { }" + ].join("\n")); + + assertVisited(program, { + visitInterfaceExtends(path) { + types.builders.interfaceExtends.from(path.node); + this.traverse(path); + }, + }); + }); });