Expose ObjcProtoAspect to Skylark.

RELNOTES: None.
PiperOrigin-RevId: 179737025
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java
index d6c795f..23d353c 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java
@@ -314,12 +314,7 @@
       List<SkylarkAspect> aspects =
           ((SkylarkList<?>) obj).getContents(SkylarkAspect.class, "aspects");
       for (SkylarkAspect aspect : aspects) {
-        if (!aspect.isExported()) {
-          throw new EvalException(
-              ast.getLocation(),
-              "Aspects should be top-level values in extension files that define them.");
-        }
-        builder.aspect(aspect, ast.getLocation());
+        aspect.attachToAttribute(builder, ast.getLocation());
       }
     }
 
@@ -748,7 +743,7 @@
         named = true,
         positional = false,
         doc = ASPECTS_ARG_DOC
-      )
+      ),
     },
     useAst = true,
     useEnvironment = true
@@ -1059,7 +1054,7 @@
         named = true,
         positional = false,
         doc = ASPECTS_ARG_DOC
-      )
+      ),
     },
     useAst = true,
     useEnvironment = true
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
index 82370f1..350e98d 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
@@ -69,6 +69,7 @@
 import com.google.devtools.build.lib.packages.RuleFactory.InvalidRuleException;
 import com.google.devtools.build.lib.packages.RuleFunction;
 import com.google.devtools.build.lib.packages.SkylarkAspect;
+import com.google.devtools.build.lib.packages.SkylarkDefinedAspect;
 import com.google.devtools.build.lib.packages.SkylarkExportable;
 import com.google.devtools.build.lib.packages.SkylarkProvider;
 import com.google.devtools.build.lib.packages.TargetUtils;
@@ -795,8 +796,7 @@
                       EvalUtils.getDataTypeName(o, true)));
             }
           }
