@@ -59,10 +59,9 @@ static FieldDefUser Clone(FieldDef origin) {
5959 /// <returns>The new TypeDef.</returns>
6060 static TypeDef PopulateContext ( TypeDef typeDef , InjectContext ctx ) {
6161 TypeDef ret ;
62- IDnlibDef existing ;
63- if ( ! ctx . Map . TryGetValue ( typeDef , out existing ) ) {
62+ if ( ! ctx . MemberMap . TryGetValue ( typeDef , out var existing ) ) {
6463 ret = Clone ( typeDef ) ;
65- ctx . Map [ typeDef ] = ret ;
64+ ctx . MemberMap [ typeDef ] = ret ;
6665 }
6766 else
6867 ret = ( TypeDef ) existing ;
@@ -71,10 +70,10 @@ static TypeDef PopulateContext(TypeDef typeDef, InjectContext ctx) {
7170 ret . NestedTypes . Add ( PopulateContext ( nestedType , ctx ) ) ;
7271
7372 foreach ( MethodDef method in typeDef . Methods )
74- ret . Methods . Add ( ( MethodDef ) ( ctx . Map [ method ] = Clone ( method ) ) ) ;
73+ ret . Methods . Add ( ( MethodDef ) ( ctx . MemberMap [ method ] = Clone ( method ) ) ) ;
7574
7675 foreach ( FieldDef field in typeDef . Fields )
77- ret . Fields . Add ( ( FieldDef ) ( ctx . Map [ field ] = Clone ( field ) ) ) ;
76+ ret . Fields . Add ( ( FieldDef ) ( ctx . MemberMap [ field ] = Clone ( field ) ) ) ;
7877
7978 return ret ;
8079 }
@@ -85,12 +84,12 @@ static TypeDef PopulateContext(TypeDef typeDef, InjectContext ctx) {
8584 /// <param name="typeDef">The origin TypeDef.</param>
8685 /// <param name="ctx">The injection context.</param>
8786 static void CopyTypeDef ( TypeDef typeDef , InjectContext ctx ) {
88- var newTypeDef = ( TypeDef ) ctx . Map [ typeDef ] ;
87+ var newTypeDef = ( TypeDef ) ctx . MemberMap [ typeDef ] ;
8988
90- newTypeDef . BaseType = ( ITypeDefOrRef ) ctx . Importer . Import ( typeDef . BaseType ) ;
89+ newTypeDef . BaseType = ctx . Importer . Import ( typeDef . BaseType ) ;
9190
9291 foreach ( InterfaceImpl iface in typeDef . Interfaces )
93- newTypeDef . Interfaces . Add ( new InterfaceImplUser ( ( ITypeDefOrRef ) ctx . Importer . Import ( iface . Interface ) ) ) ;
92+ newTypeDef . Interfaces . Add ( new InterfaceImplUser ( ctx . Importer . Import ( iface . Interface ) ) ) ;
9493 }
9594
9695 /// <summary>
@@ -99,7 +98,7 @@ static void CopyTypeDef(TypeDef typeDef, InjectContext ctx) {
9998 /// <param name="methodDef">The origin MethodDef.</param>
10099 /// <param name="ctx">The injection context.</param>
101100 static void CopyMethodDef ( MethodDef methodDef , InjectContext ctx ) {
102- var newMethodDef = ( MethodDef ) ctx . Map [ methodDef ] ;
101+ var newMethodDef = ( MethodDef ) ctx . MemberMap [ methodDef ] ;
103102
104103 newMethodDef . Signature = ctx . Importer . Import ( methodDef . Signature ) ;
105104 newMethodDef . Parameters . UpdateParameterTypes ( ) ;
@@ -151,7 +150,7 @@ static void CopyMethodDef(MethodDef methodDef, InjectContext ctx) {
151150
152151 foreach ( ExceptionHandler eh in methodDef . Body . ExceptionHandlers )
153152 newMethodDef . Body . ExceptionHandlers . Add ( new ExceptionHandler ( eh . HandlerType ) {
154- CatchType = eh . CatchType == null ? null : ( ITypeDefOrRef ) ctx . Importer . Import ( eh . CatchType ) ,
153+ CatchType = eh . CatchType == null ? null : ctx . Importer . Import ( eh . CatchType ) ,
155154 TryStart = ( Instruction ) bodyMap [ eh . TryStart ] ,
156155 TryEnd = ( Instruction ) bodyMap [ eh . TryEnd ] ,
157156 HandlerStart = ( Instruction ) bodyMap [ eh . HandlerStart ] ,
@@ -169,7 +168,7 @@ static void CopyMethodDef(MethodDef methodDef, InjectContext ctx) {
169168 /// <param name="fieldDef">The origin FieldDef.</param>
170169 /// <param name="ctx">The injection context.</param>
171170 static void CopyFieldDef ( FieldDef fieldDef , InjectContext ctx ) {
172- var newFieldDef = ( FieldDef ) ctx . Map [ fieldDef ] ;
171+ var newFieldDef = ( FieldDef ) ctx . MemberMap [ fieldDef ] ;
173172
174173 newFieldDef . Signature = ctx . Importer . Import ( fieldDef . Signature ) ;
175174 }
@@ -204,7 +203,7 @@ public static TypeDef Inject(TypeDef typeDef, ModuleDef target) {
204203 var ctx = new InjectContext ( typeDef . Module , target ) ;
205204 PopulateContext ( typeDef , ctx ) ;
206205 Copy ( typeDef , ctx , true ) ;
207- return ( TypeDef ) ctx . Map [ typeDef ] ;
206+ return ( TypeDef ) ctx . MemberMap [ typeDef ] ;
208207 }
209208
210209 /// <summary>
@@ -215,9 +214,9 @@ public static TypeDef Inject(TypeDef typeDef, ModuleDef target) {
215214 /// <returns>The injected MethodDef.</returns>
216215 public static MethodDef Inject ( MethodDef methodDef , ModuleDef target ) {
217216 var ctx = new InjectContext ( methodDef . Module , target ) ;
218- ctx . Map [ methodDef ] = Clone ( methodDef ) ;
217+ ctx . MemberMap [ methodDef ] = Clone ( methodDef ) ;
219218 CopyMethodDef ( methodDef , ctx ) ;
220- return ( MethodDef ) ctx . Map [ methodDef ] ;
219+ return ( MethodDef ) ctx . MemberMap [ methodDef ] ;
221220 }
222221
223222 /// <summary>
@@ -229,20 +228,20 @@ public static MethodDef Inject(MethodDef methodDef, ModuleDef target) {
229228 /// <returns>Injected members.</returns>
230229 public static IEnumerable < IDnlibDef > Inject ( TypeDef typeDef , TypeDef newType , ModuleDef target ) {
231230 var ctx = new InjectContext ( typeDef . Module , target ) ;
232- ctx . Map [ typeDef ] = newType ;
231+ ctx . MemberMap [ typeDef ] = newType ;
233232 PopulateContext ( typeDef , ctx ) ;
234233 Copy ( typeDef , ctx , false ) ;
235- return ctx . Map . Values . Except ( new [ ] { newType } ) ;
234+ return ctx . MemberMap . Values . Except ( new [ ] { newType } ) . OfType < IDnlibDef > ( ) ;
236235 }
237236
238237 /// <summary>
239238 /// Context of the injection process.
240239 /// </summary>
241- class InjectContext : ImportResolver {
240+ class InjectContext : ImportMapper {
242241 /// <summary>
243242 /// The mapping of origin definitions to injected definitions.
244243 /// </summary>
245- public readonly Dictionary < IDnlibDef , IDnlibDef > Map = new Dictionary < IDnlibDef , IDnlibDef > ( ) ;
244+ public readonly Dictionary < IMemberRef , IMemberRef > MemberMap = new Dictionary < IMemberRef , IMemberRef > ( ) ;
246245
247246 /// <summary>
248247 /// The module which source type originated from.
@@ -267,8 +266,7 @@ class InjectContext : ImportResolver {
267266 public InjectContext ( ModuleDef module , ModuleDef target ) {
268267 OriginModule = module ;
269268 TargetModule = target ;
270- importer = new Importer ( target , ImporterOptions . TryToUseTypeDefs ) ;
271- importer . Resolver = this ;
269+ importer = new Importer ( target , ImporterOptions . TryToUseTypeDefs , new GenericParamContext ( ) , this ) ;
272270 }
273271
274272 /// <summary>
@@ -280,23 +278,81 @@ public Importer Importer {
280278 }
281279
282280 /// <inheritdoc />
283- public override TypeDef Resolve ( TypeDef typeDef ) {
284- if ( Map . ContainsKey ( typeDef ) )
285- return ( TypeDef ) Map [ typeDef ] ;
286- return null ;
287- }
281+ public override ITypeDefOrRef Map ( ITypeDefOrRef source ) {
282+ if ( MemberMap . TryGetValue ( source , out var result ) )
283+ return ( ITypeDefOrRef ) result ;
284+
285+ //HACK: for netcore
286+ //System.Enviroment and System.AppDomain is in System.Runtime.Extensions/mscorlib/netstandard
287+ //System.Runtime.InteropServices.Marshal is in System.Runtime.InteropServices/mscorlib/netstandard
288+ if ( source . IsTypeRef && OriginModule . CorLibTypes . AssemblyRef != TargetModule . CorLibTypes . AssemblyRef &&
289+ source . DefinitionAssembly == OriginModule . CorLibTypes . AssemblyRef ) {
290+ var sourceRef = ( TypeRef ) source ;
291+ TypeRef typeRef = TryResolveType ( sourceRef , TargetModule . CorLibTypes . AssemblyRef , false ) ;
292+ if ( typeRef == null ) {
293+ if ( source . DefinitionAssembly . Name != "mscorlib" )
294+ typeRef = TryResolveType ( sourceRef , new AssemblyRefUser ( source . DefinitionAssembly ) , false ) ;
295+
296+ typeRef = typeRef ?? TryResolveType ( sourceRef , new AssemblyRefUser ( "netstandard" ) , true ) ??
297+ TryResolveType ( sourceRef , new AssemblyRefUser ( "mscorlib" ) , true ) ??
298+ TryResolveType ( sourceRef , new AssemblyRefUser ( "System.Private.CoreLib" ) , false ) ;
299+ }
300+ if ( typeRef != null ) {
301+ TargetModule . UpdateRowId ( typeRef . ResolutionScope ) ;
302+ TargetModule . UpdateRowId ( typeRef ) ;
303+ MemberMap [ source ] = typeRef ;
304+ return typeRef ;
305+ }
306+ }
288307
308+ return null ;
309+ }
310+
311+ TypeRef TryResolveType ( TypeRef sourceRef , AssemblyRef scope , bool checkExport ) {
312+ var typeRef = Import2 ( sourceRef , scope ) ;
313+
314+ if ( checkExport ) {
315+ var scopeDef = TargetModule . Context . AssemblyResolver . Resolve ( typeRef . DefinitionAssembly , TargetModule ) ;
316+ if ( scopeDef != null ) {
317+ var sigComparer = new SigComparer ( SigComparerOptions . DontCompareTypeScope ) ;
318+ var exportType = scopeDef . Modules . SelectMany ( m => m . ExportedTypes ) . Where ( et => sigComparer . Equals ( et , typeRef ) ) . FirstOrDefault ( ) ;
319+ if ( exportType != null && exportType . Implementation . Name != "System.Private.CoreLib" && exportType . Resolve ( ) != null ) {
320+ return exportType . ToTypeRef ( ) ;
321+ }
322+ }
323+ }
324+
325+ if ( typeRef . Resolve ( ) != null )
326+ return typeRef ;
327+
328+ return null ;
329+ }
330+
331+ TypeRef Import2 ( TypeRef type , IResolutionScope scope ) {
332+ if ( type is null )
333+ return null ;
334+ TypeRef result ;
335+
336+ var declaringType = type . DeclaringType ;
337+ if ( ! ( declaringType is null ) )
338+ result = new TypeRefUser ( TargetModule , type . Namespace , type . Name , Import2 ( declaringType , scope ) ) ;
339+ else
340+ result = new TypeRefUser ( TargetModule , type . Namespace , type . Name , scope ) ;
341+
342+ return result ;
343+ }
344+
289345 /// <inheritdoc />
290- public override MethodDef Resolve ( MethodDef methodDef ) {
291- if ( Map . ContainsKey ( methodDef ) )
292- return ( MethodDef ) Map [ methodDef ] ;
346+ public override IMethod Map ( MethodDef source ) {
347+ if ( MemberMap . TryGetValue ( source , out var result ) )
348+ return ( MethodDef ) result ;
293349 return null ;
294350 }
295351
296352 /// <inheritdoc />
297- public override FieldDef Resolve ( FieldDef fieldDef ) {
298- if ( Map . ContainsKey ( fieldDef ) )
299- return ( FieldDef ) Map [ fieldDef ] ;
353+ public override IField Map ( FieldDef source ) {
354+ if ( MemberMap . ContainsKey ( source ) )
355+ return ( FieldDef ) MemberMap [ source ] ;
300356 return null ;
301357 }
302358 }
0 commit comments