Skip to content

Commit 0200a5e

Browse files
authored
Merge pull request #276 from kakusuke/foreach-array
support Array Object in %for clause
2 parents 8c40996 + db29fb4 commit 0200a5e

File tree

15 files changed

+271
-14
lines changed

15 files changed

+271
-14
lines changed

src/main/java/org/seasar/doma/internal/apt/Types.java

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,27 @@
22

33
import static org.seasar.doma.internal.util.AssertionUtil.assertNotNull;
44

5-
import java.util.*;
5+
import java.util.Collections;
6+
import java.util.HashMap;
7+
import java.util.Iterator;
8+
import java.util.List;
9+
import java.util.Map;
610
import javax.annotation.processing.ProcessingEnvironment;
711
import javax.lang.model.element.Element;
812
import javax.lang.model.element.TypeElement;
913
import javax.lang.model.element.TypeParameterElement;
10-
import javax.lang.model.type.*;
14+
import javax.lang.model.type.ArrayType;
15+
import javax.lang.model.type.DeclaredType;
16+
import javax.lang.model.type.ExecutableType;
17+
import javax.lang.model.type.NoType;
18+
import javax.lang.model.type.NullType;
19+
import javax.lang.model.type.PrimitiveType;
20+
import javax.lang.model.type.TypeKind;
21+
import javax.lang.model.type.TypeMirror;
22+
import javax.lang.model.type.TypeVariable;
23+
import javax.lang.model.type.WildcardType;
1124
import javax.lang.model.util.SimpleElementVisitor8;
25+
import javax.lang.model.util.SimpleTypeVisitor6;
1226
import javax.lang.model.util.SimpleTypeVisitor8;
1327
import javax.lang.model.util.TypeKindVisitor8;
1428

@@ -153,6 +167,18 @@ public TypeVariable visitTypeVariable(TypeVariable t, Void p) {
153167
null);
154168
}
155169

