@@ -5,6 +5,7 @@ use crate::eval::cache::Cache as EvalCache;
5
5
use crate :: eval:: Closure ;
6
6
#[ cfg( feature = "nix-experimental" ) ]
7
7
use crate :: nix_ffi;
8
+ use crate :: package:: { self , LockedPackageSource , ResolvedLockFile } ;
8
9
use crate :: parser:: { lexer:: Lexer , ErrorTolerantParser } ;
9
10
use crate :: position:: TermPos ;
10
11
use crate :: program:: FieldPath ;
@@ -75,6 +76,7 @@ impl InputFormat {
75
76
/// is, the operations that have been performed on this term) is stored in an [EntryState].
76
77
#[ derive( Debug , Clone ) ]
77
78
pub struct Cache {
79
+ // TODO: associate packages to file ids
78
80
/// The content of the program sources plus imports.
79
81
files : Files < String > ,
80
82
file_paths : HashMap < FileId , SourcePath > ,
@@ -86,6 +88,10 @@ pub struct Cache {
86
88
rev_imports : HashMap < FileId , HashSet < FileId > > ,
87
89
/// The table storing parsed terms corresponding to the entries of the file database.
88
90
terms : HashMap < FileId , TermEntry > ,
91
+ /// A table mapping FileIds to the package that they belong to.
92
+ ///
93
+ /// Path dependencies have already been canonicalized to absolute paths.
94
+ package : HashMap < FileId , LockedPackageSource > ,
89
95
/// The list of ids corresponding to the stdlib modules
90
96
stdlib_ids : Option < HashMap < StdlibModule , FileId > > ,
91
97
/// The inferred type of wildcards for each `FileId`.
@@ -94,6 +100,8 @@ pub struct Cache {
94
100
error_tolerance : ErrorTolerance ,
95
101
import_paths : Vec < PathBuf > ,
96
102
103
+ lock_file : ResolvedLockFile ,
104
+
97
105
#[ cfg( debug_assertions) ]
98
106
/// Skip loading the stdlib, used for debugging purpose
99
107
pub skip_stdlib : bool ,
@@ -338,9 +346,11 @@ impl Cache {
338
346
wildcards : HashMap :: new ( ) ,
339
347
imports : HashMap :: new ( ) ,
340
348
rev_imports : HashMap :: new ( ) ,
349
+ package : HashMap :: new ( ) ,
341
350
stdlib_ids : None ,
342
351
error_tolerance,
343
352
import_paths : Vec :: new ( ) ,
353
+ lock_file : ResolvedLockFile :: default ( ) ,
344
354
345
355
#[ cfg( debug_assertions) ]
346
356
skip_stdlib : false ,
@@ -354,6 +364,10 @@ impl Cache {
354
364
self . import_paths . extend ( paths. map ( PathBuf :: from) ) ;
355
365
}
356
366
367
+ pub fn set_lock_file ( & mut self , lock_file : ResolvedLockFile ) {
368
+ self . lock_file = lock_file;
369
+ }
370
+
357
371
/// Same as [Self::add_file], but assume that the path is already normalized, and take the
358
372
/// timestamp as a parameter.
359
373
fn add_file_ ( & mut self , path : PathBuf , timestamp : SystemTime ) -> io:: Result < FileId > {
@@ -1313,6 +1327,7 @@ pub trait ImportResolver {
1313
1327
& mut self ,
1314
1328
path : & OsStr ,
1315
1329
parent : Option < FileId > ,
1330
+ pkg : Option < & package:: Name > ,
1316
1331
pos : & TermPos ,
1317
1332
) -> Result < ( ResolvedTerm , FileId ) , ImportError > ;
1318
1333
@@ -1327,18 +1342,30 @@ impl ImportResolver for Cache {
1327
1342
& mut self ,
1328
1343
path : & OsStr ,
1329
1344
parent : Option < FileId > ,
1345
+ pkg : Option < & package:: Name > ,
1330
1346
pos : & TermPos ,
1331
1347
) -> Result < ( ResolvedTerm , FileId ) , ImportError > {
1332
- // `parent` is the file that did the import. We first look in its containing directory.
1333
- let mut parent_path = parent
1334
- . and_then ( |p| self . get_path ( p) )
1335
- . map ( PathBuf :: from)
1336
- . unwrap_or_default ( ) ;
1337
- parent_path. pop ( ) ;
1338
-
1339
- let possible_parents: Vec < PathBuf > = std:: iter:: once ( parent_path)
1340
- . chain ( self . import_paths . iter ( ) . cloned ( ) )
1341
- . collect ( ) ;
1348
+ let ( possible_parents, pkg_id) = if let Some ( pkg) = pkg {
1349
+ let pkg_id = self
1350
+ . lock_file
1351
+ . get ( parent. and_then ( |p| self . package . get ( & p) ) , pkg, pos) ?;
1352
+ ( vec ! [ pkg_id. local_path( ) ] , Some ( pkg_id. clone ( ) ) )
1353
+ } else {
1354
+ // `parent` is the file that did the import. We first look in its containing directory, followed by
1355
+ // the directories in the import path.
1356
+ let mut parent_path = parent
1357
+ . and_then ( |p| self . get_path ( p) )
1358
+ . map ( PathBuf :: from)
1359
+ . unwrap_or_default ( ) ;
1360
+ parent_path. pop ( ) ;
1361
+
1362
+ (
1363
+ std:: iter:: once ( parent_path)
1364
+ . chain ( self . import_paths . iter ( ) . cloned ( ) )
1365
+ . collect ( ) ,
1366
+ None ,
1367
+ )
1368
+ } ;
1342
1369
1343
1370
// Try to import from all possibilities, taking the first one that succeeds.
1344
1371
let ( id_op, path_buf) = possible_parents
@@ -1374,6 +1401,10 @@ impl ImportResolver for Cache {
1374
1401
self . parse_multi ( file_id, format)
1375
1402
. map_err ( |err| ImportError :: ParseErrors ( err, * pos) ) ?;
1376
1403
1404
+ if let Some ( pkg_id) = pkg_id {
1405
+ self . package . insert ( file_id, pkg_id) ;
1406
+ }
1407
+
1377
1408
Ok ( ( result, file_id) )
1378
1409
}
1379
1410
@@ -1414,7 +1445,7 @@ pub fn normalize_path(path: impl Into<PathBuf>) -> std::io::Result<PathBuf> {
1414
1445
/// [`std::fs::canonicalize`] can be hard to use correctly, since it can often
1415
1446
/// fail, or on Windows returns annoying device paths. This is a problem Cargo
1416
1447
/// needs to improve on.
1417
- fn normalize_abs_path ( path : & Path ) -> PathBuf {
1448
+ pub fn normalize_abs_path ( path : & Path ) -> PathBuf {
1418
1449
use std:: path:: Component ;
1419
1450
1420
1451
let mut components = path. components ( ) . peekable ( ) ;
@@ -1461,6 +1492,7 @@ pub mod resolvers {
1461
1492
& mut self ,
1462
1493
_path : & OsStr ,
1463
1494
_parent : Option < FileId > ,
1495
+ _pkg : Option < & package:: Name > ,
1464
1496
_pos : & TermPos ,
1465
1497
) -> Result < ( ResolvedTerm , FileId ) , ImportError > {
1466
1498
panic ! ( "cache::resolvers: dummy resolver should not have been invoked" ) ;
@@ -1502,6 +1534,7 @@ pub mod resolvers {
1502
1534
& mut self ,
1503
1535
path : & OsStr ,
1504
1536
_parent : Option < FileId > ,
1537
+ _pkg : Option < & package:: Name > ,
1505
1538
pos : & TermPos ,
1506
1539
) -> Result < ( ResolvedTerm , FileId ) , ImportError > {
1507
1540
let file_id = self
0 commit comments