예제 #1
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        public NewStructExpression(IOperand[] constructorArguments = null)
        {
            m_StatementScope = StatementScope.Current;

            m_StructType           = TypeTemplate.Resolve <TStruct>();
            m_ConstructorArguments = (constructorArguments ?? new IOperand[0]);

            if (m_ConstructorArguments.Length > 0)
            {
                var argumentTypes = m_ConstructorArguments.Select(arg => arg.OperandType).ToArray();
                m_Constructor = m_StructType.GetConstructor(argumentTypes);

                if (m_Constructor == null)
                {
                    throw new ArgumentException("Could not find constructor with specified argument types.");
                }

                foreach (var argument in m_ConstructorArguments.Reverse())
                {
                    m_StatementScope.Consume(argument);
                }
            }

            m_StatementScope.RegisterExpressionStatement(this);
        }
예제 #2
0
            public void Emit(ILGenerator il, IOperand <T> left, IOperand <Type> right)
            {
                var typeConstant = (right as Constant <Type>);

                if (object.ReferenceEquals(typeConstant, null))
                {
                    throw new NotSupportedException("Cast type must be a constant type known in advance.");
                }

                var fromType = left.OperandType;
                var castType = TypeTemplate.Resolve(typeConstant.Value);

                left.EmitTarget(il);
                left.EmitLoad(il);

                if (fromType.IsValueType)
                {
                    il.Emit(OpCodes.Box, fromType);
                }
                else
                {
                    il.Emit(OpCodes.Isinst, castType);

                    if (castType.IsNullableValueType())
                    {
                        il.Emit(OpCodes.Unbox_Any, castType);
                    }
                }
            }
예제 #3
0
            public void Emit(ILGenerator il, IOperand <int> lengthOperand)
            {
                lengthOperand.EmitTarget(il);
                lengthOperand.EmitLoad(il);

                il.Emit(OpCodes.Newarr, TypeTemplate.Resolve <TElement>());
            }
예제 #4
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        public HappilOperand <TCast> CastTo <TCast>()
        {
            return(new HappilBinaryExpression <T, Type, TCast>(
                       OwnerMethod,
                       @operator: new BinaryOperators.OperatorCastOrThrow <T>(),
                       left: this,
                       right: new HappilConstant <Type>(TypeTemplate.Resolve <TCast>())));
        }
예제 #5
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        private Delegate CreateFactoryMethodDelegate(MethodInfo factoryMethod)
        {
            var parameters             = factoryMethod.GetParameters();
            var openDelegateType       = s_DelegatePrototypesByArgumentCount[parameters.Length];
            var delegateTypeParameters = parameters.Select(p => TypeTemplate.Resolve(p.ParameterType)).Concat(new[] { factoryMethod.ReturnType });
            var closedDelegateType     = openDelegateType.MakeGenericType(delegateTypeParameters.ToArray());

            return(Delegate.CreateDelegate(closedDelegateType, factoryMethod));
        }
예제 #6
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        internal HappilField(HappilClass happilClass, string name, Type fieldType, bool isStatic = false)
        {
            m_HappilClass = happilClass;
            m_Name        = happilClass.TakeMemberName(name);
            m_IsStatic    = isStatic;

            var actualType = TypeTemplate.Resolve(fieldType);
            var attributes = (isStatic ? FieldAttributes.Private | FieldAttributes.Static : FieldAttributes.Private);

            m_FieldBuilder = happilClass.TypeBuilder.DefineField(m_Name, actualType, attributes);
        }
예제 #7
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        public IHappilOperand <TObject> New <TObject>(params IHappilOperand[] constructorArguments)
        {
            if (TypeTemplate.Resolve <TObject>().IsValueType)
            {
                return(new NewStructExpression <TObject>(constructorArguments));
            }
            else
            {
                return(new NewObjectExpression <TObject>(constructorArguments));
            }
        }
예제 #8
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        protected AnonymousDelegateOperand(ClassType ownerClass, Type[] argumentTypes, Type returnType)
        {
            m_OwnerClass     = ownerClass;
            m_HomeScopeBlock = StatementScope.Current.StatementBlock;
            m_Statements     = new StatementBlock();
            m_Signature      = new MethodSignature(
                isStatic: true,
                isPublic: false,
                argumentTypes: argumentTypes.Select(TypeTemplate.Resolve).ToArray(),
                returnType: returnType != null ? TypeTemplate.Resolve(returnType) : null);
        }
