private SpecializationInfo GenerateNestedClassSpecialization(TypeDefinition type, SpecializationScope parentScope) { if (!type.HasGenericParameters) { throw new NotSupportedException(); } var specializedType = new TypeDefinition(type.Namespace, type.Name, type.Attributes, type.BaseType); // todo nested classes foreach (var genericParameter in type.GenericParameters.Skip(1)) // skipping specialized parameter { specializedType.GenericParameters.Add(new GenericParameter(genericParameter.Name, specializedType)); } var scope = new SpecializationScope(type.GenericParameters[0], parentScope.SpecializedArgumentType, parentScope, type, specializedType); var methods = new Dictionary <MethodReference, MethodReference>(); foreach (var method in type.Methods) { var newMethod = SpecializeMethod(method, scope); methods.Add(method, newMethod); specializedType.Methods.Add(newMethod); } return(new SpecializationInfo(type, scope.SpecializedArgumentType, specializedType, methods, new List <SpecializationInfo>())); }
public SpecializationScope(TypeReference genericArgumentType, TypeReference specializedArgumentType, SpecializationScope outerScope, TypeDefinition genericType, TypeDefinition specializedType) { GenericArgumentType = genericArgumentType; SpecializedArgumentType = specializedArgumentType; OuterScope = outerScope; GenericType = genericType; SpecializedType = specializedType; }
private TypeReference GetSpecializedType(TypeReference typeReference, SpecializationScope scope) { if (typeReference == scope.GenericArgumentType) { return(scope.SpecializedArgumentType); } if (typeReference is GenericInstanceType genericInstanceType) { return(typeReference.Resolve().MakeGenericInstanceType( genericInstanceType.GenericArguments.Select(x => GetSpecializedType(x, scope)).ToArray())); } return(scope.OuterScope == null ? typeReference : GetSpecializedType(typeReference, scope.OuterScope)); }
private MethodReference CloneMethodReference(MethodReference self, SpecializationScope scope) { var reference = new MethodReference(self.Name, self.ReturnType, self.DeclaringType) { HasThis = self.HasThis, ExplicitThis = self.ExplicitThis, CallingConvention = self.CallingConvention }; foreach (var parameter in self.Parameters) { reference.Parameters.Add(new ParameterDefinition(GetSpecializedType(parameter.ParameterType, scope))); } foreach (var genericParameter in self.GenericParameters) { reference.GenericParameters.Add(new GenericParameter(genericParameter.Name, reference)); } return(reference); }
private SpecializationInfo GenerateSpecialization(TypeDefinition type, TypeReference specializedArgument) { if (!type.HasGenericParameters) { throw new NotSupportedException(); } if (type.GenericParameters.Count > 1) { throw new NotImplementedException(); } var specializedType = new TypeDefinition(type.Namespace, type.Name + "$specialized$" + specializedArgument.FullName, type.Attributes, type.BaseType); var scope = new SpecializationScope(type.GenericParameters[0], specializedArgument, null, type, specializedType); var nestedInfos = new List <SpecializationInfo>(); foreach (var nestedClass in type.NestedTypes) { var specInfo = GenerateNestedClassSpecialization(nestedClass, scope); specializedType.NestedTypes.Add(specInfo.SpecializedClass); nestedInfos.Add(specInfo); } var methods = new Dictionary <MethodReference, MethodReference>(); foreach (var method in type.Methods) { var newMethod = SpecializeMethod(method, scope); methods.Add(method, newMethod); specializedType.Methods.Add(newMethod); } _moduleDefinition.Types.Add(specializedType); return(new SpecializationInfo(type, specializedArgument, specializedType, methods, nestedInfos)); }