/** * Returns the given type mirror or its component type in case of arrays as a type element. */ @Pure @LogsErrorWhenReturningNull public static @Nullable TypeElement getTypeElement(@Nonnull TypeMirror typeMirror) { switch (typeMirror.getKind()) { case DECLARED: final @Nonnull TypeElement typeElement = (TypeElement) ((DeclaredType) typeMirror).asElement(); return typeElement; case ARRAY: return getTypeElement(((ArrayType) typeMirror).getComponentType()); default: ProcessingLog.error("The type mirror of kind $ cannot be converted to a type element.", typeMirror.getKind()); return null; } }
/** * Returns the custom type for the given representing field. */ public static String getTypeName(@Nonnull TypeMirror representingFieldType, @Nonnull FiniteIterable<@Nonnull AnnotationMirror> annotations, @Nonnull TypeImporter typeImporter) { @Nonnull CustomType customType = CustomType.of(representingFieldType, annotations); // TODO: ProcessingUtility.getTypeElement(representingFieldType) is null for generic types but checking this only here leads to new problems (namely "The name 'TConverter' has to be qualified."). if (customType == CustomType.TUPLE && ProcessingUtility.getTypeElement(representingFieldType).getKind() == ElementKind.ENUM) { return typeImporter.importStaticallyIfPossible(CustomType.class.getCanonicalName() + "." + customType.getTypeName()) + ".of" + Brackets.inRound(typeImporter.importIfPossible("net.digitalid.utility.conversion.converters.StringConverter") + ".INSTANCE"); } else if (customType == CustomType.SET || customType == CustomType.LIST || customType == CustomType.ARRAY) { final @Nonnull TypeMirror componentType = ProcessingUtility.getComponentType(representingFieldType); return typeImporter.importStaticallyIfPossible(CustomType.class.getCanonicalName() + "." + customType.getTypeName()) + ".of" + Brackets.inRound(getTypeName(componentType, FiniteIterable.of(), typeImporter)); } else if (customType == CustomType.MAP) { final @Nullable List<TypeMirror> componentTypes = ProcessingUtility.getComponentTypes(representingFieldType); Require.that(componentTypes.size() == 2).orThrow("Map type does not have 2 component types."); return typeImporter.importStaticallyIfPossible(CustomType.class.getCanonicalName() + "." + customType.getTypeName()) + ".of" + Brackets.inRound(getTypeName(componentTypes.get(0), FiniteIterable.of(), typeImporter) + ", " + getTypeName(componentTypes.get(1), FiniteIterable.of(), typeImporter)); } else if (representingFieldType.getKind().isPrimitive() || customType == BINARY || customType == BINARY128 || customType == BINARY256) { return typeImporter.importStaticallyIfPossible(CustomType.class.getCanonicalName() + "." + customType.getTypeName()); } else { @Nonnull String typeName = customType.getTypeName(); @Nonnull String qualifiedName = ProcessingUtility.getQualifiedName(representingFieldType); if (!qualifiedName.startsWith("net.digitalid")) { typeName = TUPLE.getTypeName(); } return typeImporter.importStaticallyIfPossible(CustomType.class.getCanonicalName() + "." + typeName) + ".of" + Brackets.inRound(importConverterType(representingFieldType, annotations, typeImporter)); } }
/** * Returns a generated statement that reads the field value from the selection result. */ @Impure private @Nonnull String generateSelectionResultCall(@Nonnull TypeMirror fieldType, @Nonnull FiniteIterable<AnnotationMirror> annotationMirrors, @Nonnull String provideParameterName) { final @Nonnull CustomType customType = CustomType.of(fieldType, annotationMirrors); final @Nonnull String customTypeName = Strings.capitalizeFirstLetters(customType.getTypeName().toLowerCase()); if (customType.isCompositeType()) { final @Nullable TypeMirror componentType = ProcessingUtility.getComponentType(fieldType); Require.that(componentType != null).orThrow("The field type is not an array or list"); // TODO: for composite types, we cannot simply pass the annotations, because they apply to the collection. If we cannot access the type argument annotations, we should introduce a new set of annotations (something along NonNullableElemennts, MaxSizeElements, etc). return getAssignmentPrefix(fieldType, FiniteIterable.of()) + getSelectionResultStatement(customTypeName, generateSelectionResultCall(componentType, FiniteIterable.of(), provideParameterName)) + getAssignmentPostfix(fieldType, FiniteIterable.of()); } else if (customType.isObjectType()) { if (StaticProcessingEnvironment.getTypeUtils().isAssignable(fieldType, typeInformation.getType()) && ProcessingUtility.getTypeElement(fieldType).getKind() == ElementKind.ENUM) { return getSelectionResultStatement("String"); } else { final @Nonnull String converterInstance = importConverterType(fieldType, annotationMirrors); return converterInstance + ".recover(decoder, " + provideParameterName + ")"; } } else { return getSelectionResultStatement(customTypeName); } }
} else if (ProcessingUtility.getTypeElement(type).getKind() == ElementKind.ENUM && StaticProcessingEnvironment.getTypeUtils().isAssignable(type, typeInformation.getType())) { addStatement("encoder.encodeObject(" + importIfPossible("net.digitalid.utility.conversion.converters.String64Converter") + ".INSTANCE, " + access + ")" ); } else {
} else if (ProcessingUtility.getTypeElement(type).getKind() == ElementKind.ENUM && StaticProcessingEnvironment.getTypeUtils().isAssignable(type, typeInformation.getType())) { addStatement("final @" + importIfPossible(Nonnull.class) + " " + importIfPossible(String.class) + " value = decoder.decodeObject(" + importIfPossible("net.digitalid.utility.conversion.converters.String64Converter") + ".INSTANCE, " + provided + ")" ); } else {