protected virtual void EmitPlainCompositeHashCode( CompositeCodeGenerationInfo codeGenerationInfo, CompositeModel compositeModel, CompositeTypeModel typeModel, CompositeTypeGenerationInfo publicCompositeGenInfo, CompositeTypeGenerationInfo thisGenInfo, CompositeEmittingInfo emittingInfo, IEnumerable <FragmentTypeGenerationInfo> fragmentGenerationInfos ) { this.EmitCallNonCompositeMethod( codeGenerationInfo, compositeModel, typeModel, publicCompositeGenInfo, thisGenInfo, emittingInfo, fragmentGenerationInfos, HASH_CODE_METHOD, null, null, genInfos => genInfos.FirstOrDefault(genInfo => { var result = thisGenInfo.Parents.Keys.Where(t => !thisGenInfo.Builder.Equals(t)).OnlyBottomTypes().Where(t => !OBJECT_TYPE.Equals(t)).Any(p => genInfo.Parents.ContainsKey(p.GenericDefinitionIfGArgsHaveGenericParams())) || genInfo.DirectBaseFromModel.GetFullInheritanceChain().Any(t => compositeModel.ApplicationModel.GenericFragmentBaseType.NewWrapperAsType(this.ctx).Equals(t)); if (result) { var m = TypeGenerationUtils.FindMethodImplicitlyImplementingMethod(genInfo.DirectBaseFromModel, HASH_CODE_METHOD); result = !HASH_CODE_METHOD.Equals(m); } return(result); }) ); }
protected virtual void EmitCheckPropertyImmutability( PropertyModel propertyModel, CompositeTypeGenerationInfo thisGenerationInfo, MethodIL il ) { if (propertyModel.IsImmutable) { var setPropertyLabelWrapper = il.DefineLabel(); il .EmitLoadThisField(thisGenerationInfo.CompositeField) .EmitCall(IS_PROTOTYPE_GETTER) .EmitBranch(BranchType.IF_TRUE, setPropertyLabelWrapper) .EmitLoadString("Can not set immutable property ") .EmitReflectionObjectOf(thisGenerationInfo.Parents[propertyModel.NativeInfo.DeclaringType.NewWrapperAsType(this.ctx)]) .EmitLoadString(propertyModel.NativeInfo.Name) .EmitCall(QNAME_FROM_TYPE_AND_NAME) .EmitCall(TO_STRING_METHOD) .EmitLoadString("for a non-prototype composite instance.") .EmitCall(STRING_CONCAT_METHOD_3) .EmitThrowNewException(INVALID_OPERATION_EXCEPTION_CTOR_WITH_STRING) .MarkLabel(setPropertyLabelWrapper); } }
protected virtual Boolean IsCompositeGeneratedEvent( CompositeTypeGenerationInfo thisGenerationInfo, EventModel eventModel, Type genericEventMixinType ) { return(!thisGenerationInfo.AutoGeneratedEventInfos.ContainsKey(eventModel.NativeInfo) && eventModel.AddMethod != null && eventModel.RemoveMethod != null && genericEventMixinType.Equals(eventModel.AddMethod.Mixin.NativeInfo.DeclaringType) && genericEventMixinType.Equals(eventModel.RemoveMethod.Mixin.NativeInfo.DeclaringType)); }
protected override void EmitPublicCompositeHashCode( CompositeCodeGenerationInfo codeGenerationInfo, CompositeModel compositeModel, CompositeTypeModel typeModel, CompositeTypeGenerationInfo publicCompositeGenInfo, CompositeTypeGenerationInfo thisGenInfo, CompositeEmittingInfo emittingInfo, IEnumerable <FragmentTypeGenerationInfo> fragmentGenerationInfos ) { this.EmitPlainCompositeHashCode(codeGenerationInfo, compositeModel, typeModel, publicCompositeGenInfo, thisGenInfo, emittingInfo, fragmentGenerationInfos); }
protected virtual Boolean IsCompositeGeneratedProperty( CompositeTypeGenerationInfo thisGenerationInfo, PropertyModel propertyModel, Type genericPropertyMixinType ) { return(!thisGenerationInfo.AutoGeneratedPropertyInfos.ContainsKey(propertyModel.NativeInfo) && propertyModel.GetterMethod != null && propertyModel.SetterMethod != null && genericPropertyMixinType.Equals(propertyModel.GetterMethod.Mixin.NativeInfo.DeclaringType) && genericPropertyMixinType.Equals(propertyModel.SetterMethod.Mixin.NativeInfo.DeclaringType)); }
protected virtual void EmitPropertyCompareExchangeMethod( PropertyModel propertyModel, CompositeTypeGenerationInfo thisGenerationInfo, CILField propertyField, CompositeMethodGenerationInfo methodGenInfo, Action <CILField, MethodIL> compareExchangeAction ) { var il = methodGenInfo.IL; this.EmitThrowIfApplicationNotActiveWithoutLocalVariable(thisGenerationInfo, il); this.EmitCheckPropertyImmutability(propertyModel, thisGenerationInfo, il); // return Interlocked.CompareExchange(ref this._property, <arg-2>, <arg-1>); compareExchangeAction(propertyField, il); il.EmitReturn(); }
protected override void EmitTheRestOfPublicCompositeConstructor( CompositeCodeGenerationInfo codeGenerationInfo, CompositeModel model, CompositeTypeModel typeModel, CompositeEmittingInfo emittingInfo, IEnumerable <FragmentTypeGenerationInfo> fragmentGenerationInfos, CompositeTypeGenerationInfo thisGenerationInfo, ConstructorGenerationInfo ctorGenerationInfo, Int32 firstAdditionalParameterIndex ) { base.EmitTheRestOfPublicCompositeConstructor(codeGenerationInfo, model, typeModel, emittingInfo, fragmentGenerationInfos, thisGenerationInfo, ctorGenerationInfo, firstAdditionalParameterIndex); Int32 baseAdditionalParamsCount = base.GetAmountOfAdditionalArgumentsForPublicCompositeConstructor(); this.EmitSetActionMethod <ActivateAttribute>( codeGenerationInfo, model, typeModel, fragmentGenerationInfos, thisGenerationInfo, thisGenerationInfo, emittingInfo, ctorGenerationInfo, firstAdditionalParameterIndex + baseAdditionalParamsCount, ACTIVATION_METHOD_NAME, false ); this.EmitSetActionMethod <PassivateAttribute>( codeGenerationInfo, model, typeModel, fragmentGenerationInfos, thisGenerationInfo, thisGenerationInfo, emittingInfo, ctorGenerationInfo, firstAdditionalParameterIndex + baseAdditionalParamsCount + 1, PASSIVATION_METHOD_NAME, true ); }
protected virtual void EmitPropertySetterMethod( CompositeCodeGenerationInfo codeGenerationInfo, PropertyModel propertyModel, CompositeTypeGenerationInfo publicCompositeGenInfo, CompositeTypeGenerationInfo thisGenerationInfo, CILField propertyField, CILTypeBase fieldType, CILTypeBase propertyType, CompositeMethodGenerationInfo methodGenInfo, Action <CILField, MethodIL> writeAction ) { // Code for setting properties: // internal void Property<idx>Setter(<property type> value ) // { // CompositeInstance instance = this._instance; // <if the property is immutable> // if ( !this._instance.IsPrototype ) // { // throw new InvalidOperationException( "Can not set immutable propery " + QualifiedName.FromTypeAndName( <declaring type>, <name> ) + " for a non-prototype composite instance." ); // } // <end if> // <write property field> // } var il = methodGenInfo.IL; il.EmitLoadThisField(thisGenerationInfo.CompositeField) .EmitStoreLocal(methodGenInfo.GetOrCreateLocal(LB_C_INSTANCE, codeGenerationInfo.CompositeInstanceFieldType.NewWrapper(this.ctx))); this.EmitThrowIfApplicationNotActive(methodGenInfo); this.EmitProcessParameters(codeGenerationInfo, propertyModel.SetterMethod, true, publicCompositeGenInfo, thisGenerationInfo, methodGenInfo); this.EmitThrowIfViolations(thisGenerationInfo, methodGenInfo, propertyModel.SetterMethod); this.EmitCheckPropertyImmutability(propertyModel, thisGenerationInfo, il); writeAction(propertyField, il); il .EmitPop() .EmitReturn(); }
protected virtual void EmitPropertyExchangeMethod( PropertyModel propertyModel, CompositeTypeGenerationInfo thisGenerationInfo, CILField propertyField, CILTypeBase fieldType, CILTypeBase propertyType, CILMethod propertySetter, CompositeMethodGenerationInfo methodGenInfo, Action <CILField, MethodIL> exchangeAction ) { var il = methodGenInfo.IL; this.EmitThrowIfApplicationNotActiveWithoutLocalVariable(thisGenerationInfo, il); this.EmitCheckPropertyImmutability(propertyModel, thisGenerationInfo, il); exchangeAction(propertyField, il); il .EmitCastToType(fieldType, propertyType) .EmitReturn(); }
protected virtual void EmitPropertyGetterMethod( CompositeCodeGenerationInfo codeGenerationInfo, PropertyModel propertyModel, CompositeTypeGenerationInfo publicCompositeGenInfo, CompositeTypeGenerationInfo thisGenerationInfo, CILField propertyField, CILTypeBase propertyType, CompositeMethodGenerationInfo methodGenInfo, Action <CILField, MethodIL> readAction ) { // Code for getting properties: // public <property type> Property<idx>Getter( ) // { // CompositeInstance instance = this._instance; // <check application active> // var result = <read property field>; // <check constraints> // return result; // } var il = methodGenInfo.IL; il.EmitLoadThisField(thisGenerationInfo.CompositeField) .EmitStoreLocal(methodGenInfo.GetOrCreateLocal(LB_C_INSTANCE, codeGenerationInfo.CompositeInstanceFieldType.NewWrapper(this.ctx))); this.EmitThrowIfApplicationNotActive(methodGenInfo); var resultB = methodGenInfo.GetOrCreateLocal(LB_RESULT, methodGenInfo.ReturnType); readAction(propertyField, il); il.EmitStoreLocal(resultB); this.EmitProcessParameters(codeGenerationInfo, propertyModel.GetterMethod, false, publicCompositeGenInfo, thisGenerationInfo, methodGenInfo); this.EmitProcessResult(codeGenerationInfo, propertyModel.GetterMethod, publicCompositeGenInfo, thisGenerationInfo, methodGenInfo); this.EmitThrowIfViolations(thisGenerationInfo, methodGenInfo, propertyModel.GetterMethod); il.EmitLoadLocal(resultB) .EmitReturn(); }
protected virtual void EmitPlainCompositeEquals( CompositeCodeGenerationInfo codeGenerationInfo, CompositeModel compositeModel, CompositeTypeModel typeModel, CompositeTypeGenerationInfo publicCompositeGenInfo, CompositeTypeGenerationInfo thisGenInfo, CompositeEmittingInfo emittingInfo, IEnumerable <FragmentTypeGenerationInfo> fragmentGenerationInfos ) { // return Object.ReferenceEquals(this, obj) || (obj is <composite type> && <equals-implementation>); ILLabel?returnTrueL = null; ILLabel?returnFalseL = null; this.EmitCallNonCompositeMethod( codeGenerationInfo, compositeModel, typeModel, publicCompositeGenInfo, thisGenInfo, emittingInfo, fragmentGenerationInfos, EQUALS_METHOD, il => { // Make labels for true and false values returnTrueL = il.DefineLabel(); returnFalseL = il.DefineLabel(); il.EmitLoadArg(0) .EmitLoadArg(1) .EmitCall(REFERENCE_EQUALS_METHOD) .EmitBranch(BranchType.IF_TRUE, returnTrueL.Value); var continueLabel = il.DefineLabel(); foreach (var parent in thisGenInfo.Parents.Values.OnlyBottomTypes()) { il.EmitLoadArg(1) .EmitIsInst(parent) .EmitBranch(BranchType.IF_TRUE, continueLabel); } il.EmitBranch(BranchType.ALWAYS, returnFalseL.Value) .MarkLabel(continueLabel); }, il => { // return true il.MarkLabel(returnTrueL.Value) .EmitLoadBoolean(true) .EmitReturn() // return false .MarkLabel(returnFalseL.Value) .EmitLoadBoolean(false) .EmitReturn(); }, genInfos => genInfos.FirstOrDefault(genInfo => { var result = thisGenInfo.Parents.Keys.Where(t => !thisGenInfo.Builder.Equals(t)).OnlyBottomTypes().Where(t => !OBJECT_TYPE.Equals(t)).Any(p => genInfo.Parents.ContainsKey(p.GenericDefinitionIfGArgsHaveGenericParams())) || genInfo.DirectBaseFromModel.GetFullInheritanceChain().Any(t => compositeModel.ApplicationModel.GenericFragmentBaseType.NewWrapperAsType(this.ctx).Equals(t)); if (result) { var m = TypeGenerationUtils.FindMethodImplicitlyImplementingMethod(genInfo.DirectBaseFromModel, EQUALS_METHOD); result = !EQUALS_METHOD.Equals(m); } return(result); }) ); }
protected override void EmitAfterCompositeMethodBodyBegan( IEnumerable <FragmentTypeGenerationInfo> fragmentTypeGenerationInfos, CompositeTypeGenerationInfo thisGenerationInfo, CompositeMethodGenerationInfo thisMethodGenerationInfo, SPI.Model.CompositeMethodModel compositeMethodModel ) { var instanceableModel = compositeMethodModel.CompositeModel; // Need to emit code related to activation var il = thisMethodGenerationInfo.IL; var cInstanceB = thisMethodGenerationInfo.GetLocalOrThrow(LB_C_INSTANCE); LocalBuilder compositeMethodModelB = null; Boolean hasOnInvocationInjections = this.HasOnInvocationInjections(compositeMethodModel.CompositeModel.SpecialMethods.Where(sMethod => sMethod.AllAttributes.OfType <ActivateAttribute>().Any() || sMethod.AllAttributes.OfType <PrototypeAttribute>().Any())); if (hasOnInvocationInjections) { this.InitializeComplexMethodModelLocalIfNecessary(compositeMethodModel, thisMethodGenerationInfo, out compositeMethodModelB); } // cInstance.ActivateIfNeeded(<method-index>, <gargs-info>, <next fragment>); il.EmitLoadLocal(cInstanceB) .EmitLoadInt32(compositeMethodModel.MethodIndex); if (thisMethodGenerationInfo.Builder.GenericArguments.Count > 0) { // new MethodGenericArgumentsInfo(<method-handle>, <type-handle>) var cMethodInfo = thisMethodGenerationInfo.OverriddenMethod.MakeGenericMethod(thisMethodGenerationInfo.GenericArguments.ToArray()); il.Add(new OpCodeInfoWithMethodToken( OpCodes.Ldtoken, cMethodInfo)) .Add(new OpCodeInfoWithTypeToken( OpCodes.Ldtoken, cMethodInfo.DeclaringType )); il.EmitNewObject(this.METHOD_GENERIC_ARGUMENTS_INFO_CTOR); } else { il.EmitLoadNull(); } if (hasOnInvocationInjections) { il.EmitLoadLocal(compositeMethodModelB); if (compositeMethodModel.Concerns.Any()) { il.EmitCall(CONCERN_MODELS_GETTER) .EmitLoadInt32(0) .EmitCall(CONCERN_MODELS_INDEXER); } else { il.EmitCall(MIXIN_MODEL_GETTER); } } else { il.EmitLoadNull(); } il.EmitCall(SERVICE_COMPOSITE_ACTIVATE_IF_NEEDED_METHOD); }
//protected virtual void EmitEventCheckMethodForWeaklyReferencedEvents( // CILField eventField, // MethodIL il // ) //{ // il.EmitLoadThisField( eventField ) // .EmitCall( WEAK_EVENT_ARRAY_CLEANUP_METHOD ) // .EmitLoadNull() // .EmitCeq() // .EmitLoadInt32( 0 ) // .EmitCeq() // .EmitReturn(); //} protected virtual void EmitEventInvocationMethodForStronglyReferencedEvents( EventModel eventModel, CompositeTypeGenerationInfo thisGenerationInfo, CILField eventField, CILTypeBase eventType, CompositeMethodGenerationInfo invokeMethod, CILMethod eventMethodToInvoke ) { this.EmitEventInvocationMethodCore( eventModel, thisGenerationInfo, eventField, eventType, invokeMethod, eventMethodToInvoke, (eventLB, invocationStyle, exceptionType) => { if (EventInvocation.INVOKE_DIRECTLY.Equals(invocationStyle)) { // Invocation method: // private <return-type> Event<idx>Invoke(<args>) // { // <event-type> evt = this._event<idx>; // if (evt != null) // { // (return) this._event<idx>(<args>); // } else <if has return type other than void> // { // throw new InvalidOperationException("The event " + <event name> + " is not set."); // } // } this.EmitEventInvocationWithTryCatchIfNeeded( invocationStyle, exceptionType, invokeMethod, eventMethodToInvoke, il => il.EmitLoadLocal(eventLB), false ); } else { var il = invokeMethod.IL; // foreach ( Delegate handler in evt.GetInvocationList() ) // { // try // { // result = handler(<args>); // } // catch ( Exception exc ) // { // if ( exceptions == null ) // { // exceptions = new LinkedList<Exception>(); // } // exceptions.AddLast( exc ); // } // } var handlersB = invokeMethod.GetOrCreateLocal(LB_EVENT_HANDLERS); il .EmitLoadLocal(eventLB) .EmitCall(GET_INVOCATION_LIST_METHOD) .EmitStoreLocal(handlersB) .EmitSimpleForLoop( il2 => { // Int32 index = 0; var idxB = invokeMethod.GetOrCreateLocal(LB_INDEX); il2 .EmitLoadInt32(0) .EmitStoreLocal(idxB); return(idxB); }, (il2, idxB, loopBodyStartLabel) => { // index < list.Length il2 .EmitLoadLocal(idxB) .EmitLoadLocal(handlersB) .EmitLoadArrayLength() .EmitNumericConversion(CILTypeCode.UInt32, CILTypeCode.Int32, false) .EmitBranch(BranchType.IF_FIRST_LESSER_THAN_SECOND, loopBodyStartLabel); }, E_MethodIL.EmitLeftPlusPlus, (il2, idxB) => { this.EmitEventInvocationWithTryCatchIfNeeded( invocationStyle, exceptionType, invokeMethod, eventMethodToInvoke, il3 => { il3 .EmitLoadLocal(handlersB) .EmitLoadLocal(idxB) .EmitLoadElement(handlersB.LocalType) .EmitCastToType(handlersB.LocalType.GetElementType(), eventType); }, true ); } ); } }); }
protected virtual void EmitEventRelatedThings( CompositeTypeGenerationInfo thisGenerationInfo, CompositeMethodGenerationInfo thisMethodGenerationInfo, EventModel eventModel, Type genericEventMixinType ) { var nEventInfo = eventModel.NativeInfo; var eventInfo = nEventInfo.NewWrapper(this.ctx); CompositeMethodGenerationInfo invokeMethod = null; if (this.IsCompositeGeneratedEvent(thisGenerationInfo, eventModel, genericEventMixinType)) { var eventIdx = thisGenerationInfo.AutoGeneratedEventInfos.Count; var eventType = TypeGenerationUtils.CreateTypeForEmitting(eventInfo.EventHandlerType, thisGenerationInfo.GenericArguments, null); var invokeMethodFromModel = eventModel.NativeInfo.EventHandlerType.GetMethod(DELEGATE_INVOKE_METHOD_NAME).NewWrapper(this.ctx); CILTypeBase fieldType; Action <CILField, MethodIL> addAction, removeAction; Action <EventModel, CompositeTypeGenerationInfo, CILField, CILTypeBase, CompositeMethodGenerationInfo, CILMethod> invokeAction; Action <CILField, MethodIL> checkAction; this.CreateEmittingActionsForEvent( eventModel, eventType, out fieldType, out addAction, out removeAction, out invokeAction, out checkAction ); // Field: // private <field type> _event<idx>; var eventField = thisGenerationInfo.Builder.AddField( EVENT_FIELD_PREFIX + eventIdx, fieldType, FieldAttributes.Private ); var addMethod = this.ImplementMethodForEmitting( thisGenerationInfo, eventModel.AddMethod.NativeInfo.NewWrapper(this.ctx), EVENT_METHOD_PREFIX + eventIdx + EVENT_ADDITION_POSTFIX, MethodAttributes.Private | MethodAttributes.HideBySig, false ); this.EmitThrowIfApplicationNotActiveWithoutLocalVariable(thisGenerationInfo, addMethod.IL); addAction(eventField, addMethod.IL); CompositeMethodGenerationInfo removeMethod = this.ImplementMethodForEmitting( thisGenerationInfo, eventModel.RemoveMethod.NativeInfo.NewWrapper(this.ctx), EVENT_METHOD_PREFIX + eventIdx + EVENT_REMOVAL_POSTFIX, MethodAttributes.Private | MethodAttributes.HideBySig, false ); this.EmitThrowIfApplicationNotActiveWithoutLocalVariable(thisGenerationInfo, removeMethod.IL); removeAction(eventField, removeMethod.IL); invokeMethod = this.ImplementMethodForEmitting( thisGenerationInfo, decType => TypeGenerationUtils.CreateTypeForEmittingCILType(decType, thisGenerationInfo.GenericArguments, null), invokeMethodFromModel, EVENT_METHOD_PREFIX + eventIdx + EVENT_INVOCATION_POSTFIX, MethodAttributes.Private | MethodAttributes.HideBySig, false); var eventMethodToInvoke = invokeMethod.OverriddenMethod; this.EmitThrowIfApplicationNotActiveWithoutLocalVariable(thisGenerationInfo, invokeMethod.IL); invokeAction(eventModel, thisGenerationInfo, eventField, eventType, invokeMethod, eventMethodToInvoke); // Field clearer method: // private void Event<idx>Clear() // { // Interlocked.Exchange<TEvent>(ref this._event<idx>, null); // } var eventClearMB = thisGenerationInfo.Builder.AddMethod( EVENT_METHOD_PREFIX + eventIdx + EVENT_CLEAR_POSTFIX, MethodAttributes.Private | MethodAttributes.HideBySig, CallingConventions.HasThis); var il = eventClearMB.MethodIL; this.EmitThrowIfApplicationNotActiveWithoutLocalVariable(thisGenerationInfo, il); il.EmitLoadThisFieldAddress(eventField); il.EmitLoadNull(); il.EmitCall(INTERLOCKED_EXCHANGE_METHOD_GDEF.MakeGenericMethod(fieldType)); il.EmitPop(); il.EmitReturn(); // Field checker method: // private Boolean Event<idx>Checker() // { // // for strong refs // return this._event<idx>; // // for weak refs // return // } var eventCheckerMB = thisGenerationInfo.Builder.AddMethod( EVENT_METHOD_PREFIX + eventIdx + EVENT_CHECKER_POSTFIX, MethodAttributes.Private | MethodAttributes.HideBySig, CallingConventions.HasThis ); eventCheckerMB.ReturnParameter.ParameterType = BOOLEAN_TYPE; il = eventCheckerMB.MethodIL; this.EmitThrowIfApplicationNotActiveWithoutLocalVariable(thisGenerationInfo, il); checkAction(eventField, il); thisGenerationInfo.AutoGeneratedEventInfos.Add( nEventInfo, new EventGenerationInfo( this.EmitRefMethodForPropertyOrEvent(eventField, EVENT_METHOD_PREFIX + eventIdx + REF_INVOKER_METHOD_SUFFIX), eventModel, eventType, eventField, addMethod.Builder, removeMethod.Builder, invokeMethod.Builder, eventClearMB, eventCheckerMB ) ); } if (this.NeedToEmitAdditionalMemberInfo(thisGenerationInfo, eventInfo.Name, (parent, name) => parent.DeclaredEvents.FirstOrDefault(evt => Object.Equals(evt.Name, name)))) { // Need to define event if we inherit property directly from interface var name = eventInfo.Name; if (thisGenerationInfo.RawPropertyInfos.Keys.Any(pInfo => pInfo.Name.Equals(name))) { // We already have event with the same name from different type name = QualifiedName.FromMemberInfo(nEventInfo).ToString(); } CILEvent eBuilder; if (!thisGenerationInfo.RawEventInfos.TryGetValue(nEventInfo, out eBuilder)) { eBuilder = thisGenerationInfo.Builder.AddEvent( name, eventInfo.Attributes, TypeGenerationUtils.CreateTypeForEmitting(eventInfo.EventHandlerType, thisGenerationInfo.GenericArguments, null) ); if (invokeMethod != null) { eBuilder.RaiseMethod = invokeMethod.Builder; } thisGenerationInfo.RawEventInfos.Add(nEventInfo, eBuilder); } if (thisMethodGenerationInfo.MethodFromModel.Equals(eventInfo.AddMethod)) { eBuilder.AddMethod = thisMethodGenerationInfo.Builder; } else if (thisMethodGenerationInfo.MethodFromModel.Equals(eventInfo.RemoveMethod)) { eBuilder.RemoveMethod = thisMethodGenerationInfo.Builder; } else { throw new InternalException("Found an event, but neither adder nor remover methods matched the method being emitted. Event is " + eventInfo + ", method is " + thisMethodGenerationInfo.MethodFromModel + "."); } } }
protected virtual void EmitLoadDefaultValueForPropertyModel( PropertyModel propModel, CompositeTypeGenerationInfo propertyDeclaringTypeGenInfo, MethodGenerationInfo methodGenInfo ) { var il = methodGenInfo.IL; var pInfo = propModel.NativeInfo.NewWrapper(this.ctx); var propType = propertyDeclaringTypeGenInfo.AutoGeneratedPropertyInfos[propModel.NativeInfo].PropertyType; var declType = pInfo.DeclaringType; UseDefaultsAttribute udAttr; if (propModel.DefaultValueCreator != null) { // Get creator from property model il.EmitLoadLocal(methodGenInfo.GetLocalOrThrow(LB_C_INSTANCE)) .EmitCall(MODEL_INFO_GETTER) .EmitCall(MODEL_GETTER) .EmitCall(C_METHODS_GETTER) .EmitLoadInt32(propModel.GetterMethod.MethodIndex) .EmitCall(COMPOSITE_METHODS_INDEXER) .EmitCall(PROPERTY_MODEL_GETTER) .EmitCall(DEFAULT_CREATOR_GETTER); if (WillDefaultValueCreatorParameterBeNull(pInfo)) { il.EmitLoadNull(); } else { il.EmitReflectionObjectOf(propertyDeclaringTypeGenInfo.Parents[declType]) .EmitLoadString(pInfo.Name) .EmitCall(GET_PROPERTY_INFO_METHOD); } il .EmitLoadLocal(methodGenInfo.GetLocalOrThrow(LB_C_INSTANCE)) .EmitCall(STRUCTURE_OWNER_GETTER_METHOD) .EmitCall(APPLICATION_GETTER_METHOD) .EmitCall(DEFAULT_CREATOR_INVOKER) .EmitCastToType(DEFAULT_CREATOR_INVOKER.GetReturnType(), TypeGenerationUtils.CreateTypeForEmitting(propType, propertyDeclaringTypeGenInfo.GenericArguments, null)); } else if (propModel.IsUseDefaults(out udAttr)) { var propTypeGDef = propModel.NativeInfo.PropertyType.GetGenericDefinitionIfGenericType(); System.Reflection.MethodBase defaultValueCtor; CILTypeBase nullableParameter; if (propType.IsNullable(out nullableParameter)) { il.EmitLoadDefault(nullableParameter, aType => methodGenInfo.GetOrCreateLocalBasedOnType(aType)) .EmitNewObject(GetMethodBase(propType, NULLABLE_CTOR, propertyDeclaringTypeGenInfo)); } else if (STRING_TYPE.Equals(propType)) { il.EmitLoadString(DEFAULT_STRING); } else if (DEFAULT_CREATORS.TryGetValue(propTypeGDef, out defaultValueCtor)) { if (udAttr.ActualType != null) { var otherCtor = udAttr.ActualType .GetConstructors(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public) .FirstOrDefault(ctor => ctor.GetParameters().Length == 0); if (otherCtor != null) { defaultValueCtor = otherCtor; } } if (defaultValueCtor is System.Reflection.ConstructorInfo) { il.EmitNewObject(GetMethodBase(propType, ((System.Reflection.ConstructorInfo)defaultValueCtor).NewWrapper(this.ctx), propertyDeclaringTypeGenInfo)); } else if (defaultValueCtor is System.Reflection.MethodInfo) { if (((System.Reflection.MethodInfo)defaultValueCtor).IsStatic) { il.EmitCall(GetMethodBase(propType, ((System.Reflection.MethodInfo)defaultValueCtor).NewWrapper(this.ctx), propertyDeclaringTypeGenInfo)); } else { throw new InternalException("The default creators contained non-static method for type " + propTypeGDef + "."); } } else { throw new InternalException("Unknown default value creator " + defaultValueCtor + "."); } } else if (propType.IsArray() || IENUMERABLE_GDEF_TYPE.Equals(TypeGenerationUtils.GenericDefinitionIfGArgsHaveGenericParams(propType as CILType))) // || IENUMERABLE_NO_GDEF_TYPE.Equals( propType ) ) { var elementType = propType.IsArray() ? ((CILType)propType).ElementType : /*( IENUMERABLE_NO_GDEF_TYPE.Equals( propType ) ? OBJECT_TYPE :*/ ((CILType)propType).GenericArguments[0] /* )*/; il.EmitLoadInt32(0) .EmitNewArray(TypeGenerationUtils.CreateTypeForEmitting(elementType, propertyDeclaringTypeGenInfo.GenericArguments, null)); } else if (!propType.IsValueType()) { var ctorType = udAttr.ActualType == null ? (CILType)propType : udAttr.ActualType.NewWrapperAsType(this.ctx); var eDefaultValueCtor = ctorType.Constructors.FirstOrDefault(ctor => !ctor.Parameters.Any()); if (eDefaultValueCtor != null) { il.EmitNewObject(GetMethodBase(ctorType, eDefaultValueCtor, propertyDeclaringTypeGenInfo)); } else { throw new NotSupportedException("Tried to use " + USE_DEFAULTS_ATTRIBUTE_TYPE + " on a type (" + ctorType + ") with no parameterless constructor."); } } else { throw new InternalException("Could not emit default value for " + pInfo.GetPropertyType() + "."); } } }
public Boolean IsMainCompositeGenerationInfo(CompositeTypeGenerationInfo typeGenInfo, CILType mainCompositeTypeAttributeType) { return(typeGenInfo.Builder.CustomAttributeData.Any(d => d.Constructor.DeclaringType.Equals(mainCompositeTypeAttributeType))); }
public void AddPublicCompositeGenerationInfo(Assembly assembly, CompositeModel compositeModel, CompositeTypeGenerationInfo typeGenInfo) { this._publicCompositeGenerationInfo.TryAdd(Tuple.Create(assembly, compositeModel), typeGenInfo); //Interlocked.CompareExchange( ref this._firstPublicTypeGenInfo, typeGenInfo, null ); }
protected virtual void EmitEventInvocationMethodCore( EventModel eventModel, CompositeTypeGenerationInfo thisGenerationInfo, CILField eventField, CILTypeBase fieldType, CompositeMethodGenerationInfo invokeMethod, CILMethod eventMethodToInvoke, Action <LocalBuilder, EventInvocation, Type> actualEventInvoking ) { var eventInfo = eventModel.NativeInfo; var il = invokeMethod.IL; var eventLB = il.DeclareLocal(fieldType); var afterNullCheckLabel = il.DefineLabel(); il .EmitLoadThisField(eventField) .EmitStoreLocal(eventLB) .EmitLoadLocal(eventLB) .EmitBranch(BranchType.IF_FALSE, afterNullCheckLabel); EventInvocation invocationStyle; Type exceptionType; this.GetEventInvocationStyle(eventModel, out invocationStyle, out exceptionType); actualEventInvoking(eventLB, invocationStyle, exceptionType); // Throw exception if needed if (EventInvocation.INVOKE_ALL.Equals(invocationStyle)) { // TODO TODO TODO this.EmitThrowIfExceptionListHasAny(invokeMethod, exceptionType.GetConstructor(EXCEPTION_ENUMERABLE_ARRAY).NewWrapper(this.ctx)); } if (!VOID_TYPE.Equals(eventMethodToInvoke.GetReturnType())) { //LocalBuilder amountOfDeadB; //if ( invokeMethod.TryGetLocal( LB_AMOUNT_OF_DEAD_EVENT_INFOS, out amountOfDeadB ) ) //{ // il // .EmitLoadLocal( amountOfDeadB ) // .EmitBranch( BranchType.IF_FALSE, afterNullCheckLabel ); //} LocalBuilder resultB; if (invokeMethod.TryGetLocal(LB_RESULT, out resultB)) { il.EmitLoadLocal(resultB); } var returnLabel = il.DefineLabel(); il .EmitBranch(BranchType.ALWAYS, returnLabel) .MarkLabel(afterNullCheckLabel) .EmitLoadString("The event " + eventInfo.Name + " in ") .EmitReflectionObjectOf(TypeGenerationUtils.CreateTypeForEmitting(eventInfo.DeclaringType.NewWrapper(this.ctx), thisGenerationInfo.GenericArguments, null)) .EmitCall(TO_STRING_METHOD) .EmitLoadString(" is not set.") .EmitCall(STRING_CONCAT_METHOD_3) .EmitThrowNewException(INVALID_OPERATION_EXCEPTION_CTOR_WITH_STRING) .MarkLabel(returnLabel); } else { il.MarkLabel(afterNullCheckLabel); } il.EmitReturn(); }
public Boolean IsMainCompositeGenerationInfo(CompositeTypeGenerationInfo typeGenInfo, Assembly assemblyBeingProcessed) { return(typeGenInfo.CompositeModel.MainCodeGenerationType.Assembly.Equals(assemblyBeingProcessed)); //return Object.ReferenceEquals( this._firstPublicTypeGenInfo, typeGenInfo ); }
protected virtual void EmitPropertyRelatedThings( CompositeCodeGenerationInfo codeGenerationInfo, CompositeTypeGenerationInfo publicCompositeGenInfo, CompositeTypeGenerationInfo thisGenerationInfo, CompositeMethodGenerationInfo thisMethodGenerationInfo, PropertyModel propertyModel, Type genericPropertyMixinType ) { var nPropertyInfo = propertyModel.NativeInfo; var propertyInfo = nPropertyInfo.NewWrapper(this.ctx); if (this.IsCompositeGeneratedProperty(thisGenerationInfo, propertyModel, genericPropertyMixinType)) { var propertyIdx = thisGenerationInfo.AutoGeneratedPropertyInfos.Count; var propertyType = TypeGenerationUtils.CreateTypeForEmitting(propertyInfo.GetPropertyType(), thisGenerationInfo.GenericArguments, null); CILTypeBase fieldType; Action <CILField, MethodIL> readMethod; Action <CILField, MethodIL> read32Method; Action <CILField, MethodIL> writeMethod; Action <CILField, MethodIL> compareExchangeMethodEmitter; this.GetReadAndWriteMethods(propertyType, out readMethod, out read32Method, out writeMethod, out compareExchangeMethodEmitter, out fieldType); // Field: // private <property type or Object> _property<idx>; var propertyField = thisGenerationInfo.Builder.AddField( PROPERTY_FIELD_PREFIX + propertyIdx, fieldType, FieldAttributes.Private ); // Field getter var getter = thisGenerationInfo.Builder.AddMethod( PROPERTY_METHOD_PREFIX + propertyIdx + PROPERTY_GETTER_POSTFIX, MethodAttributes.Private | MethodAttributes.HideBySig, CallingConventions.HasThis); this.EmitPropertyGetterMethod(codeGenerationInfo, propertyModel, publicCompositeGenInfo, thisGenerationInfo, propertyField, propertyType, (CompositeMethodGenerationInfo) new CompositeMethodGenerationInfoImpl(getter, null, null).WithReturnType(propertyType) /*.WithParameters( propertyInfo.GetIndexParameters().Select( p => Tuple.Create( p.ParameterType, p.Attributes ) ) )*/, readMethod); // Field getter for 32-bit processes, if required CILMethod getter32 = null; if (read32Method != null) { getter32 = thisGenerationInfo.Builder.AddMethod( PROPERTY_METHOD_PREFIX + propertyIdx + PROPERTY_GETTER32_POSTFIX, MethodAttributes.Private | MethodAttributes.HideBySig, CallingConventions.HasThis); this.EmitPropertyGetterMethod(codeGenerationInfo, propertyModel, publicCompositeGenInfo, thisGenerationInfo, propertyField, propertyType, (CompositeMethodGenerationInfo) new CompositeMethodGenerationInfoImpl(getter32, null, null).WithReturnType(propertyType) /*.WithParameters( propertyInfo.GetIndexParameters().Select( p => Tuple.Create( p.ParameterType, p.Attributes ) ) )*/, read32Method); } // Field setter var setter = thisGenerationInfo.Builder.AddMethod( PROPERTY_METHOD_PREFIX + propertyIdx + PROPERTY_SETTER_POSTFIX, MethodAttributes.Public | MethodAttributes.HideBySig, // TODO MethodAttributes.Assembly when [InternalsVisibleTo(...)] attribute will be applied to all generated assemblies. CallingConventions.HasThis); this.EmitPropertySetterMethod(codeGenerationInfo, propertyModel, publicCompositeGenInfo, thisGenerationInfo, propertyField, fieldType, propertyType, (CompositeMethodGenerationInfo) new CompositeMethodGenerationInfoImpl(setter, null, null).WithParameters(Enumerable.Repeat(Tuple.Create(propertyType, ParameterAttributes.None), 1)), writeMethod); // Exchange method var exchangeMethod = thisGenerationInfo.Builder.AddMethod( PROPERTY_METHOD_PREFIX + propertyIdx + PROPERTY_EXCHANGE_POSTFIX, MethodAttributes.Private | MethodAttributes.HideBySig, CallingConventions.HasThis); this.EmitPropertyExchangeMethod(propertyModel, thisGenerationInfo, propertyField, fieldType, propertyType, setter, (CompositeMethodGenerationInfo) new CompositeMethodGenerationInfoImpl(exchangeMethod, null, null).WithReturnType(propertyType).WithParameters(Enumerable.Repeat(Tuple.Create(propertyType, ParameterAttributes.None), 1)), writeMethod); // CompareExchange method var compareExchangeMethod = thisGenerationInfo.Builder.AddMethod( PROPERTY_METHOD_PREFIX + propertyIdx + PROPERTY_COMPARE_EXCHANGE_POSTFIX, MethodAttributes.Private | MethodAttributes.HideBySig, CallingConventions.HasThis); this.EmitPropertyCompareExchangeMethod(propertyModel, thisGenerationInfo, propertyField, (CompositeMethodGenerationInfo) new CompositeMethodGenerationInfoImpl(compareExchangeMethod, null, null).WithReturnType(propertyType).WithParameters(Enumerable.Repeat(Tuple.Create(propertyType, ParameterAttributes.None), 2)), compareExchangeMethodEmitter); thisGenerationInfo.AutoGeneratedPropertyInfos.Add(nPropertyInfo, new PropertyGenerationInfo( this.EmitRefMethodForPropertyOrEvent(propertyField, PROPERTY_METHOD_PREFIX + propertyIdx + REF_INVOKER_METHOD_SUFFIX), propertyModel, propertyField, getter, getter32, setter, exchangeMethod, compareExchangeMethod, propertyType )); } if (this.NeedToEmitAdditionalMemberInfo(thisGenerationInfo, propertyInfo.Name, (parent, name) => parent.DeclaredProperties.FirstOrDefault(p => Object.Equals(p.Name, name)))) { // Need to define property if we inherit property directly from interface var name = propertyInfo.Name; if (thisGenerationInfo.RawPropertyInfos.Keys.Any(pInfo => pInfo.Name.Equals(name))) { // We already have property with the same name from different type name = QualifiedName.FromMemberInfo(nPropertyInfo).ToString(); } CILProperty pBuilder; if (!thisGenerationInfo.RawPropertyInfos.TryGetValue(nPropertyInfo, out pBuilder)) { pBuilder = thisGenerationInfo.Builder.AddProperty( name, propertyInfo.Attributes ); thisGenerationInfo.RawPropertyInfos.Add(nPropertyInfo, pBuilder); } if (thisMethodGenerationInfo.MethodFromModel.Equals(propertyInfo.GetMethod)) { pBuilder.GetMethod = thisMethodGenerationInfo.Builder; } else if (thisMethodGenerationInfo.MethodFromModel.Equals(propertyInfo.SetMethod)) { pBuilder.SetMethod = thisMethodGenerationInfo.Builder; } else { throw new InternalException("Found a property, but neither setter nor getter matched the method being emitted. Property is " + propertyInfo + ", method is " + thisMethodGenerationInfo.MethodFromModel + "."); } } }
public Boolean TryAddTypeWithCompositeMethods(CompositeTypeGenerationInfo type) { return(this._typesWithCompositeMethods.TryAdd(type, type)); }
protected override IEnumerable <CILType> GetPublicCompositeAdditionalArguments(CompositeTypeGenerationInfo typeGenInfo) { return(base.GetPublicCompositeAdditionalArguments(typeGenInfo).Concat(ACTION_REF_TYPES_2)); }