From bc10fb323f0a4be157861b8762bd7beed5f9dd82 Mon Sep 17 00:00:00 2001 From: Christian Legnitto Date: Tue, 22 May 2018 21:50:57 -0700 Subject: [PATCH 1/2] Add silence support With this patch there is a newly supported section in `.flowconfig`: ```ini [silence] .*/path/to/file.js .*/path/to/dir/*.js ``` Paths in `[silence]` will still be typechecked, but any warnings and errors will be silenced as if there was a `suppress_comment` comment string on every line where there are errors. It currently silences all warnings and errors, including lints. I believe this fixes https://github.com/facebook/flow/issues/869, though I admit I didn't read the whole issue. --- src/commands/commandUtils.ml | 23 +++++++++-- src/commands/config/flowConfig.ml | 18 +++++++- src/commands/config/flowConfig.mli | 3 ++ src/commands/genFlowFilesCommand.ml | 5 ++- src/commands/initCommand.ml | 3 +- src/commands/lsCommand.ml | 10 +++-- src/common/files.ml | 11 +++++ src/common/files.mli | 4 ++ src/flow_dot_js.ml | 4 +- src/services/inference/init_js.ml | 3 +- src/services/inference/merge_service.ml | 6 ++- src/typing/merge_js.ml | 4 +- src/typing/merge_js.mli | 1 + src/typing/type_inference_js.ml | 30 ++++++++++---- src/typing/type_inference_js.mli | 2 + testgen/flowtestgen_utils.ml | 2 +- tests/config_silence/.flowconfig | 16 +++++++ tests/config_silence/A.js | 24 +++++++++++ tests/config_silence/B.js | 2 + tests/config_silence/C.js | 5 +++ tests/config_silence/D.js | 8 ++++ tests/config_silence/config_silence.exp | 24 +++++++++++ tests/config_silence/lib.js | 1 + tests/json_exit/json_exit.exp | 2 +- website/en/docs/config/index.md | 3 +- website/en/docs/config/silence.md | 55 +++++++++++++++++++++++++ 26 files changed, 240 insertions(+), 29 deletions(-) create mode 100644 tests/config_silence/.flowconfig create mode 100644 tests/config_silence/A.js create mode 100644 tests/config_silence/B.js create mode 100644 tests/config_silence/C.js create mode 100644 tests/config_silence/D.js create mode 100644 tests/config_silence/config_silence.exp create mode 100644 tests/config_silence/lib.js create mode 100644 website/en/docs/config/silence.md diff --git a/src/commands/commandUtils.ml b/src/commands/commandUtils.ml index 153c2784ab3..b9b5a3b5a81 100644 --- a/src/commands/commandUtils.ml +++ b/src/commands/commandUtils.ml @@ -382,6 +382,7 @@ let assert_version flowconfig = type flowconfig_params = { ignores: string list; untyped: string list; + silence: string list; includes: string list; libs: string list; (* We store raw_lint_severities as a string list instead of as a LintSettings.t so we @@ -394,13 +395,14 @@ let list_of_string_arg = function | None -> [] | Some arg_str -> Str.split (Str.regexp ",") arg_str -let collect_flowconfig_flags main ignores_str untyped_str includes_str lib_str lints_str = +let collect_flowconfig_flags main ignores_str untyped_str silence_str includes_str lib_str lints_str = let ignores = list_of_string_arg ignores_str in let untyped = list_of_string_arg untyped_str in + let silence = list_of_string_arg silence_str in let includes = list_of_string_arg includes_str in let libs = list_of_string_arg lib_str in let raw_lint_severities = list_of_string_arg lints_str in - main { ignores; includes; libs; raw_lint_severities; untyped; } + main { ignores; includes; libs; raw_lint_severities; untyped; silence; } let file_options = let default_lib_dir ~no_flowlib tmp_dir = @@ -466,7 +468,7 @@ let file_options = | [] -> config_libs | _ -> config_libs @ (List.map (Files.make_path_absolute root) extras) in - fun ~root ~no_flowlib ~temp_dir ~includes ~ignores ~libs ~untyped flowconfig -> + fun ~root ~no_flowlib ~temp_dir ~includes ~ignores ~libs ~untyped ~silence flowconfig -> let default_lib_dir = let no_flowlib = no_flowlib || FlowConfig.no_flowlib flowconfig in Some (default_lib_dir ~no_flowlib temp_dir) @@ -479,6 +481,10 @@ let file_options = root (FlowConfig.untyped flowconfig) untyped in + let silence = ignores_of_arg + root + (FlowConfig.silence flowconfig) + silence in let lib_paths = lib_paths ~root flowconfig libs in let includes = includes @@ -488,6 +494,7 @@ let file_options = default_lib_dir; ignores; untyped; + silence; includes; lib_paths; module_file_exts = FlowConfig.module_file_exts flowconfig; @@ -507,6 +514,12 @@ let untyped_flag prev = CommandSpec.ArgSpec.( ~doc:"Specify one or more patterns, comma separated, for files to treat as untyped" ) +let silence_flag prev = CommandSpec.ArgSpec.( + prev + |> flag "--silence" (optional string) + ~doc:"Specify one or more patterns, comma separated, for files to treat as silenced" +) + let include_flag prev = CommandSpec.ArgSpec.( prev |> flag "--include" (optional string) @@ -536,6 +549,7 @@ let flowconfig_flags prev = CommandSpec.ArgSpec.( |> collect collect_flowconfig_flags |> ignore_flag |> untyped_flag + |> silence_flag |> include_flag |> lib_flag |> lints_flag @@ -782,8 +796,9 @@ let make_options ~flowconfig ~lazy_mode ~root (options_flags: Options_flags.t) = libs; raw_lint_severities=_; untyped; + silence; } = options_flags.flowconfig_flags in - file_options ~root ~no_flowlib ~temp_dir ~includes ~ignores ~libs ~untyped flowconfig + file_options ~root ~no_flowlib ~temp_dir ~includes ~ignores ~libs ~untyped ~silence flowconfig in let lint_severities = parse_lints_flag (FlowConfig.lint_severities flowconfig) options_flags.flowconfig_flags.raw_lint_severities diff --git a/src/commands/config/flowConfig.ml b/src/commands/config/flowConfig.ml index 73af98aaecb..f655529eb08 100644 --- a/src/commands/config/flowConfig.ml +++ b/src/commands/config/flowConfig.ml @@ -313,6 +313,8 @@ type config = { ignores: string list; (* files that should be treated as untyped *) untyped: string list; + (* files that should have errors silenced *) + silence: string list; (* non-root include paths *) includes: string list; (* library paths. no wildcards *) @@ -339,6 +341,9 @@ end = struct let untyped o untyped = List.iter (fun ex -> (fprintf o "%s\n" ex)) untyped + let silence o silence = + List.iter (fun ex -> (fprintf o "%s\n" ex)) silence + let includes o includes = List.iter (fun inc -> (fprintf o "%s\n" inc)) includes @@ -400,6 +405,7 @@ end = struct ignores o config.ignores; fprintf o "\n"; section_if_nonempty o "untyped" untyped config.untyped; + section_if_nonempty o "silence" silence config.silence; section_header o "include"; includes o config.includes; fprintf o "\n"; @@ -419,6 +425,7 @@ end let empty_config = { ignores = []; untyped = []; + silence = []; includes = []; libs = []; lint_severities = LintSettings.empty_severities; @@ -472,6 +479,10 @@ let parse_untyped config lines = let untyped = trim_lines lines in { config with untyped; } +let parse_silence config lines = + let silence = trim_lines lines in + { config with silence; } + let parse_options config lines = let open Opts in let (>>=) = Core_result.(>>=) in @@ -948,6 +959,7 @@ let parse_section config ((section_ln, section), lines) = | "ignore", _ -> parse_ignores config lines | "libs", _ -> parse_libs config lines | "lints", _ -> parse_lints config lines + | "silence", _ -> parse_silence config lines | "strict", _ -> parse_strict config lines | "options", _ -> parse_options config lines | "untyped", _ -> parse_untyped config lines @@ -986,15 +998,17 @@ let read filename = } in parse config lines -let init ~ignores ~untyped ~includes ~libs ~options ~lints = +let init ~ignores ~untyped ~silence ~includes ~libs ~options ~lints = let ignores_lines = List.map (fun s -> (1, s)) ignores in let untyped_lines = List.map (fun s -> (1, s)) untyped in + let silence_lines = List.map (fun s -> (1, s)) silence in let includes_lines = List.map (fun s -> (1, s)) includes in let options_lines = List.map (fun s -> (1, s)) options in let lib_lines = List.map (fun s -> (1, s)) libs in let lint_lines = List.map (fun s -> (1, s)) lints in let config = parse_ignores empty_config ignores_lines in let config = parse_untyped config untyped_lines in + let config = parse_silence config silence_lines in let config = parse_includes config includes_lines in let config = parse_options config options_lines in let config = parse_libs config lib_lines in @@ -1025,6 +1039,8 @@ let restore (filename, config) = cache := Some (filename, config) let ignores config = config.ignores (* files that should be treated as untyped *) let untyped config = config.untyped +(* files that should have errors silenced *) +let silence config = config.silence (* non-root include paths *) let includes config = config.includes (* library paths. no wildcards *) diff --git a/src/commands/config/flowConfig.mli b/src/commands/config/flowConfig.mli index 58782a48aac..10ca063d0c9 100644 --- a/src/commands/config/flowConfig.mli +++ b/src/commands/config/flowConfig.mli @@ -13,6 +13,7 @@ val empty_config: config val init: ignores: string list -> untyped: string list -> + silence: string list -> includes: string list -> libs: string list -> options: string list -> @@ -28,6 +29,8 @@ val restore: string * config -> unit val ignores: config -> string list (* files that should be treated as untyped *) val untyped: config -> string list +(* files that should have errors silenced *) +val silence: config -> string list (* non-root include paths *) val includes: config -> string list (* library paths. no wildcards *) diff --git a/src/commands/genFlowFilesCommand.ml b/src/commands/genFlowFilesCommand.ml index 1bef437034e..1c6f69f673c 100644 --- a/src/commands/genFlowFilesCommand.ml +++ b/src/commands/genFlowFilesCommand.ml @@ -56,6 +56,7 @@ let spec = { |> ignore_flag |> include_flag |> untyped_flag + |> silence_flag |> from_flag |> anon "src" (required string) |> flag "--out-dir" string @@ -85,7 +86,7 @@ let write_file strip_root root content perm src_file_path dest_file_path = Unix.close fd let main option_values root error_flags strip_root ignore_flag - include_flag untyped_flag from src out_dir () = ( + include_flag untyped_flag silence_flag from src out_dir () = ( FlowEventLogger.set_from from; let src = expand_path src in let root = guess_root ( @@ -111,7 +112,7 @@ let main option_values root error_flags strip_root ignore_flag FlowExitStatus.exit ~msg FlowExitStatus.Commandline_usage_error ); - let options = LsCommand.make_options ~root ~ignore_flag ~include_flag ~untyped_flag in + let options = LsCommand.make_options ~root ~ignore_flag ~include_flag ~untyped_flag ~silence_flag in let _, libs = Files.init options in let next_files = LsCommand.get_ls_files ~root ~all:false ~options ~libs ~imaginary:false (Some src) diff --git a/src/commands/initCommand.ml b/src/commands/initCommand.ml index fad991f2005..74f8324000b 100644 --- a/src/commands/initCommand.ml +++ b/src/commands/initCommand.ml @@ -50,6 +50,7 @@ let main from flowconfig_flags options root () = in let ignores = flowconfig_flags.CommandUtils.ignores in let untyped = flowconfig_flags.CommandUtils.untyped in + let silence = flowconfig_flags.CommandUtils.silence in let includes = flowconfig_flags.CommandUtils.includes in let libs = flowconfig_flags.CommandUtils.libs in let lints = flowconfig_flags.CommandUtils.raw_lint_severities in @@ -61,7 +62,7 @@ let main from flowconfig_flags options root () = FlowExitStatus.(exit ~msg Invalid_flowconfig) end; - let config = FlowConfig.init ~ignores ~untyped ~includes ~libs ~options ~lints in + let config = FlowConfig.init ~ignores ~untyped ~silence ~includes ~libs ~options ~lints in let out = Sys_utils.open_out_no_fail file in FlowConfig.write config out; diff --git a/src/commands/lsCommand.ml b/src/commands/lsCommand.ml index 4c40fb0888c..fa7879d5ec2 100644 --- a/src/commands/lsCommand.ml +++ b/src/commands/lsCommand.ml @@ -26,6 +26,7 @@ let spec = { |> ignore_flag |> include_flag |> untyped_flag + |> silence_flag |> root_flag |> json_flags |> from_flag @@ -106,15 +107,16 @@ let rec iter_get_next ~f get_next = List.iter f result; iter_get_next ~f get_next -let make_options ~root ~ignore_flag ~include_flag ~untyped_flag = +let make_options ~root ~ignore_flag ~include_flag ~untyped_flag ~silence_flag = let flowconfig = FlowConfig.get (Server_files_js.config_file root) in let temp_dir = FlowConfig.temp_dir flowconfig in let includes = CommandUtils.list_of_string_arg include_flag in let ignores = CommandUtils.list_of_string_arg ignore_flag in let untyped = CommandUtils.list_of_string_arg untyped_flag in + let silence = CommandUtils.list_of_string_arg silence_flag in let libs = [] in CommandUtils.file_options flowconfig - ~root ~no_flowlib:true ~temp_dir ~ignores ~includes ~libs ~untyped + ~root ~no_flowlib:true ~temp_dir ~ignores ~includes ~libs ~untyped ~silence (* The problem with Files.wanted is that it says yes to everything except ignored files and libs. * So implicitly ignored files (like files in another directory) pass the Files.wanted check *) @@ -174,7 +176,7 @@ let get_next_append_const get_next const = ret let main - strip_root ignore_flag include_flag untyped_flag root_flag json pretty from all imaginary reason + strip_root ignore_flag include_flag untyped_flag silence_flag root_flag json pretty from all imaginary reason input_file root_or_files () = let files_or_dirs = get_filenames_from_input ~allow_imaginary:true input_file root_or_files in @@ -194,7 +196,7 @@ let main | _ -> None) ) in - let options = make_options ~root ~ignore_flag ~include_flag ~untyped_flag in + let options = make_options ~root ~ignore_flag ~include_flag ~untyped_flag ~silence_flag in (* Turn on --no-flowlib by default, so that flow ls never reports flowlib files *) let options = { options with Files.default_lib_dir = None; } in let _, libs = Files.init options in diff --git a/src/common/files.ml b/src/common/files.ml index b8e6baee393..6f7babe9224 100644 --- a/src/common/files.ml +++ b/src/common/files.ml @@ -11,6 +11,7 @@ type options = { default_lib_dir: Path.t option; ignores: (string * Str.regexp) list; untyped: (string * Str.regexp) list; + silence: (string * Str.regexp) list; includes: Path_matcher.t; lib_paths: Path.t list; module_file_exts: SSet.t; @@ -21,6 +22,7 @@ type options = { let default_lib_dir options = options.default_lib_dir let ignores options = options.ignores let untyped options = options.untyped +let silence options = options.silence let includes options = options.includes let lib_paths options = options.lib_paths let module_file_exts options = options.module_file_exts @@ -300,6 +302,15 @@ let is_untyped (options: options) = let path = Sys_utils.normalize_filename_dir_sep path in List.exists (fun rx -> Str.string_match rx path 0) list +(* true if a file path matches an [silence] entry in config *) +let is_silenced (options: options) = + let list = List.map snd options.silence in + fun path -> + (* On Windows, the path may use \ instead of /, but let's standardize the + * ignore regex to use / *) + let path = Sys_utils.normalize_filename_dir_sep path in + List.exists (fun rx -> Str.string_match rx path 0) list + (* true if a file path matches an [include] path in config *) let is_included options f = Path_matcher.matches options.includes f diff --git a/src/common/files.mli b/src/common/files.mli index 52be9ede40c..b2558433290 100644 --- a/src/common/files.mli +++ b/src/common/files.mli @@ -11,6 +11,7 @@ type options = { default_lib_dir: Path.t option; ignores: (string * Str.regexp) list; untyped: (string * Str.regexp) list; + silence: (string * Str.regexp) list; includes: Path_matcher.t; lib_paths: Path.t list; module_file_exts: SSet.t; @@ -21,6 +22,7 @@ type options = { val default_lib_dir: options -> Path.t option val ignores: options -> (string * Str.regexp) list val untyped: options -> (string * Str.regexp) list +val silence: options -> (string * Str.regexp) list val includes: options -> Path_matcher.t val lib_paths: options -> Path.t list val module_file_exts: options -> SSet.t @@ -42,6 +44,8 @@ val is_flow_file: options: options -> string -> bool val is_ignored: options -> string -> bool (* true if a file path matches an [untyped] entry in config *) val is_untyped: options -> string -> bool +(* true if a file path matches an [silence] entry in config *) +val is_silenced: options -> string -> bool (* true if a file path matches an [include] path in config *) val is_included: options -> string -> bool diff --git a/src/flow_dot_js.ml b/src/flow_dot_js.ml index 6a1ddd9b21e..4c0b4abd85f 100644 --- a/src/flow_dot_js.ml +++ b/src/flow_dot_js.ml @@ -77,7 +77,7 @@ let load_lib_files ~master_cx ~metadata files let cx = Context.make sig_cx metadata lib_file Files.lib_module_ref in Flow_js.mk_builtins cx; let syms = Type_inference_js.infer_lib_file cx ast - ~exclude_syms ~file_sig ~lint_severities:LintSettings.empty_severities + ~exclude_syms ~file_sig ~lint_severities:LintSettings.empty_severities ~file_options:None in Context.merge_into (Context.sig_cx master_cx) sig_cx; @@ -204,7 +204,7 @@ let infer_and_merge ~root filename ast file_sig = let strict_mode = StrictModeSettings.empty in let file_sigs = Utils_js.FilenameMap.singleton filename file_sig in let cx, _other_cxs = Merge_js.merge_component_strict - ~metadata ~lint_severities ~strict_mode ~file_sigs + ~metadata ~lint_severities ~file_options:None ~strict_mode ~file_sigs ~get_ast_unsafe:(fun _ -> ast) ~get_docblock_unsafe:(fun _ -> stub_docblock) (Nel.one filename) reqs [] (Context.sig_cx master_cx) diff --git a/src/services/inference/init_js.ml b/src/services/inference/init_js.ml index cb2a2834718..824cdfaf8df 100644 --- a/src/services/inference/init_js.ml +++ b/src/services/inference/init_js.ml @@ -74,6 +74,7 @@ let load_lib_files ~master_cx ~options files = let lib_file = File_key.LibFile file in let lint_severities = options.Options.opt_lint_severities in + let file_options = Options.file_options options in let%lwt result = parse_lib_file options file in Lwt.return (match result with | Parsing.Parse_ok (ast, file_sig) -> @@ -89,7 +90,7 @@ let load_lib_files ~master_cx ~options files = Flow.mk_builtins cx; let syms = Infer.infer_lib_file cx ast - ~exclude_syms ~lint_severities ~file_sig + ~exclude_syms ~lint_severities ~file_options:(Some file_options) ~file_sig in Context.merge_into (Context.sig_cx master_cx) sig_cx; diff --git a/src/services/inference/merge_service.ml b/src/services/inference/merge_service.ml index f074a16722c..780a32ca940 100644 --- a/src/services/inference/merge_service.ml +++ b/src/services/inference/merge_service.ml @@ -99,9 +99,10 @@ let merge_strict_context ~options component = let metadata = Context.metadata_of_options options in let lint_severities = Options.lint_severities options in + let file_options = Some (Options.file_options options) in let strict_mode = Options.strict_mode options in let cx, other_cxs = Merge_js.merge_component_strict - ~metadata ~lint_severities ~strict_mode ~file_sigs + ~metadata ~lint_severities ~file_options ~strict_mode ~file_sigs ~get_ast_unsafe:Parsing_service_js.get_ast_unsafe ~get_docblock_unsafe:Parsing_service_js.get_docblock_unsafe ~do_gc:(Options.is_debug_mode options) @@ -140,9 +141,10 @@ let merge_contents_context options file ast info file_sig ~ensure_checked_depend let metadata = Context.metadata_of_options options in let lint_severities = Options.lint_severities options in + let file_options = Some (Options.file_options options) in let strict_mode = Options.strict_mode options in let cx, _ = Merge_js.merge_component_strict - ~metadata ~lint_severities ~strict_mode ~file_sigs + ~metadata ~lint_severities ~file_options ~strict_mode ~file_sigs ~get_ast_unsafe:(fun _ -> ast) ~get_docblock_unsafe:(fun _ -> info) component file_reqs dep_cxs master_cx diff --git a/src/typing/merge_js.ml b/src/typing/merge_js.ml index dffb1d99e89..96f883026e3 100644 --- a/src/typing/merge_js.ml +++ b/src/typing/merge_js.ml @@ -244,7 +244,7 @@ let apply_docblock_overrides (metadata: Context.metadata) docblock_info = 5. Link the local references to libraries in master_cx and component_cxs. *) -let merge_component_strict ~metadata ~lint_severities ~strict_mode ~file_sigs +let merge_component_strict ~metadata ~lint_severities ~file_options ~strict_mode ~file_sigs ~get_ast_unsafe ~get_docblock_unsafe ?(do_gc=false) component reqs dep_cxs (master_cx: Context.sig_t) = @@ -279,7 +279,7 @@ let merge_component_strict ~metadata ~lint_severities ~strict_mode ~file_sigs else lint_severities in let file_sig = FilenameMap.find_unsafe filename file_sigs in Type_inference_js.infer_ast cx filename ast - ~lint_severities ~file_sig; + ~lint_severities ~file_options ~file_sig; let gc_state = Option.map gc_state Gc_js.(fun gc_state -> let gc_state = mark cx gc_state in diff --git a/src/typing/merge_js.mli b/src/typing/merge_js.mli index 67ec129fbff..8a8e41eb2c3 100644 --- a/src/typing/merge_js.mli +++ b/src/typing/merge_js.mli @@ -18,6 +18,7 @@ end val merge_component_strict: metadata: Context.metadata -> lint_severities: Severity.severity LintSettings.t -> + file_options: Files.options option -> strict_mode: StrictModeSettings.t -> file_sigs: File_sig.t Utils_js.FilenameMap.t -> get_ast_unsafe: (File_key.t -> Loc.t Ast.program) -> diff --git a/src/typing/type_inference_js.ml b/src/typing/type_inference_js.ml index ba23a99fadc..cf0bd11a6b0 100644 --- a/src/typing/type_inference_js.ml +++ b/src/typing/type_inference_js.ml @@ -342,9 +342,25 @@ let scan_for_lint_suppressions = Context.add_severity_cover cx severity_cover; Context.add_unused_lint_suppressions cx suppression_locs -let scan_for_suppressions cx base_settings comments = - scan_for_error_suppressions cx comments; - scan_for_lint_suppressions cx base_settings comments +let scan_for_suppressions cx lint_severities file_options comments = + let filename = File_key.to_string (Context.file cx) in + let silenced = match file_options with + | Some file_options -> Files.is_silenced file_options filename + | None -> false + in + if silenced then + (* Whole file is silenced. *) + (* A more "correct" solution might be to keep all the errors and instead + * synthesize suppressions for them. That would be a lot of work + * for the same end result though. + *) + Context.remove_all_errors cx + else + (* Scan comments for line suppressions. *) + scan_for_error_suppressions cx comments; + scan_for_lint_suppressions cx lint_severities comments + ; + () let add_require_tvars = let add cx desc loc = @@ -377,7 +393,7 @@ let add_require_tvars = (* build module graph *) (* Lint suppressions are handled iff lint_severities is Some. *) -let infer_ast ~lint_severities ~file_sig cx filename ast = +let infer_ast ~lint_severities ~file_options ~file_sig cx filename ast = assert (Context.is_checked cx); Flow_js.Cache.clear(); @@ -434,7 +450,7 @@ let infer_ast ~lint_severities ~file_sig cx filename ast = Flow_js.flow_t cx (init_exports, local_exports_var); infer_core cx statements; - scan_for_suppressions cx lint_severities comments; + scan_for_suppressions cx lint_severities file_options comments; let module_t = Context.( match Context.module_kind cx with @@ -466,7 +482,7 @@ let infer_ast ~lint_severities ~file_sig cx filename ast = a) symbols from prior library loads are suppressed if found, b) bindings are added as properties to the builtin object *) -let infer_lib_file ~exclude_syms ~lint_severities ~file_sig cx ast = +let infer_lib_file ~exclude_syms ~lint_severities ~file_options ~file_sig cx ast = let _, statements, comments = ast in Flow_js.Cache.clear(); @@ -480,7 +496,7 @@ let infer_lib_file ~exclude_syms ~lint_severities ~file_sig cx ast = Env.init_env ~exclude_syms cx module_scope; infer_core cx statements; - scan_for_suppressions cx lint_severities comments; + scan_for_suppressions cx lint_severities file_options comments; module_scope |> Scope.(iter_entries Entry.(fun name entry -> Flow_js.set_builtin cx name (actual_type entry) diff --git a/src/typing/type_inference_js.mli b/src/typing/type_inference_js.mli index a2a037df6aa..8321203c538 100644 --- a/src/typing/type_inference_js.mli +++ b/src/typing/type_inference_js.mli @@ -8,6 +8,7 @@ (* Lint suppressions are handled iff lint_severities is Some. *) val infer_ast: lint_severities: Severity.severity LintSettings.t -> + file_options: Files.options option -> file_sig: File_sig.t -> Context.t -> File_key.t -> @@ -17,6 +18,7 @@ val infer_ast: val infer_lib_file: exclude_syms: SSet.t -> lint_severities: Severity.severity LintSettings.t -> + file_options: Files.options option -> file_sig: File_sig.t -> Context.t -> Loc.t Ast.program -> diff --git a/testgen/flowtestgen_utils.ml b/testgen/flowtestgen_utils.ml index b6f6924ac4b..0d0bf022a45 100644 --- a/testgen/flowtestgen_utils.ml +++ b/testgen/flowtestgen_utils.ml @@ -572,7 +572,7 @@ let flow_check (code : string) : string option = let builtins_cx = Context.make builtins_sig_cx builtin_metadata File_key.Builtins Files.lib_module_ref in let _ = Type_inference_js.infer_lib_file builtins_cx builtins_ast - ~exclude_syms:SSet.empty ~lint_severities ~file_sig:builtins_file_sig in + ~exclude_syms:SSet.empty ~lint_severities ~file_options ~file_options:None ~file_sig:builtins_file_sig in let () = let from_t = Context.find_module master_cx Files.lib_module_ref in let to_t = Context.find_module builtins_cx Files.lib_module_ref in diff --git a/tests/config_silence/.flowconfig b/tests/config_silence/.flowconfig new file mode 100644 index 00000000000..7c4809631f5 --- /dev/null +++ b/tests/config_silence/.flowconfig @@ -0,0 +1,16 @@ +[ignore] + +[include] + +[libs] +lib.js + +[silence] +.*/B.js +.*/C.js + +[options] +suppress_comment=.*\\$FlowFixMe +suppress_comment=.*\\$FlowIssue +suppress_comment=\\(.\\|\n\\)*\\$FlowNewLine +include_warnings=true diff --git a/tests/config_silence/A.js b/tests/config_silence/A.js new file mode 100644 index 00000000000..9037b64c7c1 --- /dev/null +++ b/tests/config_silence/A.js @@ -0,0 +1,24 @@ +// $FlowFixMe +var test1: string = 123; // This error should be suppressed + +// $FlowIssue +var test2: string = 123; // This error should be suppressed + +function getNum() { + return 123; +} + +// $FlowFixMe This was the second loc in the error +var test3: string = getNum(); // This error should be suppressed + +// $FlowFixMe Error unused suppression + +var test4: string = 123; // This error is NOT silenced + +// $FlowFixMe Indentation shouldn't matter +var test5: string = 123; // This error should be suppressed + +/* + * $FlowNewLine + */ +var test6: string = 123; diff --git a/tests/config_silence/B.js b/tests/config_silence/B.js new file mode 100644 index 00000000000..b4f41e62eb6 --- /dev/null +++ b/tests/config_silence/B.js @@ -0,0 +1,2 @@ +// $FlowFixMe +var test1: string = library_num; diff --git a/tests/config_silence/C.js b/tests/config_silence/C.js new file mode 100644 index 00000000000..149c0098c26 --- /dev/null +++ b/tests/config_silence/C.js @@ -0,0 +1,5 @@ +function takesAString(x: string): void {} + +function runTest(y: number): void { + takesAString(y); +} diff --git a/tests/config_silence/D.js b/tests/config_silence/D.js new file mode 100644 index 00000000000..bd5a7bf1624 --- /dev/null +++ b/tests/config_silence/D.js @@ -0,0 +1,8 @@ +declare var x: { + x: { foo: string } +}; +declare var y: { + // $FlowFixMe - this location is only mentioned in the extra section + x: { bar: number } +}; +x = y; diff --git a/tests/config_silence/config_silence.exp b/tests/config_silence/config_silence.exp new file mode 100644 index 00000000000..8613ac67069 --- /dev/null +++ b/tests/config_silence/config_silence.exp @@ -0,0 +1,24 @@ +Error ------------------------------------------------------------------------------------------------------- A.js:16:21 + +Cannot assign `123` to `test4` because number [1] is incompatible with string [2]. + + A.js:16:21 + 16| var test4: string = 123; // This error is NOT silenced + ^^^ [1] + +References: + A.js:16:12 + 16| var test4: string = 123; // This error is NOT silenced + ^^^^^^ [2] + + +Warning ------------------------------------------------------------------------------------------------------ A.js:14:1 + +Unused suppression comment. + + 14| // $FlowFixMe Error unused suppression + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + + +Found 1 error and 1 warning diff --git a/tests/config_silence/lib.js b/tests/config_silence/lib.js new file mode 100644 index 00000000000..21cfa88e53e --- /dev/null +++ b/tests/config_silence/lib.js @@ -0,0 +1 @@ +declare var library_num: number; diff --git a/tests/json_exit/json_exit.exp b/tests/json_exit/json_exit.exp index 4acb6531f8e..377199ac065 100644 --- a/tests/json_exit/json_exit.exp +++ b/tests/json_exit/json_exit.exp @@ -13,6 +13,6 @@ "exit":{ "code":64, "reason":"Commandline_usage_error", - "msg":"flow: --pants unknown option\nUsage: flow check [OPTION]... [ROOT]\n\nDoes a full Flow check and prints the results.\n\nFlow will search upward for a .flowconfig file, beginning at ROOT.\nROOT is assumed to be the current directory if unspecified.\n\n --all Typecheck all files, not just @flow\n --color Display terminal output in color. never, always, auto (default: auto)\n --debug Print debug info during typecheck\n --from Specify client (for use by editor plugins)\n --help This list of options\n --ignore Specify one or more ignore patterns, comma separated\n --ignore-version Ignore the version constraint in .flowconfig\n --include Specify one or more include patterns, comma separated\n --include-suppressed Ignore any `suppress_comment` lines in .flowconfig\n --include-warnings Include warnings in the error output (warnings are excluded by default)\n --json Output results in JSON format\n --json-version The version of the JSON format (defaults to 1)\n --lib Specify one or more lib files/directories, comma separated\n --lints Specify one or more lint rules, comma separated\n --max-warnings Warnings above this number will cause a nonzero exit code (implies --include-warnings)\n --max-workers Maximum number of workers to create (capped by number of cores)\n --merge-timeout The maximum time in seconds to attempt to typecheck a file or cycle of files. 0 means no timeout (default: 100)\n --message-width Sets the width of messages but not code snippets (defaults to the smaller of 120 or the terminal width)\n --munge-underscore-members Treat any class member name with a leading underscore as private\n --no-flowlib Do not include embedded declarations\n --one-line Escapes newlines so that each error prints on one line\n --pretty Pretty-print JSON output (implies --json)\n --profile Output profiling information\n --quiet Suppress output about server startup\n --sharedmemory-dep-table-pow The exponent for the size of the shared memory dependency table. The default is 17, implying a size of 2^17 bytes\n --sharedmemory-dirs Directory in which to store shared memory heap (default: /dev/shm/)\n --sharedmemory-hash-table-pow The exponent for the size of the shared memory hash table. The default is 19, implying a size of 2^19 bytes\n --sharedmemory-log-level The logging level for shared memory statistics. 0=none, 1=some\n --sharedmemory-minimum-available Flow will only use a filesystem for shared memory if it has at least these many bytes available (default: 536870912 - which is 512MB)\n --show-all-branches Print all branch errors (the default is to print the most relevant branches)\n --show-all-errors Print all errors (the default is to truncate after 50 errors)\n --strip-root Print paths without the root\n --temp-dir Directory in which to store temp files (default: FLOW_TEMP_DIR, or /tmp/flow/)\n --traces Outline an error path up to a specified level\n --unicode Display terminal output with unicode decoration. never, always, auto (default: auto)\n --untyped Specify one or more patterns, comma separated, for files to treat as untyped\n --verbose Print verbose info during typecheck\n --verbose-depth Recursively print types up to specified depth (default 1, implies --verbose)\n --verbose-indent Indent verbose info during typecheck (implies --verbose)\n --weak Typecheck with weak inference, assuming dynamic types by default" + "msg":"flow: --pants unknown option\nUsage: flow check [OPTION]... [ROOT]\n\nDoes a full Flow check and prints the results.\n\nFlow will search upward for a .flowconfig file, beginning at ROOT.\nROOT is assumed to be the current directory if unspecified.\n\n --all Typecheck all files, not just @flow\n --color Display terminal output in color. never, always, auto (default: auto)\n --debug Print debug info during typecheck\n --from Specify client (for use by editor plugins)\n --help This list of options\n --ignore Specify one or more ignore patterns, comma separated\n --ignore-version Ignore the version constraint in .flowconfig\n --include Specify one or more include patterns, comma separated\n --include-suppressed Ignore any `suppress_comment` lines in .flowconfig\n --include-warnings Include warnings in the error output (warnings are excluded by default)\n --json Output results in JSON format\n --json-version The version of the JSON format (defaults to 1)\n --lib Specify one or more lib files/directories, comma separated\n --lints Specify one or more lint rules, comma separated\n --max-warnings Warnings above this number will cause a nonzero exit code (implies --include-warnings)\n --max-workers Maximum number of workers to create (capped by number of cores)\n --merge-timeout The maximum time in seconds to attempt to typecheck a file or cycle of files. 0 means no timeout (default: 100)\n --message-width Sets the width of messages but not code snippets (defaults to the smaller of 120 or the terminal width)\n --munge-underscore-members Treat any class member name with a leading underscore as private\n --no-flowlib Do not include embedded declarations\n --one-line Escapes newlines so that each error prints on one line\n --pretty Pretty-print JSON output (implies --json)\n --profile Output profiling information\n --quiet Suppress output about server startup\n --sharedmemory-dep-table-pow The exponent for the size of the shared memory dependency table. The default is 17, implying a size of 2^17 bytes\n --sharedmemory-dirs Directory in which to store shared memory heap (default: /dev/shm/)\n --sharedmemory-hash-table-pow The exponent for the size of the shared memory hash table. The default is 19, implying a size of 2^19 bytes\n --sharedmemory-log-level The logging level for shared memory statistics. 0=none, 1=some\n --sharedmemory-minimum-available Flow will only use a filesystem for shared memory if it has at least these many bytes available (default: 536870912 - which is 512MB)\n --show-all-branches Print all branch errors (the default is to print the most relevant branches)\n --show-all-errors Print all errors (the default is to truncate after 50 errors)\n --silence Specify one or more patterns, comma separated, for files to treat as silenced\n --strip-root Print paths without the root\n --temp-dir Directory in which to store temp files (default: FLOW_TEMP_DIR, or /tmp/flow/)\n --traces Outline an error path up to a specified level\n --unicode Display terminal output with unicode decoration. never, always, auto (default: auto)\n --untyped Specify one or more patterns, comma separated, for files to treat as untyped\n --verbose Print verbose info during typecheck\n --verbose-depth Recursively print types up to specified depth (default 1, implies --verbose)\n --verbose-indent Indent verbose info during typecheck (implies --verbose)\n --weak Typecheck with weak inference, assuming dynamic types by default" } } diff --git a/website/en/docs/config/index.md b/website/en/docs/config/index.md index 42a82957dd3..2b72374a718 100644 --- a/website/en/docs/config/index.md +++ b/website/en/docs/config/index.md @@ -13,13 +13,14 @@ not proud of our custom format and plan to support a better format in the future. [GitHub issue #153](https://github.com/facebook/flow/issues/153) tracks this. -The `.flowconfig` consists of 6 sections: +The `.flowconfig` consists of 7 sections: * [`[include]`](include) * [`[ignore]`](ignore) * [`[libs]`](libs) * [`[lints]`](lints) * [`[options]`](options) +* [`[silence]`](silence) * [`[version]`](version) ### Comments diff --git a/website/en/docs/config/silence.md b/website/en/docs/config/silence.md new file mode 100644 index 00000000000..c7401cac529 --- /dev/null +++ b/website/en/docs/config/silence.md @@ -0,0 +1,55 @@ +--- +layout: guide +--- + +Often third-party libraries have broken type definitions or have type +definitions only compatible with a certain version of Flow. In those cases it +may be useful to still type check the third-party libraries but silence any +warnings or errors found. + +### `[silence]` + +The `[silence]` section in a `.flowconfig` file tells Flow to silence warnings +and errors in files matching the specified regular expressions when type +checking your code. Flow still type checks the files but acts as if there is +a comment that matches +[`suppress_comment`](options#toc-suppress-comment-regex") on every line. +By default, nothing is silenced. + +Things to keep in mind: + +1. These are [OCaml regular expressions](http://caml.inria.fr/pub/docs/manual-ocaml/libref/Str.html#TYPEregexp). +2. These regular expressions match against absolute paths. They probably should + start with `.*` + +An example `[silence]` section might look like: + +``` +[silence] +.*/third_party/.* +.*/src/\(foo\|bar\)/.* +.*\.silence\.js +``` + +This `[silence]` section will ignore: + +1. Any file or directory under a directory named `third_party` +2. Any file or directory under `.*/src/foo` or under `.*/src/bar` +3. Any file that ends with the extension `.silence.js` + +Starting with Flow v0.23.0, you may use the `` placeholder in +your regular expressions. At runtime, Flow will treat the placeholder as if it +were the absolute path to the project's root directory. This is useful for +writing regular expressions that are relative rather than absolute. + +For example, you can write: + +``` +[silence] +/third_party/.* +``` + +Which would silence any file or directory under the directory named `third_party/` +within the project root. However, unlike the previous example's +`.*/third_party/.*`, it would NOT silence files or directories under other +directories named `third_party/`, like `src/third_party/`. From 06a06afabbf46af147bc13cc8a575b1524b89d8b Mon Sep 17 00:00:00 2001 From: Christian Legnitto Date: Thu, 14 Jun 2018 14:09:02 -0700 Subject: [PATCH 2/2] Rename silence to declaration mode --- src/commands/commandUtils.ml | 30 +++++----- src/commands/config/flowConfig.ml | 30 +++++----- src/commands/config/flowConfig.mli | 6 +- src/commands/genFlowFilesCommand.ml | 6 +- src/commands/initCommand.ml | 4 +- src/commands/lsCommand.ml | 12 ++-- src/common/files.ml | 10 ++-- src/common/files.mli | 8 +-- src/typing/type_inference_js.ml | 13 ++-- .../.flowconfig | 2 +- .../A.js | 0 .../B.js | 0 .../C.js | 0 .../D.js | 0 .../config_declarations.exp} | 0 .../lib.js | 0 tests/json_exit/json_exit.exp | 4 +- website/en/docs/config/declarations.md | 59 +++++++++++++++++++ website/en/docs/config/index.md | 11 ++-- website/en/docs/config/silence.md | 55 ----------------- 20 files changed, 125 insertions(+), 125 deletions(-) rename tests/{config_silence => config_declarations}/.flowconfig (92%) rename tests/{config_silence => config_declarations}/A.js (100%) rename tests/{config_silence => config_declarations}/B.js (100%) rename tests/{config_silence => config_declarations}/C.js (100%) rename tests/{config_silence => config_declarations}/D.js (100%) rename tests/{config_silence/config_silence.exp => config_declarations/config_declarations.exp} (100%) rename tests/{config_silence => config_declarations}/lib.js (100%) create mode 100644 website/en/docs/config/declarations.md delete mode 100644 website/en/docs/config/silence.md diff --git a/src/commands/commandUtils.ml b/src/commands/commandUtils.ml index b9b5a3b5a81..7fb8f7276ff 100644 --- a/src/commands/commandUtils.ml +++ b/src/commands/commandUtils.ml @@ -382,7 +382,7 @@ let assert_version flowconfig = type flowconfig_params = { ignores: string list; untyped: string list; - silence: string list; + declarations: string list; includes: string list; libs: string list; (* We store raw_lint_severities as a string list instead of as a LintSettings.t so we @@ -395,14 +395,14 @@ let list_of_string_arg = function | None -> [] | Some arg_str -> Str.split (Str.regexp ",") arg_str -let collect_flowconfig_flags main ignores_str untyped_str silence_str includes_str lib_str lints_str = +let collect_flowconfig_flags main ignores_str untyped_str declarations_str includes_str lib_str lints_str = let ignores = list_of_string_arg ignores_str in let untyped = list_of_string_arg untyped_str in - let silence = list_of_string_arg silence_str in + let declarations = list_of_string_arg declarations_str in let includes = list_of_string_arg includes_str in let libs = list_of_string_arg lib_str in let raw_lint_severities = list_of_string_arg lints_str in - main { ignores; includes; libs; raw_lint_severities; untyped; silence; } + main { ignores; includes; libs; raw_lint_severities; untyped; declarations; } let file_options = let default_lib_dir ~no_flowlib tmp_dir = @@ -468,7 +468,7 @@ let file_options = | [] -> config_libs | _ -> config_libs @ (List.map (Files.make_path_absolute root) extras) in - fun ~root ~no_flowlib ~temp_dir ~includes ~ignores ~libs ~untyped ~silence flowconfig -> + fun ~root ~no_flowlib ~temp_dir ~includes ~ignores ~libs ~untyped ~declarations flowconfig -> let default_lib_dir = let no_flowlib = no_flowlib || FlowConfig.no_flowlib flowconfig in Some (default_lib_dir ~no_flowlib temp_dir) @@ -481,10 +481,10 @@ let file_options = root (FlowConfig.untyped flowconfig) untyped in - let silence = ignores_of_arg + let declarations = ignores_of_arg root - (FlowConfig.silence flowconfig) - silence in + (FlowConfig.declarations flowconfig) + declarations in let lib_paths = lib_paths ~root flowconfig libs in let includes = includes @@ -494,7 +494,7 @@ let file_options = default_lib_dir; ignores; untyped; - silence; + declarations; includes; lib_paths; module_file_exts = FlowConfig.module_file_exts flowconfig; @@ -514,10 +514,10 @@ let untyped_flag prev = CommandSpec.ArgSpec.( ~doc:"Specify one or more patterns, comma separated, for files to treat as untyped" ) -let silence_flag prev = CommandSpec.ArgSpec.( +let declaration_flag prev = CommandSpec.ArgSpec.( prev - |> flag "--silence" (optional string) - ~doc:"Specify one or more patterns, comma separated, for files to treat as silenced" + |> flag "--declaration" (optional string) + ~doc:"Specify one or more patterns, comma separated, for files to treat as declarations" ) let include_flag prev = CommandSpec.ArgSpec.( @@ -549,7 +549,7 @@ let flowconfig_flags prev = CommandSpec.ArgSpec.( |> collect collect_flowconfig_flags |> ignore_flag |> untyped_flag - |> silence_flag + |> declaration_flag |> include_flag |> lib_flag |> lints_flag @@ -796,9 +796,9 @@ let make_options ~flowconfig ~lazy_mode ~root (options_flags: Options_flags.t) = libs; raw_lint_severities=_; untyped; - silence; + declarations; } = options_flags.flowconfig_flags in - file_options ~root ~no_flowlib ~temp_dir ~includes ~ignores ~libs ~untyped ~silence flowconfig + file_options ~root ~no_flowlib ~temp_dir ~includes ~ignores ~libs ~untyped ~declarations flowconfig in let lint_severities = parse_lints_flag (FlowConfig.lint_severities flowconfig) options_flags.flowconfig_flags.raw_lint_severities diff --git a/src/commands/config/flowConfig.ml b/src/commands/config/flowConfig.ml index f655529eb08..943d3f29ffc 100644 --- a/src/commands/config/flowConfig.ml +++ b/src/commands/config/flowConfig.ml @@ -313,8 +313,8 @@ type config = { ignores: string list; (* files that should be treated as untyped *) untyped: string list; - (* files that should have errors silenced *) - silence: string list; + (* files that should be treated as declarations *) + declarations: string list; (* non-root include paths *) includes: string list; (* library paths. no wildcards *) @@ -341,8 +341,8 @@ end = struct let untyped o untyped = List.iter (fun ex -> (fprintf o "%s\n" ex)) untyped - let silence o silence = - List.iter (fun ex -> (fprintf o "%s\n" ex)) silence + let declarations o declarations = + List.iter (fun ex -> (fprintf o "%s\n" ex)) declarations let includes o includes = List.iter (fun inc -> (fprintf o "%s\n" inc)) includes @@ -405,7 +405,7 @@ end = struct ignores o config.ignores; fprintf o "\n"; section_if_nonempty o "untyped" untyped config.untyped; - section_if_nonempty o "silence" silence config.silence; + section_if_nonempty o "declarations" declarations config.declarations; section_header o "include"; includes o config.includes; fprintf o "\n"; @@ -425,7 +425,7 @@ end let empty_config = { ignores = []; untyped = []; - silence = []; + declarations = []; includes = []; libs = []; lint_severities = LintSettings.empty_severities; @@ -479,9 +479,9 @@ let parse_untyped config lines = let untyped = trim_lines lines in { config with untyped; } -let parse_silence config lines = - let silence = trim_lines lines in - { config with silence; } +let parse_declarations config lines = + let declarations = trim_lines lines in + { config with declarations; } let parse_options config lines = let open Opts in @@ -959,7 +959,7 @@ let parse_section config ((section_ln, section), lines) = | "ignore", _ -> parse_ignores config lines | "libs", _ -> parse_libs config lines | "lints", _ -> parse_lints config lines - | "silence", _ -> parse_silence config lines + | "declarations", _ -> parse_declarations config lines | "strict", _ -> parse_strict config lines | "options", _ -> parse_options config lines | "untyped", _ -> parse_untyped config lines @@ -998,17 +998,17 @@ let read filename = } in parse config lines -let init ~ignores ~untyped ~silence ~includes ~libs ~options ~lints = +let init ~ignores ~untyped ~declarations ~includes ~libs ~options ~lints = let ignores_lines = List.map (fun s -> (1, s)) ignores in let untyped_lines = List.map (fun s -> (1, s)) untyped in - let silence_lines = List.map (fun s -> (1, s)) silence in + let declarations_lines = List.map (fun s -> (1, s)) declarations in let includes_lines = List.map (fun s -> (1, s)) includes in let options_lines = List.map (fun s -> (1, s)) options in let lib_lines = List.map (fun s -> (1, s)) libs in let lint_lines = List.map (fun s -> (1, s)) lints in let config = parse_ignores empty_config ignores_lines in let config = parse_untyped config untyped_lines in - let config = parse_silence config silence_lines in + let config = parse_declarations config declarations_lines in let config = parse_includes config includes_lines in let config = parse_options config options_lines in let config = parse_libs config lib_lines in @@ -1039,8 +1039,8 @@ let restore (filename, config) = cache := Some (filename, config) let ignores config = config.ignores (* files that should be treated as untyped *) let untyped config = config.untyped -(* files that should have errors silenced *) -let silence config = config.silence +(* files that should be treated as declarations *) +let declarations config = config.declarations (* non-root include paths *) let includes config = config.includes (* library paths. no wildcards *) diff --git a/src/commands/config/flowConfig.mli b/src/commands/config/flowConfig.mli index 10ca063d0c9..52b3e3e5f92 100644 --- a/src/commands/config/flowConfig.mli +++ b/src/commands/config/flowConfig.mli @@ -13,7 +13,7 @@ val empty_config: config val init: ignores: string list -> untyped: string list -> - silence: string list -> + declarations: string list -> includes: string list -> libs: string list -> options: string list -> @@ -29,8 +29,8 @@ val restore: string * config -> unit val ignores: config -> string list (* files that should be treated as untyped *) val untyped: config -> string list -(* files that should have errors silenced *) -val silence: config -> string list +(* files that should be treated as declarations *) +val declarations: config -> string list (* non-root include paths *) val includes: config -> string list (* library paths. no wildcards *) diff --git a/src/commands/genFlowFilesCommand.ml b/src/commands/genFlowFilesCommand.ml index 1c6f69f673c..7f7da52fa5a 100644 --- a/src/commands/genFlowFilesCommand.ml +++ b/src/commands/genFlowFilesCommand.ml @@ -56,7 +56,7 @@ let spec = { |> ignore_flag |> include_flag |> untyped_flag - |> silence_flag + |> declaration_flag |> from_flag |> anon "src" (required string) |> flag "--out-dir" string @@ -86,7 +86,7 @@ let write_file strip_root root content perm src_file_path dest_file_path = Unix.close fd let main option_values root error_flags strip_root ignore_flag - include_flag untyped_flag silence_flag from src out_dir () = ( + include_flag untyped_flag declaration_flag from src out_dir () = ( FlowEventLogger.set_from from; let src = expand_path src in let root = guess_root ( @@ -112,7 +112,7 @@ let main option_values root error_flags strip_root ignore_flag FlowExitStatus.exit ~msg FlowExitStatus.Commandline_usage_error ); - let options = LsCommand.make_options ~root ~ignore_flag ~include_flag ~untyped_flag ~silence_flag in + let options = LsCommand.make_options ~root ~ignore_flag ~include_flag ~untyped_flag ~declaration_flag in let _, libs = Files.init options in let next_files = LsCommand.get_ls_files ~root ~all:false ~options ~libs ~imaginary:false (Some src) diff --git a/src/commands/initCommand.ml b/src/commands/initCommand.ml index 74f8324000b..5b7b0a7fb3c 100644 --- a/src/commands/initCommand.ml +++ b/src/commands/initCommand.ml @@ -50,7 +50,7 @@ let main from flowconfig_flags options root () = in let ignores = flowconfig_flags.CommandUtils.ignores in let untyped = flowconfig_flags.CommandUtils.untyped in - let silence = flowconfig_flags.CommandUtils.silence in + let declarations = flowconfig_flags.CommandUtils.declarations in let includes = flowconfig_flags.CommandUtils.includes in let libs = flowconfig_flags.CommandUtils.libs in let lints = flowconfig_flags.CommandUtils.raw_lint_severities in @@ -62,7 +62,7 @@ let main from flowconfig_flags options root () = FlowExitStatus.(exit ~msg Invalid_flowconfig) end; - let config = FlowConfig.init ~ignores ~untyped ~silence ~includes ~libs ~options ~lints in + let config = FlowConfig.init ~ignores ~untyped ~declarations ~includes ~libs ~options ~lints in let out = Sys_utils.open_out_no_fail file in FlowConfig.write config out; diff --git a/src/commands/lsCommand.ml b/src/commands/lsCommand.ml index fa7879d5ec2..bb35c94148c 100644 --- a/src/commands/lsCommand.ml +++ b/src/commands/lsCommand.ml @@ -26,7 +26,7 @@ let spec = { |> ignore_flag |> include_flag |> untyped_flag - |> silence_flag + |> declaration_flag |> root_flag |> json_flags |> from_flag @@ -107,16 +107,16 @@ let rec iter_get_next ~f get_next = List.iter f result; iter_get_next ~f get_next -let make_options ~root ~ignore_flag ~include_flag ~untyped_flag ~silence_flag = +let make_options ~root ~ignore_flag ~include_flag ~untyped_flag ~declaration_flag = let flowconfig = FlowConfig.get (Server_files_js.config_file root) in let temp_dir = FlowConfig.temp_dir flowconfig in let includes = CommandUtils.list_of_string_arg include_flag in let ignores = CommandUtils.list_of_string_arg ignore_flag in let untyped = CommandUtils.list_of_string_arg untyped_flag in - let silence = CommandUtils.list_of_string_arg silence_flag in + let declarations = CommandUtils.list_of_string_arg declaration_flag in let libs = [] in CommandUtils.file_options flowconfig - ~root ~no_flowlib:true ~temp_dir ~ignores ~includes ~libs ~untyped ~silence + ~root ~no_flowlib:true ~temp_dir ~ignores ~includes ~libs ~untyped ~declarations (* The problem with Files.wanted is that it says yes to everything except ignored files and libs. * So implicitly ignored files (like files in another directory) pass the Files.wanted check *) @@ -176,7 +176,7 @@ let get_next_append_const get_next const = ret let main - strip_root ignore_flag include_flag untyped_flag silence_flag root_flag json pretty from all imaginary reason + strip_root ignore_flag include_flag untyped_flag declaration_flag root_flag json pretty from all imaginary reason input_file root_or_files () = let files_or_dirs = get_filenames_from_input ~allow_imaginary:true input_file root_or_files in @@ -196,7 +196,7 @@ let main | _ -> None) ) in - let options = make_options ~root ~ignore_flag ~include_flag ~untyped_flag ~silence_flag in + let options = make_options ~root ~ignore_flag ~include_flag ~untyped_flag ~declaration_flag in (* Turn on --no-flowlib by default, so that flow ls never reports flowlib files *) let options = { options with Files.default_lib_dir = None; } in let _, libs = Files.init options in diff --git a/src/common/files.ml b/src/common/files.ml index 6f7babe9224..906acd7f3d3 100644 --- a/src/common/files.ml +++ b/src/common/files.ml @@ -11,7 +11,7 @@ type options = { default_lib_dir: Path.t option; ignores: (string * Str.regexp) list; untyped: (string * Str.regexp) list; - silence: (string * Str.regexp) list; + declarations: (string * Str.regexp) list; includes: Path_matcher.t; lib_paths: Path.t list; module_file_exts: SSet.t; @@ -22,7 +22,7 @@ type options = { let default_lib_dir options = options.default_lib_dir let ignores options = options.ignores let untyped options = options.untyped -let silence options = options.silence +let declarations options = options.declarations let includes options = options.includes let lib_paths options = options.lib_paths let module_file_exts options = options.module_file_exts @@ -302,9 +302,9 @@ let is_untyped (options: options) = let path = Sys_utils.normalize_filename_dir_sep path in List.exists (fun rx -> Str.string_match rx path 0) list -(* true if a file path matches an [silence] entry in config *) -let is_silenced (options: options) = - let list = List.map snd options.silence in +(* true if a file path matches a [declarations] entry in config *) +let is_declaration (options: options) = + let list = List.map snd options.declarations in fun path -> (* On Windows, the path may use \ instead of /, but let's standardize the * ignore regex to use / *) diff --git a/src/common/files.mli b/src/common/files.mli index b2558433290..471f9af5944 100644 --- a/src/common/files.mli +++ b/src/common/files.mli @@ -11,7 +11,7 @@ type options = { default_lib_dir: Path.t option; ignores: (string * Str.regexp) list; untyped: (string * Str.regexp) list; - silence: (string * Str.regexp) list; + declarations: (string * Str.regexp) list; includes: Path_matcher.t; lib_paths: Path.t list; module_file_exts: SSet.t; @@ -22,7 +22,7 @@ type options = { val default_lib_dir: options -> Path.t option val ignores: options -> (string * Str.regexp) list val untyped: options -> (string * Str.regexp) list -val silence: options -> (string * Str.regexp) list +val declarations: options -> (string * Str.regexp) list val includes: options -> Path_matcher.t val lib_paths: options -> Path.t list val module_file_exts: options -> SSet.t @@ -44,8 +44,8 @@ val is_flow_file: options: options -> string -> bool val is_ignored: options -> string -> bool (* true if a file path matches an [untyped] entry in config *) val is_untyped: options -> string -> bool -(* true if a file path matches an [silence] entry in config *) -val is_silenced: options -> string -> bool +(* true if a file path matches a [declarations] entry in config *) +val is_declaration: options -> string -> bool (* true if a file path matches an [include] path in config *) val is_included: options -> string -> bool diff --git a/src/typing/type_inference_js.ml b/src/typing/type_inference_js.ml index cf0bd11a6b0..9b84709a639 100644 --- a/src/typing/type_inference_js.ml +++ b/src/typing/type_inference_js.ml @@ -344,16 +344,13 @@ let scan_for_lint_suppressions = let scan_for_suppressions cx lint_severities file_options comments = let filename = File_key.to_string (Context.file cx) in - let silenced = match file_options with - | Some file_options -> Files.is_silenced file_options filename + let declaration = match file_options with + | Some file_options -> Files.is_declaration file_options filename | None -> false in - if silenced then - (* Whole file is silenced. *) - (* A more "correct" solution might be to keep all the errors and instead - * synthesize suppressions for them. That would be a lot of work - * for the same end result though. - *) + if declaration then + (* Declaration mode. + * We don't report any warnings or errors. *) Context.remove_all_errors cx else (* Scan comments for line suppressions. *) diff --git a/tests/config_silence/.flowconfig b/tests/config_declarations/.flowconfig similarity index 92% rename from tests/config_silence/.flowconfig rename to tests/config_declarations/.flowconfig index 7c4809631f5..99c24d2787f 100644 --- a/tests/config_silence/.flowconfig +++ b/tests/config_declarations/.flowconfig @@ -5,7 +5,7 @@ [libs] lib.js -[silence] +[declarations] .*/B.js .*/C.js diff --git a/tests/config_silence/A.js b/tests/config_declarations/A.js similarity index 100% rename from tests/config_silence/A.js rename to tests/config_declarations/A.js diff --git a/tests/config_silence/B.js b/tests/config_declarations/B.js similarity index 100% rename from tests/config_silence/B.js rename to tests/config_declarations/B.js diff --git a/tests/config_silence/C.js b/tests/config_declarations/C.js similarity index 100% rename from tests/config_silence/C.js rename to tests/config_declarations/C.js diff --git a/tests/config_silence/D.js b/tests/config_declarations/D.js similarity index 100% rename from tests/config_silence/D.js rename to tests/config_declarations/D.js diff --git a/tests/config_silence/config_silence.exp b/tests/config_declarations/config_declarations.exp similarity index 100% rename from tests/config_silence/config_silence.exp rename to tests/config_declarations/config_declarations.exp diff --git a/tests/config_silence/lib.js b/tests/config_declarations/lib.js similarity index 100% rename from tests/config_silence/lib.js rename to tests/config_declarations/lib.js diff --git a/tests/json_exit/json_exit.exp b/tests/json_exit/json_exit.exp index 377199ac065..f693d86546e 100644 --- a/tests/json_exit/json_exit.exp +++ b/tests/json_exit/json_exit.exp @@ -7,12 +7,12 @@ "msg":"Could not find file or directory pants; canceling search for .flowconfig.\nSee \"flow init --help\" for more info" } } -{"flowVersion":"0.74.0","exit":{"code":64,"reason":"Commandline_usage_error","msg":"flow: --pants unknown option\nUsage: flow check [OPTION]... [ROOT]\n\nDoes a full Flow check and prints the results.\n\nFlow will search upward for a .flowconfig file, beginning at ROOT.\nROOT is assumed to be the current directory if unspecified.\n\n --all Typecheck all files, not just @flow\n --color Display terminal output in color. never, always, auto (default: auto)\n --debug Print debug info during typecheck\n --from Specify client (for use by editor plugins)\n --help This list of options\n --ignore Specify one or more ignore patterns, comma separated\n --ignore-version Ignore the version constraint in .flowconfig\n --include Specify one or more include patterns, comma separated\n --include-suppressed Ignore any `suppress_comment` lines in .flowconfig\n --include-warnings Include warnings in the error output (warnings are excluded by default)\n --json Output results in JSON format\n --json-version The version of the JSON format (defaults to 1)\n --lib Specify one or more lib files/directories, comma separated\n --lints Specify one or more lint rules, comma separated\n --max-warnings Warnings above this number will cause a nonzero exit code (implies --include-warnings)\n --max-workers Maximum number of workers to create (capped by number of cores)\n --merge-timeout The maximum time in seconds to attempt to typecheck a file or cycle of files. 0 means no timeout (default: 100)\n --message-width Sets the width of messages but not code snippets (defaults to the smaller of 120 or the terminal width)\n --munge-underscore-members Treat any class member name with a leading underscore as private\n --no-flowlib Do not include embedded declarations\n --one-line Escapes newlines so that each error prints on one line\n --pretty Pretty-print JSON output (implies --json)\n --profile Output profiling information\n --quiet Suppress output about server startup\n --sharedmemory-dep-table-pow The exponent for the size of the shared memory dependency table. The default is 17, implying a size of 2^17 bytes\n --sharedmemory-dirs Directory in which to store shared memory heap (default: /dev/shm/)\n --sharedmemory-hash-table-pow The exponent for the size of the shared memory hash table. The default is 19, implying a size of 2^19 bytes\n --sharedmemory-log-level The logging level for shared memory statistics. 0=none, 1=some\n --sharedmemory-minimum-available Flow will only use a filesystem for shared memory if it has at least these many bytes available (default: 536870912 - which is 512MB)\n --show-all-branches Print all branch errors (the default is to print the most relevant branches)\n --show-all-errors Print all errors (the default is to truncate after 50 errors)\n --strip-root Print paths without the root\n --temp-dir Directory in which to store temp files (default: FLOW_TEMP_DIR, or /tmp/flow/)\n --traces Outline an error path up to a specified level\n --unicode Display terminal output with unicode decoration. never, always, auto (default: auto)\n --untyped Specify one or more patterns, comma separated, for files to treat as untyped\n --verbose Print verbose info during typecheck\n --verbose-depth Recursively print types up to specified depth (default 1, implies --verbose)\n --verbose-indent Indent verbose info during typecheck (implies --verbose)\n --weak Typecheck with weak inference, assuming dynamic types by default"}} +{"flowVersion":"0.74.0","exit":{"code":64,"reason":"Commandline_usage_error","msg":"flow: --pants unknown option\nUsage: flow check [OPTION]... [ROOT]\n\nDoes a full Flow check and prints the results.\n\nFlow will search upward for a .flowconfig file, beginning at ROOT.\nROOT is assumed to be the current directory if unspecified.\n\n --all Typecheck all files, not just @flow\n --color Display terminal output in color. never, always, auto (default: auto)\n --debug Print debug info during typecheck\n --declaration Specify one or more patterns, comma separated, for files to treat as declarations\n --from Specify client (for use by editor plugins)\n --help This list of options\n --ignore Specify one or more ignore patterns, comma separated\n --ignore-version Ignore the version constraint in .flowconfig\n --include Specify one or more include patterns, comma separated\n --include-suppressed Ignore any `suppress_comment` lines in .flowconfig\n --include-warnings Include warnings in the error output (warnings are excluded by default)\n --json Output results in JSON format\n --json-version The version of the JSON format (defaults to 1)\n --lib Specify one or more lib files/directories, comma separated\n --lints Specify one or more lint rules, comma separated\n --max-warnings Warnings above this number will cause a nonzero exit code (implies --include-warnings)\n --max-workers Maximum number of workers to create (capped by number of cores)\n --merge-timeout The maximum time in seconds to attempt to typecheck a file or cycle of files. 0 means no timeout (default: 100)\n --message-width Sets the width of messages but not code snippets (defaults to the smaller of 120 or the terminal width)\n --munge-underscore-members Treat any class member name with a leading underscore as private\n --no-flowlib Do not include embedded declarations\n --one-line Escapes newlines so that each error prints on one line\n --pretty Pretty-print JSON output (implies --json)\n --profile Output profiling information\n --quiet Suppress output about server startup\n --sharedmemory-dep-table-pow The exponent for the size of the shared memory dependency table. The default is 17, implying a size of 2^17 bytes\n --sharedmemory-dirs Directory in which to store shared memory heap (default: /dev/shm/)\n --sharedmemory-hash-table-pow The exponent for the size of the shared memory hash table. The default is 19, implying a size of 2^19 bytes\n --sharedmemory-log-level The logging level for shared memory statistics. 0=none, 1=some\n --sharedmemory-minimum-available Flow will only use a filesystem for shared memory if it has at least these many bytes available (default: 536870912 - which is 512MB)\n --show-all-branches Print all branch errors (the default is to print the most relevant branches)\n --show-all-errors Print all errors (the default is to truncate after 50 errors)\n --strip-root Print paths without the root\n --temp-dir Directory in which to store temp files (default: FLOW_TEMP_DIR, or /tmp/flow/)\n --traces Outline an error path up to a specified level\n --unicode Display terminal output with unicode decoration. never, always, auto (default: auto)\n --untyped Specify one or more patterns, comma separated, for files to treat as untyped\n --verbose Print verbose info during typecheck\n --verbose-depth Recursively print types up to specified depth (default 1, implies --verbose)\n --verbose-indent Indent verbose info during typecheck (implies --verbose)\n --weak Typecheck with weak inference, assuming dynamic types by default"}} { "flowVersion":"0.74.0", "exit":{ "code":64, "reason":"Commandline_usage_error", - "msg":"flow: --pants unknown option\nUsage: flow check [OPTION]... [ROOT]\n\nDoes a full Flow check and prints the results.\n\nFlow will search upward for a .flowconfig file, beginning at ROOT.\nROOT is assumed to be the current directory if unspecified.\n\n --all Typecheck all files, not just @flow\n --color Display terminal output in color. never, always, auto (default: auto)\n --debug Print debug info during typecheck\n --from Specify client (for use by editor plugins)\n --help This list of options\n --ignore Specify one or more ignore patterns, comma separated\n --ignore-version Ignore the version constraint in .flowconfig\n --include Specify one or more include patterns, comma separated\n --include-suppressed Ignore any `suppress_comment` lines in .flowconfig\n --include-warnings Include warnings in the error output (warnings are excluded by default)\n --json Output results in JSON format\n --json-version The version of the JSON format (defaults to 1)\n --lib Specify one or more lib files/directories, comma separated\n --lints Specify one or more lint rules, comma separated\n --max-warnings Warnings above this number will cause a nonzero exit code (implies --include-warnings)\n --max-workers Maximum number of workers to create (capped by number of cores)\n --merge-timeout The maximum time in seconds to attempt to typecheck a file or cycle of files. 0 means no timeout (default: 100)\n --message-width Sets the width of messages but not code snippets (defaults to the smaller of 120 or the terminal width)\n --munge-underscore-members Treat any class member name with a leading underscore as private\n --no-flowlib Do not include embedded declarations\n --one-line Escapes newlines so that each error prints on one line\n --pretty Pretty-print JSON output (implies --json)\n --profile Output profiling information\n --quiet Suppress output about server startup\n --sharedmemory-dep-table-pow The exponent for the size of the shared memory dependency table. The default is 17, implying a size of 2^17 bytes\n --sharedmemory-dirs Directory in which to store shared memory heap (default: /dev/shm/)\n --sharedmemory-hash-table-pow The exponent for the size of the shared memory hash table. The default is 19, implying a size of 2^19 bytes\n --sharedmemory-log-level The logging level for shared memory statistics. 0=none, 1=some\n --sharedmemory-minimum-available Flow will only use a filesystem for shared memory if it has at least these many bytes available (default: 536870912 - which is 512MB)\n --show-all-branches Print all branch errors (the default is to print the most relevant branches)\n --show-all-errors Print all errors (the default is to truncate after 50 errors)\n --silence Specify one or more patterns, comma separated, for files to treat as silenced\n --strip-root Print paths without the root\n --temp-dir Directory in which to store temp files (default: FLOW_TEMP_DIR, or /tmp/flow/)\n --traces Outline an error path up to a specified level\n --unicode Display terminal output with unicode decoration. never, always, auto (default: auto)\n --untyped Specify one or more patterns, comma separated, for files to treat as untyped\n --verbose Print verbose info during typecheck\n --verbose-depth Recursively print types up to specified depth (default 1, implies --verbose)\n --verbose-indent Indent verbose info during typecheck (implies --verbose)\n --weak Typecheck with weak inference, assuming dynamic types by default" + "msg":"flow: --pants unknown option\nUsage: flow check [OPTION]... [ROOT]\n\nDoes a full Flow check and prints the results.\n\nFlow will search upward for a .flowconfig file, beginning at ROOT.\nROOT is assumed to be the current directory if unspecified.\n\n --all Typecheck all files, not just @flow\n --color Display terminal output in color. never, always, auto (default: auto)\n --debug Print debug info during typecheck\n --declaration Specify one or more patterns, comma separated, for files to treat as declarations\n --from Specify client (for use by editor plugins)\n --help This list of options\n --ignore Specify one or more ignore patterns, comma separated\n --ignore-version Ignore the version constraint in .flowconfig\n --include Specify one or more include patterns, comma separated\n --include-suppressed Ignore any `suppress_comment` lines in .flowconfig\n --include-warnings Include warnings in the error output (warnings are excluded by default)\n --json Output results in JSON format\n --json-version The version of the JSON format (defaults to 1)\n --lib Specify one or more lib files/directories, comma separated\n --lints Specify one or more lint rules, comma separated\n --max-warnings Warnings above this number will cause a nonzero exit code (implies --include-warnings)\n --max-workers Maximum number of workers to create (capped by number of cores)\n --merge-timeout The maximum time in seconds to attempt to typecheck a file or cycle of files. 0 means no timeout (default: 100)\n --message-width Sets the width of messages but not code snippets (defaults to the smaller of 120 or the terminal width)\n --munge-underscore-members Treat any class member name with a leading underscore as private\n --no-flowlib Do not include embedded declarations\n --one-line Escapes newlines so that each error prints on one line\n --pretty Pretty-print JSON output (implies --json)\n --profile Output profiling information\n --quiet Suppress output about server startup\n --sharedmemory-dep-table-pow The exponent for the size of the shared memory dependency table. The default is 17, implying a size of 2^17 bytes\n --sharedmemory-dirs Directory in which to store shared memory heap (default: /dev/shm/)\n --sharedmemory-hash-table-pow The exponent for the size of the shared memory hash table. The default is 19, implying a size of 2^19 bytes\n --sharedmemory-log-level The logging level for shared memory statistics. 0=none, 1=some\n --sharedmemory-minimum-available Flow will only use a filesystem for shared memory if it has at least these many bytes available (default: 536870912 - which is 512MB)\n --show-all-branches Print all branch errors (the default is to print the most relevant branches)\n --show-all-errors Print all errors (the default is to truncate after 50 errors)\n --strip-root Print paths without the root\n --temp-dir Directory in which to store temp files (default: FLOW_TEMP_DIR, or /tmp/flow/)\n --traces Outline an error path up to a specified level\n --unicode Display terminal output with unicode decoration. never, always, auto (default: auto)\n --untyped Specify one or more patterns, comma separated, for files to treat as untyped\n --verbose Print verbose info during typecheck\n --verbose-depth Recursively print types up to specified depth (default 1, implies --verbose)\n --verbose-indent Indent verbose info during typecheck (implies --verbose)\n --weak Typecheck with weak inference, assuming dynamic types by default" } } diff --git a/website/en/docs/config/declarations.md b/website/en/docs/config/declarations.md new file mode 100644 index 00000000000..ec7a6bc6f04 --- /dev/null +++ b/website/en/docs/config/declarations.md @@ -0,0 +1,59 @@ +--- +layout: guide +--- + +Often third-party libraries have broken type definitions or have type +definitions only compatible with a certain version of Flow. In those cases it +may be useful to use type information from the third-party libraries without +typechecking their contents. + +### `[declarations]` + +The `[declarations]` section in a `.flowconfig` file tells Flow to parse files +matching the specified regular expressions in _declaration mode_. In declaration +mode the code is not typechecked. However, the signatures of functions, classes, +etc are extracted and used by the typechecker when checking other code. + +Conceptually one can think of declaration mode as if Flow still typechecks the +files but acts as if there is a comment that matches +[`suppress_comment`](options#toc-suppress-comment-regex") on every line. + +Things to keep in mind: + +1. Declaration mode should only be used for existing third-party code. You + should never use this for code under your control. +2. These are [OCaml regular expressions](http://caml.inria.fr/pub/docs/manual-ocaml/libref/Str.html#TYPEregexp). +3. These regular expressions match against absolute paths. They probably should + start with `.*` + +An example `[declarations]` section might look like: + +``` +[declarations] +.*/third_party/.* +.*/src/\(foo\|bar\)/.* +.*\.decl\.js +``` + +This `[declarations]` section will parse in declaration mode: + +1. Any file or directory under a directory named `third_party` +2. Any file or directory under `.*/src/foo` or under `.*/src/bar` +3. Any file that ends with the extension `.decl.js` + +Starting with Flow v0.23.0, you may use the `` placeholder in +your regular expressions. At runtime, Flow will treat the placeholder as if it +were the absolute path to the project's root directory. This is useful for +writing regular expressions that are relative rather than absolute. + +For example, you can write: + +``` +[declarations] +/third_party/.* +``` + +Which would parse in declaration mode any file or directory under the directory +named `third_party/` within the project root. However, unlike the previous +example's `.*/third_party/.*`, it would NOT parse files or directories under +directories named `third_party/`, like `src/third_party/`. diff --git a/website/en/docs/config/index.md b/website/en/docs/config/index.md index 2b72374a718..dcb8359ae14 100644 --- a/website/en/docs/config/index.md +++ b/website/en/docs/config/index.md @@ -15,18 +15,18 @@ this. The `.flowconfig` consists of 7 sections: +* [`[declarations]`](declarations) * [`[include]`](include) * [`[ignore]`](ignore) * [`[libs]`](libs) * [`[lints]`](lints) * [`[options]`](options) -* [`[silence]`](silence) * [`[version]`](version) ### Comments Comment support was added in v0.23.0. Lines beginning with zero or more spaces -followed by an `#` or `;` or `💩` are ignored. For example: +followed by an `#` or `;` or `💩` are ignored. For example: ``` # This is a comment @@ -40,17 +40,16 @@ followed by an `#` or `;` or `💩` are ignored. For example: ### Where to put the `.flowconfig` The location of the `.flowconfig` is significant. Flow treats the directory that -contains the `.flowconfig` as the *project root*. By default Flow includes all +contains the `.flowconfig` as the _project root_. By default Flow includes all the source code under the project root. The paths in the [[include] section](include) are relative to the project root. Some other configuration also lets you reference the project root via the macro -````. +``. Most people put the `.flowconfig` in the root of their project (i.e. next to the `package.json`). Some people put all their code in a `src/` directory and therefore put the `.flowconfig` at `src/.flowconfig`. - ### Example Say you have the following directory structure, with your `.flowconfig` in @@ -88,4 +87,4 @@ Here is an example of how you could use the `.flowconfig` directives. ``` Now `flow` will include a directory outside the `.flowconfig` path in its -check, ignore the `build` directory and use the declarations in `lib`. +check, ignore the `build` directory and use the declarations in `lib`. diff --git a/website/en/docs/config/silence.md b/website/en/docs/config/silence.md deleted file mode 100644 index c7401cac529..00000000000 --- a/website/en/docs/config/silence.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -layout: guide ---- - -Often third-party libraries have broken type definitions or have type -definitions only compatible with a certain version of Flow. In those cases it -may be useful to still type check the third-party libraries but silence any -warnings or errors found. - -### `[silence]` - -The `[silence]` section in a `.flowconfig` file tells Flow to silence warnings -and errors in files matching the specified regular expressions when type -checking your code. Flow still type checks the files but acts as if there is -a comment that matches -[`suppress_comment`](options#toc-suppress-comment-regex") on every line. -By default, nothing is silenced. - -Things to keep in mind: - -1. These are [OCaml regular expressions](http://caml.inria.fr/pub/docs/manual-ocaml/libref/Str.html#TYPEregexp). -2. These regular expressions match against absolute paths. They probably should - start with `.*` - -An example `[silence]` section might look like: - -``` -[silence] -.*/third_party/.* -.*/src/\(foo\|bar\)/.* -.*\.silence\.js -``` - -This `[silence]` section will ignore: - -1. Any file or directory under a directory named `third_party` -2. Any file or directory under `.*/src/foo` or under `.*/src/bar` -3. Any file that ends with the extension `.silence.js` - -Starting with Flow v0.23.0, you may use the `` placeholder in -your regular expressions. At runtime, Flow will treat the placeholder as if it -were the absolute path to the project's root directory. This is useful for -writing regular expressions that are relative rather than absolute. - -For example, you can write: - -``` -[silence] -/third_party/.* -``` - -Which would silence any file or directory under the directory named `third_party/` -within the project root. However, unlike the previous example's -`.*/third_party/.*`, it would NOT silence files or directories under other -directories named `third_party/`, like `src/third_party/`.