Track empty directories with BAZEL_TRACK_SOURCE_DIRECTORIES

RecursiveFilesystemTraversalFunction did not emit a ResolvedFile for
empty directories and thus didn't track their existence at all since
they have no children that would track it implicitly.

This commit adds the tracking of empty directories for
DirectoryArtifactTraversalRequest only, which is used to implement the
BAZEL_TRACK_SOURCE_DIRECTORIES flag.

Also adds a basic test for the source directory tracking functionality.

Closes #15774.

PiperOrigin-RevId: 468804794
Change-Id: I2c06c05b335781234d4fa90f3d8c1e7fe6dd184a
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java
index a50cc3f..de37dd5 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java
@@ -620,6 +620,9 @@
       paths = NestedSetBuilder.<ResolvedFile>stableOrder().addTransitive(children).add(root);
     } else {
       root = ResolvedFileFactory.directory(rootInfo.realPath);
+      if (traversal.emitEmptyDirectoryNodes() && paths.isEmpty()) {
+        paths.add(root);
+      }
     }
     return RecursiveFilesystemTraversalValue.of(root, paths.build());
   }