-
-          return new SkylarkAspect(
+          return new SkylarkDefinedAspect(
               implementation,
               attrAspects.build(),
               attributes.build(),
@@ -926,11 +926,12 @@
    * All classes of values that need special processing after they are exported from an extension
    * file.
    *
-   * <p>Order in list is significant: all {@link SkylarkAspect}s need to be exported before {@link
-   * SkylarkRuleFunction}s etc.
+   * <p>Order in list is significant: all {@link SkylarkDefinedAspect}s need to be exported before
+   * {@link SkylarkRuleFunction}s etc.
    */
   private static final ImmutableList<Class<? extends SkylarkExportable>> EXPORTABLES =
-      ImmutableList.of(SkylarkProvider.class, SkylarkAspect.class, SkylarkRuleFunction.class);
+      ImmutableList.of(
+          SkylarkProvider.class, SkylarkDefinedAspect.class, SkylarkRuleFunction.class);
 
   @SkylarkSignature(
     name = "Label",
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
index 0995d5f..1acd502 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
@@ -530,8 +530,13 @@
         public void init(Builder builder) {
           String toolsRepository = checkNotNull(builder.getToolsRepository());
 
+          // objc_proto_library should go into a separate RuleSet!
+          // TODO(ulfjack): Depending on objcProtoAspect from here is a layering violation.
+          ObjcProtoAspect objcProtoAspect = new ObjcProtoAspect();
+
           builder.addBuildInfoFactory(new ObjcBuildInfoFactory());
-          builder.addSkylarkAccessibleTopLevels("apple_common", new AppleSkylarkCommon());
+          builder.addSkylarkAccessibleTopLevels(
+              "apple_common", new AppleSkylarkCommon(objcProtoAspect));
 
           builder.addConfig(ObjcCommandLineOptions.class, new ObjcConfigurationLoader());
           builder.addConfig(AppleCommandLineOptions.class, new AppleConfiguration.Loader());
@@ -539,9 +544,6 @@
           // j2objc shouldn't be here!
           builder.addConfig(J2ObjcCommandLineOptions.class, new J2ObjcConfiguration.Loader());
 
-          // objc_proto_library should go into a separate RuleSet!
-          // TODO(ulfjack): Depending on objcProtoAspect from here is a layering violation.
-          ObjcProtoAspect objcProtoAspect = new ObjcProtoAspect();
           builder.addNativeAspectClass(objcProtoAspect);
           builder.addRuleDefinition(new AppleBinaryRule(objcProtoAspect));
           builder.addRuleDefinition(new AppleStaticLibraryRule(objcProtoAspect));
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Attribute.java b/src/main/java/com/google/devtools/build/lib/packages/Attribute.java
index 6d96a92..9877ea4 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Attribute.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Attribute.java
@@ -112,9 +112,9 @@
   }
 
   private static class SkylarkRuleAspect extends RuleAspect<SkylarkAspectClass> {
-    private final SkylarkAspect aspect;
+    private final SkylarkDefinedAspect aspect;
 
-    public SkylarkRuleAspect(SkylarkAspect aspect) {
+    public SkylarkRuleAspect(SkylarkDefinedAspect aspect) {
       super(aspect.getAspectClass(), aspect.getDefaultParametersExtractor());
       this.aspect = aspect;
     }
@@ -1003,8 +1003,8 @@
       return this.aspect(aspect, input -> AspectParameters.EMPTY);
     }
 
-    public Builder<TYPE> aspect(
-        SkylarkAspect skylarkAspect, Location location) throws EvalException {
+    public Builder<TYPE> aspect(SkylarkDefinedAspect skylarkAspect, Location location)
+        throws EvalException {
       SkylarkRuleAspect skylarkRuleAspect = new SkylarkRuleAspect(skylarkAspect);
       RuleAspect<?> oldAspect = this.aspects.put(skylarkAspect.getName(), skylarkRuleAspect);
       if (oldAspect != null) {
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkAspect.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkAspect.java
index 7e187d2..b8fed99 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/SkylarkAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkAspect.java
@@ -1,4 +1,4 @@
-// Copyright 2016 The Bazel Authors. All rights reserved.
+// 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.
@@ -14,21 +14,14 @@
 
 package com.google.devtools.build.lib.packages;
 
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
-import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
-import com.google.devtools.build.lib.syntax.BaseFunction;
-import com.google.devtools.build.lib.syntax.Environment;
-import com.google.devtools.build.lib.syntax.Type;
-import java.util.Arrays;
-import java.util.List;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
+import com.google.devtools.build.lib.syntax.EvalException;
 
-/** A Skylark value that is a result of an 'aspect(..)' function call. */
+/** Represents an aspect which can be attached to a skylark-defined rule attribute. */
 @SkylarkModule(
   name = "Aspect",
   category = SkylarkModuleCategory.NONE,
@@ -37,165 +30,23 @@
           + "documentation of the aspect function</a> or the "
           + "<a href=\"../aspects.md\">introduction to Aspects</a>."
 )
-public class SkylarkAspect implements SkylarkExportable {
-  private final BaseFunction implementation;
-  private final ImmutableList<String> attributeAspects;
-  private final ImmutableList<Attribute> attributes;
-  private final ImmutableList<ImmutableSet<SkylarkProviderIdentifier>> requiredAspectProviders;
-  private final ImmutableSet<SkylarkProviderIdentifier> provides;
-  private final ImmutableSet<String> paramAttributes;
-  private final ImmutableSet<String> fragments;
-  private final ImmutableSet<String> hostFragments;
-  private final ImmutableList<Label> requiredToolchains;
+public interface SkylarkAspect extends SkylarkValue {
 
-  private final Environment funcallEnv;
-  private SkylarkAspectClass aspectClass;
+  /**
+   * Attaches this aspect to an attribute.
+   *
+   * @param attrBuilder the builder of the attribute to add this aspect to
+   * @param loc the location in skylark which adds this aspect to an attribute
+   * @throws EvalException if this aspect cannot be successfully applied to the given attribute
+   */
+  void attachToAttribute(Attribute.Builder<?> attrBuilder, Location loc) throws EvalException;
 
-  public SkylarkAspect(
-      BaseFunction implementation,
-      ImmutableList<String> attributeAspects,
-      ImmutableList<Attribute> attributes,
-      ImmutableList<ImmutableSet<SkylarkProviderIdentifier>> requiredAspectProviders,
-      ImmutableSet<SkylarkProviderIdentifier> provides,
-      ImmutableSet<String> paramAttributes,
-      ImmutableSet<String> fragments,
-      ImmutableSet<String> hostFragments,
-      ImmutableList<Label> requiredToolchains,
-      Environment funcallEnv) {
-    this.implementation = implementation;
-    this.attributeAspects = attributeAspects;
-    this.attributes = attributes;
-    this.requiredAspectProviders = requiredAspectProviders;
-    this.provides = provides;
-    this.paramAttributes = paramAttributes;
-    this.fragments = fragments;
-    this.hostFragments = hostFragments;
-    this.requiredToolchains = requiredToolchains;
-    this.funcallEnv = funcallEnv;
-  }
+  /** Returns the aspect class for this aspect. */
+  AspectClass getAspectClass();
 
-  public BaseFunction getImplementation() {
-    return implementation;
-  }
+  /** Returns a set of the names of parameters required to create this aspect. */
+  ImmutableSet<String> getParamAttributes();
 
-  public ImmutableList<String> getAttributeAspects() {
-    return attributeAspects;
-  }
-
-  public Environment getFuncallEnv() {
-    return funcallEnv;
-  }
-
-  public ImmutableList<Attribute> getAttributes() {
-    return attributes;
-  }
-
-  @Override
-  public boolean isImmutable() {
-    return implementation.isImmutable();
-  }
-
-  @Override
-  public void repr(SkylarkPrinter printer) {
-    printer.append("<aspect>");
-  }
-
-  public String getName() {
-    return getAspectClass().getName();
-  }
-
-  public SkylarkAspectClass getAspectClass() {
-    Preconditions.checkState(isExported());
-    return aspectClass;
-  }
-
-  public ImmutableSet<String> getParamAttributes() {
-    return paramAttributes;
-  }
-
-  @Override
-  public void export(Label extensionLabel, String name) {
-    Preconditions.checkArgument(!isExported());
-    this.aspectClass = new SkylarkAspectClass(extensionLabel, name);
-  }
-
-  private static final List<String> allAttrAspects = Arrays.asList("*");
-
-  public AspectDefinition getDefinition(AspectParameters aspectParams) {
-    AspectDefinition.Builder builder = new AspectDefinition.Builder(aspectClass);
-    if (allAttrAspects.equals(attributeAspects)) {
-      builder.propagateAlongAllAttributes();
-    } else {
-      for (String attributeAspect : attributeAspects) {
-        builder.propagateAlongAttribute(attributeAspect);
-      }
-    }
-    
-    for (Attribute attribute : attributes) {
-      Attribute attr = attribute;  // Might be reassigned.
-      if (!aspectParams.getAttribute(attr.getName()).isEmpty()) {
-        String value = aspectParams.getOnlyValueOfAttribute(attr.getName());
-        Preconditions.checkState(!Attribute.isImplicit(attr.getName()));
-        Preconditions.checkState(attr.getType() == Type.STRING);
-        Preconditions.checkArgument(aspectParams.getAttribute(attr.getName()).size() == 1,
-            String.format("Aspect %s parameter %s has %d values (must have exactly 1).",
-                          getName(),
-                          attr.getName(),
-                          aspectParams.getAttribute(attr.getName()).size()));
-        attr = attr.cloneBuilder(Type.STRING).value(value).build(attr.getName());
-      }
-      builder.add(attr);
-    }
-    builder.requireAspectsWithProviders(requiredAspectProviders);
-    ImmutableList.Builder<SkylarkProviderIdentifier> advertisedSkylarkProviders =
-        ImmutableList.builder();
-    for (SkylarkProviderIdentifier provider : provides) {
-      advertisedSkylarkProviders.add(provider);
-    }
-    builder.advertiseProvider(advertisedSkylarkProviders.build());
-    builder.requiresConfigurationFragmentsBySkylarkModuleName(fragments);
-    builder.requiresHostConfigurationFragmentsBySkylarkModuleName(hostFragments);
-    builder.addRequiredToolchains(requiredToolchains);
-    return builder.build();
-  }
-
-  @Override
-  public boolean isExported() {
-    return aspectClass != null;
-  }
-
-  public Function<Rule, AspectParameters> getDefaultParametersExtractor() {
-    return rule -> {
-      AttributeMap ruleAttrs = RawAttributeMapper.of(rule);
-      AspectParameters.Builder builder = new AspectParameters.Builder();
-      for (Attribute aspectAttr : attributes) {
-        if (!Attribute.isImplicit(aspectAttr.getName())) {
-          String param = aspectAttr.getName();
-          Attribute ruleAttr = ruleAttrs.getAttributeDefinition(param);
-          if (paramAttributes.contains(aspectAttr.getName())) {
-            // These are preconditions because if they are false, RuleFunction.call() should
-            // already have generated an error.
-            Preconditions.checkArgument(
-                ruleAttr != null,
-                String.format(
-                    "Cannot apply aspect %s to %s that does not define attribute '%s'.",
-                    getName(), rule.getTargetKind(), param));
-            Preconditions.checkArgument(
-                ruleAttr.getType() == Type.STRING,
-                String.format(
-                    "Cannot apply aspect %s to %s with non-string attribute '%s'.",
-                    getName(), rule.getTargetKind(), param));
-          }
-          if (ruleAttr != null && ruleAttr.getType() == aspectAttr.getType()) {
-            builder.addAttribute(param, (String) ruleAttrs.get(param, ruleAttr.getType()));
-          }
-        }
-      }
-      return builder.build();
-    };
-  }
-
-  public ImmutableList<Label> getRequiredToolchains() {
-    return requiredToolchains;
-  }
+  /** Returns the name of this aspect. */
+  String getName();
 }
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkDefinedAspect.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkDefinedAspect.java
new file mode 100644
index 0000000..85aea03
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkDefinedAspect.java
@@ -0,0 +1,206 @@
+// Copyright 2016 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.packages;
+
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
+import com.google.devtools.build.lib.syntax.BaseFunction;
+import com.google.devtools.build.lib.syntax.Environment;
+import com.google.devtools.build.lib.syntax.EvalException;
+import com.google.devtools.build.lib.syntax.Type;
+import java.util.Arrays;
+import java.util.List;
+
+/** A Skylark value that is a result of an 'aspect(..)' function call. */
+public class SkylarkDefinedAspect implements SkylarkExportable, SkylarkAspect {
+  private final BaseFunction implementation;
+  private final ImmutableList<String> attributeAspects;
+  private final ImmutableList<Attribute> attributes;
+  private final ImmutableList<ImmutableSet<SkylarkProviderIdentifier>> requiredAspectProviders;
+  private final ImmutableSet<SkylarkProviderIdentifier> provides;
+  private final ImmutableSet<String> paramAttributes;
+  private final ImmutableSet<String> fragments;
+  private final ImmutableSet<String> hostFragments;
+  private final ImmutableList<Label> requiredToolchains;
+
+  private final Environment funcallEnv;
+  private SkylarkAspectClass aspectClass;
+
+  public SkylarkDefinedAspect(
+      BaseFunction implementation,
+      ImmutableList<String> attributeAspects,
+      ImmutableList<Attribute> attributes,
+      ImmutableList<ImmutableSet<SkylarkProviderIdentifier>> requiredAspectProviders,
+      ImmutableSet<SkylarkProviderIdentifier> provides,
+      ImmutableSet<String> paramAttributes,
+      ImmutableSet<String> fragments,
+      ImmutableSet<String> hostFragments,
+      ImmutableList<Label> requiredToolchains,
+      Environment funcallEnv) {
+    this.implementation = implementation;
+    this.attributeAspects = attributeAspects;
+    this.attributes = attributes;
+    this.requiredAspectProviders = requiredAspectProviders;
+    this.provides = provides;
+    this.paramAttributes = paramAttributes;
+    this.fragments = fragments;
+    this.hostFragments = hostFragments;
+    this.requiredToolchains = requiredToolchains;
+    this.funcallEnv = funcallEnv;
+  }
+
+  public BaseFunction getImplementation() {
+    return implementation;
+  }
+
+  public ImmutableList<String> getAttributeAspects() {
+    return attributeAspects;
+  }
+
+  public Environment getFuncallEnv() {
+    return funcallEnv;
+  }
+
+  public ImmutableList<Attribute> getAttributes() {
+    return attributes;
+  }
+
+  @Override
+  public boolean isImmutable() {
+    return implementation.isImmutable();
+  }
+
+  @Override
+  public void repr(SkylarkPrinter printer) {
+    printer.append("<aspect>");
+  }
+
+  @Override
+  public String getName() {
+    return getAspectClass().getName();
+  }
+
+  @Override
+  public SkylarkAspectClass getAspectClass() {
+    Preconditions.checkState(isExported());
+    return aspectClass;
+  }
+
+  @Override
+  public ImmutableSet<String> getParamAttributes() {
+    return paramAttributes;
+  }
+
+  @Override
+  public void export(Label extensionLabel, String name) {
+    Preconditions.checkArgument(!isExported());
+    this.aspectClass = new SkylarkAspectClass(extensionLabel, name);
+  }
+
+  private static final List<String> allAttrAspects = Arrays.asList("*");
+
+  public AspectDefinition getDefinition(AspectParameters aspectParams) {
+    AspectDefinition.Builder builder = new AspectDefinition.Builder(aspectClass);
+    if (allAttrAspects.equals(attributeAspects)) {
+      builder.propagateAlongAllAttributes();
+    } else {
+      for (String attributeAspect : attributeAspects) {
+        builder.propagateAlongAttribute(attributeAspect);
+      }
+    }
+    
+    for (Attribute attribute : attributes) {
+      Attribute attr = attribute;  // Might be reassigned.
+      if (!aspectParams.getAttribute(attr.getName()).isEmpty()) {
+        String value = aspectParams.getOnlyValueOfAttribute(attr.getName());
+        Preconditions.checkState(!Attribute.isImplicit(attr.getName()));
+        Preconditions.checkState(attr.getType() == Type.STRING);
+        Preconditions.checkArgument(aspectParams.getAttribute(attr.getName()).size() == 1,
+            String.format("Aspect %s parameter %s has %d values (must have exactly 1).",
+                          getName(),
+                          attr.getName(),
+                          aspectParams.getAttribute(attr.getName()).size()));
+        attr = attr.cloneBuilder(Type.STRING).value(value).build(attr.getName());
+      }
+      builder.add(attr);
+    }
+    builder.requireAspectsWithProviders(requiredAspectProviders);
+    ImmutableList.Builder<SkylarkProviderIdentifier> advertisedSkylarkProviders =
+        ImmutableList.builder();
+    for (SkylarkProviderIdentifier provider : provides) {
+      advertisedSkylarkProviders.add(provider);
+    }
+    builder.advertiseProvider(advertisedSkylarkProviders.build());
+    builder.requiresConfigurationFragmentsBySkylarkModuleName(fragments);
+    builder.requiresHostConfigurationFragmentsBySkylarkModuleName(hostFragments);
+    builder.addRequiredToolchains(requiredToolchains);
+    return builder.build();
+  }
+
+  @Override
+  public boolean isExported() {
+    return aspectClass != null;
+  }
+
+  public Function<Rule, AspectParameters> getDefaultParametersExtractor() {
+    return rule -> {
+      AttributeMap ruleAttrs = RawAttributeMapper.of(rule);
+      AspectParameters.Builder builder = new AspectParameters.Builder();
+      for (Attribute aspectAttr : attributes) {
+        if (!Attribute.isImplicit(aspectAttr.getName())) {
+          String param = aspectAttr.getName();
+          Attribute ruleAttr = ruleAttrs.getAttributeDefinition(param);
+          if (paramAttributes.contains(aspectAttr.getName())) {
+            // These are preconditions because if they are false, RuleFunction.call() should
+            // already have generated an error.
+            Preconditions.checkArgument(
+                ruleAttr != null,
+                String.format(
+                    "Cannot apply aspect %s to %s that does not define attribute '%s'.",
+                    getName(), rule.getTargetKind(), param));
+            Preconditions.checkArgument(
+                ruleAttr.getType() == Type.STRING,
+                String.format(
+                    "Cannot apply aspect %s to %s with non-string attribute '%s'.",
+                    getName(), rule.getTargetKind(), param));
+          }
+          if (ruleAttr != null && ruleAttr.getType() == aspectAttr.getType()) {
+            builder.addAttribute(param, (String) ruleAttrs.get(param, ruleAttr.getType()));
+          }
+        }
+      }
+      return builder.build();
+    };
+  }
+
+  public ImmutableList<Label> getRequiredToolchains() {
+    return requiredToolchains;
+  }
+
+  @Override
+  public void attachToAttribute(Attribute.Builder<?> attrBuilder, Location loc)
+      throws EvalException {
+    if (!isExported()) {
+      throw new EvalException(
+          loc, "Aspects should be top-level values in extension files that define them.");
+    }
+    attrBuilder.aspect(this, loc);
+  }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkNativeAspect.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkNativeAspect.java
new file mode 100644
index 0000000..4048b2f
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkNativeAspect.java
@@ -0,0 +1,42 @@
+// Copyright 2015 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.packages;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
+
+/** A natively-defined aspect that is may be referenced by skylark attribute definitions. */
+public abstract class SkylarkNativeAspect extends NativeAspectClass implements SkylarkAspect {
+  @Override
+  public void repr(SkylarkPrinter printer) {
+    printer.append("<native aspect>");
+  }
+
+  @Override
+  public void attachToAttribute(Attribute.Builder<?> attrBuilder, Location loc) {
+    attrBuilder.aspect(this);
+  }
+
+  @Override
+  public AspectClass getAspectClass() {
+    return this;
+  }
+
+  @Override
+  public ImmutableSet<String> getParamAttributes() {
+    return ImmutableSet.of();
+  }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java
index f9c20db..b679558 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java
@@ -24,6 +24,7 @@
 import com.google.devtools.build.lib.packages.Attribute.SplitTransitionProvider;
 import com.google.devtools.build.lib.packages.Info;
 import com.google.devtools.build.lib.packages.Provider;
+import com.google.devtools.build.lib.packages.SkylarkAspect;
 import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
 import com.google.devtools.build.lib.rules.apple.ApplePlatform;
 import com.google.devtools.build.lib.rules.apple.ApplePlatform.PlatformType;
@@ -80,6 +81,12 @@
   @Nullable private Info platformType;
   @Nullable private Info platform;
 
+  private ObjcProtoAspect objcProtoAspect;
+
+  public AppleSkylarkCommon(ObjcProtoAspect objcProtoAspect) {
+    this.objcProtoAspect = objcProtoAspect;
+  }
+
   @SkylarkCallable(
       name = "apple_toolchain",
       doc = "Utilities for resolving items from the apple toolchain."
@@ -538,6 +545,17 @@
         }
       };
 
+  @SkylarkCallable(
+    name = "objc_proto_aspect",
+    doc =
+        "objc_proto_aspect gathers the proto dependencies of the attached rule target,"
+            + "and propagates the proto values of its dependencies through the ObjcProto provider.",
+    structField = true
+  )
+  public SkylarkAspect getObjcProtoAspect() {
+    return objcProtoAspect;
+  }
+
   static {
     SkylarkSignatureProcessor.configureSkylarkFunctions(AppleSkylarkCommon.class);
   }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspect.java
index 5143484..4521672 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspect.java
@@ -28,14 +28,14 @@
 import com.google.devtools.build.lib.packages.AspectDefinition;
 import com.google.devtools.build.lib.packages.AspectParameters;
 import com.google.devtools.build.lib.packages.BuildType;
-import com.google.devtools.build.lib.packages.NativeAspectClass;
+import com.google.devtools.build.lib.packages.SkylarkNativeAspect;
 import com.google.devtools.build.lib.rules.proto.ProtoSourcesProvider;
 
 /**
  * Aspect that gathers the proto dependencies of the attached rule target, and propagates the proto
  * values of its dependencies through the ObjcProtoProvider.
  */
-public class ObjcProtoAspect extends NativeAspectClass implements ConfiguredAspectFactory {
+public class ObjcProtoAspect extends SkylarkNativeAspect implements ConfiguredAspectFactory {
   public static final String NAME = "ObjcProtoAspect";
 
   @Override
@@ -109,4 +109,9 @@
     }
     return aspectBuilder.build();
   }
+
+  @Override
+  public String getName() {
+    return NAME;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
index adc0b34..f3d47e3 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
@@ -51,6 +51,7 @@
 import com.google.devtools.build.lib.packages.RuleClassProvider;
 import com.google.devtools.build.lib.packages.SkylarkAspect;
 import com.google.devtools.build.lib.packages.SkylarkAspectClass;
+import com.google.devtools.build.lib.packages.SkylarkDefinedAspect;
 import com.google.devtools.build.lib.packages.Target;
 import com.google.devtools.build.lib.profiler.memory.CurrentRuleTracker;
 import com.google.devtools.build.lib.skyframe.AspectValue.AspectKey;
@@ -113,6 +114,30 @@
   }
 
   /**
+   * Load Skylark-defined aspect from an extension file. Is to be called from a SkyFunction.
+   *
+   * @return {@code null} if dependencies cannot be satisfied.
+   * @throws AspectCreationException if the value loaded is not a {@link SkylarkDefinedAspect}.
+   */
+  @Nullable
+  static SkylarkDefinedAspect loadSkylarkDefinedAspect(
+      Environment env, SkylarkAspectClass skylarkAspectClass)
+      throws AspectCreationException, InterruptedException {
+    Label extensionLabel = skylarkAspectClass.getExtensionLabel();
+    String skylarkValueName = skylarkAspectClass.getExportedName();
+
+    SkylarkAspect skylarkAspect = loadSkylarkAspect(env, extensionLabel, skylarkValueName);
+    if (!(skylarkAspect instanceof SkylarkDefinedAspect)) {
+      throw new AspectCreationException(
+          String.format(
+              "%s from %s is not a skylark-defined aspect",
+              skylarkValueName, extensionLabel.toString()));
+    } else {
+      return (SkylarkDefinedAspect) skylarkAspect;
+    }
+  }
+
+  /**
    * Load Skylark aspect from an extension file. Is to be called from a SkyFunction.
    *
    * @return {@code null} if dependencies cannot be satisfied.
@@ -164,11 +189,9 @@
       aspect = Aspect.forNative(nativeAspectClass, key.getParameters());
     } else if (key.getAspectClass() instanceof SkylarkAspectClass) {
       SkylarkAspectClass skylarkAspectClass = (SkylarkAspectClass) key.getAspectClass();
-      SkylarkAspect skylarkAspect;
+      SkylarkDefinedAspect skylarkAspect;
       try {
-        skylarkAspect =
-            loadSkylarkAspect(
-                env, skylarkAspectClass.getExtensionLabel(), skylarkAspectClass.getExportedName());
+        skylarkAspect = loadSkylarkDefinedAspect(env, skylarkAspectClass);
       } catch (AspectCreationException e) {
         throw new AspectFunctionException(e);
       }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java
index c2093a2..ca57cbc 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java
@@ -27,7 +27,7 @@
 import com.google.devtools.build.lib.packages.AspectDescriptor;
 import com.google.devtools.build.lib.packages.AspectParameters;
 import com.google.devtools.build.lib.packages.Info;
-import com.google.devtools.build.lib.packages.SkylarkAspect;
+import com.google.devtools.build.lib.packages.SkylarkDefinedAspect;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalException;
@@ -42,9 +42,9 @@
  */
 public class SkylarkAspectFactory implements ConfiguredAspectFactory {
 
-  private final SkylarkAspect skylarkAspect;
+  private final SkylarkDefinedAspect skylarkAspect;
 
-  public SkylarkAspectFactory(SkylarkAspect skylarkAspect) {
+  public SkylarkAspectFactory(SkylarkDefinedAspect skylarkAspect) {
     this.skylarkAspect = skylarkAspect;
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspectTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspectTest.java
index e0399b1..1197016 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspectTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspectTest.java
@@ -205,6 +205,52 @@
                 + "/x/_proto_filters/objc_proto_2/generated_filter_file.pbascii");
   }
 
+  @Test
+  public void testObjcProtoAspectPropagatesProviderThroughSkylarkRule() throws Exception {
+    scratch.file("test_skylark/BUILD");
+    scratch.file(
+        "test_skylark/top_level_stub.bzl",
+        "def top_level_stub_impl(ctx):",
+        "  deps = hasattr(ctx.attr.deps[0], 'ObjcProto')",
+        "  return struct(dep = ctx.attr.deps[0])",
+        "top_level_stub = rule(",
+        "    top_level_stub_impl,",
+        "    attrs = {",
+        "        'deps': attr.label_list(",
+        "             aspects=[apple_common.objc_proto_aspect],",
+        "        ),",
+        "    },",
+        "    fragments = ['apple'],",
+        ")");
+
+    scratch.file(
+        "x/BUILD",
+        "proto_library(",
+        "  name = 'protos',",
+        "  srcs = ['data.proto'],",
+        ")",
+        "objc_proto_library(",
+        "  name = 'x',",
+        "  deps = [':protos'],",
+        "  portable_proto_filters = ['data_filter.pbascii'],",
+        ")");
+
+    scratch.file(
+        "bin/BUILD",
+        "load('//test_skylark:top_level_stub.bzl', 'top_level_stub')",
+        "top_level_stub(",
+        "  name = 'link_target',",
+        "  deps = ['//x:x'],",
+        ")");
+
+    ConfiguredTarget topTarget = getConfiguredTarget("//bin:link_target");
+
+    ConfiguredTarget depTarget = (ConfiguredTarget) topTarget.get("dep");
+    ObjcProtoProvider objcProtoProvider = depTarget.get(ObjcProtoProvider.SKYLARK_CONSTRUCTOR);
+
+    assertThat(objcProtoProvider).isNotNull();
+  }
+
   private ConfiguredTarget getObjcProtoAspectConfiguredTarget(String label) throws Exception {
     scratch.file(
         "bin/BUILD",
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/BUILD b/src/test/java/com/google/devtools/build/lib/skylark/BUILD
index 525f9be..ca3ef36 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/skylark/BUILD
@@ -63,6 +63,7 @@
         "//src/main/java/com/google/devtools/build/lib/collect/nestedset",
         "//src/main/java/com/google/devtools/build/lib/concurrent",
         "//src/main/java/com/google/devtools/build/lib/rules/cpp",
+        "//src/main/java/com/google/devtools/build/lib/rules/objc",
         "//src/main/java/com/google/devtools/build/lib/vfs",
         "//src/main/java/com/google/devtools/build/skyframe",
         "//src/main/java/com/google/devtools/build/skyframe:skyframe-objects",
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkAspectsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkDefinedAspectsTest.java
similarity index 96%
rename from src/test/java/com/google/devtools/build/lib/skylark/SkylarkAspectsTest.java
rename to src/test/java/com/google/devtools/build/lib/skylark/SkylarkDefinedAspectsTest.java
index 1ad1699..a5353e1 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkAspectsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkDefinedAspectsTest.java
@@ -35,28 +35,38 @@
 import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition;
 import com.google.devtools.build.lib.packages.Info;
 import com.google.devtools.build.lib.packages.SkylarkProvider.SkylarkKey;
+import com.google.devtools.build.lib.packages.util.MockObjcSupport;
+import com.google.devtools.build.lib.packages.util.MockProtoSupport;
 import com.google.devtools.build.lib.rules.cpp.CppConfiguration;
 import com.google.devtools.build.lib.rules.java.Jvm;
+import com.google.devtools.build.lib.rules.objc.ObjcProtoProvider;
 import com.google.devtools.build.lib.skyframe.AspectValue;
 import com.google.devtools.build.lib.syntax.SkylarkList;
 import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
 import com.google.devtools.build.lib.vfs.FileSystemUtils;
 import java.util.Arrays;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
-/**
- * Tests for Skylark aspects
- */
+/** Tests for Skylark aspects */
 @RunWith(JUnit4.class)
-public class SkylarkAspectsTest extends AnalysisTestCase {
+public class SkylarkDefinedAspectsTest extends AnalysisTestCase {
   protected boolean keepGoing() {
     return false;
   }
 
   private static final String LINE_SEPARATOR = System.lineSeparator();
 
+  @Before
+  public final void initializeToolsConfigMock() throws Exception {
+    // Required for tests including the objc_library rule.
+    MockObjcSupport.setup(mockToolsConfig);
+    // Required for tests including the proto_library rule.
+    MockProtoSupport.setup(mockToolsConfig);
+  }
+
   @Test
   public void simpleAspect() throws Exception {
     scratch.file(
@@ -1165,7 +1175,7 @@
     }
     assertContainsEvent(
         "Extension file not found. Unable to load file '//test:aspect.bzl': "
-        + "file doesn't exist or isn't a file");
+            + "file doesn't exist or isn't a file");
   }
 
   @Test
@@ -1182,8 +1192,8 @@
     }
     assertContainsEvent(
         "Every .bzl file must have a corresponding package, but 'foo' does not have one. "
-        + "Please create a BUILD file in the same or any parent directory. "
-        + "Note that this BUILD file does not need to do anything except exist.");
+            + "Please create a BUILD file in the same or any parent directory. "
+            + "Note that this BUILD file does not need to do anything except exist.");
   }
 
   @Test
@@ -1214,9 +1224,9 @@
     } catch (Exception e) {
       // expect to fail.
     }
-    assertContainsEvent(//"ERROR /workspace/test/aspect.bzl:9:11: "
+    assertContainsEvent( // "ERROR /workspace/test/aspect.bzl:9:11: "
         "Aspect //test:aspect.bzl%MyAspectUncovered requires rule my_rule to specify attribute "
-        + "'my_attr' with type string.");
+            + "'my_attr' with type string.");
   }
 
   @Test
@@ -1235,7 +1245,7 @@
         "    implementation=_rule_impl,",
         "    attrs = { 'deps' : attr.label_list(aspects=[MyAspectMismatch]),",
         "              'my_attr' : attr.int() },",
-       ")");
+        ")");
     scratch.file("test/BUILD",
         "load('//test:aspect.bzl', 'my_rule')",
         "my_rule(name = 'xxx', my_attr = 4)");
@@ -1250,7 +1260,7 @@
     }
     assertContainsEvent(
         "Aspect //test:aspect.bzl%MyAspectMismatch requires rule my_rule to specify attribute "
-        + "'my_attr' with type string.");
+            + "'my_attr' with type string.");
   }
 
   @Test
@@ -1659,7 +1669,7 @@
   }
 
   @Test
-  public void sharedAttributeDefintionWithAspects() throws Exception {
+  public void sharedAttributeDefinitionWithAspects() throws Exception {
     scratch.file(
         "test/aspect.bzl",
         "def _aspect_impl(target,ctx):",
@@ -2104,7 +2114,7 @@
     }
     assertContainsEvent(
         "Aspect '//test:aspect.bzl%my_aspect', applied to '//test:xxx', "
-        + "does not provide advertised provider 'foo'");
+            + "does not provide advertised provider 'foo'");
   }
 
   @Test
@@ -2494,9 +2504,62 @@
             Label.parseAbsolute("//test:baz"));
   }
 
