Skip to content

Commit 6e0ef82

Browse files
committed
Merge branch 'WildcardType' into 'master'
WildcardType supported by TypeUtil See merge request exedio/copebuilder!32
2 parents 60aee13 + b6752fe commit 6e0ef82

4 files changed

Lines changed: 64 additions & 6 deletions

File tree

src/com/exedio/cope/builder/generator/Writer.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import com.exedio.cope.pattern.PriceField;
2121
import com.exedio.cope.pattern.RangeField;
2222
import com.exedio.cope.pattern.SetField;
23-
import com.exedio.cope.reflect.TypeField;
2423
import java.io.IOException;
2524
import java.lang.reflect.Modifier;
2625
import java.util.Locale;
@@ -82,10 +81,6 @@ static void writeGeneratedBuilder(final MyType<?> type, final JavaClassWriter wr
8281
feature instanceof MapField<?, ?>))
8382
continue;
8483

85-
//TODO should be handled later, will need changes in isVisible and getCanonicalName for WildcardType
86-
if (feature instanceof TypeField<?>)
87-
continue;
88-
8984
if(feature instanceof Settable &&
9085
!TypeUtil.isVisible(type.getPackageName(), ((Settable<?>) feature).getInitialType()))
9186
continue;

src/com/exedio/cope/builder/generator/type/TypeUtil.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.lang.reflect.Modifier;
1111
import java.lang.reflect.ParameterizedType;
1212
import java.lang.reflect.Type;
13+
import java.lang.reflect.WildcardType;
1314
import java.util.Arrays;
1415
import java.util.List;
1516
import java.util.Map;
@@ -38,6 +39,8 @@ public static String getCanonicalName(@Nonnull final Type type)
3839
return getCanonicalName((Class<?>) type);
3940
else if(type instanceof ParameterizedType)
4041
return getCanonicalName((ParameterizedType) type);
42+
else if(type instanceof WildcardType)
43+
return getCanonicalName((WildcardType) type);
4144
else
4245
throw new RuntimeException("Unhandled type " + type + " -- " + type.getClass());
4346
}
@@ -48,6 +51,32 @@ private static String getCanonicalName(@Nonnull final Class<?> clazz)
4851
return clazz.getCanonicalName() + typeParameterWildCards(clazz);
4952
}
5053

54+
@Nonnull
55+
private static String getCanonicalName(@Nonnull final WildcardType type)
56+
{
57+
final Type[] upper = type.getUpperBounds();
58+
if(upper.length==1)
59+
{
60+
if(type.getLowerBounds().length!=0)
61+
throw new RuntimeException(Arrays.toString(type.getLowerBounds()));
62+
63+
if(Object.class.equals(upper[0]))
64+
return "?";
65+
66+
return "? extends " + getCanonicalName(upper[0]);
67+
}
68+
69+
final Type[] lower = type.getLowerBounds();
70+
if(lower.length==1)
71+
{
72+
if(upper.length!=0)
73+
throw new RuntimeException(Arrays.toString(upper));
74+
return "? super " + getCanonicalName(lower[0]);
75+
}
76+
77+
throw new RuntimeException(Arrays.asList(upper).toString() + Arrays.asList(lower));
78+
}
79+
5180
@Nonnull
5281
private static String getCanonicalName(@Nonnull final ParameterizedType type)
5382
{
@@ -122,6 +151,8 @@ public static boolean isVisible(final String packageName, final Type type)
122151
return isVisible(packageName, (Class<?>) type);
123152
else if(type instanceof ParameterizedType)
124153
return isVisible(packageName, (ParameterizedType) type);
154+
else if(type instanceof WildcardType)
155+
return isVisible(packageName, (WildcardType) type);
125156
else
126157
throw new RuntimeException(type.getTypeName() + ' ' + type.getClass());
127158
}
@@ -149,6 +180,19 @@ private static boolean isVisible(final String packageName, final Class<?> clazz)
149180
return packageName.equals(clazz.getPackage().getName());
150181
}
151182

183+
private static boolean isVisible(final String packageName, final WildcardType type)
184+
{
185+
for(final Type argument : type.getUpperBounds())
186+
if(!isVisible(packageName, argument))
187+
return false;
188+
189+
for(final Type argument : type.getLowerBounds())
190+
if(!isVisible(packageName, argument))
191+
return false;
192+
193+
return true;
194+
}
195+
152196
private TypeUtil()
153197
{
154198
// prevent instantiation

testmodelsrc/com/exedio/cope/builder/other/ConcreteItem.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ public final class ConcreteItem extends AbstractItem
1515
@Wrapper(wrap="get", visibility=PUBLIC)
1616
private static final IntegerField concreteField = new IntegerField().toFinal();
1717

18+
@Wrapper(wrap="get", visibility=PUBLIC)
1819
private static final TypeField<AbstractItem> typeField = TypeField.create(AbstractItem.class).optional();
20+
1921
/**
2022
* Returns the value of {@link #concreteField}.
2123
*/
@@ -31,7 +33,7 @@ public final int getConcreteField()
3133
*/
3234
@com.exedio.cope.instrument.Generated // customize with @Wrapper(wrap="get")
3335
@java.lang.SuppressWarnings({"FinalMethodInFinalClass","RedundantSuppression","TypeParameterExtendsFinalClass","UnnecessarilyQualifiedStaticUsage"})
34-
private com.exedio.cope.Type<? extends AbstractItem> getTypeField()
36+
public final com.exedio.cope.Type<? extends AbstractItem> getTypeField()
3537
{
3638
return ConcreteItem.typeField.get(this);
3739
}

testsrc/com/exedio/cope/builder/test/AbstractTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,21 @@ public void commonAbstract() throws NoSuchMethodException
3737
assertTrue(Modifier.isPublic(MixedLevel2ItemBuilder.class.getDeclaredConstructor().getModifiers()));
3838
assertEquals(asList(), asList(GeneratedAbstractLevel1ItemBuilder.class.getDeclaredClasses()));
3939
}
40+
41+
@Test
42+
public void typeFieldExplicit()
43+
{
44+
final ConcreteItem i = new ConcreteItemBuilder().
45+
typeField(AbstractItem.TYPE).
46+
build();
47+
assertEquals(AbstractItem.TYPE, i.getTypeField());
48+
}
49+
50+
@Test
51+
public void typeFieldFallback()
52+
{
53+
final ConcreteItem i = new ConcreteItemBuilder().
54+
build();
55+
assertEquals(null, i.getTypeField());
56+
}
4057
}

0 commit comments

Comments
 (0)