diff --git a/src/parser/flow_ast_utils.ml b/src/parser/flow_ast_utils.ml index 5322d519ed2..030e6f70f1e 100644 --- a/src/parser/flow_ast_utils.ml +++ b/src/parser/flow_ast_utils.ml @@ -215,56 +215,60 @@ let is_super_member_access = function | { Flow_ast.Expression.Member._object = (_, Flow_ast.Expression.Super _); _ } -> true | _ -> false -let acceptable_statement_in_declaration_context ~in_declare_namespace = function - | Flow_ast.Statement.Block _ -> Error "block" - | Flow_ast.Statement.Break _ -> Error "break" - | Flow_ast.Statement.ClassDeclaration _ -> Error "class declaration" - | Flow_ast.Statement.ComponentDeclaration _ -> Error "component declaration" - | Flow_ast.Statement.Continue _ -> Error "continue" - | Flow_ast.Statement.Debugger _ -> Error "debugger" - | Flow_ast.Statement.DoWhile _ -> Error "do while" - | Flow_ast.Statement.ExportDefaultDeclaration _ -> Error "export" - | Flow_ast.Statement.ExportNamedDeclaration _ -> Error "export" - | Flow_ast.Statement.Expression _ -> Error "expression" - | Flow_ast.Statement.For _ -> Error "for" - | Flow_ast.Statement.ForIn _ -> Error "for in" - | Flow_ast.Statement.ForOf _ -> Error "for of" - | Flow_ast.Statement.FunctionDeclaration _ -> Error "function declaration" - | Flow_ast.Statement.If _ -> Error "if" - | Flow_ast.Statement.Labeled _ -> Error "labeled" - | Flow_ast.Statement.Return _ -> Error "return" - | Flow_ast.Statement.Switch _ -> Error "switch" - | Flow_ast.Statement.Throw _ -> Error "throw" - | Flow_ast.Statement.Try _ -> Error "try" - | Flow_ast.Statement.VariableDeclaration _ -> Error "variable declaration" - | Flow_ast.Statement.While _ -> Error "while" - | Flow_ast.Statement.With _ -> Error "with" - | Flow_ast.Statement.ImportDeclaration _ -> +let acceptable_statement_in_declaration_context ~in_declare_namespace = + let open Flow_ast.Statement in + function + | Block _ -> Error "block" + | Break _ -> Error "break" + | ClassDeclaration _ -> Error "class declaration" + | ComponentDeclaration _ -> Error "component declaration" + | Continue _ -> Error "continue" + | Debugger _ -> Error "debugger" + | DoWhile _ -> Error "do while" + | ExportDefaultDeclaration _ -> Error "export default" + | ExportNamedDeclaration { ExportNamedDeclaration.export_kind = ExportValue; _ } -> + Error "value export" + | Expression _ -> Error "expression" + | For _ -> Error "for" + | ForIn _ -> Error "for in" + | ForOf _ -> Error "for of" + | FunctionDeclaration _ -> Error "function declaration" + | If _ -> Error "if" + | Labeled _ -> Error "labeled" + | Return _ -> Error "return" + | Switch _ -> Error "switch" + | Throw _ -> Error "throw" + | Try _ -> Error "try" + | VariableDeclaration _ -> Error "variable declaration" + | While _ -> Error "while" + | With _ -> Error "with" + | ImportDeclaration _ -> if in_declare_namespace then Error "import declaration" else Ok () - | Flow_ast.Statement.DeclareModuleExports _ -> + | DeclareModuleExports _ -> if in_declare_namespace then Error "declare module.exports" else Ok () - | Flow_ast.Statement.DeclareClass _ - | Flow_ast.Statement.DeclareComponent _ - | Flow_ast.Statement.DeclareEnum _ - | Flow_ast.Statement.DeclareExportDeclaration _ - | Flow_ast.Statement.DeclareFunction _ - | Flow_ast.Statement.DeclareInterface _ - | Flow_ast.Statement.DeclareModule _ - | Flow_ast.Statement.DeclareNamespace _ - | Flow_ast.Statement.DeclareOpaqueType _ - | Flow_ast.Statement.DeclareTypeAlias _ - | Flow_ast.Statement.DeclareVariable _ - | Flow_ast.Statement.Empty _ - | Flow_ast.Statement.EnumDeclaration _ - | Flow_ast.Statement.InterfaceDeclaration _ - | Flow_ast.Statement.OpaqueType _ - | Flow_ast.Statement.TypeAlias _ -> + | DeclareClass _ + | DeclareComponent _ + | DeclareEnum _ + | DeclareExportDeclaration _ + | DeclareFunction _ + | DeclareInterface _ + | DeclareModule _ + | DeclareNamespace _ + | DeclareOpaqueType _ + | DeclareTypeAlias _ + | DeclareVariable _ + | Empty _ + | EnumDeclaration _ + | ExportNamedDeclaration { ExportNamedDeclaration.export_kind = ExportType; _ } + | InterfaceDeclaration _ + | OpaqueType _ + | TypeAlias _ -> Ok () let rec is_type_only_declaration_statement (_, stmt') = @@ -284,6 +288,7 @@ let rec is_type_only_declaration_statement (_, stmt') = true | DeclareNamespace { DeclareNamespace.body = (_, { Block.body; _ }); _ } -> List.for_all is_type_only_declaration_statement body + | ExportNamedDeclaration { ExportNamedDeclaration.export_kind; _ } -> export_kind = ExportType | Block _ | Break _ | ClassDeclaration _ @@ -293,7 +298,6 @@ let rec is_type_only_declaration_statement (_, stmt') = | DoWhile _ | EnumDeclaration _ | ExportDefaultDeclaration _ - | ExportNamedDeclaration _ | Expression _ | For _ | ForIn _ diff --git a/src/parser_utils/type_sig/__tests__/type_sig_tests.ml b/src/parser_utils/type_sig/__tests__/type_sig_tests.ml index 19152b8a347..1aed3ff101c 100644 --- a/src/parser_utils/type_sig/__tests__/type_sig_tests.ml +++ b/src/parser_utils/type_sig/__tests__/type_sig_tests.ml @@ -5566,19 +5566,25 @@ let%expect_test "builtin_cjs_module_auto_export_type" = (* All types in cjs modules are auto exported. *) print_builtins [{| declare module foo { - declare type T = number; + declare type T1 = number; + export type T2 = string; declare module.exports: string; } |}]; [%expect {| Local defs: - 0. TypeAlias {id_loc = [2:15-16]; name = "T"; tparams = Mono; body = (Annot (Number [2:19-25]))} + 0. TypeAlias {id_loc = [2:15-17]; + name = "T1"; tparams = Mono; + body = (Annot (Number [2:20-26]))} + 1. TypeAlias {id_loc = [3:14-16]; + name = "T2"; tparams = Mono; + body = (Annot (String [3:19-25]))} Builtin module foo: - [1:15-18] CJSModule {type_exports = [|(ExportTypeBinding 0)|]; - exports = (Some (Annot (String [3:26-32]))); + [1:15-18] CJSModule {type_exports = [|(ExportTypeBinding 0); (ExportTypeBinding 1)|]; + exports = (Some (Annot (String [4:26-32]))); info = - CJSModuleInfo {type_export_keys = [|"T"|]; + CJSModuleInfo {type_export_keys = [|"T1"; "T2"|]; type_stars = []; strict = true; platform_availability_set = None}} |}] @@ -5667,6 +5673,7 @@ let%expect_test "builtin_cjs_module_with_implicit_exports" = declare enum A { B } declare type T = number; declare export type U = string; + export const ignored = 3; // unsupported; } |}]; [%expect {| @@ -5881,11 +5888,14 @@ let%expect_test "builtin_declare_namespace" = declare function f(): string; declare function f(): number; declare type Baz = string; + export type Boz = string; enum B { C, D, } if (true) {} // unsupported + export const foo = ''; // unsupported + export default foo; // unsupported declare module.exports: {foo: string}; // unsupported import React from 'react'; // unsupported } @@ -5912,19 +5922,24 @@ let%expect_test "builtin_declare_namespace" = 4. TypeAlias {id_loc = [7:15-18]; name = "Baz"; tparams = Mono; body = (Annot (String [7:21-27]))} - 5. EnumBinding {id_loc = [8:7-8]; + 5. TypeAlias {id_loc = [8:14-17]; + name = "Boz"; tparams = Mono; + body = (Annot (String [8:20-26]))} + 6. EnumBinding {id_loc = [9:7-8]; name = "B"; rep = StringRep {truthy = true}; - members = { "C" -> [9:4-5]; "D" -> [10:4-5] }; + members = { "C" -> [10:4-5]; "D" -> [11:4-5] }; has_unknown_members = false} - 6. NamespaceBinding {id_loc = [1:18-20]; + 7. NamespaceBinding {id_loc = [1:18-20]; name = "ns"; values = - { "B" -> ([8:7-8], (Ref LocalRef {ref_loc = [8:7-8]; index = 5})); + { "B" -> ([9:7-8], (Ref LocalRef {ref_loc = [9:7-8]; index = 6})); "bar1" -> ([2:23-27], (Ref LocalRef {ref_loc = [2:23-27]; index = 0})); "bar2" -> ([3:16-20], (Ref LocalRef {ref_loc = [3:16-20]; index = 1})); "bar3" -> ([4:14-18], (Ref LocalRef {ref_loc = [4:14-18]; index = 2})); "f" -> ([5:19-20], (Ref LocalRef {ref_loc = [5:19-20]; index = 3})) }; - types = { "Baz" -> ([7:15-18], (Ref LocalRef {ref_loc = [7:15-18]; index = 4})) }} + types = + { "Baz" -> ([7:15-18], (Ref LocalRef {ref_loc = [7:15-18]; index = 4})); + "Boz" -> ([8:14-17], (Ref LocalRef {ref_loc = [8:14-17]; index = 5})) }} Builtin global value ns |}] diff --git a/src/typing/errors/error_message.ml b/src/typing/errors/error_message.ml index e2a68de44c0..6b83848ab96 100644 --- a/src/typing/errors/error_message.ml +++ b/src/typing/errors/error_message.ml @@ -3182,14 +3182,14 @@ let friendly_message_of_msg loc_of_aloc msg = | ContextDependentUnsupportedStatement (UnsupportedStatementInLibdef kind) -> [ text "Cannot use "; - code kind; + text kind; text " statements in a library file. "; text "The statement will be ignored."; ] | ContextDependentUnsupportedStatement (UnsupportedStatementInDeclareModule kind) -> [ text "Cannot use "; - code kind; + text kind; text " statements with in "; code "declare module"; text ". The statement will be ignored."; @@ -3197,7 +3197,7 @@ let friendly_message_of_msg loc_of_aloc msg = | ContextDependentUnsupportedStatement (UnsupportedStatementInDeclareNamespace kind) -> [ text "Cannot use "; - code kind; + text kind; text " statements with in "; code "declare namespace"; text ". The statement will be ignored."; diff --git a/src/typing/type_inference_js.ml b/src/typing/type_inference_js.ml index ee0f6458124..cfc4afd0bfc 100644 --- a/src/typing/type_inference_js.ml +++ b/src/typing/type_inference_js.ml @@ -433,7 +433,7 @@ class lib_def_loc_mapper_and_validator cx = | OpaqueType _ -> None | ExportNamedDeclaration { ExportNamedDeclaration.export_kind = ExportValue; _ } -> - Some (error "export") + Some (error "value export") | ImportDeclaration _ -> if in_toplevel_scope then Some diff --git a/tests/declare_namespace/declare_namespace.exp b/tests/declare_namespace/declare_namespace.exp index 0443d8fa4c8..ea94d8a930d 100644 --- a/tests/declare_namespace/declare_namespace.exp +++ b/tests/declare_namespace/declare_namespace.exp @@ -71,159 +71,204 @@ References: Error -------------------------------------------------------------------------------------------------- exported.js:9:3 -Cannot use `if` statements with in `declare namespace`. The statement will be ignored. [unsupported-syntax] +Cannot use if statements with in `declare namespace`. The statement will be ignored. [unsupported-syntax] 9| if (true) {} // unsupported ^^^^^^^^^^^^ -Error ------------------------------------------------------------------------------------------------- exported.js:10:3 +Error ------------------------------------------------------------------------------------------------- exported.js:12:3 -Cannot use `declare module.exports` statements with in `declare namespace`. The statement will be ignored. +Cannot use value export statements with in `declare namespace`. The statement will be ignored. [unsupported-syntax] + + 12| export const CONSTANT = 'foo'; // unsupported + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +Error ------------------------------------------------------------------------------------------------- exported.js:13:3 + +Cannot use export default statements with in `declare namespace`. The statement will be ignored. [unsupported-syntax] + + 13| export default CONSTANT; // unsupported + ^^^^^^^^^^^^^^^^^^^^^^^^ + + +Error ------------------------------------------------------------------------------------------------- exported.js:14:3 + +Cannot use declare module.exports statements with in `declare namespace`. The statement will be ignored. [unsupported-syntax] - 10| declare module.exports: {foo: string}; // unsupported + 14| declare module.exports: {foo: string}; // unsupported ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Error ------------------------------------------------------------------------------------------------- exported.js:10:3 +Error ------------------------------------------------------------------------------------------------- exported.js:14:3 Unable to determine module type (CommonJS vs ES) if both an export statement and `module.exports` are used in the same module! [module-type-conflict] - 10| declare module.exports: {foo: string}; // unsupported + 14| declare module.exports: {foo: string}; // unsupported ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Error ------------------------------------------------------------------------------------------------- exported.js:11:3 +Error ------------------------------------------------------------------------------------------------- exported.js:15:3 -Cannot use `import declaration` statements with in `declare namespace`. The statement will be ignored. +Cannot use import declaration statements with in `declare namespace`. The statement will be ignored. [unsupported-syntax] - 11| import React from 'react'; // unsupported + 15| import React from 'react'; // unsupported ^^^^^^^^^^^^^^^^^^^^^^^^^^ -Error ------------------------------------------------------------------------------------------------- exported.js:22:3 +Error ------------------------------------------------------------------------------------------------- exported.js:26:3 Cannot use type-only namespace `empty` [1] as a value. Type-only namespaces are erased and don't exist at runtime. [type-as-value] - exported.js:22:3 - 22| empty, // error: empty is type-only + exported.js:26:3 + 26| empty, // error: empty is type-only ^^^^^ References: - exported.js:14:19 - 14| declare namespace empty {} + exported.js:18:19 + 18| declare namespace empty {} ^^^^^ [1] -Error ------------------------------------------------------------------------------------------------- exported.js:27:1 +Error ------------------------------------------------------------------------------------------------- exported.js:31:1 Cannot cast `exported_ns.bar1` to empty because number [1] is incompatible with empty [2]. [incompatible-cast] - exported.js:27:1 - 27| exported_ns.bar1 as empty; // error: number ~> empty + exported.js:31:1 + 31| exported_ns.bar1 as empty; // error: number ~> empty ^^^^^^^^^^^^^^^^ References: exported.js:2:30 2| declare export const bar1: number; ^^^^^^ [1] - exported.js:27:21 - 27| exported_ns.bar1 as empty; // error: number ~> empty + exported.js:31:21 + 31| exported_ns.bar1 as empty; // error: number ~> empty ^^^^^ [2] -Error ------------------------------------------------------------------------------------------------- exported.js:28:1 +Error ------------------------------------------------------------------------------------------------- exported.js:32:1 Cannot cast `exported_ns.bar2` to empty because boolean [1] is incompatible with empty [2]. [incompatible-cast] - exported.js:28:1 - 28| exported_ns.bar2 as empty; // error: boolean ~> empty + exported.js:32:1 + 32| exported_ns.bar2 as empty; // error: boolean ~> empty ^^^^^^^^^^^^^^^^ References: exported.js:3:23 3| declare const bar2: boolean; ^^^^^^^ [1] - exported.js:28:21 - 28| exported_ns.bar2 as empty; // error: boolean ~> empty + exported.js:32:21 + 32| exported_ns.bar2 as empty; // error: boolean ~> empty ^^^^^ [2] -Error ------------------------------------------------------------------------------------------------- exported.js:29:1 +Error ------------------------------------------------------------------------------------------------- exported.js:33:1 Cannot cast `exported_ns.bar3` to empty because string [1] is incompatible with empty [2]. [incompatible-cast] - exported.js:29:1 - 29| exported_ns.bar3 as empty; // error: string ~> empty + exported.js:33:1 + 33| exported_ns.bar3 as empty; // error: string ~> empty ^^^^^^^^^^^^^^^^ References: exported.js:4:21 4| declare var bar3: string; ^^^^^^ [1] - exported.js:29:21 - 29| exported_ns.bar3 as empty; // error: string ~> empty + exported.js:33:21 + 33| exported_ns.bar3 as empty; // error: string ~> empty ^^^^^ [2] -Error ------------------------------------------------------------------------------------------------- exported.js:30:1 +Error ------------------------------------------------------------------------------------------------- exported.js:34:1 Cannot cast `exported_ns.f(...)` to empty because number [1] is incompatible with empty [2]. [incompatible-cast] - exported.js:30:1 - 30| exported_ns.f(3) as empty; // error: number ~> empty + exported.js:34:1 + 34| exported_ns.f(3) as empty; // error: number ~> empty ^^^^^^^^^^^^^^^^ References: exported.js:6:31 6| declare function f(number): number; ^^^^^^ [1] - exported.js:30:21 - 30| exported_ns.f(3) as empty; // error: number ~> empty + exported.js:34:21 + 34| exported_ns.f(3) as empty; // error: number ~> empty ^^^^^ [2] -Error ------------------------------------------------------------------------------------------------- exported.js:31:1 +Error ------------------------------------------------------------------------------------------------- exported.js:35:1 Cannot cast `1` to `Baz` because number [1] is incompatible with string [2]. [incompatible-cast] - exported.js:31:1 - 31| 1 as exported_ns.Baz; // error: number ~> string + exported.js:35:1 + 35| 1 as exported_ns.Baz; // error: number ~> string ^ [1] References: - exported.js:31:6 - 31| 1 as exported_ns.Baz; // error: number ~> string + exported.js:35:6 + 35| 1 as exported_ns.Baz; // error: number ~> string ^^^^^^^^^^^^^^^ [2] -Error ------------------------------------------------------------------------------------------------- exported.js:32:1 +Error ------------------------------------------------------------------------------------------------- exported.js:36:1 + +Cannot cast `1` to `Baz2` because number [1] is incompatible with string [2]. [incompatible-cast] + + exported.js:36:1 + 36| 1 as exported_ns.Baz2; // error: number ~> string + ^ [1] + +References: + exported.js:36:6 + 36| 1 as exported_ns.Baz2; // error: number ~> string + ^^^^^^^^^^^^^^^^ [2] + + +Error ------------------------------------------------------------------------------------------------- exported.js:37:1 + +Cannot cast `1` to `Baz3` because number [1], a primitive, cannot be used as a subtype of `Baz3` [2]. You can wrap it in +`new Number(...))` to turn it into an object and attempt to use it as a subtype of an interface. [incompatible-type] + + exported.js:37:1 + 37| 1 as exported_ns.Baz3; // error: number ~> interface {} + ^ [1] + +References: + exported.js:37:6 + 37| 1 as exported_ns.Baz3; // error: number ~> interface {} + ^^^^^^^^^^^^^^^^ [2] + + +Error ------------------------------------------------------------------------------------------------- exported.js:38:1 Cannot cast `exported_ns.B.C` to empty because `B` [1] is incompatible with empty [2]. [incompatible-cast] - exported.js:32:1 - 32| exported_ns.B.C as empty; // error: enum ~> empty + exported.js:38:1 + 38| exported_ns.B.C as empty; // error: enum ~> empty ^^^^^^^^^^^^^^^ References: exported.js:8:8 8| enum B { C, D } ^ [1] - exported.js:32:20 - 32| exported_ns.B.C as empty; // error: enum ~> empty + exported.js:38:20 + 38| exported_ns.B.C as empty; // error: enum ~> empty ^^^^^ [2] -Error ------------------------------------------------------------------------------------------------ exported.js:33:13 +Error ------------------------------------------------------------------------------------------------ exported.js:39:13 Cannot get `exported_ns.React` because property `React` is missing in namespace exported_ns [1]. [prop-missing] - exported.js:33:13 - 33| exported_ns.React; // error: prop-missing + exported.js:39:13 + 39| exported_ns.React; // error: prop-missing ^^^^^ References: @@ -232,6 +277,35 @@ References: ^^^^^^^^^^^ [1] +Error ------------------------------------------------------------------------------------------------- exported.js:40:1 + +Cannot cast `exported_ns.CONSTANT` to empty because `void` (due to access of non-existent property `CONSTANT`) [1] is +incompatible with empty [2]. [incompatible-cast] + + exported.js:40:1 + 40| exported_ns.CONSTANT as empty; // prop-missing + ^^^^^^^^^^^^^^^^^^^^ [1] + +References: + exported.js:40:25 + 40| exported_ns.CONSTANT as empty; // prop-missing + ^^^^^ [2] + + +Error ------------------------------------------------------------------------------------------------ exported.js:40:13 + +Cannot get `exported_ns.CONSTANT` because property `CONSTANT` is missing in namespace exported_ns [1]. [prop-missing] + + exported.js:40:13 + 40| exported_ns.CONSTANT as empty; // prop-missing + ^^^^^^^^ + +References: + exported.js:1:19 + 1| declare namespace exported_ns { + ^^^^^^^^^^^ [1] + + Error --------------------------------------------------------------------------------- type_only_react_namespace.js:3:3 Cannot resolve name `React`. [cannot-resolve-name] @@ -339,7 +413,7 @@ use it as an annotation. [value-as-type] Error ---------------------------------------------------------------------------------------------- typing_test.js:12:3 -Cannot use `declare module.exports` statements with in `declare namespace`. The statement will be ignored. +Cannot use declare module.exports statements with in `declare namespace`. The statement will be ignored. [unsupported-syntax] 12| declare module.exports: {foo: string}; // unsupported @@ -363,7 +437,7 @@ References: Error ---------------------------------------------------------------------------------------------- typing_test.js:23:3 -Cannot use `if` statements with in `declare namespace`. The statement will be ignored. [unsupported-syntax] +Cannot use if statements with in `declare namespace`. The statement will be ignored. [unsupported-syntax] 23| if (true) {} // error ^^^^^^^^^^^^ @@ -371,7 +445,7 @@ Cannot use `if` statements with in `declare namespace`. The statement will be ig Error ---------------------------------------------------------------------------------------------- typing_test.js:24:3 -Cannot use `import declaration` statements with in `declare namespace`. The statement will be ignored. +Cannot use import declaration statements with in `declare namespace`. The statement will be ignored. [unsupported-syntax] 24| import React from 'react'; // unsupported @@ -496,27 +570,56 @@ References: Error ---------------------------------------------------------------------------------------------- typing_test.js:36:1 -Cannot cast `exported_ns.B.C` to empty because `B` [1] is incompatible with empty [2]. [incompatible-cast] +Cannot cast `1` to `Baz2` because number [1] is incompatible with string [2]. [incompatible-cast] typing_test.js:36:1 - 36| exported_ns.B.C as empty; // error: enum ~> empty + 36| 1 as exported_ns.Baz2; // error: number ~> string + ^ [1] + +References: + typing_test.js:36:6 + 36| 1 as exported_ns.Baz2; // error: number ~> string + ^^^^^^^^^^^^^^^^ [2] + + +Error ---------------------------------------------------------------------------------------------- typing_test.js:37:1 + +Cannot cast `1` to `Baz3` because number [1], a primitive, cannot be used as a subtype of `Baz3` [2]. You can wrap it in +`new Number(...))` to turn it into an object and attempt to use it as a subtype of an interface. [incompatible-type] + + typing_test.js:37:1 + 37| 1 as exported_ns.Baz3; // error: number ~> interface {} + ^ [1] + +References: + typing_test.js:37:6 + 37| 1 as exported_ns.Baz3; // error: number ~> interface {} + ^^^^^^^^^^^^^^^^ [2] + + +Error ---------------------------------------------------------------------------------------------- typing_test.js:38:1 + +Cannot cast `exported_ns.B.C` to empty because `B` [1] is incompatible with empty [2]. [incompatible-cast] + + typing_test.js:38:1 + 38| exported_ns.B.C as empty; // error: enum ~> empty ^^^^^^^^^^^^^^^ References: exported.js:8:8 8| enum B { C, D } ^ [1] - typing_test.js:36:20 - 36| exported_ns.B.C as empty; // error: enum ~> empty + typing_test.js:38:20 + 38| exported_ns.B.C as empty; // error: enum ~> empty ^^^^^ [2] -Error --------------------------------------------------------------------------------------------- typing_test.js:37:13 +Error --------------------------------------------------------------------------------------------- typing_test.js:39:13 Cannot get `exported_ns.React` because property `React` is missing in namespace exported_ns [1]. [prop-missing] - typing_test.js:37:13 - 37| exported_ns.React; // error: prop-missing + typing_test.js:39:13 + 39| exported_ns.React; // error: prop-missing ^^^^^ References: @@ -525,102 +628,131 @@ References: ^^^^^^^^^^^ [1] -Error ---------------------------------------------------------------------------------------------- typing_test.js:41:1 +Error ---------------------------------------------------------------------------------------------- typing_test.js:40:1 + +Cannot cast `exported_ns.CONSTANT` to empty because `void` (due to access of non-existent property `CONSTANT`) [1] is +incompatible with empty [2]. [incompatible-cast] + + typing_test.js:40:1 + 40| exported_ns.CONSTANT as empty; // error: prop-missing + ^^^^^^^^^^^^^^^^^^^^ [1] + +References: + typing_test.js:40:25 + 40| exported_ns.CONSTANT as empty; // error: prop-missing + ^^^^^ [2] + + +Error --------------------------------------------------------------------------------------------- typing_test.js:40:13 + +Cannot get `exported_ns.CONSTANT` because property `CONSTANT` is missing in namespace exported_ns [1]. [prop-missing] + + typing_test.js:40:13 + 40| exported_ns.CONSTANT as empty; // error: prop-missing + ^^^^^^^^ + +References: + exported.js:1:19 + 1| declare namespace exported_ns { + ^^^^^^^^^^^ [1] + + +Error ---------------------------------------------------------------------------------------------- typing_test.js:44:1 Cannot use type `exported_ns_type_only` [1] as a value. Types are erased and don't exist at runtime. If the exported binding can also be used as a value, try importing it using `import exported_ns_type_only` instead of `import type exported_ns_type_only` and `import {exported_ns_type_only}` instead of `import type {exported_ns_type_only}`. [type-as-value] - typing_test.js:41:1 - 41| exported_ns_type_only; exported_ns_type_only2; // error: type-as-value + typing_test.js:44:1 + 44| exported_ns_type_only; exported_ns_type_only2; // error: type-as-value ^^^^^^^^^^^^^^^^^^^^^ References: - typing_test.js:40:51 - 40| import type {type_only as exported_ns_type_only2, exported_ns_type_only} from './exported'; + typing_test.js:43:51 + 43| import type {type_only as exported_ns_type_only2, exported_ns_type_only} from './exported'; ^^^^^^^^^^^^^^^^^^^^^ [1] -Error --------------------------------------------------------------------------------------------- typing_test.js:41:24 +Error --------------------------------------------------------------------------------------------- typing_test.js:44:24 Cannot use type `exported_ns_type_only2` [1] as a value. Types are erased and don't exist at runtime. If the exported binding can also be used as a value, try importing it using `import exported_ns_type_only2` instead of `import type exported_ns_type_only2` and `import {exported_ns_type_only2}` instead of `import type {exported_ns_type_only2}`. [type-as-value] - typing_test.js:41:24 - 41| exported_ns_type_only; exported_ns_type_only2; // error: type-as-value + typing_test.js:44:24 + 44| exported_ns_type_only; exported_ns_type_only2; // error: type-as-value ^^^^^^^^^^^^^^^^^^^^^^ References: - typing_test.js:40:27 - 40| import type {type_only as exported_ns_type_only2, exported_ns_type_only} from './exported'; + typing_test.js:43:27 + 43| import type {type_only as exported_ns_type_only2, exported_ns_type_only} from './exported'; ^^^^^^^^^^^^^^^^^^^^^^ [1] -Error ---------------------------------------------------------------------------------------------- typing_test.js:45:3 +Error ---------------------------------------------------------------------------------------------- typing_test.js:48:3 Cannot cast `1` to `B` because number [1] is incompatible with `B` [2]. [incompatible-cast] - typing_test.js:45:3 - 45| 1 as exported_ns_type_only.B; // error: number ~> enum + typing_test.js:48:3 + 48| 1 as exported_ns_type_only.B; // error: number ~> enum ^ [1] References: - typing_test.js:45:8 - 45| 1 as exported_ns_type_only.B; // error: number ~> enum + typing_test.js:48:8 + 48| 1 as exported_ns_type_only.B; // error: number ~> enum ^^^^^^^^^^^^^^^^^^^^^^^ [2] -Error ---------------------------------------------------------------------------------------------- typing_test.js:47:3 +Error ---------------------------------------------------------------------------------------------- typing_test.js:50:3 Cannot cast `exported_ns.B.C` to `T` because `B` [1] is incompatible with number [2]. [incompatible-cast] - typing_test.js:47:3 - 47| exported_ns.B.C as exported_ns_type_only2.T; // error: enum ~> number + typing_test.js:50:3 + 50| exported_ns.B.C as exported_ns_type_only2.T; // error: enum ~> number ^^^^^^^^^^^^^^^ References: exported.js:8:8 8| enum B { C, D } ^ [1] - typing_test.js:47:22 - 47| exported_ns.B.C as exported_ns_type_only2.T; // error: enum ~> number + typing_test.js:50:22 + 50| exported_ns.B.C as exported_ns_type_only2.T; // error: enum ~> number ^^^^^^^^^^^^^^^^^^^^^^^^ [2] -Error ---------------------------------------------------------------------------------------------- typing_test.js:52:3 +Error ---------------------------------------------------------------------------------------------- typing_test.js:55:3 Cannot use type-only namespace `type_only` [1] as a value. Type-only namespaces are erased and don't exist at runtime. [type-as-value] - typing_test.js:52:3 - 52| type_only; // error: type-as-value + typing_test.js:55:3 + 55| type_only; // error: type-as-value ^^^^^^^^^ References: - typing_test.js:49:21 - 49| declare namespace type_only { + typing_test.js:52:21 + 52| declare namespace type_only { ^^^^^^^^^ [1] -Error ---------------------------------------------------------------------------------------------- typing_test.js:54:3 +Error ---------------------------------------------------------------------------------------------- typing_test.js:57:3 Cannot cast `1` to `Bar` because number [1] is incompatible with string [2]. [incompatible-cast] - typing_test.js:54:3 - 54| 1 as type_only.Bar; // error: number ~> string + typing_test.js:57:3 + 57| 1 as type_only.Bar; // error: number ~> string ^ [1] References: - typing_test.js:54:8 - 54| 1 as type_only.Bar; // error: number ~> string + typing_test.js:57:8 + 57| 1 as type_only.Bar; // error: number ~> string ^^^^^^^^^^^^^ [2] -Found 43 errors +Found 53 errors Only showing the most relevant union/intersection branches. To see all branches, re-run Flow with --show-all-branches diff --git a/tests/declare_namespace/exported.js b/tests/declare_namespace/exported.js index 5dd1446eb8e..61e4e7e8b13 100644 --- a/tests/declare_namespace/exported.js +++ b/tests/declare_namespace/exported.js @@ -7,6 +7,10 @@ declare namespace exported_ns { declare type Baz = string; enum B { C, D } if (true) {} // unsupported + export type Baz2 = string; + export interface Baz3 {} + export const CONSTANT = 'foo'; // unsupported + export default CONSTANT; // unsupported declare module.exports: {foo: string}; // unsupported import React from 'react'; // unsupported } @@ -29,5 +33,8 @@ exported_ns.bar2 as empty; // error: boolean ~> empty exported_ns.bar3 as empty; // error: string ~> empty exported_ns.f(3) as empty; // error: number ~> empty 1 as exported_ns.Baz; // error: number ~> string +1 as exported_ns.Baz2; // error: number ~> string +1 as exported_ns.Baz3; // error: number ~> interface {} exported_ns.B.C as empty; // error: enum ~> empty exported_ns.React; // error: prop-missing +exported_ns.CONSTANT as empty; // prop-missing diff --git a/tests/declare_namespace/typing_test.js b/tests/declare_namespace/typing_test.js index e6885c6564a..9d8525f4376 100644 --- a/tests/declare_namespace/typing_test.js +++ b/tests/declare_namespace/typing_test.js @@ -33,8 +33,11 @@ exported_ns.bar2 as empty; // error: boolean ~> empty exported_ns.bar3 as empty; // error: string ~> empty exported_ns.f(3) as empty; // error: number ~> empty 1 as exported_ns.Baz; // error: number ~> string +1 as exported_ns.Baz2; // error: number ~> string +1 as exported_ns.Baz3; // error: number ~> interface {} exported_ns.B.C as empty; // error: enum ~> empty exported_ns.React; // error: prop-missing +exported_ns.CONSTANT as empty; // error: prop-missing empty as empty; // ok: already errored being type-only in exported.js import type {type_only as exported_ns_type_only2, exported_ns_type_only} from './exported'; diff --git a/tests/liberr/liberr.exp b/tests/liberr/liberr.exp index 1cbd437a24b..c76658c1b17 100644 --- a/tests/liberr/liberr.exp +++ b/tests/liberr/liberr.exp @@ -55,7 +55,7 @@ Error -------------------------------------------------------------------------- Error --------------------------------------------------------------------------------------- libs/invalid-nested.js:5:1 -Cannot use `block` statements in a library file. The statement will be ignored. [unsupported-syntax] +Cannot use block statements in a library file. The statement will be ignored. [unsupported-syntax] v 5| { @@ -66,7 +66,7 @@ Cannot use `block` statements in a library file. The statement will be ignored. Error --------------------------------------------------------------------------------------- libs/invalid-nested.js:9:1 -Cannot use `if` statements in a library file. The statement will be ignored. [unsupported-syntax] +Cannot use if statements in a library file. The statement will be ignored. [unsupported-syntax] v---------- 9| if (true) { @@ -101,7 +101,7 @@ Cannot use type without exactly 1 type argument. [nonpolymorphic-type-app] Error ------------------------------------------------------------------------------- libs/unsupported-statements.js:3:3 -Cannot use `if` statements in a library file. The statement will be ignored. [unsupported-syntax] +Cannot use if statements in a library file. The statement will be ignored. [unsupported-syntax] 3| if (true) {} // error ^^^^^^^^^^^^ @@ -109,12 +109,28 @@ Cannot use `if` statements in a library file. The statement will be ignored. [un Error ------------------------------------------------------------------------------- libs/unsupported-statements.js:3:3 -Cannot use `if` statements with in `declare module`. The statement will be ignored. [unsupported-syntax] +Cannot use if statements with in `declare module`. The statement will be ignored. [unsupported-syntax] 3| if (true) {} // error ^^^^^^^^^^^^ +Error ------------------------------------------------------------------------------- libs/unsupported-statements.js:4:3 + +Cannot use value export statements in a library file. The statement will be ignored. [unsupported-syntax] + + 4| export const foo = ''; // error + ^^^^^^^^^^^^^^^^^^^^^^ + + +Error ------------------------------------------------------------------------------- libs/unsupported-statements.js:4:3 + +Cannot use value export statements with in `declare module`. The statement will be ignored. [unsupported-syntax] + + 4| export const foo = ''; // error + ^^^^^^^^^^^^^^^^^^^^^^ + + Error -------------------------------------------------------------------------------------------------------- a.js:5:17 Cannot assign `0` to `x` because number [1] is incompatible with string [2]. [incompatible-type] @@ -205,7 +221,7 @@ References: -Found 20 errors +Found 22 errors ============================================ With warnings: @@ -264,7 +280,7 @@ Error -------------------------------------------------------------------------- Error --------------------------------------------------------------------------------------- libs/invalid-nested.js:5:1 -Cannot use `block` statements in a library file. The statement will be ignored. [unsupported-syntax] +Cannot use block statements in a library file. The statement will be ignored. [unsupported-syntax] v 5| { @@ -275,7 +291,7 @@ Cannot use `block` statements in a library file. The statement will be ignored. Error --------------------------------------------------------------------------------------- libs/invalid-nested.js:9:1 -Cannot use `if` statements in a library file. The statement will be ignored. [unsupported-syntax] +Cannot use if statements in a library file. The statement will be ignored. [unsupported-syntax] v---------- 9| if (true) { @@ -310,7 +326,7 @@ Cannot use type without exactly 1 type argument. [nonpolymorphic-type-app] Error ------------------------------------------------------------------------------- libs/unsupported-statements.js:3:3 -Cannot use `if` statements in a library file. The statement will be ignored. [unsupported-syntax] +Cannot use if statements in a library file. The statement will be ignored. [unsupported-syntax] 3| if (true) {} // error ^^^^^^^^^^^^ @@ -318,12 +334,28 @@ Cannot use `if` statements in a library file. The statement will be ignored. [un Error ------------------------------------------------------------------------------- libs/unsupported-statements.js:3:3 -Cannot use `if` statements with in `declare module`. The statement will be ignored. [unsupported-syntax] +Cannot use if statements with in `declare module`. The statement will be ignored. [unsupported-syntax] 3| if (true) {} // error ^^^^^^^^^^^^ +Error ------------------------------------------------------------------------------- libs/unsupported-statements.js:4:3 + +Cannot use value export statements in a library file. The statement will be ignored. [unsupported-syntax] + + 4| export const foo = ''; // error + ^^^^^^^^^^^^^^^^^^^^^^ + + +Error ------------------------------------------------------------------------------- libs/unsupported-statements.js:4:3 + +Cannot use value export statements with in `declare module`. The statement will be ignored. [unsupported-syntax] + + 4| export const foo = ''; // error + ^^^^^^^^^^^^^^^^^^^^^^ + + Error -------------------------------------------------------------------------------------------------------- a.js:5:17 Cannot assign `0` to `x` because number [1] is incompatible with string [2]. [incompatible-type] @@ -422,4 +454,4 @@ Suppression is missing a code. Please update this suppression to use an error co -Found 20 errors and 1 warning +Found 22 errors and 1 warning diff --git a/tests/liberr/libs/unsupported-statements.js b/tests/liberr/libs/unsupported-statements.js index bfa6ad341cb..07f882e587c 100644 --- a/tests/liberr/libs/unsupported-statements.js +++ b/tests/liberr/libs/unsupported-statements.js @@ -1,4 +1,6 @@ declare module 'contains-unsupported-statements' { declare const a: number; if (true) {} // error + export const foo = ''; // error + export type Bar = string; // ok } diff --git a/tests/poorly_formed_exports/poorly_formed_exports.exp b/tests/poorly_formed_exports/poorly_formed_exports.exp index ff0ccf27e3d..44dea08e6cd 100644 --- a/tests/poorly_formed_exports/poorly_formed_exports.exp +++ b/tests/poorly_formed_exports/poorly_formed_exports.exp @@ -1,7 +1,7 @@ FLOW STATUS: Error ------------------------------------------------------------------------------------------------- libs/libs.js:3:1 -Cannot use `block` statements in a library file. The statement will be ignored. [unsupported-syntax] +Cannot use block statements in a library file. The statement will be ignored. [unsupported-syntax] v 3| { diff --git a/tests/poorly_formed_exports_config_false/poorly_formed_exports_config_false.exp b/tests/poorly_formed_exports_config_false/poorly_formed_exports_config_false.exp index dd96be0c37c..74d165ae54e 100644 --- a/tests/poorly_formed_exports_config_false/poorly_formed_exports_config_false.exp +++ b/tests/poorly_formed_exports_config_false/poorly_formed_exports_config_false.exp @@ -1,7 +1,7 @@ FLOW STATUS: Error ------------------------------------------------------------------------------------------------- libs/libs.js:3:1 -Cannot use `block` statements in a library file. The statement will be ignored. [unsupported-syntax] +Cannot use block statements in a library file. The statement will be ignored. [unsupported-syntax] v 3| {