Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3abee0a

Browse files
committed
handle Optional with defaults
1 parent 668a168 commit 3abee0a

File tree

7 files changed

+194
-4
lines changed

7 files changed

+194
-4
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
Copyright 2025 Immutables Authors and Contributors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
package org.immutables.fixture.jdkonly;
17+
18+
import java.util.Optional;
19+
20+
import org.immutables.value.Value;
21+
22+
@Value.Immutable
23+
public interface OptionalDefault {
24+
@Value.Default
25+
default Optional<String> text() {
26+
return Optional.of("foo");
27+
}
28+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
Copyright 2025 Immutables Authors and Contributors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
package org.immutables.fixture.jdkonly;
17+
18+
import java.util.OptionalDouble;
19+
20+
import org.immutables.value.Value;
21+
22+
@Value.Immutable
23+
public interface OptionalDoubleDefault {
24+
@Value.Default
25+
default OptionalDouble magic() {
26+
return OptionalDouble.of(42);
27+
}
28+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
Copyright 2025 Immutables Authors and Contributors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
package org.immutables.fixture.jdkonly;
17+
18+
import java.util.OptionalInt;
19+
20+
import org.immutables.value.Value;
21+
22+
@Value.Immutable
23+
public interface OptionalIntDefault {
24+
@Value.Default
25+
default OptionalInt magic() {
26+
return OptionalInt.of(42);
27+
}
28+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
Copyright 2025 Immutables Authors and Contributors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
package org.immutables.fixture.jdkonly;
17+
18+
import java.util.OptionalLong;
19+
20+
import org.immutables.value.Value;
21+
22+
@Value.Immutable
23+
public interface OptionalLongDefault {
24+
@Value.Default
25+
default OptionalLong magic() {
26+
return OptionalLong.of(42);
27+
}
28+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
Copyright 2025 Immutables Authors and Contributors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
package org.immutables.fixture.jdkonly;
17+
18+
import static org.immutables.check.Checkers.check;
19+
20+
import java.util.Optional;
21+
import java.util.OptionalDouble;
22+
import java.util.OptionalInt;
23+
import java.util.OptionalLong;
24+
25+
import org.junit.jupiter.api.Test;
26+
27+
public class JdkOptionalDefaultTest {
28+
29+
@Test
30+
public void optionalDefault() {
31+
check(ImmutableOptionalDefault.builder().build().text()).is(Optional.of("foo"));
32+
check(ImmutableOptionalDefault.builder().text(Optional.empty()).build().text()).is(Optional.empty());
33+
check(ImmutableOptionalDefault.builder().text(Optional.of("bar")).build().text()).is(Optional.of("bar"));
34+
check(ImmutableOptionalDefault.builder().text("bar").build().text()).is(Optional.of("bar"));
35+
}
36+
37+
@Test
38+
public void optionalIntDefault() {
39+
check(ImmutableOptionalIntDefault.builder().build().magic()).is(OptionalInt.of(42));
40+
check(ImmutableOptionalIntDefault.builder().magic(OptionalInt.empty()).build().magic()).is(OptionalInt.empty());
41+
check(ImmutableOptionalIntDefault.builder().magic(OptionalInt.of(17)).build().magic()).is(OptionalInt.of(17));
42+
check(ImmutableOptionalIntDefault.builder().magic(17).build().magic()).is(OptionalInt.of(17));
43+
}
44+
45+
@Test
46+
public void optionalLongDefault() {
47+
check(ImmutableOptionalLongDefault.builder().build().magic()).is(OptionalLong.of(42));
48+
check(ImmutableOptionalLongDefault.builder().magic(OptionalLong.empty()).build().magic()).is(OptionalLong.empty());
49+
check(ImmutableOptionalLongDefault.builder().magic(OptionalLong.of(17)).build().magic()).is(OptionalLong.of(17));
50+
check(ImmutableOptionalLongDefault.builder().magic(17).build().magic()).is(OptionalLong.of(17));
51+
}
52+
53+
@Test
54+
public void optionalDoubleDefault() {
55+
check(ImmutableOptionalDoubleDefault.builder().build().magic()).is(OptionalDouble.of(42));
56+
check(ImmutableOptionalDoubleDefault.builder().magic(OptionalDouble.empty()).build().magic()).is(OptionalDouble.empty());
57+
check(ImmutableOptionalDoubleDefault.builder().magic(OptionalDouble.of(17)).build().magic()).is(OptionalDouble.of(17));
58+
check(ImmutableOptionalDoubleDefault.builder().magic(17).build().magic()).is(OptionalDouble.of(17));
59+
}
60+
}

value-processor/src/org/immutables/value/processor/Immutables.generator

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2599,6 +2599,25 @@ checkNotIsSet([v.names.isSet](), "[v.names.raw]");
25992599
[mandatorySetInBuilder v]
26002600
return [builderReturnThis type];
26012601
}
2602+
2603+
[if v.optionalWithDefault]
2604+
/**
2605+
* Initializes the optional value [sourceDocRef v] to [v.name].
2606+
* <p><em>If not set, this attribute will have a default value as returned by the initializer of [sourceDocRef v].</em>
2607+
* @param [v.name] The value for [v.name][if v.optionalAcceptNullable], {@code null} is accepted as {@code [optionalEmpty v]}[/if]
2608+
* @return {@code this} builder for chained invocation
2609+
*/
2610+
[eachLine v.elementInitializerInjectedAnnotations]
2611+
[atCanIgnoreReturnValue type]
2612+
[deprecation v]
2613+
[builderInitAccess v]final [builderReturnType type] [v.names.init]([v.unwrappedElementType] [v.name]) {
2614+
[checkNotIsSet v]
2615+
this.[v.name] = [optionalOf v]([maybeCopyOf v][v.name][/maybeCopyOf]);
2616+
[nondefaultSetInBuilder v]
2617+
return [builderReturnThis type];
2618+
}
2619+
[/if]
2620+
26022621
[if v.isAttributeBuilder]
26032622

26042623
/**

value-processor/src/org/immutables/value/processor/meta/ValueAttribute.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ public final class ValueAttribute extends TypeIntrospectionBase implements HasSt
8282

8383
public AttributeNames names;
8484
public boolean isGenerateDefault;
85+
public boolean isOptionalWithDefault;
8586
public @Nullable Object constantDefault;
8687
public boolean isGenerateDerived;
8788
public boolean isGenerateAbstract;
@@ -688,7 +689,7 @@ public boolean hasVirtualImpl() {
688689
}
689690

690691
public String getUnwrappedElementType() {
691-
return isContainerType() && nullElements.ban()
692+
return (isContainerType() && nullElements.ban()) || isOptionalWithDefault
692693
? unwrapType(firstTypeParameter())
693694
: getElementType();
694695
}
@@ -1628,9 +1629,7 @@ private void validateTypeAndAnnotations() {
16281629

16291630
if (isGenerateDefault && isOptionalType()) {
16301631
typeKind = AttributeTypeKind.REGULAR;
1631-
report()
1632-
.annotationNamed(DefaultMirror.simpleName())
1633-
.warning(About.UNTYPE, "@Value.Default on a optional attribute make it lose its special treatment");
1632+
isOptionalWithDefault = true;
16341633
}
16351634

16361635
if (isContainerType() && containingType.isUseStrictBuilder()) {

0 commit comments

Comments
 (0)