Implement aspect(...) Skylark function.

--
MOS_MIGRATED_REVID=105844221
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/Aspect.java b/src/main/java/com/google/devtools/build/lib/analysis/Aspect.java
index fe97bfc..bb6c38d 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/Aspect.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/Aspect.java
@@ -22,6 +22,7 @@
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import com.google.devtools.build.lib.events.Location;
 
 import java.util.LinkedHashMap;
 import java.util.Map;
@@ -88,6 +89,8 @@
     private final Map<Class<? extends TransitiveInfoProvider>, TransitiveInfoProvider>
         providers = new LinkedHashMap<>();
     private final Map<String, NestedSetBuilder<Artifact>> outputGroupBuilders = new TreeMap<>();
+    private final ImmutableMap.Builder<String, Object> skylarkProviderBuilder =
+        ImmutableMap.builder();
     private final String name;
 
     public Builder(String name) {
@@ -103,6 +106,8 @@
       Preconditions.checkNotNull(value);
       AnalysisUtils.checkProvider(key);
       Preconditions.checkState(!providers.containsKey(key));
+      Preconditions.checkArgument(!SkylarkProviders.class.equals(key),
+          "Do not provide SkylarkProviders directly");
       providers.put(key, value);
       return this;
     }
@@ -127,6 +132,12 @@
       return this;
     }
 
+    public Builder addSkylarkTransitiveInfo(String name, Object value, Location loc) {
+      // TODO(dslomov): add {@link RuleConfiguredTargetBuilder#checkSkylarkObjectSafe}
+      skylarkProviderBuilder.put(name, value);
+      return this;
+    }
+
     public Aspect build() {
       if (!outputGroupBuilders.isEmpty()) {
         ImmutableMap.Builder<String, NestedSet<Artifact>> outputGroups = ImmutableMap.builder();
@@ -141,6 +152,11 @@
         addProvider(OutputGroupProvider.class, new OutputGroupProvider(outputGroups.build()));
       }
 
+      ImmutableMap<String, Object> skylarkProvidersMap = skylarkProviderBuilder.build();
+      if (!skylarkProvidersMap.isEmpty()) {
+        providers.put(SkylarkProviders.class, new SkylarkProviders(skylarkProvidersMap));
+      }
+
       return new Aspect(name, ImmutableMap.copyOf(providers));
     }
   }