use of com.squareup.javapoet.JavaFile in project tiger by google.
the class CoreInjectorGenerator method generateTopLevelInjectors.
private void generateTopLevelInjectors() {
messager.printMessage(Kind.NOTE, "generateTopLevelInjectors");
SetMultimap<BindingKey, ClassName> keyToPackagedInjectorMap = utils.reverseSetMultimap(generatedBindingsForPackagedInjector);
for (CoreInjectorInfo coreInjectorInfo : orderedCoreinjectors) {
TypeSpec.Builder injectorBuilder = TypeSpec.classBuilder(getTopLevelInjectorName(coreInjectorInfo, topLevelInjectorPrefix, topLevelInjectorSuffix)).addAnnotation(AnnotationSpec.builder(Generated.class).addMember("value", "$S", GENERATOR_NAME).build()).addModifiers(Modifier.PUBLIC);
// method simple name and type.
Set<Pair<String, TypeName>> injectionMethodsDone = new HashSet<>();
// Member injector interfaces.
for (TypeElement injector : coreInjectorToComponentMap.get(coreInjectorInfo)) {
injectorBuilder.addSuperinterface(TypeName.get(injector.asType()));
}
// Ctor
MethodSpec.Builder ctorBuilder = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC);
ctorBuilder.addStatement("$T.out.printf($S, $L)", ClassName.get(System.class), "This is tiger: %s\n", "this");
// Ctor - Containing top level injector.
// TODO: remove this .
String containingInjectorName = "containingInjector";
if (componentTree.get(coreInjectorInfo) != null) {
ClassName containingInjectorClassName = ClassName.get(topLevelPackageString, getTopLevelInjectorName(componentTree.get(coreInjectorInfo), topLevelInjectorPrefix, topLevelInjectorSuffix));
injectorBuilder.addField(containingInjectorClassName, containingInjectorName, Modifier.PRIVATE);
ctorBuilder.addParameter(containingInjectorClassName, containingInjectorName).addStatement("this.$L = $L", containingInjectorName, containingInjectorName);
}
// Ctor - ancester top level injectors.
CoreInjectorInfo tmp = coreInjectorInfo;
while (componentTree.get(tmp) != null) {
tmp = componentTree.get(tmp);
ClassName className = ClassName.get(topLevelPackageString, getTopLevelInjectorName(tmp, topLevelInjectorPrefix, topLevelInjectorSuffix));
String sourceCodeName = utils.getSourceCodeName(className);
injectorBuilder.addField(className, sourceCodeName);
if (tmp.equals(componentTree.get(coreInjectorInfo))) {
ctorBuilder.addStatement("this.$L = $L", sourceCodeName, containingInjectorName);
} else {
ctorBuilder.addStatement("this.$L = $L.$L", sourceCodeName, containingInjectorName, sourceCodeName);
}
}
// Ctor - Component dependencies
for (TypeElement dep : utils.sortByFullName(coreInjectorToComponentDependencyMap.get(coreInjectorInfo))) {
if (utils.isEitherComponent(dep)) {
continue;
}
ClassName className = ClassName.get(dep);
String sourceCodeName = utils.getSourceCodeName(className);
injectorBuilder.addField(className, sourceCodeName, Modifier.PUBLIC);
ctorBuilder.addParameter(className, sourceCodeName).addStatement("this.$L = $L", sourceCodeName, sourceCodeName);
}
// Ctor - @BindsInstance
for (BindingKey key : utils.sortBindingKeys(coreInjectorToBindsInstanceMap.get(coreInjectorInfo))) {
String sourceCodeName = utils.getSourceCodeNameHandlingBox(key, dependencies);
injectorBuilder.addField(key.getTypeName(), sourceCodeName, Modifier.PUBLIC);
ctorBuilder.addParameter(key.getTypeName(), sourceCodeName).addStatement("this.$L = $L", sourceCodeName, sourceCodeName);
}
// Ctor - Passed modules.
Set<TypeElement> allPassedModules = new HashSet<>();
allPassedModules.addAll(nonNullaryCtorModules.get(coreInjectorInfo));
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(coreInjectorToComponentMap.get(coreInjectorInfo));
for (TypeElement injector : allMembersInjectors) {
for (Element element : processingEnv.getElementUtils().getAllMembers(injector)) {
messager.printMessage(Kind.NOTE, "method: " + element);
if (!element.getKind().equals(ElementKind.METHOD)) {
continue;
}
ExecutableElement method = (ExecutableElement) element;
ExecutableType methodType = (ExecutableType) processingEnv.getTypeUtils().asMemberOf((DeclaredType) injector.asType(), 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);
continue;
}
TypeMirror typeMirror = Iterables.getOnlyElement(methodType.getParameterTypes());
TypeElement cls = (TypeElement) ((DeclaredType) typeMirror).asElement();
messager.printMessage(Kind.NOTE, TAG + ".generateTopLevelInjector-injection method : " + methodType);
ClassName packagedInjectorClassName = getPackagedInjectorNameOfScope(utils.getPackageString(cls), coreInjectorInfo.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.isComponentProvisionMethod(element)) {
messager.printMessage(Kind.ERROR, "Injecting components is not supported: " + element);
} else if (utils.isSubcomponentProvisionMethod(element)) {
generateGetSubcomponentMethod((ExecutableElement) element, injectorBuilder);
} else if (utils.isProvisionMethodInInjector(element)) {
if (!miscMethodNames.add(method.getSimpleName().toString())) {
continue;
}
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().$L()";
methodBuilder.addStatement(statement, utils.getGetMethodName(packagedInjectorClassName), 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, injector));
}
}
}
// Methods to get packaged injectors.
for (Map.Entry<ClassName, TypeSpec.Builder> entry : packagedInjectorBuilders.entrySet()) {
ClassName injectorClassName = entry.getKey();
if (!coreInjectorInfo.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(coreInjectorInfo) != null) {
ClassName containingPackageInjectorClassName = getInjectorNameOfScope(injectorClassName, componentTree.get(coreInjectorInfo).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());
}
// Builder and builder().
generateInjectorBuilder(coreInjectorInfo, injectorBuilder);
ClassName builderClassName = getTopLevelInjectorBuilderClassName(coreInjectorInfo);
MethodSpec.Builder methodSpecBuilder = // "Dagger compatible component will have "builder()", we need a different name.
MethodSpec.methodBuilder("getBuilder").addModifiers(Modifier.PUBLIC, Modifier.STATIC).returns(builderClassName).addStatement("return new $T()", builderClassName);
injectorBuilder.addMethod(methodSpecBuilder.build());
// provision methods for (sub)component builders that can be provided by this core injector.
for (TypeElement b : coreInjectorToBothBuilderMap.get(coreInjectorInfo)) {
generateImplicitProvisionMethodForEitherComponentBuilderInTopLevelInjector(injectorBuilder, b);
}
// Write
JavaFile javaFile = JavaFile.builder(topLevelPackageString, injectorBuilder.build()).build();
try {
javaFile.writeTo(processingEnv.getFiler());
} catch (IOException e) {
messager.printMessage(Kind.ERROR, e.toString());
}
}
}
use of com.squareup.javapoet.JavaFile in project tiger by google.
the class CoreInjectorGenerator method generatePackagedInjectors.
private void generatePackagedInjectors() {
for (CoreInjectorInfo coreInjectorInfo : orderedCoreinjectors) {
Set<ClassName> injected = new HashSet<>();
Set<TypeElement> components = Sets.newHashSet(coreInjectorToComponentMap.get(coreInjectorInfo));
for (TypeElement c : components) {
for (Element e : elements.getAllMembers(c)) {
messager.printMessage(Kind.NOTE, "generatePackagedInjectors: element: " + e);
if (!utils.isMethod(e)) {
continue;
}
ExecutableElement method = (ExecutableElement) e;
ExecutableType methodType = ((ExecutableType) types.asMemberOf(((DeclaredType) c.asType()), e));
if (utils.isInjectionMethod(method)) {
TypeElement injectedTypeElement = (TypeElement) ((DeclaredType) Iterables.getOnlyElement(methodType.getParameterTypes())).asElement();
if (!injected.add(ClassName.get(injectedTypeElement))) {
continue;
}
messager.printMessage(Kind.NOTE, TAG + ".generatePackagedInjectors: injection method for: " + injectedTypeElement);
generateInjectionMethod(injectedTypeElement, coreInjectorInfo.getScope());
} else if (utils.isProvisionMethodInInjector(method)) {
generateProvisionMethodIfNeeded(utils.getKeyProvidedByMethod((ExecutableElement) method), c);
} else {
// TODO: ignore known elements like builders.
messager.printMessage(Kind.WARNING, String.format("Unknown element %s from injector %s.", method, c));
}
}
}
}
messager.printMessage(Kind.NOTE, TAG + ".generatePackagedInjectors. packagedInjectorBuilders: " + packagedInjectorBuilders);
// Inherited provision methods.
for (CoreInjectorInfo component : orderedCoreinjectors) {
if (componentTree.get(component) == null) {
continue;
}
for (Map.Entry<ClassName, TypeSpec.Builder> entry : packagedInjectorBuilders.entrySet()) {
ClassName packagedInjectorClassName = entry.getKey();
if (!component.equals(getComponentFromPackagedInjectorClassName(packagedInjectorClassName))) {
continue;
}
generateInheritedProvisionMethods(packagedInjectorClassName);
}
}
// Inherited injection methods.
for (CoreInjectorInfo component : orderedCoreinjectors) {
if (componentTree.get(component) == null) {
continue;
}
for (Map.Entry<ClassName, TypeSpec.Builder> entry : packagedInjectorBuilders.entrySet()) {
ClassName packagedInjectorClassName = entry.getKey();
if (!component.equals(getComponentFromPackagedInjectorClassName(packagedInjectorClassName))) {
continue;
}
generateInheritedInjectionMethods(packagedInjectorClassName);
}
}
for (Map.Entry<ClassName, TypeSpec.Builder> entry : packagedInjectorBuilders.entrySet()) {
String packageString = entry.getKey().packageName();
TypeSpec.Builder builder = entry.getValue();
JavaFile javaFile = JavaFile.builder(packageString, builder.build()).build();
// messager.printMessage(Kind.NOTE, String.format("java file: %s", javaFile));
try {
javaFile.writeTo(processingEnv.getFiler());
} catch (IOException e) {
Throwables.propagate(e);
}
}
}
use of com.squareup.javapoet.JavaFile in project tiger by google.
the class TailChaser method chase.
public void chase() {
TypeSpec.Builder builder = TypeSpec.classBuilder("Tail" + round++).addModifiers(Modifier.PUBLIC).addAnnotation(Tail.class);
JavaFile javaFile = JavaFile.builder("tiger", builder.build()).build();
try {
javaFile.writeTo(filer);
} catch (IOException e) {
e.printStackTrace();
}
}
use of com.squareup.javapoet.JavaFile in project tiger by google.
the class Tiger3ProcessorForComponent method handleHub.
@Override
protected void handleHub() {
prepairForHubInjectorGeneration();
generateHubInjectors(allEitherComponents, componentToParentMap);
JavaFile javaFile = JavaFile.builder("tiger", debugBuilder.build()).build();
try {
javaFile.writeTo(processingEnv.getFiler());
} catch (IOException e) {
logger.e("write to %s failed: %s", javaFile, e);
}
}
use of com.squareup.javapoet.JavaFile in project tiger by google.
the class Tiger4ProcessorForComponent method handleHub.
@Override
protected void handleHub() {
prepairForHubInjectorGeneration();
generateHubInjectors(allEitherComponents, componentToParentMap);
JavaFile javaFile = JavaFile.builder("tiger", debugBuilder.build()).build();
try {
javaFile.writeTo(processingEnv.getFiler());
} catch (IOException e) {
logger.e("write to %s failed: %s", javaFile, e);
}
}
Aggregations