Skip to content

Commit 581dd37

Browse files
committed
Dev: add custom type mapping
1 parent c0a455a commit 581dd37

18 files changed

+171
-99
lines changed

compiler/src/main/java/com/readdle/codegen/JavaSwiftProcessor.java

Lines changed: 89 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.readdle.codegen.anotation.SwiftModule;
66
import com.readdle.codegen.anotation.SwiftReference;
77
import com.readdle.codegen.anotation.SwiftValue;
8+
import com.readdle.codegen.anotation.TypeMapping;
89

910
import java.io.File;
1011
import java.io.IOException;
@@ -13,6 +14,7 @@
1314
import java.util.List;
1415
import java.util.Map;
1516
import java.util.Set;
17+
import java.util.regex.Pattern;
1618

1719
import javax.annotation.processing.AbstractProcessor;
1820
import javax.annotation.processing.Filer;
@@ -25,6 +27,7 @@
2527
import javax.lang.model.element.ElementKind;
2628
import javax.lang.model.element.Name;
2729
import javax.lang.model.element.TypeElement;
30+
import javax.lang.model.type.MirroredTypeException;
2831
import javax.lang.model.util.Elements;
2932
import javax.lang.model.util.Types;
3033
import javax.tools.Diagnostic;
@@ -45,7 +48,8 @@ interface WritableElement {
4548
private Messager messager;
4649

4750
private String moduleName;
48-
private String[] importPackages;
51+
String[] importPackages;
52+
HashMap<String, String> customTypeMappings = new HashMap<>();
4953

5054
@Override
5155
public synchronized void init(ProcessingEnvironment processingEnv) {
@@ -103,6 +107,22 @@ private boolean processImpl(Set<? extends TypeElement> annotations, RoundEnviron
103107
SwiftModule swiftModule = annotatedElement.getAnnotation(SwiftModule.class);
104108
moduleName = swiftModule.moduleName();
105109
importPackages = swiftModule.importPackages();
110+
TypeMapping[] customTypeMappings = swiftModule.customTypeMappings();
111+
for (TypeMapping customTypeMapping : customTypeMappings) {
112+
try {
113+
Class clazz = customTypeMapping.javaClass();
114+
String canonicalName = clazz.getCanonicalName();
115+
String swiftType = customTypeMapping.swiftType();
116+
messager.printMessage(Diagnostic.Kind.NOTE, "Added custom mapping from " + canonicalName + " to " + swiftType);
117+
this.customTypeMappings.put(canonicalName, customTypeMapping.swiftType());
118+
}
119+
catch (MirroredTypeException mirroredTypeException) {
120+
String canonicalName = mirroredTypeException.getTypeMirror().toString();
121+
String swiftType = customTypeMapping.swiftType();
122+
messager.printMessage(Diagnostic.Kind.NOTE, "Added custom mapping from " + canonicalName + " to " + swiftType);
123+
this.customTypeMappings.put(canonicalName, customTypeMapping.swiftType());
124+
}
125+
}
106126
}
107127

108128
if (moduleName == null || importPackages == null) {
@@ -120,7 +140,7 @@ private boolean processImpl(Set<? extends TypeElement> annotations, RoundEnviron
120140
TypeElement typeElement = (TypeElement) annotatedElement;
121141

122142
try {
123-
SwiftValueDescriptor swiftValueDescriptor = new SwiftValueDescriptor(typeElement, filer, importPackages);
143+
SwiftValueDescriptor swiftValueDescriptor = new SwiftValueDescriptor(typeElement, filer, this);
124144
swiftValues.put(swiftValueDescriptor.getSwiftType(), swiftValueDescriptor);
125145
}
126146
catch (IllegalArgumentException e) {
@@ -141,7 +161,7 @@ private boolean processImpl(Set<? extends TypeElement> annotations, RoundEnviron
141161
TypeElement typeElement = (TypeElement) annotatedElement;
142162

143163
try {
144-
SwiftReferenceDescriptor swiftReferenceDescriptor = new SwiftReferenceDescriptor(typeElement, filer, importPackages);
164+
SwiftReferenceDescriptor swiftReferenceDescriptor = new SwiftReferenceDescriptor(typeElement, filer, this);
145165
swiftReferences.put(swiftReferenceDescriptor.getSwiftType(), swiftReferenceDescriptor);
146166
}
147167
catch (IllegalArgumentException e) {
@@ -162,7 +182,7 @@ private boolean processImpl(Set<? extends TypeElement> annotations, RoundEnviron
162182
TypeElement typeElement = (TypeElement) annotatedElement;
163183

164184
try {
165-
SwiftDelegateDescriptor delegateDescriptor = new SwiftDelegateDescriptor(typeElement, filer, importPackages);
185+
SwiftDelegateDescriptor delegateDescriptor = new SwiftDelegateDescriptor(typeElement, filer, this);
166186
swiftDelegates.put(delegateDescriptor.simpleTypeName, delegateDescriptor);
167187
}
168188
catch (IllegalArgumentException e) {
@@ -188,7 +208,7 @@ private boolean processImpl(Set<? extends TypeElement> annotations, RoundEnviron
188208
TypeElement typeElement = (TypeElement) annotatedElement;
189209

190210
try {
191-
SwiftBlockDescriptor blockDescriptor = new SwiftBlockDescriptor(typeElement, filer, importPackages);
211+
SwiftBlockDescriptor blockDescriptor = new SwiftBlockDescriptor(typeElement, filer, this);
192212
swiftBlocks.put(blockDescriptor.simpleTypeName, blockDescriptor);
193213
}
194214
catch (IllegalArgumentException e) {
@@ -311,8 +331,71 @@ static boolean isNullable(Element element) {
311331
static String replaceLast(String text, char replace, char replacement) {
312332
int index = text.lastIndexOf(replace);
313333
if (index >= 0) {
314-
return text.substring(0, index) + replacement + text.substring(index + 1, text.length());
334+
return text.substring(0, index) + replacement + text.substring(index + 1);
315335
}
316336
return text;
317337
}
338+
339+
public SwiftEnvironment.Type parseJavaType(String javaType) {
340+
if (customTypeMappings.containsKey(javaType)) {
341+
return new SwiftEnvironment.Type(customTypeMappings.get(javaType), javaType);
342+
}
343+
switch (javaType) {
344+
case "void":
345+
return null;
346+
case "java.lang.Integer":
347+
return new SwiftEnvironment.Type("Int", javaType);
348+
case "java.lang.Byte":
349+
return new SwiftEnvironment.Type("Int8", javaType);
350+
case "java.lang.Short":
351+
return new SwiftEnvironment.Type("Int16", javaType);
352+
case "java.lang.Long":
353+
return new SwiftEnvironment.Type("Int64", javaType);
354+
case "java.math.BigInteger":
355+
return new SwiftEnvironment.Type("UInt64", javaType);
356+
case "java.lang.Boolean":
357+
return new SwiftEnvironment.Type("Bool", javaType);
358+
case "java.lang.String":
359+
return new SwiftEnvironment.Type("String", javaType);
360+
case "android.net.Uri":
361+
return new SwiftEnvironment.Type("URL", javaType);
362+
case "java.util.Date":
363+
return new SwiftEnvironment.Type("Date", javaType);
364+
case "java.nio.ByteBuffer":
365+
return new SwiftEnvironment.Type("Data", javaType);
366+
case "java.lang.Exception":
367+
return new SwiftEnvironment.Type("Error", javaType, "NSError");
368+
default:
369+
try {
370+
if (javaType.startsWith("java.util.ArrayList<")) {
371+
SwiftEnvironment.Type subType = parseJavaType(javaType.substring("java.util.ArrayList<".length(), javaType.length() - 1));
372+
return new SwiftEnvironment.Type("[" + subType.swiftType + "]", javaType);
373+
}
374+
else if (javaType.startsWith("java.util.HashSet<")) {
375+
SwiftEnvironment.Type subType = parseJavaType(javaType.substring("java.util.HashSet<".length(), javaType.length() - 1));
376+
return new SwiftEnvironment.Type("Set<" + subType.swiftType + ">", javaType);
377+
}
378+
else if (javaType.startsWith("java.util.HashMap<")) {
379+
String substring = javaType.substring("java.util.HashMap<".length(), javaType.length() - 1);
380+
int commaIndex = substring.indexOf(",");
381+
SwiftEnvironment.Type keyType = parseJavaType(substring.substring(0, commaIndex));
382+
SwiftEnvironment.Type valueType = parseJavaType(substring.substring(commaIndex + 1));
383+
return new SwiftEnvironment.Type("[" + keyType.swiftType + ":" + valueType.swiftType + "]", javaType);
384+
}
385+
else {
386+
// Try found enclosing typename
387+
String[] parts = javaType.split(Pattern.quote("$"));
388+
if (parts.length == 1) {
389+
// If not found enclosing, find typename
390+
parts = javaType.split(Pattern.quote("."));
391+
}
392+
String swiftType = parts[parts.length - 1];
393+
return new SwiftEnvironment.Type(swiftType, javaType);
394+
}
395+
}
396+
catch (Exception e) {
397+
throw new IllegalArgumentException(javaType);
398+
}
399+
}
400+
}
318401
}

compiler/src/main/java/com/readdle/codegen/SwiftBlockDescriptor.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import java.io.File;
66
import java.io.IOException;
7+
import java.util.HashMap;
78
import java.util.LinkedList;
89
import java.util.List;
910

@@ -40,9 +41,9 @@ class SwiftBlockDescriptor {
4041
private String sig;
4142
private List<SwiftParamDescriptor> params = new LinkedList<>();
4243

43-
SwiftBlockDescriptor(TypeElement classElement, Filer filer, String[] importPackages) throws IllegalArgumentException {
44+
SwiftBlockDescriptor(TypeElement classElement, Filer filer, JavaSwiftProcessor processor) throws IllegalArgumentException {
4445
this.annotatedClassElement = classElement;
45-
this.importPackages = importPackages;
46+
this.importPackages = processor.importPackages;
4647

4748
// Get the full QualifiedTypeName
4849
try {
@@ -79,13 +80,13 @@ class SwiftBlockDescriptor {
7980
// Except init. We generate it's manually
8081
this.funcName = executableElement.getSimpleName().toString();
8182
this.isThrown = executableElement.getThrownTypes() != null && executableElement.getThrownTypes().size() > 0;
82-
this.returnSwiftType = SwiftEnvironment.parseJavaType(executableElement.getReturnType().toString());
83+
this.returnSwiftType = processor.parseJavaType(executableElement.getReturnType().toString());
8384
this.isReturnTypeOptional = JavaSwiftProcessor.isNullable(executableElement);
8485

8586
this.sig = "(";
8687

8788
for (VariableElement variableElement : executableElement.getParameters()) {
88-
params.add(new SwiftParamDescriptor(variableElement));
89+
params.add(new SwiftParamDescriptor(variableElement, processor));
8990
sig += Utils.javaClassToSig(variableElement.asType().toString());
9091
}
9192

compiler/src/main/java/com/readdle/codegen/SwiftCallbackFuncDescriptor.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import java.io.IOException;
66
import java.util.Arrays;
7+
import java.util.HashMap;
78
import java.util.LinkedList;
89
import java.util.List;
910

@@ -27,20 +28,20 @@ public class SwiftCallbackFuncDescriptor {
2728
private List<SwiftParamDescriptor> params = new LinkedList<>();
2829
private List<String> paramNames = new LinkedList<>();
2930

30-
SwiftCallbackFuncDescriptor(ExecutableElement executableElement) {
31+
SwiftCallbackFuncDescriptor(ExecutableElement executableElement, JavaSwiftProcessor processor) {
3132
String elementName = executableElement.getSimpleName().toString();
3233
this.javaMethodName = elementName;
3334
this.swiftMethodName = elementName;
3435

3536
this.isStatic = executableElement.getModifiers().contains(Modifier.STATIC);
3637
this.isThrown = executableElement.getThrownTypes() != null && executableElement.getThrownTypes().size() > 0;
37-
this.returnSwiftType = SwiftEnvironment.parseJavaType(executableElement.getReturnType().toString());
38+
this.returnSwiftType = processor.parseJavaType(executableElement.getReturnType().toString());
3839
this.isReturnTypeOptional = JavaSwiftProcessor.isNullable(executableElement);
3940

4041
StringBuilder signatureBuilder = new StringBuilder("(");
4142

4243
for (VariableElement variableElement : executableElement.getParameters()) {
43-
params.add(new SwiftParamDescriptor(variableElement));
44+
params.add(new SwiftParamDescriptor(variableElement, processor));
4445
String javaClass = variableElement.asType().toString();
4546
signatureBuilder.append(Utils.javaClassToSig(javaClass));
4647
}

compiler/src/main/java/com/readdle/codegen/SwiftDelegateDescriptor.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ class SwiftDelegateDescriptor {
3939

4040
private boolean isInterface;
4141

42-
SwiftDelegateDescriptor(TypeElement classElement, Filer filer, String[] importPackages) throws IllegalArgumentException {
42+
SwiftDelegateDescriptor(TypeElement classElement, Filer filer, JavaSwiftProcessor processor) throws IllegalArgumentException {
4343
this.annotatedClassElement = classElement;
4444
this.isInterface = classElement.getKind() == ElementKind.INTERFACE;
45-
this.importPackages = importPackages;
45+
this.importPackages = processor.importPackages;
4646

4747
// Get the full QualifiedTypeName
4848
try {
@@ -141,7 +141,7 @@ class SwiftDelegateDescriptor {
141141
ExecutableElement executableElement = (ExecutableElement) element;
142142
// Except init. We generate it's manually
143143
if (executableElement.getModifiers().contains(Modifier.NATIVE) && !executableElement.getSimpleName().contentEquals("init")) {
144-
functions.add(new SwiftFuncDescriptor(executableElement));
144+
functions.add(new SwiftFuncDescriptor(executableElement, processor));
145145
}
146146
}
147147

@@ -153,7 +153,7 @@ class SwiftDelegateDescriptor {
153153
throw new SwiftMappingException(message, executableElement);
154154
}
155155

156-
callbackFunctions.add(new SwiftCallbackFuncDescriptor(executableElement));
156+
callbackFunctions.add(new SwiftCallbackFuncDescriptor(executableElement, processor));
157157
}
158158
}
159159
}

compiler/src/main/java/com/readdle/codegen/SwiftEnvironment.java

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -30,64 +30,4 @@ public String toString() {
3030
}
3131
}
3232

33-
public static Type parseJavaType(String javaType) {
34-
switch (javaType) {
35-
case "void":
36-
return null;
37-
case "java.lang.Integer":
38-
return new Type("Int", javaType);
39-
case "java.lang.Byte":
40-
return new Type("Int8", javaType);
41-
case "java.lang.Short":
42-
return new Type("Int16", javaType);
43-
case "java.lang.Long":
44-
return new Type("Int64", javaType);
45-
case "java.math.BigInteger":
46-
return new Type("UInt64", javaType);
47-
case "java.lang.Boolean":
48-
return new Type("Bool", javaType);
49-
case "java.lang.String":
50-
return new Type("String", javaType);
51-
case "android.net.Uri":
52-
return new Type("URL", javaType);
53-
case "java.util.Date":
54-
return new Type("Date", javaType);
55-
case "java.nio.ByteBuffer":
56-
return new Type("Data", javaType);
57-
case "java.lang.Exception":
58-
return new Type("Error", javaType, "NSError");
59-
default:
60-
try {
61-
if (javaType.startsWith("java.util.ArrayList<")) {
62-
Type subType = parseJavaType(javaType.substring("java.util.ArrayList<".length(), javaType.length() - 1));
63-
return new Type("[" + subType.swiftType + "]", javaType);
64-
}
65-
else if (javaType.startsWith("java.util.HashSet<")) {
66-
Type subType = parseJavaType(javaType.substring("java.util.HashSet<".length(), javaType.length() - 1));
67-
return new Type("Set<" + subType.swiftType + ">", javaType);
68-
}
69-
else if (javaType.startsWith("java.util.HashMap<")) {
70-
String substring = javaType.substring("java.util.HashMap<".length(), javaType.length() - 1);
71-
int commaIndex = substring.indexOf(",");
72-
Type keyType = parseJavaType(substring.substring(0, commaIndex));
73-
Type valueType = parseJavaType(substring.substring(commaIndex + 1, substring.length()));
74-
return new Type("[" + keyType.swiftType + ":" + valueType.swiftType + "]", javaType);
75-
}
76-
else {
77-
// Try found enclosing typename
78-
String[] parts = javaType.split(Pattern.quote("$"));
79-
if (parts.length == 1) {
80-
// If not found enclosing, find typename
81-
parts = javaType.split(Pattern.quote("."));
82-
}
83-
String swiftType = parts[parts.length - 1];
84-
return new Type(swiftType, javaType);
85-
}
86-
}
87-
catch (Exception e) {
88-
throw new IllegalArgumentException(javaType);
89-
}
90-
}
91-
}
92-
9333
}

compiler/src/main/java/com/readdle/codegen/SwiftFuncDescriptor.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.io.IOException;
66
import java.util.ArrayList;
77
import java.util.Collections;
8+
import java.util.HashMap;
89
import java.util.List;
910

1011
import javax.lang.model.element.ExecutableElement;
@@ -25,22 +26,22 @@ class SwiftFuncDescriptor implements JavaSwiftProcessor.WritableElement {
2526
private List<SwiftParamDescriptor> params;
2627
private List<String> paramNames;
2728

28-
SwiftFuncDescriptor(ExecutableElement executableElement) {
29+
SwiftFuncDescriptor(ExecutableElement executableElement, JavaSwiftProcessor processor) {
2930
String elementName = executableElement.getSimpleName().toString();
3031
this.javaMethodName = elementName;
3132
this.swiftMethodName = elementName;
3233

3334
this.isStatic = executableElement.getModifiers().contains(Modifier.STATIC);
3435
this.isThrown = executableElement.getThrownTypes() != null && executableElement.getThrownTypes().size() > 0;
35-
this.returnSwiftType = SwiftEnvironment.parseJavaType(executableElement.getReturnType().toString());
36+
this.returnSwiftType = processor.parseJavaType(executableElement.getReturnType().toString());
3637
this.isReturnTypeOptional = JavaSwiftProcessor.isNullable(executableElement);
3738

3839
int paramsSize = executableElement.getParameters().size();
3940
this.params = new ArrayList<>(paramsSize);
4041
this.paramNames = new ArrayList<>(paramsSize);
4142

4243
for (VariableElement variableElement : executableElement.getParameters()) {
43-
params.add(new SwiftParamDescriptor(variableElement));
44+
params.add(new SwiftParamDescriptor(variableElement, processor));
4445
}
4546

4647
SwiftFunc swiftFunc = executableElement.getAnnotation(SwiftFunc.class);

compiler/src/main/java/com/readdle/codegen/SwiftGetterDescriptor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ class SwiftGetterDescriptor implements JavaSwiftProcessor.WritableElement {
1818
private SwiftEnvironment.Type returnSwiftType;
1919
private boolean isReturnTypeOptional;
2020

21-
SwiftGetterDescriptor(ExecutableElement executableElement, SwiftGetter getterAnnotation) {
21+
SwiftGetterDescriptor(ExecutableElement executableElement, SwiftGetter getterAnnotation, JavaSwiftProcessor processor) {
2222
this.javaName = executableElement.getSimpleName().toString();
2323
this.isStatic = executableElement.getModifiers().contains(Modifier.STATIC);
24-
this.returnSwiftType = SwiftEnvironment.parseJavaType(executableElement.getReturnType().toString());
24+
this.returnSwiftType = processor.parseJavaType(executableElement.getReturnType().toString());
2525
this.isReturnTypeOptional = JavaSwiftProcessor.isNullable(executableElement);
2626

2727
if (executableElement.getThrownTypes().size() != 0) {

0 commit comments

Comments
 (0)