Skip to content

Commit

Permalink
Generation of default interface attributes was fixed #104
Browse files Browse the repository at this point in the history
+ make value attribute on annotations in absence of mandatory attributes
to be constructor parameter
+ improved validation of Value.Derived and Value.Default

+ so added Value source to value module so you can javadoc and have
sources and while you building a release
  • Loading branch information
elucash committed Apr 14, 2015
1 parent 4eeec9c commit 48b906e
Show file tree
Hide file tree
Showing 7 changed files with 615 additions and 13 deletions.
6 changes: 6 additions & 0 deletions value-fixture/src/org/immutables/fixture/IfaceValue.java
Expand Up @@ -26,4 +26,10 @@ public interface IfaceValue {


@Value.Auxiliary @Value.Auxiliary
List<String> auxiliary(); List<String> auxiliary();

@Value.Auxiliary
@Value.Derived
default int get() {
return getNumber() + auxiliary().size();
}
} }
9 changes: 8 additions & 1 deletion value-fixture/src/org/immutables/fixture/annotation/An.java
Expand Up @@ -26,6 +26,13 @@
String otherValue(); String otherValue();
} }


@Value.Immutable
@interface HasDefault {
int value();

String otherValue() default "";
}

@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Value.Immutable @Value.Immutable
@interface An { @interface An {
Expand All @@ -38,5 +45,5 @@
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@Value.Immutable @Value.Immutable
@interface Be { @interface Be {
Class<? extends Number>[] cl() default {Integer.class}; Class<? extends Number>[] cl() default {Integer.class, Double.class};
} }
Expand Up @@ -22,8 +22,7 @@
public class AnnotationTest { public class AnnotationTest {


@Test @Test
public void testName() { public void ann() {

An runtime = getClass().getAnnotation(An.class); An runtime = getClass().getAnnotation(An.class);
An immutable = ImmutableAn.of(13); An immutable = ImmutableAn.of(13);


Expand All @@ -34,4 +33,13 @@ public void testName() {


check(immutable.bees()).isOf(runtime.bees()); check(immutable.bees()).isOf(runtime.bees());
} }

@Test
public void bee() {
ImmutableHasDefault.of(1).withOtherValue("w");

check(ImmutableBe.builder().build()).is(ImmutableBe.builder()
.cl(Integer.class, Double.class)
.build());
}
} }
Expand Up @@ -195,23 +195,40 @@ private void processGenerationCandidateMethod(ExecutableElement attributeMethodC


if (isAbstract) { if (isAbstract) {
attribute.isGenerateAbstract = true; attribute.isGenerateAbstract = true;

if (attributeMethodCandidate.getDefaultValue() != null) { if (attributeMethodCandidate.getDefaultValue() != null) {
attribute.isGenerateDefault = true; attribute.isGenerateDefault = true;
} else if (defaultAnnotationPresent) { }
report(attributeMethodCandidate)
.annotationNamed(DefaultMirror.simpleName()) if (defaultAnnotationPresent || derivedAnnotationPresent) {
.error("@Value.Default should have initializer body", name); if (defaultAnnotationPresent) {
} else if (derivedAnnotationPresent) { if (attribute.isGenerateDefault) {
report(attributeMethodCandidate) report(attributeMethodCandidate)
.annotationNamed(DerivedMirror.simpleName()) .annotationNamed(DefaultMirror.simpleName())
.error("@Value.Derived should have initializer body", name); .warning("@Value.Default annotation is superflous for default annotation attribute");
} else {
report(attributeMethodCandidate)
.annotationNamed(DefaultMirror.simpleName())
.error("@Value.Default attibute should have initializer body", name);
}
}
if (derivedAnnotationPresent) {
if (attribute.isGenerateDefault) {
report(attributeMethodCandidate)
.annotationNamed(DerivedMirror.simpleName())
.error("@Value.Derived cannot be used with default annotation attribute");
} else {
report(attributeMethodCandidate)
.annotationNamed(DerivedMirror.simpleName())
.error("@Value.Derived attibute should have initializer body", name);
}
}
} }
} else if (defaultAnnotationPresent && derivedAnnotationPresent) { } else if (defaultAnnotationPresent && derivedAnnotationPresent) {
report(attributeMethodCandidate) report(attributeMethodCandidate)
.annotationNamed(DerivedMirror.simpleName()) .annotationNamed(DerivedMirror.simpleName())
.error("Attribute '%s' cannot be both @Value.Default and @Value.Derived", name); .error("Attribute '%s' cannot be both @Value.Default and @Value.Derived", name);
attribute.isGenerateDefault = true; attribute.isGenerateDefault = true;
attribute.isGenerateDerived = false;
} else if ((defaultAnnotationPresent || derivedAnnotationPresent) && isFinal) { } else if ((defaultAnnotationPresent || derivedAnnotationPresent) && isFinal) {
report(attributeMethodCandidate) report(attributeMethodCandidate)
.error("Annotated attribute '%s' will be overriden and cannot be final", name); .error("Annotated attribute '%s' will be overriden and cannot be final", name);
Expand Down
Expand Up @@ -55,6 +55,7 @@ public final class ValueAttribute extends TypeIntrospectionBase {


private static final String GUAVA_IMMUTABLE_PREFIX = UnshadeGuava.typeString("collect.Immutable"); private static final String GUAVA_IMMUTABLE_PREFIX = UnshadeGuava.typeString("collect.Immutable");
private static final String NULLABLE_SIMPLE_NAME = "Nullable"; private static final String NULLABLE_SIMPLE_NAME = "Nullable";
private static final String VALUE_ATTRIBUTE_NAME = "value";
private static final String ID_ATTRIBUTE_NAME = "_id"; private static final String ID_ATTRIBUTE_NAME = "_id";


public AttributeNames names; public AttributeNames names;
Expand Down Expand Up @@ -132,6 +133,7 @@ public boolean requiresAlternativeStrictConstructor() {


public boolean isMandatory() { public boolean isMandatory() {
return isGenerateAbstract return isGenerateAbstract
&& !isGenerateDefault // is the case for defaulted abstract annotation attribute
&& !isContainerType() && !isContainerType()
&& !isNullable() && !isNullable()
&& !hasBuilderSwitcherDefault(); && !hasBuilderSwitcherDefault();
Expand Down Expand Up @@ -650,10 +652,24 @@ int getConstructorParameterOrder() {
constructorOrder = parameter.isPresent() constructorOrder = parameter.isPresent()
? parameter.get().order() ? parameter.get().order()
: -1; : -1;

if (containingType.isAnnotationType() && names.get.equals(VALUE_ATTRIBUTE_NAME)) {
constructorOrder = thereNoOtherMandatoryAttributes() ? 0 : -1;
}
} }
return constructorOrder; return constructorOrder;
} }


private boolean thereNoOtherMandatoryAttributes() {
List<ValueAttribute> mandatories = containingType.getMandatoryAttributes();
for (ValueAttribute m : mandatories) {
if (m != this) {
return false;
}
}
return true;
}

public boolean isConstructorParameter() { public boolean isConstructorParameter() {
return getConstructorParameterOrder() >= 0; return getConstructorParameterOrder() >= 0;
} }
Expand Down Expand Up @@ -732,7 +748,7 @@ private void makeRegularIfDefaultWithValidation() {


private void makeRegularIfContainsWildcards() { private void makeRegularIfContainsWildcards() {
// I hope this check isn't too simplistic // I hope this check isn't too simplistic
if (returnTypeName.indexOf('?') >= 0) { if (returnTypeName.indexOf('?') >= 0 && typeKind != AttributeTypeKind.ARRAY) {
typeKind = AttributeTypeKind.REGULAR; typeKind = AttributeTypeKind.REGULAR;
} }
} }
Expand Down
6 changes: 6 additions & 0 deletions value/pom.xml
Expand Up @@ -16,11 +16,13 @@
<artifactId>value</artifactId> <artifactId>value</artifactId>


<dependencies> <dependencies>
<!--
<dependency> <dependency>
<groupId>org.immutables</groupId> <groupId>org.immutables</groupId>
<artifactId>value-annotations</artifactId> <artifactId>value-annotations</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
-->
<dependency> <dependency>
<groupId>org.immutables</groupId> <groupId>org.immutables</groupId>
<artifactId>value-processor</artifactId> <artifactId>value-processor</artifactId>
Expand Down Expand Up @@ -56,7 +58,9 @@
<artifactSet> <artifactSet>
<includes> <includes>
<include>org.immutables:value</include> <include>org.immutables:value</include>
<!--
<include>org.immutables:value-annotations</include> <include>org.immutables:value-annotations</include>
-->
<include>org.immutables:value-processor</include> <include>org.immutables:value-processor</include>
<include>org.immutables:generator</include> <include>org.immutables:generator</include>
<include>com.google.guava:guava</include> <include>com.google.guava:guava</include>
Expand All @@ -83,12 +87,14 @@
</relocations> </relocations>


<filters> <filters>
<!--
<filter> <filter>
<artifact>org.immutables:value-annotations</artifact> <artifact>org.immutables:value-annotations</artifact>
<includes> <includes>
<include>**</include> <include>**</include>
</includes> </includes>
</filter> </filter>
-->
<filter> <filter>
<artifact>org.immutables:value-processor</artifact> <artifact>org.immutables:value-processor</artifact>
<includes> <includes>
Expand Down

0 comments on commit 48b906e

Please sign in to comment.