+  @Test
+  // This test verifies that aspects which are defined natively and exported for use in skylark
+  // can be referenced at the top level using the --aspects flag. For ease of testing,
+  // apple_common.objc_proto_aspect is used as an example.
+  public void testTopLevelSkylarkObjcProtoAspect() throws Exception {
+    scratch.file("test_skylark/BUILD");
+    scratch.file(
+        "test_skylark/top_level_stub.bzl",
+        "top_level_aspect = apple_common.objc_proto_aspect",
+        "",
+        "def top_level_stub_impl(ctx):",
+        "  return struct()",
+        "top_level_stub = rule(",
+        "    top_level_stub_impl,",
+        "    attrs = {",
+        "        'deps': attr.label_list(),",
+        "    },",
+        "    fragments = ['apple'],",
+        ")");
+
+    scratch.file(
+        "x/BUILD",
+        "proto_library(",
+        "  name = 'protos',",
+        "  srcs = ['data.proto'],",
+        ")",
+        "objc_proto_library(",
+        "  name = 'x',",
+        "  deps = [':protos'],",
+        "  portable_proto_filters = ['data_filter.pbascii'],",
+        ")");
+
+    scratch.file(
+        "bin/BUILD",
+        "load('//test_skylark:top_level_stub.bzl', 'top_level_stub')",
+        "top_level_stub(",
+        "  name = 'link_target',",
+        "  deps = ['//x:x'],",
+        ")");
+
+    useConfiguration(MockObjcSupport.requiredObjcCrosstoolFlags().toArray(new String[1]));
+    AnalysisResult analysisResult =
+        update(
+            ImmutableList.of("test_skylark/top_level_stub.bzl%top_level_aspect"),
+            "//bin:link_target");
+    ConfiguredAspect configuredAspect =
+        Iterables.getOnlyElement(analysisResult.getAspects()).getConfiguredAspect();
+
+    ObjcProtoProvider objcProtoProvider =
+        (ObjcProtoProvider) configuredAspect.get(ObjcProtoProvider.SKYLARK_CONSTRUCTOR.getKey());
+    assertThat(objcProtoProvider).isNotNull();
+  }
+
   /** SkylarkAspectTest with "keep going" flag */
   @RunWith(JUnit4.class)
