//----------------------------------------------------------------------------------------------------------------------------------------------------- private void WriteParentFieldInitialization() { using (TypeTemplate.CreateScope <TypeTemplate.TField>(m_Parent.ClosureClass.TypeBuilder)) { m_ParentField.AsOperand <TypeTemplate.TField>(m_ClosureInstanceReference).Assign(m_Parent.m_ClosureInstanceReference.CastTo <TypeTemplate.TField>()); } }
//------------------------------------------------------------------------------------------------------------------------------------------------- public override void DefineMemberBody() { var typedGetterDefinition = (GetterBodyDefinition as Action <IHappilMethodBody <T>, HappilArgument <TIndex1> >); var typedSetterDefinition = (SetterBodyDefinition as Action <IVoidHappilMethodBody, HappilArgument <TIndex1>, HappilArgument <T> >); using (TypeTemplate.CreateScope( typeof(TypeTemplate.TIndex1), OwnerProperty.Declaration.GetIndexParameters()[0].ParameterType)) { if (typedGetterDefinition != null) { using ((GetterMethod as IHappilMember).CreateTypeTemplateScope()) { using (GetterMethod.CreateBodyScope()) { typedGetterDefinition(GetterMethod.GetMethodBody <T>(), new HappilArgument <TIndex1>(GetterMethod, 1)); } } } if (typedSetterDefinition != null) { using ((SetterMethod as IHappilMember).CreateTypeTemplateScope()) { using (SetterMethod.CreateBodyScope()) { typedSetterDefinition(SetterMethod, new HappilArgument <TIndex1>(SetterMethod, 1), new HappilArgument <T>(SetterMethod, 2)); } } } } }
//----------------------------------------------------------------------------------------------------------------------------------------------------- internal override IDisposable CreateTypeTemplateScope() { var reflectionCache = DelegateShortcuts.GetReflectionCache(m_Declaration.EventHandlerType); return(TypeTemplate.CreateScope( typeof(TypeTemplate.TEventHandler), m_Declaration.EventHandlerType, typeof(TypeTemplate.TEventArgs), reflectionCache.Invoke.GetParameters()[1].ParameterType)); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- public IDisposable CreateTypeTemplateScope() { if (m_TemplateActualTypePairs == null) { m_TemplateActualTypePairs = BuildTemplateActualTypePairs(); } return(TypeTemplate.CreateScope(m_TemplateActualTypePairs)); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- //internal void MakeInstanceMethod() //{ // var anonymousMethodFactory = (m_MethodFactory as AnonymousMethodFactory); // if ( anonymousMethodFactory == null ) // { // throw new InvalidOperationException("Method modifiers are mutable only for anonymous methods."); // } // anonymousMethodFactory.ChangeMethodAttributes(isStatic: false); //} //----------------------------------------------------------------------------------------------------------------------------------------------------- //internal void HoistInClosure(ClosureDefinition closure) //{ // var anonymousMethodFactory = (m_MethodFactory as AnonymousMethodFactory); // if ( anonymousMethodFactory == null ) // { // throw new InvalidOperationException("Only anonymous method can be moved to a closure class."); // } // base.OwnerClass.MoveMember(this, destination: closure.ClosureClass); // base.OwnerClass = closure.ClosureClass; // anonymousMethodFactory.MethodMovedToClosure(closure.ClosureClass); // m_Writers.Clear(); // m_Closure = closure; //} //----------------------------------------------------------------------------------------------------------------------------------------------------- internal override IDisposable CreateTypeTemplateScope() { if (m_CachedTemplateTypePairs == null) { m_CachedTemplateTypePairs = Signature.BuildTemplateTypePairs(); } return(TypeTemplate.CreateScope(m_CachedTemplateTypePairs)); }
//------------------------------------------------------------------------------------------------------------------------------------------------- private void WriteReturnValueCheck(MethodDecorationBuilder decoration) { decoration.OnReturnValue((w, retVal) => { using (TypeTemplate.CreateScope <TypeTemplate.TArgument>(m_ParameterInfo.ParameterType)) { WriteArgumentOrCollectionItemCheck(w, retVal.CastTo <TypeTemplate.TArgument>(), isOutput: true); } }); }
//------------------------------------------------------------------------------------------------------------------------------------------------- private void WriteArgumentInputCheck(MethodDecorationBuilder decoration) { decoration.OnBefore(w => { using (TypeTemplate.CreateScope <TypeTemplate.TArgument>(m_ParameterInfo.ParameterType)) { var argument = w.Argument <TypeTemplate.TArgument>(m_ParameterInfo.Position + 1); WriteArgumentOrCollectionItemCheck(w, argument, isOutput: false); } }); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- private void WriteCaptureFieldInitialization(OperandCapture capture) { using (TypeTemplate.CreateScope <TypeTemplate.TField>(capture.OperandType)) { if (capture.SourceOperand.ShouldInitializeHoistedField) { capture.HoistedField.AsOperand <TypeTemplate.TField>(m_ClosureInstanceReference).Assign(capture.SourceOperand.CastTo <TypeTemplate.TField>()); } } }
//------------------------------------------------------------------------------------------------------------------------------------------------- protected override IDisposable CreateTemplateScope(MethodInfo method) { var parameterTypes = method.GetParameters().Select(p => p.ParameterType).ToArray(); var templateTypePairs = new Type[2 * (1 + parameterTypes.Length)]; templateTypePairs[0] = typeof(TypeTemplate.TReturn); templateTypePairs[1] = method.ReturnType; TypeTemplate.BuildArgumentsTypePairs(parameterTypes, templateTypePairs, arrayStartIndex: 2); return(TypeTemplate.CreateScope(templateTypePairs)); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- public void ForEachArgument(Action <HappilArgument <TypeTemplate.TArgument> > action) { var argumentTypes = GetArgumentTypes(); var indexBase = (IsStatic ? 0 : 1); for (byte i = 0; i < argumentTypes.Length; i++) { using (TypeTemplate.CreateScope <TypeTemplate.TArgument>(argumentTypes[i])) { var argument = this.Argument <TypeTemplate.TArgument>((byte)(i + indexBase)); action(argument); } } }
//------------------------------------------------------------------------------------------------------------------------------------------------- protected override IDisposable CreateTemplateScope(PropertyInfo property) { var parameterTypes = property.GetIndexParameters().Select(p => p.ParameterType).ToArray(); var templateTypePairs = new Type[2 * (1 + parameterTypes.Length)]; templateTypePairs[0] = typeof(TypeTemplate.TProperty); templateTypePairs[1] = property.PropertyType; if (parameterTypes.Length > 0) { TypeTemplate.BuildArgumentsTypePairs(parameterTypes, templateTypePairs, arrayStartIndex: 2); } return(TypeTemplate.CreateScope(templateTypePairs)); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- //TODO: refactor to reuse the overloaded method public void ForEachArgument(Action <Argument <TypeTemplate.TArgument>, int> action) { ValidateNotAnonymousMethod(); var argumentTypes = OwnerMethod.Signature.ArgumentType; for (int index = 0; index < argumentTypes.Length; index++) { using (TypeTemplate.CreateScope <TypeTemplate.TArgument>(argumentTypes[index])) { var argument = this.Argument <TypeTemplate.TArgument>(position: index + 1); action(argument, index); } } }
////----------------------------------------------------------------------------------------------------------------------------------------------------- //public void EmitFromLambda(Expression<Action> lambda) //{ // var callInfo = (MethodCallExpression)lambda.Body; // var methodInfo = callInfo.Method; // var arguments = callInfo.Arguments.Select(Helpers.GetLambdaArgumentAsConstant).ToArray(); // var happilExpression = new HapilUnaryExpression<object, object>( // ownerMethod: this, // @operator: new UnaryOperators.OperatorCall<object>(methodInfo, arguments), // operand: null); // //var arguments = new IHapilOperandInternals[callInfo.Arguments.Count]; // //for ( int i = 0 ; i < arguments.Length ; i++ ) // //{ // // //var argument = callInfo.Arguments[i]; // // //Expression<Func<object>> argumentLambda = Expression.Lambda<Func<object>>(argument); // // //var argumentValueFunc = argumentLambda.Compile(); // // //var argumentValue = argumentValueFunc(); // // arguments[i] = Helpers.GetLambdaArgumentAsConstant(callInfo.Arguments[i]); // //} // //m_HapilClass.CurrentScope.AddStatement(); //} //----------------------------------------------------------------------------------------------------------------------------------------------------- public void ForEachArgument(Action <Argument <TypeTemplate.TArgument> > action) { ValidateNotAnonymousMethod(); //TODO: refactor to reuse the overloaded method var argumentTypes = OwnerMethod.Signature.ArgumentType; var indexBase = (OwnerMethod.Signature.IsStatic ? 0 : 1); for (byte i = 0; i < argumentTypes.Length; i++) { using (TypeTemplate.CreateScope <TypeTemplate.TArgument>(argumentTypes[i])) { var argument = this.Argument <TypeTemplate.TArgument>((byte)(i + indexBase)); action(argument); } } }
//------------------------------------------------------------------------------------------------------------------------------------------------- internal IHappilClassBody <TBase> DefineMembers <TProperty>(Action <HappilProperty.BodyBase> invokeAccessorBodyDefinitions) { var propertiesToImplement = OwnerBody.HappilClass.TakeNotImplementedMembers(SelectedProperties); foreach (var declaration in propertiesToImplement) { using (TypeTemplate.CreateScope(typeof(TypeTemplate.TProperty), declaration.PropertyType)) { var copyOfDeclaration = declaration; var propertyMember = OwnerBody.HappilClass.GetOrAddDeclaredMember( copyOfDeclaration, memberFactory: () => new HappilProperty(OwnerBody.HappilClass, copyOfDeclaration)); invokeAccessorBodyDefinitions(propertyMember.GetPropertyBody <TypeTemplate.TProperty>()); } } return(OwnerBody); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- private IOperand GetRewrittenOperand(OperandCapture capture, IOperand target) { using (TypeTemplate.CreateScope <TypeTemplate.TField>(capture.OperandType)) { if (capture.HoistingClosure == this) { return(new Field <TypeTemplate.TField>(target, capture.HoistedField)); } else if (m_Parent != null) { return(m_Parent.GetRewrittenOperand(capture, m_ParentField.AsOperand <TypeTemplate.TField>(target))); } else { Debug.Fail("Captured operand is not hoisted."); throw new Exception(); } } }
//------------------------------------------------------------------------------------------------------------------------------------------------- private void WriteArgumentOrCollectionItemCheck(MethodWriterBase writer, Operand <TypeTemplate.TArgument> argument, bool isOutput) { var actualType = argument.OperandType.UnderlyingType(); Type collectionItemType; if (actualType.IsCollectionType(out collectionItemType) && !(this is ICheckCollectionTypes)) { using (TypeTemplate.CreateScope <TypeTemplate.TItem>(collectionItemType)) { writer.ForeachElementIn(argument.CastTo <IEnumerable <TypeTemplate.TItem> >()).Do((loop, item) => { using (TypeTemplate.CreateScope <TypeTemplate.TArgument>(collectionItemType)) { OnWriteArgumentCheck(writer, item.CastTo <TypeTemplate.TArgument>(), isOutput); } }); } } else { OnWriteArgumentCheck(writer, argument, isOutput); } }
//----------------------------------------------------------------------------------------------------------------------------------------------------- private void WriteClosureInstanceInitialization() { using (TypeTemplate.CreateScope <TypeTemplate.TClosure>(m_ClosureClass.TypeBuilder)) { using (var scope = new StatementScope(m_HostScopeBlock, StatementScope.RewriteMode.On)) { var scopeRewriter = m_HostMethod.TransparentWriter; var closureInstance = scopeRewriter.Local <TypeTemplate.TClosure>(); closureInstance.Assign(new NewObjectExpression <TypeTemplate.TClosure>(m_ClosureClassConstructor, new IOperand[0])); m_ClosureInstanceReference = closureInstance; if (m_Parent != null) { WriteParentFieldInitialization(); } foreach (var capture in m_Captures.Where(c => c.HoistingClosure == this)) { WriteCaptureFieldInitialization(capture); } } } }
//----------------------------------------------------------------------------------------------------------------------------------------------------- internal override IDisposable CreateTypeTemplateScope() { var indexParameters = m_Declaration.GetIndexParameters(); switch (indexParameters.Length) { case 0: return(TypeTemplate.CreateScope <TypeTemplate.TProperty>(m_Declaration.PropertyType)); case 1: return(TypeTemplate.CreateScope( typeof(TypeTemplate.TProperty), m_Declaration.PropertyType, typeof(TypeTemplate.TIndex1), indexParameters[0].ParameterType)); case 2: return(TypeTemplate.CreateScope( typeof(TypeTemplate.TProperty), m_Declaration.PropertyType, typeof(TypeTemplate.TIndex1), indexParameters[0].ParameterType, typeof(TypeTemplate.TIndex2), indexParameters[1].ParameterType)); default: throw new NotSupportedException("Properties with more than 2 indexer parameters are not supported."); } }
//----------------------------------------------------------------------------------------------------------------------------------------------------- public IDisposable CreateTypeTemplateScope() { return(TypeTemplate.CreateScope(typeof(TypeTemplate.TProperty), m_Declaration.PropertyType)); }
//------------------------------------------------------------------------------------------------------------------------------------------------- protected override IDisposable CreateTemplateScope(EventInfo @event) { return(TypeTemplate.CreateScope <TypeTemplate.TEventHandler>(@event.EventHandlerType)); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- public IDisposable CreateTypeTemplateScope() { return(TypeTemplate.CreateScope(typeof(TypeTemplate.TEventHandler), m_Declaration.EventHandlerType)); }
//------------------------------------------------------------------------------------------------------------------------------------------------- protected override IDisposable CreateTemplateScope(FieldInfo field) { return(TypeTemplate.CreateScope <TypeTemplate.TField>(field.FieldType)); }