Search in sources :

Example 1 with PropertyBuilder

use of com.google.auto.value.processor.PropertyBuilderClassifier.PropertyBuilder in project auto by google.

the class BuilderMethodClassifier method classifyMethods.

/**
 * Classifies the given methods and sets the state of this object based on what is found.
 */
boolean classifyMethods(Iterable<ExecutableElement> methods, boolean autoValueHasToBuilder) {
    int startErrorCount = errorReporter.errorCount();
    for (ExecutableElement method : methods) {
        classifyMethod(method);
    }
    if (errorReporter.errorCount() > startErrorCount) {
        return false;
    }
    Multimap<String, PropertySetter> propertyNameToSetter;
    if (propertyNameToPrefixedSetters.isEmpty()) {
        propertyNameToSetter = propertyNameToUnprefixedSetters;
        this.settersPrefixed = false;
    } else if (propertyNameToUnprefixedSetters.isEmpty()) {
        propertyNameToSetter = propertyNameToPrefixedSetters;
        this.settersPrefixed = true;
    } else {
        errorReporter.reportError(propertyNameToUnprefixedSetters.values().iterator().next().getSetter(), "[%sSetNotSet] If any setter methods use the setFoo convention then all must", autoWhat());
        return false;
    }
    for (String property : rewrittenPropertyTypes.keySet()) {
        TypeMirror propertyType = rewrittenPropertyTypes.get(property);
        boolean hasSetter = propertyNameToSetter.containsKey(property);
        PropertyBuilder propertyBuilder = propertyNameToPropertyBuilder.get(property);
        boolean hasBuilder = propertyBuilder != null;
        if (hasBuilder) {
            // If property bar of type Bar has a barBuilder() that returns BarBuilder, then it must
            // be possible to make a BarBuilder from a Bar if either (1) the @AutoValue class has a
            // toBuilder() or (2) there is also a setBar(Bar). Making BarBuilder from Bar is
            // possible if Bar either has a toBuilder() method or BarBuilder has an addAll or putAll
            // method that accepts a Bar argument.
            boolean canMakeBarBuilder = (propertyBuilder.getBuiltToBuilder() != null || propertyBuilder.getCopyAll() != null);
            boolean needToMakeBarBuilder = (autoValueHasToBuilder || hasSetter);
            if (needToMakeBarBuilder && !canMakeBarBuilder) {
                errorReporter.reportError(propertyBuilder.getPropertyBuilderMethod(), "[AutoValueCantMakeBuilder] Property builder method returns %1$s but there is no" + " way to make that type from %2$s: %2$s does not have a non-static" + " toBuilder() method that returns %1$s, and %1$s does not have a method" + " addAll or putAll that accepts an argument of type %2$s", propertyBuilder.getBuilderTypeMirror(), propertyType);
            }
        } else if (!hasSetter && !propertiesWithDefaults.contains(property)) {
            // We have neither barBuilder() nor setBar(Bar), so we should complain.
            String setterName = settersPrefixed ? prefixWithSet(property) : property;
            errorReporter.reportError(builderType, "[%sBuilderMissingMethod] Expected a method with this signature: %s" + " %s(%s), or a %sBuilder() method", autoWhat(), builderType.asType(), setterName, propertyType, property);
        }
    }
    return errorReporter.errorCount() == startErrorCount;
}
Also used : TypeMirror(javax.lang.model.type.TypeMirror) PropertySetter(com.google.auto.value.processor.BuilderSpec.PropertySetter) ExecutableElement(javax.lang.model.element.ExecutableElement) PropertyBuilder(com.google.auto.value.processor.PropertyBuilderClassifier.PropertyBuilder)

Example 2 with PropertyBuilder

use of com.google.auto.value.processor.PropertyBuilderClassifier.PropertyBuilder in project auto by google.

the class BuilderMethodClassifier method classifyMethodNoArgs.

/**
 * Classifies a method given that it has no arguments. Currently a method with no arguments can be
 * a {@code build()} method, meaning that its return type must be the {@code @AutoValue} class; it
 * can be a getter, with the same signature as one of the property getters in the
 * {@code @AutoValue} class; or it can be a property builder, like {@code
 * ImmutableList.Builder<String> foosBuilder()} for the property defined by {@code
 * ImmutableList<String> foos()} or {@code getFoos()}.
 */
