Allow query output=location support relative_locations

RELNOTES: Querying with output=location now allows the relative_locations flag to properly display relative locations instead of the full path. Fixes https://github.com/bazelbuild/bazel/issues/3497.
PiperOrigin-RevId: 337477244
diff --git a/src/main/java/com/google/devtools/build/lib/query2/query/output/LocationOutputFormatter.java b/src/main/java/com/google/devtools/build/lib/query2/query/output/LocationOutputFormatter.java
index c0d964e..754bacd 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/query/output/LocationOutputFormatter.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/query/output/LocationOutputFormatter.java
@@ -15,8 +15,10 @@
 package com.google.devtools.build.lib.query2.query.output;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.hash.HashFunction;
 import com.google.devtools.build.lib.packages.Target;
 import com.google.devtools.build.lib.query2.common.AbstractBlazeQueryEnvironment;
+import com.google.devtools.build.lib.query2.common.CommonQueryOptions;
 import com.google.devtools.build.lib.query2.engine.AggregatingQueryExpressionVisitor.ContainsFunctionQueryExpressionVisitor;
 import com.google.devtools.build.lib.query2.engine.OutputFormatterCallback;
 import com.google.devtools.build.lib.query2.engine.QueryEnvironment;
@@ -24,10 +26,10 @@
 import com.google.devtools.build.lib.query2.engine.QueryExpression;
 import com.google.devtools.build.lib.query2.engine.SynchronizedDelegatingOutputFormatterCallback;
 import com.google.devtools.build.lib.query2.engine.ThreadSafeOutputFormatterCallback;
+import com.google.devtools.build.lib.query2.query.aspectresolvers.AspectResolver;
 import com.google.devtools.build.lib.server.FailureDetails.Query;
 import java.io.IOException;
 import java.io.OutputStream;
-import net.starlark.java.syntax.Location;
 
 /**
  * An output formatter that prints the labels of the targets, preceded by
@@ -37,12 +39,21 @@
  */
 class LocationOutputFormatter extends AbstractUnorderedFormatter {
 
+  private boolean relativeLocations;
+
   @Override
   public String getName() {
     return "location";
   }
 
   @Override
+  public void setOptions(
+      CommonQueryOptions options, AspectResolver aspectResolver, HashFunction hashFunction) {
+    super.setOptions(options, aspectResolver, hashFunction);
+    this.relativeLocations = options.relativeLocations;
+  }
+
+  @Override
   public void verifyCompatible(QueryEnvironment<?> env, QueryExpression expr)
       throws QueryException {
     if (!(env instanceof AbstractBlazeQueryEnvironment)) {
@@ -69,9 +80,8 @@
       public void processOutput(Iterable<Target> partialResult) throws IOException {
         final String lineTerm = options.getLineTerminator();
         for (Target target : partialResult) {
-          Location location = target.getLocation();
           writer
-              .append(location.toString())
+              .append(FormatUtils.getLocation(target, relativeLocations))
               .append(": ")
               .append(target.getTargetKind())
               .append(" ")
diff --git a/src/test/shell/integration/bazel_query_test.sh b/src/test/shell/integration/bazel_query_test.sh
index 9cc8730..7f50faa 100755
--- a/src/test/shell/integration/bazel_query_test.sh
+++ b/src/test/shell/integration/bazel_query_test.sh
@@ -479,6 +479,24 @@
   done
 }
 
+function test_location_output_relative_locations() {
+  rm -rf foo
+  mkdir -p foo
+  cat > foo/BUILD <<EOF
+sh_library(name='foo')
+EOF
+
+  bazel query --output=location '//foo' >& $TEST_log || fail "Expected success"
+  expect_log "${TEST_TMPDIR}/.*/foo/BUILD"
+  expect_log "//foo:foo"
+
+  bazel query --output=location --relative_locations '//foo' >& $TEST_log || fail "Expected success"
+  # Query with --relative_locations should not show full path
+  expect_not_log "${TEST_TMPDIR}/.*/foo/BUILD"
+  expect_log "^foo/BUILD"
+  expect_log "//foo:foo"
+}
+
 function test_subdirectory_named_external() {
   mkdir -p foo/external foo/bar
   cat > foo/external/BUILD <<EOF