@@ -685,9 +685,21 @@ extension JavaClassTranslator {
685
685
686
686
// If this superclass declares a method with the same parameter types,
687
687
// 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 ( ) ) {
691
703
return true
692
704
}
693
705
} catch {
@@ -697,3 +709,126 @@ extension JavaClassTranslator {
697
709
return false
698
710
}
699
711
}
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