Skip to content

Commit 995919e

Browse files
committed
improve generic implements
1 parent e7a5580 commit 995919e

File tree

7 files changed

+62
-43
lines changed

7 files changed

+62
-43
lines changed

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ android-support-17:
5454
libs/android-support/27.0.1/android-support-core-utils.jar libs/android-support/27.0.1/android-support-animated-vector-drawable.jar \
5555
libs/android-support/27.0.1/android-support-vector-drawable.jar libs/android-support/27.0.1/android-support-compat.jar \
5656
libs/android-support/27.0.1/android-support-annotations.jar libs/android-support/27.0.1/android-support-multidex.jar \
57-
-input-generics libs/generics.txt -super /Users/trifonov/Library/Android/sdk/platforms/android-17/android.jar
57+
-all-generic-implements -input-generics libs/generics.txt -super /Users/trifonov/Library/Android/sdk/platforms/android-17/android.jar
5858
mv out/android.d.ts out/android-support-17.d.ts
5959

6060
android-support-23:
@@ -66,7 +66,7 @@ android-support-23:
6666
libs/android-support/27.0.1/android-support-core-utils.jar libs/android-support/27.0.1/android-support-animated-vector-drawable.jar \
6767
libs/android-support/27.0.1/android-support-vector-drawable.jar libs/android-support/27.0.1/android-support-compat.jar \
6868
libs/android-support/27.0.1/android-support-annotations.jar libs/android-support/27.0.1/android-support-multidex.jar \
69-
-input-generics libs/generics.txt -super /Users/trifonov/Library/Android/sdk/platforms/android-23/android.jar
69+
-all-generic-implements -input-generics libs/generics.txt -super /Users/trifonov/Library/Android/sdk/platforms/android-23/android.jar
7070
mv out/android.d.ts out/android-support-23.d.ts
7171

7272
android-support-26:
@@ -78,7 +78,7 @@ android-support-26:
7878
libs/android-support/27.0.1/android-support-core-utils.jar libs/android-support/27.0.1/android-support-animated-vector-drawable.jar \
7979
libs/android-support/27.0.1/android-support-vector-drawable.jar libs/android-support/27.0.1/android-support-compat.jar \
8080
libs/android-support/27.0.1/android-support-annotations.jar libs/android-support/27.0.1/android-support-multidex.jar \
81-
-input-generics libs/generics.txt -super /Users/trifonov/Library/Android/sdk/platforms/android-26/android.jar
81+
-all-generic-implements -input-generics libs/generics.txt -super /Users/trifonov/Library/Android/sdk/platforms/android-26/android.jar
8282
mv out/android.d.ts out/android-support-26.d.ts
8383

8484
android-support-all: android-support-17 android-support-23 android-support-26

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ There are two type of dependencies that can be passed:
5959
2. Input generics - When trying to get the type of a parameter which is a generic class we cannot really get the generic types of that class, so we cannot generate working typings. To fix this we are adding information about the generics of each package at the end of the file with comments starting with `//Generics information:`.
6060
So to fix this we need to provide a file with all the generic information for the packages the current jar relies on. You need to create a file and copy all the generic informations of the related packages and provide it in the **input-generics** argument. This will make all the generic classes referenced without passing types to pass **any** so that the ouput will be valid.
6161

62+
## Adding all implements for generic types
63+
There is an option **all-generic-implements** which is disabled by default which controls whether to add implements for all interfaces (if they are more than one) to generic type declarations. The problem is that in most of the cases one of those interfaces is actually an extend, so it should be manual reviewed and fixed after generation.
64+
6265
## Android support specifics
6366
One of the ways to get the android support jar files is to follow the steps bellow:
6467

