Skip to content

Commit cb025b2

Browse files
committed
Add global jsx pragma
1 parent a05cbb2 commit cb025b2

File tree

9 files changed

+70
-9
lines changed

9 files changed

+70
-9
lines changed

src/commands/commandUtils.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,6 +1083,7 @@ let make_options ~flowconfig_name ~flowconfig ~lazy_mode ~root (options_flags: O
10831083
opt_abstract_locations;
10841084
opt_include_suppressions = options_flags.include_suppressions;
10851085
opt_trust_mode = Option.value options_flags.trust_mode ~default:(FlowConfig.trust_mode flowconfig);
1086+
opt_jsx_pragma = FlowConfig.jsx_pragma flowconfig;
10861087
}
10871088

10881089
let make_env flowconfig_name connect_flags root =

src/commands/config/flowConfig.ml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ module Opts = struct
9797
types_first: bool;
9898
wait_for_recheck: bool;
9999
weak: bool;
100+
jsx_pragma: string option;
100101
}
101102

102103
let warn_on_unknown_opts (raw_opts, config) : (t * warning list, error) result =
@@ -184,6 +185,7 @@ module Opts = struct
184185
types_first = false;
185186
wait_for_recheck = false;
186187
weak = false;
188+
jsx_pragma = None;
187189
}
188190

189191
let parse_lines : line list -> (raw_options, error) result =
@@ -614,6 +616,9 @@ module Opts = struct
614616
("none", Options.NoTrust);
615617
]
616618
(fun opts trust_mode -> Ok { opts with trust_mode });
619+
620+
"jsx.pragma",
621+
string (fun opts v -> Ok { opts with jsx_pragma = Some v });
617622
]
618623

619624
let parse =
@@ -1046,6 +1051,7 @@ let temp_dir c = c.options.Opts.temp_dir
10461051
let traces c = c.options.Opts.traces
10471052
let trust_mode c = c.options.Opts.trust_mode
10481053
let types_first c = c.options.Opts.types_first
1054+
let jsx_pragma c = c.options.Opts.jsx_pragma
10491055
let required_version c = c.version
10501056
let wait_for_recheck c = c.options.Opts.wait_for_recheck
10511057
let weak c = c.options.Opts.weak

src/commands/config/flowConfig.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ val temp_dir: config -> string
9191
val traces: config -> int
9292
val trust_mode: config -> Options.trust_mode
9393
val types_first: config -> bool
94+
val jsx_pragma: config -> string option
9495
val wait_for_recheck: config -> bool
9596
val weak: config -> bool
9697

src/common/options.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ type t = {
112112
opt_strict_mode: StrictModeSettings.t;
113113
opt_arch: arch;
114114
opt_include_suppressions : bool;
115-
opt_trust_mode: trust_mode
115+
opt_trust_mode: trust_mode;
116+
opt_jsx_pragma: string option;
116117
}
117118

118119
let all opts = opts.opt_all
@@ -173,6 +174,7 @@ let lint_severities opts = opts.opt_lint_severities
173174
let strict_mode opts = opts.opt_strict_mode
174175

175176
let trust_mode opts = opts.opt_trust_mode
177+
let jsx_pragma opts = opts.opt_jsx_pragma
176178

177179

178180
let lazy_mode_to_string lazy_mode =