예제 #9
0
파일: Operand.cs 프로젝트: bitfringe/Hapil
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        #region IOperand Members

        public virtual Operand <TCast> CastTo <TCast>()
        {
            if (this is ITransformType && TypeTemplate.Resolve <TCast>() == m_OperandType)
            {
                return(((ITransformType)this).TransformToType <TCast>());
            }

            return(new BinaryExpressionOperand <T, Type, TCast>(
                       @operator: new BinaryOperators.OperatorCastOrThrow <T>(),
                       left: this,
                       right: new Constant <Type>(TypeTemplate.Resolve <TCast>())));
        }
예제 #10
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        public HappilClassBody(HappilClass happilClass)
        {
            m_HappilClass   = happilClass;
            m_ReflectedType = TypeTemplate.Resolve(typeof(TBase));

            var members = TypeMembers.Of(m_ReflectedType);

            m_ImplementableMembers    = members.ImplementableMembers;
            m_ImplementableMethods    = members.ImplementableMethods.Where(m => !m.IsSpecialName).ToArray();
            m_ImplementableProperties = members.ImplementableProperties;
            m_ImplementableEvents     = members.ImplementableEvents;
        }
예제 #11
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        internal FieldMember(ClassType ownerClass, string name, Type fieldType, bool isStatic = false, bool isPublic = false)
            : base(ownerClass, name)
        {
            m_IsStatic = isStatic;

            var actualType = TypeTemplate.Resolve(fieldType);
            var attributes = GetFieldAttributes(isStatic, isPublic);
            var uniqueName = ownerClass.TakeMemberName(name);

            m_FieldBuilder = ownerClass.TypeBuilder.DefineField(uniqueName, actualType, attributes);
            m_Writers      = new List <FieldWriter>();
        }
예제 #12
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        public HappilOperand <T> Default <T>()
        {
            var actualType = TypeTemplate.Resolve <T>();

            if (actualType.IsPrimitive || !actualType.IsValueType)
            {
                return(new HappilConstant <T>(default(T)));
            }
            else
            {
                return(new NewStructExpression <T>());
            }
        }
예제 #13
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        public ImplementationClassWriter(ClassType ownerClass, Type baseType)
            : base(ownerClass)
        {
            m_BaseType = TypeTemplate.Resolve(baseType);

            if (m_BaseType.IsInterface)
            {
                ownerClass.AddInterface(m_BaseType);
            }

            m_Members = TypeMemberCache.Of(m_BaseType);
            //TODO: validate base type
        }
예제 #14
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        public Operand <T> Default <T>()
        {
            var actualType = TypeTemplate.Resolve <T>();

            if (actualType.IsPrimitive || !actualType.IsValueType)
            {
                var constant = Helpers.CreateConstant(actualType, actualType.GetDefaultValue());
                return(constant.CastTo <T>());
                //new ConstantOperand<T>(default(T));
            }
            else
            {
                return(new NewStructExpression <T>());
            }
        }
예제 #15
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        public HappilOperand <TCast> As <TCast>()
        {
            var castType = TypeTemplate.Resolve <TCast>();

            if (castType.IsValueType && !castType.IsNullableValueType())
            {
                throw new ArgumentException("The cast type must be a reference type or a nullable value type.");
            }

            return(new HappilBinaryExpression <T, Type, TCast>(
                       OwnerMethod,
                       @operator: new BinaryOperators.OperatorTryCast <T>(),
                       left: this,
                       right: new HappilConstant <Type>(typeof(TCast))));
        }
예제 #16
0
파일: Operand.cs 프로젝트: bitfringe/Hapil
        //-------------------------------------------------------------------------------------------------------------------------------------------------

        public static Operand <T> operator !(Operand <T> x)
        {
            if (TypeTemplate.Resolve <T>() == typeof(bool))
            {
                object result = new UnaryExpressionOperand <bool, bool>(
                    @operator: new UnaryOperators.OperatorLogicalNot(),
                    operand: (IOperand <bool>)x.OrNullConstant <T>());

                return((Operand <T>)result);
            }
            else
            {
                throw new ArgumentException("Operator ! can only be applied to type Boolean.");
            }
        }
