private void ProcessConstructors(pMixinGeneratorPipelineState manager, CodeGeneratorProxy requirementInterface) { bool hasANonParamaterlessConstructor = manager.CurrentpMixinAttribute.Mixin.GetConstructors() .Any(c => !c.Parameters.Any()); if (hasANonParamaterlessConstructor && !manager.CurrentpMixinAttribute.Mixin.GetDefinition().IsAbstract&& !manager.CurrentpMixinAttribute.ExplicitlyInitializeMixin) { return; } //Update ExplicitlyInitializeMixin - Changed mind, user has to always set //ExplicitlyInitializeMixin to true even if mixin does not have parameterless constructor. //They could be using a custom MixinActivator that uses DI //manager.CurrentpMixinAttribute.ExplicitlyInitializeMixin = true; if (!manager.CurrentpMixinAttribute.ExplicitlyInitializeMixin) { return; } var requiredMixinWrapperType = (manager.CurrentpMixinAttribute.Mixin.GetDefinition().IsAbstract) ? GenerateMixinSpecificAutoGeneratedClass.GetFullNameForChildType( manager, GenerateAbstractMixinMembersWrapperClass.GetWrapperClassName(manager)) : manager.CurrentpMixinAttribute.Mixin.GetOriginalFullNameWithGlobal(); //generate the mixin initialization method requirementInterface.CreateMethod( string.Empty, //no modifier for interface member requiredMixinWrapperType, GetInitializationMethod(manager), new List <KeyValuePair <string, string> >(), ""); }
private string CreateConstructorInitializersForVirtualMemberFunctions( pMixinGeneratorPipelineState manager, ICodeGeneratorProxy wrapperClass) { var proxyMemberHelper = new MasterWrapperCodeGeneratorProxyMemberHelper(wrapperClass, manager.BaseState.Context.TypeResolver.Compilation); var sb = new StringBuilder(); foreach ( var member in manager.CurrentMixinMembers .Select(x => x.Member) .DistinctMembers() .Where(member => !member.IsPrivate && (member.IsVirtual || member.IsOverride || member.IsOverridable))) { if (member is IMethod) { //ProtectedVirtualMethodFunc = (i) => AbstractWrapper.ProtectedVirtualMethod(i); sb.AppendFormat("{0} = ({1}) => {2};", GenerateVirtualMethodFuncName(member), string.Join(",", (member as IMethod).Parameters.Select(x => x.Name)), proxyMemberHelper.GetMethodBodyCallStatement( member as IMethod, (m) => MixinInstanceDataMemberName, (m) => m.IsProtected ? GenerateAbstractMixinMembersWrapperClass.GetProtectedMemberWrapperMemberName(m) : m.Name)); } else if (member is IProperty) { if ((member as IProperty).CanGet) { //PublicVirtaulPropertyFuncGet = () => AbstractWrapper.PublicVirtualProperty; sb.AppendFormat( @"{0}Get = () => {1};", GenerateVirtualMethodFuncName(member), proxyMemberHelper.GetPropertyGetterReturnBodyStatement( member as IProperty, (m) => MixinInstanceDataMemberName, (m) => m.IsProtected ? GenerateAbstractMixinMembersWrapperClass.GetProtectedMemberWrapperMemberName(m) : m.Name)); } if ((member as IProperty).CanSet) { //PublicVirtualPropertySetFunc = (s) => AbstractWrapper.PublicVirtualProperty = s; sb.AppendFormat( @"{0}Set = (value) => {1};", GenerateVirtualMethodFuncName(member), proxyMemberHelper.GetPropertySetterReturnBodyStatement( member as IProperty, (m) => MixinInstanceDataMemberName, (m) => m.IsProtected ? GenerateAbstractMixinMembersWrapperClass.GetProtectedMemberWrapperMemberName(m) : m.Name)); } } } return(sb.ToString()); }
/// <summary> /// Wrap every non-private member in current pMixin with special /// handling for static and virtual members /// </summary> /// <param name="manager"></param> /// <param name="wrapperClass"></param> private void ProcessMembers(pMixinGeneratorPipelineState manager, ICodeGeneratorProxy wrapperClass) { var proxyMemberHelper = new MasterWrapperCodeGeneratorProxyMemberHelper(wrapperClass, manager.BaseState.Context.TypeResolver.Compilation); //Static Members proxyMemberHelper.CreateMembers( manager.CurrentMixinMembers .Select(x => x.Member) .DistinctMembers() .Where(member => member.IsStatic), generateMemberModifier: member => "internal static", baseObjectIdentifierFunc: member => manager.CurrentpMixinAttribute.Mixin.IsStaticOrSealed() ? manager.CurrentpMixinAttribute.Mixin.GetOriginalFullNameWithGlobal() : manager.CurrentMixinAbstractMembersWrapperClass.Name ); //Regular Members proxyMemberHelper.CreateMembers( manager.CurrentMixinMembers .Select(x => x.Member) .DistinctMembers() .Where( member => !member.IsStatic && !(member.IsAbstract && member.IsProtected) && !member.IsOverride && !member.IsOverridable && !member.IsVirtual), generateMemberModifier: member => "internal", baseObjectIdentifierFunc: member => MixinInstanceDataMemberName); //Protected Abstract Members proxyMemberHelper.CreateMembers( manager.CurrentMixinMembers .Select(x => x.Member) .DistinctMembers() .Where(member => (member.IsAbstract || member.IsOverride) && member.IsProtected), generateMemberModifier: member => "internal", baseObjectIdentifierFunc: member => MixinInstanceDataMemberName, baseObjectMemberNameFunc: member => GenerateAbstractMixinMembersWrapperClass.GetProtectedMemberWrapperMemberName(member)); //Virtual Members foreach ( var member in manager.CurrentMixinMembers .Select(x => x.Member) .DistinctMembers() .Where(member => member.IsVirtual || (member.IsOverride || member.IsOverridable && !member.IsProtected))) { #region Virtual Method if (member is IMethod) { //Virtual methods call to the Virtual Method Func wrapperClass.CreateMethod( "internal", member.ReturnType.GetOriginalFullNameWithGlobal(), member.Name, (member as IMethod).Parameters.ToKeyValuePair(), string.Format("{0} {1}({2});", (member as IMethod).GetReturnString(), GenerateVirtualMethodFuncName(member), string.Join(",", (member as IMethod).Parameters.Select(x => x.Name))), (member as IMethod).GetGenericMethodConstraints( manager.BaseState.Context.TypeResolver.Compilation)); } #endregion #region Virtual Property else if (member is IProperty) { wrapperClass.CreateProperty( "internal", member.ReturnType.GetOriginalFullNameWithGlobal(), member.Name, (member as IProperty).CanGet && !(member as IProperty).Getter.IsPrivate ? string.Format("get{{ return {0}(); }}", GenerateVirtualMethodFuncName(member) + "Get") : "", (member as IProperty).CanSet && !(member as IProperty).Setter.IsPrivate ? string.Format("set {{{0}(value); }}", GenerateVirtualMethodFuncName(member) + "Set") : "" ); } #endregion } }
/// <summary> /// Generate code similar to: /// <code> /// <![CDATA[ /// AbstractWrapper _host; /// /// public TargetWrapper(IMixinRequirements host){ _host = host; } /// ]]> /// </code> /// </summary> private void CreateConstructorAndRequirementsInterfaceDataMember( pMixinGeneratorPipelineState manager, ICodeGeneratorProxy wrapperClass) { var mixinInstanceType = ""; #region Assign Mixin Instance Type if (manager.CurrentpMixinAttribute.Mixin.GetDefinition().IsAbstract) { //Abstract Mixin Wrapper is in a different namespace, so we need the fullname mixinInstanceType = ExternalGeneratedNamespaceHelper.GenerateChildClassFullName( manager, GenerateAbstractMixinMembersWrapperClass.GetWrapperClassName(manager)); } else if (manager.CurrentMixinMembers.Any(x => x.Member.IsProtected)) { //Abstract Mixin Wrapper is in the same namespace mixinInstanceType = GenerateAbstractMixinMembersWrapperClass.GetWrapperClassName(manager); } else { mixinInstanceType = manager.CurrentpMixinAttribute.Mixin.GetOriginalFullNameWithGlobal(); } #endregion //add data member wrapperClass.CreateDataMember( /* Can't remember why it was necessary to have a modifier other than public * manager.CurrentpMixinAttribute.Mixin.GetDefinition().IsPublic * ? "public" * : manager.CurrentpMixinAttribute.Mixin.GetDefinition().IsInternal * ? "internal" * : "private" */"public" + " readonly", mixinInstanceType, MixinInstanceDataMemberName); string mixinInstanceInitialization; #region Create Mixin Instance (InitializeMixin / TryActivateMixin if (manager.CurrentpMixinAttribute.ExplicitlyInitializeMixin) { mixinInstanceInitialization = string.Format("(({0}){1}).{2}();", AddMixinConstructorRequirementDependency .GetMixinConstructorRequirement(manager), MixinInstanceDataMemberName.Replace("_", ""), "InitializeMixin"); } else if (manager.CurrentpMixinAttribute.Mixin.GetDefinition().IsSealed) { mixinInstanceInitialization = string.Format("base.TryActivateMixin<{0}>();", manager.CurrentpMixinAttribute.Mixin.GetOriginalFullNameWithGlobal()); } else if (manager.CurrentpMixinAttribute.Mixin.GetDefinition().IsAbstract) { mixinInstanceInitialization = string.Format("base.TryActivateMixin<{0}>({1});", mixinInstanceType, MixinInstanceDataMemberName.Replace("_", "")); } else { mixinInstanceInitialization = string.Format("base.TryActivateMixin<{0}>({1});", GenerateMixinSpecificAutoGeneratedClass.GetFullNameForChildType( manager, GenerateAbstractMixinMembersWrapperClass.GetWrapperClassName(manager)), MixinInstanceDataMemberName.Replace("_", "")); } #endregion var initializeBaseExpression = #region base.Initialize string.Format("base.Initialize( {0}, {1}, new global::{2}<global::{3}>{{ {4} }});", MixinInstanceDataMemberName.Replace("_", ""), MixinInstanceDataMemberName, "System.Collections.Generic.List", typeof(IMixinInterceptor), string.Join(",", manager.CurrentpMixinAttribute.Interceptors .Select(x => x.GenerateActivationExpression()) ) ); #endregion wrapperClass.CreateConstructor( "public", new List <KeyValuePair <string, string> > { new KeyValuePair <string, string>( manager.CurrentMixinRequirementsInterface.EnsureStartsWith("global::"), MixinInstanceDataMemberName.Replace("_", "")) }, constructorInitializer: "", constructorBody: MixinInstanceDataMemberName + " = " + mixinInstanceInitialization + CreateConstructorInitializersForVirtualMemberFunctions(manager, wrapperClass) + initializeBaseExpression ); }