1
1
use std:: {
2
- collections:: { BTreeMap , HashSet } ,
2
+ collections:: { BTreeMap , HashMap , HashSet } ,
3
3
sync:: Arc ,
4
4
} ;
5
5
@@ -10,8 +10,9 @@ use oxc_resolver::{ResolveError, Resolver, TsConfig};
10
10
use swc_common:: { comments:: SingleThreadedComments , SourceFile , Span } ;
11
11
use turbo_trace:: ImportType ;
12
12
use turbopath:: { AbsoluteSystemPath , AnchoredSystemPathBuf , PathRelation , RelativeUnixPath } ;
13
+ use turborepo_errors:: Spanned ;
13
14
use turborepo_repository:: {
14
- package_graph:: { PackageInfo , PackageName , PackageNode } ,
15
+ package_graph:: { PackageName , PackageNode } ,
15
16
package_json:: PackageJson ,
16
17
} ;
17
18
@@ -20,6 +21,64 @@ use crate::{
20
21
run:: Run ,
21
22
} ;
22
23
24
+ /// All the places a dependency can be declared
25
+ #[ derive( Clone , Copy ) ]
26
+ pub struct DependencyLocations < ' a > {
27
+ pub ( crate ) internal_dependencies : & ' a HashSet < & ' a PackageNode > ,
28
+ pub ( crate ) package_json : & ' a PackageJson ,
29
+ pub ( crate ) unresolved_external_dependencies : Option < & ' a BTreeMap < String , String > > ,
30
+ pub ( crate ) implicit_dependencies : & ' a HashMap < String , Spanned < ( ) > > ,
31
+ pub ( crate ) global_implicit_dependencies : & ' a HashMap < String , Spanned < ( ) > > ,
32
+ }
33
+
34
+ impl < ' a > DependencyLocations < ' a > {
35
+ /// Go through all the possible places a package could be declared to see if
36
+ /// it's a valid import. We don't use `oxc_resolver` because there are some
37
+ /// cases where you can resolve a package that isn't declared properly.
38
+ fn is_dependency ( & self , package_name : & PackageNode ) -> bool {
39
+ self . internal_dependencies . contains ( package_name)
40
+ || self
41
+ . unresolved_external_dependencies
42
+ . is_some_and ( |external_dependencies| {
43
+ external_dependencies. contains_key ( package_name. as_package_name ( ) . as_str ( ) )
44
+ } )
45
+ || self
46
+ . package_json
47
+ . dependencies
48
+ . as_ref ( )
49
+ . is_some_and ( |dependencies| {
50
+ dependencies. contains_key ( package_name. as_package_name ( ) . as_str ( ) )
51
+ } )
52
+ || self
53
+ . package_json
54
+ . dev_dependencies
55
+ . as_ref ( )
56
+ . is_some_and ( |dev_dependencies| {
57
+ dev_dependencies. contains_key ( package_name. as_package_name ( ) . as_str ( ) )
58
+ } )
59
+ || self
60
+ . package_json
61
+ . peer_dependencies
62
+ . as_ref ( )
63
+ . is_some_and ( |peer_dependencies| {
64
+ peer_dependencies. contains_key ( package_name. as_package_name ( ) . as_str ( ) )
65
+ } )
66
+ || self
67
+ . package_json
68
+ . optional_dependencies
69
+ . as_ref ( )
70
+ . is_some_and ( |optional_dependencies| {
71
+ optional_dependencies. contains_key ( package_name. as_package_name ( ) . as_str ( ) )
72
+ } )
73
+ || self
74
+ . implicit_dependencies
75
+ . contains_key ( package_name. as_package_name ( ) . as_str ( ) )
76
+ || self
77
+ . global_implicit_dependencies
78
+ . contains_key ( package_name. as_package_name ( ) . as_str ( ) )
79
+ }
80
+ }
81
+
23
82
impl Run {
24
83
/// Checks if the given import can be resolved as a tsconfig path alias,
25
84
/// e.g. `@/types/foo` -> `./src/foo`, and if so, checks the resolved paths.
@@ -79,9 +138,7 @@ impl Run {
79
138
span : & Span ,
80
139
file_path : & AbsoluteSystemPath ,
81
140
file_content : & str ,
82
- package_info : & PackageInfo ,
83
- internal_dependencies : & HashSet < & PackageNode > ,
84
- unresolved_external_dependencies : Option < & BTreeMap < String , String > > ,
141
+ dependency_locations : DependencyLocations < ' _ > ,
85
142
resolver : & Resolver ,
86
143
) -> Result < ( ) , Error > {
87
144
// If the import is prefixed with `@boundaries-ignore`, we ignore it, but print
@@ -154,9 +211,7 @@ impl Run {
154
211
span,
155
212
file_path,
156
213
file_content,
157
- & package_info. package_json ,
158
- internal_dependencies,
159
- unresolved_external_dependencies,
214
+ dependency_locations,
160
215
resolver,
161
216
)
162
217
} else {
@@ -207,45 +262,6 @@ impl Run {
207
262
}
208
263
}
209
264
210
- /// Go through all the possible places a package could be declared to see if
211
- /// it's a valid import. We don't use `oxc_resolver` because there are some
212
- /// cases where you can resolve a package that isn't declared properly.
213
- fn is_dependency (
214
- internal_dependencies : & HashSet < & PackageNode > ,
215
- package_json : & PackageJson ,
216
- unresolved_external_dependencies : Option < & BTreeMap < String , String > > ,
217
- package_name : & PackageNode ,
218
- ) -> bool {
219
- internal_dependencies. contains ( & package_name)
220
- || unresolved_external_dependencies. is_some_and ( |external_dependencies| {
221
- external_dependencies. contains_key ( package_name. as_package_name ( ) . as_str ( ) )
222
- } )
223
- || package_json
224
- . dependencies
225
- . as_ref ( )
226
- . is_some_and ( |dependencies| {
227
- dependencies. contains_key ( package_name. as_package_name ( ) . as_str ( ) )
228
- } )
229
- || package_json
230
- . dev_dependencies
231
- . as_ref ( )
232
- . is_some_and ( |dev_dependencies| {
233
- dev_dependencies. contains_key ( package_name. as_package_name ( ) . as_str ( ) )
234
- } )
235
- || package_json
236
- . peer_dependencies
237
- . as_ref ( )
238
- . is_some_and ( |peer_dependencies| {
239
- peer_dependencies. contains_key ( package_name. as_package_name ( ) . as_str ( ) )
240
- } )
241
- || package_json
242
- . optional_dependencies
243
- . as_ref ( )
244
- . is_some_and ( |optional_dependencies| {
245
- optional_dependencies. contains_key ( package_name. as_package_name ( ) . as_str ( ) )
246
- } )
247
- }
248
-
249
265
fn get_package_name ( import : & str ) -> String {
250
266
if import. starts_with ( "@" ) {
251
267
import. split ( '/' ) . take ( 2 ) . join ( "/" )
@@ -266,9 +282,7 @@ impl Run {
266
282
span : SourceSpan ,
267
283
file_path : & AbsoluteSystemPath ,
268
284
file_content : & str ,
269
- package_json : & PackageJson ,
270
- internal_dependencies : & HashSet < & PackageNode > ,
271
- unresolved_external_dependencies : Option < & BTreeMap < String , String > > ,
285
+ dependency_locations : DependencyLocations < ' _ > ,
272
286
resolver : & Resolver ,
273
287
) -> Option < BoundariesDiagnostic > {
274
288
let package_name = Self :: get_package_name ( import) ;
@@ -282,12 +296,7 @@ impl Run {
282
296
}
283
297
let package_name = PackageNode :: Workspace ( PackageName :: Other ( package_name) ) ;
284
298
let folder = file_path. parent ( ) . expect ( "file_path should have a parent" ) ;
285
- let is_valid_dependency = Self :: is_dependency (
286
- internal_dependencies,
287
- package_json,
288
- unresolved_external_dependencies,
289
- & package_name,
290
- ) ;
299
+ let is_valid_dependency = dependency_locations. is_dependency ( & package_name) ;
291
300
292
301
if !is_valid_dependency
293
302
&& !matches ! (
@@ -300,12 +309,7 @@ impl Run {
300
309
"@types/{}" ,
301
310
package_name. as_package_name( ) . as_str( )
302
311
) ) ) ;
303
- let is_types_dependency = Self :: is_dependency (
304
- internal_dependencies,
305
- package_json,
306
- unresolved_external_dependencies,
307
- & types_package_name,
308
- ) ;
312
+ let is_types_dependency = dependency_locations. is_dependency ( & types_package_name) ;
309
313
310
314
if is_types_dependency {
311
315
return match import_type {
0 commit comments