@@ -57,10 +57,10 @@ struct JavaClassTranslator {
5757 var constructors : [ Constructor < JavaObject > ] = [ ]
5858
5959 /// The (instance) methods of the Java class.
60- var methods : [ Method ] = [ ]
60+ var methods : MethodCollector = MethodCollector ( )
6161
6262 /// The static methods of the Java class.
63- var staticMethods : [ Method ] = [ ]
63+ var staticMethods : MethodCollector = MethodCollector ( )
6464
6565 /// The native instance methods of the Java class, which are also reflected
6666 /// in a `*NativeMethods` protocol so they can be implemented in Swift.
@@ -215,8 +215,8 @@ extension JavaClassTranslator {
215215 /// Add a method to the appropriate list for later translation.
216216 private mutating func addMethod( _ method: Method , isNative: Bool ) {
217217 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)
220220 case ( false , true ) : nativeMethods. append ( method)
221221 case ( true , true ) : nativeStaticMethods. append ( method)
222222 }
@@ -266,7 +266,7 @@ extension JavaClassTranslator {
266266 }
267267
268268 // Render all of the instance methods in Swift.
269- let instanceMethods = methods. compactMap { method in
269+ let instanceMethods = methods. methods . compactMap { method in
270270 do {
271271 return try renderMethod ( method, implementedInSwift: false )
272272 } catch {
@@ -355,7 +355,7 @@ extension JavaClassTranslator {
355355 }
356356
357357 // Render static methods.
358- let methods = staticMethods. compactMap { method in
358+ let methods = staticMethods. methods . compactMap { method in
359359 // Translate each static method.
360360 do {
361361 return try renderMethod (
@@ -553,3 +553,41 @@ extension JavaClassTranslator {
553553 }
554554 }
555555}
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