Skip to content

Commit

Permalink
Add global jsx pragma
Browse files Browse the repository at this point in the history
  • Loading branch information
goodmind committed Jun 4, 2019
1 parent a05cbb2 commit cb025b2
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 9 deletions.
1 change: 1 addition & 0 deletions src/commands/commandUtils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1083,6 +1083,7 @@ let make_options ~flowconfig_name ~flowconfig ~lazy_mode ~root (options_flags: O
opt_abstract_locations;
opt_include_suppressions = options_flags.include_suppressions;
opt_trust_mode = Option.value options_flags.trust_mode ~default:(FlowConfig.trust_mode flowconfig);
opt_jsx_pragma = FlowConfig.jsx_pragma flowconfig;
}

let make_env flowconfig_name connect_flags root =
Expand Down
6 changes: 6 additions & 0 deletions src/commands/config/flowConfig.ml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ module Opts = struct
types_first: bool;
wait_for_recheck: bool;
weak: bool;
jsx_pragma: string option;
}

let warn_on_unknown_opts (raw_opts, config) : (t * warning list, error) result =
Expand Down Expand Up @@ -184,6 +185,7 @@ module Opts = struct
types_first = false;
wait_for_recheck = false;
weak = false;
jsx_pragma = None;
}

let parse_lines : line list -> (raw_options, error) result =
Expand Down Expand Up @@ -614,6 +616,9 @@ module Opts = struct
("none", Options.NoTrust);
]
(fun opts trust_mode -> Ok { opts with trust_mode });

"jsx.pragma",
string (fun opts v -> Ok { opts with jsx_pragma = Some v });
]

let parse =
Expand Down Expand Up @@ -1046,6 +1051,7 @@ let temp_dir c = c.options.Opts.temp_dir
let traces c = c.options.Opts.traces
let trust_mode c = c.options.Opts.trust_mode
let types_first c = c.options.Opts.types_first
let jsx_pragma c = c.options.Opts.jsx_pragma
let required_version c = c.version
let wait_for_recheck c = c.options.Opts.wait_for_recheck
let weak c = c.options.Opts.weak
Expand Down
1 change: 1 addition & 0 deletions src/commands/config/flowConfig.mli
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ val temp_dir: config -> string
val traces: config -> int
val trust_mode: config -> Options.trust_mode
val types_first: config -> bool
val jsx_pragma: config -> string option
val wait_for_recheck: config -> bool
val weak: config -> bool

Expand Down
4 changes: 3 additions & 1 deletion src/common/options.ml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ type t = {
opt_strict_mode: StrictModeSettings.t;
opt_arch: arch;
opt_include_suppressions : bool;
opt_trust_mode: trust_mode
opt_trust_mode: trust_mode;
opt_jsx_pragma: string option;
}

let all opts = opts.opt_all
Expand Down Expand Up @@ -173,6 +174,7 @@ let lint_severities opts = opts.opt_lint_severities
let strict_mode opts = opts.opt_strict_mode

let trust_mode opts = opts.opt_trust_mode
let jsx_pragma opts = opts.opt_jsx_pragma


