diff --git a/src/commands/commandUtils.ml b/src/commands/commandUtils.ml index 7d3494eb3e4..8e5a6855f1d 100644 --- a/src/commands/commandUtils.ml +++ b/src/commands/commandUtils.ml @@ -300,18 +300,20 @@ type flowconfig_params = { * can defer parsing of the lint settings until after the flowconfig lint settings * are known, to properly detect redundant settings (and avoid false positives) *) raw_lint_severities: string list; + silences: string list; } let list_of_string_arg = function | None -> [] | Some arg_str -> Str.split (Str.regexp ",") arg_str -let collect_flowconfig_flags main ignores_str includes_str lib_str lints_str = +let collect_flowconfig_flags main ignores_str includes_str lib_str lints_str silence_str = let ignores = list_of_string_arg ignores_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; } + let silences = list_of_string_arg silence_str in + main { ignores; includes; libs; raw_lint_severities; silences; } let file_options = let default_lib_dir ~no_flowlib tmp_dir = @@ -341,6 +343,12 @@ let file_options = Path_matcher.add acc path ) Path_matcher.empty paths in + let silences_of_arg root paths = + List.fold_left (fun acc path -> + let path = Files.make_path_absolute root path in + Path_matcher.add acc path + ) Path_matcher.empty paths + in let lib_paths ~root flowconfig extras = let flowtyped_path = Files.get_flowtyped_path root in let has_explicit_flowtyped_lib = ref false in @@ -365,7 +373,7 @@ let file_options = | [] -> config_libs | _ -> config_libs @ (List.map Path.make extras) in - fun ~root ~no_flowlib ~temp_dir ~includes ~ignores ~libs flowconfig -> + fun ~root ~no_flowlib ~temp_dir ~includes ~ignores ~libs ~silences flowconfig -> let default_lib_dir = let no_flowlib = no_flowlib || FlowConfig.no_flowlib flowconfig in Some (default_lib_dir ~no_flowlib temp_dir) @@ -378,6 +386,10 @@ let file_options = includes |> List.rev_append (FlowConfig.includes flowconfig) |> includes_of_arg root in + let silences = + silences + |> List.rev_append (FlowConfig.silences flowconfig) + |> silences_of_arg root in { Files. default_lib_dir; ignores; @@ -386,6 +398,7 @@ let file_options = module_file_exts = FlowConfig.module_file_exts flowconfig; module_resource_exts = FlowConfig.module_resource_exts flowconfig; node_resolver_dirnames = FlowConfig.node_resolver_dirnames flowconfig; + silences; } let ignore_flag prev = CommandSpec.ArgSpec.( @@ -412,6 +425,12 @@ let lints_flag prev = CommandSpec.ArgSpec.( ~doc:"Specify one or more lint rules, comma separated" ) +let silence_flag prev = CommandSpec.ArgSpec.( + prev + |> flag "--silence" (optional string) + ~doc:"Specify one or more files/directories to silence, comma separated" +) + let flowconfig_flags prev = CommandSpec.ArgSpec.( prev |> collect collect_flowconfig_flags @@ -419,6 +438,7 @@ let flowconfig_flags prev = CommandSpec.ArgSpec.( |> include_flag |> lib_flag |> lints_flag + |> silence_flag ) type command_params = { @@ -589,8 +609,8 @@ let make_options ~flowconfig ~lazy_mode ~root (options_flags: Options_flags.t) = let open Options_flags in let file_options = let no_flowlib = options_flags.no_flowlib in - let { includes; ignores; libs; raw_lint_severities=_; } = options_flags.flowconfig_flags in - file_options ~root ~no_flowlib ~temp_dir ~includes ~ignores ~libs flowconfig + let { includes; ignores; libs; raw_lint_severities=_; silences; } = options_flags.flowconfig_flags in + file_options ~root ~no_flowlib ~temp_dir ~includes ~ignores ~libs ~silences 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 b6c8b1293c9..0352888b1f5 100644 --- a/src/commands/config/flowConfig.ml +++ b/src/commands/config/flowConfig.ml @@ -312,6 +312,8 @@ type config = { strict_mode: StrictModeSettings.t; (* config options *) options: Opts.t; + (* non-root silence paths *) + silences: string list; } module Pp : sig @@ -366,6 +368,9 @@ end = struct (string_of_severity state))) lint_severities + let silences o silences = + List.iter (fun silence -> (fprintf o "%s\n" silence)) silences + let strict o config = let open Lints in let strict_mode = config.strict_mode in @@ -390,6 +395,9 @@ end = struct section_header o "options"; options o config; fprintf o "\n"; + section_header o "silence"; + silences o config.silences; + fprintf o "\n"; section_header o "strict"; strict o config end @@ -400,6 +408,7 @@ let empty_config = { libs = []; lint_severities = LintSettings.default_severities; strict_mode = StrictModeSettings.empty; + silences = []; options = Opts.default_options } @@ -445,6 +454,10 @@ let parse_ignores config lines = let ignores = trim_lines lines in { config with ignores; } +let parse_silences config lines = + let silences = trim_lines lines in + { config with silences; } + let parse_options config lines = let open Opts in let (>>=) = Core_result.(>>=) in @@ -886,6 +899,7 @@ let parse_section config ((section_ln, section), lines) = | "lints", _ -> parse_lints config lines | "strict", _ -> parse_strict config lines | "options", _ -> parse_options config lines + | "silence", _ -> parse_silences config lines | "version", _ -> parse_version config lines | _ -> error section_ln (spf "Unsupported config section: \"%s\"" section) @@ -911,17 +925,19 @@ let read filename = |> List.filter is_not_comment in parse empty_config lines -let init ~ignores ~includes ~libs ~options ~lints = +let init ~ignores ~includes ~libs ~lints ~options ~silences = let ignores_lines = List.map (fun s -> (1, s)) ignores 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 options_lines = List.map (fun s -> (1, s)) options in + let silences_lines = List.map (fun s -> (1, s)) silences in let config = parse_ignores empty_config ignores_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 let config = parse_lints config lint_lines in + let config = parse_options config options_lines in + let config = parse_silences config silences_lines in config let write config oc = Pp.config oc config @@ -950,6 +966,8 @@ let ignores config = config.ignores let includes config = config.includes (* library paths. no wildcards *) let libs config = config.libs +(* silence paths. no wildcards *) +let silences config = config.silences (* options *) let all c = c.options.Opts.all diff --git a/src/commands/config/flowConfig.mli b/src/commands/config/flowConfig.mli index 4620942261b..d55b814ab8d 100644 --- a/src/commands/config/flowConfig.mli +++ b/src/commands/config/flowConfig.mli @@ -14,8 +14,9 @@ val init: ignores: string list -> includes: string list -> libs: string list -> - options: string list -> lints: string list -> + options: string list -> + silences: string list -> config val write: config -> out_channel -> unit @@ -29,6 +30,8 @@ val ignores: config -> string list val includes: config -> string list (* library paths. no wildcards *) val libs: config -> string list +(* non-root paths to silence *) +val silences: config -> string list (* options *) val all: config -> bool diff --git a/src/commands/configCommands.ml b/src/commands/configCommands.ml index 3fc8cdfbde0..724fc823038 100644 --- a/src/commands/configCommands.ml +++ b/src/commands/configCommands.ml @@ -43,6 +43,7 @@ module Init = struct let includes = flowconfig_flags.CommandUtils.includes in let libs = flowconfig_flags.CommandUtils.libs in let lints = flowconfig_flags.CommandUtils.raw_lint_severities in + let silences = flowconfig_flags.CommandUtils.silences in let file = Server_files_js.config_file root in if Sys.file_exists file @@ -51,7 +52,7 @@ module Init = struct FlowExitStatus.(exit ~msg Invalid_flowconfig) end; - let config = FlowConfig.init ~ignores ~includes ~libs ~options ~lints in + let config = FlowConfig.init ~ignores ~includes ~libs ~lints ~options ~silences in let out = Sys_utils.open_out_no_fail file in FlowConfig.write config out; diff --git a/src/commands/genFlowFilesCommand.ml b/src/commands/genFlowFilesCommand.ml index cc82db5187f..3205aee3036 100644 --- a/src/commands/genFlowFilesCommand.ml +++ b/src/commands/genFlowFilesCommand.ml @@ -111,7 +111,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 in + let options = LsCommand.make_options ~root ~ignore_flag ~include_flag ~silence_flag:None 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/lsCommand.ml b/src/commands/lsCommand.ml index 9349ac090f7..ce09567d617 100644 --- a/src/commands/lsCommand.ml +++ b/src/commands/lsCommand.ml @@ -26,6 +26,7 @@ let spec = { |> ignore_flag |> include_flag |> root_flag + |> silence_flag |> json_flags |> from_flag |> flag "--all" no_arg @@ -106,13 +107,14 @@ 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 = +let make_options ~root ~ignore_flag ~include_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 libs = [] in - CommandUtils.file_options ~root ~no_flowlib:true ~temp_dir ~ignores ~includes ~libs flowconfig + let silences = CommandUtils.list_of_string_arg silence_flag in + CommandUtils.file_options ~root ~no_flowlib:true ~temp_dir ~ignores ~includes ~libs ~silences flowconfig (* 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 *) @@ -172,7 +174,7 @@ let get_next_append_const get_next const = ret let main - strip_root ignore_flag include_flag root_flag json pretty from all imaginary reason + strip_root ignore_flag include_flag root_flag silence_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 @@ -192,7 +194,7 @@ let main | _ -> None) ) in - let options = make_options ~root ~ignore_flag ~include_flag in + let options = make_options ~root ~ignore_flag ~include_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 92040495402..853562b01d3 100644 --- a/src/common/files.ml +++ b/src/common/files.ml @@ -15,6 +15,7 @@ type options = { module_file_exts: SSet.t; module_resource_exts: SSet.t; node_resolver_dirnames: string list; + silences: Path_matcher.t; } let default_lib_dir options = options.default_lib_dir @@ -24,6 +25,7 @@ let lib_paths options = options.lib_paths let module_file_exts options = options.module_file_exts let module_resource_exts options = options.module_resource_exts let node_resolver_dirnames options = options.node_resolver_dirnames +let silences options = options.silences let node_modules_containers = ref SSet.empty @@ -293,6 +295,10 @@ let is_ignored (options: options) = let is_included options f = Path_matcher.matches options.includes f +(* true if a file path matches a [silence] path in config *) +let is_silenced options f = + Path_matcher.matches options.silences f + let wanted ~options lib_fileset = let is_ignored_ = is_ignored options in fun path -> not (is_ignored_ path) && not (SSet.mem path lib_fileset) diff --git a/src/common/files.mli b/src/common/files.mli index 010333c9695..f0761a19c3a 100644 --- a/src/common/files.mli +++ b/src/common/files.mli @@ -15,6 +15,7 @@ type options = { module_file_exts: SSet.t; module_resource_exts: SSet.t; node_resolver_dirnames: string list; + silences: Path_matcher.t; } val default_lib_dir: options -> Path.t option @@ -24,6 +25,7 @@ val lib_paths: options -> Path.t list val module_file_exts: options -> SSet.t val module_resource_exts: options -> SSet.t val node_resolver_dirnames: options -> string list +val silences: options -> Path_matcher.t val node_modules_containers: SSet.t ref @@ -40,6 +42,8 @@ val is_flow_file: options: options -> string -> bool val is_ignored: options -> string -> bool (* true if a file path matches an [include] path in config *) val is_included: options -> string -> bool +(* true if a file path matches a [silence] path in config *) +val is_silenced: options -> string -> bool val is_valid_path: options: options -> string -> bool diff --git a/src/flow_dot_js.ml b/src/flow_dot_js.ml index b22c6340606..2c6d9683ae0 100644 --- a/src/flow_dot_js.ml +++ b/src/flow_dot_js.ml @@ -55,7 +55,7 @@ let load_lib_files ~master_cx ~metadata files match parse_content lib_file lib_content with | ast, [] -> let cx, syms = Type_inference_js.infer_lib_file - ~metadata ~exclude_syms ~lint_severities:LintSettings.default_severities + ~metadata ~exclude_syms ~file_options:None ~lint_severities:LintSettings.default_severities lib_file ast in @@ -168,7 +168,7 @@ let infer_and_merge ~root filename ast = let strict_mode = StrictModeSettings.empty in let file_sigs = Utils_js.FilenameMap.singleton filename file_sig in Merge_js.merge_component_strict - ~metadata ~lint_severities ~strict_mode ~file_sigs + ~metadata ~file_options:None ~lint_severities ~strict_mode ~file_sigs ~get_ast_unsafe:(fun _ -> ast) ~get_docblock_unsafe:(fun _ -> stub_docblock) [filename] reqs [] master_cx diff --git a/src/services/inference/init_js.ml b/src/services/inference/init_js.ml index 084be4dee1f..48185a1aef0 100644 --- a/src/services/inference/init_js.ml +++ b/src/services/inference/init_js.ml @@ -71,6 +71,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 match parse_lib_file options file with | Parsing.Parse_ok ast -> @@ -82,7 +83,7 @@ let load_lib_files ~master_cx ~options files = in let cx, syms = Infer.infer_lib_file - ~metadata ~exclude_syms ~lint_severities + ~metadata ~exclude_syms ~file_options:(Some file_options) ~lint_severities lib_file ast in diff --git a/src/services/inference/merge_service.ml b/src/services/inference/merge_service.ml index 179de99cbc0..58fe74df1e5 100644 --- a/src/services/inference/merge_service.ml +++ b/src/services/inference/merge_service.ml @@ -93,9 +93,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 = 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) @@ -135,9 +136,10 @@ let merge_contents_context options file ast info ~ensure_checked_dependencies = 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 ~file_options ~lint_severities ~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 dc6ff8c9f71..5a84e302d7a 100644 --- a/src/typing/merge_js.ml +++ b/src/typing/merge_js.ml @@ -203,7 +203,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 ~file_options ~lint_severities ~strict_mode ~file_sigs ~get_ast_unsafe ~get_docblock_unsafe ?(do_gc=false) component reqs dep_cxs master_cx = @@ -224,7 +224,7 @@ let merge_component_strict ~metadata ~lint_severities ~strict_mode ~file_sigs Context.merge_into cx master_cx; implicit_require_strict cx master_cx cx; Type_inference_js.infer_ast cx filename ast - ~lint_severities ~file_sig; + ~file_options ~lint_severities ~file_sig; if do_gc then Gc_js.do_gc ~master_cx cx; cx::cxs, FilenameMap.add filename cx impl_cxs ) ([], FilenameMap.empty) component in diff --git a/src/typing/merge_js.mli b/src/typing/merge_js.mli index 0737008b23f..8bf59842f13 100644 --- a/src/typing/merge_js.mli +++ b/src/typing/merge_js.mli @@ -28,6 +28,7 @@ end val merge_component_strict: metadata: Context.metadata -> + file_options: Files.options option -> lint_severities: Severity.severity LintSettings.t -> strict_mode: StrictModeSettings.t -> file_sigs: File_sig.t Utils_js.FilenameMap.t -> diff --git a/src/typing/type_inference_js.ml b/src/typing/type_inference_js.ml index 2bd7dca821b..52e8fadeb58 100644 --- a/src/typing/type_inference_js.ml +++ b/src/typing/type_inference_js.ml @@ -343,13 +343,29 @@ let scan_for_lint_suppressions = Context.set_severity_cover cx severity_cover; Context.set_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 file_options base_settings 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 base_settings comments + ; + () (* 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 ~file_options ~lint_severities ~file_sig cx filename ast = Flow_js.Cache.clear(); let _, statements, comments = ast in @@ -411,7 +427,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 file_options lint_severities comments; let module_t = Context.( match Context.module_kind cx with @@ -446,7 +462,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 ~metadata ~exclude_syms ~lint_severities file ast = +let infer_lib_file ~metadata ~exclude_syms ~file_options ~lint_severities file ast = let _, statements, comments = ast in Flow_js.Cache.clear(); @@ -465,7 +481,7 @@ let infer_lib_file ~metadata ~exclude_syms ~lint_severities file ast = Env.init_env ~exclude_syms cx module_scope; infer_core cx statements; - scan_for_suppressions cx lint_severities comments; + scan_for_suppressions cx file_options lint_severities 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 ab032db3a75..89af0c7d627 100644 --- a/src/typing/type_inference_js.mli +++ b/src/typing/type_inference_js.mli @@ -7,6 +7,7 @@ (* Lint suppressions are handled iff lint_severities is Some. *) val infer_ast: + file_options: Files.options option -> lint_severities: Severity.severity LintSettings.t -> file_sig: File_sig.t -> Context.t -> @@ -17,6 +18,7 @@ val infer_ast: val infer_lib_file: metadata: Context.metadata -> exclude_syms: SSet.t -> + file_options: Files.options option -> lint_severities: Severity.severity LintSettings.t -> File_key.t -> Loc.t Ast.program -> diff --git a/tests/json_exit/json_exit.exp b/tests/json_exit/json_exit.exp index 041436f8c25..cbc9fb7c7c8 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.57.3","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 --lib Specify one or more lib files/directories, comma separated\n --lints Specify one or more lint rules, comma separated\n --max-workers Maximum number of workers to create (capped by number of cores)\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-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 --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.57.3","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 --lib Specify one or more lib files/directories, comma separated\n --lints Specify one or more lint rules, comma separated\n --max-workers Maximum number of workers to create (capped by number of cores)\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-errors Print all errors (the default is to truncate after 50 errors)\n --silence Specify one or more files/directories to silence, comma separated\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 --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.57.3", "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 --lib Specify one or more lib files/directories, comma separated\n --lints Specify one or more lint rules, comma separated\n --max-workers Maximum number of workers to create (capped by number of cores)\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-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 --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 --lib Specify one or more lib files/directories, comma separated\n --lints Specify one or more lint rules, comma separated\n --max-workers Maximum number of workers to create (capped by number of cores)\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-errors Print all errors (the default is to truncate after 50 errors)\n --silence Specify one or more files/directories to silence, comma separated\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 --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/tests/silence/.flowconfig b/tests/silence/.flowconfig new file mode 100644 index 00000000000..8ef9225656e --- /dev/null +++ b/tests/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/silence/A.js b/tests/silence/A.js new file mode 100644 index 00000000000..3411f3e65e0 --- /dev/null +++ b/tests/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 suppressed + + // $FlowFixMe Indentation shouldn't matter +var test5: string = 123; // This error should be suppressed + +/* + * $FlowNewLine + */ +var test6: string = 123; diff --git a/tests/silence/B.js b/tests/silence/B.js new file mode 100644 index 00000000000..b4f41e62eb6 --- /dev/null +++ b/tests/silence/B.js @@ -0,0 +1,2 @@ +// $FlowFixMe +var test1: string = library_num; diff --git a/tests/silence/C.js b/tests/silence/C.js new file mode 100644 index 00000000000..149c0098c26 --- /dev/null +++ b/tests/silence/C.js @@ -0,0 +1,5 @@ +function takesAString(x: string): void {} + +function runTest(y: number): void { + takesAString(y); +} diff --git a/tests/silence/D.js b/tests/silence/D.js new file mode 100644 index 00000000000..bd5a7bf1624 --- /dev/null +++ b/tests/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/silence/lib.js b/tests/silence/lib.js new file mode 100644 index 00000000000..21cfa88e53e --- /dev/null +++ b/tests/silence/lib.js @@ -0,0 +1 @@ +declare var library_num: number; diff --git a/tests/silence/silence.exp b/tests/silence/silence.exp new file mode 100644 index 00000000000..dd76d7dd5b3 --- /dev/null +++ b/tests/silence/silence.exp @@ -0,0 +1,12 @@ +Error: A.js:16 + 16: var test4: string = 123; // This error is NOT suppressed + ^^^ number. This type is incompatible with + 16: var test4: string = 123; // This error is NOT suppressed + ^^^^^^ string + +Warning: A.js:14 + 14: // $FlowFixMe Error unused suppression + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Error suppressing comment. Unused suppression + + +Found 1 error and 1 warning