Esempio n. 1
0
  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();
  }
Esempio n. 2
0
  public FieldSpec buildRowIdColumnFieldSpec() {
    String name = "_rowid_";
    TypeName columnDefType = ParameterizedTypeName.get(Types.ColumnDef, TypeName.LONG.box());

    CodeBlock initializer;
    initializer =
        CodeBlock.builder()
            .add(
                "new $T($S, $T.class, $L, $L, $L, $L, $L, $L)",
                columnDefType,
                name,
                TypeName.LONG,
                false /* nullable */,
                true /* primary key */,
                false /* autoincrement */,
                true /* autoId */,
                false,
                false)
            .build();

    return FieldSpec.builder(columnDefType, name)
        .addModifiers(publicStaticFinal)
        .initializer(initializer)
        .build();
  }
Esempio n. 3
0
  public static final class Builder {
    private final TypeName type;
    private final String name;

    private final CodeBlock.Builder javadoc = CodeBlock.builder();
    private final List<AnnotationSpec> annotations = new ArrayList<>();
    private final List<Modifier> modifiers = new ArrayList<>();
    private CodeBlock initializer = null;

    private Builder(TypeName type, String name) {
      this.type = type;
      this.name = name;
    }

    public Builder addJavadoc(String format, Object... args) {
      javadoc.add(format, args);
      return this;
    }

    public Builder addAnnotations(Iterable<AnnotationSpec> annotationSpecs) {
      checkArgument(annotationSpecs != null, "annotationSpecs == null");
      for (AnnotationSpec annotationSpec : annotationSpecs) {
        this.annotations.add(annotationSpec);
      }
      return this;
    }

    public Builder addAnnotation(AnnotationSpec annotationSpec) {
      this.annotations.add(annotationSpec);
      return this;
    }

    public Builder addAnnotation(ClassName annotation) {
      this.annotations.add(AnnotationSpec.builder(annotation).build());
      return this;
    }

    public Builder addAnnotation(Class<?> annotation) {
      return addAnnotation(ClassName.get(annotation));
    }

    public Builder addModifiers(Modifier... modifiers) {
      Collections.addAll(this.modifiers, modifiers);
      return this;
    }

    public Builder initializer(String format, Object... args) {
      return initializer(CodeBlock.builder().add(format, args).build());
    }

    public Builder initializer(CodeBlock codeBlock) {
      checkState(this.initializer == null, "initializer was already set");
      this.initializer = checkNotNull(codeBlock, "codeBlock == null");
      return this;
    }

    public FieldSpec build() {
      return new FieldSpec(this);
    }
  }
Esempio n. 4
0
  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();
  }
Esempio n. 5
0
 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();
 }
Esempio n. 6
0
 public Builder toBuilder() {
   Builder builder = new Builder(type, name);
   builder.javadoc.add(javadoc);
   builder.annotations.addAll(annotations);
   builder.modifiers.addAll(modifiers);
   builder.initializer = initializer.isEmpty() ? null : initializer;
   return builder;
 }
Esempio n. 7
0
  private CodeBlock versionSetInit() {
    CodeBlock.Builder init =
        CodeBlock.builder().add("versionSet = $T.builder()\n", VersionSet.class);

    schemaTypeInfo.acceptVersionSetInit(init);

    return init.addStatement("    .build()").build();
  }
Esempio n. 8
0
 private FieldSpec(Builder builder) {
   this.type = checkNotNull(builder.type, "type == null");
   this.name = checkNotNull(builder.name, "name == null");
   this.javadoc = builder.javadoc.build();
   this.annotations = Util.immutableList(builder.annotations);
   this.modifiers = Util.immutableSet(builder.modifiers);
   this.initializer =
       (builder.initializer == null) ? CodeBlock.builder().build() : builder.initializer;
 }
