Exemple #1
0
        /// <summary>
        /// Creates a backing field for the given property
        /// </summary>
        /// <param name="property">The code property</param>
        /// <param name="type">The type of the property</param>
        /// <param name="initialValue">The initial value expression for the field</param>
        /// <returns>A reference to the generated backing field</returns>
        public static CodeFieldReferenceExpression CreateBackingField(this CodeMemberProperty property, CodeTypeReference type, CodeExpression initialValue)
        {
            var reference = CodeDomHelper.GetOrCreateUserItem <CodeFieldReferenceExpression>(property, CodeDomHelper.BackingFieldKey);

            if (reference == null)
            {
                var field = new CodeMemberField()
                {
                    Attributes = MemberAttributes.Private,
                    Name       = "_" + property.Name.ToCamelCase(),
                    Type       = type ?? new CodeTypeReference(typeof(object))
                };

                field.WriteDocumentation(string.Format("The backing field for the {0} property", property.Name));

                property.DependentMembers(true).Add(field);

                if (initialValue != null)
                {
                    field.InitExpression = initialValue;
                }

                reference = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), field.Name);
                CodeDomHelper.SetUserItem(property, CodeDomHelper.BackingFieldRefKey, reference);
                CodeDomHelper.SetUserItem(property, CodeDomHelper.BackingFieldKey, field);
            }
            return(reference);
        }
Exemple #2
0
 /// <summary>
 /// Creates a dependency to generate the code for the base classes of the current class
 /// </summary>
 /// <typeparam name="TClass">The model element type from which to generate the base class</typeparam>
 /// <param name="rule">The transformation rule that is used to generate the class</param>
 /// <param name="selector">A function used to select the model element from which to generate a base class</param>
 /// <returns>The transformation rule dependency</returns>
 public ITransformationRuleDependency RequireBaseClass <TClass>(TransformationRuleBase <TClass, CodeTypeDeclaration> rule, Func <T, TClass> selector)
     where TClass : class
 {
     return(Require(rule, selector, (cl, baseClass) =>
     {
         var typeRef = CodeDomHelper.GetOrCreateUserItem <CodeTypeReference>(baseClass, CodeDomHelper.TypeReferenceKey, () => new CodeTypeReference());
         cl.BaseTypes.Add(typeRef);
     }));
 }
Exemple #3
0
        protected virtual void ResolveMultipleInheritanceMembers(CodeTypeDeclaration generatedType, HashSet <CodeTypeMember> shadows, CodeConstructor constructor)
        {
            Func <CodeTypeDeclaration, IEnumerable <CodeTypeDeclaration> > getBaseTypes =
                type => {
                var interfaceType = CodeDomHelper.GetOrCreateUserItem <CodeTypeDeclaration>(type, CodeDomHelper.InterfaceKey);
                if (interfaceType == null)
                {
                    interfaceType = type;
                }
                return(interfaceType.BaseTypes.Cast <CodeTypeReference>().Select(r => r.GetTypeForReference()).Where(c => c != null));
            };
            var layering = Layering <CodeTypeDeclaration> .CreateLayers(generatedType, getBaseTypes);

            CodeTypeDeclaration implBaseType = FindBaseClassAndCreateShadows(generatedType, shadows, layering);
            IEnumerable <CodeTypeDeclaration> inheritedBaseClasses;

            if (implBaseType != null)
            {
                inheritedBaseClasses = implBaseType.Closure(getBaseTypes);
                var implementationRef = new CodeTypeReference();
                implementationRef.BaseType = implBaseType.Name;
                var n = implBaseType.GetReferenceForType().Namespace();
                if (n != null && n.EndsWith(implBaseType.Name))
                {
                    implementationRef.BaseType = n + "." + implBaseType.Name;
                }
                else
                {
                    implementationRef.SetNamespace(n);
                }
                generatedType.BaseTypes.Insert(0, implementationRef);
            }
            else
            {
                inheritedBaseClasses = Enumerable.Empty <CodeTypeDeclaration>();
                AddImplementationBaseClass(generatedType);
            }
            for (int i = layering.Count - 1; i >= 0; i--)
            {
                foreach (var baseType in layering[i])
                {
                    if (!inheritedBaseClasses.Contains(baseType) &&
                        baseType != generatedType &&
                        ShouldContainMembers(generatedType, baseType.GetReferenceForType()))
                    {
                        var dependent = baseType.DependentMembers(false);
                        if (dependent != null)
                        {
                            foreach (var inheritedMember in dependent)
                            {
                                RecursivelyAddDependentMembers(generatedType.Members, constructor.Statements, inheritedMember, shadows);
                            }
                        }
                    }
                }
            }
        }