예제 #17
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        public NewObjectExpression(ConstructorInfo constructor, IOperand[] constructorArguments)
        {
            m_ObjectType           = TypeTemplate.Resolve <TObject>();
            m_ConstructorArguments = constructorArguments;
            m_Constructor          = constructor;

            var scope = StatementScope.Current;

            foreach (var argument in constructorArguments.Reverse())
            {
                scope.Consume(argument);
            }

            scope.RegisterExpressionStatement(this);
        }
예제 #18
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        internal FieldMember RegisterDependency <T>(Func <FieldMember> newFieldFactory)
        {
            var dependencyType = TypeTemplate.Resolve <T>();
            var existingField  = m_DependencyFields.FirstOrDefault(f => dependencyType.IsAssignableFrom(f.FieldType));

            if (existingField != null)
            {
                return(existingField);
            }
            else
            {
                var newField = newFieldFactory();
                // no need to AddMember(newField) because newFieldFactory() uses DefineField() which already does that.
                m_DependencyFields.Add(newField);

                return(newField);
            }
        }
예제 #19
0
파일: Operand.cs 프로젝트: bitfringe/Hapil
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        public Operand <TCast> As <TCast>()
        {
            var castType = TypeTemplate.Resolve <TCast>();

            if (castType.IsValueType && !castType.IsNullableValueType())
            {
                throw new ArgumentException("The cast type must be a reference type or a nullable value type.");
            }

            if (this is ITransformType && TypeTemplate.Resolve <TCast>() == m_OperandType)
            {
                return(((ITransformType)this).TransformToType <TCast>());
            }

            return(new BinaryExpressionOperand <T, Type, TCast>(
                       @operator: new BinaryOperators.OperatorTryCast <T>(),
                       left: this,
                       right: new Constant <Type>(typeof(TCast))));
        }
예제 #20
0
            //-------------------------------------------------------------------------------------------------------------------------------------------------

            protected override void OnWriteArgumentCheck(MethodWriterBase writer, Operand <TypeTemplate.TArgument> argument, bool isOutput)
            {
                Type actualParameterType = TypeTemplate.Resolve <TypeTemplate.TArgument>().UnderlyingType();

                if (actualParameterType.IsIntegralType())
                {
                    Static.Void(
                        m_CheckMethodTypeLong,
                        argument.CastTo <long>(), writer.Const((long)m_BoundValue), writer.Const(ParameterName), writer.Const(isOutput));
                }
                else if (actualParameterType.IsNumericType())
                {
                    Static.Void(
                        m_CheckMethodTypeDouble,
                        argument.CastTo <double>(), writer.Const(m_BoundValue), writer.Const(ParameterName), writer.Const(isOutput));
                }
                else
                {
                    throw new NotSupportedException(string.Format("InRange is not supported on parameter of type [{0}].", actualParameterType));
                }
            }
예제 #21
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        public NewObjectExpression(IOperand[] constructorArguments)
        {
            m_ObjectType           = TypeTemplate.Resolve <TObject>();
            m_ConstructorArguments = constructorArguments;

            var argumentTypes = constructorArguments.Select(arg => arg.OperandType).ToArray();

            m_Constructor = m_ObjectType.GetConstructor(argumentTypes);             //TODO: use MemberTypeCache for this

            if (m_Constructor == null)
            {
                throw new ArgumentException("Could not find constructor with specified argument types.");
            }

            var scope = StatementScope.Current;

            foreach (var argument in constructorArguments.Reverse())
            {
                scope.Consume(argument);
            }

            scope.RegisterExpressionStatement(this);
        }
