<#@ template language="c#v3.5" #> <#@ assembly name="System.Core.dll" #> <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="System.Linq" #> <#+ private class Member { public string Type; public string Name; } void GenerateImmutable(string definition) { GenerateImmutable(definition, string.Empty); } void GenerateImmutable(string definition, string comment) { var typeBuilder = new System.Text.StringBuilder(); int indexOfColon = definition.IndexOf(':'); if (indexOfColon == -1) { Error("No colon; expected, eg 'Rectangle: '"); } string ns = ""; string typeName = definition.Split(':')[0]; string members = definition.Split(':')[1]; // // NAMESPACE // int lastNsDot = typeName.LastIndexOf("."); if (lastNsDot != -1) { ns = typeName.Substring(0, lastNsDot); typeName = typeName.Substring(lastNsDot+1); } if (String.IsNullOrEmpty(ns) == false) { typeBuilder.Append("namespace ").AppendLine(ns).AppendLine("{"); } // // TYPE DEFINITION // typeBuilder.Append(" ///").Append(comment).AppendLine(""); typeBuilder.Append(" public partial struct ").AppendLine(typeName).AppendLine(" {"); var memberList = members .Split(';') .Select(x => x.Trim()) .Where(x => x.Length > 0) .Select(x => x.Split(' ')) .Select(arr => new Member { Type = arr[0], Name=arr[1] }) ; // // CONSTRUCTOR // typeBuilder.Append(" ///Create a new ").Append(typeName).Append("").AppendLine(); typeBuilder.Append(" public ").Append(typeName).Append("("); foreach(var memberItem in memberList) { typeBuilder.Append(memberItem.Type).Append(" ").Append(memberItem.Name).Append(","); } typeBuilder.Length = typeBuilder.Length-1; // remove trailing comma typeBuilder.AppendLine(")"); typeBuilder.AppendLine(" {"); foreach(var memberItem in memberList) { typeBuilder .Append(" this.") .Append(memberItem.Name) .Append(" = ") .Append(memberItem.Name) .Append(";") .AppendLine(); } typeBuilder.AppendLine(" }"); // // fields // typeBuilder.AppendLine(" // fields"); foreach(var memberItem in memberList) { typeBuilder .AppendFormat(" public readonly {0} {1};", memberItem.Type, memberItem.Name) .AppendLine(); } typeBuilder.AppendLine(); foreach(var memberItem in memberList) { typeBuilder .AppendLine(" ///mutator for " + memberItem.Name + " property") .AppendFormat(" public {0} With{1}({2} new{1})", typeName, memberItem.Name, memberItem.Type) .AppendLine(" {") .AppendFormat(" var newItem = new {0}(", typeName) ; foreach(var memberItemParam in memberList) { if (memberItem.Name == memberItemParam.Name) { typeBuilder.Append("new").Append(memberItem.Name).Append(","); } else { typeBuilder.Append("this.").Append(memberItemParam.Name).Append(","); } } typeBuilder.Length = typeBuilder.Length-1; // remove trailing comma typeBuilder.AppendLine(");"); typeBuilder.AppendLine(" return newItem;"); typeBuilder.AppendLine(" }"); typeBuilder.AppendLine(); } typeBuilder.AppendLine(" }"); if (String.IsNullOrEmpty(ns) == false) { typeBuilder.AppendLine("}"); } Write(typeBuilder.ToString()); } #>