public void BuildRoutines(ILConversion conversion, ConvertedTypeDefinitionMask_I input) { if (input.SourceTypeReference is GenericInstanceType genericInstance) { Methods.Building.RuntimeCreated.BuildMethods(conversion, (ConvertedGenericTypeDefinition_I)input); Constructors.Building.RuntimeCreated.BuildConstructors(conversion, (ConvertedGenericTypeDefinition_I)input); } else { // Done on purpose to find errors var typeDefinition = (TypeDefinition)input.SourceTypeReference; if (!typeDefinition.HasMethods) { return; } for (int i = 0; i < typeDefinition.Methods.Count; i++) { var method = typeDefinition.Methods[i]; BuildRoutine(conversion, input, method); } } }
public FieldInfo ResolveFieldReference(ILConversion conversion, ConvertedTypeDefinitionMask_I accessingType, BoundTypeDefinitionMask_I declaringFieldReferenceType, FieldReference fieldReference) { // The problem we run into is that for generic types, we need the fully baked type and we do not have access to a builder // that is able to act as a type. So I think we are going to have to bake the types. It looks like we will have to figure out // what it takes to make that work. // OLD WAY var declaringTypeRef = fieldReference.DeclaringType; var declaringSematicType = Execution.Types.Ensuring.EnsureBound(conversion, declaringTypeRef); FieldInfo fieldInfo = null; if (declaringSematicType.IsConverted()) { fieldInfo = Fields.GetFieldInfo(conversion, declaringSematicType, fieldReference.Name); } else { fieldInfo = Fields.GetFieldInfo(conversion, declaringSematicType.UnderlyingType, fieldReference); // Get field builder } // prevents returning a null reference to the IL builder. if (fieldInfo == null) { throw new Exception($"Expected to find field {fieldReference.Name} in type {declaringTypeRef.FullName}."); } return(fieldInfo); }
public MethodInfo MakeArrayMethod(ILConversion conversion, ConvertedTypeDefinitionMask_I callingType, BoundTypeDefinitionMask_I declaringType, MethodReference methodReference) { var systemParameters = Parameters.GetSystemParameterTypes(conversion, methodReference.Parameters); var returnType = Execution.Types.Ensuring.EnsureToType(conversion, methodReference.ReturnType); var callingConventions = Methods.GetCallingConventions(methodReference); return(callingType.Module.ModuleBuilder.GetArrayMethod(declaringType.UnderlyingType, methodReference.Name, callingConventions, returnType, systemParameters)); }
public void BuildCustomAttributes(ILConversion conversion, ConvertedTypeDefinitionMask_I input, ConvertedEmittedConstructor constructorEntry) { var methodDefinition = (MethodDefinition)constructorEntry.MethodReference; var builders = CreateCustomAttributeList(conversion, methodDefinition.CustomAttributes); for (int i = 0; i < builders.Count; i++) { var builder1 = builders[i]; constructorEntry.ConstructorBuilder.SetCustomAttribute(builder1); } }
public MethodInfo GetMethodInfoOrThrow(ILConversion conversion, ConvertedTypeDefinitionMask_I typeBeingBuilt, ConvertedRoutine methodBeingBuilt, BoundTypeDefinitionMask_I methodReferenceDeclaringType, MethodReference methodReference) { //var declaringType = Execution.Types.Ensuring.EnsureBound(conversion.Model, methodReference.DeclaringType); if (!(methodReferenceDeclaringType is BoundTypeDefinitionWithMethodsMask_I declaringTypeWithMethods)) { throw new System.Exception("Expected a type with methods declared."); } var methodInfo = GetMethodOrThrow_Internal(conversion, typeBeingBuilt, declaringTypeWithMethods, methodReference); if (methodInfo == null) { throw new System.Exception("Could not locate a MethodInfo."); } if (!methodReference.IsGenericInstance) { return(methodInfo); } if (!methodInfo.IsGenericMethod) { throw new System.Exception("Did not find a generic method"); } var genericInstanceMethod = (GenericInstanceMethod)methodReference; var typeArguments = new Type[genericInstanceMethod.GenericArguments.Count]; for (var i = 0; i < typeArguments.Length; i++) { var typeArgumentReference = genericInstanceMethod.GenericArguments[i]; var semanticTypeNode = Execution.Types.Ensuring.Ensure(new ExecutionEnsureContext() { Conversion = conversion, RuntimicSystem = conversion.RuntimicSystem, TypeReference = typeArgumentReference, MethodReference = methodBeingBuilt.MethodReference }); typeArguments[i] = semanticTypeNode.Type.UnderlyingType; } return(methodInfo.MakeGenericMethod(typeArguments)); }
public bool GetGenericParameterType(ILConversion conversion, ConvertedTypeDefinitionMask_I input, ConvertedRoutine routine, GenericParameter genericParameter, out System.Type type) { switch (genericParameter.Type) { case GenericParameterType.Method: { var method = (ConvertedBuiltMethod)routine; var operandDeclaringType = method.DeclaringType; if ((operandDeclaringType is ConvertedTypeDefinition_I convertedType) && Types.Building.CheckForPhase3Dependency(convertedType, (ConvertedTypeDefinition_I)routine.DeclaringType, true)) { type = null; return(false); } type = method.TypeParameters.Builders[genericParameter.Position]; return(true); } case GenericParameterType.Type: { var declaringType = genericParameter.DeclaringType; var boundType = Execution.Types.Ensuring.EnsureBound(conversion, declaringType); if ((boundType is ConvertedTypeDefinition_I convertedType) && Types.Building.CheckForPhase3Dependency(convertedType, (ConvertedTypeDefinition_I)routine.DeclaringType, true)) { type = null; return(false); } var x = (ConvertedTypeDefinitionWithTypeParameters_I)boundType; type = x.TypeParameters.Builders[genericParameter.Position]; return(true); } default: { throw new System.Exception("Not a method or a type."); } } }
public void BuildRoutine(ILConversion conversion, ConvertedTypeDefinitionMask_I input, MethodDefinition method) { // TODO: remove filter and enable the generic methods to have methods and constructors. if (input.IsGeneric() && input is ConvertedGenericTypeDefinition_I generic && generic.IsClosedType()) { return; } if (method.Name == ConstructorInfo.ConstructorName || method.Name == ConstructorInfo.TypeConstructorName) { // access container Constructors.Building.Emitted.BuildConstructor(conversion, input, method); } else { Methods.Building.Emitted.BuildMethod(conversion, (ConvertedTypeWithMethods_I)input, method); } }
public bool GetConstructor(ILConversion conversion, ConvertedTypeDefinitionMask_I callingType, BoundTypeDefinitionMask_I declaringBound, MethodReference methodReference, out MemberInfo memberInfo) { memberInfo = null; if (!declaringBound.IsConverted()) { // NOTE - This call can only be used when accessing types that fully built. memberInfo = Bound.Metadata.Members.Constructors.FindConstructorBySignature(conversion.RuntimicSystem, declaringBound, methodReference); } else { if (declaringBound.SourceTypeReference.IsArray) { memberInfo = Methods.Building.MakeArrayMethod(conversion, callingType, declaringBound, methodReference); return(true); } // This method HAS to be used for accessing constructors of types that are not fullying built. var withConstructors = (BoundTypeDefinitionWithConstructorsMask_I)declaringBound; var semanticConstructor = GetConstructor(conversion, withConstructors, methodReference); if (semanticConstructor == null) { return(false); } if (!(semanticConstructor is BoundConstructorDefinitionMask_I boundConstructor)) { throw new Exception("Semantic constructor is not a bound constructor. Cannot return a constructor info from a non-executive type."); } memberInfo = boundConstructor.UnderlyingConstructor; } return(memberInfo != null); }
public void BuildMethods(ILConversion conversion, ConvertedTypeDefinitionMask_I input) { // Done on purpose to find errors var typeDefinition = (TypeDefinition)input.SourceTypeReference; if (!typeDefinition.HasMethods) { return; } if (!(input is ConvertedTypeWithMethods_I convertedTypeWithMethods)) { throw new Exception("Trying to add a method to a type that does not support methods."); } for (int i = 0; i < typeDefinition.Methods.Count; i++) { var method = typeDefinition.Methods[i]; BuildMethod(conversion, convertedTypeWithMethods, method); } }
public bool GetMemberInfo(ILConversion conversion, ConvertedTypeDefinitionMask_I typeBeingBuilt, ConvertedRoutine routineBeingBuilt, BoundTypeDefinitionMask_I methodReferenceDeclaringType, MethodReference methodReference, out MemberInfo memberInfo) { if (methodReference == null) { throw new System.Exception($"Member reference is null. Cannot resolve member info."); } // If a constructor if (methodReference.Name == ConstructorInfo.ConstructorName) { return(Constructors.Getting.GetConstructor(conversion, typeBeingBuilt, methodReferenceDeclaringType, methodReference, out memberInfo)); } memberInfo = Methods.Getting.GetMethodInfoOrThrow(conversion, typeBeingBuilt, routineBeingBuilt, methodReferenceDeclaringType, methodReference); return(memberInfo != null); }
/// <summary> /// The goal here is to get the method definition that corresponds to the method /// </summary> /// <param name="conversion"></param> /// <param name="declaringType"></param> /// <param name="declaringTypeReference"></param> /// <param name="declaringTypeDefinition"></param> /// <param name="method"></param> private ConvertedMethod BuildMethod(ILConversion conversion, ConvertedTypeDefinitionMask_I declaringType, MethodInfo method, MethodReference methodReference) { ConvertedMethod methodEntry; var genericArguments = method.GetGenericArguments(); // ReSharper disable once ConstantConditionalAccessQualifier - IT CAN BE NULL. if (genericArguments?.Length > 0) { methodEntry = new ConvertedGenericMethod { MethodReference = methodReference, DeclaringType = declaringType, Conversion = conversion, MethodAttributes = method.Attributes, Name = method.Name, UnderlyingMethod = method }; } else { if (methodReference.MetadataToken.RID == 0) { } methodEntry = new ConvertedBoundMethod { MethodReference = methodReference, DeclaringType = declaringType, Conversion = conversion, MethodAttributes = method.Attributes, Name = method.Name, UnderlyingMethod = method }; } return(methodEntry); }
public void AddMethodOverride(ILConversion conversion, ConvertedTypeDefinitionMask_I input, BoundMethodDefinitionMask_I method) { if (!method.MethodReference.IsDefinition) { return; } var methodDefinition = (MethodDefinition)method.MethodReference; if (!methodDefinition.HasOverrides) { return; } for (int j = 0; j < methodDefinition.Overrides.Count; j++) { var methodOverride = methodDefinition.Overrides[j]; var interfaceDeclaringType = Execution.Types.Ensuring.EnsureBound(conversion, methodOverride.DeclaringType); if (!(methodOverride is MethodDefinition methodOverrideDefinition)) { methodOverrideDefinition = Cecil.Metadata.Members.Methods.ResolveReferenceToNonSignatureDefinition(conversion.RuntimicSystem, methodOverride); } var semanticMethod = Bound.Metadata.Members.Methods.Getting.FindMethodByDefinition(conversion.RuntimicSystem, (BoundTypeDefinitionWithMethodsMask_I)interfaceDeclaringType, methodOverrideDefinition); if (!(semanticMethod is BoundMethodDefinitionMask_I boundMethod)) { throw new Exception("Not a bound method. Could not add the method override."); } MethodInfo interfaceMethodInfo = boundMethod.UnderlyingMethod; input.TypeBuilder.DefineMethodOverride(method.UnderlyingMethod, interfaceMethodInfo); } }
//public new UnifiedApi_I<TContainer> Unified { get; set; } //UnifiedApiMask_I EnsuringApiMask_I.Unified => Unified; #endregion public bool EnsurePhase3Type(ILConversion conversion, ConvertedTypeDefinitionMask_I routineDeclaringType, MethodDefinition methodDefinition, TypeReference typeReference, out BoundTypeDefinitionMask_I type) { type = Execution.Types.Ensuring.EnsureBound(new ExecutionEnsureContext() { RuntimicSystem = conversion.RuntimicSystem, Conversion = conversion, TypeReference = typeReference, MethodReference = methodDefinition, RoutineDeclaringType = routineDeclaringType }); if ((type is ConvertedTypeDefinition_I convertedType)) { if (Types.Building.CheckForPhase3Dependency(convertedType, (ConvertedTypeDefinition_I)routineDeclaringType, true)) { return(false); } } return(true); }
public void BuildConstructor(ILConversion conversion, ConvertedTypeDefinitionMask_I input, MethodDefinition methodDefinition) { if (!(input is ConvertedTypeWithConstructors_I typeWithConstructors)) { throw new Exception("Trying to build a field on a type that does not support fields."); } ConstructorBuilder constructorBuilder; var constructorEntry = new ConvertedEmittedConstructor { Conversion = conversion, DeclaringType = input, MethodReference = methodDefinition, ReturnType = Execution.Types.Ensuring.EnsureBound(conversion, methodDefinition.ReturnType), }; Type[] systemParameterTypes = Routines.Building.CreateParameters(conversion, constructorEntry); Type returnType = Routines.Building.SetReturnType(conversion, constructorEntry); // ReSharper disable once AssignmentInConditionalExpression if (constructorEntry.IsStaticConstructor = (methodDefinition.Name == ConstructorInfo.TypeConstructorName)) { constructorBuilder = typeWithConstructors.TypeBuilder.DefineTypeInitializer(); } // ReSharper disable once AssignmentInConditionalExpression else if (constructorEntry.IsInstanceConstructor = (methodDefinition.Name == ConstructorInfo.ConstructorName)) { var constructorAttributes = GetConstructorAttributes(methodDefinition); var callConventions = Methods.GetCallingConventions(methodDefinition); constructorBuilder = typeWithConstructors.TypeBuilder.DefineConstructor(constructorAttributes, callConventions, systemParameterTypes); } else { throw new Exception("Expected a method definition marked as a constructor."); } constructorEntry.ConstructorBuilder = constructorBuilder; // The 'CreateParameterBuilder' call has to called after the parameters are defined // in the define constructor call. Thus a second loop is needed. Routines.Building.CreateParameterBuilders(conversion, constructorEntry); if (methodDefinition.HasBody) { constructorEntry.Body = new ConvertedRoutineBody(); if (methodDefinition.Body.HasVariables) { constructorEntry.Body.LocalVariables = new ConvertedRoutineLocalVariable[methodDefinition.Body.Variables.Count]; for (int i = 0; i < methodDefinition.Body.Variables.Count; i++) { var variable = methodDefinition.Body.Variables[i]; var variableTypeReference = variable.VariableType; var variableType = Execution.Types.Ensuring.EnsureToType(conversion, variableTypeReference); constructorEntry.Body.LocalVariables[i] = new ConvertedRoutineLocalVariable() { IsPinned = variable.IsPinned, UnderlyingType = variableType, Index = variable.Index }; } } } SetImplementationFlagsIfPresent(methodDefinition, constructorBuilder); typeWithConstructors.Routines.Add(constructorEntry); typeWithConstructors.Constructors.All.Add(constructorEntry); CustomAttributes.BuildCustomAttributes(conversion, input, constructorEntry); }
public void AddGenericParameters(ILConversion conversion, ConvertedTypeDefinitionMask_I input, ConvertedBuiltMethod methodEntry) { var methodDefinition = methodEntry.MethodReference; if (!methodDefinition.HasGenericParameters) { return; } List <string> genericParameterNamesList = new List <string>(); foreach (var parameter in methodDefinition.GenericParameters) { var genericParamaterTypeDefintionEntry = new ConvertedGenericParameterTypeDefinition() { Attributes = Cecil.Metadata.Members.GenericParameters.GetTypeParameterAttributes(parameter), Name = parameter.Name, FullName = parameter.FullName, Position = parameter.Position, TypeParameterKind = GetTypeParameterKind(parameter.Type), Definition = parameter, SourceTypeReference = parameter, DeclaringTypeDefinitionEntry = methodEntry.DeclaringType, ResolutionName = Cecil.Types.Naming.GetResolutionName(parameter) }; genericParamaterTypeDefintionEntry.ConversionState.BuildPhase = BuildPhaseKind.TypeCreated; genericParameterNamesList.Add(genericParamaterTypeDefintionEntry.Name); Methods.TypeParameters.Add(conversion, methodEntry, genericParamaterTypeDefintionEntry); } var genericParameterNames = genericParameterNamesList.ToArray(); GenericTypeParameterBuilder[] genericTypeParameterBuilders = methodEntry.MethodBuilder.DefineGenericParameters(genericParameterNames); methodEntry.TypeParameters.Builders = genericTypeParameterBuilders; foreach (var builder in genericTypeParameterBuilders) { var name = builder.Name; var genericTypeParameterEntry = Methods.TypeParameters.GetOrThrow(conversion, methodEntry, name); var definition = genericTypeParameterEntry.Definition; var attributes = GetGenericParameterAttributes(definition); builder.SetGenericParameterAttributes(attributes); genericTypeParameterEntry.Builder = builder; if (definition.HasConstraints) { List <Type> interfaceConstraintTypes = new List <Type>(); foreach (var constraint in definition.Constraints) { bool isClassConstraint = Cecil.Types.IsClass(conversion.RuntimicSystem, constraint); var semanticConstraint = Execution.Types.Ensuring.EnsureBound(conversion, constraint, null); if (isClassConstraint) { builder.SetBaseTypeConstraint(semanticConstraint.UnderlyingType); } else { interfaceConstraintTypes.Add(semanticConstraint.UnderlyingType); } } if (interfaceConstraintTypes.Count > 0) { builder.SetInterfaceConstraints(interfaceConstraintTypes.ToArray()); } } genericTypeParameterEntry.UnderlyingType = builder; } }
public MethodInfo GetMethodOrThrow_Internal(ILConversion conversion, ConvertedTypeDefinitionMask_I callingType, BoundTypeDefinitionWithMethodsMask_I boundTypeWithMethods, MethodReference methodReference) { if (boundTypeWithMethods.IsArrayType()) { return(Methods.Building.MakeArrayMethod(conversion, callingType, boundTypeWithMethods, methodReference)); } if (!boundTypeWithMethods.Methods.ByName.TryGetValue(methodReference.Name, out List <SemanticMethodMask_I> list)) { throw new Exception($"Could not find the method {methodReference.FullName}."); } if (list.Count == 0) { throw new Exception("Could not find the method."); } for (int i = 0; i < list.Count; i++) { var currentSemanticMethod = list[i]; if (!(currentSemanticMethod is BoundMethodDefinitionMask_I boundMethod)) { throw new Exception($"The converted type {boundTypeWithMethods.FullName} has a non-bound method present and it cannot be used to get a method info."); } var method = boundMethod.UnderlyingMethod; if (!VerifyReturnType(conversion, currentSemanticMethod.MethodReference, methodReference)) { continue; } if (!VerifyGenericArguments(currentSemanticMethod.MethodReference, methodReference)) { continue; } if (!Cecil.Methods.AreSame(conversion.RuntimicSystem, currentSemanticMethod.MethodReference.Parameters, methodReference.Parameters, methodReference)) { continue; } return(method); ////var currentSemanticMethod = list[i]; //if (Cecil.Metadata.Members.Methods.AreSame(currentSemanticMethod.MethodReference, methodReference)) //{ // if (!(currentSemanticMethod is BoundMethodDefinitionMask_I boundMethod1)) // { // throw new Exception($"The converted type {boundTypeWithMethods.FullName} has a non-bound method present and it cannot be used to get a method info."); // } // var method1 = boundMethod1.UnderlyingMethod; // return method1; //} } //for (int i = 0; i < list.Count; i++) //{ // if (i == 6) // { // } // var currentSemanticMethod = list[i]; // if (Cecil.Metadata.Members.Methods.AreSame(currentSemanticMethod.MethodReference, methodReference)) // { // if (!(currentSemanticMethod is BoundMethodDefinitionMask_I boundMethod1)) // { // throw new Exception($"The converted type {boundTypeWithMethods.FullName} has a non-bound method present and it cannot be used to get a method info."); // } // var method1 = boundMethod1.UnderlyingMethod; // return method1; // } //} throw new Exception("Could not find the method."); }