Implement default provider

Default providers can now be used not only to return standard providers values
from a rule implementation function, but also to access these values provided
by other rules.
PiperOrigin-RevId: 152797193
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/AbstractConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/AbstractConfiguredTarget.java
index d32b279..f5313b8 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/AbstractConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/AbstractConfiguredTarget.java
@@ -16,7 +16,6 @@
 
 import com.google.common.collect.ImmutableCollection;
 import com.google.common.collect.ImmutableList;
-import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
@@ -27,10 +26,10 @@
 import com.google.devtools.build.lib.packages.PackageSpecification;
 import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
 import com.google.devtools.build.lib.packages.Target;
+import com.google.devtools.build.lib.rules.SkylarkRuleContext;
 import com.google.devtools.build.lib.syntax.ClassObject;
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.EvalUtils;
-import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
 import javax.annotation.Nullable;
 
 /**
@@ -108,19 +107,17 @@
 
   @Override
   public Object getValue(String name) {
+    // Standard fields should be proxied to their default provider object
+    DefaultProvider defaultProvider =
+        (DefaultProvider) get(SkylarkRuleContext.getDefaultProvider().getKey());
     switch (name) {
+      case FILES_FIELD:
+      case DEFAULT_RUNFILES_FIELD:
+      case DATA_RUNFILES_FIELD:
+      case FilesToRunProvider.SKYLARK_NAME:
+        return defaultProvider.getValue(name);
       case LABEL_FIELD:
         return getLabel();
-      case FILES_FIELD:
-        // A shortcut for files to build in Skylark. FileConfiguredTarget and RuleConfiguredTarget
-        // always has FileProvider and Error- and PackageGroupConfiguredTarget-s shouldn't be
-        // accessible in Skylark.
-        return SkylarkNestedSet.of(
-            Artifact.class, getProvider(FileProvider.class).getFilesToBuild());
-      case DEFAULT_RUNFILES_FIELD:
-        return RunfilesProvider.DEFAULT_RUNFILES.apply(this);
-      case DATA_RUNFILES_FIELD:
-        return RunfilesProvider.DATA_RUNFILES.apply(this);
       default:
         return get(name);
     }
@@ -173,6 +170,10 @@
   @Override
   public ImmutableCollection<String> getKeys() {
     return ImmutableList.of(
-        DATA_RUNFILES_FIELD, DEFAULT_RUNFILES_FIELD, LABEL_FIELD, FILES_FIELD);
+        DATA_RUNFILES_FIELD,
+        DEFAULT_RUNFILES_FIELD,
+        LABEL_FIELD,
+        FILES_FIELD,
+        FilesToRunProvider.SKYLARK_NAME);
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/DefaultProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/DefaultProvider.java
new file mode 100644
index 0000000..c0c2a31
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/analysis/DefaultProvider.java
@@ -0,0 +1,58 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.analysis;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import com.google.devtools.build.lib.packages.ClassObjectConstructor;
+import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.rules.SkylarkRuleContext;
+import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
+import java.util.Map;
+
+/** DefaultProvider is provided by all targets implicitly and contains all standard fields. */
+@Immutable
+public final class DefaultProvider extends SkylarkClassObject {
+
+  // Accessors for Skylark
+  private static final String DATA_RUNFILES_FIELD = "data_runfiles";
+  private static final String DEFAULT_RUNFILES_FIELD = "default_runfiles";
+  private static final String FILES_FIELD = "files";
+
+  private DefaultProvider(ClassObjectConstructor constructor, Map<String, Object> values) {
+    super(constructor, values);
+  }
+
+  public static DefaultProvider build(
+      RunfilesProvider runfilesProvider,
+      FileProvider fileProvider,
+      FilesToRunProvider filesToRunProvider) {
+    ImmutableMap.Builder<String, Object> attrBuilder = new ImmutableMap.Builder<>();
+    if (runfilesProvider != null) {
+      attrBuilder.put(DATA_RUNFILES_FIELD, runfilesProvider.getDataRunfiles());
+      attrBuilder.put(DEFAULT_RUNFILES_FIELD, runfilesProvider.getDefaultRunfiles());
+    } else {
+      attrBuilder.put(DATA_RUNFILES_FIELD, Runfiles.EMPTY);
+      attrBuilder.put(DEFAULT_RUNFILES_FIELD, Runfiles.EMPTY);
+    }
+
+    attrBuilder.put(
+        FILES_FIELD, SkylarkNestedSet.of(Artifact.class, fileProvider.getFilesToBuild()));
+    attrBuilder.put(FilesToRunProvider.SKYLARK_NAME, filesToRunProvider);
+
+    ClassObjectConstructor constructor = SkylarkRuleContext.getDefaultProvider();
+    return new DefaultProvider(constructor, attrBuilder.build());
+  }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/FileConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/FileConfiguredTarget.java
index 0bc9b53..0fe798b 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/FileConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/FileConfiguredTarget.java
@@ -14,6 +14,7 @@
 
 package com.google.devtools.build.lib.analysis;
 
+import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
@@ -21,6 +22,7 @@
 import com.google.devtools.build.lib.packages.ClassObjectConstructor;
 import com.google.devtools.build.lib.packages.FileTarget;
 import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.rules.SkylarkRuleContext;
 import com.google.devtools.build.lib.rules.fileset.FilesetProvider;
 import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider;
 import com.google.devtools.build.lib.util.FileType;
@@ -40,12 +42,22 @@
     super(targetContext);
     NestedSet<Artifact> filesToBuild = NestedSetBuilder.create(Order.STABLE_ORDER, artifact);
     this.artifact = artifact;
+    FileProvider fileProvider = new FileProvider(filesToBuild);
+    FilesToRunProvider filesToRunProvider =
+        FilesToRunProvider.fromSingleExecutableArtifact(artifact);
+    SkylarkClassObject defaultProvider =
+        DefaultProvider.build(null, fileProvider, filesToRunProvider);
+    SkylarkProviders skylarkProviders =
+        new SkylarkProviders(
+            ImmutableMap.<String, Object>of(),
+            ImmutableMap.of(SkylarkRuleContext.getDefaultProvider().getKey(), defaultProvider));
     TransitiveInfoProviderMap.Builder builder =
         TransitiveInfoProviderMap.builder()
             .put(VisibilityProvider.class, this)
             .put(LicensesProvider.class, this)
-            .add(new FileProvider(filesToBuild))
-            .add(FilesToRunProvider.fromSingleExecutableArtifact(artifact));
+            .put(SkylarkProviders.class, skylarkProviders)
+            .add(fileProvider)
+            .add(filesToRunProvider);
     if (this instanceof FilesetProvider) {
       builder.put(FilesetProvider.class, this);
     }
@@ -86,6 +98,6 @@
   @Nullable
   @Override
   public SkylarkClassObject get(ClassObjectConstructor.Key providerKey) {
-    return null;
+    return getProvider(SkylarkProviders.class).getDeclaredProvider(providerKey);
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/OutputGroupProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/OutputGroupProvider.java
index 51954c13..7ba2eff 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/OutputGroupProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/OutputGroupProvider.java
@@ -53,7 +53,7 @@
 @Immutable
 public final class OutputGroupProvider implements
     TransitiveInfoProvider, SkylarkIndexable, Iterable<String> {
-  public static String SKYLARK_NAME = "output_groups";
+  public static final String SKYLARK_NAME = "output_groups";
 
   /**
    * Prefix for output groups that are not reported to the user on the terminal output of Blaze when
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java
index 9bab046..077e2ec 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java
@@ -92,7 +92,6 @@
         getFilesToRun(runfilesSupport, filesToBuild), runfilesSupport, executable);
     addProvider(new FileProvider(filesToBuild));
     addProvider(filesToRunProvider);
-    addSkylarkTransitiveInfo(FilesToRunProvider.SKYLARK_NAME, filesToRunProvider);
 
     if (runfilesSupport != null) {
       // If a binary is built, build its runfiles, too
@@ -136,6 +135,14 @@
       addSkylarkTransitiveInfo(OutputGroupProvider.SKYLARK_NAME, outputGroupProvider);
     }
 
+    // Populate default provider fields and build it
+    DefaultProvider defaultProvider =
+        DefaultProvider.build(
+            providersBuilder.getProvider(RunfilesProvider.class),
+            providersBuilder.getProvider(FileProvider.class),
+            filesToRunProvider);
+    skylarkDeclaredProviders.put(defaultProvider.getConstructor().getKey(), defaultProvider);
+
     TransitiveInfoProviderMap providers = providersBuilder.build();
     addRegisteredProvidersToSkylarkProviders(providers);
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java
index c3f6954..6f0ac7f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java
@@ -13,7 +13,6 @@
 // limitations under the License.
 package com.google.devtools.build.lib.rules;
 
-import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.actions.Artifact;
@@ -270,7 +269,7 @@
     }
 
     if (!isParsed) {
-      addSimpleProviders(builder, ruleContext, loc, executable, null, null, null, null);
+      addSimpleProviders(builder, ruleContext, loc, executable, null, null, null);
     }
 
     try {
@@ -365,18 +364,19 @@
       }
     }
 
-    addSimpleProviders(builder, ruleContext, loc, executable, statelessRunfiles, dataRunfiles,
-        defaultRunfiles, (isDefaultProvider ? provider : null));
+    addSimpleProviders(
+        builder, ruleContext, loc, executable, statelessRunfiles, dataRunfiles, defaultRunfiles);
   }
 
-  private static void addSimpleProviders(RuleConfiguredTargetBuilder builder,
+  private static void addSimpleProviders(
+      RuleConfiguredTargetBuilder builder,
       RuleContext ruleContext,
       Location loc,
       Artifact executable,
       Runfiles statelessRunfiles,
       Runfiles dataRunfiles,
-      Runfiles defaultRunfiles,
-      SkylarkClassObject defaultProvider) throws EvalException {
+      Runfiles defaultRunfiles)
+      throws EvalException {
 
     if ((statelessRunfiles != null) && (dataRunfiles != null || defaultRunfiles != null)) {
       throw new EvalException(loc, "Cannot specify the provider 'runfiles' "
@@ -414,19 +414,6 @@
           ruleContext.getAnalysisEnvironment().getRegisteredActions());
       builder.addSkylarkDeclaredProvider(actions, loc);
     }
-
-    // Populate default provider fields and build it
-    ImmutableMap.Builder<String, Object> attrBuilder = new ImmutableMap.Builder<>();
-    // TODO: Add actual attributes that users expect to access from default providers
-    attrBuilder.put("runfiles", runfilesProvider);
-    SkylarkClassObject statelessDefaultProvider =
-        new SkylarkClassObject(
-            SkylarkRuleContext.getDefaultProvider(),
-            attrBuilder.build());
-
-    // Add the default provider
-    builder.addSkylarkDeclaredProvider(statelessDefaultProvider, (defaultProvider == null) ? loc
-        : Optional.fromNullable(defaultProvider.getCreationLocOrNull()).or(loc));
   }
 
   private static <T> T cast(String paramName, ClassObject struct, Class<T> expectedGenericType,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java
index 76ac1a9..de8d3de 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java
@@ -594,13 +594,19 @@
         }
       };
 
-  @SkylarkCallable(name = "default_provider", structField = true,
-      doc = "A provider that's provided by every rule, even if it's not returned explicitly. "
-          + "A <code>default_provider</code> accepts all special parameters that can be returned "
-          + "from rule implementation function in a struct, which are <code>runfiles</code>, "
-          + "<code>data_runfiles</code>, <code>default_runfiles</code>, "
-          + "<code>output_groups</code>, <code>instrumented_files</code>, and all "
-          + "<a href=\"skylark-provider.html\">providers</a> that are available on built-in rules.")
+  @SkylarkCallable(
+    name = "default_provider",
+    structField = true,
+    doc = "A provider that's provided by every rule, even if it's not returned explicitly. "
+        + "A <code>default_provider</code> accepts all special parameters that can be returned "
+        + "from rule implementation function in a struct, which are <code>runfiles</code>, "
+        + "<code>data_runfiles</code>, <code>default_runfiles</code>, "
+        + "<code>output_groups</code>, <code>instrumented_files</code>, and all "
+        + "<a href=\"skylark-provider.html\">providers</a> that are available on built-in rules. "
+        + "Each instance of the default provider contains the following standard fields: "
+        + "<code>data_runfiles</code>, <code>default_runfiles</code>, <code>files</code>, "
+        + "and <code>files_to_run</code>. The values of these fields are equivalent to the "
+        + "values of the corresponding fields of the target the default provider belongs to.")
   public static ClassObjectConstructor getDefaultProvider() {
     return DEFAULT_PROVIDER;
   }
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java
index 3954ecf..a1f8ed6 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java
@@ -30,8 +30,9 @@
 import com.google.devtools.build.lib.actions.RunfilesSupplier;
 import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
 import com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.analysis.DefaultProvider;
+import com.google.devtools.build.lib.analysis.FilesToRunProvider;
 import com.google.devtools.build.lib.analysis.Runfiles;
-import com.google.devtools.build.lib.analysis.RunfilesProvider;
 import com.google.devtools.build.lib.analysis.SkylarkProviders;
 import com.google.devtools.build.lib.analysis.actions.FileWriteAction;
 import com.google.devtools.build.lib.analysis.actions.SpawnAction;
@@ -864,38 +865,111 @@
         "test/bar.bzl",
         "load(':foo.bzl', 'foo_provider')",
         "def _impl(ctx):",
-        "    dep = ctx.attr.deps[0]",
-        "    provider = dep[ctx.default_provider]",  // The goal is to test this object
-        "    return struct(",                        // so we return it here
-        "        default = provider,",
+        "    provider = ctx.attr.deps[0][ctx.default_provider]",
+        "    return struct(",
+        "        provider = provider,",
+        "        dir = str(sorted(dir(provider))),",
+        "        rule_data_runfiles = provider.data_runfiles,",
+        "        rule_default_runfiles = provider.default_runfiles,",
+        "        rule_files = provider.files,",
+        "        rule_files_to_run = provider.files_to_run,",
         "    )",
         "bar_rule = rule(",
         "    implementation = _impl,",
         "    attrs = {",
         "       'deps': attr.label_list(allow_files=True),",
         "    }",
-        ")"
-    );
+        ")");
     scratch.file(
         "test/BUILD",
         "load(':foo.bzl', 'foo_rule')",
         "load(':bar.bzl', 'bar_rule')",
         "foo_rule(name = 'dep_rule', runs = ['run.file', 'run2.file'])",
-        "bar_rule(name = 'my_rule', deps = [':dep_rule'])");
+        "bar_rule(name = 'my_rule', deps = [':dep_rule', 'file.txt'])");
     ConfiguredTarget configuredTarget = getConfiguredTarget("//test:my_rule");
-    Object provider = configuredTarget.getProvider(SkylarkProviders.class).getValue("default");
-    assertThat(provider).isInstanceOf(SkylarkClassObject.class);
-    SkylarkClassObject defaultProvider = (SkylarkClassObject) provider;
-    assertThat((defaultProvider).getConstructor().getPrintableName())
+    SkylarkProviders providers = configuredTarget.getProvider(SkylarkProviders.class);
+
+    Object provider = providers.getValue("provider");
+    assertThat(provider).isInstanceOf(DefaultProvider.class);
+    assertThat(((DefaultProvider) provider).getConstructor().getPrintableName())
         .isEqualTo("default_provider");
 
-    // Test .runfiles
-    Object runfilesProvider = defaultProvider.getValue("runfiles");
-    assertThat(runfilesProvider).isInstanceOf(RunfilesProvider.class);
-    assertThat(Iterables.transform(
-        ((RunfilesProvider) runfilesProvider).getDefaultRunfiles().getAllArtifacts(), TO_STRING)
-    ).containsExactly("File:[/workspace[source]]test/run.file",
-        "File:[/workspace[source]]test/run2.file");
+    assertThat(providers.getValue("dir"))
+        .isEqualTo(
+            "[\"data_runfiles\", \"default_runfiles\", \"files\", \"files_to_run\", \"to_json\", "
+                + "\"to_proto\"]");
+
+    assertThat(providers.getValue("rule_data_runfiles")).isInstanceOf(Runfiles.class);
+    assertThat(
+            Iterables.transform(
+                ((Runfiles) providers.getValue("rule_data_runfiles")).getAllArtifacts(), TO_STRING))
+        .containsExactly(
+            "File:[/workspace[source]]test/run.file", "File:[/workspace[source]]test/run2.file");
+
+    assertThat(providers.getValue("rule_default_runfiles")).isInstanceOf(Runfiles.class);
+    assertThat(
+            Iterables.transform(
+                ((Runfiles) providers.getValue("rule_default_runfiles")).getAllArtifacts(),
+                TO_STRING))
+        .containsExactly(
+            "File:[/workspace[source]]test/run.file", "File:[/workspace[source]]test/run2.file");
+
+    assertThat(providers.getValue("rule_files")).isInstanceOf(SkylarkNestedSet.class);
+    assertThat(providers.getValue("rule_files_to_run")).isInstanceOf(FilesToRunProvider.class);
+  }
+
+  @Test
+  public void testDefaultProviderOnFileTarget() throws Exception {
+    scratch.file(
+        "test/bar.bzl",
+        "def _impl(ctx):",
+        "    provider = ctx.attr.deps[0][ctx.default_provider]",
+        "    return struct(",
+        "        provider = provider,",
+        "        dir = str(sorted(dir(provider))),",
+        "        file_data_runfiles = provider.data_runfiles,",
+        "        file_default_runfiles = provider.default_runfiles,",
+        "        file_files = provider.files,",
+        "        file_files_to_run = provider.files_to_run,",
+        "    )",
+        "bar_rule = rule(",
+        "    implementation = _impl,",
+        "    attrs = {",
+        "       'deps': attr.label_list(allow_files=True),",
+        "    }",
+        ")");
+    scratch.file(
+        "test/BUILD",
+        "load(':bar.bzl', 'bar_rule')",
+        "bar_rule(name = 'my_rule', deps = ['file.txt'])");
+    ConfiguredTarget configuredTarget = getConfiguredTarget("//test:my_rule");
+    SkylarkProviders providers = configuredTarget.getProvider(SkylarkProviders.class);
+
+    Object provider = providers.getValue("provider");
+    assertThat(provider).isInstanceOf(DefaultProvider.class);
+    assertThat(((DefaultProvider) provider).getConstructor().getPrintableName())
+        .isEqualTo("default_provider");
+
+    assertThat(providers.getValue("dir"))
+        .isEqualTo(
+            "[\"data_runfiles\", \"default_runfiles\", \"files\", \"files_to_run\", \"to_json\", "
+                + "\"to_proto\"]");
+
+    assertThat(providers.getValue("file_data_runfiles")).isInstanceOf(Runfiles.class);
+    assertThat(
+            Iterables.transform(
+                ((Runfiles) providers.getValue("file_data_runfiles")).getAllArtifacts(), TO_STRING))
+        .isEmpty();
+
+    assertThat(providers.getValue("file_default_runfiles")).isInstanceOf(Runfiles.class);
+    assertThat(
+            Iterables.transform(
+                ((Runfiles) providers.getValue("file_default_runfiles")).getAllArtifacts(),
+                TO_STRING))
+        .isEmpty();
+
+    assertThat(providers.getValue("file_files")).isInstanceOf(SkylarkNestedSet.class);
+    assertThat(providers.getValue("file_files_to_run")).isInstanceOf(FilesToRunProvider.class);
   }
 
   @Test
@@ -934,8 +1008,8 @@
         "bar_rule(name = 'my_rule', deps = [':dep_rule'])");
     ConfiguredTarget configuredTarget = getConfiguredTarget("//test:my_rule");
     Object provider = configuredTarget.getProvider(SkylarkProviders.class).getValue("default");
-    assertThat(provider).isInstanceOf(SkylarkClassObject.class);
-    SkylarkClassObject defaultProvider = (SkylarkClassObject) provider;
+    assertThat(provider).isInstanceOf(DefaultProvider.class);
+    SkylarkClassObject defaultProvider = (DefaultProvider) provider;
     assertThat((defaultProvider).getConstructor().getPrintableName())
         .isEqualTo("default_provider");
   }