• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 Google LLC
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 package com.google.auto.common;
17 
18 import static com.google.common.base.Preconditions.checkNotNull;
19 import static javax.lang.model.element.ElementKind.PACKAGE;
20 
21 import com.google.common.base.Enums;
22 import com.google.common.collect.Ordering;
23 import java.util.Set;
24 import javax.lang.model.element.Element;
25 import javax.lang.model.element.ElementKind;
26 import javax.lang.model.element.Modifier;
27 
28 /**
29  * Represents the visibility of a given {@link Element}: {@code public}, {@code protected},
30  * {@code private} or default/package-private.
31  *
32  * <p>The constants for this enum are ordered according by increasing visibility.
33  *
34  * @author Gregory Kick
35  */
36 public enum Visibility {
37   PRIVATE,
38   DEFAULT,
39   PROTECTED,
40   PUBLIC;
41 
42   // TODO(ronshapiro): remove this and reference ElementKind.MODULE directly once we start building
43   // with -source 9
44   private static final ElementKind MODULE =
45       Enums.getIfPresent(ElementKind.class, "MODULE").orNull();
46 
47   /**
48    * Returns the visibility of the given {@link Element}. While package and module elements don't
49    * technically have a visibility associated with them, this method returns {@link #PUBLIC} for
50    * them.
51    */
ofElement(Element element)52   public static Visibility ofElement(Element element) {
53     checkNotNull(element);
54     // packages and module don't have modifiers, but they're obviously "public"
55     if (element.getKind().equals(PACKAGE) || element.getKind().equals(MODULE)) {
56       return PUBLIC;
57     }
58     Set<Modifier> modifiers = element.getModifiers();
59     if (modifiers.contains(Modifier.PRIVATE)) {
60       return PRIVATE;
61     } else if (modifiers.contains(Modifier.PROTECTED)) {
62       return PROTECTED;
63     } else if (modifiers.contains(Modifier.PUBLIC)) {
64       return PUBLIC;
65     } else {
66       return DEFAULT;
67     }
68   }
69 
70   /**
71    * Returns effective visibility of the given element meaning that it takes into account the
72    * visibility of its enclosing elements.
73    */
effectiveVisibilityOfElement(Element element)74   public static Visibility effectiveVisibilityOfElement(Element element) {
75     checkNotNull(element);
76     Visibility effectiveVisibility = PUBLIC;
77     Element currentElement = element;
78     while (currentElement != null) {
79       effectiveVisibility =
80           Ordering.natural().min(effectiveVisibility, ofElement(currentElement));
81       currentElement = currentElement.getEnclosingElement();
82     }
83     return effectiveVisibility;
84   }
85 }
86