protected KeyValuePair<string, CodeBlock> writeProperty(FileStreamWriter text, WcfCleanerOptions options, CodeClass codeClass, KeyValuePair<string, CodeBlock> kv) { var prop = (CodeProperty)kv.Value; if (options.AutoSetSpecified && codeClass.Properties.ContainsKey(kv.Key + "Specified")) { text.WriteLine("\t\tprotected ", prop.Type, " _", kv.Key, ";") .WriteLine() .WriteLine(prop.Headings) .WriteLine("\t\tpublic ", prop.Type, " ", kv.Key) .WriteLine("\t\t{") .WriteLine("\t\t\tget { return _", kv.Key, "; }") .WriteLine("\t\t\tset {") .WriteLine("\t\t\t\t_", kv.Key, " = value;") .WriteLine("\t\t\t\t", kv.Key, "Specified = true;") .WriteLine("\t\t\t}") .WriteLine("\t\t}"); } else { text.WriteLine(prop.Headings) .WriteLine("\t\tpublic ", prop.Type, " ", kv.Key, " { get; set; }"); } return kv; }
protected void parseCodeBlocks(string src, CodeClass codeClass, HashSet<string> usingNamespaces, WcfCleanerOptions options) { //var chunks = RegexHelper.MatchesGeneric(@"(public|protected)? ?(event)? ?([\w_\.\[\]\<\>]+) ([\w_\$\<\>]+)(\()?", src); /* TODO: If method is private, generated code contains no protection statement - not public/protected/private, just omitting it, meaning the remaining pattern is entirely contextual - we can't just search the broad way below, we have to count curly braces throughout the entire class to identify these. Semicolon and curly brace counting could do to find miscellaneous unhandled extras in classes as a catchall... */ var chunks = RegexHelper.MatchesGeneric(@"(public|protected) (event)? ?([\w_\.\[\]\<\>]+) ([\w_\$\<\>]+)(\()?", src); int index = 0; foreach (var chunkMatch in chunks) { int prevIndex = index; index = chunkMatch.Index; var groups = chunkMatch.Groups.Cast<Group>().ToArray(); // event if (groups[2].Value == "event") { string chunk = parseChunk(index, prevIndex, src, usingNamespaces, options); codeClass.Chunks.Add(chunk); continue; } if (groups[5].Value == "(") { string chunk = parseChunk(index, prevIndex, src, usingNamespaces, options); codeClass.Chunks.Add(chunk); continue; } string name = groups[4].Value; var prop = parseProperty(groups[3].Value, name, index, prevIndex, src, usingNamespaces, options); codeClass.Properties.Add(name, prop); } }
protected void writeClass(FileStreamWriter text, WcfCleanerOptions options, CodeClass codeClass) { text.WriteLine(codeClass.Headings) .WriteLine("\tpublic class ", codeClass.Name, " ", codeClass.Inheritance) .WriteLine("\t{"); int written = 0; codeClass.Chunks.FencePostBefore( chunk => { text.WriteLine(); }, chunk => { written++; writeCodeChunk(text, chunk); } ); if (written > 0) { foreach (var kv in codeClass.Properties) { text.WriteLine(); writeProperty(text, options, codeClass, kv); } } else { codeClass.Properties.FencePostBefore( kv => { text.WriteLine(); }, kv => { writeProperty(text, options, codeClass, kv); } ); } text.WriteLine("\t}"); }
protected List<CodeClass> parseClasses(string src, int namespaceIndex, HashSet<string> usingNamespaces, WcfCleanerOptions options) { var classes = new List<CodeClass>(); var classMatches = RegexHelper.MatchesGeneric("public partial class ([^ ]+) ([^{]+)? ?{", src.Substring(namespaceIndex)); int index = namespaceIndex; foreach(var classMatch in classMatches) { int prevIndex = index; // 4) Parse forward until finding public partial class ____ index = classMatch.Index + namespaceIndex; // 5) Gather preceding remarks and attributes string headings = gatherHeadings(src, index, prevIndex, usingNamespaces, options); // 6) Save class name, inheritance var groups = classMatch.Groups; var className = groups[1].Value; var inheritance = groups[2].Value; // TODO: Cleanup namespaces in inheritance, get rid of unnecessary : object var codeClass = new CodeClass { Headings = headings, Name = className, Inheritance = inheritance }; // Count open/closing curly braces until end of class int startClass = 0; int endClass = 0; countCodeBraces(src, index, out startClass, out endClass); string classBody = src.Substring(startClass, endClass - startClass); // 7) Begin property/method loop parseCodeBlocks(classBody, codeClass, usingNamespaces, options); index = endClass + 1; classes.Add(codeClass); } return classes; }