@@ -57,10 +57,10 @@ struct JavaClassTranslator {
57
57
var constructors : [ Constructor < JavaObject > ] = [ ]
58
58
59
59
/// The (instance) methods of the Java class.
60
- var methods : [ Method ] = [ ]
60
+ var methods : MethodCollector = MethodCollector ( )
61
61
62
62
/// The static methods of the Java class.
63
- var staticMethods : [ Method ] = [ ]
63
+ var staticMethods : MethodCollector = MethodCollector ( )
64
64
65
65
/// The native instance methods of the Java class, which are also reflected
66
66
/// in a `*NativeMethods` protocol so they can be implemented in Swift.
@@ -215,8 +215,8 @@ extension JavaClassTranslator {
215
215
/// Add a method to the appropriate list for later translation.
216
216
private mutating func addMethod( _ method: Method , isNative: Bool ) {
217
217
switch ( method. isStatic, isNative) {
218
- case ( false , false ) : methods. append ( method)
219
- case ( true , false ) : staticMethods. append ( method)
218
+ case ( false , false ) : methods. add ( method)
219
+ case ( true , false ) : staticMethods. add ( method)
220
220
case ( false , true ) : nativeMethods. append ( method)
221
221
case ( true , true ) : nativeStaticMethods. append ( method)
222
222
}
@@ -266,7 +266,7 @@ extension JavaClassTranslator {
266
266
}
267
267
268
268
// Render all of the instance methods in Swift.
269
- let instanceMethods = methods. compactMap { method in
269
+ let instanceMethods = methods. methods . compactMap { method in
270
270
do {
271
271
return try renderMethod ( method, implementedInSwift: false )
272
272
} catch {
@@ -355,7 +355,7 @@ extension JavaClassTranslator {
355
355
}
356
356
357
357
// Render static methods.
358
- let methods = staticMethods. compactMap { method in
358
+ let methods = staticMethods. methods . compactMap { method in
359
359
// Translate each static method.
360
360
do {
361
361
return try renderMethod (
@@ -553,3 +553,41 @@ extension JavaClassTranslator {
553
553
}
554
554
}
555
555
}
556
+
557
+ /// Helper struct that collects methods, removing any that have been overridden
558
+ /// by a covariant method.
559
+ struct MethodCollector {
560
+ var methods : [ Method ] = [ ]
561
+
562
+ /// Mapping from method names to the indices of each method within the
563
+ /// list of methods.
564
+ var methodsByName : [ String : [ Int ] ] = [ : ]
565
+
566
+ /// Add this method to the collector.
567
+ mutating func add( _ method: Method ) {
568
+ // Compare against existing methods with this same name.
569
+ for existingMethodIndex in methodsByName [ method. getName ( ) ] ?? [ ] {
570
+ let existingMethod = methods [ existingMethodIndex]
571
+ switch MethodVariance ( method, existingMethod) {
572
+ case . equivalent, . unrelated:
573
+ // Nothing to do.
574
+ continue
575
+
576
+ case . contravariantResult:
577
+ // This method is worse than what we have; there is nothing to do.
578
+ return
579
+
580
+ case . covariantResult:
581
+ // This method is better than the one we have; replace the one we
582
+ // have with it.
583
+ methods [ existingMethodIndex] = method
584
+ return
585
+ }
586
+ }
587
+
588
+ // If we get here, there is no related method in the list. Add this
589
+ // new method.
590
+ methodsByName [ method. getName ( ) , default: [ ] ] . append ( methods. count)
591
+ methods. append ( method)
592
+ }
593
+ }
0 commit comments