use of javax.lang.model.type.ExecutableType in project tiger by google.
the class Utils method getCtorDependencies.
public List<BindingKey> getCtorDependencies(SetMultimap<BindingKey, DependencyInfo> dependencies, BindingKey key) {
TypeElement cls = getClassFromKey(key);
DeclaredType clsType = (DeclaredType) getTypeFromKey(key);
ExecutableElement ctor = findInjectedCtor(cls);
Preconditions.checkNotNull(ctor, String.format("Did not find ctor for %s", cls));
ExecutableType ctorType = (ExecutableType) types.asMemberOf(clsType, ctor);
List<BindingKey> dependencyKeys = getDependenciesFromMethod(ctorType, ctor);
return dependencyKeys;
}
use of javax.lang.model.type.ExecutableType in project tiger by google.
the class Utils method getProduced.
public Pair<Set<BindingKey>, Set<BindingKey>> getProduced(TypeElement eitherComponent) {
Set<BindingKey> provided = new HashSet<>();
Set<BindingKey> injected = new HashSet<>();
// Set<String> s = new HashSet<>();
// s.add("PartyHatPromoController");
// s.add("ReviewAtAPlaceNotificationAdapterRecommend");
// s.add("ReviewAtAPlaceNotificationAdapterStars");
DeclaredType eitherComponentType = (DeclaredType) eitherComponent.asType();
traverseAndDo(types, eitherComponentType, eitherComponent, p -> {
Element element = p.second;
// logger.n(element.toString());
if (!element.getKind().equals(ElementKind.METHOD)) {
return null;
}
ExecutableElement method = (ExecutableElement) element;
ExecutableType methodType = (ExecutableType) processingEnvironment.getTypeUtils().asMemberOf(eitherComponentType, method);
// Injection methods.
if (isInjectionMethod(element)) {
TypeMirror typeMirror = Iterables.getOnlyElement(methodType.getParameterTypes());
while (typeMirror != null) {
if (!((DeclaredType) typeMirror).getTypeArguments().isEmpty()) {
logger.w("Inject generic type: %s", typeMirror);
typeMirror = types.erasure(typeMirror);
}
injected.add(BindingKey.get(typeMirror));
TypeElement closestInjectedAncestor = getClosestInjectedAncestor((TypeElement) ((DeclaredType) typeMirror).asElement());
typeMirror = closestInjectedAncestor == null ? null : closestInjectedAncestor.asType();
}
// if (typeMirror instanceof DeclaredType) {
// String qN =
// ((TypeElement) ((DeclaredType) typeMirror).asElement())
// .getQualifiedName()
// .toString();
// for (String i : s) {
// if (qN.contains(i)) {
// for (StackTraceElement j : utils.getStack()) {
// logger.e("%s.%s", method.getEnclosingElement(), method);
// }
// }
// }
// }
} else if (isProvisionMethodInInjector(element)) {
provided.add(getKeyProvidedByMethod(method));
} else if (isIrrelevantMethodInInjector(element)) {
// do nothing
} else {
logger.l(Kind.WARNING, "Element %s ignored from injector %s.", element, eitherComponentType);
}
return null;
});
// addFromComponentDependencies(provided);
// addBindsInstance(provided);
// addFromPackagedHubInterfaces(provided);
// addFromSubcomponentHubInterfaces(provided);
logger.n("provided: %s\ninjected: %s", provided, injected);
return Pair.of(provided, injected);
}
use of javax.lang.model.type.ExecutableType in project tiger by google.
the class Utils method getKeyForOnlyParameterOfMethod.
public BindingKey getKeyForOnlyParameterOfMethod(Types types, DeclaredType containingType, Element e) {
ExecutableType method = (ExecutableType) types.asMemberOf(containingType, e);
VariableElement variableElement = Iterables.getOnlyElement(((ExecutableElement) e).getParameters());
TypeMirror argumentType = Iterables.getOnlyElement(method.getParameterTypes());
AnnotationMirror annotationTypeMirror = getQualifier(variableElement);
return BindingKey.get(argumentType, annotationTypeMirror);
}
use of javax.lang.model.type.ExecutableType in project tiger by google.
the class Tiger2InjectorGenerator method doSpecific.
@Override
protected void doSpecific() {
// TODO: remove this, just and the contracts to trigger generating things when needed.
// generateImplicitMethods();
// Injection methods and non-injection methods.
Set<String> miscMethodNames = new HashSet<>();
DeclaredType eitherComponentType = (DeclaredType) eitherComponent.asType();
utils.traverseAndDo(types, eitherComponentType, eitherComponent, p -> {
Element element = p.second;
messager.printMessage(Kind.NOTE, "method: " + element);
if (!element.getKind().equals(ElementKind.METHOD)) {
return null;
}
ExecutableElement method = (ExecutableElement) element;
ExecutableType methodType = (ExecutableType) processingEnv.getTypeUtils().asMemberOf(eitherComponentType, method);
// Injection methods.
if (utils.isInjectionMethod(element)) {
// TODO: add duplicate check for provision method also.
if (injectionMethodsDone.add(Pair.of(method.getSimpleName().toString(), TypeName.get(Iterables.getOnlyElement(methodType.getParameterTypes())))) == false) {
messager.printMessage(Kind.WARNING, "duplicate injection method: " + method);
return null;
}
TypeMirror typeMirror = Iterables.getOnlyElement(methodType.getParameterTypes());
TypeElement cls = (TypeElement) ((DeclaredType) typeMirror).asElement();
messager.printMessage(Kind.NOTE, TAG + ".generateTopLevelInjector-injection method : " + methodType);
injectorBuilder.addMethod(MethodSpec.methodBuilder(method.getSimpleName().toString()).addModifiers(Modifier.PUBLIC).addParameter(ClassName.get(cls), "arg").addStatement("inject(arg)").build());
} else if (utils.isComponentProvisionMethod(element)) {
messager.printMessage(Kind.ERROR, "Injecting components is not supported: " + element);
} else if (utils.isSubcomponentProvisionMethod(element)) {
/**
* TODO: handle this in {@link #generateProvisionMethodIfNeeded(BindingKey)}
*/
generateGetSubcomponentMethod((ExecutableElement) element, injectorBuilder);
} else if (utils.isProvisionMethodInInjector(element)) {
if (!miscMethodNames.add(method.getSimpleName().toString())) {
return null;
}
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(method.getSimpleName().toString()).addModifiers(Modifier.PUBLIC).returns(TypeName.get(method.getReturnType()));
BindingKey providedKey = utils.getKeyProvidedByMethod(method);
// ClassName packagedInjectorClassName = null;
// for (ClassName className : keyToPackagedInjectorMap.get(providedKey)) {
// if (isInjectorOfScope(className, coreInjectorInfo.getScope())) {
// packagedInjectorClassName = className;
// break;
// }
// }
// if (packagedInjectorClassName == null) {
// messager.printMessage(Kind.WARNING,
// String.format(
// "PackagedInjector or multiBindingInjector not found for key: %s "
// + "from provisionMethod: %s. Probably it is not used.",
// providedKey, method));
// // Create a dumb method
// String statement = "return ";
// TypeKind typeKind = method.getReturnType().getKind();
// if (typeKind.equals(TypeKind.BOOLEAN)) {
// statement += "false";
// } else if (typeKind.equals(TypeKind.CHAR)) {
// statement += "\'0\'";
// } else if (typeKind.isPrimitive()) {
// statement += "0";
// } else {
// statement += "null";
// }
// methodBuilder.addStatement(statement);
// } else {
String statement = "return $L()";
methodBuilder.addStatement(statement, Utils.getProvisionMethodName(dependencies, providedKey));
// }
// messager.printMessage(Kind.NOTE, "provision method added: " + methodBuilder.build());
injectorBuilder.addMethod(methodBuilder.build());
// } else if (utils.isEitherComponentProvisionMethod(element)) {
// // TODO: support get component method.
// if(utils.isComponentProvisionMethod(element)) {
// throw new RuntimeException("component provision method is not suported yet.");
// }
// generateGetSubcomponentMethod((ExecutableElement) element, injectorBuilder);
// } else if (utils.isEitherComponentBuilderProvisionMethod(element)) {
// /**
// * TODO: handle it in the way consistent with other {@link DependencySourceType} in
// * {@link #generateProvisionMethodIfNeeded(BindingKey, TypeElement)}
// */
// generateExplicitProvisionMethodForEitherComponentBuilder(
// (ExecutableElement) element, injectorBuilder);
} else if (isIrrelevantMethodInInjector(element)) {
// do nothing
} else {
messager.printMessage(Kind.WARNING, String.format("Element %s ignored from injector %s.", element, eitherComponentType));
}
return null;
});
// Builder.
TypeElement explicitBuilder = utils.findBuilder(elements, eitherComponent);
generateInjectorBuilder(explicitBuilder);
// builder().
ClassName builderClassName = ClassName.get(utils.getPackageString(eitherComponent), utils.getComponentImplementationSimpleNameFromInterface(eitherComponent), explicitBuilder != null ? explicitBuilder.getSimpleName().toString() : "Builder");
MethodSpec.Builder builderMethodSpecBuilder = MethodSpec.methodBuilder("builder").addModifiers(Modifier.PUBLIC, Modifier.STATIC).returns(builderClassName);
boolean isSubcomponent = utils.isSubcomponent(eitherComponent);
if (isSubcomponent) {
builderMethodSpecBuilder.addParameter(ClassName.get(parentEitherComponent.asType()), "v");
}
builderMethodSpecBuilder.addCode("return new $T($L);", builderClassName, isSubcomponent ? "v" : "");
injectorBuilder.addMethod(builderMethodSpecBuilder.build());
// provision methods for (sub)component builders that can be provided by this core injector.
// TODO: handle implicit ones here, explicit ones have been handled in {@link
// #generateProvisionMethodForThoseFromTopLevel}.
// generateImplicitProvisionMethodForEitherComponentBuilder(injectorBuilder, builder);
}
use of javax.lang.model.type.ExecutableType in project tiger by google.
the class Tiger2Processor method completeComponents.
/**
* Find all the (sub)eitherComponents in question. {@link Component}s are from annotation already. But
* some {@link Subcomponent}s can only be traced by provision methods for them or their builders.
*/
private void completeComponents(Set<TypeElement> components) {
Set<TypeElement> work = Sets.newHashSet(components);
Set<TypeElement> done = Sets.newHashSet();
while (!work.isEmpty()) {
TypeElement c = Preconditions.checkNotNull(Iterables.getFirst(work, null));
work.remove(c);
done.add(c);
utils.traverseAndDo(types, (DeclaredType) c.asType(), c, pair -> {
TypeMirror type = pair.getFirst();
Element element = pair.getSecond();
if (utils.isEitherComponentProvisionMethod(element) || utils.isEitherComponentBuilderProvisionMethod(element)) {
TypeElement newFound = (TypeElement) ((DeclaredType) ((ExecutableType) type).getReturnType()).asElement();
if (utils.isEitherComponentBuilder(newFound)) {
newFound = (TypeElement) newFound.getEnclosingElement();
}
if (components.add(newFound)) {
messager.printMessage(Kind.NOTE, TAG + ".completeComponents found new " + newFound + "component: " + c + " method: " + element);
}
if (!done.contains(newFound)) {
work.add(newFound);
}
}
return null;
});
}
}
Aggregations