Esempio n. 9
0
  public FieldSpec buildColumnFieldSpec(ColumnDefinition c) {
    TypeName type = c.getType();

    CodeBlock initializer;
    if (type instanceof ParameterizedTypeName) {
      initializer =
          CodeBlock.builder()
              .add(
                  "new $T($S, $T.getType(new $T<$T>(){}), $L, $L, $L, $L, $L, $L)",
                  c.getColumnDefType(),
                  c.columnName,
                  Types.ParameterizedTypes,
                  Types.TypeHolder,
                  type,
                  c.nullable,
                  c.primaryKey,
                  c.autoincrement,
                  c.autoId,
                  c.indexed,
                  c.unique)
              .build();

    } else {
      initializer =
          CodeBlock.builder()
              .add(
                  "new $T($S, $T.class, $L, $L, $L, $L, $L, $L)",
                  c.getColumnDefType(),
                  c.columnName,
                  type,
                  c.nullable,
                  c.primaryKey,
                  c.autoincrement,
                  c.autoId,
                  c.indexed,
                  c.unique)
              .build();
    }

    return FieldSpec.builder(c.getColumnDefType(), c.name)
        .addModifiers(publicStaticFinal)
        .initializer(initializer)
        .build();
  }
Esempio n. 10
0
 public MethodSpec createShow() {
   return MethodSpec.methodBuilder("show")
       .addAnnotation(Override.class)
       .addModifiers(Modifier.PUBLIC)
       .returns(String.class)
       .addCode(
           CodeBlock.builder()
               .addStatement("return String.format(\"<$L>%s</$L>\", value)", tag, tag)
               .build())
       .build();
 }
Esempio n. 11
0
 public MethodSpec createCompareTo() {
   final String other = "other";
   return MethodSpec.methodBuilder("compareTo")
       .addAnnotation(Override.class)
       .addModifiers(Modifier.PUBLIC)
       .returns(int.class)
       .addParameter(ParameterSpec.builder(terminalTypeName, other, Modifier.FINAL).build())
       .addCode(
           CodeBlock.builder().addStatement("return value.compareTo($L.value)", other).build())
       .build();
 }
Esempio n. 12
0
 void emit(CodeWriter codeWriter, Set<Modifier> implicitModifiers) throws IOException {
   codeWriter.emitJavadoc(javadoc);
   codeWriter.emitAnnotations(annotations, false);
   codeWriter.emitModifiers(modifiers, implicitModifiers);
   codeWriter.emit("$T $L", type, name);
   if (!initializer.isEmpty()) {
     codeWriter.emit(" = ");
     codeWriter.emit(initializer);
   }
   codeWriter.emit(";\n");
 }
Esempio n. 13
0
  public void emitJavadoc(CodeBlock javadocCodeBlock) throws IOException {
    if (javadocCodeBlock.isEmpty()) return;

    emit("/**\n");
    javadoc = true;
    try {
      emit(javadocCodeBlock);
    } finally {
      javadoc = false;
    }
    emit(" */\n");
  }
Esempio n. 14
0
 public MethodSpec createHashCode() {
   return MethodSpec.methodBuilder("hashCode")
       .addAnnotation(Override.class)
       .addModifiers(Modifier.PUBLIC)
       .returns(int.class)
       .addCode(
           CodeBlock.builder()
               .addStatement("final int prime = $L", prime)
               .addStatement("return prime + value.hashCode()")
               .build())
       .build();
 }
Esempio n. 15
0
 public MethodSpec createValueGetter() {
   return MethodSpec.methodBuilder("value")
       .addAnnotation(Override.class)
       .addJavadoc(
           "Returns this {@code $L}'s value.\n\n@return this {@code $L}'s value.\n",
           terminalName,
           terminalName)
       .addModifiers(Modifier.PUBLIC)
       .returns(String.class)
       .addCode(CodeBlock.builder().addStatement("return value").build())
       .build();
 }