-  public static final class WithKeepGoing extends SkylarkAspectsTest {
+  public static final class WithKeepGoing extends SkylarkDefinedAspectsTest {
     @Override
     protected FlagBuilder defaultFlags() {
       return new FlagBuilder().with(Flag.KEEP_GOING);
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
index d947562..202e289 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
@@ -40,8 +40,8 @@
 import com.google.devtools.build.lib.packages.RequiredProviders;
 import com.google.devtools.build.lib.packages.RuleClass;
 import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
-import com.google.devtools.build.lib.packages.SkylarkAspect;
 import com.google.devtools.build.lib.packages.SkylarkAspectClass;
+import com.google.devtools.build.lib.packages.SkylarkDefinedAspect;
 import com.google.devtools.build.lib.packages.SkylarkInfo;
 import com.google.devtools.build.lib.packages.SkylarkProvider;
 import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
@@ -321,7 +321,7 @@
             "my_aspect = aspect(implementation = _impl)",
             "a = attr.label_list(aspects = [my_aspect])");
     SkylarkAttr.Descriptor attr = (SkylarkAttr.Descriptor) ev.lookup("a");
-            SkylarkAspect aspect = (SkylarkAspect) ev.lookup("my_aspect");
+    SkylarkDefinedAspect aspect = (SkylarkDefinedAspect) ev.lookup("my_aspect");
     assertThat(aspect).isNotNull();
     assertThat(attr.build("xxx").getAspectClasses()).containsExactly(aspect.getAspectClass());
   }
@@ -334,7 +334,7 @@
         "my_aspect = aspect(implementation = _impl)",
         "a = attr.label(aspects = [my_aspect])");
     SkylarkAttr.Descriptor attr = (SkylarkAttr.Descriptor) ev.lookup("a");
