private TypeSpec buildModule(ModuleSpec spec) { CodeBlock.Builder blockBuilder = CodeBlock.builder().add("return new $T(", spec.getPresenterTypeName()); int i = 0; for (ParameterSpec parameterSpec : spec.getPresenterArgs()) { blockBuilder.add(parameterSpec.name); if (i++ < spec.getPresenterArgs().size() - 1) { blockBuilder.add(", "); } } blockBuilder.add(");\n"); MethodSpec.Builder methodSpecBuilder = MethodSpec.methodBuilder("providesPresenter") .addModifiers(Modifier.PUBLIC) .returns(spec.getPresenterTypeName()) .addAnnotation(Provides.class) .addParameters(spec.getProvideParameters()) .addCode(blockBuilder.build()); if (spec.getScopeAnnotationSpec() != null) { methodSpecBuilder.addAnnotation(spec.getScopeAnnotationSpec()); } return TypeSpec.classBuilder(spec.getClassName().simpleName()) .addModifiers(Modifier.PUBLIC) .addAnnotation(Module.class) .addMethod(methodSpecBuilder.build()) .build(); }
private CodeBlock buildPopulateValuesIntoCursor() { CodeBlock.Builder builder = CodeBlock.builder(); List<ColumnDefinition> columns = schema.getColumns(); for (int i = 0; i < columns.size(); i++) { ColumnDefinition c = columns.get(i); RelationDefinition r = c.getRelation(); TypeName type = c.getUnboxType(); if (r == null) { CodeBlock.Builder getCursorExpr = CodeBlock.builder(); if (Types.needsTypeAdapter(type)) { getCursorExpr.add( "conn.getTypeAdapterRegistry().$L($T.$L.type, $L)", c.nullable ? "deserializeNullable" : "deserialize", schema.getSchemaClassName(), c.name, cursorGetter(c, i)); } else { getCursorExpr.add("$L", cursorGetter(c, i)); } if (c.setter != null) { builder.addStatement("model.$L($L)", c.setter.getSimpleName(), getCursorExpr.build()); } else { builder.addStatement("model.$L = $L", c.name, getCursorExpr.build()); } } else { // SingleRelation if (c.setter != null) { builder.addStatement( "model.$L(new $T<>(conn, OrmaDatabase.schema$T, cursor.getLong($L)))", c.setter.getSimpleName(), r.relationType, r.modelType, i); } else { builder.addStatement( "model.$L = new $T<>(conn, OrmaDatabase.schema$T, cursor.getLong($L))", c.name, r.relationType, r.modelType, i); } } } return builder.build(); }
private void columnAnnotationClassArrayAnnotationValue( CodeBlock.Builder code, Iterator<ForeignKeyPartMethodInfo> iterator, Function<ForeignKeyPartMethodInfo, TypeName> typeNameMapper) { ForeignKeyPartMethodInfo part = iterator.next(); code.add("$T.class", typeNameMapper.apply(part)); }
private CodeBlock annotationClassArrayAnnotationValue( Function<ForeignKeyPartMethodInfo, TypeName> typeNameMapper) { CodeBlock.Builder code = CodeBlock.builder(); code.add("{ "); List<ForeignKeyPartMethodInfo> keyPartList = keyPartList(); Iterator<ForeignKeyPartMethodInfo> iterator = keyPartList.iterator(); if (iterator.hasNext()) { columnAnnotationClassArrayAnnotationValue(code, iterator, typeNameMapper); while (iterator.hasNext()) { code.add(", "); columnAnnotationClassArrayAnnotationValue(code, iterator, typeNameMapper); } } return code.add(" }").build(); }
private CodeBlock buildCreateModelFromCursor() { CodeBlock.Builder builder = CodeBlock.builder(); builder.addStatement( "$T model = new $T()", schema.getModelClassName(), schema.getModelClassName()); // FIXME builder.add(buildPopulateValuesIntoCursor()); builder.addStatement("return model"); return builder.build(); }
public CodeBlock buildColumnsInitializer(List<FieldSpec> columns) { CodeBlock.Builder builder = CodeBlock.builder(); builder.add("$T.<$T>asList(\n", Types.Arrays, Types.WildcardColumnDef).indent(); for (int i = 0; i < columns.size(); i++) { builder.add("$N", columns.get(i)); if ((i + 1) != columns.size()) { builder.add(",\n"); } else { builder.add("\n"); } } builder.unindent().add(")"); return builder.build(); }
public CodeBlock buildEscapedColumnNamesInitializer() { CodeBlock.Builder builder = CodeBlock.builder(); builder.add("{\n").indent(); List<ColumnDefinition> columns = schema.getColumns(); for (int i = 0; i < columns.size(); i++) { builder.add("$S", '"' + columns.get(i).columnName + '"'); if ((i + 1) != columns.size()) { builder.add(",\n"); } else { builder.add("\n"); } } builder.unindent().add("}"); return builder.build(); }
public Builder addJavadoc(String format, Object... args) { javadoc.add(format, args); return this; }
@Override public void onWriteDefinition(TypeSpec.Builder typeBuilder) { typeBuilder.addField( FieldSpec.builder( ClassName.get(String.class), AUTHORITY, Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL) .initializer("$S", authority) .build()); int code = 0; for (TableEndpointDefinition endpointDefinition : endpointDefinitions) { for (ContentUriDefinition contentUriDefinition : endpointDefinition.contentUriDefinitions) { typeBuilder.addField( FieldSpec.builder( TypeName.INT, contentUriDefinition.name, Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL) .initializer(String.valueOf(code)) .build()); code++; } } FieldSpec.Builder uriField = FieldSpec.builder( ClassNames.URI_MATCHER, URI_MATCHER, Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL); CodeBlock.Builder initializer = CodeBlock.builder() .addStatement("new $T($T.NO_MATCH)", ClassNames.URI_MATCHER, ClassNames.URI_MATCHER) .add("static {\n"); for (TableEndpointDefinition endpointDefinition : endpointDefinitions) { for (ContentUriDefinition contentUriDefinition : endpointDefinition.contentUriDefinitions) { String path; if (contentUriDefinition.path != null) { path = "\"" + contentUriDefinition.path + "\""; } else { path = CodeBlock.builder() .add( "$L.$L.getPath()", contentUriDefinition.elementClassName, contentUriDefinition.name) .build() .toString(); } initializer.addStatement( "$L.addURI($L, $L, $L)", URI_MATCHER, AUTHORITY, path, contentUriDefinition.name); } } initializer.add("}\n"); typeBuilder.addField(uriField.initializer(initializer.build()).build()); typeBuilder.addMethod( MethodSpec.methodBuilder("getDatabaseName") .addAnnotation(Override.class) .addModifiers(Modifier.PUBLIC, Modifier.FINAL) .addStatement("return $S", databaseNameString) .returns(ClassName.get(String.class)) .build()); MethodSpec.Builder getTypeBuilder = MethodSpec.methodBuilder("getType") .addAnnotation(Override.class) .addParameter(ClassNames.URI, "uri") .returns(ClassName.get(String.class)) .addModifiers(Modifier.PUBLIC, Modifier.FINAL); CodeBlock.Builder getTypeCode = CodeBlock.builder() .addStatement("$T type = null", ClassName.get(String.class)) .beginControlFlow("switch($L.match(uri))", URI_MATCHER); for (TableEndpointDefinition tableEndpointDefinition : endpointDefinitions) { for (ContentUriDefinition uriDefinition : tableEndpointDefinition.contentUriDefinitions) { getTypeCode .beginControlFlow("case $L:", uriDefinition.name) .addStatement("type = $S", uriDefinition.type) .addStatement("break") .endControlFlow(); } } getTypeCode .beginControlFlow("default:") .addStatement( "throw new $T($S + $L)", ClassName.get(IllegalArgumentException.class), "Unknown URI", "uri") .endControlFlow(); getTypeCode.endControlFlow(); getTypeCode.addStatement("return type"); getTypeBuilder.addCode(getTypeCode.build()); typeBuilder.addMethod(getTypeBuilder.build()); for (MethodDefinition method : methods) { MethodSpec methodSpec = method.getMethodSpec(); if (methodSpec != null) { typeBuilder.addMethod(methodSpec); } } }
public Builder addStatement(String format, Object... args) { add("$["); add(format, args); add(";\n$]"); return this; }
/** * @param controlFlow the optional control flow construct and its code, such as "while(foo == * 20)". Only used for "do/while" control flows. */ public Builder endControlFlow(String controlFlow, Object... args) { unindent(); add("} " + controlFlow + ";\n", args); return this; }
public Builder endControlFlow() { unindent(); add("}\n"); return this; }
/** * @param controlFlow the control flow construct and its code, such as "if (foo == 5)". * Shouldn't contain braces or newline characters. */ public Builder beginControlFlow(String controlFlow, Object... args) { add(controlFlow + " {\n", args); indent(); return this; }
@Override Optional<TypeSpec.Builder> write(ClassName generatedTypeName, ProvisionBinding binding) { // We don't want to write out resolved bindings -- we want to write out the generic version. checkState(!binding.unresolved().isPresent()); TypeMirror keyType = binding.contributionType().equals(ContributionType.MAP) ? MapType.from(binding.key().type()).unwrappedValueType(Provider.class) : binding.key().type(); TypeName providedTypeName = TypeName.get(keyType); ParameterizedTypeName parameterizedFactoryName = factoryOf(providedTypeName); Optional<ParameterizedTypeName> factoryOfRawTypeName = Optional.absent(); TypeSpec.Builder factoryBuilder; Optional<MethodSpec.Builder> constructorBuilder = Optional.absent(); ImmutableList<TypeVariableName> typeParameters = bindingTypeElementTypeVariableNames(binding); ImmutableMap<BindingKey, FrameworkField> fields = generateBindingFieldsForDependencies(dependencyRequestMapper, binding); switch (binding.factoryCreationStrategy()) { case ENUM_INSTANCE: factoryBuilder = enumBuilder(generatedTypeName.simpleName()).addEnumConstant("INSTANCE"); // If we have type parameters, then remove the parameters from our providedTypeName, // since we'll be implementing an erased version of it. if (!typeParameters.isEmpty()) { factoryBuilder.addAnnotation(SUPPRESS_WARNINGS_RAWTYPES); // TODO(ronshapiro): instead of reassigning, introduce an optional/second parameter providedTypeName = ((ParameterizedTypeName) providedTypeName).rawType; factoryOfRawTypeName = Optional.of(factoryOf(providedTypeName)); } break; case CLASS_CONSTRUCTOR: factoryBuilder = classBuilder(generatedTypeName.simpleName()) .addTypeVariables(typeParameters) .addModifiers(FINAL); constructorBuilder = Optional.of(constructorBuilder().addModifiers(PUBLIC)); if (binding.bindingKind().equals(PROVISION) && !binding.bindingElement().getModifiers().contains(STATIC)) { addConstructorParameterAndTypeField( TypeName.get(binding.bindingTypeElement().asType()), "module", factoryBuilder, constructorBuilder.get()); } for (FrameworkField bindingField : fields.values()) { addConstructorParameterAndTypeField( bindingField.javapoetFrameworkType(), bindingField.name(), factoryBuilder, constructorBuilder.get()); } break; default: throw new AssertionError(); } factoryBuilder .addModifiers(PUBLIC) .addSuperinterface(factoryOfRawTypeName.or(parameterizedFactoryName)); // If constructing a factory for @Inject or @Provides bindings, we use a static create method // so that generated components can avoid having to refer to the generic types // of the factory. (Otherwise they may have visibility problems referring to the types.) Optional<MethodSpec> createMethod; switch (binding.bindingKind()) { case INJECTION: case PROVISION: // The return type is usually the same as the implementing type, except in the case // of enums with type variables (where we cast). MethodSpec.Builder createMethodBuilder = methodBuilder("create") .addModifiers(PUBLIC, STATIC) .addTypeVariables(typeParameters) .returns(parameterizedFactoryName); List<ParameterSpec> params = constructorBuilder.isPresent() ? constructorBuilder.get().build().parameters : ImmutableList.<ParameterSpec>of(); createMethodBuilder.addParameters(params); switch (binding.factoryCreationStrategy()) { case ENUM_INSTANCE: if (typeParameters.isEmpty()) { createMethodBuilder.addStatement("return INSTANCE"); } else { // We use an unsafe cast here because the types are different. // It's safe because the type is never referenced anywhere. createMethodBuilder.addStatement("return ($T) INSTANCE", TypeNames.FACTORY); createMethodBuilder.addAnnotation(SUPPRESS_WARNINGS_UNCHECKED); } break; case CLASS_CONSTRUCTOR: createMethodBuilder.addStatement( "return new $T($L)", javapoetParameterizedGeneratedTypeNameForBinding(binding), makeParametersCodeBlock(Lists.transform(params, CodeBlocks.PARAMETER_NAME))); break; default: throw new AssertionError(); } createMethod = Optional.of(createMethodBuilder.build()); break; default: createMethod = Optional.absent(); } if (constructorBuilder.isPresent()) { factoryBuilder.addMethod(constructorBuilder.get().build()); } List<CodeBlock> parameters = Lists.newArrayList(); for (DependencyRequest dependency : binding.dependencies()) { parameters.add( frameworkTypeUsageStatement( CodeBlocks.format("$L", fields.get(dependency.bindingKey()).name()), dependency.kind())); } CodeBlock parametersCodeBlock = makeParametersCodeBlock(parameters); MethodSpec.Builder getMethodBuilder = methodBuilder("get") .returns(providedTypeName) .addAnnotation(Override.class) .addModifiers(PUBLIC); if (binding.bindingKind().equals(PROVISION)) { CodeBlock.Builder providesMethodInvocationBuilder = CodeBlock.builder(); if (binding.bindingElement().getModifiers().contains(STATIC)) { providesMethodInvocationBuilder.add("$T", ClassName.get(binding.bindingTypeElement())); } else { providesMethodInvocationBuilder.add("module"); } providesMethodInvocationBuilder.add( ".$L($L)", binding.bindingElement().getSimpleName(), parametersCodeBlock); CodeBlock providesMethodInvocation = providesMethodInvocationBuilder.build(); if (binding.provisionType().equals(SET)) { TypeName paramTypeName = TypeName.get(MoreTypes.asDeclared(keyType).getTypeArguments().get(0)); // TODO(cgruber): only be explicit with the parameter if paramType contains wildcards. getMethodBuilder.addStatement( "return $T.<$T>singleton($L)", Collections.class, paramTypeName, providesMethodInvocation); } else if (binding.nullableType().isPresent() || nullableValidationType.equals(Diagnostic.Kind.WARNING)) { if (binding.nullableType().isPresent()) { getMethodBuilder.addAnnotation((ClassName) TypeName.get(binding.nullableType().get())); } getMethodBuilder.addStatement("return $L", providesMethodInvocation); } else { String failMsg = CANNOT_RETURN_NULL_FROM_NON_NULLABLE_PROVIDES_METHOD; getMethodBuilder .addStatement( "$T provided = $L", getMethodBuilder.build().returnType, providesMethodInvocation) .addCode("if (provided == null) { ") .addStatement("throw new $T($S)", NullPointerException.class, failMsg) .addCode("}") .addStatement("return provided"); } } else if (binding.membersInjectionRequest().isPresent()) { getMethodBuilder.addStatement( "$1T instance = new $1T($2L)", providedTypeName, parametersCodeBlock); getMethodBuilder.addStatement( "$L.injectMembers(instance)", fields.get(binding.membersInjectionRequest().get().bindingKey()).name()); getMethodBuilder.addStatement("return instance"); } else { getMethodBuilder.addStatement("return new $T($L)", providedTypeName, parametersCodeBlock); } factoryBuilder.addMethod(getMethodBuilder.build()); if (createMethod.isPresent()) { factoryBuilder.addMethod(createMethod.get()); } // TODO(gak): write a sensible toString return Optional.of(factoryBuilder); }