/** * Returns the component type of the type of the given element if it is an array or an iterable. */ @Pure @LogsErrorWhenReturningNull public static @Nullable TypeMirror getComponentType(@Nonnull Element element) { return getComponentType(element, ErrorLogger.INSTANCE); }
/** * 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 the component type of the given type if it is an array or an iterable. */ @Pure @LogsErrorWhenReturningNull public static @Nullable TypeMirror getComponentType(@Nonnull TypeMirror type) { return getComponentType(type, ErrorLogger.INSTANCE); }
@Pure @Override public @Nonnull TypeMirror getComponentType() { return ProcessingUtility.getComponentType(getType()); }
/** * Returns the component type of the type of the given element if it is an array or an iterable and logs errors with the given logger otherwise. */ @Pure @LogsErrorWhenReturningNull public static @Nullable TypeMirror getComponentType(@Nonnull Element element, @NonCaptured @Modified @Nonnull ErrorLogger errorLogger) { return getComponentType(getType(element), errorLogger); }
@Pure @Override public void checkUsage(@Nonnull Element element, @Nonnull AnnotationMirror annotationMirror, @NonCaptured @Modified @Nonnull ErrorLogger errorLogger) { super.checkUsage(element, annotationMirror, errorLogger); final @Nullable TypeMirror componentType = ProcessingUtility.getComponentType(element, errorLogger); if (componentType != null && !componentType.getKind().isPrimitive() && !ProcessingUtility.isRawSubtype(componentType, Comparable.class)) { errorLogger.log("The annotation $ may only be used on arrays and iterables whose component type is comparable, which is not the case for $:", SourcePosition.of(element, annotationMirror), getAnnotationNameWithLeadingAt(), componentType); } }
/** * 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); } }
final @Nullable TypeMirror componentType = ProcessingUtility.getComponentType(type); if (componentType != null) { if (componentType.getKind() == TypeKind.BYTE) {
final @Nullable TypeMirror componentType = ProcessingUtility.getComponentType(type); if (componentType != null) { if (componentType.getKind() == TypeKind.BYTE) {