-    SkylarkAspect aspect = (SkylarkAspect) ev.lookup("my_aspect");
+    SkylarkDefinedAspect aspect = (SkylarkDefinedAspect) ev.lookup("my_aspect");
     assertThat(aspect).isNotNull();
     assertThat(attr.build("xxx").getAspectClasses()).containsExactly(aspect.getAspectClass());
   }
@@ -358,7 +358,7 @@
         "my_aspect = aspect(_impl,",
         "   attrs = { '_extra_deps' : attr.label(default = Label('//foo/bar:baz')) }",
         ")");
-    SkylarkAspect aspect = (SkylarkAspect) ev.lookup("my_aspect");
+    SkylarkDefinedAspect aspect = (SkylarkDefinedAspect) ev.lookup("my_aspect");
     Attribute attribute = Iterables.getOnlyElement(aspect.getAttributes());
     assertThat(attribute.getName()).isEqualTo("$extra_deps");
     assertThat(attribute.getDefaultValue(null))
@@ -373,7 +373,7 @@
         "my_aspect = aspect(_impl,",
         "   attrs = { 'param' : attr.string(values=['a', 'b']) }",
         ")");
-    SkylarkAspect aspect = (SkylarkAspect) ev.lookup("my_aspect");
+    SkylarkDefinedAspect aspect = (SkylarkDefinedAspect) ev.lookup("my_aspect");
     Attribute attribute = Iterables.getOnlyElement(aspect.getAttributes());
     assertThat(attribute.getName()).isEqualTo("param");
   }
