Add support for alias targets to cquery's `providers`

When applied to an `alias` target, the `providers` function of `cquery`'s `--output=starlark` mode now returns the providers of the aliased target rather than `None`.

This is achieved by moving `getProvidersDict` from `AbstractConfiguredTarget` up to `ConfiguredTarget`.

Fixes #17749

Closes #17753.

PiperOrigin-RevId: 516707744
Change-Id: I840588d605e3a64b968a019cf4bf43b56d18f4f5
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTarget.java
index 8fded0c..a53fea1 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTarget.java
@@ -20,6 +20,7 @@
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.skyframe.BuildConfigurationKey;
 import javax.annotation.Nullable;
+import net.starlark.java.eval.Dict;
 import net.starlark.java.eval.Structure;
 
 /**
@@ -110,4 +111,13 @@
   default ConfiguredTarget unwrapIfMerged() {
     return this;
   }
+
+  /**
+   * This is only intended to be called from the query dialects of Starlark.
+   *
+   * @return a map of provider names to their values
+   */
+  default Dict<String, Object> getProvidersDict() {
+    return null;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/configuredtargets/AbstractConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/configuredtargets/AbstractConfiguredTarget.java
index e5156c1..0c3330d 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/configuredtargets/AbstractConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/configuredtargets/AbstractConfiguredTarget.java
@@ -35,7 +35,6 @@
 import com.google.devtools.build.lib.skyframe.BuildConfigurationKey;
 import java.util.function.Consumer;
 import javax.annotation.Nullable;
-import net.starlark.java.eval.Dict;
 import net.starlark.java.eval.EvalException;
 import net.starlark.java.eval.Printer;
 import net.starlark.java.eval.Starlark;
@@ -255,12 +254,4 @@
   public void repr(Printer printer) {
     printer.append("<unknown target " + getLabel() + ">");
   }
-
-  /**
-   * Returns a map of provider names to their values. This is only intended to be called from the
-   * query dialects of Starlark. Implement in subclasses which can have providers.
-   */
-  public Dict<String, Object> getProvidersDict() {
-    return null;
-  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/query2/cquery/StarlarkOutputFormatterCallback.java b/src/main/java/com/google/devtools/build/lib/query2/cquery/StarlarkOutputFormatterCallback.java
index 267ec00..d107529 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/cquery/StarlarkOutputFormatterCallback.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/cquery/StarlarkOutputFormatterCallback.java
@@ -21,7 +21,6 @@
 import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
 import com.google.devtools.build.lib.analysis.config.BuildOptions;
 import com.google.devtools.build.lib.analysis.config.FragmentOptions;
-import com.google.devtools.build.lib.analysis.configuredtargets.AbstractConfiguredTarget;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.events.Event;
 import com.google.devtools.build.lib.events.ExtendedEventHandler;
@@ -121,10 +120,7 @@
           @Param(name = "target"),
         })
     public Object providers(ConfiguredTarget target) {
-      if (!(target instanceof AbstractConfiguredTarget)) {
-        return Starlark.NONE;
-      }
-      Dict<String, Object> ret = ((AbstractConfiguredTarget) target).getProvidersDict();
+      Dict<String, Object> ret = target.getProvidersDict();
       if (ret == null) {
         return Starlark.NONE;
       }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/AliasConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/rules/AliasConfiguredTarget.java
index 27148fa..1471171 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/AliasConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/AliasConfiguredTarget.java
@@ -38,6 +38,7 @@
 import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.skyframe.BuildConfigurationKey;
 import javax.annotation.Nullable;
+import net.starlark.java.eval.Dict;
 import net.starlark.java.eval.EvalException;
 import net.starlark.java.eval.Printer;
 import net.starlark.java.eval.StarlarkSemantics;
@@ -197,6 +198,11 @@
   }
 
   @Override
+  public Dict<String, Object> getProvidersDict() {
+    return actual.getProvidersDict();
+  }
+
+  @Override
   public void repr(Printer printer) {
     printer.append("<alias target " + label + " of " + actual.getLabel() + ">");
   }
diff --git a/src/test/shell/integration/configured_query_test.sh b/src/test/shell/integration/configured_query_test.sh
index 5e29340..8cf1271 100755
--- a/src/test/shell/integration/configured_query_test.sh
+++ b/src/test/shell/integration/configured_query_test.sh
@@ -1268,6 +1268,37 @@
   assert_contains "some_value" output
 }
 
+function test_starlark_output_providers_starlark_provider_for_alias() {
+  local -r pkg=$FUNCNAME
+  mkdir -p $pkg
+  cat > $pkg/BUILD <<EOF
+load(":my_rule.bzl", "my_rule")
+my_rule(name="myrule")
+alias(name="myalias", actual="myrule")
+EOF
+  cat > $pkg/my_rule.bzl <<'EOF'
+# A no-op rule that manifests a provider
+MyRuleInfo = provider(fields={"label": "a_rule_label"})
+
+def _my_rule_impl(ctx):
+    return [MyRuleInfo(label="some_value")]
+
+my_rule = rule(
+    implementation = _my_rule_impl,
+    attrs = {},
+)
+EOF
+  cat > $pkg/outfunc.bzl <<EOF
+def format(target):
+    p = providers(target)
+    return p["//$pkg:my_rule.bzl%MyRuleInfo"].label
+EOF
+  bazel cquery "//$pkg:myalias" --output=starlark --starlark:file="$pkg/outfunc.bzl" >output \
+    2>"$TEST_log" || fail "Expected success"
+
+  assert_contains "some_value" output
+}
+
 function test_bazelignore_error_cquery_nocrash() {
   local -r pkg=$FUNCNAME