Search in sources :

Example 16 with ParameterizedTypeName

use of com.squareup.javapoet.ParameterizedTypeName in project LoganSquare by bluelinelabs.

the class ObjectMapperInjector method getTypeSpec.

private TypeSpec getTypeSpec() {
    TypeSpec.Builder builder = TypeSpec.classBuilder(mJsonObjectHolder.injectedClassName).addModifiers(Modifier.PUBLIC, Modifier.FINAL);
    builder.addAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "\"unsafe,unchecked\"").build());
    builder.superclass(ParameterizedTypeName.get(ClassName.get(JsonMapper.class), mJsonObjectHolder.objectTypeName));
    for (TypeParameterElement typeParameterElement : mJsonObjectHolder.typeParameters) {
        builder.addTypeVariable(TypeVariableName.get((TypeVariable) typeParameterElement.asType()));
    }
    if (mJsonObjectHolder.hasParentClass()) {
        FieldSpec.Builder parentMapperBuilder;
        if (mJsonObjectHolder.parentTypeParameters.size() == 0) {
            parentMapperBuilder = FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(JsonMapper.class), mJsonObjectHolder.parentTypeName), PARENT_OBJECT_MAPPER_VARIABLE_NAME).addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL).initializer("$T.mapperFor($T.class)", LoganSquare.class, mJsonObjectHolder.parentTypeName);
        } else {
            parentMapperBuilder = FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(JsonMapper.class), mJsonObjectHolder.getParameterizedParentTypeName()), PARENT_OBJECT_MAPPER_VARIABLE_NAME).addModifiers(Modifier.PRIVATE);
            if (mJsonObjectHolder.typeParameters.size() == 0) {
                parentMapperBuilder.initializer("$T.mapperFor(new $T<$T>() { })", LoganSquare.class, ParameterizedType.class, mJsonObjectHolder.getParameterizedParentTypeName());
            }
        }
        builder.addField(parentMapperBuilder.build());
    }
    // TypeConverters could be expensive to create, so just use one per class
    Set<ClassName> typeConvertersUsed = new HashSet<>();
    for (JsonFieldHolder fieldHolder : mJsonObjectHolder.fieldMap.values()) {
        if (fieldHolder.type instanceof TypeConverterFieldType) {
            typeConvertersUsed.add(((TypeConverterFieldType) fieldHolder.type).getTypeConverterClassName());
        }
    }
    for (ClassName typeConverter : typeConvertersUsed) {
        builder.addField(FieldSpec.builder(typeConverter, getStaticFinalTypeConverterVariableName(typeConverter)).addModifiers(Modifier.PROTECTED, Modifier.STATIC, Modifier.FINAL).initializer("new $T()", typeConverter).build());
    }
    MethodSpec.Builder constructorBuilder = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC);
    List<String> createdJsonMappers = new ArrayList<>();
    if (mJsonObjectHolder.typeParameters.size() > 0) {
        constructorBuilder.addParameter(ClassName.get(ParameterizedType.class), "type");
        constructorBuilder.addStatement("partialMappers.put(type, this)");
        for (TypeParameterElement typeParameterElement : mJsonObjectHolder.typeParameters) {
            final String typeName = typeParameterElement.getSimpleName().toString();
            final String typeArgumentName = typeName + "Type";
            final String jsonMapperVariableName = getJsonMapperVariableNameForTypeParameter(typeName);
            if (!createdJsonMappers.contains(jsonMapperVariableName)) {
                createdJsonMappers.add(jsonMapperVariableName);
                // Add a JsonMapper reference
                builder.addField(FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(JsonMapper.class), TypeVariableName.get(typeName)), jsonMapperVariableName).addModifiers(Modifier.PRIVATE, Modifier.FINAL).build());
                constructorBuilder.addParameter(ClassName.get(ParameterizedType.class), typeArgumentName);
                constructorBuilder.addStatement("$L = $T.mapperFor($L, partialMappers)", jsonMapperVariableName, LoganSquare.class, typeArgumentName);
            }
        }
        constructorBuilder.addParameter(ParameterizedTypeName.get(ClassName.get(SimpleArrayMap.class), ClassName.get(ParameterizedType.class), ClassName.get(JsonMapper.class)), "partialMappers");
    }
    for (JsonFieldHolder jsonFieldHolder : mJsonObjectHolder.fieldMap.values()) {
        if (jsonFieldHolder.type instanceof ParameterizedTypeField) {
            final String jsonMapperVariableName = getJsonMapperVariableNameForTypeParameter(((ParameterizedTypeField) jsonFieldHolder.type).getParameterName());
            if (!createdJsonMappers.contains(jsonMapperVariableName)) {
                ParameterizedTypeName parameterizedType = ParameterizedTypeName.get(ClassName.get(JsonMapper.class), jsonFieldHolder.type.getTypeName());
                createdJsonMappers.add(jsonMapperVariableName);
                builder.addField(FieldSpec.builder(parameterizedType, jsonMapperVariableName).addModifiers(Modifier.PRIVATE, Modifier.FINAL).build());
                String typeName = jsonMapperVariableName + "Type";
                constructorBuilder.addStatement("$T $L = new $T<$T>() { }", ParameterizedType.class, typeName, ParameterizedType.class, jsonFieldHolder.type.getTypeName());
                if (mJsonObjectHolder.typeParameters.size() > 0) {
                    constructorBuilder.beginControlFlow("if ($L.equals(type))", typeName);
                    constructorBuilder.addStatement("$L = ($T)this", jsonMapperVariableName, JsonMapper.class);
                    constructorBuilder.nextControlFlow("else");
                    constructorBuilder.addStatement("$L = $T.mapperFor($L, partialMappers)", jsonMapperVariableName, LoganSquare.class, typeName);
                    constructorBuilder.endControlFlow();
                } else {
                    constructorBuilder.addStatement("$L = $T.mapperFor($L)", jsonMapperVariableName, LoganSquare.class, typeName);
                }
            }
        }
    }
    if (createdJsonMappers.size() > 0) {
        if (mJsonObjectHolder.hasParentClass()) {
            constructorBuilder.addStatement("$L = $T.mapperFor(new $T<$T>() { })", PARENT_OBJECT_MAPPER_VARIABLE_NAME, LoganSquare.class, ParameterizedType.class, mJsonObjectHolder.getParameterizedParentTypeName());
        }
        builder.addMethod(constructorBuilder.build());
    }
    builder.addMethod(getParseMethod());
    builder.addMethod(getParseFieldMethod());
    builder.addMethod(getSerializeMethod());
    addUsedJsonMapperVariables(builder);
    addUsedTypeConverterMethods(builder);
    return builder.build();
}
Also used : MethodSpec(com.squareup.javapoet.MethodSpec) ParameterizedTypeField(com.bluelinelabs.logansquare.processor.type.field.ParameterizedTypeField) ArrayList(java.util.ArrayList) FieldSpec(com.squareup.javapoet.FieldSpec) TypeParameterElement(javax.lang.model.element.TypeParameterElement) JsonMapper(com.bluelinelabs.logansquare.JsonMapper) ParameterizedType(com.bluelinelabs.logansquare.ParameterizedType) TypeConverterFieldType(com.bluelinelabs.logansquare.processor.type.field.TypeConverterFieldType) TypeVariable(javax.lang.model.type.TypeVariable) LoganSquare(com.bluelinelabs.logansquare.LoganSquare) ClassName(com.squareup.javapoet.ClassName) TypeSpec(com.squareup.javapoet.TypeSpec) HashSet(java.util.HashSet) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName)

