~a-schlapsi/nunit-3.0/linux-makefile

« back to all changes in this revision

Viewing changes to tools/src/GenSyntax/Stanza.cs

  • Committer: Charlie Poole
  • Date: 2009-07-17 06:38:34 UTC
  • Revision ID: charlie@nunit.com-20090717063834-frp0jzany1xtbno9
Add Gensyntax tool source code to this project

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
using System;
 
2
using System.IO;
 
3
using System.Collections.Generic;
 
4
using System.CodeDom.Compiler;
 
5
 
 
6
namespace GenSyntax
 
7
{
 
8
    class Stanza
 
9
    {
 
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>();
 
15
 
 
16
        private string currentRegion;
 
17
 
 
18
        public static Stanza Read(TextReader rdr)
 
19
        {
 
20
            Stanza stanza = new Stanza();
 
21
            string line = rdr.ReadLine();
 
22
 
 
23
            while (line != null && line != "%")
 
24
            {
 
25
                if (!line.StartsWith("#"))
 
26
                    stanza.AddLine(line);
 
27
 
 
28
                line = rdr.ReadLine();
 
29
            }
 
30
 
 
31
            stanza.ProcessLines();
 
32
 
 
33
            return stanza;
 
34
        }
 
35
 
 
36
        private void AddLine(string line)
 
37
        {
 
38
            int count = lines.Count;
 
39
 
 
40
            if (char.IsWhiteSpace(line[0]) && count > 0)
 
41
                lines[count - 1] += line.Trim();
 
42
            else
 
43
                lines.Add(line);
 
44
        }
 
45
 
 
46
        private void ProcessLines()
 
47
        {
 
48
            foreach (string line in lines)
 
49
            {
 
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());
 
62
                else
 
63
                    IssueFormatError(line);
 
64
            }
 
65
        }
 
66
 
 
67
        private void AddSyntaxElement(string line, bool isVoid)
 
68
        {
 
69
            this.genSpecs.Add(new GenSpec(line, typeName == "void"));
 
70
        }
 
71
 
 
72
        private void AddStandardSyntaxElements(string element)
 
73
        {
 
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);
 
78
            
 
79
            string fullname = leftside;
 
80
            string attributes = "";
 
81
            int rbrack = leftside.LastIndexOf("]");
 
82
            if (rbrack > 0)
 
83
            {
 
84
                attributes = leftside.Substring(0, rbrack + 1);
 
85
                fullname = leftside.Substring(rbrack + 1);
 
86
            }
 
87
 
 
88
            string constraint = rightside;
 
89
            if (constraint.StartsWith("return "))
 
90
                constraint = constraint.Substring(7);
 
91
            if (constraint.StartsWith("new "))
 
92
                constraint = constraint.Substring(4);
 
93
 
 
94
            int dot = fullname.IndexOf('.');
 
95
            if (dot < 0) IssueFormatError(element);
 
96
            string name = fullname.Substring(dot + 1);
 
97
 
 
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 + ")"));
 
105
        }
 
106
 
 
107
        private void IssueFormatError(string line)
 
108
        {
 
109
            throw new ArgumentException("Invalid line in spec file" + Environment.NewLine + line);
 
110
        }
 
111
 
 
112
        public void Generate(IndentedTextWriter writer, string className, bool isStatic)
 
113
        {
 
114
            foreach (GenSpec spec in genSpecs)
 
115
            {
 
116
                if (spec.ClassName == className)
 
117
                {
 
118
                    if (currentRegion == null)
 
119
                    {
 
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);
 
126
 
 
127
                        writer.WriteLine("#region " + currentRegion);
 
128
                        writer.WriteLine();
 
129
                    }
 
130
 
 
131
                    if (spec.IsGeneric)
 
132
                        writer.WriteLineNoTabs("#if NET_2_0");
 
133
 
 
134
                    if (spec.ClassName == "Assert")
 
135
                        GenerateAssertOverloads(writer, isStatic, spec);
 
136
                    else
 
137
                        GenerateMethod(writer, isStatic, spec);
 
138
 
 
139
                    if (spec.IsGeneric)
 
140
                        writer.WriteLineNoTabs("#endif");
 
141
                }
 
142
            }
 
143
 
 
144
            if (currentRegion != null)
 
145
            {
 
146
                writer.WriteLine("#endregion");
 
147
                writer.WriteLine();
 
148
                currentRegion = null;
 
149
            }
 
150
        }
 
151
 
 
152
        private void GenerateMethod(IndentedTextWriter writer, bool isStatic, GenSpec spec)
 
153
        {
 
154
            WriteComments(writer);
 
155
            WriteMethodDefinition(writer, isStatic, spec);
 
156
        }
 
157
 
 
158
        private void WriteMethodDefinition(IndentedTextWriter writer, bool isStatic, GenSpec spec)
 
159
        {
 
160
            if (spec.Attributes != null)
 
161
                writer.WriteLine(spec.Attributes);
 
162
 
 
163
            if (isStatic)
 
164
                writer.WriteLine("public static {0} {1}", typeName, spec.MethodName);
 
165
            else
 
166
                writer.WriteLine("public {0} {1}", typeName, spec.MethodName);
 
167
            writer.WriteLine("{");
 
168
            writer.Indent++;
 
169
            writer.WriteLine(spec.IsProperty
 
170
                    ? "get { return " + spec.RightPart + "; }"
 
171
                    : typeName == "void"
 
172
                        ? spec.RightPart + ";"
 
173
                        : "return " + spec.RightPart + ";" );
 
174
            writer.Indent--;
 
175
            writer.WriteLine("}");
 
176
            writer.WriteLine();
 
177
        }
 
178
 
 
179
        private void WriteComments(IndentedTextWriter writer)
 
180
        {
 
181
            foreach (string comment in comments)
 
182
                writer.WriteLine(comment);
 
183
        }
 
184
 
 
185
        private void GenerateAssertOverloads(IndentedTextWriter writer, bool isStatic, GenSpec spec)
 
186
        {
 
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);
 
191
 
 
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);
 
198
 
 
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);
 
204
 
 
205
            GenSpec spec3 = new GenSpec(
 
206
                "Gen: " + leftPart + ")=>" + rightPart + " ,null, null)");
 
207
            WriteComments(writer);
 
208
            WriteMethodDefinition(writer, isStatic, spec3);
 
209
        }
 
210
 
 
211
        public List<string> Defaults
 
212
        {
 
213
            get { return defaults; }
 
214
        }
 
215
    }
 
216
}