14
14
using SR = System . Reflection ;
15
15
16
16
using Mono . Cecil . Metadata ;
17
+ using System . Reflection ;
17
18
18
19
namespace Mono . Cecil {
19
20
@@ -191,7 +192,11 @@ TypeReference ImportType (Type type, ImportGenericContext context, ImportGeneric
191
192
192
193
protected virtual IMetadataScope ImportScope ( Type type )
193
194
{
194
- return ImportScope ( type . Assembly ) ;
195
+ if ( type . Assembly == typeof ( object ) . Assembly && Mixin . TryGetAssemblyNameReference ( module , type . Assembly . GetName ( ) , out var scope , true ) ) {
196
+ return scope ;
197
+ } else {
198
+ return ImportScope ( type . Assembly ) ;
199
+ }
195
200
}
196
201
197
202
static bool ImportOpenGenericType ( Type type , ImportGenericKind import_kind )
@@ -754,20 +759,69 @@ public static void CheckModule (ModuleDefinition module)
754
759
throw new ArgumentNullException ( Argument . module . ToString ( ) ) ;
755
760
}
756
761
757
- public static bool TryGetAssemblyNameReference ( this ModuleDefinition module , AssemblyNameReference name_reference , out AssemblyNameReference assembly_reference )
762
+ public static bool TryGetAssemblyNameReference ( this ModuleDefinition module , AssemblyNameWrapper name_reference , out AssemblyNameReference assembly_reference , bool check_name_only = false )
758
763
{
759
- var references = module . AssemblyReferences ;
760
-
761
- for ( int i = 0 ; i < references . Count ; i ++ ) {
762
- var reference = references [ i ] ;
763
- if ( ! Equals ( name_reference , reference ) )
764
- continue ;
764
+ // Try to resolve the assembly using direct reference first
765
+ if ( module . TryGetDirectAssemblyNameReference ( name_reference , out assembly_reference ) ) {
766
+ return true ;
767
+ }
765
768
766
- assembly_reference = reference ;
769
+ // If direct resolution fails, try to resolve using forwarded types
770
+ if ( module . TryGetForwardedAssemblyNameReference ( name_reference , out assembly_reference , check_name_only ) ) {
767
771
return true ;
768
772
}
769
773
774
+ // If resolution fails, set the output reference to null
775
+ assembly_reference = null ;
776
+ return false ;
777
+ }
778
+
779
+ static bool TryGetDirectAssemblyNameReference ( this ModuleDefinition module , AssemblyNameWrapper name_reference , out AssemblyNameReference assembly_reference )
780
+ {
781
+ // Check each assembly reference in the module for a match by full name
782
+ foreach ( var reference in module . AssemblyReferences ) {
783
+ if ( reference . FullName == name_reference . FullName ) {
784
+ assembly_reference = reference ;
785
+ return true ;
786
+ }
787
+ }
788
+
789
+ // If no direct reference is found, set the output reference to null
790
+ assembly_reference = null ;
791
+ return false ;
792
+ }
793
+
794
+ static bool TryGetForwardedAssemblyNameReference ( this ModuleDefinition module , AssemblyNameWrapper name_reference , out AssemblyNameReference assembly_reference , bool check_name_only )
795
+ {
796
+ // Initialize the output parameter to null
770
797
assembly_reference = null ;
798
+
799
+ // Iterate through all assembly references
800
+ foreach ( var asm_ref in module . AssemblyReferences ) {
801
+ AssemblyDefinition resolved_assembly ;
802
+ try {
803
+ // Attempt to resolve the assembly reference
804
+ resolved_assembly = module . AssemblyResolver . Resolve ( asm_ref ) ;
805
+ }
806
+ catch ( AssemblyResolutionException ) {
807
+ // Skip the assembly if resolution fails
808
+ continue ;
809
+ }
810
+
811
+ // Check exported types for type forwarding within the assembly
812
+ foreach ( ModuleDefinition module_def in resolved_assembly . Modules ) {
813
+ foreach ( ExportedType exported_type in module_def . ExportedTypes ) {
814
+ // Check if the exported type has a scope that matches the target assembly name
815
+ var scope = exported_type . Scope as AssemblyNameReference ;
816
+ if ( scope != null && AssemblyNameWrapper . Equals ( scope , name_reference , check_name_only ) ) {
817
+ // If a match is found, return the assembly reference from which the type was forwarded
818
+ assembly_reference = asm_ref ;
819
+ return true ;
820
+ }
821
+ }
822
+ }
823
+ }
824
+
771
825
return false ;
772
826
}
773
827
@@ -794,19 +848,104 @@ static bool Equals<T> (T a, T b) where T : class, IEquatable<T>
794
848
return a . Equals ( b ) ;
795
849
}
796
850
797
- static bool Equals ( AssemblyNameReference a , AssemblyNameReference b )
798
- {
799
- if ( ReferenceEquals ( a , b ) )
851
+ public sealed class AssemblyNameWrapper {
852
+ private readonly AssemblyName assembly_name ;
853
+ private readonly AssemblyNameReference assembly_name_reference ;
854
+
855
+ public AssemblyNameWrapper ( AssemblyName assembly_name )
856
+ {
857
+ CheckName ( assembly_name ) ;
858
+ this . assembly_name = assembly_name ;
859
+ }
860
+
861
+ public AssemblyNameWrapper ( AssemblyNameReference assembly_name_reference )
862
+ {
863
+ CheckName ( assembly_name_reference ) ;
864
+ this . assembly_name_reference = assembly_name_reference ;
865
+ }
866
+
867
+ public string FullName {
868
+ get {
869
+ if ( assembly_name == null ) {
870
+ return assembly_name_reference . FullName ;
871
+ } else {
872
+ return assembly_name . FullName ;
873
+ }
874
+ }
875
+ }
876
+
877
+ public string Name {
878
+ get {
879
+ if ( assembly_name == null ) {
880
+ return assembly_name_reference . Name ;
881
+ } else {
882
+ return assembly_name . Name ;
883
+ }
884
+ }
885
+ }
886
+
887
+ public Version Version {
888
+ get {
889
+ if ( assembly_name == null ) {
890
+ return assembly_name_reference . Version ;
891
+ } else {
892
+ return assembly_name . Version ;
893
+ }
894
+ }
895
+ }
896
+
897
+ public byte [ ] PublicKeyToken {
898
+ get {
899
+ if ( assembly_name == null ) {
900
+ return assembly_name_reference . PublicKeyToken ;
901
+ } else {
902
+ return assembly_name . GetPublicKeyToken ( ) ;
903
+ }
904
+ }
905
+ }
906
+
907
+ public string Culture {
908
+ get {
909
+ if ( assembly_name == null ) {
910
+ return assembly_name_reference . Culture ;
911
+ } else {
912
+ return assembly_name . CultureInfo . Name ;
913
+ }
914
+ }
915
+ }
916
+
917
+ public static bool Equals ( AssemblyNameWrapper a , AssemblyNameWrapper b , bool check_name_only )
918
+ {
919
+ if ( ReferenceEquals ( a , b ) )
920
+ return true ;
921
+ if ( a . assembly_name != null && ReferenceEquals ( a . assembly_name , b . assembly_name ) )
922
+ return true ;
923
+ if ( a . assembly_name_reference != null && ReferenceEquals ( a . assembly_name_reference , b . assembly_name_reference ) )
924
+ return true ;
925
+ if ( a . Name != b . Name )
926
+ return false ;
927
+
928
+ if ( ! check_name_only ) {
929
+ if ( ! Equals ( a . Version , b . Version ) )
930
+ return false ;
931
+ if ( a . Culture != b . Culture )
932
+ return false ;
933
+ if ( ! Equals ( a . PublicKeyToken , b . PublicKeyToken ) )
934
+ return false ;
935
+ }
936
+
800
937
return true ;
801
- if ( a . Name != b . Name )
802
- return false ;
803
- if ( ! Equals ( a . Version , b . Version ) )
804
- return false ;
805
- if ( a . Culture != b . Culture )
806
- return false ;
807
- if ( ! Equals ( a . PublicKeyToken , b . PublicKeyToken ) )
808
- return false ;
809
- return true ;
938
+ }
939
+
940
+ public static implicit operator AssemblyNameWrapper ( AssemblyName assembly_name )
941
+ {
942
+ return new AssemblyNameWrapper ( assembly_name ) ;
943
+ }
944
+
945
+ public static implicit operator AssemblyNameWrapper ( AssemblyNameReference assembly_name_reference )
946
+ {
947
+ return new AssemblyNameWrapper ( assembly_name_reference ) ;
948
+ }
810
949
}
811
950
}
812
951
}
0 commit comments