Example 17 with ParameterizedTypeName

use of com.squareup.javapoet.ParameterizedTypeName in project tiger by google.

the class NewInjectorGenerator method createAnonymousBuiltinType.

/**
   * Generate for either unique a binding or a contributor to a multi-binding. NewDependencyInfo is
   * null for unique one and non-null or multi-binding one. ReferencingClass is the opposite, for
   * multi-binding, it is the module in dependency. Scope is null for unique binding.
   */
private TypeSpec createAnonymousBuiltinType(ClassName leafInjectorClassName, NewBindingKey key, @Nullable TypeElement scope, @Nullable TypeElement referencingClass, @Nullable NewDependencyInfo newDependencyInfo) {
    Preconditions.checkArgument(key.getTypeName() instanceof ParameterizedTypeName);
    boolean isMultiBinding = newDependencyInfo != null;
    if (isMultiBinding) {
        Preconditions.checkArgument(referencingClass == null);
        Preconditions.checkNotNull(scope);
    } else {
        Preconditions.checkNotNull(referencingClass);
    }
    TypeName rawTypeName = ((ParameterizedTypeName) key.getTypeName()).rawType;
    Preconditions.checkArgument(Utils.hasBuiltinBinding(key), String.format("Built-in binding expected(Provider or Lazy), but get %s", key));
    boolean isLazy = rawTypeName.equals(ClassName.get(Lazy.class));
    NewBindingKey elementKey = Utils.getElementKeyForBuiltinBinding(key);
    Preconditions.checkNotNull(elementKey);
    if (!isMultiBinding) {
        generateProvisionMethodIfNeeded(elementKey, referencingClass);
    }
    MethodSpec.Builder builderForGet = MethodSpec.methodBuilder("get").returns(elementKey.getTypeName()).addAnnotation(Override.class).addModifiers(Modifier.PUBLIC);
    builderForGet.addStatement("$T var = null", elementKey.getTypeName());
    if (isLazy) {
        builderForGet.beginControlFlow("if (var == null)");
    }
    if (!isMultiBinding) {
        builderForGet.addStatement("var = $N()", getProvisionMethodName(elementKey));
    } else {
        addNewStatementToMethodSpec(scope, newDependencyInfo, leafInjectorClassName, builderForGet, "var");
    }
    if (isLazy) {
        builderForGet.endControlFlow();
    }
    builderForGet.addStatement("return var");
    TypeSpec result = TypeSpec.anonymousClassBuilder("").addSuperinterface(key.getTypeName()).addMethod(builderForGet.build()).build();
    return result;
}
Also used : Lazy(dagger.Lazy) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) TypeName(com.squareup.javapoet.TypeName) MethodSpec(com.squareup.javapoet.MethodSpec) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) TypeSpec(com.squareup.javapoet.TypeSpec)