예제 #22
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        protected ClassType(DynamicModule module, TypeKey key, string classFullName, Type baseType, ClassType containingClass)
        {
            var resolvedBaseType = TypeTemplate.Resolve(baseType);

            m_Key     = key;
            m_Module  = module;
            m_Writers = new List <ClassWriterBase>();
            m_Members = new List <MemberBase>();
            m_MembersByDeclarations = new Dictionary <MemberInfo, MemberBase>();
            m_MembersByName         = new Dictionary <string, MemberBase>();
            m_FactoryMethods        = new List <MethodInfo>();
            m_MemberNames           = new UniqueNameSet();
            m_NotImplementedMembers = new HashSet <MemberInfo>();
            m_NotImplementedMembers.UnionWith(TypeMemberCache.Of(resolvedBaseType).ImplementableMembers);
            m_CompiledType     = null;
            m_DependencyFields = new List <FieldMember>();
            m_NestedClasses    = new List <NestedClassType>();

            //m_TypeBuilder = module.ModuleBuilder.DefineType(classFullName, DefaultTypeAtributes, resolvedBaseType);

            // ReSharper disable once DoNotCallOverridableMethodsInConstructor
            m_TypeBuilder = CreateTypeBuilder(module, classFullName, resolvedBaseType, containingClass);
        }
예제 #23
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        public AnonymousMethodFactory(ClassType type, MethodMember hostMethod, Type[] argumentTypes, Type returnType, bool isStatic, bool isPublic)
        {
            var resolvedArgumentTypes = argumentTypes.Select(TypeTemplate.Resolve).ToArray();
            var resolvedReturnType    = (returnType != null ? TypeTemplate.Resolve(returnType) : null);
            var methodAttributes      = (MethodAttributes.Final | MethodAttributes.HideBySig | GetMethodModifierAttributes(isStatic, isPublic));

            m_MethodBuilder = type.TypeBuilder.DefineMethod(
                type.TakeMemberName(GetAnonymousMethodName(hostMethod.Name)),
                methodAttributes,
                resolvedReturnType,
                resolvedArgumentTypes);

            m_Signature = new MethodSignature(isStatic, isPublic, resolvedArgumentTypes, returnType: resolvedReturnType);

            m_Parameters = resolvedArgumentTypes.Select((argType, argIndex) => m_MethodBuilder.DefineParameter(
                                                            argIndex + 1,
                                                            ParameterAttributes.None,
                                                            "arg" + (argIndex + 1).ToString())).ToArray();

            if (!m_Signature.IsVoid)
            {
                m_ReturnParameter = m_MethodBuilder.DefineParameter(0, ParameterAttributes.Retval, strParamName: null);
            }
        }
예제 #24
0
            //-------------------------------------------------------------------------------------------------------------------------------------------------

            public override string ToString()
            {
                return(string.Format("new {0}[]", TypeTemplate.Resolve <TElement>().Name));
            }
예제 #25
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        public void ImplementInterface(Type interfaceType)
        {
            m_TypeBuilder.AddInterfaceImplementation(TypeTemplate.Resolve(interfaceType));
        }
예제 #26
0
파일: Operand.cs 프로젝트: bitfringe/Hapil
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        internal Operand()
        {
            m_OperandType = TypeTemplate.Resolve <T>();
        }
예제 #27
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        public static TypeMemberCache Of(Type reflectedType)
        {
            return(s_TypeMembersByReflectedType.GetOrAdd(
                       TypeTemplate.Resolve(reflectedType),
                       key => new TypeMemberCache(key)));
        }
예제 #28
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        public FieldSelector SelectFields <TField>(Func <FieldInfo, bool> where = null)
        {
            return(new FieldSelector(m_Fields.Where(f => f.FieldType == TypeTemplate.Resolve <TField>()), where));
        }
예제 #29
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        public EventSelector SelectEvents <TEventHandler>(Func <EventInfo, bool> where = null)
        {
            return(new EventSelector(m_Events.Where(ev => ev.EventHandlerType == TypeTemplate.Resolve <TEventHandler>()), where));
        }
예제 #30
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        public Operand <TMethod> MakeDelegate <TTarget, TMethod, TDelegate>(IOperand <TTarget> target, Expression <Func <TTarget, TMethod> > methodSelector)
        {
            var method = Helpers.ResolveMethodFromLambda(methodSelector);

            return(new DelegateOperand <TMethod>(target, method, delegateTypeOverride: TypeTemplate.Resolve <TDelegate>()));
        }