11use biome_rowan:: TextSize ;
22use oak_package_metadata:: namespace:: Namespace ;
33use salsa:: Setter ;
4+ use stdext:: SortedVec ;
45
56use crate :: tests:: test_db:: file_path;
67use crate :: tests:: test_db:: workspace_root;
@@ -10,6 +11,7 @@ use crate::Definition;
1011use crate :: File ;
1112use crate :: Package ;
1213use crate :: Root ;
14+ use crate :: RootKind ;
1315
1416fn make_file ( db : & mut TestDb , path : & str , contents : & str ) -> File {
1517 File :: new ( db, file_path ( path) , contents. to_string ( ) , None )
@@ -338,21 +340,36 @@ fn install_library_package(
338340 exports : & [ & str ] ,
339341 files : & [ ( & str , & str ) ] ,
340342) -> ( Root , Package ) {
341- use oak_package_metadata:: namespace:: Namespace ;
342- use stdext:: SortedVec ;
343-
344- use crate :: tests:: test_db:: library_root;
343+ install_package ( db, RootKind :: Library , name, exports, files)
344+ }
345345
346- let root = library_root ( db, & format ! ( "library/{name}" ) ) ;
346+ fn install_package (
347+ db : & mut TestDb ,
348+ kind : RootKind ,
349+ name : & str ,
350+ exports : & [ & str ] ,
351+ files : & [ ( & str , & str ) ] ,
352+ ) -> ( Root , Package ) {
353+ let ( prefix, version) = match kind {
354+ RootKind :: Library => ( "library" , Some ( "1.0.0" . to_string ( ) ) ) ,
355+ RootKind :: Workspace => ( "workspace" , None ) ,
356+ } ;
357+ let root = Root :: new (
358+ db,
359+ file_url ( & format ! ( "{prefix}/{name}" ) ) ,
360+ kind,
361+ vec ! [ ] ,
362+ vec ! [ ] ,
363+ ) ;
347364 let namespace = Namespace {
348365 exports : SortedVec :: from_vec ( exports. iter ( ) . map ( |s| s. to_string ( ) ) . collect ( ) ) ,
349366 ..Default :: default ( )
350367 } ;
351368 let pkg = Package :: new (
352369 db,
353- file_url ( & format ! ( "library /{name}/DESCRIPTION" ) ) ,
370+ file_url ( & format ! ( "{prefix} /{name}/DESCRIPTION" ) ) ,
354371 name. to_string ( ) ,
355- Some ( "1.0.0" . to_string ( ) ) ,
372+ version ,
356373 namespace,
357374 Vec :: new ( ) ,
358375 Vec :: new ( ) ,
@@ -364,7 +381,10 @@ fn install_library_package(
364381 . collect ( ) ;
365382 pkg. set_files ( db) . to ( pkg_files) ;
366383 root. set_packages ( db) . to ( vec ! [ pkg] ) ;
367- db. library_roots ( ) . set_roots ( db) . to ( vec ! [ root] ) ;
384+ match kind {
385+ RootKind :: Library => db. library_roots ( ) . set_roots ( db) . to ( vec ! [ root] ) ,
386+ RootKind :: Workspace => db. workspace_roots ( ) . set_roots ( db) . to ( vec ! [ root] ) ,
387+ } ;
368388 ( root, pkg)
369389}
370390
@@ -393,6 +413,31 @@ fn test_library_call_makes_pkg_export_resolve() {
393413 assert_eq ! ( def. name( & db) . text( & db) . as_str( ) , "foo" ) ;
394414}
395415
416+ #[ test]
417+ fn test_library_call_makes_workspace_pkg_export_resolve ( ) {
418+ // Same as `test_library_call_makes_pkg_export_resolve` but `mypkg` lives
419+ // in the workspace rather than an installed library. `package_by_name`
420+ // walks both workspace and library roots, so the resolution path is the
421+ // same for both.
422+ let mut db = TestDb :: new ( ) ;
423+ let ( _root, pkg) = install_package ( & mut db, RootKind :: Workspace , "mypkg" , & [ "foo" ] , & [ (
424+ "workspace/mypkg/R/a.R" ,
425+ "foo <- function() 42\n " ,
426+ ) ] ) ;
427+ let pkg_file = pkg. files ( & db) [ 0 ] ;
428+
429+ // Script is a floating file (no root registration needed for `imports()`
430+ // to find workspace packages via `package_by_name`).
431+ let source = "library(mypkg)\n foo\n " ;
432+ let script = make_file ( & mut db, "ws/script.R" , source) ;
433+
434+ let offset = TextSize :: from ( source. rfind ( "foo" ) . unwrap ( ) as u32 ) ;
435+ let def = resolve_one ( & db, script, offset) ;
436+
437+ assert_eq ! ( def. file( & db) , pkg_file) ;
438+ assert_eq ! ( def. name( & db) . text( & db) . as_str( ) , "foo" ) ;
439+ }
440+
396441#[ test]
397442fn test_namespace_import_pkg_makes_export_resolve_in_package_file ( ) {
398443 // A package file whose NAMESPACE has `import(extpkg)` can resolve
0 commit comments