use of com.squareup.javapoet.ClassName in project tiger by google.
the class NewInjectorGenerator method createInjectorTypeSpec.
private TypeSpec.Builder createInjectorTypeSpec(ComponentInfo component, ClassName injectorClassName) {
ClassName cn = getInjectorNameOfScope(injectorClassName, component.getScope());
// System.out.println("createPackagedInjectorTypeSpec. name: " +
// Utilities.getClassCanonicalName(cn));
TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder(cn.simpleName()).addModifiers(Modifier.PUBLIC).addAnnotation(AnnotationSpec.builder(Generated.class).addMember("value", "$S", GENERATOR_NAME).build());
// Top level injector.
ClassName topLevelInjectorClassName = ClassName.get(topLevelPackageString, getTopLevelInjectorName(component));
typeSpecBuilder.addField(topLevelInjectorClassName, TOP_LEVEL_INJECTOR_FIELD, Modifier.PRIVATE);
MethodSpec.Builder ctorSpec = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC).addParameter(topLevelInjectorClassName, TOP_LEVEL_INJECTOR_FIELD);
ctorSpec.addStatement("this.$N = $N", TOP_LEVEL_INJECTOR_FIELD, TOP_LEVEL_INJECTOR_FIELD);
// Containing packaged injector.
if (componentTree.get(component) != null) {
ClassName containingInjectorClassName = getInjectorNameOfScope(injectorClassName, componentTree.get(component).getScope());
typeSpecBuilder.addField(containingInjectorClassName, CONTAINING_PACKAGED_INJECTOR_FIELD, Modifier.PRIVATE);
ctorSpec.addParameter(containingInjectorClassName, CONTAINING_PACKAGED_INJECTOR_FIELD);
ctorSpec.addStatement("this.$N = $N", CONTAINING_PACKAGED_INJECTOR_FIELD, CONTAINING_PACKAGED_INJECTOR_FIELD);
}
typeSpecBuilder.addMethod(ctorSpec.build());
return typeSpecBuilder;
}
use of com.squareup.javapoet.ClassName in project tiger by google.
the class NewInjectorGenerator method generateUniqueTypeProvisionMethodFromModule.
private void generateUniqueTypeProvisionMethodFromModule(NewBindingKey key, String suffix) {
NewDependencyInfo dependencyInfo = Iterables.getOnlyElement(dependencies.get(key));
Preconditions.checkNotNull(dependencyInfo.getProvisionMethodElement());
TypeMirror returnType = dependencyInfo.getProvisionMethodElement().getReturnType();
ClassName injectorClassName = getPackagedInjectorForNewDependencyInfo(key, dependencyInfo);
TypeSpec.Builder componentSpecBuilder = getInjectorTypeSpecBuilder(injectorClassName);
NewBindingKey returnKey = NewBindingKey.get(returnType, key.getQualifier());
MethodSpec.Builder methodSpecBuilder = MethodSpec.methodBuilder(getProvisionMethodName(returnKey) + suffix);
methodSpecBuilder.addModifiers(suffix.isEmpty() ? Modifier.PUBLIC : Modifier.PRIVATE).returns(TypeName.get(returnType));
methodSpecBuilder.addStatement("$T result", returnType);
addNewStatementToMethodSpec(key, dependencyInfo, injectorClassName, methodSpecBuilder, "result");
methodSpecBuilder.addStatement("return result");
componentSpecBuilder.addMethod(methodSpecBuilder.build());
// messager.printMessage(Kind.NOTE, String.format(
// "generateUniqueTypeProvisionMethodFromModule: \n key: %s, \n injector: %s, \n method: %s.",
// key, injectorClassName, methodSpecBuilder.build()));
}
use of com.squareup.javapoet.ClassName in project tiger by google.
the class NewInjectorGenerator method generateSetTypeProvisionMethodForPackage.
// If dependencyInfo is not null, then it is a contributor to set binding.
private void generateSetTypeProvisionMethodForPackage(NewBindingKey key, Set<NewDependencyInfo> dependencyInfos, String suffix) {
Preconditions.checkArgument(!dependencyInfos.isEmpty(), String.format("Empty dependencyInfo for key: %s", key));
NewDependencyInfo dependencyInfo = Iterables.getFirst(dependencyInfos, null);
TypeName returnType = key.getTypeName();
ClassName injectorClassName = getPackagedInjectorForNewDependencyInfo(key, dependencyInfo);
TypeSpec.Builder componentSpecBuilder = getInjectorTypeSpecBuilder(injectorClassName);
MethodSpec.Builder methodSpecBuilder = MethodSpec.methodBuilder(getProvisionMethodName(key) + suffix);
methodSpecBuilder.addModifiers(Modifier.PUBLIC).returns(returnType);
methodSpecBuilder.addStatement("$T result = new $T<>()", returnType, HashSet.class);
for (NewDependencyInfo di : dependencyInfos) {
methodSpecBuilder.beginControlFlow("");
Preconditions.checkNotNull(di.getProvisionMethodElement());
TypeName contributorType = TypeName.get(di.getProvisionMethodElement().getReturnType());
methodSpecBuilder.addStatement("$T contributor", contributorType);
addNewStatementToMethodSpec(key, di, injectorClassName, methodSpecBuilder, "contributor");
if (di.getType().equals(Type.SET)) {
methodSpecBuilder.addStatement("result.add(contributor)");
} else {
Preconditions.checkState(di.getType().equals(Type.SET_VALUES));
methodSpecBuilder.addStatement("result.addAll(contributor)");
}
methodSpecBuilder.endControlFlow();
}
methodSpecBuilder.addStatement("return result");
componentSpecBuilder.addMethod(methodSpecBuilder.build());
// messager.printMessage(Kind.NOTE, String.format(
// "generateSetTypeProvisionMethodFromModule: \n key: %s, \n injector: %s, \n method: %s.",
// key, injectorClassName, methodSpecBuilder.build()));
}
use of com.squareup.javapoet.ClassName in project tiger by google.
the class NewInjectorGenerator method getInjectorFor.
/**
* For all bindings but single contributor of a multi-binding, which is handled by
* {@link #getPackagedInjectorForNewDependencyInfo(NewBindingKey, NewDependencyInfo)} . For
* generic binding, package of referencing class has access to both raw type and parameter types,
* though the provision method generated for it will be duplicated in each such package.
*/
private ClassName getInjectorFor(NewBindingKey key, TypeElement referencingClass) {
ClassName result = null;
TypeElement scope = scopeCalculator.calculate(key);
NewDependencyInfo dependencyInfo = Iterables.getFirst(Utils.getDependencyInfo(dependencies, key), null);
// System.out.println("getInjectorFor: " + key + " dependencyInfo: "
// + dependencyInfo);
String packageString = null;
boolean isMultiBinding = false;
if (dependencyInfo != null) {
isMultiBinding = dependencyInfo.isMultiBinding();
packageString = Utils.getPackage(dependencyInfo.getSourceClassElement()).getQualifiedName().toString();
} else if (Utils.hasBuiltinBinding(key)) {
result = getInjectorFor(Utils.getElementKeyForBuiltinBinding(key), referencingClass);
} else {
NewDependencyInfo genericNewDependencyInfo = Utils.getDependencyInfoByGeneric(dependencies, key);
if (genericNewDependencyInfo != null) {
packageString = Utils.getPackageString(referencingClass);
} else {
errors.add(String.format("Cannot resolve %s.", key));
throw new RuntimeException(errors.toString());
}
}
if (result == null) {
String simpleName = isMultiBinding ? Utils.getMultiBindingInjectorSimpleName(scope) : Utils.getPackagedInjectorSimpleName(scope);
result = ClassName.get(isMultiBinding ? topLevelPackageString : packageString, simpleName);
}
return result;
}
use of com.squareup.javapoet.ClassName in project tiger by google.
the class NewInjectorGenerator method generateTopLevelInjectors.
private void generateTopLevelInjectors() {
SetMultimap<NewBindingKey, ClassName> keyToPackagedInjectorMap = Utils.reverseSetMultimap(generatedBindingsForPackagedInjector);
// messager.printMessage(Kind.NOTE,
// "generatedBindingsForPackagedInjector: " + generatedBindingsForPackagedInjector);
// messager.printMessage(Kind.NOTE, "keyToPackagedInjectorMap: " + keyToPackagedInjectorMap);
Set<ClassName> topLevelInjectedClassNames = new HashSet<>();
for (ComponentInfo component : orderedComponents) {
TypeSpec.Builder injectorBuilder = TypeSpec.classBuilder(getTopLevelInjectorName(component)).addAnnotation(AnnotationSpec.builder(Generated.class).addMember("value", "$S", GENERATOR_NAME).build()).addModifiers(Modifier.PUBLIC);
// Member injector interfaces.
for (TypeElement injector : memberInjectors.get(component)) {
injectorBuilder.addSuperinterface(TypeName.get(injector.asType()));
}
MethodSpec.Builder ctorBuilder = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC);
// Containing top level injector.
String containingInjectorName = "containingInjector";
if (componentTree.get(component) != null) {
ClassName containingInjectorClassName = ClassName.get(topLevelPackageString, getTopLevelInjectorName(componentTree.get(component)));
injectorBuilder.addField(containingInjectorClassName, containingInjectorName, Modifier.PRIVATE);
ctorBuilder.addParameter(containingInjectorClassName, containingInjectorName).addStatement("this.$L = $L", containingInjectorName, containingInjectorName);
}
// Passed modules.
Set<TypeElement> allPassedModules = new HashSet<>();
allPassedModules.addAll(nonNullaryCtorModules.get(component));
allPassedModules.addAll(nonNullaryCtorUnscopedModules);
for (TypeElement passedModule : Utils.sortByFullName(allPassedModules)) {
String moduleName = Utils.getSourceCodeName(passedModule);
ClassName moduleTypeName = (ClassName) TypeName.get(passedModule.asType());
ctorBuilder.addParameter(moduleTypeName, moduleName).addStatement("this.$N = $N", moduleName, moduleName);
injectorBuilder.addField(moduleTypeName, moduleName, Modifier.PRIVATE).addMethod(MethodSpec.methodBuilder(Utils.getGetMethodName(moduleTypeName)).addModifiers(Modifier.PUBLIC).returns(moduleTypeName).addStatement("return $N", moduleName).build());
}
injectorBuilder.addMethod(ctorBuilder.build());
// Injection methods and non-injection methods.
Set<String> miscMethodNames = new HashSet<>();
Set<TypeElement> allMembersInjectors = Sets.newHashSet(memberInjectors.get(component));
while (!allMembersInjectors.isEmpty()) {
TypeElement injector = Iterables.getFirst(allMembersInjectors, null);
Preconditions.checkNotNull(injector, String.format("Empty allMembersInjector."));
allMembersInjectors.remove(injector);
for (TypeMirror parentInterface : injector.getInterfaces()) {
allMembersInjectors.add((TypeElement) ((DeclaredType) parentInterface).asElement());
}
for (Element element : injector.getEnclosedElements()) {
if (!element.getKind().equals(ElementKind.METHOD)) {
continue;
}
// Injection methods.
if (Utils.isInjectionMethod(element)) {
ExecutableElement method = (ExecutableElement) element;
TypeMirror typeMirror = Iterables.getOnlyElement(method.getParameters()).asType();
if (typeMirror.getKind().equals(TypeKind.TYPEVAR)) {
// TODO(freeman): support generic injection method.
continue;
}
TypeElement cls = (TypeElement) ((DeclaredType) typeMirror).asElement();
if (!topLevelInjectedClassNames.add(ClassName.get(cls))) {
continue;
}
ClassName packagedInjectorClassName = getPackagedInjectorNameOfScope(Utils.getPackageString(cls), component.getScope());
injectorBuilder.addMethod(MethodSpec.methodBuilder(method.getSimpleName().toString()).addModifiers(Modifier.PUBLIC).addParameter(ClassName.get(cls), "arg").addStatement("$L().inject(arg)", Utils.getGetMethodName(packagedInjectorClassName)).build());
} else if (Utils.isProvisionMethodInInjector(element)) {
// non-injection methods, provision methods or getSubComponent method in
// editors. NOTE(freeman): subcomponent should be converted to component.
ExecutableElement method = (ExecutableElement) element;
if (!miscMethodNames.add(method.getSimpleName().toString())) {
continue;
}
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(method.getSimpleName().toString()).addModifiers(Modifier.PUBLIC).returns(TypeName.get(method.getReturnType()));
NewBindingKey providedKey = Utils.getKeyProvidedByMethod(method);
ClassName packagedInjectorClassName = null;
for (ClassName className : keyToPackagedInjectorMap.get(providedKey)) {
if (isInjectorOfScope(className, component.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().$L()";
methodBuilder.addStatement(statement, Utils.getGetMethodName(packagedInjectorClassName), getProvisionMethodName(providedKey));
}
// System.out.println("provision method added: " + methodBuilder.build());
injectorBuilder.addMethod(methodBuilder.build());
} else {
messager.printMessage(Kind.WARNING, String.format("Element %s ignored from injector %s.", element, injector));
}
}
}
// Methods to get injectors.
for (Map.Entry<ClassName, TypeSpec.Builder> entry : packagedInjectorBuilders.entrySet()) {
ClassName injectorClassName = entry.getKey();
if (!component.equals(getComponentFromPackagedInjectorClassName(injectorClassName))) {
continue;
}
String packagedInjectorSourceCodeName = Utils.getSourceCodeName(injectorClassName);
injectorBuilder.addField(injectorClassName, packagedInjectorSourceCodeName, Modifier.PRIVATE);
MethodSpec.Builder methodSpecBuilder = MethodSpec.methodBuilder(Utils.getGetMethodName(injectorClassName)).addModifiers(Modifier.PUBLIC).returns(injectorClassName).addStatement("$T result = $N", injectorClassName, packagedInjectorSourceCodeName).beginControlFlow("if (result == null)");
StringBuilder stringBuilder = new StringBuilder("result = $N = new $T(this");
if (componentTree.get(component) != null) {
ClassName containingPackageInjectorClassName = getInjectorNameOfScope(injectorClassName, componentTree.get(component).getScope());
stringBuilder.append(", ").append(containingInjectorName).append(".").append(Utils.getGetMethodName(containingPackageInjectorClassName)).append("()");
}
stringBuilder.append(")");
methodSpecBuilder.addStatement(stringBuilder.toString(), packagedInjectorSourceCodeName, injectorClassName);
methodSpecBuilder.endControlFlow().addStatement("return result");
injectorBuilder.addMethod(methodSpecBuilder.build());
}
generateInjectorBuilder(component, injectorBuilder);
JavaFile javaFile = JavaFile.builder(topLevelPackageString, injectorBuilder.build()).build();
try {
javaFile.writeTo(processingEnv.getFiler());
} catch (IOException e) {
Throwables.propagate(e);
}
}
}
Aggregations