Example 18 with ParameterizedTypeName

use of com.squareup.javapoet.ParameterizedTypeName in project tiger by google.

the class NewInjectorGenerator method generateProvisionMethodForMap.

private void generateProvisionMethodForMap(final NewBindingKey key, TypeElement referencingClass, String suffix) {
    TypeSpec.Builder componentSpecBuilder = getInjectorTypeSpecBuilder(getInjectorFor(key, referencingClass));
    // messager.printMessage(Kind.NOTE, "generateProvisionMethodForSet: " + key +
    // " PackagedInjector: "
    // + getInjectorFor(key, referencingClass) + " SpecBuilder: " + componentSpecBuilder);
    ParameterizedTypeName type = (ParameterizedTypeName) key.getTypeName();
    Preconditions.checkArgument(type.rawType.equals(ClassName.get(Map.class)));
    MethodSpec.Builder methodSpecBuilder = MethodSpec.methodBuilder(getProvisionMethodName(key) + suffix).addModifiers(suffix.isEmpty() ? Modifier.PUBLIC : Modifier.PRIVATE).returns(type);
    methodSpecBuilder.addStatement("$T result = new $T<>()", type, HashMap.class);
    methodSpecBuilder.addStatement("$T packagedMap", type);
    SetMultimap<PackageElement, NewDependencyInfo> packageToDependencyInfoMap = HashMultimap.create();
    Set<NewDependencyInfo> dependencyInfos = Utils.getDependencyInfo(dependencies, key);
    Preconditions.checkNotNull(dependencyInfos, String.format("dependencyInfo not found for key: %s", key));
    for (NewDependencyInfo dependencyInfo : Utils.getDependencyInfo(dependencies, key)) {
        packageToDependencyInfoMap.put(Utils.getPackage(dependencyInfo.getSourceClassElement()), dependencyInfo);
    }
    for (PackageElement pkg : packageToDependencyInfoMap.keySet()) {
        // messager.printMessage(Kind.NOTE, String.format("generateProvisionMethodForSet for %s from"
        // +
        // " %s", key, packageToDependencyInfoMap.get(pkg)));
        generateMapTypeProvisionMethodForPackage(key, packageToDependencyInfoMap.get(pkg), suffix);
        NewDependencyInfo dependencyInfo = Iterables.getFirst(packageToDependencyInfoMap.get(pkg), null);
        Preconditions.checkNotNull(dependencyInfo, String.format("no dependencyInfo for set key %s in module %s", key, pkg));
        ClassName packagedInjectorClassName = getPackagedInjectorForNewDependencyInfo(key, dependencyInfo);
        methodSpecBuilder.addStatement("packagedMap = $L.$N().$N()", TOP_LEVEL_INJECTOR_FIELD, Utils.getGetMethodName(packagedInjectorClassName), getProvisionMethodName(key));
        methodSpecBuilder.addStatement("result.putAll($L)", "packagedMap");
    }
    methodSpecBuilder.addStatement("return result");
    componentSpecBuilder.addMethod(methodSpecBuilder.build());
}
Also used : MethodSpec(com.squareup.javapoet.MethodSpec) Builder(com.squareup.javapoet.TypeSpec.Builder) ClassName(com.squareup.javapoet.ClassName) PackageElement(javax.lang.model.element.PackageElement) TypeSpec(com.squareup.javapoet.TypeSpec) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName)