Exemple #4
0
        private static IEnumerable <CodeTypeDeclaration> GetBaseClasses(CodeTypeDeclaration type)
        {
            var interfaceType = CodeDomHelper.GetOrCreateUserItem <CodeTypeDeclaration>(type, CodeDomHelper.InterfaceKey);

            if (interfaceType == null)
            {
                interfaceType = type;
            }
            return(interfaceType.BaseTypes.Cast <CodeTypeReference>().Select(r => r.GetTypeForReference()).Where(c => c != null));
        }
Exemple #5
0
        protected virtual bool ShouldContainMembers(CodeTypeDeclaration generatedType, CodeTypeDeclaration baseType)
        {
            var baseClasses = CodeDomHelper.GetOrCreateUserItem <IEnumerable <CodeTypeDeclaration> >(generatedType, CodeDomHelper.BaseClassesKey);

            if (baseClasses == null)
            {
                return(true);
            }
            else
            {
                return(!baseClasses.Contains(baseType));
            }
        }
Exemple #6
0
        /// <summary>
        /// Initializes the generated type declaration
        /// </summary>
        /// <param name="input">The input model element</param>
        /// <param name="generatedType">The generated class declaration</param>
        /// <param name="context">The transformation context</param>
        /// <remarks>Can be overridden to refine code generation</remarks>
        public override void Transform(T input, CodeTypeDeclaration generatedType, ITransformationContext context)
        {
            HashSet <CodeTypeMember> shadows;
            var ownShadows = generatedType.Shadows(false);

            if (ownShadows != null)
            {
                shadows = new HashSet <CodeTypeMember>(ownShadows);
            }
            else
            {
                shadows = new HashSet <CodeTypeMember>();
            }
            var constructor = CodeDomHelper.GetOrCreateDefaultConstructor(generatedType, () => new CodeConstructor()
            {
                Attributes = MemberAttributes.Public
            });
            var dependends = generatedType.DependentMembers(false);

            if (dependends != null)
            {
                foreach (var member in dependends)
                {
                    RecursivelyAddDependentMembers(generatedType.Members, constructor.Statements, member, shadows);
                }
            }

            var interfaceDecl = CreateSeparatePublicInterface(input, generatedType);

            if (interfaceDecl != null)
            {
                CodeDomHelper.SetUserItem(generatedType, CodeDomHelper.InterfaceKey, interfaceDecl);
                var dependentTypes = CodeDomHelper.DependentTypes(generatedType, true);
                dependentTypes.Add(interfaceDecl);

                var typeReference = generatedType.GetReferenceForType();
                typeReference.BaseType = interfaceDecl.Name;

                CreateInterfaceMembers(generatedType, interfaceDecl);

                for (int i = generatedType.BaseTypes.Count - 1; i >= 0; i--)
                {
                    var baseTypeRef = generatedType.BaseTypes[i];
                    var baseType    = CodeDomHelper.GetOrCreateUserItem <CodeTypeDeclaration>(baseTypeRef, CodeDomHelper.ClassKey);
                    if (baseType == null)
                    {
                        continue;
                    }
                    interfaceDecl.BaseTypes.Add(baseTypeRef);
                    generatedType.BaseTypes.RemoveAt(i);
                }
                generatedType.BaseTypes.Add(typeReference);

                ResolveMultipleInheritanceMembers(generatedType, shadows, constructor);
            }

            if (constructor.Statements.Count > 0)
            {
                CodeDomHelper.SetUserItem(generatedType, CodeDomHelper.ConstructorKey, constructor);
                generatedType.Members.Add(constructor);
            }
        }