@@ -687,6 +687,11 @@ pub fn getOrLoadHandle(store: *DocumentStore, uri: Uri) ?*Handle {
687687
688688 const file_contents = store .readUri (uri ) orelse return null ;
689689 return store .createAndStoreDocument (uri , file_contents , false ) catch | err | {
690+ store .lock .lock ();
691+ defer store .lock .unlock ();
692+
693+ _ = store .currently_loading_uris .swapRemove (uri );
694+
690695 log .err ("failed to store document '{s}': {}" , .{ uri , err });
691696 return null ;
692697 };
@@ -1366,8 +1371,6 @@ fn createAndStoreDocument(
13661371 self .allocator .destroy (old_handle );
13671372 }
13681373
1369- try self .loadDependencies (handle .import_uris .items );
1370-
13711374 if (isBuildFile (handle .uri )) {
13721375 log .debug ("Opened document '{s}' (build file)" , .{handle .uri });
13731376 } else {
@@ -1377,9 +1380,46 @@ fn createAndStoreDocument(
13771380 return handle ;
13781381}
13791382
1380- fn loadDependencies (store : * DocumentStore , import_uris : []const []const u8 ) ! void {
1381- var not_currently_loading_uris : std .ArrayListUnmanaged ([]const u8 ) =
1382- try .initCapacity (store .allocator , import_uris .len );
1383+ pub fn loadDirectoryRecursive (store : * DocumentStore , directory_uri : Uri ) ! void {
1384+ const workspace_path = try URI .parse (store .allocator , directory_uri );
1385+ defer store .allocator .free (workspace_path );
1386+
1387+ var workspace_dir = try std .fs .openDirAbsolute (workspace_path , .{ .iterate = true });
1388+ defer workspace_dir .close ();
1389+
1390+ var walker = try workspace_dir .walk (store .allocator );
1391+ defer walker .deinit ();
1392+
1393+ var uris : std .ArrayListUnmanaged ([]const u8 ) = .empty ;
1394+ defer uris .deinit (store .allocator );
1395+
1396+ {
1397+ errdefer {
1398+ for (uris .items ) | uri | {
1399+ store .allocator .free (uri );
1400+ }
1401+ }
1402+
1403+ while (try walker .next ()) | entry | {
1404+ if (std .mem .indexOf (u8 , entry .path , std .fs .path .sep_str ++ ".zig-cache" ++ std .fs .path .sep_str ) != null ) continue ;
1405+ if (std .mem .startsWith (u8 , entry .path , ".zig-cache" ++ std .fs .path .sep_str )) continue ;
1406+ if (! std .mem .eql (u8 , std .fs .path .extension (entry .basename ), ".zig" )) continue ;
1407+
1408+ const uri = try std .fs .path .join (store .allocator , &.{ workspace_path , entry .path });
1409+ defer store .allocator .free (uri );
1410+
1411+ _ = try uris .append (store .allocator , try URI .fromPath (store .allocator , uri ));
1412+ }
1413+ }
1414+
1415+ try store .loadManyUrisAtOnce (uris .items );
1416+ }
1417+
1418+ /// **Thread safe**
1419+ /// Takes ownership of uris
1420+ fn loadManyUrisAtOnce (store : * DocumentStore , uris : []const Uri ) ! void {
1421+ var not_currently_loading_uris : std .ArrayListUnmanaged (Uri ) =
1422+ try .initCapacity (store .allocator , uris .len );
13831423 defer {
13841424 not_currently_loading_uris .deinit (store .allocator );
13851425 }
@@ -1393,30 +1433,28 @@ fn loadDependencies(store: *DocumentStore, import_uris: []const []const u8) !voi
13931433 store .lock .lockShared ();
13941434 defer store .lock .unlockShared ();
13951435
1396- for (import_uris ) | import_uri | {
1397- if (! store .handles .contains (import_uri ) and
1398- ! store .currently_loading_uris .contains (import_uri ))
1436+ for (uris ) | uri | {
1437+ if (! store .handles .contains (uri ) and
1438+ ! store .currently_loading_uris .contains (uri ))
13991439 {
1400- not_currently_loading_uris .appendAssumeCapacity (
1401- try store .allocator .dupe (u8 , import_uri ),
1402- );
1440+ not_currently_loading_uris .appendAssumeCapacity (uri );
14031441 }
14041442 }
14051443 }
14061444
14071445 errdefer comptime unreachable ;
14081446
14091447 const S = struct {
1410- fn getOrLoadHandleVoid (s : * DocumentStore , duped_import_uri : Uri ) void {
1411- _ = s .getOrLoadHandle (duped_import_uri );
1412- defer s .allocator .free (duped_import_uri );
1448+ fn getOrLoadHandleVoid (s : * DocumentStore , uri : Uri ) void {
1449+ _ = s .getOrLoadHandle (uri );
1450+ defer s .allocator .free (uri );
14131451 }
14141452 };
14151453
1416- for (not_currently_loading_uris .items ) | duped_import_uri | {
1417- store .thread_pool .spawn (S .getOrLoadHandleVoid , .{ store , duped_import_uri }) catch {
1418- defer store .allocator .free (duped_import_uri );
1419- _ = store .getOrLoadHandle (duped_import_uri );
1454+ for (not_currently_loading_uris .items ) | uri | {
1455+ store .thread_pool .spawn (S .getOrLoadHandleVoid , .{ store , uri }) catch {
1456+ defer store .allocator .free (uri );
1457+ _ = store .getOrLoadHandle (uri );
14201458 };
14211459 }
14221460}
0 commit comments