@@ -411,7 +411,7 @@
         "   attrs = { 'param' : attr.string(values=['a', 'b']),",
         "             '_extra' : attr.label(default = Label('//foo/bar:baz')) }",
         ")");
-    SkylarkAspect aspect = (SkylarkAspect) ev.lookup("my_aspect");
+    SkylarkDefinedAspect aspect = (SkylarkDefinedAspect) ev.lookup("my_aspect");
     assertThat(aspect.getAttributes()).hasSize(2);
     assertThat(aspect.getParamAttributes()).containsExactly("param");
   }
@@ -432,7 +432,7 @@
     scratch.file("test/BUILD", "toolchain_type(name = 'my_toolchain_type')");
     evalAndExport(
         "def _impl(ctx): pass", "a1 = aspect(_impl, toolchains=['//test:my_toolchain_type'])");
-    SkylarkAspect a = (SkylarkAspect) lookup("a1");
+    SkylarkDefinedAspect a = (SkylarkDefinedAspect) lookup("a1");
     assertThat(a.getRequiredToolchains()).containsExactly(makeLabel("//test:my_toolchain_type"));
   }
 
@@ -1327,7 +1327,7 @@
         "   pass",
         "my_aspect = aspect(_impl, attr_aspects=['*'])");
 
-    SkylarkAspect myAspect = (SkylarkAspect) lookup("my_aspect");
+    SkylarkDefinedAspect myAspect = (SkylarkDefinedAspect) lookup("my_aspect");
     assertThat(myAspect.getDefinition(AspectParameters.EMPTY).propagateAlong(
         Attribute.attr("foo", BuildType.LABEL).allowedFileTypes().build()
     )).isTrue();
