Skip to content

Commit

Permalink
Merge pull request #1423 from immutables/impl-1112
Browse files Browse the repository at this point in the history
Experimental #1112 requiring Enclosing annotation
  • Loading branch information
elucash committed Mar 22, 2023
2 parents 8c1a8c7 + 37e14ee commit 5eb1de3
Show file tree
Hide file tree
Showing 11 changed files with 1,099 additions and 963 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
package org.immutables.builder.fixture.telescopic;
import org.immutables.value.Value;

// in current implementation stagedBuilder is ignored
@Value.Immutable
@Value.Style(stagedBuilder = true, implementationNestedInBuilder = true)
public interface ImplInBuilder {
int a();
String b();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.immutables.builder.fixture.telescopic;

import javax.annotation.Nullable;
import org.immutables.builder.Builder;
import org.immutables.value.Value;

@Value.Enclosing
@Value.Style(stagedBuilder = true)
public class StagedFactory {
@Builder.Factory
public static String superstring(int theory, String reality, @Nullable Void evidence) {
return theory + " != " + reality + ", " + evidence;
}

@Builder.Factory
public static String hop(@Builder.Parameter String a, int b) {
return a + b;
}
}
24 changes: 15 additions & 9 deletions builder/test/org/immutables/builder/fixture/telescopic/Use.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,21 @@

public class Use {
public static void main(String... args) {
ImmutableMoji.builder()
.a(1)
.b("")
.build();
ImmutableMoji.ABuildStage b = ImmutableMoji.builder();
ImmutableMoji.BBuildStage a = b.a(1);
ImmutableMoji.BuildFinal f = a.b("");
ImmutableMoji moji = f.build();

ImmutableStg.builder()
.a(1)
.b(1.2)
.c("c")
.build();
ImmutableStg.ABuildStage b1 = ImmutableStg.builder();
ImmutableStg.BBuildStage a1 = b1.a(1);
ImmutableStg.CBuildStage c1 = a1.b(1.2);
ImmutableStg.BuildFinal f1 = c1.c("c");
ImmutableStg stg = f1.build();

ImmutableStagedFactory.SuperstringTheoryBuildStage b2 = ImmutableStagedFactory.superstringBuilder();
ImmutableStagedFactory.SuperstringRealityBuildStage t2 = b2.theory(1);
ImmutableStagedFactory.SuperstringBuildFinal r2 = t2.reality("x");
ImmutableStagedFactory.SuperstringBuildFinal e2 = r2.evidence(null);
String superstring = e2.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.immutables.fixture;

import org.immutables.value.Value;

@Value.Style(jdkOnly = true)
@Value.Immutable
public interface HasFirstRedactedCompletely {
@Value.Redacted
int a1();
int a2();
}
10 changes: 10 additions & 0 deletions value-fixture/test/org/immutables/fixture/ValuesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,16 @@ public void redactedCompletely() {
check(b).hasToString("Redacted{id=2}");
}

@Test
public void redactedCompletelyAgain() {
HasFirstRedactedCompletely b = ImmutableHasFirstRedactedCompletely.builder()
.a1(1)
.a2(2)
.build();

check(b).hasToString("HasFirstRedactedCompletely{a2=2}");
}

@Test
public void redactedMask() {
ImmutableRedactedMask m = ImmutableRedactedMask.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,13 @@ import static [routine].immutableCopyOf;
[type.typeEnclosing.access]final class [type.typeEnclosing.simple] {
private [type.typeEnclosing.simple]() {}
[for v in type.nested]
[if v.constitution.isNested]
[generateImmutable v false]
[/if]
[if v.constitution.isOutsideBuilder]
[if v.kind.isNestedFactoryOrConstructor]
[generateBuilderFactory v]
[/if]
[generateBuilder v false]
[/if]
[if v.generateWithInterface]
Expand All @@ -121,6 +126,25 @@ import static [routine].immutableCopyOf;
}
[/template]

[template generateBuilderFactory Type type]
[if not type.factoryBuilder.isNew]
[for parameters = type.builderParameters]

/**
* Creates a {@code [type.typeBuilderImpl.simple]} factory builder.
[javadocGenerics type]
[for p in parameters]
* @param [p.name] {@code [p.name]} parameter[if p.nullable], can be {@code null}[/if]
[/for]
* @return A new {@code [type.typeBuilderImpl.simple]} builder
*/
public static[type.generics.def] [factoryBuildStageBuilderType type] [type.factoryBuilder.applied]([for p in parameters][if not for.first], [/if][p.atNullability][constructorAcceptType p] [p.name][/for]) {
return new [type.typeBuilderImpl.relativeRaw][type.generics.diamond]([for p in parameters][if not for.first], [/if][p.name][/for]);
}
[/for]
[/if]
[/template]

[template generateImmutable Type type Boolean topLevel]
[packageWhenTopLevel type topLevel]

Expand Down Expand Up @@ -1000,18 +1024,18 @@ public [type.typeAbstract.relative] [v.names.with]([v.atNullability][v.type] val

[template castBuildStagedBuilder Type type String expression][for tb = type.telescopicBuild][if tb andnot type.innerBuilder.isExtending](([type.typeBuilderImpl.relative]) [expression])[else][expression][/if][/for][/template]

[template factoryBuildStageBuilderType Type type][for tb = type.telescopicBuild][if tb][toUpper tb.firstStage.attribute.name]BuildStage[type.generics.args][else][type.typeBuilderImpl.relative][/if][/for][/template]
[template factoryBuildStageBuilderType Type type][for tb = type.telescopicBuild][if tb][toUpper tb.firstStage.nameBuildStage][type.generics.args][else][type.typeBuilderImpl.relative][/if][/for][/template]

[template telescopicBuilderImplementInterfaces Type type][for tb = type.telescopicBuild][if tb][for nt in tb.stages, v = nt.attribute][toUpper v.name]BuildStage[type.generics.args], [/for]BuildFinal[type.generics.args][/if][/for][/template]
[template telescopicBuilderImplementInterfaces Type type][for tb = type.telescopicBuild][if tb][for nt in tb.stages, v = nt.attribute][nt.nameBuildStage][type.generics.args], [/for][tb.nameBuildFinal][type.generics.args][/if][/for][/template]

[template generateTelescopicBuilderInterfaces Type type]
[for tb = type.telescopicBuild]
[if tb]
[for nt in tb.stages, v = nt.attribute]
[let builderReturn][if nt.next][toUpper nt.next.attribute.name]BuildStage[type.generics.args][else]BuildFinal[type.generics.args][/if][/let]
[let builderReturn][if nt.next][nt.next.nameBuildStage][type.generics.args][else][tb.nameBuildFinal][type.generics.args][/if][/let]

[atGenerated type]
public interface [toUpper v.name]BuildStage[type.generics] {
public interface [nt.nameBuildStage][type.generics] {
/**
* Initializes the value for the [sourceDocRef v] attribute.
* @param [v.name] The value for [v.name] [if v.nullable](can be {@code null})[/if]
Expand All @@ -1023,7 +1047,7 @@ public interface [toUpper v.name]BuildStage[type.generics] {
[/for]

[atGenerated type]
public interface BuildFinal[type.generics] {
public interface [tb.nameBuildFinal][type.generics] {
[for v in tb.finals]
[if v.encoding]
[-- not implemented --]
Expand All @@ -1035,23 +1059,23 @@ public interface BuildFinal[type.generics] {
* @return {@code this} builder for use in a chained invocation
*/
[deprecation v]
BuildFinal[type.generics.args] [v.names.add]([v.unwrappedElementType] element);
[tb.nameBuildFinal][type.generics.args] [v.names.add]([v.unwrappedElementType] element);

/**
* Adds elements to [sourceDocRef v] [toLower v.rawCollectionType].
* @param elements An array of [v.name] elements
* @return {@code this} builder for use in a chained invocation
*/
[deprecation v]
BuildFinal[type.generics.args] [v.names.addv]([v.unwrappedElementType]... elements);
[tb.nameBuildFinal][type.generics.args] [v.names.addv]([v.unwrappedElementType]... elements);

/**
* Adds elements to [sourceDocRef v] [toLower v.rawCollectionType].
* @param elements An iterable of [v.name] elements
* @return {@code this} builder for use in a chained invocation
*/
[deprecation v]
BuildFinal[type.generics.args] [v.names.addAll](Iterable<[v.consumedElementType]> elements);
[tb.nameBuildFinal][type.generics.args] [v.names.addAll](Iterable<[v.consumedElementType]> elements);
[else if v.optionalType]

/**
Expand All @@ -1060,15 +1084,15 @@ public interface BuildFinal[type.generics] {
* @return {@code this} builder for chained invocation
*/
[deprecation v]
BuildFinal[type.generics.args] [v.names.init]([unwrappedOptionalType v] [v.name]);
[tb.nameBuildFinal][type.generics.args] [v.names.init]([unwrappedOptionalType v] [v.name]);

/**
* Initializes the optional value [sourceDocRef v] to [v.name].
* @param [v.name] The value for [v.name]
* @return {@code this} builder for use in a chained invocation
*/
[deprecation v]
BuildFinal[type.generics.args] [v.names.init]([v.rawType][if not v.jdkSpecializedOptional]<[v.consumedElementType]>[/if] [v.name]);
[tb.nameBuildFinal][type.generics.args] [v.names.init]([v.rawType][if not v.jdkSpecializedOptional]<[v.consumedElementType]>[/if] [v.name]);
[else if v.mapType]
[for gE = v.consumedElementType, uK = v.unwrappedElementType, wK = v.wrappedElementType, uV = v.unwrappedSecondaryElementType, wV = v.wrappedSecondaryElementType]
[if v.multimapType]
Expand All @@ -1080,7 +1104,7 @@ public interface BuildFinal[type.generics] {
* @return {@code this} builder for use in a chained invocation
*/
[deprecation v]
BuildFinal[type.generics.args] [v.names.putv]([uK] key, [uV]... values);
[tb.nameBuildFinal][type.generics.args] [v.names.putv]([uK] key, [uV]... values);

/**
* Put all mappings from the specified key to values for [sourceDocRef v] [toLower v.mapType]. Nulls are not permitted
Expand All @@ -1089,7 +1113,7 @@ public interface BuildFinal[type.generics] {
* @return {@code this} builder for use in a chained invocation
*/
[deprecation v]
BuildFinal[type.generics.args] [v.names.putAll]([uK] key, Iterable<[wV]> values);
[tb.nameBuildFinal][type.generics.args] [v.names.putAll]([uK] key, Iterable<[wV]> values);
[/if]

/**
Expand All @@ -1099,23 +1123,23 @@ public interface BuildFinal[type.generics] {
* @return {@code this} builder for use in a chained invocation
*/
[deprecation v]
BuildFinal[type.generics.args] [v.names.put]([uK] key, [uV] value);
[tb.nameBuildFinal][type.generics.args] [v.names.put]([uK] key, [uV] value);

/**
* Put one entry to the [sourceDocRef v] map. Nulls are not permitted
* @param entry The key and value entry
* @return {@code this} builder for use in a chained invocation
*/
[deprecation v]
BuildFinal[type.generics.args] [v.names.put](java.util.Map.Entry<[gE], ? extends [wV]> entry);
[tb.nameBuildFinal][type.generics.args] [v.names.put](java.util.Map.Entry<[gE], ? extends [wV]> entry);

/**
* Put all mappings from the specified map as entries to [sourceDocRef v] map. Nulls are not permitted
* @param entries The entries that will be added to the [v.name] map
* @return {@code this} builder for use in a chained invocation
*/
[deprecation v]
BuildFinal[type.generics.args] [v.names.putAll]([if v.multimapType][guava].collect.Multimap[else]java.util.Map[/if]<[gE], ? extends [wV]> entries);
[tb.nameBuildFinal][type.generics.args] [v.names.putAll]([if v.multimapType][guava].collect.Multimap[else]java.util.Map[/if]<[gE], ? extends [wV]> entries);
[/for]
[else if v.arrayType]

Expand All @@ -1128,7 +1152,7 @@ public interface BuildFinal[type.generics] {
* @return {@code this} builder for use in a chained invocation
*/
[deprecation v]
BuildFinal[type.generics.args] [v.names.init]([v.elementType]... elements);
[tb.nameBuildFinal][type.generics.args] [v.names.init]([v.elementType]... elements);
[else]

/**
Expand All @@ -1140,7 +1164,7 @@ public interface BuildFinal[type.generics] {
* @return {@code this} builder for use in a chained invocation
*/
[deprecation v]
BuildFinal[type.generics.args] [v.names.init]([v.atNullability][v.type] [v.name]);
[tb.nameBuildFinal][type.generics.args] [v.names.init]([v.atNullability][v.type] [v.name]);
[/if]
[/for]

Expand All @@ -1165,7 +1189,7 @@ public interface BuildFinal[type.generics] {
LongPositions nondefaultsPositions = longsFor nondefaults]

/**
[if type.kind.isFactory]
[if type.kind.isFactory or type.kind.isNestedFactoryOrConstructor]
* {@code [type.typeBuilderImpl.simple]} collects parameters and invokes the static factory method:
* {@code [type.factoryOf](..)}.
* Call the {@link #[type.names.build]()} method to get a result of type {@code [type.typeValue]}.
Expand Down Expand Up @@ -1275,7 +1299,7 @@ public interface BuildFinal[type.generics] {
}
[/if]
[if useFactoryMethod]
[if type.kind.isFactory or type.constitution.isOutsideBuilder]
[if type.kind.isFactoryNotNested or type.constitution.isOutsideBuilderNotNested]

/**
[if type.kind.isFactory]
Expand Down Expand Up @@ -1344,7 +1368,7 @@ public interface BuildFinal[type.generics] {
[atCanIgnoreReturnValue type]
public final [builderReturnType type] [type.names.from]([type.typeImmutable.relative] instance) {
[requireNonNull type](instance, "instance");
from((Object) instance);
from((short) 0, (Object) instance);
return [builderReturnThis type];
}

Expand All @@ -1356,7 +1380,7 @@ public interface BuildFinal[type.generics] {
[atCanIgnoreReturnValue type]
public final [builderReturnType type] [type.names.from]([type.typeAbstract.relative] instance) {
[requireNonNull type](instance, "instance");
from((Object) instance);
from((short) 0, (Object) instance);
return [builderReturnThis type];
}
[else]
Expand All @@ -1369,7 +1393,7 @@ public interface BuildFinal[type.generics] {
[atCanIgnoreReturnValue type]
public final [builderReturnType type] [type.names.from]([s.type] instance) {
[requireNonNull type](instance, "instance");
from((Object) instance);
from((short) 0, (Object) instance);
return [builderReturnThis type];
}
[/if]
Expand All @@ -1379,7 +1403,7 @@ public interface BuildFinal[type.generics] {
[if bs.hasWildcards andnot type.suppressesUncheckedWarning]
@SuppressWarnings("unchecked")
[/if]
private void from(Object object) {
private void from(short _unused, Object object) {
[dynamicFromModifiableCheck type 'object' 'return;']
[for l in bs.positions.longs]
[atVar type]long bits[emptyIfZero l.index] = 0;
Expand Down Expand Up @@ -3350,9 +3374,8 @@ public String toString() {
return builder.append([if type.annotationType]")"[else]"}"[/if]).toString();
[else]
return [if type.annotationType]"@[type.name]("[else]"[type.name]{"[/if]
[for v in type.equivalenceAttributes]
[if v.redactedCompletely][-- Nothing --]
[else if v.arrayType]
[for v in type.equivalenceAttributes if not (v.redactedCompletely)]
[if v.arrayType]
+ "[if not for.first], [/if][v.names.raw]=" + [maybeMasked v]java.util.Arrays.toString([v.name])[/maybeMasked]
[else if v.encoding]
+ "[if not for.first], [/if][v.names.raw]=" + [maybeMasked v]([rr.string v])[/maybeMasked]
Expand Down

0 comments on commit 5eb1de3

Please sign in to comment.