public bool PerformTask(pMixinGeneratorPipelineState manager)
        {
            if (manager.CurrentpMixinAttribute.Mixin.IsStaticOrSealed())
            {
                return(true);
            }

            var wrapperClassDeclaration = new TypeDeclaration
            {
                ClassType = ClassType.Class,
                Modifiers = GenerateProtectedMixinMembersWrapperClass.GetMixinTypeModifiers(manager),
                Name      = GetWrapperClassName(manager)
            };


            var simpleType = new SimpleType(
                (Identifier)
                manager.CurrentMixinProtectedMembersWrapperClass.Descendants.OfType <Identifier>().First().Clone());

            wrapperClassDeclaration.BaseTypes.Add(simpleType);

            manager.CurrentMixinAbstractMembersWrapperClass = wrapperClassDeclaration;

            ICodeGeneratorProxy wrapperClass;

            if (manager.CurrentpMixinAttribute.Mixin.GetDefinition().IsAbstract)
            {
                //Protected/Abstract Wrappers will all be created in the external
                //namespace (Mixin is not allowed to be private)
                manager.BaseState.GeneratedCodeSyntaxTree.AddChildTypeDeclaration(
                    wrapperClassDeclaration,
                    new NamespaceDeclaration(ExternalGeneratedNamespaceHelper.GenerateNamespace(manager)));

                wrapperClass = new CodeGeneratorProxy(wrapperClassDeclaration, "");
            }
            else
            {
                //Protected/Abstract Wrappers will all be created as
                //a nested type inside Target (in case Mixin is private)

                wrapperClass = manager.CurrentAutoGeneratedTypeDeclaration.AddNestedType(wrapperClassDeclaration);
            }

            CreateRequirementsDataMemberAndConstructor(wrapperClass, manager);

            ProcessMembers(wrapperClass, manager);

            return(true);
        }
Ejemplo n.º 2
0
        public bool PerformTask(pMixinGeneratorPipelineState manager)
        {
            if (manager.CurrentpMixinAttribute.Mixin.GetDefinition().IsStatic)
            {
                return(true);
            }

            //Create the TypeDeclaration
            var requirementsInterfaceDeclaration =
                new TypeDeclaration
            {
                ClassType = ClassType.Interface,
                Modifiers = Modifiers.Public,
                Name      =
                    "I"
                    + manager.CurrentpMixinAttribute.Mixin.GetNameAsIdentifier()
                    + "Requirements"
            };

            var interfaceNamespace = ExternalGeneratedNamespaceHelper.GenerateNamespace(manager);

            //Save the interface's FullName into the manager
            manager.CurrentMixinRequirementsInterface =
                interfaceNamespace
                .EnsureStartsWith("global::").EnsureEndsWith(".") +
                requirementsInterfaceDeclaration.Name;

            //Add the TypeDeclaration to the Generated Code Tree
            manager.BaseState.GeneratedCodeSyntaxTree.AddChildTypeDeclaration(
                requirementsInterfaceDeclaration, new NamespaceDeclaration(interfaceNamespace));

            //Create the Code Generator
            var requirementInterface = new CodeGeneratorProxy(
                requirementsInterfaceDeclaration, "");

            ProcessAbstractMembers(manager, requirementInterface);

            //Have the Target implement mixinRequirementsInterface
            manager.GeneratedClass.ImplementInterface(manager.CurrentMixinRequirementsInterface);

            return(true);
        }
        /// <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
                );
        }