Esempio n. 16
0
  // http://developer.android.com/intl/ja/reference/android/database/sqlite/SQLiteStatement.html
  private CodeBlock buildBindArgs() {
    CodeBlock.Builder builder = CodeBlock.builder();

    List<ColumnDefinition> columns = schema.getColumnsWithoutAutoId();
    for (int i = 0; i < columns.size(); i++) {
      int n = i + 1; // bind index starts 1
      ColumnDefinition c = columns.get(i);
      TypeName type = c.getUnboxType();
      RelationDefinition r = c.getRelation();
      boolean nullable = !type.isPrimitive() && c.nullable;

      if (nullable) {
        builder.beginControlFlow("if (model.$L != null)", c.name);
      }

      if (type.equals(TypeName.BOOLEAN)) {
        builder.addStatement(
            "statement.bindLong($L, model.$L ? 1 : 0)", n, c.getColumnGetterExpr());
      } else if (Types.looksLikeIntegerType(type)) {
        builder.addStatement("statement.bindLong($L, model.$L)", n, c.getColumnGetterExpr());
      } else if (Types.looksLikeFloatType(type)) {
        builder.addStatement("statement.bindDouble($L, model.$L)", n, c.getColumnGetterExpr());
      } else if (type.equals(Types.ByteArray)) {
        builder.addStatement("statement.bindBlob($L, model.$L)", n, c.getColumnGetterExpr());
      } else if (type.equals(Types.String)) {
        builder.addStatement("statement.bindString($L, model.$L)", n, c.getColumnGetterExpr());
      } else if (r != null && r.relationType.equals(Types.SingleRelation)) {
        builder.addStatement(
            "statement.bindLong($L, model.$L.getId())", n, c.getColumnGetterExpr());
      } else {
        builder.addStatement(
            "statement.bindString($L, conn.getTypeAdapterRegistry().serialize($T.$L.type, model.$L))",
            n,
            schema.getSchemaClassName(),
            c.name,
            c.getColumnGetterExpr());
      }

      if (nullable) {
        builder.endControlFlow();
        builder.beginControlFlow("else");
        builder.addStatement("statement.bindNull($L)", n);
        builder.endControlFlow();
      }
    }

    return builder.build();
  }
Esempio n. 17
0
  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();
  }
Esempio n. 18
0
  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();
  }
Esempio n. 19
0
 public MethodSpec createPublicConstructor() {
   final ParameterSpec value =
       ParameterSpec.builder(String.class, "value", Modifier.FINAL)
           .addAnnotation(
               AnnotationSpec.builder(Text.class).addMember("required", "false").build())
           .build();
   return MethodSpec.constructorBuilder()
       .addJavadoc(
           "Creates a new {@code $L} instance.\n\n@param value the value representing the actual $L.\n",
           terminalName,
           simpleName)
       .addModifiers(Modifier.PUBLIC)
       .addParameter(value)
       .addCode(
           CodeBlock.builder()
               .addStatement("$T.checkNotNull(value, \"Missing 'value'.\")", Preconditions.class)
               .addStatement("this.value = value.trim()")
               .build())
       .build();
 }
Esempio n. 20
0
  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();
  }
Esempio n. 21
0
 public MethodSpec createEquals() {
   final ParameterSpec object =
       ParameterSpec.builder(Object.class, "object", Modifier.FINAL).build();
   return MethodSpec.methodBuilder("equals")
       .addAnnotation(Override.class)
       .addModifiers(Modifier.PUBLIC)
       .returns(boolean.class)
       .addParameter(object)
       .addCode(
           CodeBlock.builder()
               .beginControlFlow("if (this == $L)", object.name)
               .addStatement("return true")
               .endControlFlow()
               .beginControlFlow(
                   "if ($L == null || getClass() != $L.getClass())", object.name, object.name)
               .addStatement("return false")
               .endControlFlow()
               .addStatement(
                   "final $T other = ($T) $L", terminalTypeName, terminalTypeName, object.name)
               .addStatement("return value.equals(other.value)")
               .build())
       .build();
 }
  @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);
      }
    }
  }
Esempio n. 23
0
 final CodeBlock parseArgsCode() {
   CodeBlock.Builder code = CodeBlock.builder().add("    .$L(", propertyName);
   return parseArgsCode(code).add(")\n").build();
 }
