dagger.internal.codegen.CodeGen Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dagger-compiler Show documentation
Show all versions of dagger-compiler Show documentation
Tools to generate Dagger injection and module adapters from annotated code and validate them.
The newest version!
/*
* Copyright (C) 2012 Square, Inc.
*
* 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;
import dagger.internal.Keys;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.AnnotationValueVisitor;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.util.SimpleAnnotationValueVisitor6;
import javax.lang.model.util.SimpleTypeVisitor6;
/**
* Support for annotation processors.
*/
final class CodeGen {
private CodeGen() {
}
public static PackageElement getPackage(Element type) {
while (type.getKind() != ElementKind.PACKAGE) {
type = type.getEnclosingElement();
}
return (PackageElement) type;
}
/**
* Returns the supertype, or {@code null} if the supertype is a platform
* class. This is intended for annotation processors that assume platform
* classes will never be annotated with application annotations.
*/
public static TypeMirror getApplicationSupertype(TypeElement type) {
TypeMirror supertype = type.getSuperclass();
return Keys.isPlatformType(supertype.toString()) ? null : supertype;
}
/** Returns a fully qualified class name to complement {@code type}. */
public static String adapterName(TypeElement typeElement, String suffix) {
StringBuilder builder = new StringBuilder();
rawTypeToString(builder, typeElement, '$');
builder.append(suffix);
return builder.toString();
}
/** Returns a string like {@code java.util.List}. */
public static String parameterizedType(Class> raw, String... parameters) {
StringBuilder result = new StringBuilder();
result.append(raw.getName());
result.append("<");
for (int i = 0; i < parameters.length; i++) {
if (i != 0) {
result.append(", ");
}
result.append(parameters[i]);
}
result.append(">");
return result.toString();
}
/** Returns a string for {@code type}. Primitive types are always boxed. */
public static String typeToString(TypeMirror type) {
StringBuilder result = new StringBuilder();
typeToString(type, result, '.');
return result.toString();
}
/** Returns a string for the raw type of {@code type}. Primitive types are always boxed. */
public static String rawTypeToString(TypeMirror type, char innerClassSeparator) {
if (!(type instanceof DeclaredType)) {
throw new IllegalArgumentException("Unexpected type: " + type);
}
StringBuilder result = new StringBuilder();
DeclaredType declaredType = (DeclaredType) type;
rawTypeToString(result, (TypeElement) declaredType.asElement(), innerClassSeparator);
return result.toString();
}
/**
* Appends a string for {@code type} to {@code result}. Primitive types are
* always boxed.
*
* @param innerClassSeparator either '.' or '$', which will appear in a
* class name like "java.lang.Map.Entry" or "java.lang.Map$Entry".
* Use '.' for references to existing types in code. Use '$' to define new
* class names and for strings that will be used by runtime reflection.
*/
public static void typeToString(final TypeMirror type, final StringBuilder result,
final char innerClassSeparator) {
type.accept(new SimpleTypeVisitor6() {
@Override public Void visitDeclared(DeclaredType declaredType, Void v) {
TypeElement typeElement = (TypeElement) declaredType.asElement();
rawTypeToString(result, typeElement, innerClassSeparator);
List extends TypeMirror> typeArguments = declaredType.getTypeArguments();
if (!typeArguments.isEmpty()) {
result.append("<");
for (int i = 0; i < typeArguments.size(); i++) {
if (i != 0) {
result.append(", ");
}
typeToString(typeArguments.get(i), result, innerClassSeparator);
}
result.append(">");
}
return null;
}
@Override public Void visitPrimitive(PrimitiveType primitiveType, Void v) {
result.append(box((PrimitiveType) type).getName());
return null;
}
@Override public Void visitArray(ArrayType arrayType, Void v) {
typeToString(arrayType.getComponentType(), result, innerClassSeparator);
result.append("[]");
return null;
}
@Override public Void visitTypeVariable(TypeVariable typeVariable, Void v) {
return null;
}
@Override protected Void defaultAction(TypeMirror typeMirror, Void v) {
throw new UnsupportedOperationException(
"Unexpected TypeKind " + typeMirror.getKind() + " for " + typeMirror);
}
}, null);
}
private static final AnnotationValueVisitor
© 2015 - 2025 Weber Informatics LLC | Privacy Policy