Search in sources :

Example 1 with Type

use of org.immutables.value.processor.encode.Type in project immutables by immutables.

the class CriteriaModelProcessorTest method assertAttribute.

private void assertAttribute(String name, String expected) {
    ValueAttribute attribute = findAttribute(name);
    final Type element = attribute.criteria().matcher().matcherType();
    final UnaryOperator<String> stripFn = str -> str.replaceAll("\\s+", "");
    assertEquals(String.format("for attribute %s", name), stripFn.apply(expected), stripFn.apply(element.toString()));
}
Also used : Checkers(org.immutables.check.Checkers) TimeZone(java.util.TimeZone) OptionalDouble(java.util.OptionalDouble) Test(org.junit.Test) UnaryOperator(java.util.function.UnaryOperator) StringChecker(org.immutables.check.StringChecker) ProcessorRule(org.immutables.value.processor.meta.ProcessorRule) OptionalInt(java.util.OptionalInt) ValueAttribute(org.immutables.value.processor.meta.ValueAttribute) ValueType(org.immutables.value.processor.meta.ValueType) Type(org.immutables.value.processor.encode.Type) Objects(java.util.Objects) BigDecimal(java.math.BigDecimal) OptionalLong(java.util.OptionalLong) Criteria(org.immutables.criteria.Criteria) List(java.util.List) Rule(org.junit.Rule) Optional(java.util.Optional) BigInteger(java.math.BigInteger) NoSuchElementException(java.util.NoSuchElementException) Method(java.lang.reflect.Method) Nullable(javax.annotation.Nullable) Assert.assertEquals(org.junit.Assert.assertEquals) ValueType(org.immutables.value.processor.meta.ValueType) Type(org.immutables.value.processor.encode.Type) ValueAttribute(org.immutables.value.processor.meta.ValueAttribute)

Example 2 with Type

use of org.immutables.value.processor.encode.Type in project immutables by immutables.

the class FromSupertypesModel method isEligibleFromType.

private boolean isEligibleFromType(TypeElement typeElement, ValueAttribute attr) {
    @Nullable ExecutableElement accessor = findMethod(typeElement, attr.names.get);
    if (accessor == null) {
        // it can be now as we've changed upper loop
        return false;
    }
    if (!typeElement.getTypeParameters().isEmpty()) {
        TypeElement containingTypeElement = (TypeElement) attr.containingType.originalElement();
        // bail early if types don't both have 1 parameter
        if ((typeElement.getTypeParameters().size() != 1) || (containingTypeElement.getTypeParameters().size() != 1)) {
            return false;
        }
        // ensure this is a direct ancestor
        if (!isDirectAncestor(typeElement, containingTypeElement)) {
            return false;
        }
        // confirm bounds match
        for (int i = 0; i < typeElement.getTypeParameters().size(); i++) {
            if (!boundsMatch(typeElement.getTypeParameters().get(i).getBounds(), containingTypeElement.getTypeParameters().get(i).getBounds())) {
                return false;
            }
        }
    }
    try {
        String ownType = accessor.getReturnType().toString();
        String inheritedType = attr.returnType.toString();
        // This kind of parsing normalizes and ignores type annotations
        Type.Producer tf = new Type.Producer();
        Type.Parser parser = new Type.Parser(tf, tf.parameters());
        if (parser.parse(ownType).equals(parser.parse(inheritedType))) {
            attr.initNullabilitySupertype(accessor);
            return true;
        }
    } catch (Exception typeParseException) {
        if (typeParseExceptionReported.compareAndSet(false, true)) {
            reporter.warning("Type parsing problem in FromSupertypesModel: %s", typeParseException);
        }
    }
    reporter.warning(About.FROM, "Generated builder '.from' method will not copy from attribute '%s'" + " because it has different return type in supertype" + " (And we cannot handle generic specialization or covariant overrides yet)." + " Sometimes it is possible to avoid this by providing abstract override method in this value object", attr.name());
    return false;
}
Also used : Type(org.immutables.value.processor.encode.Type) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Nullable(javax.annotation.Nullable)

Example 3 with Type

