• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Dagger Authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package dagger.internal.codegen.xprocessing;
18 
19 import static androidx.room.compiler.processing.compat.XConverters.toJavac;
20 import static com.google.common.base.Preconditions.checkNotNull;
21 import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList;
22 import static kotlin.streams.jdk8.StreamsKt.asStream;
23 
24 import androidx.room.compiler.processing.XHasModifiers;
25 import androidx.room.compiler.processing.XMethodElement;
26 import androidx.room.compiler.processing.XTypeElement;
27 import com.google.common.collect.ImmutableList;
28 import com.google.common.collect.ImmutableSet;
29 
30 // TODO(bcorso): Consider moving these methods into XProcessing library.
31 /** A utility class for {@link XTypeElement} helper methods. */
32 public final class XTypeElements {
33   private enum Visibility {
34     PUBLIC,
35     PRIVATE,
36     OTHER;
37 
38     /** Returns the visibility of the given {@link XTypeElement}. */
of(XTypeElement element)39     private static Visibility of(XTypeElement element) {
40       checkNotNull(element);
41       if (element.isPrivate()) {
42         return Visibility.PRIVATE;
43       } else if (element.isPublic()) {
44         return Visibility.PUBLIC;
45       } else {
46         return Visibility.OTHER;
47       }
48     }
49   }
50 
51   /** Returns {@code true} if the given element is nested. */
isNested(XTypeElement typeElement)52   public static boolean isNested(XTypeElement typeElement) {
53     return typeElement.getEnclosingTypeElement() != null;
54   }
55 
56   /** Returns {@code true} if the given {@code type} has type parameters. */
hasTypeParameters(XTypeElement type)57   public static boolean hasTypeParameters(XTypeElement type) {
58     // TODO(bcorso): Add support for XTypeElement#getTypeParameters() or at least
59     // XTypeElement#hasTypeParameters() in XProcessing. XTypes#getTypeArguments() isn't quite the
60     // same -- it tells you if the declared type has parameters rather than the element itself.
61     return !toJavac(type).getTypeParameters().isEmpty();
62   }
63 
64   /** Returns all non-private, non-static, abstract methods in {@code type}. */
getAllUnimplementedMethods(XTypeElement type)65   public static ImmutableList<XMethodElement> getAllUnimplementedMethods(XTypeElement type) {
66     return asStream(type.getAllNonPrivateInstanceMethods())
67         .filter(XHasModifiers::isAbstract)
68         .collect(toImmutableList());
69   }
70 
isEffectivelyPublic(XTypeElement element)71   public static boolean isEffectivelyPublic(XTypeElement element) {
72     return allVisibilities(element).stream()
73         .allMatch(visibility -> visibility.equals(Visibility.PUBLIC));
74   }
75 
isEffectivelyPrivate(XTypeElement element)76   public static boolean isEffectivelyPrivate(XTypeElement element) {
77     return allVisibilities(element).contains(Visibility.PRIVATE);
78   }
79 
80   /**
81    * Returns a list of visibilities containing visibility of the given element and the visibility of
82    * its enclosing elements.
83    */
allVisibilities(XTypeElement element)84   private static ImmutableSet<Visibility> allVisibilities(XTypeElement element) {
85     checkNotNull(element);
86     ImmutableSet.Builder<Visibility> visibilities = ImmutableSet.builder();
87     XTypeElement currentElement = element;
88     while (currentElement != null) {
89       visibilities.add(Visibility.of(currentElement));
90       currentElement = currentElement.getEnclosingTypeElement();
91     }
92     return visibilities.build();
93   }
94 
XTypeElements()95   private XTypeElements() {}
96 }
97