Skip to content

Commit 7b624f5

Browse files
SamChou19815facebook-github-bot
authored andcommitted
[flow] Include the full set of libdefs in saved state
Summary: The only reason we are excluding the builtin ones is because its relative path against the root might be unstable across machines. However, the problem has been addressed with the infra added in D69577613, and we are fully capable of normalizing, storing, and denormalizing all libdef paths, so let's reduce the complexity and just store everything. Changelog: [internal] Reviewed By: panagosg7 Differential Revision: D69871981 fbshipit-source-id: 2024b362b78bc33ab531e02e2652eab9fe8c89b4
1 parent 95bcff8 commit 7b624f5

File tree

10 files changed

+77
-53
lines changed

10 files changed

+77
-53
lines changed

src/common/files.ml

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -546,14 +546,9 @@ let is_in_flowlib (options : options) : string -> bool =
546546
let root = File_path.make root_str in
547547
is_prefix (File_path.to_string root)
548548

549-
let init ?(flowlibs_only = false) (options : options) =
549+
let init (options : options) =
550550
let node_module_filter = is_node_module options in
551-
let libs =
552-
if flowlibs_only then
553-
[]
554-
else
555-
options.lib_paths
556-
in
551+
let libs = options.lib_paths in
557552
let (libs, filter) =
558553
match options.default_lib_dir with
559554
| None -> (libs, is_valid_path ~options)

src/common/files.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ val is_in_flowlib : options -> string -> bool
108108

109109
val get_all_watched_extensions : options -> SSet.t
110110

111-
val init : ?flowlibs_only:bool -> options -> string list * SSet.t
111+
val init : options -> string list * SSet.t
112112

113113
(* regexp for Filename constants *)
114114
val dir_sep : Str.regexp

src/services/inference/types_js.ml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1874,18 +1874,13 @@ let init_with_initial_state
18741874
let init_from_saved_state ~profiling ~workers ~saved_state ~updates ?env options =
18751875
with_transaction "init" @@ fun transaction reader ->
18761876
let is_init = Option.is_none env in
1877-
let file_options = Options.file_options options in
1878-
1879-
(* We don't want to walk the file system for the checked in files. But we still need to find the
1880-
* flowlibs *)
1881-
let (ordered_flowlib_libs, _) = Files.init ~flowlibs_only:true file_options in
18821877

