/// <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); }
/// <summary> /// Creates the code type declaration for the given input model element /// </summary> /// <param name="input">The input model element</param> /// <param name="context">The transformation context</param> /// <returns>The code type declaration that will be the transformation result for the given enumeration</returns> public override CodeTypeDeclaration CreateOutput(T input, Transformations.Core.ITransformationContext context) { var declaration = new CodeTypeDeclaration() { Name = GetName(input), IsEnum = true }; var reference = new CodeTypeReference(declaration.Name); CodeDomHelper.SetUserItem(declaration, CodeDomHelper.TypeReferenceKey, reference); CodeDomHelper.SetUserItem(reference, CodeDomHelper.ClassKey, declaration); return(declaration); }
/// <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); } }
protected virtual void ResolveMultipleInheritanceMembers(CodeTypeDeclaration generatedType, HashSet <CodeTypeMember> shadows, CodeConstructor constructor) { var allClasses = generatedType.Closure(GetBaseClasses); var layering = Layering <CodeTypeDeclaration> .CreateLayers(generatedType, c => Edges(c, allClasses)); CodeTypeDeclaration implBaseType = null; int layerIndex; for (layerIndex = layering.Count - 1; layerIndex >= 0; layerIndex--) { var layer = layering[layerIndex]; if (layer.Count == 1 && layer.First() != generatedType && !shadows.IntersectsWith(AllFeatures(layer.First()))) { implBaseType = layer.First(); break; } foreach (var cl in layer) { shadows.UnionWith(Refinements(cl)); } } IEnumerable <CodeTypeDeclaration> inheritedBaseClasses; if (implBaseType != null) { inheritedBaseClasses = layering.Take(layerIndex + 1).SelectMany(s => s); 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); } CodeDomHelper.SetUserItem(generatedType, CodeDomHelper.BaseClassesKey, inheritedBaseClasses); for (int i = layerIndex + 1; i < layering.Count; i++) { foreach (var baseType in layering[i]) { if (baseType != generatedType) { var dependent = baseType.DependentMembers(false); if (dependent != null) { foreach (var inheritedMember in dependent) { RecursivelyAddDependentMembers(generatedType.Members, constructor.Statements, inheritedMember, shadows); } } } } } }