private void classifyMethodNoArgs(ExecutableElement method) {
    Optional<String> getterProperty = propertyForBuilderGetter(method);
    if (getterProperty.isPresent()) {
        classifyGetter(method, getterProperty.get());
        return;
    }
    String methodName = method.getSimpleName().toString();
    TypeMirror returnType = builderMethodReturnType(method);
    if (methodName.endsWith("Builder")) {
        String prefix = methodName.substring(0, methodName.length() - "Builder".length());
        String property = rewrittenPropertyTypes.containsKey(prefix) ? prefix : rewrittenPropertyTypes.keySet().stream().filter(p -> PropertyNames.decapitalizeNormally(p).equals(prefix)).findFirst().orElse(null);
        if (property != null) {
            PropertyBuilderClassifier propertyBuilderClassifier = new PropertyBuilderClassifier(errorReporter, typeUtils, elementUtils, this, this::propertyIsNullable, rewrittenPropertyTypes, eclipseHack);
            Optional<PropertyBuilder> propertyBuilder = propertyBuilderClassifier.makePropertyBuilder(method, property);
            if (propertyBuilder.isPresent()) {
                propertyNameToPropertyBuilder.put(property, propertyBuilder.get());
            }
            return;
        }
    }
    if (TYPE_EQUIVALENCE.equivalent(returnType, builtType)) {
        buildMethods.add(method);
    } else {
        errorReporter.reportError(method, "[%1$sBuilderNoArg] Method without arguments should be a build method returning" + " %2$s, or a getter method with the same name and type as %3$s," + " or fooBuilder() where %4$s is %3$s", // "where foo() or getFoo() is a method in..." or "where foo is a parameter of..."
        autoWhat(), builtType, getterMustMatch(), fooBuilderMustMatch());
    }
}
Also used : Iterables(com.google.common.collect.Iterables) AutoValueishProcessor.nullableAnnotationFor(com.google.auto.value.processor.AutoValueishProcessor.nullableAnnotationFor) MoreTypes(com.google.auto.common.MoreTypes) Modifier(javax.lang.model.element.Modifier) VariableElement(javax.lang.model.element.VariableElement) TypeElement(javax.lang.model.element.TypeElement) Multimap(com.google.common.collect.Multimap) Function(java.util.function.Function) Elements(javax.lang.model.util.Elements) ImmutableBiMap(com.google.common.collect.ImmutableBiMap) LinkedHashMap(java.util.LinkedHashMap) PropertySetter(com.google.auto.value.processor.BuilderSpec.PropertySetter) ImmutableList(com.google.common.collect.ImmutableList) Copier(com.google.auto.value.processor.BuilderSpec.Copier) Map(java.util.Map) DeclaredType(javax.lang.model.type.DeclaredType) ElementFilter(javax.lang.model.util.ElementFilter) ImmutableMultimap(com.google.common.collect.ImmutableMultimap) LinkedHashSet(java.util.LinkedHashSet) LinkedListMultimap(com.google.common.collect.LinkedListMultimap) MoreElements(com.google.auto.common.MoreElements) ImmutableSet(com.google.common.collect.ImmutableSet) Equivalence(com.google.common.base.Equivalence) ExecutableType(javax.lang.model.type.ExecutableType) ImmutableMap(com.google.common.collect.ImmutableMap) ExecutableElement(javax.lang.model.element.ExecutableElement) Set(java.util.Set) Element(javax.lang.model.element.Element) Types(javax.lang.model.util.Types) PropertyBuilder(com.google.auto.value.processor.PropertyBuilderClassifier.PropertyBuilder) TypeKind(javax.lang.model.type.TypeKind) TypeMirror(javax.lang.model.type.TypeMirror) Stream(java.util.stream.Stream) ProcessingEnvironment(javax.annotation.processing.ProcessingEnvironment) Optional(java.util.Optional) TypeMirror(javax.lang.model.type.TypeMirror) PropertyBuilder(com.google.auto.value.processor.PropertyBuilderClassifier.PropertyBuilder)

Aggregations

PropertySetter (com.google.auto.value.processor.BuilderSpec.PropertySetter)2 PropertyBuilder (com.google.auto.value.processor.PropertyBuilderClassifier.PropertyBuilder)2 ExecutableElement (javax.lang.model.element.ExecutableElement)2 TypeMirror (javax.lang.model.type.TypeMirror)2 MoreElements (com.google.auto.common.MoreElements)1 MoreTypes (com.google.auto.common.MoreTypes)1 AutoValueishProcessor.nullableAnnotationFor (com.google.auto.value.processor.AutoValueishProcessor.nullableAnnotationFor)1 Copier (com.google.auto.value.processor.BuilderSpec.Copier)1 Equivalence (com.google.common.base.Equivalence)1 ImmutableBiMap (com.google.common.collect.ImmutableBiMap)1 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 ImmutableMultimap (com.google.common.collect.ImmutableMultimap)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 Iterables (com.google.common.collect.Iterables)1 LinkedListMultimap (com.google.common.collect.LinkedListMultimap)1 Multimap (com.google.common.collect.Multimap)1 LinkedHashMap (java.util.LinkedHashMap)1 LinkedHashSet (java.util.LinkedHashSet)1 Map (java.util.Map)1