//----------------------------------------------------------------------------------------------------------------------------------------------------- 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); }
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); } } }
public void Emit(ILGenerator il, IOperand <int> lengthOperand) { lengthOperand.EmitTarget(il); lengthOperand.EmitLoad(il); il.Emit(OpCodes.Newarr, TypeTemplate.Resolve <TElement>()); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- 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>()))); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- 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)); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- 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); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- public IHappilOperand <TObject> New <TObject>(params IHappilOperand[] constructorArguments) { if (TypeTemplate.Resolve <TObject>().IsValueType) { return(new NewStructExpression <TObject>(constructorArguments)); } else { return(new NewObjectExpression <TObject>(constructorArguments)); } }
//----------------------------------------------------------------------------------------------------------------------------------------------------- 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); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- #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>()))); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- 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; }
//----------------------------------------------------------------------------------------------------------------------------------------------------- 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>(); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- 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>()); } }
//----------------------------------------------------------------------------------------------------------------------------------------------------- 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 }
//----------------------------------------------------------------------------------------------------------------------------------------------------- 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>()); } }
//----------------------------------------------------------------------------------------------------------------------------------------------------- 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)))); }
//------------------------------------------------------------------------------------------------------------------------------------------------- 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."); } }
//----------------------------------------------------------------------------------------------------------------------------------------------------- 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); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- 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); } }
//----------------------------------------------------------------------------------------------------------------------------------------------------- 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)))); }
//------------------------------------------------------------------------------------------------------------------------------------------------- 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)); } }
//----------------------------------------------------------------------------------------------------------------------------------------------------- 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); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- 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); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- 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); } }
//------------------------------------------------------------------------------------------------------------------------------------------------- public override string ToString() { return(string.Format("new {0}[]", TypeTemplate.Resolve <TElement>().Name)); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- public void ImplementInterface(Type interfaceType) { m_TypeBuilder.AddInterfaceImplementation(TypeTemplate.Resolve(interfaceType)); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- internal Operand() { m_OperandType = TypeTemplate.Resolve <T>(); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- public static TypeMemberCache Of(Type reflectedType) { return(s_TypeMembersByReflectedType.GetOrAdd( TypeTemplate.Resolve(reflectedType), key => new TypeMemberCache(key))); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- public FieldSelector SelectFields <TField>(Func <FieldInfo, bool> where = null) { return(new FieldSelector(m_Fields.Where(f => f.FieldType == TypeTemplate.Resolve <TField>()), where)); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- public EventSelector SelectEvents <TEventHandler>(Func <EventInfo, bool> where = null) { return(new EventSelector(m_Events.Where(ev => ev.EventHandlerType == TypeTemplate.Resolve <TEventHandler>()), where)); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- 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>())); }