unplugged-system/external/dagger2/java/dagger/internal/codegen/xprocessing/XElements.java

178 lines
7.0 KiB
Java
Raw Normal View History

/*
* Copyright (C) 2021 The Dagger Authors.
*
* 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 dagger.internal.codegen.xprocessing;
import static androidx.room.compiler.processing.XElementKt.isConstructor;
import static androidx.room.compiler.processing.XElementKt.isField;
import static androidx.room.compiler.processing.XElementKt.isMethod;
import static androidx.room.compiler.processing.XElementKt.isMethodParameter;
import static androidx.room.compiler.processing.XElementKt.isTypeElement;
import static androidx.room.compiler.processing.XElementKt.isVariableElement;
import static androidx.room.compiler.processing.compat.XConverters.toJavac;
import static com.google.common.base.Preconditions.checkState;
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet;
import androidx.room.compiler.processing.XAnnotated;
import androidx.room.compiler.processing.XAnnotation;
import androidx.room.compiler.processing.XConstructorElement;
import androidx.room.compiler.processing.XElement;
import androidx.room.compiler.processing.XEnumEntry;
import androidx.room.compiler.processing.XExecutableElement;
import androidx.room.compiler.processing.XExecutableParameterElement;
import androidx.room.compiler.processing.XFieldElement;
import androidx.room.compiler.processing.XMethodElement;
import androidx.room.compiler.processing.XTypeElement;
import androidx.room.compiler.processing.XVariableElement;
import com.google.common.collect.ImmutableSet;
import com.squareup.javapoet.ClassName;
import java.util.Collection;
import java.util.Optional;
import javax.lang.model.element.ElementKind;
// TODO(bcorso): Consider moving these methods into XProcessing library.
/** A utility class for {@link XElement} helper methods. */
public final class XElements {
// TODO(bcorso): Replace usages with getJvmName() once it exists.
/** Returns the simple name of the element. */
public static String getSimpleName(XElement element) {
return toJavac(element).getSimpleName().toString();
}
/**
* Returns the closest enclosing element that is a {@link XTypeElement} or throws an {@link
* IllegalStateException} if one doesn't exists.
*/
public static XTypeElement closestEnclosingTypeElement(XElement element) {
return optionalClosestEnclosingTypeElement(element)
.orElseThrow(() -> new IllegalStateException("No enclosing TypeElement for: " + element));
}
private static Optional<XTypeElement> optionalClosestEnclosingTypeElement(XElement element) {
if (isTypeElement(element)) {
return Optional.of(asTypeElement(element));
} else if (isConstructor(element)) {
return Optional.of(asConstructor(element).getEnclosingElement());
} else if (isMethod(element)) {
return optionalClosestEnclosingTypeElement(asMethod(element).getEnclosingElement());
} else if (isField(element)) {
return optionalClosestEnclosingTypeElement(asField(element).getEnclosingElement());
} else if (isMethodParameter(element)) {
return optionalClosestEnclosingTypeElement(
asMethodParameter(element).getEnclosingMethodElement());
}
return Optional.empty();
}
public static boolean isEnumEntry(XElement element) {
return element instanceof XEnumEntry;
}
public static boolean isEnum(XElement element) {
return toJavac(element).getKind() == ElementKind.ENUM;
}
public static boolean isExecutable(XElement element) {
return isConstructor(element) || isMethod(element);
}
public static XExecutableElement asExecutable(XElement element) {
checkState(isExecutable(element));
return (XExecutableElement) element;
}
public static XTypeElement asTypeElement(XElement element) {
checkState(isTypeElement(element));
return (XTypeElement) element;
}
// TODO(bcorso): Rename this and the XElementKt.isMethodParameter to isExecutableParameter.
public static XExecutableParameterElement asMethodParameter(XElement element) {
checkState(isMethodParameter(element));
return (XExecutableParameterElement) element;
}
public static XFieldElement asField(XElement element) {
checkState(isField(element));
return (XFieldElement) element;
}
public static XVariableElement asVariable(XElement element) {
checkState(isVariableElement(element));
return (XVariableElement) element;
}
public static XConstructorElement asConstructor(XElement element) {
checkState(isConstructor(element));
return (XConstructorElement) element;
}
public static XMethodElement asMethod(XElement element) {
checkState(isMethod(element));
return (XMethodElement) element;
}
public static ImmutableSet<XAnnotation> getAnnotatedAnnotations(
XAnnotated annotated, ClassName annotationName) {
return annotated.getAllAnnotations().stream()
.filter(annotation -> annotation.getType().getTypeElement().hasAnnotation(annotationName))
.collect(toImmutableSet());
}
/** Returns {@code true} if {@code annotated} is annotated with any of the given annotations. */
public static boolean hasAnyAnnotation(XAnnotated annotated, ClassName... annotations) {
return hasAnyAnnotation(annotated, ImmutableSet.copyOf(annotations));
}
/** Returns {@code true} if {@code annotated} is annotated with any of the given annotations. */
public static boolean hasAnyAnnotation(XAnnotated annotated, Collection<ClassName> annotations) {
return annotations.stream().anyMatch(annotated::hasAnnotation);
}
/**
* Returns any annotation from {@code annotations} that annotates {@code annotated} or else {@code
* Optional.empty()}.
*/
public static Optional<XAnnotation> getAnyAnnotation(
XAnnotated annotated, ClassName... annotations) {
return getAnyAnnotation(annotated, ImmutableSet.copyOf(annotations));
}
/**
* Returns any annotation from {@code annotations} that annotates {@code annotated} or else
* {@code Optional.empty()}.
*/
public static Optional<XAnnotation> getAnyAnnotation(
XAnnotated annotated, Collection<ClassName> annotations) {
return annotations.stream()
.filter(annotated::hasAnnotation)
.map(annotated::getAnnotation)
.findFirst();
}
/** Returns all annotations from {@code annotations} that annotate {@code annotated}. */
public static ImmutableSet<XAnnotation> getAllAnnotations(
XAnnotated annotated, Collection<ClassName> annotations) {
return annotations.stream()
.filter(annotated::hasAnnotation)
.map(annotated::getAnnotation)
.collect(toImmutableSet());
}
private XElements() {}
}