18831878
let {
18841879
Saved_state.flowconfig_hash = _;
18851880
parsed_heaps;
18861881
unparsed_heaps;
18871882
package_heaps;
1888-
ordered_non_flowlib_libs;
1883+
ordered_libs;
18891884
local_errors;
18901885
node_modules_containers;
18911886
dependency_graph;
@@ -2077,7 +2072,6 @@ let init_from_saved_state ~profiling ~workers ~saved_state ~updates ?env options
20772072

20782073
if verify then assert_valid_hashes updates invalid_hashes;
20792074

2080-
let ordered_libs = List.rev_append (List.rev ordered_flowlib_libs) ordered_non_flowlib_libs in
20812075
let%lwt (env, libs_ok) =
20822076
init_with_initial_state
20832077
~profiling
@@ -2299,7 +2293,7 @@ let load_saved_state ~profiling ~workers options =
22992293
let updates =
23002294
Recheck_updates.process_updates
23012295
~options
2302-
~libs:(SSet.of_list saved_state.Saved_state.ordered_non_flowlib_libs)
2296+
~libs:(SSet.of_list saved_state.Saved_state.ordered_libs)
23032297
changed_files
23042298
in
23052299
let updates =

src/services/saved_state/saved_state.ml

Lines changed: 25 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ type saved_state_data = {
5151
parsed_heaps: (File_key.t * parsed_file_data) list;
5252
unparsed_heaps: (File_key.t * unparsed_file_data) list;
5353
package_heaps: (File_key.t * package_file_data) list; (** package.json info *)
54-
ordered_non_flowlib_libs: string list;
54+
ordered_libs: string list;
5555
(* Why store local errors and not merge_errors/suppressions/etc? Well, I have a few reasons:
5656
*
5757
* 1. Much smaller data structure. The whole env.errors data structure can be hundreds of MBs
@@ -170,15 +170,14 @@ end = struct
170170
* *)
171171
let normalize_path t path = intern t (Files.relative_path t.root path)
172172

173+
let normalize_libdef_path t p =
174+
match t.builtin_flowlib_root with
175+
| Some flowlib_root when String.starts_with ~prefix:flowlib_root p ->
176+
intern t (builtin_flow_lib_marker ^ Files.relative_path flowlib_root p)
177+
| _ -> normalize_path t p
178+
173179
let normalize_file_key t = function
174-
| File_key.LibFile p ->
175-
let p =
176-
match t.builtin_flowlib_root with
177-
| Some flowlib_root when String.starts_with ~prefix:flowlib_root p ->
178-
intern t (builtin_flow_lib_marker ^ Files.relative_path flowlib_root p)
179-
| _ -> normalize_path t p
180-
in
181-
File_key.LibFile p
180+
| File_key.LibFile p -> File_key.LibFile (normalize_libdef_path t p)
182181
| File_key.SourceFile p -> File_key.SourceFile (normalize_path t p)
183182
| File_key.JsonFile p -> File_key.JsonFile (normalize_path t p)
184183
| File_key.ResourceFile p -> File_key.ResourceFile (normalize_path t p)
@@ -325,13 +324,6 @@ end = struct
325324
let relative_fn = normalize_file_key t fn in
326325
(relative_fn, relative_file_data) :: unparsed_heaps
327326

328-
(* The builtin flowlibs are excluded from the saved state. The server which loads the saved state
329-
* will extract and typecheck its own builtin flowlibs *)
330-
let is_not_in_flowlib ~options =
331-
let file_options = Options.file_options options in
332-
let is_in_flowlib = Files.is_in_flowlib file_options in
333-
(fun f -> not (is_in_flowlib f))
334-
335327
let normalize_error_set t = Flow_error.ErrorSet.map (normalize_error t)
336328

337329
(* Collect all the data for all the files *)
@@ -365,11 +357,7 @@ end = struct
365357
[]
366358
)
367359
in
368-
let ordered_non_flowlib_libs =
369-
env.ServerEnv.ordered_libs
370-
|> List.filter (is_not_in_flowlib ~options)
371-
|> Base.List.map ~f:(normalize_path t)
372-
in
360+
let ordered_libs = Base.List.map env.ServerEnv.ordered_libs ~f:(normalize_libdef_path t) in
373361
let local_errors =
374362
FilenameMap.fold
375363
(fun fn error_set acc ->
@@ -417,7 +405,7 @@ end = struct
417405
parsed_heaps;
418406
unparsed_heaps;
419407
package_heaps;
420-
ordered_non_flowlib_libs;
408+
ordered_libs;
421409
local_errors;
422410
node_modules_containers;
423411
dependency_graph;
@@ -526,6 +514,8 @@ end = struct
526514

527515
val denormalize_path : t -> string -> string
528516

517+
val denormalize_libdef_path : t -> string -> string
518+
529519
val denormalize_file_key_no_cache : t -> File_key.t -> File_key.t
530520

531521
val denormalize_file_key : t -> File_key.t -> File_key.t
@@ -545,17 +535,16 @@ end = struct
545535
* these calls does not even save a single word in the denormalized saved state object. *)
546536
let denormalize_path { root; _ } path = Files.absolute_path root path
547537

538+
let denormalize_libdef_path t p =
539+
match t.builtin_flowlib_root with
540+
| Some flowlib_root ->
541+
(match Base.String.chop_prefix ~prefix:builtin_flow_lib_marker p with
542+
| Some p -> Files.absolute_path flowlib_root p
543+
| None -> denormalize_path t p)
544+
| None -> denormalize_path t p
545+
548546
let denormalize_file_key_no_cache t = function
549-
| File_key.LibFile p ->
550-
let p =
551-
match t.builtin_flowlib_root with
552-
| Some flowlib_root ->
553-
(match Base.String.chop_prefix ~prefix:builtin_flow_lib_marker p with
554-
| Some p -> Files.absolute_path flowlib_root p
555-
| None -> denormalize_path t p)
556-
| None -> denormalize_path t p
557-
in
558-
File_key.LibFile p
547+
| File_key.LibFile p -> File_key.LibFile (denormalize_libdef_path t p)
559548
| File_key.SourceFile p -> File_key.SourceFile (denormalize_path t p)
560549
| File_key.JsonFile p -> File_key.JsonFile (denormalize_path t p)
561550
| File_key.ResourceFile p -> File_key.ResourceFile (denormalize_path t p)
@@ -686,7 +675,7 @@ end = struct
686675
parsed_heaps;
687676
unparsed_heaps;
688677
package_heaps;
689-
ordered_non_flowlib_libs;
678+
ordered_libs;
690679
local_errors;
691680
node_modules_containers;
692681
dependency_graph;
@@ -712,8 +701,8 @@ end = struct
712701
let progress_fn = progress_fn (List.length unparsed_heaps) in
713702
denormalize_unparsed_heaps ~workers ~denormalizer ~progress_fn unparsed_heaps
714703
in
715-
let ordered_non_flowlib_libs =
716-
Base.List.map ~f:(FileDenormalizer.denormalize_path denormalizer) ordered_non_flowlib_libs
704+
let ordered_libs =
705+
Base.List.map ~f:(FileDenormalizer.denormalize_libdef_path denormalizer) ordered_libs
717706
in
718707
let local_errors =
719708
FilenameMap.fold
@@ -738,7 +727,7 @@ end = struct
738727
parsed_heaps;
739728
unparsed_heaps;
740729
package_heaps;
741-
ordered_non_flowlib_libs;
730+
ordered_libs;
742731
local_errors;
743732
node_modules_containers;
744733
dependency_graph;

src/services/saved_state/saved_state.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ type saved_state_data = {
4343
parsed_heaps: (File_key.t * parsed_file_data) list;
4444
unparsed_heaps: (File_key.t * unparsed_file_data) list;
4545
package_heaps: (File_key.t * package_file_data) list;
46-
ordered_non_flowlib_libs: string list;
46+
ordered_libs: string list;
4747
local_errors: Flow_error.ErrorSet.t Utils_js.FilenameMap.t;
4848
node_modules_containers: SSet.t SMap.t;
4949
dependency_graph: saved_state_dependency_graph;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[options]
2+
all=true
3+
lazy_mode=true
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
shell: test.sh
2+
skip_saved_state: true

tests/saved_state_different_root/new_root/.gitkeep

Whitespace-only changes.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
Generate saved-state
2+
Use saved state in a different root
3+
Error ----------------------------------------------------------------------------------------------------- test.js:1:19
4+
5+
Cannot assign `new Object()` to `a` because `Object` [1] is incompatible with string [2]. [incompatible-type]
6+
7+
test.js:1:19
8+
1| const a: string = new Object()
9+
^^^^^^^^^^^^ [1]
10+
11+
References:
12+
test.js:1:10
13+
1| const a: string = new Object()
14+
^^^^^^ [2]
15+
16+
17+
18+
Found 1 error
19+
20+
The Flow server is currently in lazy mode and is only checking 2/2 files.
21+
To learn more, visit flow.org/en/docs/lang/lazy-modes
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/bin/bash
2+
# Copyright (c) Meta Platforms, Inc. and affiliates.
3+
#
4+
# This source code is licensed under the MIT license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
echo "Generate saved-state"
8+
"$FLOW" stop
9+
"$FLOW" start --saved-state-fetcher none
10+
"$FLOW" save-state --out new_root/.flow.saved_state >> /dev/null
11+
"$FLOW" stop
12+
13+
echo "" > new_root/.flow.saved_state_file_changes
14+
echo "Use saved state in a different root"
15+
mv .flowconfig new_root
16+
cd new_root
17+
"$FLOW" start --saved-state-fetcher local --wait
18+
echo "const a: string = new Object()" > test.js
19+
"$FLOW" force-recheck test.js
20+
assert_errors "$FLOW" status --strip-root

0 commit comments

Comments
 (0)