let lazy_mode_to_string lazy_mode =
Expand Down
26 changes: 18 additions & 8 deletions src/parsing/parsing_service_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ let does_content_match_file_hash ~reader file content =
* Add success/error info to passed accumulator. *)
let reducer
~worker_mutator ~reader ~parse_options ~skip_hash_mismatch
~max_header_tokens ~noflow ~parse_unchanged
~max_header_tokens ~noflow ~jsx_pragma ~parse_unchanged
parse_results file
: results =
(* It turns out that sometimes files appear and disappear very quickly. Just
Expand Down Expand Up @@ -511,6 +511,13 @@ let reducer
if noflow file then { info with Docblock.flow = Some Docblock.OptOut }
else info
in
let info = match jsx_pragma with
| Some jsx_pragma ->
let padding = (String.make 1 '\n') ^ (String.make 1 ' ') in
let (jsx_expr, _) = Parser_flow.jsx_pragma_expression (padding ^ jsx_pragma) (Some file) in
{ info with Docblock.jsx = Some (Docblock.Jsx_pragma (jsx_pragma, jsx_expr)) }
| None -> info
in
begin match (do_parse ~parse_options ~info content file) with
| Parse_ok parse_ok ->
let ast, file_sig = basic parse_ok in
Expand Down Expand Up @@ -588,13 +595,13 @@ let next_of_filename_set ?(with_progress=false) workers filenames =
else MultiWorkerLwt.next workers (FilenameSet.elements filenames)

let parse ~worker_mutator ~reader ~parse_options ~skip_hash_mismatch ~profile
~max_header_tokens ~noflow ~parse_unchanged workers next
~max_header_tokens ~noflow ~jsx_pragma ~parse_unchanged workers next
: results Lwt.t =
let t = Unix.gettimeofday () in
let reducer =
reducer
~worker_mutator ~reader ~parse_options ~skip_hash_mismatch
~max_header_tokens ~noflow ~parse_unchanged
~max_header_tokens ~noflow ~jsx_pragma ~parse_unchanged
in
let%lwt results = MultiWorkerLwt.call
workers
Expand All @@ -618,15 +625,15 @@ let parse ~worker_mutator ~reader ~parse_options ~skip_hash_mismatch ~profile
Lwt.return results

let reparse
~transaction ~reader ~parse_options ~profile ~max_header_tokens ~noflow
~transaction ~reader ~parse_options ~profile ~max_header_tokens ~noflow ~jsx_pragma
~parse_unchanged ~with_progress ~workers ~modified:files ~deleted =
(* save old parsing info for files *)
let all_files = FilenameSet.union files deleted in
let master_mutator, worker_mutator = Parsing_heaps.Reparse_mutator.create transaction all_files in
let next = next_of_filename_set ?with_progress workers files in
let%lwt results =
parse ~worker_mutator ~reader ~parse_options ~skip_hash_mismatch:false ~profile
~max_header_tokens ~noflow ~parse_unchanged workers next
~max_header_tokens ~noflow ~jsx_pragma ~parse_unchanged workers next
in
let modified = results.parse_ok |> FilenameMap.keys |> FilenameSet.of_list in
let modified = List.fold_left (fun acc (fail, _, _) ->
Expand All @@ -648,6 +655,7 @@ let parse_with_defaults ?types_mode ?use_strict ~reader options workers next =
in
let module_ref_prefix = Options.haste_module_ref_prefix options in
let facebook_fbt = Options.facebook_fbt options in
let jsx_pragma = Options.jsx_pragma options in
let arch = options.Options.opt_arch in
let parse_options =
make_parse_options ~arch ~types_mode ~use_strict ~module_ref_prefix ~facebook_fbt ()
Expand All @@ -657,7 +665,7 @@ let parse_with_defaults ?types_mode ?use_strict ~reader options workers next =
let worker_mutator = Parsing_heaps.Parse_mutator.create () in
parse
~worker_mutator ~reader ~parse_options ~skip_hash_mismatch:false
~profile ~max_header_tokens ~noflow ~parse_unchanged workers next
~profile ~max_header_tokens ~noflow ~jsx_pragma ~parse_unchanged workers next

let reparse_with_defaults
~transaction ~reader ?types_mode ?use_strict ?with_progress
Expand All @@ -668,12 +676,13 @@ let reparse_with_defaults
let module_ref_prefix = Options.haste_module_ref_prefix options in
let parse_unchanged = false in (* We're rechecking, so let's skip files which haven't changed *)
let facebook_fbt = Options.facebook_fbt options in
let jsx_pragma = Options.jsx_pragma options in
let arch = options.Options.opt_arch in
let parse_options =
make_parse_options ~arch ~types_mode ~use_strict ~module_ref_prefix ~facebook_fbt ()
in
reparse
~transaction ~reader ~parse_options ~profile ~max_header_tokens ~noflow
~transaction ~reader ~parse_options ~profile ~max_header_tokens ~noflow ~jsx_pragma
~parse_unchanged ~with_progress ~workers ~modified ~deleted

(* ensure_parsed takes a set of files, finds the files which haven't been parsed, and parses them.
Expand Down Expand Up @@ -710,6 +719,7 @@ let ensure_parsed ~reader options workers files =
MultiWorkerLwt.next ~progress_fn workers (FilenameSet.elements files_missing_asts)
in
let facebook_fbt = Options.facebook_fbt options in
let jsx_pragma = Options.jsx_pragma options in
let arch = options.Options.opt_arch in

let parse_options =
Expand All @@ -718,7 +728,7 @@ let ensure_parsed ~reader options workers files =

let%lwt results = parse
~worker_mutator ~reader ~parse_options ~skip_hash_mismatch:true
~profile ~max_header_tokens ~noflow ~parse_unchanged workers next
~profile ~max_header_tokens ~noflow ~jsx_pragma ~parse_unchanged workers next
in

Lwt.return results.parse_hash_mismatch_skips
2 changes: 2 additions & 0 deletions tests/jsx_pragma_option/.flowconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[options]
jsx.pragma=bar
10 changes: 10 additions & 0 deletions tests/jsx_pragma_option/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//@flow

import { bar } from './jsx'


// ok
const Hello = <hello a="nice" />;

// error
const Bye = <a />;
5 changes: 5 additions & 0 deletions tests/jsx_pragma_option/jsx.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//@flow

declare export var bar: {
(type: 'hello', props: {|a: string|}, children: any): {| hello: 'div' |}
}
24 changes: 24 additions & 0 deletions tests/jsx_pragma_option/jsx_pragma_option.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Error --------------------------------------------------------------------------------------------------- index.js:10:13

Cannot create `a` element because:
- `a` [1] is incompatible with string literal `hello` [2].
- inexact null [3] is incompatible with exact object type [4].

index.js:10:13
10| const Bye = <a />;
^^^^^ [3]

References:
index.js:10:14
10| const Bye = <a />;
^ [1]
jsx.js:4:10
4| (type: 'hello', props: {|a: string|}, children: any): {| hello: 'div' |}
^^^^^^^ [2]
jsx.js:4:26
4| (type: 'hello', props: {|a: string|}, children: any): {| hello: 'div' |}
^^^^^^^^^^^^^ [4]



Found 2 errors

0 comments on commit cb025b2

Please sign in to comment.