Skip to content

Commit 4a57323

Browse files
committed
Try to remove duplicate overloads caused by Java primitives
1 parent d8ebaf7 commit 4a57323

File tree

3 files changed

+70
-42
lines changed

3 files changed

+70
-42
lines changed

src/main/java/io/github/bensku/tsbind/AstGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ private Method processMethod(MethodDeclaration member, Set<String> privateOverri
264264
&& method.getTypeParameters().isEmpty()) {
265265
// GraalJS will make this getter work, somehow
266266
return new Getter(name, returnType, methodDoc, method.isStatic(), override);
267-
} else if (name.length() > 4 && name.startsWith("set") && method.getNumberOfParams() == 1
267+
} else if (name.length() > 3 && name.startsWith("set") && method.getNumberOfParams() == 1
268268
&& TypeRef.fromType(method.getParam(0).getType()) != TypeRef.BOOLEAN
269269
&& method.getTypeParameters().isEmpty()) {
270270
// GraalJS will make this setter work, somehow

src/main/java/io/github/bensku/tsbind/binding/TsClass.java

Lines changed: 55 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.util.ArrayList;
44
import java.util.HashMap;
55
import java.util.HashSet;
6+
import java.util.Iterator;
67
import java.util.List;
78
import java.util.Map;
89
import java.util.Objects;
@@ -12,7 +13,6 @@
1213
import java.util.stream.Collectors;
1314
import java.util.stream.Stream;
1415

15-
import io.github.bensku.tsbind.ast.Constructor;
1616
import io.github.bensku.tsbind.ast.Getter;
1717
import io.github.bensku.tsbind.ast.Member;
1818
import io.github.bensku.tsbind.ast.Method;
@@ -26,7 +26,39 @@ public class TsClass implements TsGenerator<TypeDefinition> {
2626

2727
private TsClass() {}
2828

29-
private class Members {
29+
private static class MethodId {
30+
String name;
31+
List<String> paramTypes;
32+
33+
MethodId(Method method) {
34+
this.name = method.name();
35+
this.paramTypes = method.params.stream().map(param -> param.type)
36+
.map(type -> TsTypes.primitiveName(type).orElse(type.name()))
37+
.collect(Collectors.toList());
38+
}
39+
40+
@Override
41+
public int hashCode() {
42+
return Objects.hash(name, paramTypes);
43+
}
44+
45+
@Override
46+
public boolean equals(Object obj) {
47+
if (this == obj) {
48+
return true;
49+
}
50+
if (obj == null) {
51+
return false;
52+
}
53+
if (getClass() != obj.getClass()) {
54+
return false;
55+
}
56+
MethodId other = (MethodId) obj;
57+
return Objects.equals(name, other.name) && Objects.equals(paramTypes, other.paramTypes);
58+
}
59+
}
60+
61+
private static class Members {
3062

3163
private final TypeDefinition type;
3264
private final List<Member> members;
@@ -65,36 +97,6 @@ private void visitSupertypes(TypeDefinition type, Consumer<TypeDefinition> visit
6597
* We do exactly that.
6698
*/
6799
public void addMissingOverloads() {
68-
class MethodId {
69-
String name;
70-
List<TypeRef> paramTypes;
71-
72-
MethodId(Method method) {
73-
this.name = method.name();
74-
this.paramTypes = method.params.stream().map(param -> param.type).collect(Collectors.toList());
75-
}
76-
77-
@Override
78-
public int hashCode() {
79-
return Objects.hash(name, paramTypes);
80-
}
81-
82-
@Override
83-
public boolean equals(Object obj) {
84-
if (this == obj) {
85-
return true;
86-
}
87-
if (obj == null) {
88-
return false;
89-
}
90-
if (getClass() != obj.getClass()) {
91-
return false;
92-
}
93-
MethodId other = (MethodId) obj;
94-
return Objects.equals(name, other.name) && Objects.equals(paramTypes, other.paramTypes);
95-
}
96-
}
97-
98100
// Figure out what methods we already have
99101
Set<MethodId> methods = new HashSet<>();
100102
for (Member member : members) {
@@ -190,6 +192,26 @@ public void fixInheritDoc() {
190192
}
191193
}
192194

195+
/**
196+
* Many Java types are emitted as 'number', which can cause strange
197+
* duplicates to appear in TS types. This pass removes them.
198+
*/
199+
public void removeDuplicates() {
200+
Set<MethodId> methods = new HashSet<>();
201+
Iterator<Member> it = members.iterator();
202+
while (it.hasNext()) {
203+
Member member = it.next();
204+
if (member instanceof Method) {
205+
MethodId id = new MethodId((Method) member);
206+
if (methods.contains(id)) {
207+
it.remove(); // Duplicate, remove it
208+
} else {
209+
methods.add(id); // First occurrance
210+
}
211+
}
212+
}
213+
}
214+
193215
/**
194216
* Transforms a TS getter/setter at given index to a normal method.
195217
* If the member there is not an accessor, nothing is done.
@@ -282,6 +304,7 @@ public void emit(TypeDefinition node, TsEmitter out) {
282304
Members members = new Members(node, out);
283305
members.addMissingOverloads();
284306
members.fixInheritDoc();
307+
members.removeDuplicates();
285308
members.resolveConflicts();
286309

287310
// Emit class members with some indentation

src/main/java/io/github/bensku/tsbind/binding/TsTypes.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,34 @@
11
package io.github.bensku.tsbind.binding;
22

3+
import java.util.Optional;
4+
35
import io.github.bensku.tsbind.ast.TypeRef;
46

57
public class TsTypes {
6-
7-
public static final TsGenerator<TypeRef.Simple> SIMPLE = (node, out) -> {
8+
9+
public static Optional<String> primitiveName(TypeRef node) {
810
if (node == TypeRef.VOID) {
9-
out.print("void");
11+
return Optional.of("void");
1012
} else if (node == TypeRef.BOOLEAN) {
11-
out.print("boolean");
13+
return Optional.of("boolean");
1214
} else if (node == TypeRef.BYTE || node == TypeRef.SHORT
1315
|| node == TypeRef.INT || node == TypeRef.FLOAT
1416
|| node == TypeRef.LONG || node == TypeRef.DOUBLE) {
1517
// Closest TS type of most primitives is number
1618
// FIXME GraalJS can't implicitly convert between all of these
17-
out.print("number");
19+
return Optional.of("number");
1820
} else if (node == TypeRef.STRING || node == TypeRef.CHAR) {
19-
out.print("string");
21+
return Optional.of("string");
2022
} else if (node == TypeRef.OBJECT) {
2123
// Allow autoboxing JS boolean and number to Object
2224
// Also helps with generic inheritance
23-
out.print("any");
24-
} else {
25-
out.printType(node);
25+
return Optional.of("any");
2626
}
27+
return Optional.empty();
28+
}
29+
30+
public static final TsGenerator<TypeRef.Simple> SIMPLE = (node, out) -> {
31+
primitiveName(node).ifPresentOrElse(out::print, () -> out.printType(node));
2732
};
2833

2934
public static final TsGenerator<TypeRef.Wildcard> WILDCARD = (node, out) -> {

0 commit comments

Comments
 (0)