Esempio n. 24
0
  @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);
  }
  public static DeriveResult<DerivedCodeSpec> derive(
      AlgebraicDataType adt, DeriveContext deriveContext, DeriveUtils deriveUtils) {

    // skip constructors for enums
    if (adt.typeConstructor().declaredType().asElement().getKind() == ElementKind.ENUM) {
      return result(none());
    }

    TypeConstructor typeConstructor = adt.typeConstructor();
    TypeElement lazyTypeElement =
        FlavourImpl.findF0(deriveContext.flavour(), deriveUtils.elements());
    TypeName lazyArgTypeName =
        TypeName.get(
            deriveUtils.types().getDeclaredType(lazyTypeElement, typeConstructor.declaredType()));
    String lazyArgName = Utils.uncapitalize(typeConstructor.typeElement().getSimpleName());
    TypeName typeName = TypeName.get(typeConstructor.declaredType());

    List<TypeVariableName> typeVariableNames =
        adt.typeConstructor()
            .typeVariables()
            .stream()
            .map(TypeVariableName::get)
            .collect(Collectors.toList());

    String className = "Lazy";
    TypeSpec.Builder typeSpecBuilder =
        TypeSpec.classBuilder(className)
            .addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
            .addTypeVariables(typeVariableNames)
            .addField(
                FieldSpec.builder(
                        TypeName.get(Object.class), "lock", Modifier.PRIVATE, Modifier.FINAL)
                    .initializer("new Object()")
                    .build())
            .addField(FieldSpec.builder(lazyArgTypeName, "expression", Modifier.PRIVATE).build())
            .addField(
                FieldSpec.builder(typeName, "evaluation", Modifier.PRIVATE, Modifier.VOLATILE)
                    .build())
            .addMethod(
                MethodSpec.constructorBuilder()
                    .addParameter(ParameterSpec.builder(lazyArgTypeName, lazyArgName).build())
                    .addStatement("this.expression = $N", lazyArgName)
                    .build())
            .addMethod(
                MethodSpec.methodBuilder("eval")
                    .addModifiers(Modifier.PRIVATE)
                    .returns(typeName)
                    .addCode(
                        CodeBlock.builder()
                            .addStatement("$T _evaluation = this.evaluation", typeName)
                            .beginControlFlow("if (_evaluation == null)")
                            .beginControlFlow("synchronized (this.lock)")
                            .addStatement("_evaluation = this.evaluation")
                            .beginControlFlow("if (_evaluation == null)")
                            .addStatement(
                                "this.evaluation = _evaluation = expression.$L()",
                                Utils.getAbstractMethods(lazyTypeElement.getEnclosedElements())
                                    .get(0)
                                    .getSimpleName())
                            .addStatement("this.expression = null")
                            .endControlFlow()
                            .endControlFlow()
                            .endControlFlow()
                            .addStatement("return _evaluation")
                            .build())
                    .build())
            .addMethod(
                Utils.overrideMethodBuilder(adt.matchMethod().element())
                    .addStatement(
                        "return this.eval().$L($L)",
                        adt.matchMethod().element().getSimpleName(),
                        Utils.asArgumentsStringOld(adt.matchMethod().element().getParameters()))
                    .build());

    if (adt.typeConstructor().declaredType().asElement().getKind() == ElementKind.INTERFACE) {
      typeSpecBuilder.addSuperinterface(typeName);
    } else {
      typeSpecBuilder.superclass(typeName);
    }

    typeSpecBuilder.addMethods(
        optionalAsStream(
                findAbstractEquals(typeConstructor.typeElement(), deriveUtils.elements())
                    .map(
                        equals ->
                            deriveUtils
                                .overrideMethodBuilder(equals)
                                .addStatement(
                                    "return this.eval().equals($L)",
                                    equals.getParameters().get(0).getSimpleName())
                                .build()))
            .collect(Collectors.toList()));

    typeSpecBuilder.addMethods(
        optionalAsStream(
                findAbstractHashCode(typeConstructor.typeElement(), deriveUtils.elements())
                    .map(
                        hashCode ->
                            deriveUtils
                                .overrideMethodBuilder(hashCode)
                                .addStatement("return this.eval().hashCode()")
                                .build()))
            .collect(Collectors.toList()));

    typeSpecBuilder.addMethods(
        optionalAsStream(
                findAbstractToString(typeConstructor.typeElement(), deriveUtils.elements())
                    .map(
                        toString ->
                            deriveUtils
                                .overrideMethodBuilder(toString)
                                .addStatement("return this.eval().toString()")
                                .build()))
            .collect(Collectors.toList()));

    return result(
        codeSpec(
            typeSpecBuilder.build(),
            MethodSpec.methodBuilder("lazy")
                .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
                .addTypeVariables(
                    typeConstructor
                        .typeVariables()
                        .stream()
                        .map(TypeVariableName::get)
                        .collect(Collectors.toList()))
                .addParameter(lazyArgTypeName, lazyArgName)
                .returns(typeName)
                .addStatement(
                    "return new $L$L($L)",
                    className,
                    typeVariableNames.isEmpty() ? "" : "<>",
                    lazyArgName)
                .build()));
  }
