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 Jul 9, 2019
1 parent 07679f6 commit 126d916
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/commands/commandUtils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,7 @@ let make_options ~flowconfig_name ~flowconfig ~lazy_mode ~root (options_flags: O
opt_recursion_limit = FlowConfig.recursion_limit flowconfig;
opt_max_files_checked_per_worker = FlowConfig.max_files_checked_per_worker flowconfig;
opt_type_asserts = FlowConfig.type_asserts 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 @@ -101,6 +101,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 @@ -192,6 +193,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 @@ -634,6 +636,9 @@ module Opts = struct

"experimental.types_first.max_files_checked_per_worker",
uint (fun opts v -> Ok { opts with max_files_checked_per_worker = v });

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

let parse =
Expand Down Expand Up @@ -1070,6 +1075,7 @@ let traces c = c.options.Opts.traces
let trust_mode c = c.options.Opts.trust_mode
let type_asserts c = c.options.Opts.type_asserts
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 @@ -95,6 +95,7 @@ val traces: config -> int
val trust_mode: config -> Options.trust_mode
val type_asserts: config -> bool
val types_first: config -> bool
val jsx_pragma: config -> string option
val wait_for_recheck: config -> bool
val weak: config -> bool

Expand Down
2 changes: 2 additions & 0 deletions src/common/options.ml
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ type t = {
opt_include_suppressions : bool;
opt_trust_mode: trust_mode;
opt_type_asserts: bool;
opt_jsx_pragma: string option;
}

let all opts = opts.opt_all
Expand Down Expand Up @@ -182,6 +183,7 @@ let strict_mode opts = opts.opt_strict_mode

let trust_mode opts = opts.opt_trust_mode
let type_asserts opts = opts.opt_type_asserts
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 @@ -472,7 +472,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 @@ -525,6 +525,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 @@ -602,13 +609,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 @@ -632,15 +639,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 @@ -664,6 +671,7 @@ let parse_with_defaults ?types_mode ?use_strict ~reader options workers next =
let facebook_fbt = Options.facebook_fbt options in
let arch = Options.arch options in
let abstract_locations = options.Options.opt_abstract_locations in
let jsx_pragma = Options.jsx_pragma options in
let parse_options =
make_parse_options ~arch ~abstract_locations ~types_mode ~use_strict ~module_ref_prefix
~facebook_fbt ()
Expand All @@ -673,7 +681,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 @@ -686,12 +694,13 @@ let reparse_with_defaults
let facebook_fbt = Options.facebook_fbt options in
let arch = Options.arch options in
let abstract_locations = options.Options.opt_abstract_locations in
let jsx_pragma = Options.jsx_pragma options in
let parse_options =
make_parse_options ~arch ~abstract_locations ~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 @@ -730,6 +739,7 @@ let ensure_parsed ~reader options workers files =
let facebook_fbt = Options.facebook_fbt options in
let arch = Options.arch options in
let abstract_locations = options.Options.opt_abstract_locations in
let jsx_pragma = Options.jsx_pragma options in

let parse_options =
make_parse_options ~types_mode ~use_strict ~module_ref_prefix ~facebook_fbt ~arch
Expand All @@ -738,7 +748,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 126d916

Please sign in to comment.