Skip to content

Commit 8e8c883

Browse files
authored
86 custom array type (#88)
* Locate array component type by search supertype for top defined array type
1 parent b93d8cf commit 8e8c883

7 files changed

Lines changed: 146 additions & 79 deletions

File tree

client-test/typescript/src/types.java17.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
type DependencyClassA, type DependencyClassB, type DependencyClassC, type EnumGalaxy, type EnumSize,
33
EnumTShirt, type JavaRecord, type AnotherJavaClass, type RecursiveClass, type MapClass,
44
type OptionalMethod,
5+
type ArrayClass,
56
} from "./index.java17";
67

78
export const list1: EnumGalaxy[] = ["Andromeda", "MilkyWay", "Triangulum"];
@@ -101,3 +102,7 @@ export const optionalMethods: OptionalMethod = {
101102
optionalMethods.mapNestedValueOptional = { 1: "foo" };
102103
optionalMethods.setNestedValueOptional = ["foo"];
103104
optionalMethods.nestedValueOptional = "bar";
105+
106+
export const arrayClass: ArrayClass = {
107+
arr: ["abc"],
108+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package online.sharedtype.it.java8;
2+
3+
import online.sharedtype.SharedType;
4+
5+
@SharedType
6+
final class ArrayClass {
7+
private CustomList arr;
8+
}

processor/src/main/java/online/sharedtype/processor/context/Context.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,16 @@ public boolean isArraylike(TypeMirror typeMirror) {
7373
return false;
7474
}
7575

76+
/** Check if the type is directly the same type as one of the defined arraylike types */
77+
public boolean isTopArrayType(TypeMirror typeMirror) {
78+
for (TypeMirror toArrayType : arraylikeTypes) {
79+
if (types.isSameType(types.erasure(typeMirror), toArrayType)) {
80+
return true;
81+
}
82+
}
83+
return false;
84+
}
85+
7686
public boolean isMaplike(TypeMirror typeMirror) {
7787
for (TypeMirror maplikeType : maplikeTypes) {
7888
if (types.isSubtype(types.erasure(typeMirror), maplikeType)) {

processor/src/main/java/online/sharedtype/processor/parser/type/TypeInfoParserImpl.java

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import online.sharedtype.processor.context.TypeStore;
55
import online.sharedtype.processor.domain.ArrayTypeInfo;
66
import online.sharedtype.processor.domain.ConcreteTypeInfo;
7-
import online.sharedtype.processor.domain.Constants;
87
import online.sharedtype.processor.domain.DependingKind;
98
import online.sharedtype.processor.domain.TypeInfo;
109
import online.sharedtype.processor.domain.TypeVariableInfo;
@@ -17,6 +16,7 @@
1716
import javax.lang.model.type.TypeKind;
1817
import javax.lang.model.type.TypeMirror;
1918
import javax.lang.model.type.TypeVariable;
19+
import javax.lang.model.util.Types;
2020
import java.util.Collections;
2121
import java.util.List;
2222
import java.util.stream.Collectors;
@@ -25,16 +25,17 @@
2525
import static online.sharedtype.processor.support.Preconditions.checkArgument;
2626

2727
/**
28-
*
2928
* @author Cause Chung
3029
*/
3130
final class TypeInfoParserImpl implements TypeInfoParser {
3231
private final Context ctx;
3332
private final TypeStore typeStore;
33+
private final Types types;
3434

3535
TypeInfoParserImpl(Context ctx) {
3636
this.ctx = ctx;
3737
this.typeStore = ctx.getTypeStore();
38+
this.types = ctx.getProcessingEnv().getTypeUtils();
3839
}
3940

4041
@Override
@@ -66,9 +67,8 @@ private TypeInfo parseDeclared(DeclaredType declaredType, TypeContext typeContex
6667
TypeMirror currentType = declaredType;
6768
TypeInfo typeInfo = null;
6869
while (ctx.isArraylike(currentType)) {
69-
checkArgument(typeArgs.size() == 1, "Array type must have exactly one type argument, but got: %s, type: %s", typeArgs.size(), currentType);
7070
arrayStack++;
71-
currentType = typeArgs.get(0);
71+
currentType = locateArrayComponentType(currentType);
7272
if (currentType instanceof DeclaredType) {
7373
DeclaredType argDeclaredType = (DeclaredType) currentType;
7474
TypeElement element = (TypeElement) argDeclaredType.asElement();
@@ -108,7 +108,7 @@ private TypeInfo parseDeclared(DeclaredType declaredType, TypeContext typeContex
108108
}
109109

110110
if (typeContext.getDependingKind() == DependingKind.COMPONENTS && typeInfo instanceof ConcreteTypeInfo) {
111-
ConcreteTypeInfo concreteTypeInfo = (ConcreteTypeInfo)typeInfo;
111+
ConcreteTypeInfo concreteTypeInfo = (ConcreteTypeInfo) typeInfo;
112112
concreteTypeInfo.referencingTypes().add(typeContext.getTypeDef());
113113
}
114114

@@ -125,14 +125,33 @@ private TypeVariableInfo parseTypeVariable(TypeVariable typeVariable, TypeContex
125125
String qualifiedName = TypeVariableInfo.concatQualifiedName(contextTypeQualifiedName, simpleName);
126126
TypeInfo typeInfo = typeStore.getTypeInfo(qualifiedName, Collections.emptyList());
127127
if (typeInfo != null) {
128-
return (TypeVariableInfo)typeInfo;
128+
return (TypeVariableInfo) typeInfo;
129129
}
130130
typeInfo = TypeVariableInfo.builder()
131131
.contextTypeQualifiedName(contextTypeQualifiedName)
132132
.name(simpleName)
133133
.qualifiedName(qualifiedName)
134134
.build();
135135
typeStore.saveTypeInfo(qualifiedName, Collections.emptyList(), typeInfo);
136-
return (TypeVariableInfo)typeInfo;
136+
return (TypeVariableInfo) typeInfo;
137+
}
138+
139+
private TypeMirror locateArrayComponentType(TypeMirror typeMirror) {
140+
TypeMirror cur = typeMirror;
141+
int depth = 0;
142+
while (!ctx.isTopArrayType(cur)) {
143+
for (TypeMirror supertype : types.directSupertypes(cur)) {
144+
if (ctx.isArraylike(supertype)) {
145+
cur = supertype;
146+
break;
147+
}
148+
}
149+
if (depth++ > 100) {
150+
throw new SharedTypeInternalError("Array type hierarchy exceed max depth: " + typeMirror);
151+
}
152+
}
153+
List<? extends TypeMirror> typeArgs = ((DeclaredType)cur).getTypeArguments();
154+
checkArgument(typeArgs.size() == 1, "Array type must have exactly one type argument, but got: %s, type: %s", typeArgs.size(), typeMirror);
155+
return typeArgs.get(0);
137156
}
138157
}

processor/src/test/java/online/sharedtype/processor/context/AbstractElementMock.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ public final M withModifiers(Modifier... modifiers) {
6969
return returnThis();
7070
}
7171

72+
public M withSuperTypes(TypeMirror... superTypes) {
73+
when(types.directSupertypes(type)).thenAnswer(invoc -> Arrays.asList(superTypes));
74+
return returnThis();
75+
}
76+
7277
public final M ofTree(VariableTreeMock tree) {
7378
tree.fromElement(element);
7479
return returnThis();

processor/src/test/java/online/sharedtype/processor/context/DeclaredTypeVariableElementMock.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
import javax.lang.model.element.VariableElement;
44
import javax.lang.model.type.DeclaredType;
55
import javax.lang.model.type.TypeKind;
6+
import javax.lang.model.type.TypeMirror;
67
import javax.lang.model.util.Types;
78

9+
import java.util.Arrays;
10+
811
import static org.mockito.Mockito.mock;
912
import static org.mockito.Mockito.when;
1013

0 commit comments

Comments
 (0)