private MethodBase ResolveConstructor(Cci.IMethodReference methodRef) { Debug.Assert(!methodRef.IsGeneric); // A method ref to a varargs method is always resolved as an entry in the method // ref table, never in the method def table, *even if the method is locally declared.* // (We could in theory resolve it as a method def if there were no extra arguments, // but in practice we do not.) var methodDef = (Cci.IMethodDefinition)methodRef.AsDefinition(_context); if (methodDef != null && IsLocal(methodRef.GetContainingType(_context)) && !methodRef.AcceptsExtraArguments) { return _constructorBuilders[methodDef]; } MethodBase result; if (_methodRefs.TryGetValue(methodRef, out result)) { return result; } Debug.Assert(methodRef.AsGenericMethodInstanceReference == null); Cci.ISpecializedMethodReference specializedRef = methodRef.AsSpecializedMethodReference; if (specializedRef != null && IsLocal(specializedRef.UnspecializedVersion.GetContainingType(_context))) { // get declaring type (TypeBuilder or TypeBuilderInstantiation since it's defined in the module being built): Type declaringType = ResolveType(methodRef.GetContainingType(_context)); ConstructorBuilder ctorBuilder = _constructorBuilders[(Cci.IMethodDefinition)specializedRef.UnspecializedVersion.AsDefinition(_context)]; result = TypeBuilder.GetConstructor(declaringType, ctorBuilder); } else { result = MakeMethodRef(methodRef, specializedRef, isConstructor: true); } _methodRefs.Add(methodRef, result); return result; }
private MethodInfo ResolveMethod(Cci.IMethodReference methodRef) { var methodDef = (Cci.IMethodDefinition)methodRef.AsDefinition(_context); // A method ref to a varargs method is always resolved as an entry in the method // ref table, never in the method def table, *even if the method is locally declared.* // (We could in theory resolve it as a method def if there were no extra arguments, // but in practice we do not.) if (methodDef != null && IsLocal(methodRef.GetContainingType(_context)) && !methodRef.AcceptsExtraArguments) { return _methodBuilders[methodDef]; } MethodBase methodBase; if (_methodRefs.TryGetValue(methodRef, out methodBase)) { return (MethodInfo)methodBase; } MethodInfo result; Cci.ISpecializedMethodReference specializedRef = methodRef.AsSpecializedMethodReference; Cci.IGenericMethodInstanceReference genericRef = methodRef.AsGenericMethodInstanceReference; if (specializedRef != null && IsLocal(specializedRef.UnspecializedVersion.GetContainingType(_context))) { // get declaring type (TypeBuilder or TypeBuilderInstantiation since it's defined in the module being built): Type type = ResolveType(specializedRef.GetContainingType(_context)); MethodBuilder methodBuilder = _methodBuilders[(Cci.IMethodDefinition)specializedRef.UnspecializedVersion.AsDefinition(_context)]; MethodInfo methodOnTypeBuilder = TypeBuilder.GetMethod(type, methodBuilder); if (genericRef != null) { Type[] typeArgs = genericRef.GetGenericArguments(_context).Select(arg => ResolveType(arg)).ToArray(); result = methodOnTypeBuilder.MakeGenericMethod(typeArgs); } else { result = methodOnTypeBuilder; } } else if (genericRef != null) { MethodInfo genericMethod = ResolveMethod(genericRef.GetGenericMethod(_context)); Type[] typeArgs = genericRef.GetGenericArguments(_context).Select((arg) => ResolveType(arg)).ToArray(); if (genericMethod is MethodRef) { result = new MethodSpec(genericMethod, typeArgs); } else { result = genericMethod.MakeGenericMethod(typeArgs); } } else { result = MakeMethodRef(methodRef, specializedRef, isConstructor: false); } _methodRefs.Add(methodRef, result); return result; }