7
7
8
8
use std:: path:: PathBuf ;
9
9
10
+ use fnv:: FnvBuildHasher ;
11
+ use indexmap:: IndexMap ;
10
12
use relay_typegen:: TypegenLanguage ;
11
13
use watchman_client:: prelude:: * ;
12
14
15
+ use crate :: compiler_state:: ProjectSet ;
13
16
use crate :: config:: Config ;
14
17
use crate :: config:: SchemaLocation ;
15
18
19
+ type FnvIndexMap < K , V > = IndexMap < K , V , FnvBuildHasher > ;
20
+
16
21
pub fn get_watchman_expr ( config : & Config ) -> Expr {
17
- let mut sources_conditions = vec ! [ expr_any(
18
- config
19
- . sources
20
- . iter( )
21
- . flat_map( |( path, project_set) | {
22
- project_set
23
- . iter( )
24
- . map( |name| ( path, & config. projects[ name] ) )
25
- . collect:: <Vec <_>>( )
26
- } )
27
- . map( |( path, project) | {
28
- Expr :: All ( vec![
29
- // Ending in *.js(x) or *.ts(x) depending on the project language.
30
- Expr :: Suffix ( match & project. typegen_config. language {
31
- TypegenLanguage :: Flow | TypegenLanguage :: JavaScript => {
32
- vec![ PathBuf :: from( "js" ) , PathBuf :: from( "jsx" ) ]
33
- }
34
- TypegenLanguage :: TypeScript => {
35
- vec![
36
- PathBuf :: from( "js" ) ,
37
- PathBuf :: from( "jsx" ) ,
38
- PathBuf :: from( "ts" ) ,
39
- PathBuf :: from( "tsx" ) ,
40
- ]
41
- }
42
- } ) ,
43
- // In the related source root.
44
- Expr :: DirName ( DirNameTerm {
45
- path: path. clone( ) ,
46
- depth: None ,
47
- } ) ,
48
- ] )
49
- } )
50
- . collect( ) ,
51
- ) ] ;
22
+ let mut sources_conditions = vec ! [ expr_any( get_sources_dir_exprs( config, & config. sources) ) ] ;
52
23
// not excluded by any glob
53
24
if !config. excludes . is_empty ( ) {
54
25
sources_conditions. push ( Expr :: Not ( Box :: new ( expr_any (
@@ -69,6 +40,11 @@ pub fn get_watchman_expr(config: &Config) -> Expr {
69
40
70
41
let mut expressions = vec ! [ sources_expr] ;
71
42
43
+ let generated_sources_dir_exprs = get_sources_dir_exprs ( config, & config. generated_sources ) ;
44
+ if !generated_sources_dir_exprs. is_empty ( ) {
45
+ expressions. push ( expr_any ( generated_sources_dir_exprs) ) ;
46
+ }
47
+
72
48
let output_dir_paths = get_output_dir_paths ( config) ;
73
49
if !output_dir_paths. is_empty ( ) {
74
50
let output_dir_expr = expr_files_in_dirs ( output_dir_paths) ;
@@ -103,17 +79,62 @@ pub fn get_watchman_expr(config: &Config) -> Expr {
103
79
] )
104
80
}
105
81
82
+ fn get_sources_dir_exprs (
83
+ config : & Config ,
84
+ paths_to_project : & FnvIndexMap < PathBuf , ProjectSet > ,
85
+ ) -> Vec < Expr > {
86
+ paths_to_project
87
+ . iter ( )
88
+ . flat_map ( |( path, project_set) | {
89
+ project_set
90
+ . iter ( )
91
+ . map ( |name| ( path, & config. projects [ name] ) )
92
+ . collect :: < Vec < _ > > ( )
93
+ } )
94
+ . map ( |( path, project) | {
95
+ Expr :: All ( vec ! [
96
+ // In the related source root.
97
+ Expr :: DirName ( DirNameTerm {
98
+ path: path. clone( ) ,
99
+ depth: None ,
100
+ } ) ,
101
+ // Match file extensions
102
+ get_project_file_ext_expr( project. typegen_config. language) ,
103
+ ] )
104
+ } )
105
+ . collect ( )
106
+ }
107
+
108
+ fn get_project_file_ext_expr ( typegen_language : TypegenLanguage ) -> Expr {
109
+ // Ending in *.js(x) or *.ts(x) depending on the project language.
110
+ Expr :: Suffix ( match & typegen_language {
111
+ TypegenLanguage :: Flow | TypegenLanguage :: JavaScript => {
112
+ vec ! [ PathBuf :: from( "js" ) , PathBuf :: from( "jsx" ) ]
113
+ }
114
+ TypegenLanguage :: TypeScript => {
115
+ vec ! [
116
+ PathBuf :: from( "js" ) ,
117
+ PathBuf :: from( "jsx" ) ,
118
+ PathBuf :: from( "ts" ) ,
119
+ PathBuf :: from( "tsx" ) ,
120
+ ]
121
+ }
122
+ } )
123
+ }
124
+
106
125
/// Compute all root paths that we need to query Watchman with. All files
107
126
/// relevant to the compiler should be in these directories.
108
127
pub fn get_all_roots ( config : & Config ) -> Vec < PathBuf > {
109
128
let source_roots = get_source_roots ( config) ;
129
+ let extra_sources_roots = get_generated_sources_roots ( config) ;
110
130
let output_roots = get_output_dir_paths ( config) ;
111
131
let extension_roots = get_extension_roots ( config) ;
112
132
let schema_file_roots = get_schema_file_roots ( config) ;
113
133
let schema_dir_roots = get_schema_dir_paths ( config) ;
114
134
unify_roots (
115
135
source_roots
116
136
. into_iter ( )
137
+ . chain ( extra_sources_roots)
117
138
. chain ( output_roots)
118
139
. chain ( extension_roots)
119
140
. chain ( schema_file_roots)
@@ -127,6 +148,11 @@ fn get_source_roots(config: &Config) -> Vec<PathBuf> {
127
148
config. sources . keys ( ) . cloned ( ) . collect ( )
128
149
}
129
150
151
+ /// Returns all root directories of JS source files for the config.
152
+ fn get_generated_sources_roots ( config : & Config ) -> Vec < PathBuf > {
153
+ config. generated_sources . keys ( ) . cloned ( ) . collect ( )
154
+ }
155
+
130
156
/// Returns all root directories of GraphQL schema extension files for the
131
157
/// config.
132
158
fn get_extension_roots ( config : & Config ) -> Vec < PathBuf > {
0 commit comments