From a0dba5d402631a96f571f0e9e90705fe78d0c6b2 Mon Sep 17 00:00:00 2001 From: andretshurotshka Date: Wed, 16 Oct 2019 14:37:30 -0700 Subject: [PATCH] [PR] Implement versioned .js.flow Summary: Proof of concept for https://github.com/facebook/flow/issues/4917 Has bad performance on all resolutions ## Performance checks Current measurements: https://gist.github.com/goodmind/65695c3b7a3aa0766812b15779a984dc 1. Build flow binary 2. Run `flow check --profile` on codebase 3. Record results 4. Repeat with regular flow binary and this PR, properly stopping all servers before running new binary Pull Request resolved: https://github.com/facebook/flow/pull/7842 Differential Revision: D16431326 fbshipit-source-id: a18211b0160cf44f76f80b74ac246fd06d24c9d5 --- hack/utils/string/string_utils.ml | 4 +- hack/utils/string/string_utils.mli | 2 +- src/parser_utils/package_json.ml | 65 +++++++++++++++- src/parser_utils/package_json.mli | 2 + src/services/inference/module/module_js.ml | 76 ++++++++++++++++++ .../inference/module/node_paths_part.ml | 78 +++++++++++++++++++ src/state/locals/module/module_hashtables.ml | 9 +++ src/state/locals/module/module_hashtables.mli | 3 + .../.flowconfig | 7 ++ .../declaration_files_node_versions.exp | 1 + .../node_modules/bar/index.js | 3 + .../node_modules/flow_empty/index.js | 3 + .../node_modules/flow_empty/package.json | 5 ++ .../node_modules/flow_random/index.js | 3 + .../node_modules/flow_random/package.json | 5 ++ .../node_modules/foo/index.js | 3 + .../node_modules/foo/ok.js | 3 + .../node_modules/foo/package.json | 9 +++ .../node_modules/foo_fail/index.js | 3 + .../node_modules/foo_fail/package.json | 9 +++ .../hello/flow_0.98.x-/foo/index.js.flow | 3 + .../hello/flow_0.98.x-/index.js.flow | 3 + .../node_modules/hello/index.js.flow | 2 + .../node_modules/hello/package.json | 9 +++ .../types_versions_empty/index.js | 3 + .../types_versions_empty/package.json | 7 ++ .../types_versions_random/index.js | 3 + .../types_versions_random/package.json | 9 +++ .../types_versions_random_2/index.js | 3 + .../types_versions_random_2/package.json | 9 +++ .../test_empty_flow_section.js | 5 ++ .../test_empty_types_versions.js | 5 ++ .../test_file_resolving.js | 5 ++ .../test_flow_random.js | 5 ++ .../test_folder.js | 7 ++ .../test_relative_parent.js | 5 ++ .../test_types_versions_random.js | 7 ++ 37 files changed, 379 insertions(+), 4 deletions(-) create mode 100644 src/services/inference/module/node_paths_part.ml create mode 100644 tests/declaration_files_node_versions/.flowconfig create mode 100644 tests/declaration_files_node_versions/declaration_files_node_versions.exp create mode 100644 tests/declaration_files_node_versions/node_modules/bar/index.js create mode 100644 tests/declaration_files_node_versions/node_modules/flow_empty/index.js create mode 100644 tests/declaration_files_node_versions/node_modules/flow_empty/package.json create mode 100644 tests/declaration_files_node_versions/node_modules/flow_random/index.js create mode 100644 tests/declaration_files_node_versions/node_modules/flow_random/package.json create mode 100644 tests/declaration_files_node_versions/node_modules/foo/index.js create mode 100644 tests/declaration_files_node_versions/node_modules/foo/ok.js create mode 100644 tests/declaration_files_node_versions/node_modules/foo/package.json create mode 100644 tests/declaration_files_node_versions/node_modules/foo_fail/index.js create mode 100644 tests/declaration_files_node_versions/node_modules/foo_fail/package.json create mode 100644 tests/declaration_files_node_versions/node_modules/hello/flow_0.98.x-/foo/index.js.flow create mode 100644 tests/declaration_files_node_versions/node_modules/hello/flow_0.98.x-/index.js.flow create mode 100644 tests/declaration_files_node_versions/node_modules/hello/index.js.flow create mode 100644 tests/declaration_files_node_versions/node_modules/hello/package.json create mode 100644 tests/declaration_files_node_versions/node_modules/types_versions_empty/index.js create mode 100644 tests/declaration_files_node_versions/node_modules/types_versions_empty/package.json create mode 100644 tests/declaration_files_node_versions/node_modules/types_versions_random/index.js create mode 100644 tests/declaration_files_node_versions/node_modules/types_versions_random/package.json create mode 100644 tests/declaration_files_node_versions/node_modules/types_versions_random_2/index.js create mode 100644 tests/declaration_files_node_versions/node_modules/types_versions_random_2/package.json create mode 100644 tests/declaration_files_node_versions/test_empty_flow_section.js create mode 100644 tests/declaration_files_node_versions/test_empty_types_versions.js create mode 100644 tests/declaration_files_node_versions/test_file_resolving.js create mode 100644 tests/declaration_files_node_versions/test_flow_random.js create mode 100644 tests/declaration_files_node_versions/test_folder.js create mode 100644 tests/declaration_files_node_versions/test_relative_parent.js create mode 100644 tests/declaration_files_node_versions/test_types_versions_random.js diff --git a/hack/utils/string/string_utils.ml b/hack/utils/string/string_utils.ml index 6872f6f3d4d..1fd97cab021 100644 --- a/hack/utils/string/string_utils.ml +++ b/hack/utils/string/string_utils.ml @@ -34,7 +34,7 @@ let string_ends_with long short = `haystack`. If not found, returns -1. An implementation of the Knuth-Morris-Pratt (KMP) algorithm. *) -let substring_index needle = +let substring_index ?(start_pos = 0) needle = (* see Wikipedia pseudocode *) let needle_len = String.length needle in if needle_len = 0 then raise (Invalid_argument needle); @@ -55,7 +55,7 @@ let substring_index needle = done; fun haystack -> let len = String.length haystack in - let p = ref 0 in + let p = ref start_pos in let q = ref 0 in while !p < len && !q < needle_len do if haystack.[!p] = needle.[!q] then ( diff --git a/hack/utils/string/string_utils.mli b/hack/utils/string/string_utils.mli index 768a7170172..215d033e037 100644 --- a/hack/utils/string/string_utils.mli +++ b/hack/utils/string/string_utils.mli @@ -27,7 +27,7 @@ val string_starts_with : string -> string -> bool val string_ends_with : string -> string -> bool -val substring_index : string -> string -> int +val substring_index : ?start_pos:int -> string -> string -> int val is_substring : string -> string -> bool diff --git a/src/parser_utils/package_json.ml b/src/parser_utils/package_json.ml index b5163afa0c0..38caebad28b 100644 --- a/src/parser_utils/package_json.ml +++ b/src/parser_utils/package_json.ml @@ -7,21 +7,29 @@ module Ast = Flow_ast +type flow_t = { types_versions: string SMap.t } + type t = { name: string option; main: string option; + flow: flow_t option; } type 'a t_or_error = (t, 'a * string) result let ( >>= ) = Core_result.( >>= ) -let empty = { name = None; main = None } +let empty = { name = None; main = None; flow = None } let name package = package.name let main package = package.main +let flow_types_versions package = + match package.flow with + | Some t -> t.types_versions + | None -> SMap.empty + let statement_of_program = function | (_, [statement], _) -> Ok statement | (loc, _, _) -> Error (loc, "Expected a single statement.") @@ -45,6 +53,46 @@ let properties_of_object = function | (_, Ast.Expression.Object { Ast.Expression.Object.properties; comments = _ }) -> Ok properties | (loc, _) -> Error (loc, "Expected an object literal") +let parse_flow properties = + Ast.( + Expression.Object.( + let extract_property (flow : flow_t) = function + | Property + ( _, + Property.Init + { + key = Property.Literal (_, { Literal.value = Literal.String key; _ }); + value = (_, Expression.Object { Expression.Object.properties; _ }); + _; + } ) -> + begin + match key with + | "typesVersions" -> + let value = + List.fold_left + (fun map property -> + match property with + | Property + ( _, + Property.Init + { + key = Property.Literal (_, { Literal.value = Literal.String key; _ }); + value = + (_, Expression.Literal { Literal.value = Literal.String value; _ }); + _; + } ) -> + SMap.add key value map + | _ -> map) + SMap.empty + properties + in + { types_versions = value } + | _ -> flow + end + | _ -> flow + in + List.fold_left extract_property { types_versions = SMap.empty } properties)) + let parse ast : 'a t_or_error = statement_of_program ast >>= object_of_statement @@ -67,6 +115,21 @@ let parse ast : 'a t_or_error = | "main" -> { package with main = Some value } | _ -> package end + | Property + ( _, + Property.Init + { + key = Property.Literal (_, { Literal.value = Literal.String key; _ }); + value = (_, Expression.Object { Expression.Object.properties; _ }); + _; + } ) -> + begin + match key with + | "flow" -> + let value = parse_flow properties in + { package with flow = Some value } + | _ -> package + end | _ -> package in Ok (List.fold_left extract_property empty properties))) diff --git a/src/parser_utils/package_json.mli b/src/parser_utils/package_json.mli index 966a4814796..a8cec78d6aa 100644 --- a/src/parser_utils/package_json.mli +++ b/src/parser_utils/package_json.mli @@ -15,4 +15,6 @@ val name : t -> string option val main : t -> string option +val flow_types_versions : t -> string SMap.t + val parse : (Loc.t, Loc.t) Flow_ast.program -> Loc.t t_or_error diff --git a/src/services/inference/module/module_js.ml b/src/services/inference/module/module_js.ml index 014e1ccd235..b909fed4c31 100644 --- a/src/services/inference/module/module_js.ml +++ b/src/services/inference/module/module_js.ml @@ -93,6 +93,69 @@ let module_name_candidates ~options = in List.rev (name :: List.fold_left map_name [] mappers)) +let types_versions_package_candidates reader = + Module_hashtables.memoize_with_types_versions_candidates_cache ~f:(fun package_filename -> + let package = + match Module_heaps.Reader_dispatcher.get_package ~reader package_filename with + | Some (Ok package) -> package + | _ -> Package_json.empty + in + let types_versions = Package_json.flow_types_versions package in + let version_path = + SMap.find_first_opt + (fun k -> + try Semver.satisfies ~include_prereleases:true k Flow_version.version + with Semver.Parse_error _ -> false) + types_versions + in + version_path) + +let types_versions_candidates ~reader dir rel_path dirname = + Node_paths_part.( + let parts = get_node_module_path_parts rel_path dirname in + match parts with + | Some parts -> + let package_root = + if parts.package_root_index == -1 then + rel_path + else + String.sub rel_path 0 parts.package_root_index + in + let package_filename = Filename.concat package_root "package.json" in + let package_filename = Files.normalize_path dir package_filename in + let version_path = types_versions_package_candidates reader package_filename in + let filename = + if parts.package_root_index == -1 then + "" + else + String.sub + rel_path + (parts.package_root_index + 1) + (String.length rel_path - (parts.package_root_index + 1)) + in + let rel_path = + match version_path with + | Some (_, version_path) -> + (* Chop trailing "/" *) + let tail = + if filename = "" then + version_path + else + Filename.concat version_path filename + in + Files.normalize_path package_root tail + | None -> rel_path + in + (* If file points outside of root, resolve current package root *) + let rel_path = + if String_utils.string_starts_with rel_path package_root then + rel_path + else + Files.normalize_path package_root filename + in + Some rel_path + | _ -> None) + let add_package filename = function | Ok package -> Module_heaps.Package_heap_mutator.add_package_json filename package | Error _ -> Module_heaps.Package_heap_mutator.add_error filename @@ -320,6 +383,19 @@ module Node = struct let file_options = Options.file_options options in lazy_seq [ + lazy + ( if SSet.mem dir node_modules_containers then + lazy_seq + ( Files.node_resolver_dirnames file_options + |> Core_list.map ~f:(fun dirname -> + let rel_path = spf "%s%s%s" dirname Filename.dir_sep r in + let rel_path_opt = types_versions_candidates ~reader dir rel_path dirname in + match rel_path_opt with + | Some rel_path -> + lazy (resolve_relative ~options ~reader loc ?resolution_acc dir rel_path) + | _ -> lazy None) ) + else + None ); lazy ( if SSet.mem dir node_modules_containers then lazy_seq diff --git a/src/services/inference/module/node_paths_part.ml b/src/services/inference/module/node_paths_part.ml new file mode 100644 index 00000000000..1bfd6a4d39f --- /dev/null +++ b/src/services/inference/module/node_paths_part.ml @@ -0,0 +1,78 @@ +(** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + *) + +type node_module_path_parts = { + top_level_node_modules_index: int; + top_level_package_name_index: int; + package_root_index: int; + file_name_index: int; +} + +type states = { + before_node_modules: int; + node_modules: int; + scope: int; + package_content: int; +} + +let states = { before_node_modules = 0; node_modules = 1; scope = 2; package_content = 3 } + +(* Example of expected pattern: /base/path/node_modules/[@scope/otherpackage/@otherscope/node_modules/]package/[subdirectory/]file.js *) +(* Returns indices: ^ ^ ^ ^ *) +let get_node_module_path_parts (full_path : string) (node_modules_path_part : string) : + node_module_path_parts option = + let top_level_node_modules_index = ref 0 in + let top_level_package_name_index = ref 0 in + let package_root_index = ref 0 in + let file_name_index = ref 0 in + let part_start = ref 0 in + let part_end = ref 0 in + let state = ref states.before_node_modules in + while !part_end >= 0 do + part_start := !part_end; + part_end := + String_utils.substring_index ~start_pos:(!part_start + 1) Filename.dir_sep full_path; + + if !state == states.before_node_modules then ( + let start = !part_start in + let index = String_utils.substring_index ~start_pos:start node_modules_path_part full_path in + if index == start then ( + top_level_node_modules_index := start; + top_level_package_name_index := !part_end; + state := states.node_modules + ) + ) else if !state == states.node_modules || !state == states.scope then + let index = !part_start + 1 in + let ch = full_path.[index] in + let has_scope = ch == '@' in + if !state == states.node_modules && has_scope then + state := states.scope + else ( + package_root_index := !part_end; + state := states.package_content + ) + else if !state == states.package_content then ( + let index = + String_utils.substring_index ~start_pos:!part_start node_modules_path_part full_path + in + if index == !part_start then state := states.node_modules + ) else + state := states.package_content + done; + + file_name_index := !part_start; + + if !state > states.node_modules then + Some + { + top_level_node_modules_index = !top_level_node_modules_index; + top_level_package_name_index = !top_level_package_name_index; + package_root_index = !package_root_index; + file_name_index = !file_name_index; + } + else + None diff --git a/src/state/locals/module/module_hashtables.ml b/src/state/locals/module/module_hashtables.ml index 437dde288c2..e11ca3e8e15 100644 --- a/src/state/locals/module/module_hashtables.ml +++ b/src/state/locals/module/module_hashtables.ml @@ -114,3 +114,12 @@ let memoize_with_module_name_candidates_cache ~f name = let result = f name in Hashtbl.add module_name_candidates_cache name result; result + +let types_versions_candidates_cache = Hashtbl.create 100 + +let memoize_with_types_versions_candidates_cache ~f name = + try Hashtbl.find types_versions_candidates_cache name + with Not_found -> + let result = f name in + Hashtbl.add types_versions_candidates_cache name result; + result diff --git a/src/state/locals/module/module_hashtables.mli b/src/state/locals/module/module_hashtables.mli index 56da6763d20..6740b843fca 100644 --- a/src/state/locals/module/module_hashtables.mli +++ b/src/state/locals/module/module_hashtables.mli @@ -24,3 +24,6 @@ module All_providers_mutator : sig end val memoize_with_module_name_candidates_cache : f:(string -> string list) -> string -> string list + +val memoize_with_types_versions_candidates_cache : + f:(string -> (SMap.key * string) option) -> string -> (SMap.key * string) option diff --git a/tests/declaration_files_node_versions/.flowconfig b/tests/declaration_files_node_versions/.flowconfig new file mode 100644 index 00000000000..4a58bdcdef3 --- /dev/null +++ b/tests/declaration_files_node_versions/.flowconfig @@ -0,0 +1,7 @@ +[ignore] + +[include] + +[libs] + +[options] diff --git a/tests/declaration_files_node_versions/declaration_files_node_versions.exp b/tests/declaration_files_node_versions/declaration_files_node_versions.exp new file mode 100644 index 00000000000..2829d581f51 --- /dev/null +++ b/tests/declaration_files_node_versions/declaration_files_node_versions.exp @@ -0,0 +1 @@ +Found 0 errors diff --git a/tests/declaration_files_node_versions/node_modules/bar/index.js b/tests/declaration_files_node_versions/node_modules/bar/index.js new file mode 100644 index 00000000000..4f9ca88ccd0 --- /dev/null +++ b/tests/declaration_files_node_versions/node_modules/bar/index.js @@ -0,0 +1,3 @@ +//@flow + +declare export var foo: 'this is bar'; diff --git a/tests/declaration_files_node_versions/node_modules/flow_empty/index.js b/tests/declaration_files_node_versions/node_modules/flow_empty/index.js new file mode 100644 index 00000000000..0f3d6249a1e --- /dev/null +++ b/tests/declaration_files_node_versions/node_modules/flow_empty/index.js @@ -0,0 +1,3 @@ +// @flow + +declare export var flow_empty: 'ok'; diff --git a/tests/declaration_files_node_versions/node_modules/flow_empty/package.json b/tests/declaration_files_node_versions/node_modules/flow_empty/package.json new file mode 100644 index 00000000000..aead33ea702 --- /dev/null +++ b/tests/declaration_files_node_versions/node_modules/flow_empty/package.json @@ -0,0 +1,5 @@ +{ + "name": "flow_empty", + "flow": {}, + "main": "./index.js" +} diff --git a/tests/declaration_files_node_versions/node_modules/flow_random/index.js b/tests/declaration_files_node_versions/node_modules/flow_random/index.js new file mode 100644 index 00000000000..b6a40d3a396 --- /dev/null +++ b/tests/declaration_files_node_versions/node_modules/flow_random/index.js @@ -0,0 +1,3 @@ +// @flow + +declare export var flow_random: 'ok'; diff --git a/tests/declaration_files_node_versions/node_modules/flow_random/package.json b/tests/declaration_files_node_versions/node_modules/flow_random/package.json new file mode 100644 index 00000000000..e6c578992fe --- /dev/null +++ b/tests/declaration_files_node_versions/node_modules/flow_random/package.json @@ -0,0 +1,5 @@ +{ + "name": "flow_empty", + "flow": "flow", + "main": "./index.js" +} diff --git a/tests/declaration_files_node_versions/node_modules/foo/index.js b/tests/declaration_files_node_versions/node_modules/foo/index.js new file mode 100644 index 00000000000..a327b9f8d04 --- /dev/null +++ b/tests/declaration_files_node_versions/node_modules/foo/index.js @@ -0,0 +1,3 @@ +//@flow + +declare export var foo: 'not ok'; diff --git a/tests/declaration_files_node_versions/node_modules/foo/ok.js b/tests/declaration_files_node_versions/node_modules/foo/ok.js new file mode 100644 index 00000000000..65f8cab9ef4 --- /dev/null +++ b/tests/declaration_files_node_versions/node_modules/foo/ok.js @@ -0,0 +1,3 @@ +//@flow + +declare export var foo: 'ok'; diff --git a/tests/declaration_files_node_versions/node_modules/foo/package.json b/tests/declaration_files_node_versions/node_modules/foo/package.json new file mode 100644 index 00000000000..b7a74e97b0b --- /dev/null +++ b/tests/declaration_files_node_versions/node_modules/foo/package.json @@ -0,0 +1,9 @@ +{ + "name": "foo", + "main": "./index.js", + "flow": { + "typesVersions": { + ">=0.98.0": "./ok.js" + } + } +} diff --git a/tests/declaration_files_node_versions/node_modules/foo_fail/index.js b/tests/declaration_files_node_versions/node_modules/foo_fail/index.js new file mode 100644 index 00000000000..066a600cfbe --- /dev/null +++ b/tests/declaration_files_node_versions/node_modules/foo_fail/index.js @@ -0,0 +1,3 @@ +//@flow + +declare export var foo: 'this is foo'; diff --git a/tests/declaration_files_node_versions/node_modules/foo_fail/package.json b/tests/declaration_files_node_versions/node_modules/foo_fail/package.json new file mode 100644 index 00000000000..d4f8a214502 --- /dev/null +++ b/tests/declaration_files_node_versions/node_modules/foo_fail/package.json @@ -0,0 +1,9 @@ +{ + "name": "foo_fail", + "main": "./index.js", + "flow": { + "typesVersions": { + ">=0.98.0": "../bar" + } + } +} diff --git a/tests/declaration_files_node_versions/node_modules/hello/flow_0.98.x-/foo/index.js.flow b/tests/declaration_files_node_versions/node_modules/hello/flow_0.98.x-/foo/index.js.flow new file mode 100644 index 00000000000..fb2b78265d1 --- /dev/null +++ b/tests/declaration_files_node_versions/node_modules/hello/flow_0.98.x-/foo/index.js.flow @@ -0,0 +1,3 @@ +//@flow + +declare export default number; diff --git a/tests/declaration_files_node_versions/node_modules/hello/flow_0.98.x-/index.js.flow b/tests/declaration_files_node_versions/node_modules/hello/flow_0.98.x-/index.js.flow new file mode 100644 index 00000000000..9a7b8880f3b --- /dev/null +++ b/tests/declaration_files_node_versions/node_modules/hello/flow_0.98.x-/index.js.flow @@ -0,0 +1,3 @@ +//@flow + +declare export var version: '>=0.98.0'; diff --git a/tests/declaration_files_node_versions/node_modules/hello/index.js.flow b/tests/declaration_files_node_versions/node_modules/hello/index.js.flow new file mode 100644 index 00000000000..f7128bf961a --- /dev/null +++ b/tests/declaration_files_node_versions/node_modules/hello/index.js.flow @@ -0,0 +1,2 @@ +//@flow + diff --git a/tests/declaration_files_node_versions/node_modules/hello/package.json b/tests/declaration_files_node_versions/node_modules/hello/package.json new file mode 100644 index 00000000000..50312c3b069 --- /dev/null +++ b/tests/declaration_files_node_versions/node_modules/hello/package.json @@ -0,0 +1,9 @@ +{ + "name": "hello", + "main": "./index.js", + "flow": { + "typesVersions": { + ">=0.98.0": "./flow_0.98.x-" + } + } +} diff --git a/tests/declaration_files_node_versions/node_modules/types_versions_empty/index.js b/tests/declaration_files_node_versions/node_modules/types_versions_empty/index.js new file mode 100644 index 00000000000..6b6a14dfa2c --- /dev/null +++ b/tests/declaration_files_node_versions/node_modules/types_versions_empty/index.js @@ -0,0 +1,3 @@ +// @flow + +declare export var types_versions_empty: 'ok'; diff --git a/tests/declaration_files_node_versions/node_modules/types_versions_empty/package.json b/tests/declaration_files_node_versions/node_modules/types_versions_empty/package.json new file mode 100644 index 00000000000..0b378027b60 --- /dev/null +++ b/tests/declaration_files_node_versions/node_modules/types_versions_empty/package.json @@ -0,0 +1,7 @@ +{ + "name": "types_versions_empty", + "flow": { + "typesVersions": {} + }, + "main": "./index.js" +} diff --git a/tests/declaration_files_node_versions/node_modules/types_versions_random/index.js b/tests/declaration_files_node_versions/node_modules/types_versions_random/index.js new file mode 100644 index 00000000000..7deba4d63bf --- /dev/null +++ b/tests/declaration_files_node_versions/node_modules/types_versions_random/index.js @@ -0,0 +1,3 @@ +// @flow + +declare export var types_versions_random: 'ok'; diff --git a/tests/declaration_files_node_versions/node_modules/types_versions_random/package.json b/tests/declaration_files_node_versions/node_modules/types_versions_random/package.json new file mode 100644 index 00000000000..565118dab80 --- /dev/null +++ b/tests/declaration_files_node_versions/node_modules/types_versions_random/package.json @@ -0,0 +1,9 @@ +{ + "name": "types_versions_random", + "main": "./index.js", + "flow": { + "typesVersions": { + "wow": "xd" + } + } +} diff --git a/tests/declaration_files_node_versions/node_modules/types_versions_random_2/index.js b/tests/declaration_files_node_versions/node_modules/types_versions_random_2/index.js new file mode 100644 index 00000000000..899cf9fae75 --- /dev/null +++ b/tests/declaration_files_node_versions/node_modules/types_versions_random_2/index.js @@ -0,0 +1,3 @@ +// @flow + +declare export var types_versions_random_2: 'ok'; diff --git a/tests/declaration_files_node_versions/node_modules/types_versions_random_2/package.json b/tests/declaration_files_node_versions/node_modules/types_versions_random_2/package.json new file mode 100644 index 00000000000..fdb21e30b3f --- /dev/null +++ b/tests/declaration_files_node_versions/node_modules/types_versions_random_2/package.json @@ -0,0 +1,9 @@ +{ + "name": "types_versions_random_2", + "main": "./index.js", + "flow": { + "typesVersions": { + ">=0.98.0": "foo" + } + } +} diff --git a/tests/declaration_files_node_versions/test_empty_flow_section.js b/tests/declaration_files_node_versions/test_empty_flow_section.js new file mode 100644 index 00000000000..c23601586cf --- /dev/null +++ b/tests/declaration_files_node_versions/test_empty_flow_section.js @@ -0,0 +1,5 @@ +// @flow + +import { flow_empty } from 'flow_empty'; + +(flow_empty: 'ok'); // no errors diff --git a/tests/declaration_files_node_versions/test_empty_types_versions.js b/tests/declaration_files_node_versions/test_empty_types_versions.js new file mode 100644 index 00000000000..7232a29a2e7 --- /dev/null +++ b/tests/declaration_files_node_versions/test_empty_types_versions.js @@ -0,0 +1,5 @@ +// @flow + +import {types_versions_empty} from 'types_versions_empty' + +;(types_versions_empty: 'ok') // no errors diff --git a/tests/declaration_files_node_versions/test_file_resolving.js b/tests/declaration_files_node_versions/test_file_resolving.js new file mode 100644 index 00000000000..fc5eebfa4e4 --- /dev/null +++ b/tests/declaration_files_node_versions/test_file_resolving.js @@ -0,0 +1,5 @@ +//@flow + +import { foo } from 'foo'; + +(foo: 'ok'); // no errors diff --git a/tests/declaration_files_node_versions/test_flow_random.js b/tests/declaration_files_node_versions/test_flow_random.js new file mode 100644 index 00000000000..e74624f51b0 --- /dev/null +++ b/tests/declaration_files_node_versions/test_flow_random.js @@ -0,0 +1,5 @@ +// @flow + +import {flow_random} from 'flow_random'; + +;(flow_random: 'ok') // no errors diff --git a/tests/declaration_files_node_versions/test_folder.js b/tests/declaration_files_node_versions/test_folder.js new file mode 100644 index 00000000000..e01e0017dce --- /dev/null +++ b/tests/declaration_files_node_versions/test_folder.js @@ -0,0 +1,7 @@ +//@flow + +import {version} from 'hello'; +import data from 'hello/foo'; + +;(version: '>=0.98.0') // no errors +;(data: number) // no errors diff --git a/tests/declaration_files_node_versions/test_relative_parent.js b/tests/declaration_files_node_versions/test_relative_parent.js new file mode 100644 index 00000000000..45d02aeaa8f --- /dev/null +++ b/tests/declaration_files_node_versions/test_relative_parent.js @@ -0,0 +1,5 @@ +//@flow + +import { foo } from 'foo_fail'; + +(foo: 'this is foo'); // no error diff --git a/tests/declaration_files_node_versions/test_types_versions_random.js b/tests/declaration_files_node_versions/test_types_versions_random.js new file mode 100644 index 00000000000..23fc3c5a635 --- /dev/null +++ b/tests/declaration_files_node_versions/test_types_versions_random.js @@ -0,0 +1,7 @@ +// @flow + +import {types_versions_random} from 'types_versions_random' +import {types_versions_random_2} from 'types_versions_random_2' + +;(types_versions_random: 'ok') // no errors, no crashes +;(types_versions_random_2: 'ok') // no errors