Make absolute labels in remote repositories refer to the same repository by default.

If we do otherwise, this makes it impossible to seamlessly move code from the main repository to another one, because if two targets (one depending another) were moved, the dependency edge would still point back to the main repository.

--
MOS_MIGRATED_REVID=97650057
diff --git a/src/main/java/com/google/devtools/build/lib/packages/AbstractAttributeMapper.java b/src/main/java/com/google/devtools/build/lib/packages/AbstractAttributeMapper.java
index 906447b..52f78ab 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/AbstractAttributeMapper.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/AbstractAttributeMapper.java
@@ -16,6 +16,7 @@
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.syntax.Label;
+import com.google.devtools.build.lib.vfs.PathFragment;
 
 import javax.annotation.Nullable;
 
@@ -154,7 +155,20 @@
     Object value = get(attribute.getName(), type);
     if (value != null) { // null values are particularly possible for computed defaults.
       for (Label label : type.getLabels(value)) {
-        observer.acceptLabelAttribute(label, attribute);
+        Label absoluteLabel;
+        if (attribute.isImplicit() || attribute.isLateBound()) {
+          // Implicit dependencies are not usually present in remote repositories. They are
+          // generally tools, which go to the main repository.
+          absoluteLabel = label;
+        } else if (label.getPackageIdentifier().getRepository().isDefault()
+            && label.getPackageIdentifier().getPackageFragment().equals(
+                new PathFragment("visibility"))) {
+          // //visibility: labels must also be special-cased :(
+          absoluteLabel = label;
+        } else {
+          absoluteLabel = ruleLabel.resolveRepositoryRelative(label);
+        }
+        observer.acceptLabelAttribute(absoluteLabel, attribute);
       }
     }
   }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Label.java b/src/main/java/com/google/devtools/build/lib/syntax/Label.java
index 5a744c0f..61621b9 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Label.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Label.java
@@ -355,6 +355,30 @@
     }
   }
 
+  /**
+   * Resolves the repository of a label in the context of another label.
+   *
+   * <p>This is necessary so that dependency edges in remote repositories do not need to explicitly
+   * mention their repository name. Otherwise, referring to e.g. <code>//a:b</code> in a remote
+   * repository would point back to the main repository, which is usually not what is intended.
+   */
+  public Label resolveRepositoryRelative(Label relative) {
+    if (packageIdentifier.getRepository().isDefault()
+        || !relative.packageIdentifier.getRepository().isDefault()) {
+      return relative;
+    } else {
+      try {
+        return new Label(
+            new PackageIdentifier(packageIdentifier.getRepository(), relative.getPackageFragment()),
+            relative.getName());
+      } catch (Label.SyntaxException e) {
+        // We are creating the new label from an existing one which is guaranteed to be valid, so
+        // this can't happen
+        throw new IllegalStateException(e);
+      }
+    }
+  }
+
   @Override
   public int hashCode() {
     return name.hashCode() ^ packageIdentifier.hashCode();
diff --git a/src/test/shell/bazel/local_repository_test.sh b/src/test/shell/bazel/local_repository_test.sh
index 5a587e6..682245b 100755
--- a/src/test/shell/bazel/local_repository_test.sh
+++ b/src/test/shell/bazel/local_repository_test.sh
@@ -481,4 +481,39 @@
   assert_contains "Michaelangelo" bazel-genfiles/tmnt
 }
 
+function test_local_deps() {
+  local r=$TEST_TMPDIR/r
+  mkdir -p $r
+  cat > WORKSPACE <<EOF
+local_repository(
+    name = "r",
+    path = "$r",
+)
+
+EOF
+
+  mkdir -p $r/a
+  cat > $r/a/BUILD <<'EOF'
+genrule(
+    name = "a",
+    srcs = ["//b:b"],
+    outs = ["a.out"],
+    cmd = "cp $< $@",
+)
+EOF
+
+  mkdir -p $r/b
+  cat > $r/b/BUILD <<'EOF'
+genrule(
+    name = "b",
+    srcs = [],
+    outs = ["b.out"],
+    cmd = "echo SHOUT > $@",
+    visibility = ["//visibility:public"],
+)
+EOF
+
+  bazel build @r//a || fail "build failed"
+}
+
 run_suite "local repository tests"