/** * Returns whether the given mirror corresponds to the given type. */ @Pure public static boolean correspond(@Nonnull TypeMirror mirror, @Nonnull Class<?> type) { return getQualifiedName(mirror).equals(type.getCanonicalName()); }
/** * Returns the annotation mirror corresponding to the given annotation type of the given element or null if not found. */ @Pure public static @Nullable AnnotationMirror getAnnotationMirror(@Nonnull Element element, @Nonnull Class<? extends Annotation> annotationType) { return getAnnotationMirrors(element).findFirst(annotationMirror -> getQualifiedName(annotationMirror).equals(annotationType.getCanonicalName())); }
@Pure private @Nonnull String getAssignmentPostfix(@Nonnull TypeMirror fieldType, @Nonnull FiniteIterable<@Nonnull AnnotationMirror> annotationMirrors) { if (CustomType.of(fieldType, annotationMirrors).isCompositeType() && ProcessingUtility.getQualifiedName(fieldType).startsWith("net.digitalid.utility.collections.")) { return ")"; } else { return ""; } }
/** * Retrieves declared field information objects for fields in a type. */ public static @Nonnull FiniteIterable<@Nonnull NonDirectlyAccessibleDeclaredFieldInformation> getNonDirectlyAccessibleFieldInformation(@Nonnull TypeElement typeElement, @Nonnull FiniteIterable<@Nonnull MethodInformation> methodsOfType) { final @Nonnull FiniteIterable<@Nonnull VariableElement> fields = ProcessingUtility.getAllFields(typeElement); return fields.filter(field -> ( field.getModifiers().contains(Modifier.PRIVATE) && hasGetter(field.getSimpleName().toString(), field.asType(), methodsOfType) )).map(field -> NonDirectlyAccessibleDeclaredFieldInformation.of(field, (DeclaredType) typeElement.asType(), getGetterOf(field.getSimpleName().toString(), methodsOfType), getSetterOf(field.getSimpleName().toString(), ProcessingUtility.getQualifiedName(field.asType()), methodsOfType)) ); }
@Pure @Override public @Nonnull String visitEnumConstant(@Nonnull VariableElement constant, @NonCaptured @Modified @Nullable TypeImporter typeImporter) { final @Nonnull String qualifiedMemberName = ProcessingUtility.getQualifiedName(constant.asType()) + "." + constant.getSimpleName(); return typeImporter != null ? typeImporter.importStaticallyIfPossible(qualifiedMemberName) : qualifiedMemberName; }
@Pure private @Nonnull String getAssignmentPrefix(@Nonnull TypeMirror fieldType, @Nonnull FiniteIterable<@Nonnull AnnotationMirror> annotationMirrors) { if (CustomType.of(fieldType, annotationMirrors).isCompositeType() && ProcessingUtility.getQualifiedName(fieldType).startsWith("net.digitalid.utility.collections.")) { return ProcessingUtility.getSimpleName(fieldType) + ".withElementsOf("; } return ""; }
@Pure @Override public @Nonnull String visitType(@Nonnull TypeMirror type, @NonCaptured @Modified @Nullable TypeImporter typeImporter) { final @Nonnull String qualifiedTypeName = ProcessingUtility.getQualifiedName(type); return (typeImporter != null ? typeImporter.importIfPossible(qualifiedTypeName) : qualifiedTypeName) + ".class"; }
/** * Returns the imported name (if possible) of the converter of the given type. */ @Pure public static @Nonnull String importConverterType(@Nonnull TypeMirror type, @Nonnull FiniteIterable<@Nonnull AnnotationMirror> annotations, @Nonnull TypeImporter typeImporter) { final @Nullable CustomType customType = get(type, annotations); final @Nonnull String qualifiedName; if (customType == null || customType.isObjectType()) { qualifiedName = ProcessingUtility.getQualifiedName(type); } else { qualifiedName = "net.digitalid.utility.conversion.converters." + Strings.uppercaseFirstCharacter(customType.getTypeName().toLowerCase()); } return typeImporter.importIfPossible(qualifiedName + "Converter") + ".INSTANCE"; }
/** * Checks whether the given object matches this method signature. */ @Override public boolean evaluate(@Nonnull MethodInformation methodInformation) { boolean matches = namePattern.matcher(methodInformation.getName()).matches(); final @Nonnull @NonNullableElements List<? extends VariableElement> methodParameters = methodInformation.getElement().getParameters(); if (parameters.length == methodParameters.size()) { for (int i = 0; i < methodParameters.size(); i++) { final @Nonnull String nameOfDeclaredType = ProcessingUtility.getQualifiedName(methodParameters.get(i).asType()); ProcessingLog.debugging("name of type: $", nameOfDeclaredType); final @Nonnull String parameter = parameters[i]; if (!parameter.equals("?")) { matches = matches && nameOfDeclaredType.equals(parameter); } } } else { matches = false; } return matches; }
/** * Returns true if the field is annotated with @MaxSize and the value is lower or equal than the given max size parameter value. */ @Pure public boolean hasMaxSize(int maxSize) { boolean hasMaxSize = true; final @Nullable AnnotationMirror first = annotationMirrors.findFirst(annotationMirror -> ProcessingUtility.getQualifiedName(annotationMirror).equals(MaxSize.class.getName())); hasMaxSize = hasMaxSize && first != null; if (first != null) { final @Nullable AnnotationValue annotationValue = ProcessingUtility.getAnnotationValue(first); Require.that(annotationValue != null).orThrow("MaxSize requires an annotation value."); hasMaxSize = hasMaxSize && ((int) annotationValue.getValue()) <= maxSize; } return hasMaxSize; }
if (element.getKind() == ElementKind.METHOD) { final @Nonnull ExecutableElement executableElement = (ExecutableElement) element; final @Nonnull String methodKey = executableElement.getSimpleName().toString() + FiniteIterable.of(executableElement.getParameters()).map(parameter -> ProcessingUtility.getQualifiedName(parameter.asType())).join(Brackets.ROUND); if (!nonAbstractMethodEntries.contains(methodKey)) { allMethods.add(MethodInformation.of(executableElement, containingType, typeInformation));
/** * Returns the annotation handlers of the given type which are found with the given meta-annotation type on the annotations of the given element. */ @Pure @SuppressWarnings("unchecked") public static @Capturable <H extends AnnotationHandler> @Modifiable @Nonnull Map<@Nonnull AnnotationMirror, @Nonnull H> getAnnotationHandlers(@Nonnull Element element, @Nonnull Class<? extends Annotation> metaAnnotationType, @Nonnull Class<H> annotationHandlerType) { final @Nonnull Map<@Nonnull AnnotationMirror, @Nonnull H> result = new LinkedHashMap<>(); for (@Nonnull AnnotationMirror annotationMirror : ProcessingUtility.getAnnotationMirrors(element)) { final @Nullable H annotationHandler; final @Nonnull String cacheKey = ProcessingUtility.getQualifiedName(annotationMirror) + "$" + metaAnnotationType.getCanonicalName(); if (cachedAnnotationHandlers.containsKey(cacheKey)) { final @Nullable AnnotationHandler cachedAnnotationHandler = cachedAnnotationHandlers.get(cacheKey); annotationHandler = annotationHandlerType.isInstance(cachedAnnotationHandler) ? (H) cachedAnnotationHandler : null; } else { final @Nonnull TypeElement annotationElement = (TypeElement) annotationMirror.getAnnotationType().asElement(); final @Nullable AnnotationValue metaAnnotationValue = ProcessingUtility.getAnnotationValue(annotationElement, metaAnnotationType); annotationHandler = ProcessingUtility.getInstance(metaAnnotationValue, annotationHandlerType); cachedAnnotationHandlers.put(cacheKey, annotationHandler); } if (annotationHandler != null) { ProcessingLog.debugging("Found the annotation handler $ for", SourcePosition.of(element, annotationMirror), annotationHandler.getClass().getCanonicalName()); annotationHandler.checkUsage(element, annotationMirror, ErrorLogger.INSTANCE); result.put(annotationMirror, annotationHandler); } } return result; }
/** * 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)); } }
final @Nonnull String qualifiedAnnotationName = ProcessingUtility.getQualifiedName(annotation.getAnnotationType()); final @Nonnull String annotationValuesMap = fieldName + Strings.capitalizeFirstLetters(annotationName); if (customAnnotations.length() != 0) {
final @Nonnull Predicate<MethodInformation> validatePredicate = MethodSignatureMatcher.of("validate").and(method -> !method.isFinal()); final @Nonnull FiniteIterable<@Nonnull MethodInformation> equalsMethods = methodInformationIterable.filter(equalsPredicate); Require.that(equalsMethods.size() <= 1).orThrow("Expected at most one equals method in $", ProcessingUtility.getQualifiedName(typeElement.asType())); this.equalsMethod = equalsMethods.getFirstOrNull(); final @Nonnull FiniteIterable<@Nonnull MethodInformation> hashCodeMethods = methodInformationIterable.filter(hashCodePredicate); Require.that(hashCodeMethods.size() <= 1).orThrow("Expected at most one hashCode method in $", ProcessingUtility.getQualifiedName(typeElement.asType())); this.hashCodeMethod = hashCodeMethods.getFirstOrNull(); final @Nonnull FiniteIterable<@Nonnull MethodInformation> toStringMethods = methodInformationIterable.filter(toStringPredicate); Require.that(toStringMethods.size() <= 1).orThrow("Expected at most one toString method in $", ProcessingUtility.getQualifiedName(typeElement.asType())); this.toStringMethod = toStringMethods.getFirstOrNull(); final @Nonnull FiniteIterable<@Nonnull MethodInformation> compareToMethods = methodInformationIterable.filter(compareToPredicate); Require.that(compareToMethods.size() <= 1).orThrow("Expected at most one compareTo method in $", ProcessingUtility.getQualifiedName(typeElement.asType())); this.compareToMethod = compareToMethods.getFirstOrNull(); final @Nonnull FiniteIterable<@Nonnull MethodInformation> cloneMethods = methodInformationIterable.filter(clonePredicate); Require.that(cloneMethods.size() <= 1).orThrow("Expected at most one clone method in $", ProcessingUtility.getQualifiedName(typeElement.asType())); this.cloneMethod = cloneMethods.getFirstOrNull(); final @Nonnull FiniteIterable<@Nonnull MethodInformation> validateMethods = methodInformationIterable.filter(validatePredicate); Require.that(validateMethods.size() <= 1).orThrow("Expected at most one validate method in $", ProcessingUtility.getQualifiedName(typeElement.asType())); this.validateMethod = validateMethods.getFirstOrNull();