@@ -1341,7 +1341,7 @@
         "cc = provider()",
         "my_aspect = aspect(_impl, required_aspect_providers=['java', cc])"
     );
-    SkylarkAspect myAspect = (SkylarkAspect) lookup("my_aspect");
+    SkylarkDefinedAspect myAspect = (SkylarkDefinedAspect) lookup("my_aspect");
     RequiredProviders requiredProviders = myAspect.getDefinition(AspectParameters.EMPTY)
         .getRequiredProvidersForAspects();
     assertThat(requiredProviders.isSatisfiedBy(AdvertisedProviderSet.ANY)).isTrue();
@@ -1367,7 +1367,7 @@
         "cc = provider()",
         "my_aspect = aspect(_impl, required_aspect_providers=[['java'], [cc]])"
     );
-    SkylarkAspect myAspect = (SkylarkAspect) lookup("my_aspect");
+    SkylarkDefinedAspect myAspect = (SkylarkDefinedAspect) lookup("my_aspect");
     RequiredProviders requiredProviders = myAspect.getDefinition(AspectParameters.EMPTY)
         .getRequiredProvidersForAspects();
     assertThat(requiredProviders.isSatisfiedBy(AdvertisedProviderSet.ANY)).isTrue();
@@ -1396,7 +1396,7 @@
         "   pass",
         "my_aspect = aspect(_impl, required_aspect_providers=[])"
     );