use of org.immutables.value.processor.encode.Type in project immutables by immutables.

the class CriteriaModel method matcherType.

private Type.Parameterized matcherType(IntrospectedType introspected) {
    final TypeMirror type = introspected.type;
    String name;
    if (introspected.useOptional()) {
        IntrospectedType param = introspected.optionalParameter();
        // use optional intersection-types ?
        if (param.isString()) {
            name = "org.immutables.criteria.matcher.OptionalStringMatcher.Template";
        } else if (param.isBoolean()) {
            name = "org.immutables.criteria.matcher.OptionalBooleanMatcher.Template";
        } else if (param.isNumber()) {
            if (param.isInteger()) {
                name = "org.immutables.criteria.matcher.OptionalIntegerMatcher.Template";
            } else if (param.isLong()) {
                name = "org.immutables.criteria.matcher.OptionalLongMatcher.Template";
            } else if (param.isDouble()) {
                name = "org.immutables.criteria.matcher.OptionalDoubleMatcher.Template";
            } else if (param.isBigInteger()) {
                name = "org.immutables.criteria.matcher.OptionalBigIntegerMatcher.Template";
            } else if (param.isBigDecimal()) {
                name = "org.immutables.criteria.matcher.OptionalBigDecimalMatcher.Template";
            } else {
                // generic number
                name = "org.immutables.criteria.matcher.OptionalNumberMatcher.Template";
            }
        } else if (param.isComparable()) {
            name = "org.immutables.criteria.matcher.OptionalComparableMatcher.Template";
        } else {
            name = "org.immutables.criteria.matcher.OptionalObjectMatcher.Template";
        }
    } else if (introspected.hasCriteria()) {
        name = topLevelCriteriaClassName(type);
    } else if (introspected.isBoolean()) {
        name = "org.immutables.criteria.matcher.BooleanMatcher.Template";
    } else if (introspected.isNumber()) {
        if (introspected.isInteger()) {
            name = "org.immutables.criteria.matcher.IntegerMatcher.Template";
        } else if (introspected.isLong()) {
            name = "org.immutables.criteria.matcher.LongMatcher.Template";
        } else if (introspected.isDouble()) {
            name = "org.immutables.criteria.matcher.DoubleMatcher.Template";
        } else if (introspected.isBigInteger()) {
            name = "org.immutables.criteria.matcher.BigIntegerMatcher.Template";
        } else if (introspected.isBigDecimal()) {
            name = "org.immutables.criteria.matcher.BigDecimalMatcher.Template";
        } else {
            // generic number
            name = "org.immutables.criteria.matcher.NumberMatcher.Template";
        }
    } else if (introspected.isString()) {
        name = "org.immutables.criteria.matcher.StringMatcher.Template";
    } else if (introspected.isIterable() || introspected.isArray()) {
        name = "org.immutables.criteria.matcher.IterableMatcher.Template";
    } else if (introspected.isComparable()) {
        name = "org.immutables.criteria.matcher.ComparableMatcher.Template";
    } else {
        name = "org.immutables.criteria.matcher.ObjectMatcher.Template";
    }
    final Element element = elements.getTypeElement(name);
    final Type.Parameterized matcherType;
    if (element == null) {
        // means type not found in classpath. probably not yet generated criteria
        // create PersonCriteria<R> manually with Type.Parameterized
        final Type.Variable variable = factory.parameters().introduce("R", NO_BOUNDS).variable("R");
        matcherType = factory.parameterized(factory.reference(name), Collections.singleton(variable));
    } else {
        matcherType = (Type.Parameterized) toType(element.asType());
    }
    return matcherType;
}
Also used : Type(org.immutables.value.processor.encode.Type) DeclaredType(javax.lang.model.type.DeclaredType) TypeMirror(javax.lang.model.type.TypeMirror) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement)

Example 4 with Type

use of org.immutables.value.processor.encode.Type in project immutables by immutables.

the class CriteriaModel method buildMatcher.

