use of javax.lang.model.util.Types in project dagger by square.
the class GraphAnalysisProcessor method collectIncludesRecursively.
void collectIncludesRecursively(TypeElement module, Map<String, TypeElement> result, Deque<String> path) {
Map<String, Object> annotation = getAnnotation(Module.class, module);
if (annotation == null) {
// TODO(tbroyer): pass annotation information
throw new ModuleValidationException("No @Module on " + module, module);
}
// Add the module.
String name = module.getQualifiedName().toString();
if (path.contains(name)) {
StringBuilder message = new StringBuilder("Module Inclusion Cycle: ");
if (path.size() == 1) {
message.append(name).append(" includes itself directly.");
} else {
String current = null;
String includer = name;
for (int i = 0; path.size() > 0; i++) {
current = includer;
includer = path.pop();
message.append("\n").append(i).append(". ").append(current).append(" included by ").append(includer);
}
message.append("\n0. ").append(name);
}
throw new ModuleValidationException(message.toString(), module);
}
result.put(name, module);
// Recurse for each included module.
Types types = processingEnv.getTypeUtils();
List<Object> seedModules = new ArrayList<Object>();
seedModules.addAll(Arrays.asList((Object[]) annotation.get("includes")));
if (!annotation.get("addsTo").equals(Void.class))
seedModules.add(annotation.get("addsTo"));
for (Object include : seedModules) {
if (!(include instanceof TypeMirror)) {
// TODO(tbroyer): pass annotation information
processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, "Unexpected value for include: " + include + " in " + module, module);
continue;
}
TypeElement includedModule = (TypeElement) types.asElement((TypeMirror) include);
path.push(name);
collectIncludesRecursively(includedModule, result, path);
path.pop();
}
}
use of javax.lang.model.util.Types in project dagger by square.
the class ModuleAdapterProcessor method providerMethodsByClass.
/**
* Returns a map containing all {@code @Provides} methods, indexed by class.
*/
private Map<String, List<ExecutableElement>> providerMethodsByClass(RoundEnvironment env) {
Elements elementUtils = processingEnv.getElementUtils();
Types types = processingEnv.getTypeUtils();
Map<String, List<ExecutableElement>> result = new HashMap<String, List<ExecutableElement>>();
provides: for (Element providerMethod : findProvidesMethods(env)) {
switch(providerMethod.getEnclosingElement().getKind()) {
case CLASS:
// valid, move along
break;
default:
// TODO(tbroyer): pass annotation information
error("Unexpected @Provides on " + elementToString(providerMethod), providerMethod);
continue;
}
TypeElement type = (TypeElement) providerMethod.getEnclosingElement();
Set<Modifier> typeModifiers = type.getModifiers();
if (typeModifiers.contains(PRIVATE) || typeModifiers.contains(ABSTRACT)) {
error("Classes declaring @Provides methods must not be private or abstract: " + type.getQualifiedName(), type);
continue;
}
Set<Modifier> methodModifiers = providerMethod.getModifiers();
if (methodModifiers.contains(PRIVATE) || methodModifiers.contains(ABSTRACT) || methodModifiers.contains(STATIC)) {
error("@Provides methods must not be private, abstract or static: " + type.getQualifiedName() + "." + providerMethod, providerMethod);
continue;
}
ExecutableElement providerMethodAsExecutable = (ExecutableElement) providerMethod;
if (!providerMethodAsExecutable.getThrownTypes().isEmpty()) {
error("@Provides methods must not have a throws clause: " + type.getQualifiedName() + "." + providerMethod, providerMethod);
continue;
}
// Invalidate return types.
TypeMirror returnType = types.erasure(providerMethodAsExecutable.getReturnType());
if (!returnType.getKind().equals(TypeKind.ERROR)) {
// processors is not "invalid" in this way, so ignore).
for (String invalidTypeName : INVALID_RETURN_TYPES) {
TypeElement invalidTypeElement = elementUtils.getTypeElement(invalidTypeName);
if (invalidTypeElement != null && types.isSameType(returnType, types.erasure(invalidTypeElement.asType()))) {
error(String.format("@Provides method must not return %s directly: %s.%s", invalidTypeElement, type.getQualifiedName(), providerMethod), providerMethod);
// Skip to next provides method.
continue provides;
}
}
}
List<ExecutableElement> methods = result.get(type.getQualifiedName().toString());
if (methods == null) {
methods = new ArrayList<ExecutableElement>();
result.put(type.getQualifiedName().toString(), methods);
}
methods.add(providerMethodAsExecutable);
}
TypeMirror objectType = elementUtils.getTypeElement("java.lang.Object").asType();
// should still be registered and a ModuleAdapter should still be written.
for (Element module : env.getElementsAnnotatedWith(Module.class)) {
if (!module.getKind().equals(ElementKind.CLASS)) {
error("Modules must be classes: " + elementToString(module), module);
continue;
}
TypeElement moduleType = (TypeElement) module;
// Verify that all modules do not extend from non-Object types.
if (!types.isSameType(moduleType.getSuperclass(), objectType)) {
error("Modules must not extend from other classes: " + elementToString(module), module);
}
String moduleName = moduleType.getQualifiedName().toString();
if (result.containsKey(moduleName))
continue;
result.put(moduleName, new ArrayList<ExecutableElement>());
}
return result;
}
use of javax.lang.model.util.Types in project javapoet by square.
the class AbstractTypesTest method wildcardMirrorSuperType.
@Test
public void wildcardMirrorSuperType() throws Exception {
Types types = getTypes();
Elements elements = getElements();
TypeMirror string = elements.getTypeElement(String.class.getName()).asType();
WildcardType wildcard = types.getWildcardType(null, string);
TypeName type = TypeName.get(wildcard);
assertThat(type.toString()).isEqualTo("? super java.lang.String");
}
use of javax.lang.model.util.Types in project javapoet by square.
the class AbstractTypesTest method wildcardMirrorExtendsType.
@Test
public void wildcardMirrorExtendsType() throws Exception {
Types types = getTypes();
Elements elements = getElements();
TypeMirror charSequence = elements.getTypeElement(CharSequence.class.getName()).asType();
WildcardType wildcard = types.getWildcardType(charSequence, null);
TypeName type = TypeName.get(wildcard);
assertThat(type.toString()).isEqualTo("? extends java.lang.CharSequence");
}
use of javax.lang.model.util.Types in project auto by google.
the class EclipseHack method noArgMethodsIn.
/**
* Constructs a map from name to method of the no-argument methods in the given type. We need
* this because an ExecutableElement returned by {@link Elements#getAllMembers} will not compare
* equal to the original ExecutableElement if {@code getAllMembers} substituted type parameters,
* as it does in Eclipse.
*/
private Map<Name, ExecutableElement> noArgMethodsIn(DeclaredType in) {
Types typeUtils = processingEnv.getTypeUtils();
Elements elementUtils = processingEnv.getElementUtils();
TypeElement autoValueType = MoreElements.asType(typeUtils.asElement(in));
List<ExecutableElement> allMethods = ElementFilter.methodsIn(elementUtils.getAllMembers(autoValueType));
Map<Name, ExecutableElement> map = new LinkedHashMap<Name, ExecutableElement>();
for (ExecutableElement method : allMethods) {
if (method.getParameters().isEmpty()) {
map.put(method.getSimpleName(), method);
}
}
return map;
}
Aggregations