170+
public ArrayType toArrayType(TypeMirror typeMirror) {
171+
assertNotNull(typeMirror);
172+
return typeMirror.accept(
173+
new SimpleTypeVisitor6<ArrayType, Void>() {
174+
175+
public ArrayType visitArray(ArrayType t, Void p) {
176+
return t;
177+
}
178+
},
179+
null);
180+
}
181+
156182
public boolean isAssignable(TypeMirror lhs, Class<?> rhs) {
157183
assertNotNull(lhs, rhs);
158184
TypeElement typeElement = ctx.getElements().getTypeElement(rhs);
@@ -197,6 +223,15 @@ public boolean isSameType(TypeMirror typeMirror, Class<?> clazz) {
197223
if (typeMirror.getKind() == TypeKind.VOID) {
198224
return clazz == void.class;
199225
}
226+
if (clazz.isArray()) {
227+
TypeElement componentType = ctx.getElements().getTypeElement(clazz.getComponentType());
228+
ArrayType arrayType = ctx.getTypes().getArrayType(componentType.asType());
229+
if (arrayType == null) {
230+
return false;
231+
}
232+
return isSameType(typeMirror, arrayType);
233+
}
234+
200235
TypeElement typeElement = ctx.getElements().getTypeElement(clazz);
201236
if (typeElement == null) {
202237
return false;
@@ -227,6 +262,10 @@ public boolean isSameType(TypeMirror t1, TypeMirror t2) {
227262
|| erasuredType1.equals(erasuredType2);
228263
}
229264

265+
public boolean isArray(TypeMirror typeMirror) {
266+
return typeMirror.getKind() == TypeKind.ARRAY;
267+
}
268+
230269
public String getTypeName(TypeMirror typeMirror) {
231270
assertNotNull(typeMirror);
232271
StringBuilder p = new StringBuilder();

src/main/java/org/seasar/doma/internal/apt/cttype/AbstractCtType.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,11 @@ public boolean isWildcard() {
127127
return type.getKind() == TypeKind.WILDCARD;
128128
}
129129

130+
@Override
131+
public boolean isArray() {
132+
return type.getKind() == TypeKind.ARRAY;
133+
}
134+
130135
@Override
131136
public boolean isTypevar() {
132137
return type.getKind() == TypeKind.TYPEVAR;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package org.seasar.doma.internal.apt.cttype;
2+
3+
import static org.seasar.doma.internal.util.AssertionUtil.assertNotNull;
4+
5+
import javax.lang.model.type.TypeMirror;
6+
import org.seasar.doma.internal.apt.Context;
7+
8+
public class ArrayCtType extends AbstractCtType {
9+
10+
private final CtType elementCtType;
11+
12+
ArrayCtType(Context ctx, TypeMirror type, CtType elementCtType) {
13+
super(ctx, type);
14+
assertNotNull(elementCtType);
15+
this.elementCtType = elementCtType;
16+
}
17+
18+
public CtType getElementCtType() {
19+
return elementCtType;
20+
}
21+
22+
@Override
23+
public <R, P, TH extends Throwable> R accept(CtTypeVisitor<R, P, TH> visitor, P p) throws TH {
24+
return visitor.visitArrayCtType(this, p);
25+
}
26+
}

src/main/java/org/seasar/doma/internal/apt/cttype/CtType.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ public interface CtType {
3333

3434
boolean isTypevar();
3535

36+
boolean isArray();
37+
3638
boolean isSameType(CtType ctType);
3739

3840
<R, P, TH extends Throwable> R accept(CtTypeVisitor<R, P, TH> visitor, P p) throws TH;

src/main/java/org/seasar/doma/internal/apt/cttype/CtTypeVisitor.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ public interface CtTypeVisitor<R, P, TH extends Throwable> {
1616

1717
R visitIterableCtType(IterableCtType ctType, P p) throws TH;
1818

19+
R visitArrayCtType(ArrayCtType ctType, P p) throws TH;
20+
1921
R visitCollectorCtType(CollectorCtType ctType, P p) throws TH;
2022

2123
R visitReferenceCtType(ReferenceCtType ctType, P p) throws TH;

src/main/java/org/seasar/doma/internal/apt/cttype/CtTypes.java

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,21 @@
44
import static org.seasar.doma.internal.util.AssertionUtil.assertEquals;
55
import static org.seasar.doma.internal.util.AssertionUtil.assertNotNull;
66

7-
import java.util.*;
7+
import java.util.Arrays;
8+
import java.util.Iterator;
9+
import java.util.List;
10+
import java.util.Map;
11+
import java.util.Objects;
12+
import java.util.Optional;
13+
import java.util.OptionalDouble;
14+
import java.util.OptionalInt;
15+
import java.util.OptionalLong;
816
import java.util.function.BiFunction;
917
import java.util.function.Function;
1018
import java.util.stream.Collector;
1119
import java.util.stream.Stream;
1220
import javax.lang.model.element.TypeElement;
21+
import javax.lang.model.type.ArrayType;
1322
import javax.lang.model.type.DeclaredType;
1423
import javax.lang.model.type.MirroredTypeException;
1524
import javax.lang.model.type.TypeKind;
@@ -22,7 +31,12 @@
2231
import org.seasar.doma.internal.apt.AptIllegalStateException;
2332
import org.seasar.doma.internal.apt.Context;
2433
import org.seasar.doma.internal.apt.annot.DomainConvertersAnnot;
25-
import org.seasar.doma.jdbc.*;
34+
import org.seasar.doma.jdbc.BatchResult;
35+
import org.seasar.doma.jdbc.Config;
36+
import org.seasar.doma.jdbc.PreparedSql;
37+
import org.seasar.doma.jdbc.Reference;
38+
import org.seasar.doma.jdbc.Result;
39+
import org.seasar.doma.jdbc.SelectOptions;
2640
import org.seasar.doma.jdbc.domain.DomainConverter;
2741
import org.seasar.doma.message.Message;
2842
import org.seasar.doma.wrapper.EnumWrapper;
@@ -266,6 +280,19 @@ public IterableCtType newIterableCtType(TypeMirror type) {
266280
return new IterableCtType(ctx, type, elementCtType);
267281
}
268282

283+
public ArrayCtType newArrayCtType(TypeMirror type) {
284+
assertNotNull(type);
285+
if (type.getKind() != TypeKind.ARRAY) {
286+
return null;
287+
}
288+
TypeMirror componentType = ((ArrayType) type).getComponentType();
289+
if (componentType.getKind() == TypeKind.BYTE) {
290+
return null;
291+
}
292+
CtType elementCtType = newCtType(componentType);
293+
return new ArrayCtType(ctx, type, elementCtType);
294+
}
295+
269296
private MapCtType newMapCtType(TypeMirror type) {
270297
if (!ctx.getTypes().isSameType(type, Map.class)) {
271298
return null;
@@ -410,6 +437,7 @@ private CtType newCtTypeInternal(
410437
List<Function<TypeMirror, CtType>> functions =
411438
Arrays.asList(
412439
this::newIterableCtType,
440+
this::newArrayCtType,
413441
this::newStreamCtType,
414442
this::newEntityCtType,
415443
this::newOptionalCtType,

src/main/java/org/seasar/doma/internal/apt/cttype/SimpleCtTypeVisitor.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ public R visitIterableCtType(IterableCtType ctType, P p) throws TH {
4949
return defaultAction(ctType, p);
5050
}
5151

52+
@Override
53+
public R visitArrayCtType(ArrayCtType ctType, P p) throws TH {
54+
return defaultAction(ctType, p);
55+
}
56+
5257
@Override
5358
public R visitCollectorCtType(CollectorCtType ctType, P p) throws TH {
5459
return defaultAction(ctType, p);

src/main/java/org/seasar/doma/internal/apt/generator/DaoImplMethodGenerator.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.util.Iterator;
66
import java.util.List;
77
import java.util.function.Function;
8+
import javax.lang.model.type.TypeKind;
89
import org.seasar.doma.DomaNullPointerException;
910
import org.seasar.doma.FetchType;
1011
import org.seasar.doma.MapKeyNamingType;
@@ -756,7 +757,11 @@ private void printEnteringStatements(QueryMeta m) {
756757
iprint("entering(\"%1$s\", \"%2$s\"", className, m.getName());
757758
for (Iterator<QueryParameterMeta> it = m.getParameterMetas().iterator(); it.hasNext(); ) {
758759
QueryParameterMeta parameterMeta = it.next();
759-
print(", %1$s", parameterMeta.getName());
760+
if (parameterMeta.getType().getKind() != TypeKind.ARRAY) {
761+
print(", %1$s", parameterMeta.getName());
762+
} else {
763+
print(", (Object) %1$s", parameterMeta.getName());
764+
}
760765
}
761766
print(");%n");
762767
iprint("try {%n");

src/main/java/org/seasar/doma/internal/apt/meta/query/QueryParameterMeta.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import javax.lang.model.element.VariableElement;
99
import javax.lang.model.type.TypeMirror;
1010
import org.seasar.doma.internal.apt.cttype.AnyCtType;
11+
import org.seasar.doma.internal.apt.cttype.ArrayCtType;
1112
import org.seasar.doma.internal.apt.cttype.BasicCtType;
1213
import org.seasar.doma.internal.apt.cttype.CtType;
1314
import org.seasar.doma.internal.apt.cttype.DomainCtType;
@@ -164,6 +165,11 @@ public Boolean visitIterableCtType(IterableCtType ctType, Void p) throws Runtime
164165
return true;
165166
}
166167

168+
@Override
169+
public Boolean visitArrayCtType(ArrayCtType ctType, Void p) throws RuntimeException {
170+
return true;
171+
}
172+
167173
@Override
168174
public Boolean visitReferenceCtType(ReferenceCtType ctType, Void p) throws RuntimeException {
169175
return true;

src/main/java/org/seasar/doma/internal/apt/validator/SqlValidator.java

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,21 @@
22

33
import static org.seasar.doma.internal.util.AssertionUtil.assertNotNull;
44

5+
import java.util.Collections;
56
import java.util.Iterator;
67
import java.util.LinkedHashMap;
78
import java.util.List;
89
import java.util.Set;
910
import javax.lang.model.element.ExecutableElement;
1011
import javax.lang.model.element.VariableElement;
12+
import javax.lang.model.type.ArrayType;
1113
import javax.lang.model.type.DeclaredType;
1214
import javax.lang.model.type.TypeMirror;
1315
import javax.tools.Diagnostic.Kind;
1416
import org.seasar.doma.internal.apt.AptException;
1517
import org.seasar.doma.internal.apt.AptIllegalStateException;
1618
import org.seasar.doma.internal.apt.Context;
19+
import org.seasar.doma.internal.apt.cttype.ArrayCtType;
1720
import org.seasar.doma.internal.apt.cttype.BasicCtType;
1821
import org.seasar.doma.internal.apt.cttype.DomainCtType;
1922
import org.seasar.doma.internal.apt.cttype.IterableCtType;
@@ -127,7 +130,7 @@ protected Void visitValueNode(ValueNode node, Void p) {
127130
});
128131
}
129132
} else {
130-
if (!isScalarIterable(typeDeclaration)) {
133+
if (!isScalarIterable(typeDeclaration) && !isScalarArray(typeDeclaration)) {
131134
String sql = getSql(location);
132135
throw new AptException(
133136
Message.DOMA4161,
@@ -178,6 +181,32 @@ public Boolean visitDomainCtType(DomainCtType ctType, Void p)
178181
return false;
179182
}
180183

184+
protected boolean isScalarArray(TypeDeclaration typeDeclaration) {
185+
TypeMirror typeMirror = typeDeclaration.getType();
186+
ArrayCtType arrayCtType = ctx.getCtTypes().newArrayCtType(typeMirror);
187+
if (arrayCtType != null) {
188+
return arrayCtType
189+
.getElementCtType()
190+
.accept(
191+
new SimpleCtTypeVisitor<Boolean, Void, RuntimeException>(false) {
192+
193+
@Override
194+
public Boolean visitBasicCtType(BasicCtType ctType, Void p)
195+
throws RuntimeException {
196+
return true;
197+
}
198+
199+
@Override
200+
public Boolean visitDomainCtType(DomainCtType ctType, Void p)
201+
throws RuntimeException {
202+
return true;
203+
}
204+
},
205+
null);
206+
}
207+
return false;
208+
}
209+
181210
@Override
182211
public Void visitEmbeddedVariableNode(EmbeddedVariableNode node, Void p) {
183212
SqlLocation location = node.getLocation();
@@ -240,7 +269,14 @@ public Void visitForNode(ForNode node, Void p) {
240269
String expression = node.getExpression();
241270
TypeDeclaration typeDeclaration = validateExpressionVariable(location, expression);
242271
TypeMirror typeMirror = typeDeclaration.getType();
243-
if (!ctx.getTypes().isAssignable(typeMirror, Iterable.class)) {
272+
List<? extends TypeMirror> typeArgs;
273+
if (ctx.getTypes().isAssignable(typeMirror, Iterable.class)) {
274+
DeclaredType declaredType = ctx.getTypes().toDeclaredType(typeMirror);
275+
typeArgs = declaredType.getTypeArguments();
276+
} else if (ctx.getTypes().isArray(typeMirror)) {
277+
ArrayType arrayType = ctx.getTypes().toArrayType(typeMirror);
278+
typeArgs = Collections.singletonList(arrayType.getComponentType());
279+
} else {
244280
String sql = getSql(location);
245281
throw new AptException(
246282
Message.DOMA4149,
@@ -254,8 +290,6 @@ public Void visitForNode(ForNode node, Void p) {
254290
typeDeclaration.getBinaryName()
255291
});
256292
}
257-
DeclaredType declaredType = ctx.getTypes().toDeclaredType(typeMirror);
258-
List<? extends TypeMirror> typeArgs = declaredType.getTypeArguments();
259293
if (typeArgs.isEmpty()) {
260294
String sql = getSql(location);
261295
throw new AptException(

0 commit comments

Comments
 (0)