Example 19 with ParameterizedTypeName

use of com.squareup.javapoet.ParameterizedTypeName in project tiger by google.

the class NewInjectorGenerator method generateProvisionMethodFromClass.

/**
   * Handles generic.
   */
private void generateProvisionMethodFromClass(NewBindingKey key, TypeElement referencingClass, String suffix) {
    // System.out.println(
    // "generateProvisionMethodFromClass. key: " + key + " referencingClass: " +
    // referencingClass);
    ClassName packagedInjectorClassName = getInjectorFor(key, referencingClass);
    TypeSpec.Builder injectorSpecBuilder = getInjectorTypeSpecBuilder(packagedInjectorClassName);
    TypeElement cls = getClassFromKey(key);
    ExecutableElement ctor = Utils.findInjectedCtor(cls, processingEnv);
    Preconditions.checkNotNull(ctor, String.format("Did not find ctor for %s", cls));
    List<NewBindingKey> dependencyKeys = Utils.getDependenciesFromExecutableElement(ctor);
    if (key.getTypeName() instanceof ParameterizedTypeName) {
        List<NewBindingKey> specializedKeys = new ArrayList<>();
        Map<TypeVariableName, TypeName> map = Utils.getMapFromTypeVariableToSpecialized((ParameterizedTypeName) key.getTypeName(), (ParameterizedTypeName) TypeName.get(cls.asType()));
        for (NewBindingKey k : dependencyKeys) {
            specializedKeys.add(Utils.specializeIfNeeded(k, map));
        }
        dependencyKeys = specializedKeys;
    }
    // System.out.println("generateProvisionMethodFromClass. dependencyKeys: " +
    // dependencyKeys);
    MethodSpec.Builder methodSpecBuilder = MethodSpec.methodBuilder(getProvisionMethodName(key) + suffix);
    methodSpecBuilder.addModifiers(suffix.isEmpty() ? Modifier.PUBLIC : Modifier.PRIVATE).returns(key.getTypeName());
    StringBuilder builder = new StringBuilder("$T result = new $T(");
    if (dependencyKeys.size() > 0) {
        for (NewBindingKey dependencyKey : dependencyKeys) {
            // System.out.println("generateProvisionMethodFromClass. dependencyKey: "
            // + dependencyKey);
            generateProvisionMethodAndAppendAsParameter(dependencyKey, cls, packagedInjectorClassName, builder);
        }
        builder.delete(builder.length() - 2, builder.length());
    }
    builder.append(")");
    methodSpecBuilder.addStatement(builder.toString(), key.getTypeName(), key.getTypeName());
    if (Utils.hasInjectedFieldsOrMethods(cls, processingEnv)) {
        // System.out.println("generateProvisionMethodFromClass. hasInjected");
        generateInjectionMethod(key, referencingClass);
        methodSpecBuilder.addStatement("inject(result)");
    }
    methodSpecBuilder.addStatement("return result");
    injectorSpecBuilder.addMethod(methodSpecBuilder.build());
}
Also used : ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) TypeName(com.squareup.javapoet.TypeName) MethodSpec(com.squareup.javapoet.MethodSpec) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList) Builder(com.squareup.javapoet.TypeSpec.Builder) ClassName(com.squareup.javapoet.ClassName) TypeVariableName(com.squareup.javapoet.TypeVariableName) TypeSpec(com.squareup.javapoet.TypeSpec) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName)

