use of com.squareup.javapoet.TypeName in project tiger by google.
the class HubInjectorGenerator method generateInjectorBuilder.
/**
* Subcomponents has 1 ctor parameter, which is the parent (sub)component. Components has 0 ctor
* parameter and 0 or more dependecies.
*/
protected void generateInjectorBuilder(@Nullable TypeElement expliciteBuilder) {
logger.n("component: " + eitherComponent + " explicit: " + (expliciteBuilder != null));
Preconditions.checkArgument(utils.isEitherComponent(eitherComponent), "Expect (sub)component, but found: " + eitherComponent);
boolean explicit = expliciteBuilder != null;
boolean isSubcomponent = utils.isSubcomponent(eitherComponent);
// logger.n("pos: 1");
String packageString = utils.getPackageString(eitherComponent);
String generatedComponentSimpleName = utils.getComponentImplementationSimpleNameFromInterface(eitherComponent);
ClassName componentClassName = ClassName.get(packageString, generatedComponentSimpleName);
// logger.n("pos: 2");
// Generate class header.
String builderName = explicit ? expliciteBuilder.getSimpleName().toString() : "Builder";
Builder builderBuilder = TypeSpec.classBuilder(builderName).addModifiers(Modifier.PUBLIC, Modifier.STATIC);
// logger.n("pos: 3");
if (explicit) {
ElementKind kind = expliciteBuilder.getKind();
ClassName superName = ClassName.get(eitherComponent).nestedClass(builderName);
if (kind.equals(ElementKind.INTERFACE)) {
builderBuilder.addSuperinterface(superName);
} else {
Preconditions.checkState(kind.equals(ElementKind.CLASS), TAG + " unexpected kind for builder: " + expliciteBuilder);
builderBuilder.superclass(superName);
}
}
// ctor for subcomponent.
if (isSubcomponent) {
TypeName parentComponentTypeName = getSubcomponentParentInterfaceClassName(eitherComponent);
String parentComponentSourceCodeName = Utils.getSourceCodeName(parentComponentTypeName);
builderBuilder.addField(FieldSpec.builder(parentComponentTypeName, parentComponentSourceCodeName, Modifier.PRIVATE).build());
MethodSpec.Builder ctorBuilder = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC);
ctorBuilder.addParameter(parentComponentTypeName, parentComponentSourceCodeName).addCode("this.$N = $N;", parentComponentSourceCodeName, parentComponentSourceCodeName);
builderBuilder.addMethod(ctorBuilder.build());
}
/**
* Set deps methods.
*/
for (TypeElement m : componentDependencies) {
String methodName = explicit ? Preconditions.checkNotNull(utils.getBuilderSetterName(types, elements, expliciteBuilder, m)) : null;
logger.l(Kind.NOTE, "componentDependency: %s", m);
utils.addSetMethod(types, elements, componentClassName, builderBuilder, ClassName.get(m.asType()), methodName, builderName);
}
// logger.n("pos: 6");
/**
* Set @BindsInstance methods.
*/
/**
* TODO: refactor this. see {@link #collectComponentToBindsInstanceMap()}
*/
// if (isSubcomponent) {
// instanceDeps.remove(BindingKey.get(componentToParentMap.get(component)));
// } else {
// if (dependencyComponent != null) {
// instanceDeps.remove(BindingKey.get(dependencyComponent));
// }
// }
// for (TypeElement typeElement :componentToComponentDependencyMap.get(component)) {
// instanceDeps.remove(BindingKey.get(typeElement));
// }
// for (TypeElement typeElement :sortedPassedModules) {
// instanceDeps.remove(BindingKey.get(typeElement));
// }
logger.l(Kind.NOTE, "instanceDeps" + bindsInstances);
for (BindingKey key : bindsInstances) {
String methodName = explicit ? Preconditions.checkNotNull(utils.getBuilderSetterName(types, elements, expliciteBuilder, key)) : null;
ClassName builderParentClassName = componentClassName;
if (explicit) {
ExecutableElement setter = utils.getBuilderSetter(types, elements, expliciteBuilder, key);
if (setter.getReturnType().getKind() == TypeKind.VOID) {
builderParentClassName = null;
}
}
logger.l(Kind.NOTE, "@BindsInstance " + key);
utils.addSetMethod(types, elements, builderParentClassName, builderBuilder, key, methodName, builderName);
}
/**
* Set module methods.
*/
for (TypeElement m : nonNullaryCtorModules) {
String methodName = explicit ? Preconditions.checkNotNull(utils.getBuilderSetterName(types, elements, expliciteBuilder, m)) : null;
logger.l(Kind.NOTE, "nonNullaryCtorModules: %s", m);
utils.addSetMethod(types, elements, componentClassName, builderBuilder, ClassName.get(m.asType()), methodName, builderName);
}
// build() method.
String methodName = explicit ? utils.getBuildMethod(processingEnv.getTypeUtils(), elements, expliciteBuilder).getSimpleName().toString() : "build";
MethodSpec.Builder buildMethodBuilder = MethodSpec.methodBuilder(methodName).addModifiers(Modifier.PUBLIC).returns(componentClassName);
StringBuilder returnCodeBuilder = new StringBuilder("return new $T(");
for (BindingKey key : utils.sortBindingKeys(getAllCtorParameters())) {
returnCodeBuilder.append(Utils.getSourceCodeNameHandlingBox(key, dependencies)).append(", ");
}
if (returnCodeBuilder.charAt(returnCodeBuilder.length() - 1) != '(') {
returnCodeBuilder.delete(returnCodeBuilder.length() - 2, returnCodeBuilder.length());
}
returnCodeBuilder.append(");");
logger.l(Kind.NOTE, "generateInjectorBuilder, return string: %s", returnCodeBuilder.toString());
buildMethodBuilder.addCode(returnCodeBuilder.toString(), componentClassName);
builderBuilder.addMethod(buildMethodBuilder.build());
injectorBuilder.addType(builderBuilder.build());
}
use of com.squareup.javapoet.TypeName in project tiger by google.
the class HubInjectorGenerator method generateGenericInjectorIfNeeded.
private void generateGenericInjectorIfNeeded(DependencyInfo dependencyInfo) {
BindingKey dependant = dependencyInfo.getDependant();
if (!generatedGenericInjectors.add(utils.getGenericInjectorName(dependant))) {
return;
}
TypeSpec.Builder genericInjectorBuilder = TypeSpec.classBuilder(utils.getGenericInjectorSimpleName(dependant)).addAnnotation(AnnotationSpec.builder(Generated.class).addMember("value", "$S", GENERATOR_NAME).build()).addModifiers(Modifier.PUBLIC);
TypeName returnType = dependant.getTypeName();
MethodSpec.Builder generateBuilder = MethodSpec.methodBuilder("generate").addModifiers(Modifier.PUBLIC).returns(returnType);
for (BindingKey key : utils.sortBindingKeys(dependencyInfo.getDependencies())) {
generateBuilder.addParameter(key.getTypeName(), utils.getSourceCodeName(key));
}
DeclaredType type = (DeclaredType) utils.getTypeFromTypeName(returnType);
TypeElement classElement = (TypeElement) type.asElement();
ExecutableElement ctor = Preconditions.checkNotNull(utils.findInjectedCtor(classElement), "injector ctor not found for dI: " + dependencyInfo);
TypeMirror ctorTypeMirror = types.asMemberOf(type, ctor);
List<BindingKey> ctorDependencies = utils.getCtorDependencies(dependencies, dependant);
StringBuilder statementBuilder = new StringBuilder("$T result = new $T(");
for (BindingKey key : ctorDependencies) {
statementBuilder.append(utils.getSourceCodeName(key)).append(", ");
}
utils.trimTrailing(statementBuilder, ", ");
statementBuilder.append(")");
generateBuilder.addStatement(statementBuilder.toString(), returnType, returnType);
for (Element element : classElement.getEnclosedElements()) {
if (element.getKind().equals(ElementKind.FIELD) && utils.isInjected(element)) {
generateBuilder.addStatement("result.$N = $L", element.getSimpleName(), utils.getSourceCodeName(utils.getKeyForField(type, element)));
}
if (element.getKind().equals(ElementKind.METHOD) && utils.isInjected(element)) {
statementBuilder = new StringBuilder("result.$L(");
for (BindingKey key : utils.getDependenciesFromMethod((ExecutableType) types.asMemberOf(type, element), (ExecutableElement) element)) {
statementBuilder.append(utils.getSourceCodeName(key)).append(", ");
}
utils.trimTrailing(statementBuilder, ", ");
statementBuilder.append(")");
generateBuilder.addStatement(statementBuilder.toString(), element.getSimpleName());
}
}
generateBuilder.addStatement("return result");
genericInjectorBuilder.addMethod(generateBuilder.build());
JavaFile javaFile = JavaFile.builder(utils.getPackageString(utils.getClassFromKey(dependant)), genericInjectorBuilder.build()).build();
try {
javaFile.writeTo(processingEnv.getFiler());
} catch (IOException e) {
e.printStackTrace();
}
}
use of com.squareup.javapoet.TypeName in project tiger by google.
the class HubInjectorGenerator method generateGetPackagedInjectorMethodInternal.
/**
* generate a getXXX_internal() that xxx packaged injector.
*/
protected void generateGetPackagedInjectorMethodInternal(String packageString) {
ClassName packagedInjectorClassName = getPackagedInjectorClassName(packageString);
StringBuilder statementBuilder = new StringBuilder("return new $T(");
TypeElement packagedInjectorTypeElement = utils.getTypeElementForClassName(packagedInjectorClassName);
if (packagedInjectorTypeElement == null) {
logger.e("packaged injector not found: %s", packagedInjectorClassName);
return;
}
ExecutableElement ctor = utils.findCtor(packagedInjectorTypeElement);
for (BindingKey key : utils.getDependenciesFromExecutableElement(ctor)) {
TypeName typeName = key.getTypeName();
if (typeName.equals(ClassName.get(packageString, PackagedHubInterfaceGenerator.HUB_INTERFACE))) {
statementBuilder.append("this, ");
} else {
// nonNullaryCtor ones
TypeElement module = utils.getTypeElement(key);
Preconditions.checkState(utils.isModule(module));
if (modules.contains(module)) {
statementBuilder.append(utils.getSourceCodeName(typeName)).append(", ");
} else {
// modules belongs to lower scopes, whill never be used at this scope.
statementBuilder.append("null, ");
}
}
}
if (statementBuilder.substring(statementBuilder.length() - 2).equals(", ")) {
statementBuilder.delete(statementBuilder.length() - 2, statementBuilder.length());
}
statementBuilder.append(")");
injectorBuilder.addMethod(MethodSpec.methodBuilder(getInternalPackagedInjectorGetterName(packagedInjectorClassName)).addModifiers(Modifier.PRIVATE).returns(packagedInjectorClassName).addStatement(statementBuilder.toString(), packagedInjectorClassName).build());
}
use of com.squareup.javapoet.TypeName in project tiger by google.
the class DependencyCollector method collectionToMultimap.
/**
* NOTE: the key of the returned map is of the raw type if the related
* {@link DependencyInfo#getDependant()} is for a generic class.
*/
public static SetMultimap<BindingKey, DependencyInfo> collectionToMultimap(Collection<DependencyInfo> dependencies) {
SetMultimap<BindingKey, DependencyInfo> result = HashMultimap.create();
for (DependencyInfo info : dependencies) {
BindingKey key = info.getDependant();
TypeName typeName = key.getTypeName();
// For generic type with type variable, only keep raw type.
if (typeName instanceof ParameterizedTypeName) {
ParameterizedTypeName parameterizedTypeName = (ParameterizedTypeName) typeName;
TypeName anyParameter = Preconditions.checkNotNull(Iterables.getFirst(parameterizedTypeName.typeArguments, null), String.format("ParameterizedTypeName of %s has no parameter.", key));
if (anyParameter instanceof TypeVariableName) {
typeName = parameterizedTypeName.rawType;
key = BindingKey.get(typeName, key.getQualifier());
}
}
result.put(key, info);
}
return result;
}
use of com.squareup.javapoet.TypeName in project tiger by google.
the class DependencyCollector method addDependencyInfo.
/**
* Adds the give {@link DependencyInfo} to the map, handling generic type with formal
* parameters. Returns if it changed the given map.
*/
private boolean addDependencyInfo(SetMultimap<BindingKey, DependencyInfo> existingDependencies, DependencyInfo info) {
checkOneDependency(existingDependencies, info);
BindingKey key = info.getDependant();
TypeName typeName = key.getTypeName();
// For generic type with type variable, only keep raw type.
if (typeName instanceof ParameterizedTypeName) {
ParameterizedTypeName parameterizedTypeName = (ParameterizedTypeName) typeName;
for (TypeName anyParameter : parameterizedTypeName.typeArguments) {
if (anyParameter instanceof TypeVariableName) {
logger.e("unexpected type with TypeVariable: " + typeName);
// typeName = parameterizedTypeName.rawType;
// key = BindingKey.get(typeName, key.getQualifier());
}
}
}
/**
* TODO: remove this. This hack elimite duplicate UNIQUE deps. It depends on the order deps are
* collected, module->componentDependencies->bindsInstance. Check the warning from {@link
* #checkOneDependency(SetMultimap, DependencyInfo)}.
*/
if (info.getType().equals(UNIQUE) && existingDependencies.containsKey(key)) {
DependencyInfo old = Iterables.getOnlyElement(existingDependencies.get(key));
if (shouldKeep(info, old)) {
logger.w(TAG + ".addDependencyInfo: old info is stronger then the new one. Old: " + old + " new: " + info);
return false;
} else {
existingDependencies.get(key).clear();
}
}
boolean result = existingDependencies.put(key, info);
Preconditions.checkState(result, "failed to add dependency: " + info);
return true;
}
Aggregations