private Type.Parameterized buildMatcher(IntrospectedType introspected) {
    Preconditions.checkNotNull(introspected, introspected);
    final TypeMirror type = introspected.type;
    final Type.Parameterized matcher = matcherType(introspected);
    if (matcher.arguments.size() > 1) {
        // replace second and maybe third argument
        // first type argument R unchanged
        Type.VariableResolver resolver = Type.VariableResolver.empty();
        final Type valueType;
        final Type.Variable arg1 = (Type.Variable) matcher.arguments.get(1);
        // resolve P (which is projection type) for Optional
        for (Type.Nonprimitive arg : matcher.arguments) {
            if (arg instanceof Type.Variable && ((Type.Variable) arg).name.equals("P")) {
                // resolve projection type (P) for .Template<R, P>.
                // projection type is identical to attribute type
                // Example .Template<R, Optional<Boolean>>
                resolver = resolver.bind((Type.Variable) arg, factory.reference(type.toString()));
            }
        }
        if (introspected.useOptional()) {
            final IntrospectedType newType = introspected.optionalParameter();
            valueType = toType(newType.type());
            if (newType.hasOptionalMatcher()) {
                // don't recurse if optional matcher is present like OptionalComparableMatcher
                resolver = resolver.bind(arg1, (Type.Nonprimitive) valueType);
            } else {
                resolver = resolver.bind(arg1, buildMatcher(newType));
            }
        } else if (introspected.isScalar()) {
            // this is leaf no need to recurse
            valueType = toType(introspected.box());
            resolver = resolver.bind(arg1, (Type.Nonprimitive) valueType);
        } else if (introspected.isArray()) {
            final TypeMirror mirror = MoreTypes.asArray(type).getComponentType();
            valueType = toType(mirror);
            resolver = resolver.bind(arg1, buildMatcher(introspected.withType(mirror)));
        } else {
            final TypeMirror mirror = MoreTypes.asDeclared(type).getTypeArguments().get(0);
            valueType = toType(mirror);
            resolver = resolver.bind(arg1, buildMatcher(introspected.withType(mirror)));
        }
        if (matcher.arguments.size() > 2 && ((Type.Variable) matcher.arguments.get(2)).name.equals("V")) {
            // parameter called V is usually value type
            resolver = resolver.bind((Type.Variable) matcher.arguments.get(2), (Type.Nonprimitive) valueType);
        }
        // resolve P (which is projection type) for Array / Iterable
        if (introspected.isArray() || introspected.isIterable()) {
            for (Type.Nonprimitive arg : matcher.arguments) {
                if (arg instanceof Type.Variable && ((Type.Variable) arg).name.equals("P")) {
                    // resolve projection type (P) for .Template<R, P>.
                    // projection type is identical to attribute type
                    // Example .Template<R, Optional<Boolean>>
                    resolver = resolver.bind((Type.Variable) arg, factory.reference(type.toString()));
                }
            }
        }
        return (Type.Parameterized) matcher.accept(resolver);
    }
    return matcher;
}
Also used : Type(org.immutables.value.processor.encode.Type) DeclaredType(javax.lang.model.type.DeclaredType) TypeMirror(javax.lang.model.type.TypeMirror)

Aggregations

Type (org.immutables.value.processor.encode.Type)4 Nullable (javax.annotation.Nullable)2 TypeElement (javax.lang.model.element.TypeElement)2 DeclaredType (javax.lang.model.type.DeclaredType)2 TypeMirror (javax.lang.model.type.TypeMirror)2 Method (java.lang.reflect.Method)1 BigDecimal (java.math.BigDecimal)1 BigInteger (java.math.BigInteger)1 List (java.util.List)1 NoSuchElementException (java.util.NoSuchElementException)1 Objects (java.util.Objects)1 Optional (java.util.Optional)1 OptionalDouble (java.util.OptionalDouble)1 OptionalInt (java.util.OptionalInt)1 OptionalLong (java.util.OptionalLong)1 TimeZone (java.util.TimeZone)1 UnaryOperator (java.util.function.UnaryOperator)1 Element (javax.lang.model.element.Element)1 ExecutableElement (javax.lang.model.element.ExecutableElement)1 Checkers (org.immutables.check.Checkers)1