123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- using System;
- using System.IO;
- using System.Text;
- namespace etoy
- {
- /// <summary>
- /// Static and instance helpers for code generation
- /// </summary>
- class CodeWriter : IDisposable
- {
- #region Settings
- public static string DefaultIndentPrefix = " ";
- public static string DefaultNewLine = "\r\n";
- public string IndentPrefix;
- public string NewLine;
- #endregion
- #region Constructors
- readonly TextWriter w;
- MemoryStream ms = new MemoryStream();
- /// <summary>
- /// Writes to memory, get the code using the "Code" property
- /// </summary>
- public CodeWriter()
- {
- this.IndentPrefix = DefaultIndentPrefix;
- this.NewLine = DefaultNewLine;
- ms = new MemoryStream();
- w = new StreamWriter(ms, Encoding.UTF8);
- //w.NewLine = NewLine; // does not appear to work
- }
- /// <summary>
- /// Writes code directly to file
- /// </summary>
- public CodeWriter(string csPath)
- {
- this.IndentPrefix = DefaultIndentPrefix;
- this.NewLine = DefaultNewLine;
- w = new StreamWriter(csPath, false, Encoding.UTF8);
- }
- /// <summary>
- /// Return the generated code as a string.
- /// </summary>
- public string Code
- {
- get
- {
- w.Flush();
- return Encoding.UTF8.GetString(ms.ToArray());
- }
- }
- public virtual void Flush()
- {
- w.Flush();
- }
- public virtual void Dispose()
- {
- //Console.WriteLine("CodeWriter Dispose.");
- w.Close();
- }
- #endregion
- #region Indentation
- /// <summary>
- /// Level of indentation
- /// </summary>
- public int IndentLevel { get; private set; }
- /// <summary>
- /// Accumulated prefixes over indentations
- /// </summary>
- string prefix = "";
- ///<summary> 增加缩进 </summary>
- public void Indent()
- {
- IndentLevel += 1;
- prefix += IndentPrefix;
- }
- ///<summary> 减少缩进 </summary>
- public void Dedent()
- {
- IndentLevel -= 1;
- if (IndentLevel < 0)
- throw new InvalidOperationException("Indent error");
- prefix = prefix.Substring(0, prefix.Length - IndentPrefix.Length);
- }
- #endregion
- public void Attribute(string attributeConstructor)
- {
- WriteLine("[" + attributeConstructor + "]");
- }
- /// <summary>
- /// Write leading bracket and indent
- /// </summary>
- /// <param name="str">String.</param>
- public void Bracket()
- {
- WriteLine("{");
- Indent();
- }
- /// <summary>
- /// Write leading bracket and indent
- /// </summary>
- /// <param name="str">Line before bracket</param>
- public void Bracket(string str)
- {
- WriteLine(str);
- WriteLine("{");
- Indent();
- }
- public void Using(string str)
- {
- WriteLine("using (" + str + ")");
- WriteLine("{");
- Indent();
- }
- public void IfBracket(string str)
- {
- WriteLine("if (" + str + ")");
- WriteLine("{");
- Indent();
- }
- /// <summary>
- /// Close a previous Bracket and start an "else if"
- /// </summary>
- public void ElseIfBracket(string str)
- {
- WriteLine("}");
- Dedent();
- WriteLine("else if (" + str + ")");
- WriteLine("{");
- Indent();
- }
- /// <summary>
- /// Close a previous IfBracket and start an else
- /// </summary>
- public void ElseBracket()
- {
- Dedent();
- WriteLine("}");
- WriteLine("else");
- WriteLine("{");
- Indent();
- }
- public void WhileBracket(string str)
- {
- WriteLine("while (" + str + ")");
- WriteLine("{");
- Indent();
- }
- public void Switch(string str)
- {
- Bracket("switch (" + str + ")");
- Indent();
- }
- public void SwitchEnd()
- {
- Dedent();
- EndBracket();
- }
- public void Case(string str)
- {
- Dedent();
- WriteLine("case " + str + ":");
- Indent();
- }
- public void Case(int id)
- {
- Dedent();
- WriteLine("case " + id + ":");
- Indent();
- }
- public void CaseDefault()
- {
- Dedent();
- WriteLine("default:");
- Indent();
- }
- public void ForeachBracket(string str)
- {
- WriteLine("foreach (" + str + ")");
- WriteLine("{");
- Indent();
- }
- public void EndBracket()
- {
- Dedent();
- WriteLine("}");
- }
- public void EndBracketSpace()
- {
- Dedent();
- WriteLine("}");
- WriteLine();
- }
- /// <summary>
- /// Writes a singe line indented.
- /// </summary>
- public void WriteIndent(string str)
- {
- WriteLine(IndentPrefix + str);
- }
- public void Write(string line, bool needPrefix = false)
- {
- if (needPrefix)
- w.Write(prefix);
- w.Write(line);
- }
- public void OnlyWriteLine(string line, bool needPrefix = false)
- {
- if (needPrefix)
- w.Write(prefix);
- w.WriteLine(line);
- }
- public void WriteLine(string line)
- {
- foreach (string l in SplitTrimEnd(line))
- {
- string pl = (prefix + l).TrimEnd(' ', '\t');
- w.Write(pl + NewLine);
- }
- }
- public void WritePragma(string line)
- {
- w.Write("#pragma " + line + NewLine);
- }
- public void WriteLine()
- {
- WriteLine("");
- }
- #region Region
- public void BeginRegion(string regionName)
- {
- WriteLine($"#region {regionName}");
- }
- public void EndRegion()
- {
- WriteLine("#endregion");
- }
- #endregion
- #region Comments
- public void Comment(string code)
- {
- if (code == null)
- return;
- const string commentPrefix = "// ";
- prefix += commentPrefix;
- foreach (string line in SplitTrimEnd(code))
- WriteLine(line);
- prefix = prefix.Substring(0, prefix.Length - commentPrefix.Length);
- }
- /// <summary>
- /// 增加注释
- /// </summary>
- /// <param name="summary"></param>
- public void Summary(string summary)
- {
- if (summary == null || summary.Trim() == "")
- return;
- string[] lines = SplitTrimEnd(summary);
- if (lines.Length == 1)
- {
- WriteLine("/// <summary> " + lines[0] + " </summary>");
- return;
- }
- prefix += "/// ";
- WriteLine("<summary>");
- foreach (string line in lines)
- WriteLine("<para>" + line + "</para>");
- WriteLine("</summary>");
- prefix = prefix.Substring(0, prefix.Length - 4);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="name"></param>
- /// <param name="description"></param>
- public void SummaryParam(string name, string description)
- {
- if (name == null || description == null)
- return;
- if (string.IsNullOrEmpty(name) || IsNullOrWhiteSpace(description))
- return;
- string[] lines = SplitTrimEnd(description);
- if (lines.Length == 1)
- {
- WriteLine("/// <param name=\"" + name + "\">" + lines[0] + "</summary>");
- return;
- }
- prefix += "/// ";
- WriteLine("<param name=\"" + name + "\">");
- foreach (string line in lines)
- WriteLine("<para>" + line + "</para>");
- WriteLine("</param>");
- prefix = prefix.Substring(0, prefix.Length - 4);
- }
- #endregion
- /// <summary>
- /// Split string into an array of lines and trim whitespace at the end
- /// </summary>
- static string[] SplitTrimEnd(string text)
- {
- var lines = text.Replace("\r\n", "\n").Replace('\r', '\n').Split('\n');
- for (int n = 0; n < lines.Length; n++)
- lines[n] = lines[n].TrimEnd(' ', '\t');
- return lines;
- }
- private bool IsNullOrWhiteSpace(string value)
- {
- if (value != null)
- {
- for (int i = 0; i < value.Length; i++)
- {
- if (!char.IsWhiteSpace(value[i]))
- {
- return false;
- }
- }
- }
- return true;
- }
- public virtual void Clear()
- {
- ms.SetLength(0);
- }
- }
- }
|