Exemple #1
0
        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);
                }
            }
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
            }
        }
Exemple #5
0
        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));
        }
Exemple #6
0
        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.");
            }
            }
        }
Exemple #7
0
        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);
            }
        }
Exemple #8
0
        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);
            }
        }
Exemple #10
0
        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);
        }
Exemple #11
0
        /// <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);
            }
        }
Exemple #13
0
        //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);
        }
Exemple #14
0
        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;
            }
        }
Exemple #16
0
        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.");
        }