Esempio n. 26
0
 public Builder initializer(String format, Object... args) {
   return initializer(CodeBlock.builder().add(format, args).build());
 }
Esempio n. 27
0
 public MethodSpec createPrivateConstructor() {
   return MethodSpec.constructorBuilder()
       .addModifiers(Modifier.PRIVATE)
       .addCode(CodeBlock.builder().addStatement("this.value = \"\"").build())
       .build();
 }
Esempio n. 28
0
  private DeriveResult<DerivedCodeSpec> functionDispatchImpl(List<DataConstructor> constructors) {

    NameAllocator nameAllocator = nameAllocator(constructors);

    TypeElement f = FlavourImpl.findF(context.flavour(), utils.elements());
    TypeName returnType =
        TypeName.get(
            utils
                .types()
                .getDeclaredType(
                    f,
                    adt.typeConstructor().declaredType(),
                    adt.matchMethod().returnTypeVariable()));

    TypeSpec wrapper =
        TypeSpec.anonymousClassBuilder("")
            .addField(
                FieldSpec.builder(returnType, nameAllocator.get("cata"))
                    .initializer(
                        CodeBlock.builder()
                            .addStatement(
                                "$L -> $L.$L($L)",
                                nameAllocator.get("adt var"),
                                nameAllocator.get("adt var"),
                                adt.matchMethod().element().getSimpleName(),
                                Utils.joinStringsAsArguments(
                                    constructors
                                        .stream()
                                        .map(
                                            constructor ->
                                                constructor
                                                        .arguments()
                                                        .stream()
                                                        .map(DataArguments::getType)
                                                        .noneMatch(
                                                            tm ->
                                                                utils
                                                                    .types()
                                                                    .isSameType(
                                                                        tm,
                                                                        adt.typeConstructor()
                                                                            .declaredType()))
                                                    ? constructor.name()
                                                    : CodeBlock.builder()
                                                        .add(
                                                            "($L) -> $L.$L($L)",
                                                            Utils.asLambdaParametersString(
                                                                constructor.arguments(),
                                                                constructor.typeRestrictions()),
                                                            constructor.name(),
                                                            MapperDerivator.mapperApplyMethod(
                                                                utils, context, constructor),
                                                            Utils.joinStringsAsArguments(
                                                                Stream.concat(
                                                                    constructor
                                                                        .arguments()
                                                                        .stream()
                                                                        .map(
                                                                            argument ->
                                                                                utils
                                                                                        .types()
                                                                                        .isSameType(
                                                                                            argument
                                                                                                .type(),
                                                                                            adt.typeConstructor()
                                                                                                .declaredType())
                                                                                    ? "() -> this."
                                                                                        + nameAllocator
                                                                                            .get(
                                                                                                "cata")
                                                                                        + "."
                                                                                        + FlavourImpl
                                                                                            .functionApplyMethod(
                                                                                                utils,
                                                                                                context)
                                                                                        + "("
                                                                                        + argument
                                                                                            .fieldName()
                                                                                        + ")"
                                                                                    : argument
                                                                                        .fieldName()),
                                                                    constructor
                                                                        .typeRestrictions()
                                                                        .stream()
                                                                        .map(
                                                                            TypeRestriction
                                                                                ::idFunction)
                                                                        .map(
                                                                            DataArgument
                                                                                ::fieldName))))
                                                        .build()
                                                        .toString())))
                            .build())
                    .build())
            .build();

    MethodSpec cataMethod =
        MethodSpec.methodBuilder("cata")
            .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
            .addTypeVariables(
                Stream.concat(
                        adt.typeConstructor().typeVariables().stream(),
                        Stream.of(adt.matchMethod().returnTypeVariable()))
                    .map(TypeVariableName::get)
                    .collect(Collectors.toList()))
            .returns(returnType)
            .addParameters(
                constructors
                    .stream()
                    .map(
                        dc ->
                            ParameterSpec.builder(
                                    cataMapperTypeName(dc), MapperDerivator.mapperFieldName(dc))
                                .build())
                    .collect(toList()))
            .addStatement("return $L.$L", wrapper, nameAllocator.get("cata"))
            .build();

    return result(methodSpec(cataMethod));
  }
