示例#1
0
        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
                );
        }