@@ -323,7 +323,7 @@ let run_merge_service
323323 acc
324324 =
325325 with_timer_lwt ~options " Merge" profiling (fun () ->
326- let % lwt merged, skipped_count = Merge_service. merge_strict
326+ let % lwt merged, { Merge_service. skipped_count; sig_new_or_changed } = Merge_service. merge_strict
327327 ~master_mutator ~worker_mutator ~reader ~intermediate_result_callback ~options ~workers
328328 dependency_graph component_map recheck_map
329329 in
@@ -349,7 +349,7 @@ let run_merge_service
349349 update_errset errors file new_errors, warnings, suppressions, coverage
350350 ) acc merged
351351 in
352- Lwt. return (errs, warnings, suppressions, coverage, skipped_count)
352+ Lwt. return (errs, warnings, suppressions, coverage, skipped_count, sig_new_or_changed )
353353 )
354354
355355(* This function does some last minute preparation and then calls into the merge service, which
@@ -362,7 +362,6 @@ let merge
362362 ~profiling
363363 ~workers
364364 ~errors
365- ~unchanged_checked
366365 ~to_merge
367366 ~components
368367 ~recheck_map
@@ -371,6 +370,7 @@ let merge
371370 ~persistent_connections
372371 ~prep_merge =
373372 let { ServerEnv. local_errors; merge_errors; warnings; suppressions; } = errors in
373+ let coverage = FilenameMap. empty in
374374
375375 let % lwt send_errors_over_connection =
376376 match persistent_connections with
@@ -451,15 +451,14 @@ let merge
451451 initially.
452452 *)
453453 Hh_logger. info " to_merge: %s" (CheckedSet. debug_counts_to_string to_merge);
454- Hh_logger. info " unchanged_checked: %s" (CheckedSet. debug_counts_to_string unchanged_checked);
455454 Hh_logger. info " Calculating dependencies" ;
456455 MonitorRPC. status_update ~event: ServerStatus. Calculating_dependencies_progress ;
457456 let files_to_merge = CheckedSet. all to_merge in
458457 let % lwt dependency_graph, component_map =
459458 calc_deps ~options ~profiling ~dependency_graph ~components files_to_merge in
460459
461460 Hh_logger. info " Merging" ;
462- let % lwt merge_errors, warnings, suppressions, coverage, skipped_count =
461+ let % lwt merge_errors, warnings, suppressions, coverage, skipped_count, sig_new_or_changed =
463462 let intermediate_result_callback results =
464463 let errors = lazy (
465464 Core_list. map ~f: (fun (file , result ) ->
@@ -486,7 +485,7 @@ let merge
486485
487486 let merge_start_time = Unix. gettimeofday () in
488487
489- let % lwt merge_errors, warnings, suppressions, coverage, skipped_count =
488+ let % lwt result =
490489 run_merge_service
491490 ~master_mutator
492491 ~worker_mutator
@@ -498,7 +497,7 @@ let merge
498497 dependency_graph
499498 component_map
500499 recheck_map
501- (merge_errors, warnings, suppressions, FilenameMap. empty )
500+ (merge_errors, warnings, suppressions, coverage )
502501 in
503502 let % lwt () =
504503 if Options. should_profile options
@@ -515,24 +514,44 @@ let merge
515514 in
516515
517516 Hh_logger. info " Done" ;
518- Lwt. return (merge_errors, warnings, suppressions, coverage, skipped_count)
517+ Lwt. return result
519518 in
520519
521- let checked = CheckedSet. union unchanged_checked to_merge in
522- Hh_logger. info " Checked set: %s" (CheckedSet. debug_counts_to_string checked);
523-
524520 let errors = { ServerEnv. local_errors; merge_errors; warnings; suppressions } in
525521 let cycle_leaders = component_map
526522 |> Utils_js.FilenameMap. elements
527523 |> Core_list. map ~f: (fun (leader , members ) -> (leader, Nel. length members))
528524 |> Core_list. filter ~f: (fun (_ , member_count ) -> member_count > 1 ) in
529- Lwt. return (checked, cycle_leaders, errors, coverage, skipped_count)
525+ Lwt. return (cycle_leaders, errors, coverage, skipped_count, sig_new_or_changed )
530526
531- let check_files ~options ~reader ~workers errors coverage checked_files =
532- let files = FilenameSet. union (CheckedSet. focused checked_files) (CheckedSet. dependents checked_files) in
527+ let check_files
528+ ~reader
529+ ~options
530+ ~workers
531+ ~errors
532+ ~updated_errors
533+ ~coverage
534+ ~merged_files
535+ ~sig_new_or_changed
536+ ~dependency_info =
533537 match options.Options. opt_arch with
534- | Options. Classic -> Lwt. return (errors , coverage)
538+ | Options. Classic -> Lwt. return (updated_errors , coverage)
535539 | Options. TypesFirst ->
540+ Hh_logger. info " Check prep" ;
541+ Hh_logger. info " new or changed signatures: %d" (FilenameSet. cardinal sig_new_or_changed);
542+ let focused_to_check = CheckedSet. focused merged_files in
543+ let merged_dependents = CheckedSet. dependents merged_files in
544+ let skipped_count = ref 0 in
545+ let all_dependency_graph = Dependency_info. all_dependency_graph dependency_info in
546+ (* skip dependents whenever none of their dependencies have new or changed signatures *)
547+ let dependents_to_check =
548+ FilenameSet. filter (fun f ->
549+ (FilenameSet. exists (fun f' -> FilenameSet. mem f' sig_new_or_changed)
550+ @@ FilenameMap. find_unsafe f all_dependency_graph)
551+ || (incr skipped_count; false )
552+ ) @@ merged_dependents in
553+ Hh_logger. info " Check will skip %d files" ! skipped_count;
554+ let files = FilenameSet. union focused_to_check dependents_to_check in
536555 let job = List. fold_left (fun (errors , warnings , suppressions , coverage ) file ->
537556 let new_errors, new_warnings, new_suppressions, new_coverage =
538557 Merge_service. check_file options ~reader file in
@@ -547,27 +566,32 @@ let check_files ~options ~reader ~workers errors coverage checked_files =
547566 Error_suppressions. empty,
548567 FilenameMap. empty in
549568 let merge
550- ( errors , warnings , suppressions , coverage )
551- ( new_errors , new_warnings , new_suppressions , new_coverage ) =
552- FilenameMap. union errors new_errors,
553- FilenameMap. union warnings new_warnings,
569+ ( new_errors , new_warnings , new_suppressions , new_coverage )
570+ ( errors , warnings , suppressions , coverage ) =
571+ FilenameMap. union new_errors errors, (* WARNING! order matters (new wins over old) *)
572+ FilenameMap. union new_warnings warnings, (* WARNING! order matters (new wins over old) *)
554573 Error_suppressions. update_suppressions suppressions new_suppressions,
555- FilenameMap. union coverage new_coverage
574+ FilenameMap. union new_coverage coverage (* WARNING! order matters (new wins over old) *)
556575 in
557576
558577 Hh_logger. info " Checking files" ;
559578 let progress_fn ~total ~start ~length :_ =
560579 MonitorRPC. status_update
561580 ServerStatus. (Checking_progress { total = Some total; finished = start })
562581 in
563- let % lwt merge_errors, warnings, suppressions, coverage = MultiWorkerLwt. call
582+ let % lwt new_errors, new_warnings, new_suppressions, new_coverage = MultiWorkerLwt. call
564583 workers
565584 ~job
566585 ~neutral
567586 ~merge
568587 ~next: (MultiWorkerLwt. next ~progress_fn ~max_size: 100 workers
569588 (FilenameSet. elements files))
570589 in
590+ let merge_errors, warnings, suppressions, coverage =
591+ merge
592+ (* NOTE: Order matters when there is overlap. We want new stuff to overwrite old stuff. *)
593+ (new_errors, new_warnings, new_suppressions, new_coverage)
594+ ServerEnv. (errors.merge_errors, errors.warnings, errors.suppressions, coverage) in
571595 Hh_logger. info " Done" ;
572596 let errors = { errors with
573597 ServerEnv. merge_errors;
@@ -626,12 +650,12 @@ let ensure_checked_dependencies ~options ~reader ~env file file_sig =
626650 else acc
627651 | None -> acc (* complain elsewhere about required module not found *)
628652 ) resolved_requires CheckedSet. empty in
629- let unchanged_checked = env.ServerEnv. checked_files in
653+ let checked = env.ServerEnv. checked_files in
630654
631655 (* Often, all dependencies have already been checked, so infer_input contains no unchecked files.
632656 * In that case, let's short-circuit typecheck, since a no-op typecheck still takes time on
633657 * large repos *)
634- let unchecked_dependencies = CheckedSet. diff infer_input unchanged_checked in
658+ let unchecked_dependencies = CheckedSet. diff infer_input checked in
635659 if CheckedSet. is_empty unchecked_dependencies
636660 then Lwt. return_unit
637661 else begin
@@ -1466,14 +1490,13 @@ end = struct
14661490
14671491 let dependency_graph = Dependency_info. dependency_graph dependency_info in
14681492 (* recheck *)
1469- let % lwt checked_files, cycle_leaders, errors , coverage, skipped_count = merge
1493+ let % lwt cycle_leaders, updated_errors , coverage, skipped_count, sig_new_or_changed = merge
14701494 ~transaction
14711495 ~reader
14721496 ~options
14731497 ~profiling
14741498 ~workers
14751499 ~errors
1476- ~unchanged_checked
14771500 ~to_merge
14781501 ~components
14791502 ~recheck_map
@@ -1493,7 +1516,20 @@ end = struct
14931516 ))
14941517 in
14951518
1496- let % lwt errors, coverage = check_files ~options ~reader ~workers errors coverage checked_files in
1519+ let merged_files = to_merge in
1520+ let % lwt errors, coverage = check_files
1521+ ~reader
1522+ ~options
1523+ ~workers
1524+ ~errors
1525+ ~updated_errors
1526+ ~coverage
1527+ ~merged_files
1528+ ~sig_new_or_changed
1529+ ~dependency_info in
1530+
1531+ let checked_files = CheckedSet. union unchanged_checked merged_files in
1532+ Hh_logger. info " Checked set: %s" (CheckedSet. debug_counts_to_string checked_files);
14971533
14981534 (* NOTE: unused fields are left in their initial empty state *)
14991535 env.ServerEnv. collated_errors := None ;
@@ -2073,12 +2109,10 @@ let full_check ~profiling ~options ~workers ?focus_targets env =
20732109 let % lwt infer_input = files_to_infer
20742110 ~options ~reader ?focus_targets ~profiling ~parsed ~dependency_info in
20752111
2076- let unchanged_checked = CheckedSet. empty in
2077-
20782112 let % lwt to_merge, components, recheck_map =
20792113 include_dependencies_and_dependents
20802114 ~options ~profiling
2081- ~unchanged_checked
2115+ ~unchanged_checked: CheckedSet. empty
20822116 ~infer_input
20832117 ~dependency_info
20842118 ~all_dependent_files: FilenameSet. empty
@@ -2090,21 +2124,32 @@ let full_check ~profiling ~options ~workers ?focus_targets env =
20902124 let % lwt () = ensure_parsed ~options ~profiling ~workers ~reader to_merge in
20912125
20922126 let dependency_graph = Dependency_info. dependency_graph dependency_info in
2093- let % lwt (checked_files, _, errors , coverage, _) = merge
2127+ let % lwt _, updated_errors , coverage, _, sig_new_or_changed = merge
20942128 ~transaction
20952129 ~reader
20962130 ~options
20972131 ~profiling
20982132 ~workers
20992133 ~errors
2100- ~unchanged_checked
21012134 ~to_merge
21022135 ~components
21032136 ~recheck_map
21042137 ~dependency_graph
21052138 ~deleted: FilenameSet. empty
21062139 ~persistent_connections: None
21072140 ~prep_merge: None in
2108- let % lwt errors, coverage = check_files ~options ~reader ~workers errors coverage checked_files in
2141+ let merged_files = to_merge in
2142+ let % lwt errors, coverage = check_files
2143+ ~reader
2144+ ~options
2145+ ~workers
2146+ ~errors
2147+ ~updated_errors
2148+ ~coverage
2149+ ~merged_files
2150+ ~sig_new_or_changed
2151+ ~dependency_info in
2152+ let checked_files = merged_files in
2153+ Hh_logger. info " Checked set: %s" (CheckedSet. debug_counts_to_string checked_files);
21092154 Lwt. return { env with ServerEnv. checked_files; errors; coverage }
21102155 )
0 commit comments