public @Nullable String getReturnType(@Nonnull TypeImporter typeImporter) { final @Nullable TypeMirror returnType = getReturnType(); if (returnType == null) { return null; } final @Nonnull StringBuilder returnTypeAsString = new StringBuilder(); if (returnType instanceof Type.AnnotatedType) { final Type.AnnotatedType annotatedType = (Type.AnnotatedType) returnType; returnTypeAsString.append(getReturnTypeAnnotations(typeImporter)); returnTypeAsString.append(typeImporter.importIfPossible(annotatedType.unannotatedType())); } else { returnTypeAsString.append(typeImporter.importIfPossible(returnType)); } ProcessingLog.debugging("Stringifying return type: $ = $", returnType.getClass(), returnTypeAsString); return returnTypeAsString.toString(); }
@Pure @Override public @Nonnull Contract generateContract(@Nonnull Element element, @Nonnull AnnotationMirror annotationMirror, @NonCaptured @Modified @Nonnull TypeImporter typeImporter) { return Contract.with(typeImporter.importIfPossible(JavaExpression.class) + ".Validator.validate(#)", "The # has to be a valid Java expression but was $.", element); }
@Pure @Override public @Nonnull Contract generateContract(@Nonnull Element element, @Nonnull AnnotationMirror annotationMirror, @NonCaptured @Modified @Nonnull TypeImporter typeImporter) { return Contract.with(typeImporter.importIfPossible(NonNullableElements.class) + ".Validator.validate(#)", "The # may not contain null.", element); }
public @Nonnull String getFieldType(@Nonnull TypeImporter typeImporter) { final @Nonnull StringBuilder returnTypeAsString = new StringBuilder(); returnTypeAsString.append(ProcessingUtility.getAnnotationsAsString(FiniteIterable.of(getType().getAnnotationMirrors()), typeImporter)); returnTypeAsString.append(typeImporter.importIfPossible(getType())); return returnTypeAsString.toString(); }
@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"; }
@Pure @Override public @Nonnull Contract generateContract(@Nonnull Element element, @Nonnull AnnotationMirror annotationMirror, @NonCaptured @Modified @Nonnull TypeImporter typeImporter) { return Contract.with(typeImporter.importIfPossible(UniqueElements.class) + ".Validator.validate(#)", "The # may not contain duplicates.", element); }
@Pure @Override public @Nonnull Contract generateContract(@Nonnull Element element, @Nonnull AnnotationMirror annotationMirror, @NonCaptured @Modified @Nonnull TypeImporter typeImporter) { return Contract.with(typeImporter.importIfPossible(DomainName.class) + ".Validator.validate(#)", "The # has to denote a valid domain name but was $.", element); }
@Pure @Override public @Nonnull Contract generateContract(@Nonnull Element element, @Nonnull AnnotationMirror annotationMirror, @NonCaptured @Modified @Nonnull TypeImporter typeImporter) { return Contract.with(typeImporter.importIfPossible(Threading.class) + ".isMainThread()", "The method " + Quotes.inSingle(element.getSimpleName().toString()) + " may only be called on the main thread."); }
@Pure @Override public @Nonnull Contract generateContract(@Nonnull Element element, @Nonnull AnnotationMirror annotationMirror, @NonCaptured @Modified @Nonnull TypeImporter typeImporter) { return Contract.with(typeImporter.importIfPossible(CodeIdentifier.class) + ".Validator.validate(#)", "The # has to be a valid code identifier but was $.", element); }
/** * 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"; }
@Pure @Override public @Nonnull Contract generateContract(@Nonnull Element element, @Nonnull AnnotationMirror annotationMirror, @NonCaptured @Modified @Nonnull TypeImporter typeImporter) { if (ProcessingUtility.isRawSubtype(element, BigIntegerNumerical.class)) { return Contract.with("# == null || #.getValue().mod(" + typeImporter.importIfPossible(BigInteger.class) + ".valueOf(@)).equals(" + typeImporter.importIfPossible(BigInteger.class) + ".ZERO)", "The # has to be null or a multiple of @ but was $.", element, annotationMirror); } else if (ProcessingUtility.isRawSubtype(element, BigInteger.class)) { return Contract.with("# == null || #.mod(" + typeImporter.importIfPossible(BigInteger.class) + ".valueOf(@)).equals(" + typeImporter.importIfPossible(BigInteger.class) + ".ZERO)", "The # has to be null or a multiple of @ but was $.", element, annotationMirror); } else if (ProcessingUtility.isRawSubtype(element, LongNumerical.class)) { return Contract.with("# == null || #.getValue() % @ == 0", "The # has to be a multiple of @ but was $.", element, annotationMirror); } else { return Contract.with("# % @ == 0", "The # has to be a multiple of @ but was $.", element, annotationMirror); } }
/** * Returns the given annotation with its values as a string. */ @Pure public static @Nonnull String getAnnotationAsString(@Nonnull AnnotationMirror annotationMirror, @NonCaptured @Modified @Nonnull TypeImporter typeImporter) { final boolean isUniqueEntry = annotationMirror.getElementValues().size() == 1; return "@" + typeImporter.importIfPossible(annotationMirror.getAnnotationType()) + FiniteIterable.of(annotationMirror.getElementValues().entrySet()).map(annotationEntry -> getAnnotationEntryAsString(annotationEntry, typeImporter, isUniqueEntry)).join(Brackets.ROUND, ""); }
@Pure @Override public @Nonnull Contract generateContract(@Nonnull Element element, @Nonnull AnnotationMirror annotationMirror, @NonCaptured @Modified @Nonnull TypeImporter typeImporter) { return Contract.with(typeImporter.importIfPossible(OrderingValidator.class) + ".validate(#, " + isStrictly() + ", " + isAscending() + ")", "The # has to be ordered.", element); }
/** * Returns the condition for the given element depending on the type of the element. */ @Pure public static @Nonnull String getCondition(@Nonnull Element element, @Nonnull ElementKind kind, @NonCaptured @Modified @Nonnull TypeImporter typeImporter) { if (ProcessingUtility.isRawSubtype(element, Class.class)) { switch (kind) { case CLASS: return "!#.isInterface() && !#.isEnum()"; case INTERFACE: return "#.isInterface() && !#.isAnnotation()"; case ENUM: return "#.isEnum()"; case ANNOTATION_TYPE: return "#.isAnnotation()"; default: return "false"; } } else { return "#.getKind() == " + typeImporter.importIfPossible(ElementKind.class) + "." + kind.name(); } }
/** * Returns the condition for the given element depending on the type of the element. */ @Pure public static @Nonnull String getCondition(@Nonnull Element element, @Nonnull NestingKind kind, @NonCaptured @Modified @Nonnull TypeImporter typeImporter) { if (ProcessingUtility.isRawSubtype(element, Class.class)) { switch (kind) { case ANONYMOUS: return "#.isAnonymousClass()"; case LOCAL: return "#.isLocalClass()"; case MEMBER: return "#.isMemberClass()"; case TOP_LEVEL: return "!#.isAnonymousClass() && !#.isLocalClass() && !#.isMemberClass()"; default: return "false"; } } else { return "#.getNestingKind() == " + typeImporter.importIfPossible(NestingKind.class) + "." + kind.name(); } }
@Pure @Override public @Nonnull Contract generateContract(@Nonnull Element element, @Nonnull AnnotationMirror annotationMirror, @NonCaptured @Modified @Nonnull TypeImporter typeImporter) { if (ProcessingUtility.isRawSubtype(element, BigIntegerNumerical.class)) { return Contract.with("# == null || #.getValue().compareTo(" + typeImporter.importIfPossible(BigInteger.class) + ".ZERO) " + getComparisonOperator() + " 0", "The # has to be null or " + getDecamelizedAnnotationName().replace(" ", "-") + " but was $.", element); } else if (ProcessingUtility.isRawSubtype(element, BigInteger.class)) { return Contract.with("# == null || #.compareTo(" + typeImporter.importIfPossible(BigInteger.class) + ".ZERO) " + getComparisonOperator() + " 0", "The # has to be null or " + getDecamelizedAnnotationName().replace(" ", "-") + " but was $.", element); } else if (ProcessingUtility.isRawSubtype(element, LongNumerical.class)) { return Contract.with("# == null || #.getValue() " + getComparisonOperator() + " 0", "The # has to be null or " + getDecamelizedAnnotationName().replace(" ", "-") + " but was $.", element); } else if (ProcessingUtility.isRawSubtype(element, Number.class)) { return Contract.with("# == null || # " + getComparisonOperator() + " 0", "The # has to be null or " + getDecamelizedAnnotationName().replace(" ", "-") + " but was $.", element); } else { return Contract.with("# " + getComparisonOperator() + " 0", "The # has to be " + getDecamelizedAnnotationName().replace(" ", "-") + " but was $.", element); } }
/** * 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)); } }
@Pure @Override public @Nonnull Contract generateContract(@Nonnull Element element, @Nonnull AnnotationMirror annotationMirror, @NonCaptured @Modified @Nonnull TypeImporter typeImporter) { if (ProcessingUtility.isRawSubtype(element, BigIntegerNumerical.class)) { return Contract.with("# == null || #.getValue().compareTo(" + typeImporter.importIfPossible(BigInteger.class) + ".valueOf(@)) " + getComparisonOperator() + " 0", "The # has to be null or " + getDecamelizedAnnotationName() + " @ but was $.", element, annotationMirror); } else if (ProcessingUtility.isRawSubtype(element, BigInteger.class)) { return Contract.with("# == null || #.compareTo(" + typeImporter.importIfPossible(BigInteger.class) + ".valueOf(@)) " + getComparisonOperator() + " 0", "The # has to be null or " + getDecamelizedAnnotationName() + " @ but was $.", element, annotationMirror); } else if (ProcessingUtility.isRawSubtype(element, LongNumerical.class)) { return Contract.with("# == null || #.getValue() " + getComparisonOperator() + " @", "The # has to be null or " + getDecamelizedAnnotationName() + " @ but was $.", element, annotationMirror); } else if (ProcessingUtility.isRawSubtype(element, Number.class)) { return Contract.with("# == null || # " + getComparisonOperator() + " @", "The # has to be null or " + getDecamelizedAnnotationName() + " @ but was $.", element, annotationMirror); } else { return Contract.with("# " + getComparisonOperator() + " @", "The # has to be " + getDecamelizedAnnotationName() + " @ but was $.", element, annotationMirror); } }