dts-generator/src/main/java/com/telerik/InputParameters.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ public class InputParameters {
1313
private List<File> inputJars;
1414
private List<File> superJars;
1515
private File inputGenerics;
16-
private boolean generateGenericImplements;
16+
private boolean allGenericImplements;
1717

1818
public InputParameters() {
1919
this.outputDir = new File("out");
2020
this.inputJars = new ArrayList<>();
2121
this.superJars = new ArrayList<>();
22-
this.generateGenericImplements = false;
22+
this.allGenericImplements = false;
2323
}
2424

2525
public File getOutputDir() {
@@ -46,11 +46,11 @@ public void setInputGenerics(File inputGenerics) {
4646
this.inputGenerics = inputGenerics;
4747
}
4848

49-
public boolean isGenerateGenericImplementsEnabled() {
50-
return generateGenericImplements;
49+
public boolean isAllGenericImplementsEnabled() {
50+
return allGenericImplements;
5151
}
5252

53-
public void setGenerateGenericImplements(boolean generateGenericImplements) {
54-
this.generateGenericImplements = generateGenericImplements;
53+
public void setAllGenericImplements(boolean allGenericImplements) {
54+
this.allGenericImplements = allGenericImplements;
5555
}
5656
}

dts-generator/src/main/java/com/telerik/Main.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class Main {
1717
private static final String INPUT_GENERICS = "-input-generics";
1818

1919
// whether to generate implements for all interfaces implemented by the generic types
20-
private static final String GENERATE_GENERIC_IMPLEMENTS = "-generate-generic-implements";
20+
private static final String ALL_GENERIC_IMPLEMENTS = "-all-generic-implements";
2121

2222
private static final String HELP = "-help";
2323

@@ -44,8 +44,8 @@ public static InputParameters parseCommand(String[] args) throws Exception {
4444
printHelpMessage();
4545
}
4646

47-
if (commandArg.equals(GENERATE_GENERIC_IMPLEMENTS)) {
48-
inputParameters.setGenerateGenericImplements(true);
47+
if (commandArg.equals(ALL_GENERIC_IMPLEMENTS)) {
48+
inputParameters.setAllGenericImplements(true);
4949
}
5050

5151
if (commandArg.equals(OUT_DIR)) {
@@ -102,6 +102,8 @@ private static void printHelpMessage() {
102102
helpMessage.appendln("\t\t[-input]:\t\tThe input jars or class directories from which the d.ts files will be generated.");
103103
helpMessage.appendln("\t\t[-super]:\t\tProvide jar files from which to search for super classes.");
104104
helpMessage.appendln("\t\t[-input-generics]:\tProvide a file with information for number of generic types per given generic class name.");
105+
helpMessage.appendln("\t\t[-all-generic-implements]:\tAdd this flag to generate implements for all interfaces implemented by the generic types." +
106+
" It is not enabled by default as when there are more than one implementation most probably one of them needs to be changed to extends, but this have to be made manually");
105107
helpMessage.appendln("\t\t[-help]:\t\tPrints this help message.");
106108

107109
System.out.println(helpMessage);

dts-generator/src/main/java/com/telerik/dts/DtsApi.java

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ public class DtsApi {
5757
private Map<String, String> aliasedTypes;
5858
private String[] namespaceParts;
5959
private int indent = 0;
60-
private boolean generateGenericImplements;
60+
private boolean allGenericImplements;
6161
private Pattern methodSignature = Pattern.compile("\\((?<ArgumentsSignature>.*)\\)(?<ReturnSignature>.*)");
6262
private Pattern isWordPattern = Pattern.compile("^[\\w\\d]+$");
6363

64-
public DtsApi(boolean generateGenericImplements) {
65-
this.generateGenericImplements = generateGenericImplements;
64+
public DtsApi(boolean allGenericImplements) {
65+
this.allGenericImplements = allGenericImplements;
6666
this.indent = 0;
6767

6868
overrideFieldComparator();
@@ -286,34 +286,31 @@ private String getExtendsLine(JavaClass currClass, TypeDefinition typeDefinition
286286
StringBuilder result = new StringBuilder();
287287
ReferenceType parent = typeDefinition.getParent();
288288

289-
if(!this.generateGenericImplements) {
289+
List<ReferenceType> interfaces = typeDefinition.getInterfaces();
290+
// if the object parent is java.lang.Object or any and it has exactly one interface
291+
// this means that this is actually a super class but not interface
292+
// if(interfaces.size() == 1 && parent != null
293+
// && (getTypeScriptTypeFromJavaType(parent, typeDefinition).equals("java.lang.Object")
294+
// || getTypeScriptTypeFromJavaType(parent, typeDefinition).equals("any"))) {
295+
// result.append(" extends ");
296+
// result.append(getTypeScriptTypeFromJavaType(interfaces.get(0), typeDefinition));
297+
// } else {
290298
if(parent != null) {
291299
result.append(" extends ");
292300
result.append(getTypeScriptTypeFromJavaType(parent, typeDefinition));
293301
}
294-
} else {
295-
List<ReferenceType> interfaces = typeDefinition.getInterfaces();
296-
if(interfaces.size() == 1 && parent == null && getTypeScriptTypeFromJavaType(parent, typeDefinition).equals("java.lang.Object")) {
297-
result.append(" extends ");
298-
result.append(getTypeScriptTypeFromJavaType(interfaces.get(0), typeDefinition));
299-
} else {
300-
if(parent != null) {
301-
result.append(" extends ");
302-
result.append(getTypeScriptTypeFromJavaType(parent, typeDefinition));
303-
}
304-
if(interfaces.size() > 0) {
305-
result.append(" implements ");
302+
if(interfaces.size() == 1 || (this.allGenericImplements && interfaces.size() > 0)) {
303+
result.append(" implements ");
306304

307-
for (ReferenceType referenceType : interfaces) {
308-
String tsType = getTypeScriptTypeFromJavaType(referenceType, typeDefinition);
309-
if(!this.isPrimitiveTSType(tsType)) {
310-
result.append(tsType + ", ");
311-
}
305+
for (ReferenceType referenceType : interfaces) {
306+
String tsType = getTypeScriptTypeFromJavaType(referenceType, typeDefinition);
307+
if(!this.isPrimitiveTSType(tsType)) {
308+
result.append(tsType + ", ");
312309
}
313-
result.deleteCharAt(result.lastIndexOf(","));
314310
}
311+
result.deleteCharAt(result.lastIndexOf(","));
315312
}
316-
}
313+
//}
317314
return result.toString();
318315
} else {
319316
JavaClass superClass = getSuperClass(currClass);
@@ -1167,9 +1164,13 @@ private void setOverrides() {
11671164

11681165
private void setExtendsOverrides() {
11691166
// here we put extends overrides to avoid manual work to fix the generated .d.ts file
1170-
this.extendsOverrides.put("android.renderscript.ProgramFragmentFixedFunction$Builder", "android.renderscript.Program.BaseProgramBuilder"); // android-17
1171-
this.extendsOverrides.put("android.renderscript.ProgramVertexFixedFunction$Builder", "android.renderscript.ProgramVertex.Builder"); // android-17
1172-
this.extendsOverrides.put("android.support.v4.app.JobIntentService$JobServiceEngineImpl", "android.support.v4.app.JobIntentService.CompatJobEngine"); // android-support
1167+
this.extendsOverrides.put("android.renderscript.ProgramFragmentFixedFunction$Builder", "android.renderscript.Program.BaseProgramBuilder"); // android-17
1168+
this.extendsOverrides.put("android.renderscript.ProgramVertexFixedFunction$Builder", "android.renderscript.ProgramVertex.Builder"); // android-17
1169+
this.extendsOverrides.put("android.support.v4.app.JobIntentService$JobServiceEngineImpl", "android.support.v4.app.JobIntentService.CompatJobEngine"); // android-support
1170+
1171+
// this.extendsOverrides.put("android.net.wifi.SupplicantState", "android.os.Parcelable");
1172+
// this.extendsOverrides.put("java.util.concurrent.ScheduledFuture", "java.util.concurrent.Delayed implements java.util.concurrent.Future<V>"); // android-17
1173+
// this.extendsOverrides.put("java.util.concurrent.RunnableScheduledFuture", "java.util.concurrent.ScheduledFuture<V> implements java.util.concurrent.RunnableFuture<V>"); // android-17
11731174
}
11741175

11751176
private void setTypeOverrides() {
@@ -1203,6 +1204,7 @@ private List<String> getIgnoredNamespaces(){
12031204
result.add("android.media.Rating");
12041205
result.add("android.service.media");
12051206
result.add("android.print");
1207+
result.add("java.util.function");
12061208

12071209
return result;
12081210
}

dts-generator/src/main/java/com/telerik/dts/Generator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ public class Generator {
1818
private static File inputGenericsFile;
1919
private FileHelper fileHelper;
2020
private DtsApi dtsApi;
21-
private boolean generateGenericImplements;
21+
private boolean allGenericImplements;
2222
private String outFileName;
2323
private String declarationsFileName;
2424

2525
public void start(InputParameters inputParameters) throws Exception {
2626
Generator.inputGenericsFile = inputParameters.getInputGenerics();
27-
this.generateGenericImplements = inputParameters.isGenerateGenericImplementsEnabled();
27+
this.allGenericImplements = inputParameters.isAllGenericImplementsEnabled();
2828
this.fileHelper = new FileHelper(inputParameters.getOutputDir());
29-
this.dtsApi = new DtsApi(generateGenericImplements);
29+
this.dtsApi = new DtsApi(allGenericImplements);
3030
this.outFileName = FileHelper.DEFAULT_DTS_FILE_NAME;
3131
this.declarationsFileName = FileHelper.DEFAULT_DECLARATIONS_FILE_NAME;
3232

dts-generator/src/main/java/com/telerik/dts/TypeDefinition.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.telerik.dts;
22

3+
import org.apache.bcel.generic.ObjectType;
34
import org.apache.bcel.generic.ReferenceType;
45
import org.apache.bcel.generic.Type;
56

@@ -69,9 +70,20 @@ private void checkSignature() {
6970
if (interfacesSignature != null) {
7071
this.interfaces = GenericUtilities.getTypeParameters(interfacesSignature);
7172
if(this.interfaces.size() > 0){
73+
// we assume that the first type parameter is the base class and the others are interfaces
7274
parent = this.interfaces.get(0);
73-
if ((parent instanceof GenericObjectType) && ((GenericObjectType)parent).getClassName().equals("java.lang.Enum")){
74-
parent = null; // we don't need extends for enum
75+
if ((parent instanceof ObjectType) &&
76+
(((ObjectType)parent).getClassName().equals("java.lang.Enum")
77+
|| ((ObjectType)parent).getClassName().equals("java.lang.Object"))){
78+
if(((ObjectType)parent).getClassName().equals("java.lang.Enum")) {
79+
parent = null; // we don't need extends for enum
80+
}
81+
// if we have only one another interface set it as a parent
82+
// otherwise we don't know which one to set as a parent
83+
if(this.interfaces.size() == 2) {
84+
parent = this.interfaces.get(1);
85+
this.interfaces.remove(1);
86+
}
7587
}
7688
this.interfaces.remove(0);
7789
}

0 commit comments

Comments
 (0)