src/parsing/parsing_service_js.ml

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ let does_content_match_file_hash ~reader file content =
458458
* Add success/error info to passed accumulator. *)
459459
let reducer
460460
~worker_mutator ~reader ~parse_options ~skip_hash_mismatch
461-
~max_header_tokens ~noflow ~parse_unchanged
461+
~max_header_tokens ~noflow ~jsx_pragma ~parse_unchanged
462462
parse_results file
463463
: results =
464464
(* It turns out that sometimes files appear and disappear very quickly. Just
@@ -511,6 +511,13 @@ let reducer
511511
if noflow file then { info with Docblock.flow = Some Docblock.OptOut }
512512
else info
513513
in
514+
let info = match jsx_pragma with
515+
| Some jsx_pragma ->
516+
let padding = (String.make 1 '\n') ^ (String.make 1 ' ') in
517+
let (jsx_expr, _) = Parser_flow.jsx_pragma_expression (padding ^ jsx_pragma) (Some file) in
518+
{ info with Docblock.jsx = Some (Docblock.Jsx_pragma (jsx_pragma, jsx_expr)) }
519+
| None -> info
520+
in
514521
begin match (do_parse ~parse_options ~info content file) with
515522
| Parse_ok parse_ok ->
516523
let ast, file_sig = basic parse_ok in
@@ -588,13 +595,13 @@ let next_of_filename_set ?(with_progress=false) workers filenames =
588595
else MultiWorkerLwt.next workers (FilenameSet.elements filenames)
589596

590597
let parse ~worker_mutator ~reader ~parse_options ~skip_hash_mismatch ~profile
591-
~max_header_tokens ~noflow ~parse_unchanged workers next
598+
~max_header_tokens ~noflow ~jsx_pragma ~parse_unchanged workers next
592599
: results Lwt.t =
593600
let t = Unix.gettimeofday () in
594601
let reducer =
595602
reducer
596603
~worker_mutator ~reader ~parse_options ~skip_hash_mismatch
597-
~max_header_tokens ~noflow ~parse_unchanged
604+
~max_header_tokens ~noflow ~jsx_pragma ~parse_unchanged
598605
in
599606
let%lwt results = MultiWorkerLwt.call
600607
workers
@@ -618,15 +625,15 @@ let parse ~worker_mutator ~reader ~parse_options ~skip_hash_mismatch ~profile
618625
Lwt.return results
619626

620627
let reparse
621-
~transaction ~reader ~parse_options ~profile ~max_header_tokens ~noflow
628+
~transaction ~reader ~parse_options ~profile ~max_header_tokens ~noflow ~jsx_pragma
622629
~parse_unchanged ~with_progress ~workers ~modified:files ~deleted =
623630
(* save old parsing info for files *)
624631
let all_files = FilenameSet.union files deleted in
625632
let master_mutator, worker_mutator = Parsing_heaps.Reparse_mutator.create transaction all_files in
626633
let next = next_of_filename_set ?with_progress workers files in
627634
let%lwt results =
628635
parse ~worker_mutator ~reader ~parse_options ~skip_hash_mismatch:false ~profile
629-
~max_header_tokens ~noflow ~parse_unchanged workers next
636+
~max_header_tokens ~noflow ~jsx_pragma ~parse_unchanged workers next
630637
in
631638
let modified = results.parse_ok |> FilenameMap.keys |> FilenameSet.of_list in
632639
let modified = List.fold_left (fun acc (fail, _, _) ->
@@ -648,6 +655,7 @@ let parse_with_defaults ?types_mode ?use_strict ~reader options workers next =
648655
in
649656
let module_ref_prefix = Options.haste_module_ref_prefix options in
650657
let facebook_fbt = Options.facebook_fbt options in
658+
let jsx_pragma = Options.jsx_pragma options in
651659
let arch = options.Options.opt_arch in
652660
let parse_options =
653661
make_parse_options ~arch ~types_mode ~use_strict ~module_ref_prefix ~facebook_fbt ()
@@ -657,7 +665,7 @@ let parse_with_defaults ?types_mode ?use_strict ~reader options workers next =
657665
let worker_mutator = Parsing_heaps.Parse_mutator.create () in
658666
parse
659667
~worker_mutator ~reader ~parse_options ~skip_hash_mismatch:false
660-
~profile ~max_header_tokens ~noflow ~parse_unchanged workers next
668+
~profile ~max_header_tokens ~noflow ~jsx_pragma ~parse_unchanged workers next
661669

662670
let reparse_with_defaults
663671
~transaction ~reader ?types_mode ?use_strict ?with_progress
@@ -668,12 +676,13 @@ let reparse_with_defaults
668676
let module_ref_prefix = Options.haste_module_ref_prefix options in
669677
let parse_unchanged = false in (* We're rechecking, so let's skip files which haven't changed *)
670678
let facebook_fbt = Options.facebook_fbt options in
679+
let jsx_pragma = Options.jsx_pragma options in
671680
let arch = options.Options.opt_arch in
672681
let parse_options =
673682
make_parse_options ~arch ~types_mode ~use_strict ~module_ref_prefix ~facebook_fbt ()
674683
in
675684
reparse
676-
~transaction ~reader ~parse_options ~profile ~max_header_tokens ~noflow
685+
~transaction ~reader ~parse_options ~profile ~max_header_tokens ~noflow ~jsx_pragma
677686
~parse_unchanged ~with_progress ~workers ~modified ~deleted
678687

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

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

719729
let%lwt results = parse
720730
~worker_mutator ~reader ~parse_options ~skip_hash_mismatch:true
721-
~profile ~max_header_tokens ~noflow ~parse_unchanged workers next
731+
~profile ~max_header_tokens ~noflow ~jsx_pragma ~parse_unchanged workers next
722732
in
723733

724734
Lwt.return results.parse_hash_mismatch_skips
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[options]
2+
jsx.pragma=bar

tests/jsx_pragma_option/index.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//@flow
2+
3+
import { bar } from './jsx'
4+
5+
6+
// ok
7+
const Hello = <hello a="nice" />;
8+
9+
// error
10+
const Bye = <a />;

tests/jsx_pragma_option/jsx.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
//@flow
2+
3+
declare export var bar: {
4+
(type: 'hello', props: {|a: string|}, children: any): {| hello: 'div' |}
5+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Error --------------------------------------------------------------------------------------------------- index.js:10:13
2+
3+
Cannot create `a` element because:
4+
- `a` [1] is incompatible with string literal `hello` [2].
5+
- inexact null [3] is incompatible with exact object type [4].
6+
7+
index.js:10:13
8+
10| const Bye = <a />;
9+
^^^^^ [3]
10+
11+
References:
12+
index.js:10:14
13+
10| const Bye = <a />;
14+
^ [1]
15+
jsx.js:4:10
16+
4| (type: 'hello', props: {|a: string|}, children: any): {| hello: 'div' |}
17+
^^^^^^^ [2]
18+
jsx.js:4:26
19+
4| (type: 'hello', props: {|a: string|}, children: any): {| hello: 'div' |}
20+
^^^^^^^^^^^^^ [4]
21+
22+
23+
24+
Found 2 errors

0 commit comments

Comments
 (0)