Introduce an AspectClass: a representation of a class of aspects.

For native aspects, AspectClass is a facade for Class<AspectFactory<...>>.

--
MOS_MIGRATED_REVID=105986390
diff --git a/src/main/java/com/google/devtools/build/lib/packages/AspectClass.java b/src/main/java/com/google/devtools/build/lib/packages/AspectClass.java
new file mode 100644
index 0000000..9c82922
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/packages/AspectClass.java
@@ -0,0 +1,33 @@
+// 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;
+
+/**
+ *  A class of aspects.
+ *
+ *  <p>This interface serves as a factory for {@link AspectFactory}.
+ */
+public interface AspectClass {
+
+  /**
+   * Returns an aspect name.
+   */
+  String getName();
+
+  /**
+   * Instantiates an {@link AspectFactory} for this aspect class.
+   */
+  AspectFactory<?, ?, ?> newInstance();
+}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java b/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java
index 9bacb4a..a9c75d7 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java
@@ -55,13 +55,13 @@
   private final ImmutableSet<Class<?>> requiredProviders;
   private final ImmutableSet<String> requiredProviderNames;
   private final ImmutableMap<String, Attribute> attributes;
-  private final ImmutableMultimap<String, Class<? extends AspectFactory<?, ?, ?>>> attributeAspects;
+  private final ImmutableMultimap<String, AspectClass> attributeAspects;
 
   private AspectDefinition(
       String name,
       ImmutableSet<Class<?>> requiredProviders,
       ImmutableMap<String, Attribute> attributes,
-      ImmutableMultimap<String, Class<? extends AspectFactory<?, ?, ?>>> attributeAspects) {
+      ImmutableMultimap<String, AspectClass> attributeAspects) {
     this.name = name;
     this.requiredProviders = requiredProviders;
     this.requiredProviderNames = toStringSet(requiredProviders);
@@ -116,7 +116,7 @@
    * <p>Note that the map actually contains {@link AspectFactory}
    * instances, except that we cannot reference that class here.
    */
-  public ImmutableMultimap<String, Class<? extends AspectFactory<?, ?, ?>>> getAttributeAspects() {
+  public ImmutableMultimap<String, AspectClass> getAttributeAspects() {
     return attributeAspects;
   }
 
@@ -144,7 +144,7 @@
     }
 
     LinkedHashMultimap<Attribute, Label> result = LinkedHashMultimap.create();
-    for (Class<? extends AspectFactory<?, ?, ?>> candidateClass : attribute.getAspects()) {
+    for (AspectClass candidateClass : attribute.getAspects()) {
       AspectFactory<?, ?, ?> candidate = AspectFactory.Util.create(candidateClass);
       // Check if target satisfies condition for this aspect (has to provide all required
       // TransitiveInfoProviders)
@@ -195,8 +195,7 @@
     private final String name;
     private final Map<String, Attribute> attributes = new LinkedHashMap<>();
     private final Set<Class<?>> requiredProviders = new LinkedHashSet<>();
-    private final Multimap<String, Class<? extends AspectFactory<?, ?, ?>>> attributeAspects =
-        LinkedHashMultimap.create();
+    private final Multimap<String, AspectClass> attributeAspects = LinkedHashMultimap.create();
 
     public Builder(String name) {
       this.name = name;
@@ -223,7 +222,8 @@
         String attribute, Class<? extends AspectFactory<?, ?, ?>>... aspectFactories) {
       Preconditions.checkNotNull(attribute);
       for (Class<? extends AspectFactory<?, ?, ?>> aspectFactory : aspectFactories) {
-        this.attributeAspects.put(attribute, Preconditions.checkNotNull(aspectFactory));
+        this.attributeAspects.put(
+                attribute, new NativeAspectClass(Preconditions.checkNotNull(aspectFactory)));
       }
       return this;
     }
diff --git a/src/main/java/com/google/devtools/build/lib/packages/AspectFactory.java b/src/main/java/com/google/devtools/build/lib/packages/AspectFactory.java
index cd7ba2c..bbc1fea 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/AspectFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/AspectFactory.java
@@ -45,13 +45,10 @@
       // Should never be instantiated
     }
 
-    public static AspectFactory<?, ?, ?> create(Class<? extends AspectFactory<?, ?, ?>> clazz) {
+    public static AspectFactory<?, ?, ?> create(AspectClass aspectClass) {
       // TODO(bazel-team): This should be cached somehow, because this method is invoked quite often
-      try {
-        return clazz.newInstance();
-      } catch (Exception e) {
-        throw new IllegalStateException(e);
-      }
+
+      return aspectClass.newInstance();
     }
   }
 }
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 18dc41c..a987570 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
@@ -61,17 +61,15 @@
   public static final Predicate<RuleClass> NO_RULE = Predicates.alwaysFalse();
 
   private static final class RuleAspect {
-    private final Class<? extends AspectFactory<?, ?, ?>> aspectFactory;
+    private final AspectClass aspectFactory;
     private final Function<Rule, AspectParameters> parametersExtractor;
 
-    RuleAspect(
-        Class<? extends AspectFactory<?, ?, ?>> aspectFactory,
-        Function<Rule, AspectParameters> parametersExtractor) {
+    RuleAspect(AspectClass aspectFactory, Function<Rule, AspectParameters> parametersExtractor) {
       this.aspectFactory = aspectFactory;
       this.parametersExtractor = parametersExtractor;
     }
 
-    Class<? extends AspectFactory<?, ?, ?>> getAspectFactory() {
+    AspectClass getAspectFactory() {
       return aspectFactory;
     }
     
@@ -701,7 +699,7 @@
      */
     public Builder<TYPE> aspect(Class<? extends AspectFactory<?, ?, ?>> aspect,
         Function<Rule, AspectParameters> evaluator) {
-      this.aspects.add(new RuleAspect(aspect, evaluator));
+      this.aspects.add(new RuleAspect(new NativeAspectClass(aspect), evaluator));
       return this;
     }
 
@@ -1312,8 +1310,8 @@
   /**
    * Returns the set of aspects required for dependencies through this attribute.
    */
-  public ImmutableSet<Class<? extends AspectFactory<?, ?, ?>>> getAspects() {
-    ImmutableSet.Builder<Class<? extends AspectFactory<?, ?, ?>>> builder = ImmutableSet.builder();
+  public ImmutableSet<AspectClass> getAspects() {
+    ImmutableSet.Builder<AspectClass> builder = ImmutableSet.builder();
     for (RuleAspect aspect : aspects) {
       builder.add(aspect.getAspectFactory());
     }
@@ -1323,10 +1321,8 @@
   /**
    * Returns set of pairs of aspect factories and corresponding aspect parameters.
    */
-  public ImmutableMap<Class<? extends AspectFactory<?, ?, ?>>, AspectParameters>
-      getAspectsWithParameters(Rule rule) {
-    ImmutableMap.Builder<Class<? extends AspectFactory<?, ?, ?>>, AspectParameters> builder =
-        ImmutableMap.builder();
+  public ImmutableMap<AspectClass, AspectParameters> getAspectsWithParameters(Rule rule) {
+    ImmutableMap.Builder<AspectClass, AspectParameters> builder = ImmutableMap.builder();
     for (RuleAspect aspect : aspects) {
       builder.put(aspect.getAspectFactory(), aspect.getParametersExtractor().apply(rule));
     }
diff --git a/src/main/java/com/google/devtools/build/lib/packages/NativeAspectClass.java b/src/main/java/com/google/devtools/build/lib/packages/NativeAspectClass.java
new file mode 100644
index 0000000..66360c1
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/packages/NativeAspectClass.java
@@ -0,0 +1,56 @@
+// 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;
+
+/**
+ * A class of aspects that are implemented natively in Bazel.
+ *
+ * <p>This class just wraps a {@link java.lang.Class} implementing the
+ * aspect factory. All wrappers of the same class are
+ */
+public final class NativeAspectClass implements AspectClass {
+  private final Class<? extends AspectFactory<?, ?, ?>> nativeClass;
+
+  public NativeAspectClass(Class<? extends AspectFactory<?, ?, ?>> nativeClass) {
+    this.nativeClass = nativeClass;
+  }
+
+  @Override
+  public String getName() {
+    return nativeClass.getSimpleName();
+  }
+
+  @Override
+  public AspectFactory<?, ?, ?> newInstance() {
+    try {
+      return nativeClass.newInstance();
+    } catch (Exception e) {
+      throw new IllegalStateException(e);
+    }
+  }
+
+  @Override
+  public int hashCode() {
+    return nativeClass.hashCode();
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (!(obj instanceof NativeAspectClass)) {
+      return false;
+    }
+    return nativeClass.equals(((NativeAspectClass) obj).nativeClass);
+  }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Rule.java b/src/main/java/com/google/devtools/build/lib/packages/Rule.java
index 24ed1f7..1cc5f63 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Rule.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Rule.java
@@ -704,7 +704,7 @@
       BinaryPredicate<Rule, Attribute> predicate) {
     LinkedHashMultimap<Attribute, Label> labels = LinkedHashMultimap.create();
     for (Attribute attribute : this.getAttributes()) {
-      for (Class<? extends AspectFactory<?, ?, ?>> candidateClass : attribute.getAspects()) {
+      for (AspectClass candidateClass : attribute.getAspects()) {
         AspectFactory<?, ?, ?> candidate = AspectFactory.Util.create(candidateClass);
         AspectDefinition.addAllAttributesOfAspect(Rule.this, labels,
             candidate.getDefinition(), predicate);