3
using System.Collections.Generic;
4
using System.CodeDom.Compiler;
10
private List<string> lines = new List<string>();
11
private string typeName = "void";
12
private List<string> comments = new List<string>();
13
private List<GenSpec> genSpecs = new List<GenSpec>();
14
private List<string> defaults = new List<string>();
16
private string currentRegion;
18
public static Stanza Read(TextReader rdr)
20
Stanza stanza = new Stanza();
21
string line = rdr.ReadLine();
23
while (line != null && line != "%")
25
if (!line.StartsWith("#"))
28
line = rdr.ReadLine();
31
stanza.ProcessLines();
36
private void AddLine(string line)
38
int count = lines.Count;
40
if (char.IsWhiteSpace(line[0]) && count > 0)
41
lines[count - 1] += line.Trim();
46
private void ProcessLines()
48
foreach (string line in lines)
50
if (line.StartsWith("Type:"))
51
this.typeName = line.Substring(5).Trim();
52
else if (line.StartsWith("///"))
53
this.comments.Add(line);
54
else if (line.StartsWith("Gen:") || line.StartsWith("Assert:"))
55
AddSyntaxElement(line, typeName == "void");
56
else if (line.StartsWith("Gen3:"))
57
AddStandardSyntaxElements(line.Substring(5).Trim());
58
//else if (line.StartsWith("Assert:"))
59
// ProcessAssert(line.Substring(7).Trim());
60
else if (line.StartsWith("Default:"))
61
this.defaults.Add(line.Substring(8).Trim());
63
IssueFormatError(line);
67
private void AddSyntaxElement(string line, bool isVoid)
69
this.genSpecs.Add(new GenSpec(line, typeName == "void"));
72
private void AddStandardSyntaxElements(string element)
74
int arrow = element.IndexOf("=>");
75
if (arrow < 0) IssueFormatError(element);
76
string leftside = element.Substring(0, arrow);
77
string rightside = element.Substring(arrow + 2);
79
string fullname = leftside;
80
string attributes = "";
81
int rbrack = leftside.LastIndexOf("]");
84
attributes = leftside.Substring(0, rbrack + 1);
85
fullname = leftside.Substring(rbrack + 1);
88
string constraint = rightside;
89
if (constraint.StartsWith("return "))
90
constraint = constraint.Substring(7);
91
if (constraint.StartsWith("new "))
92
constraint = constraint.Substring(4);
94
int dot = fullname.IndexOf('.');
95
if (dot < 0) IssueFormatError(element);
96
string name = fullname.Substring(dot + 1);
98
this.typeName = constraint.Substring(0, constraint.IndexOf("("));
99
this.genSpecs.Add(new GenSpec(
100
"Gen: " + leftside + "=>" + rightside));
101
this.genSpecs.Add(new GenSpec(
102
"Gen: " + attributes + "ConstraintFactory." + name + "=>" + rightside));
103
this.genSpecs.Add(new GenSpec(
104
"Gen: " + attributes + "ConstraintExpression." + name + "=>(" + typeName + ")this.Append(" + rightside + ")"));
107
private void IssueFormatError(string line)
109
throw new ArgumentException("Invalid line in spec file" + Environment.NewLine + line);
112
public void Generate(IndentedTextWriter writer, string className, bool isStatic)
114
foreach (GenSpec spec in genSpecs)
116
if (spec.ClassName == className)
118
if (currentRegion == null)
120
//currentRegion = spec.LeftPart;
121
//int dot = currentRegion.IndexOf('.');
122
//if (dot > 0) currentRegion = currentRegion.Substring(dot + 1);
123
currentRegion = spec.MethodName;
124
int lpar = currentRegion.IndexOf('(');
125
if (lpar > 0) currentRegion = currentRegion.Substring(0, lpar);
127
writer.WriteLine("#region " + currentRegion);
132
writer.WriteLineNoTabs("#if NET_2_0");
134
if (spec.ClassName == "Assert")
135
GenerateAssertOverloads(writer, isStatic, spec);
137
GenerateMethod(writer, isStatic, spec);
140
writer.WriteLineNoTabs("#endif");
144
if (currentRegion != null)
146
writer.WriteLine("#endregion");
148
currentRegion = null;
152
private void GenerateMethod(IndentedTextWriter writer, bool isStatic, GenSpec spec)
154
WriteComments(writer);
155
WriteMethodDefinition(writer, isStatic, spec);
158
private void WriteMethodDefinition(IndentedTextWriter writer, bool isStatic, GenSpec spec)
160
if (spec.Attributes != null)
161
writer.WriteLine(spec.Attributes);
164
writer.WriteLine("public static {0} {1}", typeName, spec.MethodName);
166
writer.WriteLine("public {0} {1}", typeName, spec.MethodName);
167
writer.WriteLine("{");
169
writer.WriteLine(spec.IsProperty
170
? "get { return " + spec.RightPart + "; }"
172
? spec.RightPart + ";"
173
: "return " + spec.RightPart + ";" );
175
writer.WriteLine("}");
179
private void WriteComments(IndentedTextWriter writer)
181
foreach (string comment in comments)
182
writer.WriteLine(comment);
185
private void GenerateAssertOverloads(IndentedTextWriter writer, bool isStatic, GenSpec spec)
187
if (!spec.LeftPart.EndsWith(")") || !spec.RightPart.EndsWith(")"))
188
IssueFormatError(spec.ToString());
189
string leftPart = spec.LeftPart.Substring(0, spec.LeftPart.Length - 1);
190
string rightPart = spec.RightPart.Substring(0, spec.RightPart.Length - 1);
192
GenSpec spec1 = new GenSpec(
193
"Gen: " + leftPart + ", string message, params object[] args)=>" + rightPart + " ,message, args)");
194
WriteComments(writer);
195
writer.WriteLine("/// <param name=\"message\">The message to display in case of failure</param>");
196
writer.WriteLine("/// <param name=\"args\">Array of objects to be used in formatting the message</param>");
197
WriteMethodDefinition(writer, isStatic, spec1);
199
GenSpec spec2 = new GenSpec(
200
"Gen: " + leftPart + ", string message)=>" + rightPart + " ,message, null)");
201
WriteComments(writer);
202
writer.WriteLine("/// <param name=\"message\">The message to display in case of failure</param>");
203
WriteMethodDefinition(writer, isStatic, spec2);
205
GenSpec spec3 = new GenSpec(
206
"Gen: " + leftPart + ")=>" + rightPart + " ,null, null)");
207
WriteComments(writer);
208
WriteMethodDefinition(writer, isStatic, spec3);
211
public List<string> Defaults
213
get { return defaults; }