Search in sources :

Example 1 with ParameterizedTypeField

use of com.bluelinelabs.logansquare.processor.type.field.ParameterizedTypeField in project LoganSquare by bluelinelabs.

the class Type method typeFor.

public static Type typeFor(TypeMirror typeMirror, TypeMirror typeConverterType, Elements elements, Types types) {
    TypeMirror genericClassTypeMirror = types.erasure(typeMirror);
    boolean hasTypeConverter = typeConverterType != null && !typeConverterType.toString().equals("void");
    Type type;
    if (!hasTypeConverter && typeMirror instanceof ArrayType) {
        TypeMirror arrayTypeMirror = ((ArrayType) typeMirror).getComponentType();
        type = new ArrayCollectionType(Type.typeFor(arrayTypeMirror, null, elements, types));
    } else if (!hasTypeConverter && !genericClassTypeMirror.toString().equals(typeMirror.toString())) {
        type = CollectionType.collectionTypeFor(typeMirror, genericClassTypeMirror, elements, types);
        if (type == null) {
            if (typeMirror.toString().contains("?")) {
                throw new RuntimeException("Generic types with wildcards are currently not supported by LoganSquare.");
            }
            try {
                type = new ParameterizedTypeField(TypeName.get(typeMirror));
            } catch (Exception ignored) {
            }
        }
    } else {
        type = FieldType.fieldTypeFor(typeMirror, typeConverterType, elements, types);
    }
    return type;
}
Also used : ArrayType(javax.lang.model.type.ArrayType) ArrayType(javax.lang.model.type.ArrayType) FieldType(com.bluelinelabs.logansquare.processor.type.field.FieldType) ArrayCollectionType(com.bluelinelabs.logansquare.processor.type.collection.ArrayCollectionType) CollectionType(com.bluelinelabs.logansquare.processor.type.collection.CollectionType) TypeMirror(javax.lang.model.type.TypeMirror) ParameterizedTypeField(com.bluelinelabs.logansquare.processor.type.field.ParameterizedTypeField) ArrayCollectionType(com.bluelinelabs.logansquare.processor.type.collection.ArrayCollectionType)

Example 2 with ParameterizedTypeField

use of com.bluelinelabs.logansquare.processor.type.field.ParameterizedTypeField in project LoganSquare by bluelinelabs.

the class ObjectMapperInjector method setFieldHolderJsonMapperVariableName.

private void setFieldHolderJsonMapperVariableName(Type type) {
    if (type instanceof ParameterizedTypeField) {
        ParameterizedTypeField parameterizedType = (ParameterizedTypeField) type;
        parameterizedType.setJsonMapperVariableName(getJsonMapperVariableNameForTypeParameter(parameterizedType.getParameterName()));
    }
    for (Type subType : type.parameterTypes) {
        setFieldHolderJsonMapperVariableName(subType);
    }
}
Also used : Type(com.bluelinelabs.logansquare.processor.type.Type) TypeConverterFieldType(com.bluelinelabs.logansquare.processor.type.field.TypeConverterFieldType) ParameterizedType(com.bluelinelabs.logansquare.ParameterizedType) ParameterizedTypeField(com.bluelinelabs.logansquare.processor.type.field.ParameterizedTypeField)

Example 3 with ParameterizedTypeField

use of com.bluelinelabs.logansquare.processor.type.field.ParameterizedTypeField 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)

Aggregations

ParameterizedTypeField (com.bluelinelabs.logansquare.processor.type.field.ParameterizedTypeField)3 ParameterizedType (com.bluelinelabs.logansquare.ParameterizedType)2 TypeConverterFieldType (com.bluelinelabs.logansquare.processor.type.field.TypeConverterFieldType)2 JsonMapper (com.bluelinelabs.logansquare.JsonMapper)1 LoganSquare (com.bluelinelabs.logansquare.LoganSquare)1 Type (com.bluelinelabs.logansquare.processor.type.Type)1 ArrayCollectionType (com.bluelinelabs.logansquare.processor.type.collection.ArrayCollectionType)1 CollectionType (com.bluelinelabs.logansquare.processor.type.collection.CollectionType)1 FieldType (com.bluelinelabs.logansquare.processor.type.field.FieldType)1 ClassName (com.squareup.javapoet.ClassName)1 FieldSpec (com.squareup.javapoet.FieldSpec)1 MethodSpec (com.squareup.javapoet.MethodSpec)1 ParameterizedTypeName (com.squareup.javapoet.ParameterizedTypeName)1 TypeSpec (com.squareup.javapoet.TypeSpec)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 TypeParameterElement (javax.lang.model.element.TypeParameterElement)1 ArrayType (javax.lang.model.type.ArrayType)1 TypeMirror (javax.lang.model.type.TypeMirror)1 TypeVariable (javax.lang.model.type.TypeVariable)1