Esempio n. 29
0
 public CodeWriter emit(String format, Object... args) throws IOException {
   return emit(CodeBlock.builder().add(format, args).build());
 }
Esempio n. 30
0
  private TypeSpec build(ScopeSpec spec) {
    MethodSpec configureScopeSpec =
        MethodSpec.methodBuilder("configureScope")
            .addModifiers(Modifier.PUBLIC)
            .addAnnotation(Override.class)
            .addParameter(ClassName.get(MortarScope.Builder.class), "builder")
            .addParameter(ClassName.get(MortarScope.class), "parentScope")
            .addCode(
                CodeBlock.builder()
                    .add(
                        "builder.withService($T.SERVICE_NAME, $T.builder()\n",
                        DAGGERSERVICE_CLS,
                        spec.getDaggerComponentTypeName())
                    .indent()
                    .add(
                        ".$L(parentScope.<$T>getService($T.SERVICE_NAME))\n",
                        spec.getDaggerComponentBuilderDependencyMethodName(),
                        spec.getDaggerComponentBuilderDependencyTypeName(),
                        DAGGERSERVICE_CLS)
                    .add(".module(new Module())\n")
                    .add(".build());\n")
                    .unindent()
                    .build())
            .build();

    List<FieldSpec> fieldSpecs = new ArrayList<>();
    for (ParameterSpec parameterSpec : spec.getModuleSpec().getInternalParameters()) {
      fieldSpecs.add(FieldSpec.builder(parameterSpec.type, parameterSpec.name).build());
    }

    MethodSpec.Builder constructorBuilder =
        MethodSpec.constructorBuilder()
            .addModifiers(Modifier.PUBLIC)
            .addAnnotation(AnnotationSpec.builder(ParcelConstructor.class).build())
            .addParameters(spec.getModuleSpec().getInternalParameters());
    for (ParameterSpec parameterSpec : spec.getModuleSpec().getInternalParameters()) {
      constructorBuilder.addStatement("this.$L = $L", parameterSpec.name, parameterSpec.name);
    }

    TypeSpec.Builder builder =
        TypeSpec.classBuilder(spec.getClassName().simpleName())
            .addModifiers(Modifier.PUBLIC)
            .addAnnotation(
                AnnotationSpec.builder(Generated.class)
                    .addMember(
                        "value",
                        "$S",
                        architect.autostack.compiler.AnnotationProcessor.class.getName())
                    .build())
            .addAnnotation(spec.getComponentAnnotationSpec())
            .addAnnotation(
                AnnotationSpec.builder(Parcel.class).addMember("parcelsIndex", "false").build())
            .addType(buildModule(spec.getModuleSpec()))
            .addMethod(constructorBuilder.build())
            .addMethod(configureScopeSpec)
            .addFields(fieldSpecs);

    if (spec.getScopeAnnotationSpec() != null) {
      builder.addAnnotation(spec.getScopeAnnotationSpec());
    }

    if (spec.getPathViewTypeName() != null) {
      builder.addSuperinterface(PATH_CLS);
      MethodSpec createViewSpec =
          MethodSpec.methodBuilder("createView")
              .addModifiers(Modifier.PUBLIC)
              .returns(spec.getPathViewTypeName())
              .addAnnotation(Override.class)
              .addParameter(CONTEXT_CLS, "context")
              .addStatement("return new $T(context)", spec.getPathViewTypeName())
              .build();

      builder.addMethod(createViewSpec);
    } else {
      builder.addSuperinterface(STACKABLE_CLS);
    }

    return builder.build();
  }