From: Daniel C. \(kzu\) <dca...@us...> - 2004-10-21 20:42:17
|
Update of /cvsroot/mvp-xml/Design/v1/src/CustomTools/XsdToClasses/Extensions In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28388/v1/src/CustomTools/XsdToClasses/Extensions Added Files: ArraysToCollectionsExtension.cs DocumentationExtension.cs FieldsToPropertiesExtension.cs InitializeFieldsExtension.cs Log Message: --- NEW FILE: InitializeFieldsExtension.cs --- #region using using System; using System.CodeDom; #endregion using namespace Mvp.Xml.Design.CustomTools.Extensions { /// <summary> /// Initializes all non-ValueType properties to /// a new instance. /// </summary> internal class InitializeFieldsExtension : ICodeExtension { #region ICodeExtension Members public void Process(System.CodeDom.CodeNamespace code, System.Xml.Schema.XmlSchema schema) { foreach (CodeTypeDeclaration type in code.Types) { foreach (CodeTypeMember member in type.Members) { if (member is CodeMemberField) { CodeMemberField field = (CodeMemberField) member; Type ft = Type.GetType(field.Type.BaseType); // If we have a class we can construct. if (ft == null || (ft.IsClass && ft != typeof(string))) { field.InitExpression = new CodeObjectCreateExpression(field.Type); } } } } } #endregion ICodeExtension Members } } --- NEW FILE: FieldsToPropertiesExtension.cs --- #region using using System; using System.CodeDom; #endregion using namespace Mvp.Xml.Design.CustomTools.Extensions { /// <summary> /// Converts the default public fields into properties backed by a private field. /// </summary> internal class FieldsToPropertiesExtension : ICodeExtension { #region ICodeExtension Members public void Process(System.CodeDom.CodeNamespace code, System.Xml.Schema.XmlSchema schema) { foreach (CodeTypeDeclaration type in code.Types) { if (type.IsClass || type.IsStruct) { // Copy the colletion to an array for safety. We will be // changing this collection. CodeTypeMember[] members = new CodeTypeMember[type.Members.Count]; type.Members.CopyTo(members, 0); foreach (CodeTypeMember member in members) { // Process fields only. if (member is CodeMemberField) { CodeMemberProperty prop = new CodeMemberProperty(); prop.Name = member.Name; prop.Attributes = member.Attributes; prop.Type = ((CodeMemberField)member).Type; // Copy attributes from field to the property. prop.CustomAttributes.AddRange(member.CustomAttributes); member.CustomAttributes.Clear(); // Copy comments from field to the property. prop.Comments.AddRange(member.Comments); member.Comments.Clear(); // Modify the field. member.Attributes = MemberAttributes.Private; Char[] letters = member.Name.ToCharArray(); letters[0] = Char.ToLower(letters[0]); member.Name = String.Concat("_", new string(letters)); prop.HasGet = true; prop.HasSet = true; // Add get/set statements pointing to field. Generates: // return this._fieldname; prop.GetStatements.Add( new CodeMethodReturnStatement( new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), member.Name))); // Generates: // this._fieldname = value; prop.SetStatements.Add( new CodeAssignStatement( new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), member.Name), new CodeArgumentReferenceExpression("value"))); // Finally add the property to the type type.Members.Add(prop); } } } } } #endregion ICodeExtension Members } } --- NEW FILE: ArraysToCollectionsExtension.cs --- #region using using System; using System.CodeDom; using System.Collections; using System.Xml.Schema; #endregion using namespace Mvp.Xml.Design.CustomTools.Extensions { /// <summary> /// Converts array-based properties into collection-based ones, and /// creates a typed <see cref="CollectionBase"/> inherited class for it. /// </summary> internal class ArraysToCollectionsExtension : ICodeExtension { #region ICodeExtension Members public void Process(CodeNamespace code, XmlSchema schema) { // Copy as we will be adding types. CodeTypeDeclaration[] types = new CodeTypeDeclaration[code.Types.Count]; code.Types.CopyTo(types, 0); foreach (CodeTypeDeclaration type in types) { if (type.IsClass || type.IsStruct) { foreach (CodeTypeMember member in type.Members) { // Process fields only, but not those that are System.Xml.* typed. if (member is CodeMemberField && ((CodeMemberField)member).Type.ArrayElementType != null && !((CodeMemberField)member).Type.BaseType.StartsWith("System.Xml")) { CodeMemberField field = (CodeMemberField) member; CodeTypeDeclaration col = GetCollection(code, field.Type.ArrayElementType); // Change field type to collection. field.Type = new CodeTypeReference(col.Name); } } } } } #endregion ICodeExtension Members #region Helper methods private CodeTypeDeclaration GetCollection(CodeNamespace code, CodeTypeReference forType) { string name = forType.BaseType + "Collection"; // Try to locate an existing collection for the same type. foreach (CodeTypeDeclaration td in code.Types) { if (td.Name == name) return td; } CodeTypeDeclaration col = new CodeTypeDeclaration(name); col.Comments.Add(new CodeCommentStatement("<remarks/>", true)); col.BaseTypes.Add(typeof(CollectionBase)); col.Attributes = MemberAttributes.Final | MemberAttributes.Public; // Add method CodeMemberMethod add = new CodeMemberMethod(); add.Comments.Add(new CodeCommentStatement("<remarks/>", true)); add.Attributes = MemberAttributes.Final | MemberAttributes.Public; add.Name = "Add"; add.ReturnType = new CodeTypeReference(typeof(int)); add.Parameters.Add(new CodeParameterDeclarationExpression ( forType, "value")); // Generates: return base.InnerList.Add(value); add.Statements.Add(new CodeMethodReturnStatement ( new CodeMethodInvokeExpression( new CodePropertyReferenceExpression( new CodeBaseReferenceExpression(), "InnerList"), "Add", new CodeExpression[] { new CodeArgumentReferenceExpression("value") } ) ) ); // Add to type. col.Members.Add(add); // Indexer property ('this') CodeMemberProperty indexer = new CodeMemberProperty(); indexer.Comments.Add(new CodeCommentStatement("<remarks/>", true)); indexer.Attributes = MemberAttributes.Final | MemberAttributes.Public; indexer.Name = "Item"; indexer.Type = forType; indexer.Parameters.Add(new CodeParameterDeclarationExpression ( typeof(int), "idx")); indexer.HasGet = true; indexer.HasSet = true; // Generates: return (theType) base.InnerList[idx]; indexer.GetStatements.Add( new CodeMethodReturnStatement ( new CodeCastExpression( forType, new CodeIndexerExpression( new CodePropertyReferenceExpression( new CodeBaseReferenceExpression(), "InnerList"), new CodeExpression[] { new CodeArgumentReferenceExpression("idx") }) ) ) ); // Generates: base.InnerList[idx] = value; indexer.SetStatements.Add( new CodeAssignStatement( new CodeIndexerExpression( new CodePropertyReferenceExpression( new CodeBaseReferenceExpression(), "InnerList"), new CodeExpression[] { new CodeArgumentReferenceExpression("idx") }), new CodeArgumentReferenceExpression("value") ) ); // Add to type. col.Members.Add(indexer); // Add to namespace. code.Types.Add(col); return col; } #endregion Helper methods } } --- NEW FILE: DocumentationExtension.cs --- #region using using System; using System.CodeDom; #endregion using namespace Mvp.Xml.Design.CustomTools.Extensions { /// <summary> /// Adds documentation items as comments on code. /// </summary> internal class DocumentationExtension : ICodeExtension { #region ICodeExtension Members public void Process(System.CodeDom.CodeNamespace code, System.Xml.Schema.XmlSchema schema) { // TODO: add XML comments to code. } #endregion ICodeExtension Members } } |