Example 20 with ParameterizedTypeName

use of com.squareup.javapoet.ParameterizedTypeName in project tiger by google.

the class Utils method peelMapWithBuiltinValue.

/**
   * If the key comes with value of type that has dagger builtin binding, return one
   * with the type replaced by the element of the original value type, null otherwise.
   * Nested built-in binding like Lazy<Lazy<Foo>>, Provider<Lazy<Foo>>, etc, are not 
   * supported.
   */
@Nullable
public static NewBindingKey peelMapWithBuiltinValue(NewBindingKey key) {
    Preconditions.checkState(isMap(key), String.format("Expect a map but got %s", key));
    ParameterizedTypeName parameterizedTypeName = (ParameterizedTypeName) key.getTypeName();
    TypeName valueType = parameterizedTypeName.typeArguments.get(1);
    if (hasBuiltinBinding(valueType)) {
        TypeName mapKeyType = parameterizedTypeName.typeArguments.get(0);
        TypeName elementType = Iterables.getOnlyElement(((ParameterizedTypeName) valueType).typeArguments);
        TypeName newType = ParameterizedTypeName.get(ClassName.get(Map.class), mapKeyType, elementType);
        return NewBindingKey.get(newType, key.getQualifier());
    }
    return null;
}
Also used : TypeName(com.squareup.javapoet.TypeName) WildcardTypeName(com.squareup.javapoet.WildcardTypeName) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) ArrayTypeName(com.squareup.javapoet.ArrayTypeName) Map(java.util.Map) HashMap(java.util.HashMap) IntoMap(dagger.multibindings.IntoMap) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) Nullable(javax.annotation.Nullable)

Aggregations

ParameterizedTypeName (com.squareup.javapoet.ParameterizedTypeName)31 TypeName (com.squareup.javapoet.TypeName)23 ClassName (com.squareup.javapoet.ClassName)21 TypeSpec (com.squareup.javapoet.TypeSpec)14 MethodSpec (com.squareup.javapoet.MethodSpec)13 TypeElement (javax.lang.model.element.TypeElement)10 WildcardTypeName (com.squareup.javapoet.WildcardTypeName)9 TypeMirror (javax.lang.model.type.TypeMirror)8 Map (java.util.Map)6 ArrayTypeName (com.squareup.javapoet.ArrayTypeName)5 FieldSpec (com.squareup.javapoet.FieldSpec)5 ParameterSpec (com.squareup.javapoet.ParameterSpec)5 TypeVariableName (com.squareup.javapoet.TypeVariableName)5 ArrayList (java.util.ArrayList)5 HashSet (java.util.HashSet)5 Set (java.util.Set)5 Builder (com.squareup.javapoet.TypeSpec.Builder)4 Attribute (io.requery.meta.Attribute)4 AnnotationSpec (com.squareup.javapoet.AnnotationSpec)3 CodeBlock (com.squareup.javapoet.CodeBlock)3