-    SkylarkAspect myAspect = (SkylarkAspect) lookup("my_aspect");
+    SkylarkDefinedAspect myAspect = (SkylarkDefinedAspect) lookup("my_aspect");
     RequiredProviders requiredProviders = myAspect.getDefinition(AspectParameters.EMPTY)
         .getRequiredProvidersForAspects();
     assertThat(requiredProviders.isSatisfiedBy(AdvertisedProviderSet.ANY)).isFalse();
@@ -1410,7 +1410,7 @@
         "   pass",
         "my_aspect = aspect(_impl)"
     );
-    SkylarkAspect myAspect = (SkylarkAspect) lookup("my_aspect");
+    SkylarkDefinedAspect myAspect = (SkylarkDefinedAspect) lookup("my_aspect");
     RequiredProviders requiredProviders = myAspect.getDefinition(AspectParameters.EMPTY)
         .getRequiredProvidersForAspects();
     assertThat(requiredProviders.isSatisfiedBy(AdvertisedProviderSet.ANY)).isFalse();
@@ -1425,7 +1425,7 @@
         "y = provider()",
         "my_aspect = aspect(_impl, provides = ['x', y])"
     );
-    SkylarkAspect myAspect = (SkylarkAspect) lookup("my_aspect");
+    SkylarkDefinedAspect myAspect = (SkylarkDefinedAspect) lookup("my_aspect");
     AdvertisedProviderSet advertisedProviders = myAspect.getDefinition(AspectParameters.EMPTY)
         .getAdvertisedProviders();
     assertThat(advertisedProviders.canHaveAnyProvider()).isFalse();
@@ -1476,7 +1476,7 @@
         "]"
     );
     SkylarkProvider p = (SkylarkProvider) lookup("p");
-    SkylarkAspect a = (SkylarkAspect) lookup("a");
+    SkylarkDefinedAspect a = (SkylarkDefinedAspect) lookup("a");
     SkylarkProvider p1 = (SkylarkProvider) lookup("p1");
     assertThat(p.getPrintableName()).isEqualTo("p");
     assertThat(p.getKey()).isEqualTo(new SkylarkProvider.SkylarkKey(FAKE_LABEL, "p"));