@@ -685,9 +685,21 @@ extension JavaClassTranslator {
685685
686686 // If this superclass declares a method with the same parameter types,
687687 // we have an override.
688- let overriddenMethod = try currentSuperclassNonOpt
689- . getDeclaredMethod ( method. getName ( ) , method. getParameterTypes ( ) )
690- if overriddenMethod != nil {
688+ guard let overriddenMethod = try currentSuperclassNonOpt
689+ . getDeclaredMethod ( method. getName ( ) , method. getParameterTypes ( ) ) else {
690+ continue
691+ }
692+
693+ // Ignore non-public, non-protected methods because they would not
694+ // have been render into the Swift superclass.
695+ if !overriddenMethod. isPublic && !overriddenMethod. isProtected {
696+ continue
697+ }
698+
699+ // We know that Java considers this method an override. However, it is
700+ // possible that Swift will not consider it an override, because Java
701+ // has subtyping relations that Swift does not.
702+ if method. getGenericReturnType ( ) . isEqualToOrSubtypeOf ( overriddenMethod. getGenericReturnType ( ) ) {
691703 return true
692704 }
693705 } catch {
@@ -697,3 +709,126 @@ extension JavaClassTranslator {
697709 return false
698710 }
699711}
712+
713+ extension [ Type ? ] {
714+ /// Determine whether the types in the array match the other array.
715+ func allTypesEqual( _ other: [ Type ? ] ) -> Bool {
716+ if self . count != other. count {
717+ return false
718+ }
719+
720+ for (selfType, otherType) in zip ( self , other) {
721+ if !selfType!. isEqualTo ( otherType!) {
722+ return false
723+ }
724+ }
725+
726+ return true
727+ }
728+ }
729+
730+ extension Type {
731+ /// Adjust the given type to use its bounds, mirroring what we do in
732+ /// mapping Java types into Swift.
733+ func adjustToJavaBounds( adjusted: inout Bool ) -> Type {
734+ if let typeVariable = self . as ( TypeVariable< GenericDeclaration> . self ) ,
735+ typeVariable. getBounds ( ) . count == 1 ,
736+ let bound = typeVariable. getBounds ( ) [ 0 ] {
737+ adjusted = true
738+ return bound
739+ }
740+
741+ if let wildcardType = self . as ( WildcardType . self) ,
742+ wildcardType. getUpperBounds ( ) . count == 1 ,
743+ let bound = wildcardType. getUpperBounds ( ) [ 0 ] {
744+ adjusted = true
745+ return bound
746+ }
747+
748+ return self
749+ }
750+
751+ /// Determine whether this type is equivalent to or a subtype of the other
752+ /// type.
753+ func isEqualTo( _ other: Type ) -> Bool {
754+ // First, adjust types to their bounds, if we need to.
755+ var anyAdjusted : Bool = false
756+ let adjustedSelf = self . adjustToJavaBounds ( adjusted: & anyAdjusted)
757+ let adjustedOther = other. adjustToJavaBounds ( adjusted: & anyAdjusted)
758+ if anyAdjusted {
759+ return adjustedSelf. isEqualTo ( adjustedOther)
760+ }
761+
762+ // If both are classes, check for equivalence.
763+ if let selfClass = self . as ( JavaClass< JavaObject> . self ) ,
764+ let otherClass = other. as ( JavaClass< JavaObject> . self ) {
765+ return selfClass. equals ( otherClass. as ( JavaObject . self) )
766+ }
767+
768+ // If both are arrays, check that their component types are equivalent.
769+ if let selfArray = self . as ( GenericArrayType . self) ,
770+ let otherArray = other. as ( GenericArrayType . self) {
771+ return selfArray. getGenericComponentType ( ) . isEqualTo ( otherArray. getGenericComponentType ( ) )
772+ }
773+
774+ // If both are parameterized types, check their raw type and type
775+ // arguments for equivalence.
776+ if let selfParameterizedType = self . as ( ParameterizedType . self) ,
777+ let otherParameterizedType = other. as ( ParameterizedType . self) {
778+ if !selfParameterizedType. getRawType ( ) . isEqualTo ( otherParameterizedType. getRawType ( ) ) {
779+ return false
780+ }
781+
782+ return selfParameterizedType. getActualTypeArguments ( )
783+ . allTypesEqual ( otherParameterizedType. getActualTypeArguments ( ) )
784+ }
785+
786+ // If both are type variables, compare their bounds.
787+ // FIXME: This is a hack.
788+ if let selfTypeVariable = self . as ( TypeVariable< GenericDeclaration> . self ) ,
789+ let otherTypeVariable = other. as ( TypeVariable< GenericDeclaration> . self ) {
790+ return selfTypeVariable. getBounds ( ) . allTypesEqual ( otherTypeVariable. getBounds ( ) )
791+ }
792+
793+ // If both are wildcards, compare their upper and lower bounds.
794+ if let selfWildcard = self . as ( WildcardType . self) ,
795+ let otherWildcard = other. as ( WildcardType . self) {
796+ return selfWildcard. getUpperBounds ( ) . allTypesEqual ( otherWildcard. getUpperBounds ( ) )
797+ && selfWildcard. getLowerBounds ( ) . allTypesEqual ( otherWildcard. getLowerBounds ( ) )
798+ }
799+
800+ return false
801+ }
802+
803+ /// Determine whether this type is equivalent to or a subtype of the
804+ /// other type.
805+ func isEqualToOrSubtypeOf( _ other: Type ) -> Bool {
806+ // First, adjust types to their bounds, if we need to.
807+ var anyAdjusted : Bool = false
808+ let adjustedSelf = self . adjustToJavaBounds ( adjusted: & anyAdjusted)
809+ let adjustedOther = other. adjustToJavaBounds ( adjusted: & anyAdjusted)
810+ if anyAdjusted {
811+ return adjustedSelf. isEqualToOrSubtypeOf ( adjustedOther)
812+ }
813+
814+ if isEqualTo ( other) {
815+ return true
816+ }
817+
818+ // If both are classes, check for subclassing.
819+ if let selfClass = self . as ( JavaClass< JavaObject> . self ) ,
820+ let otherClass = other. as ( JavaClass< JavaObject> . self ) {
821+ return selfClass. isSubclass ( of: otherClass)
822+ }
823+
824+ // Anything object-like is a subclass of java.lang.Object
825+ if let otherClass = other. as ( JavaClass< JavaObject> . self ) ,
826+ otherClass. getName ( ) == " java.lang.Object " {
827+ if self . is ( GenericArrayType . self) || self . is ( ParameterizedType . self) ||
828+ self . is ( WildcardType . self) || self . is ( TypeVariable< GenericDeclaration> . self ) {
829+ return true
830+ }
831+ }
832+ return false
833+ }
834+ }
0 commit comments