예제 #1
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);
        }
예제 #2
0
        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);
            }
        }