From d35e7f8feb622c692b23ca8c5757fce3b3483bd1 Mon Sep 17 00:00:00 2001 From: mrward Date: Fri, 3 Sep 2010 17:12:18 +0100 Subject: [PATCH] Move common code from IronPython and IronRuby code builder class to Scripting project. --- .../Project/Src/PythonCodeBuilder.cs | 150 +----------- .../Test/Designer/PythonCodeBuilderTests.cs | 165 +------------ .../Project/Src/RubyCodeBuilder.cs | 185 +-------------- .../Test/Designer/RubyCodeBuilderTests.cs | 196 --------------- .../Project/ICSharpCode.Scripting.csproj | 1 + .../Project/Src/ScriptingCodeBuilder.cs | 185 +++++++++++++++ .../Designer/ScriptingCodeBuilderTests.cs | 223 ++++++++++++++++++ .../Test/ICSharpCode.Scripting.Tests.csproj | 1 + 8 files changed, 421 insertions(+), 685 deletions(-) create mode 100644 src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingCodeBuilder.cs create mode 100644 src/AddIns/BackendBindings/Scripting/Test/Designer/ScriptingCodeBuilderTests.cs diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeBuilder.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeBuilder.cs index d43bfe4635..d5441207bf 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeBuilder.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeBuilder.cs @@ -8,14 +8,12 @@ using System; using System.ComponentModel; using System.Text; +using ICSharpCode.Scripting; namespace ICSharpCode.PythonBinding { - public class PythonCodeBuilder + public class PythonCodeBuilder : ScriptingCodeBuilder { - StringBuilder codeBuilder = new StringBuilder(); - string indentString = "\t"; - int indent; bool insertedCreateComponentsContainer; public PythonCodeBuilder() @@ -23,75 +21,8 @@ namespace ICSharpCode.PythonBinding } public PythonCodeBuilder(int initialIndent) + : base(initialIndent) { - indent = initialIndent; - } - - /// - /// Gets or sets the string used for indenting. - /// - public string IndentString { - get { return indentString; } - set { indentString = value; } - } - - /// - /// Returns the code. - /// - public override string ToString() - { - return codeBuilder.ToString(); - } - - /// - /// Returns true if the previous line contains code. If the previous line contains a - /// comment or is an empty line then it returns false; - /// - public bool PreviousLineIsCode { - get { - string code = ToString(); - int end = MoveToPreviousLineEnd(code, code.Length - 1); - if (end > 0) { - int start = MoveToPreviousLineEnd(code, end); - string line = code.Substring(start + 1, end - start).Trim(); - return (line.Length > 0) && (!line.Trim().StartsWith("#")); - } - return false; - } - } - - /// - /// Appends text at the end of the current code. - /// - public void Append(string text) - { - codeBuilder.Append(text); - } - - /// - /// Appends carriage return and line feed to the existing text. - /// - public void AppendLine() - { - Append("\r\n"); - } - - /// - /// Appends the text indented. - /// - public void AppendIndented(string text) - { - codeBuilder.Append(GetIndentString()); - codeBuilder.Append(text); - } - - /// - /// Inserts a new line at the start of the code before everything else. - /// - public void InsertIndentedLine(string text) - { - text = GetIndentString() + text + "\r\n"; - codeBuilder.Insert(0, text, 1); } /// @@ -105,81 +36,10 @@ namespace ICSharpCode.PythonBinding public void InsertCreateComponentsContainer() { if (!insertedCreateComponentsContainer) { - InsertIndentedLine("self._components = " + typeof(Container).FullName + "()"); + string text = String.Format("self._components = {0}()", typeof(Container).FullName); + InsertIndentedLine(text); insertedCreateComponentsContainer = true; } } - - /// - /// Inserts the text with a carriage return and newline at the end. - /// - public void AppendIndentedLine(string text) - { - AppendIndented(text + "\r\n"); - } - - public void AppendLineIfPreviousLineIsCode() - { - if (PreviousLineIsCode) { - codeBuilder.AppendLine(); - } - } - - /// - /// Appends the specified text to the end of the previous line. - /// - public void AppendToPreviousLine(string text) - { - string code = ToString(); - int end = MoveToPreviousLineEnd(code, code.Length - 1); - if (end > 0) { - codeBuilder.Insert(end + 1, text); - } - } - - public void IncreaseIndent() - { - indent++; - } - - public void DecreaseIndent() - { - indent--; - } - - public int Indent { - get { return indent; } - } - - /// - /// Gets the length of the current code string. - /// - public int Length { - get { return codeBuilder.Length; } - } - - string GetIndentString() - { - StringBuilder currentIndentString = new StringBuilder(); - for (int i = 0; i < indent; ++i) { - currentIndentString.Append(indentString); - } - return currentIndentString.ToString(); - } - - /// - /// Returns the index of the end of the previous line. - /// - /// This is the index to start working backwards from. - int MoveToPreviousLineEnd(string code, int index) - { - while (index >= 0) { - if (code[index] == '\r') { - return index - 1; - } - --index; - } - return -1; - } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonCodeBuilderTests.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonCodeBuilderTests.cs index 109cc3ee52..3a952b1b0a 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonCodeBuilderTests.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonCodeBuilderTests.cs @@ -23,93 +23,6 @@ namespace PythonBinding.Tests.Designer codeBuilder.IndentString = "\t"; } - [Test] - public void AppendNewLine() - { - codeBuilder.AppendLine(); - Assert.AreEqual("\r\n", codeBuilder.ToString()); - } - - [Test] - public void AppendText() - { - codeBuilder.Append("abc"); - Assert.AreEqual("abc", codeBuilder.ToString()); - } - - [Test] - public void AppendIndentedText() - { - codeBuilder.IncreaseIndent(); - codeBuilder.AppendIndented("abc"); - Assert.AreEqual("\tabc", codeBuilder.ToString()); - } - - [Test] - public void IncreaseIndentTwice() - { - codeBuilder.IncreaseIndent(); - codeBuilder.IncreaseIndent(); - codeBuilder.AppendIndented("abc"); - Assert.AreEqual("\t\tabc", codeBuilder.ToString()); - } - - [Test] - public void DecreaseIndent() - { - codeBuilder.IncreaseIndent(); - codeBuilder.AppendIndented("abc"); - codeBuilder.AppendLine(); - codeBuilder.DecreaseIndent(); - codeBuilder.AppendIndented("abc"); - Assert.AreEqual("\tabc\r\nabc", codeBuilder.ToString()); - } - - [Test] - public void AppendIndentedLine() - { - codeBuilder.IncreaseIndent(); - codeBuilder.AppendIndentedLine("abc"); - Assert.AreEqual("\tabc\r\n", codeBuilder.ToString()); - } - - [Test] - public void InitialIndentWhenCodeBuilderCreatedIsZero() - { - Assert.AreEqual(0, codeBuilder.Indent); - } - - [Test] - public void IncreaseIndentByOne() - { - codeBuilder.IncreaseIndent(); - Assert.AreEqual(1, codeBuilder.Indent); - } - - [Test] - public void LengthAfterAddingText() - { - codeBuilder.Append("abc"); - Assert.AreEqual(3, codeBuilder.Length); - } - - [Test] - public void IndentPassedToConstructor() - { - codeBuilder = new PythonCodeBuilder(2); - codeBuilder.AppendIndented("abc"); - Assert.AreEqual("\t\tabc", codeBuilder.ToString()); - } - - [Test] - public void InsertIndentedLine() - { - codeBuilder.IncreaseIndent(); - codeBuilder.AppendIndentedLine("def"); - codeBuilder.InsertIndentedLine("abc"); - Assert.AreEqual("\tabc\r\n\tdef\r\n", codeBuilder.ToString()); - } - /// /// Check that the "self._components = System.ComponentModel.Container()" line is generated /// the once and before any other lines of code. @@ -123,85 +36,11 @@ namespace PythonBinding.Tests.Designer codeBuilder.InsertCreateComponentsContainer(); codeBuilder.InsertCreateComponentsContainer(); - string expectedCode = " self._components = System.ComponentModel.Container()\r\n" + + string expectedCode = + " self._components = System.ComponentModel.Container()\r\n" + " self._listView = System.Windows.Forms.ListView()\r\n"; Assert.AreEqual(expectedCode, codeBuilder.ToString()); } - - [Test] - public void PreviousLineIsEmptyNewLine() - { - codeBuilder.AppendLine(); - Assert.IsFalse(codeBuilder.PreviousLineIsCode); - } - - [Test] - public void PreviousLineIsComment() - { - codeBuilder.AppendIndentedLine("# comment"); - Assert.IsFalse(codeBuilder.PreviousLineIsCode); - } - - [Test] - public void PreviousLineIsNotEmptyNewLine() - { - codeBuilder.AppendIndentedLine("abc"); - Assert.IsTrue(codeBuilder.PreviousLineIsCode); - } - - [Test] - public void PreviousLineDoesNotExist() - { - Assert.IsFalse(codeBuilder.PreviousLineIsCode); - } - - [Test] - public void PreviousLineIsEmptyAndCurrentLineHasText() - { - codeBuilder.AppendLine(); - codeBuilder.Append("abc"); - Assert.IsFalse(codeBuilder.PreviousLineIsCode); - } - - [Test] - public void PreviousLineIsMadeUpOfWhiteSpace() - { - codeBuilder.AppendIndentedLine(" \t "); - Assert.IsFalse(codeBuilder.PreviousLineIsCode); - } - - [Test] - public void TwoLinesWithPreviousLineMadeUpOfWhiteSpace() - { - codeBuilder.AppendIndentedLine("1st"); - codeBuilder.AppendIndentedLine(" \t "); - Assert.IsFalse(codeBuilder.PreviousLineIsCode); - } - - [Test] - public void TwoLinesWithPreviousEmptyLine() - { - codeBuilder.AppendIndentedLine("1st"); - codeBuilder.AppendLine(); - codeBuilder.Append("abc"); - Assert.IsFalse(codeBuilder.PreviousLineIsCode); - } - - [Test] - public void TwoLinesWithNoPreviousEmptyLine() - { - codeBuilder.AppendIndentedLine("First"); - codeBuilder.AppendIndentedLine("Second"); - Assert.IsTrue(codeBuilder.PreviousLineIsCode); - } - - [Test] - public void AppendToPreviousLine() - { - codeBuilder.AppendIndentedLine("abc"); - codeBuilder.AppendToPreviousLine(" # comment"); - Assert.AreEqual("abc # comment\r\n", codeBuilder.ToString()); - } } } diff --git a/src/AddIns/BackendBindings/Ruby/RubyBinding/Project/Src/RubyCodeBuilder.cs b/src/AddIns/BackendBindings/Ruby/RubyBinding/Project/Src/RubyCodeBuilder.cs index 031accf869..592c60d17c 100644 --- a/src/AddIns/BackendBindings/Ruby/RubyBinding/Project/Src/RubyCodeBuilder.cs +++ b/src/AddIns/BackendBindings/Ruby/RubyBinding/Project/Src/RubyCodeBuilder.cs @@ -8,132 +8,19 @@ using System; using System.ComponentModel; using System.Text; +using ICSharpCode.Scripting; namespace ICSharpCode.RubyBinding { - public class RubyCodeBuilder + public class RubyCodeBuilder : ScriptingCodeBuilder { - StringBuilder codeBuilder = new StringBuilder(); - string indentString = "\t"; - int indent; - bool insertedCreateComponentsContainer; - public RubyCodeBuilder() { } public RubyCodeBuilder(int initialIndent) + : base(initialIndent) { - indent = initialIndent; - } - - /// - /// Gets or sets the string used for indenting. - /// - public string IndentString { - get { return indentString; } - set { indentString = value; } - } - - /// - /// Returns the code. - /// - public override string ToString() - { - return codeBuilder.ToString(); - } - - /// - /// Returns true if the previous line contains code. If the previous line contains a - /// comment or is an empty line then it returns false; - /// - public bool PreviousLineIsCode { - get { - string code = ToString(); - int end = MoveToPreviousLineEnd(code, code.Length - 1); - if (end > 0) { - int start = MoveToPreviousLineEnd(code, end); - string line = code.Substring(start + 1, end - start).Trim(); - return (line.Length > 0) && (!line.Trim().StartsWith("#")); - } - return false; - } - } - - public string GetPreviousLine() - { - string code = ToString(); - int end = MoveToPreviousLineEnd(code, code.Length - 1); - if (end > 0) { - int start = MoveToPreviousLineEnd(code, end); - return code.Substring(start + 1, end - start); - } - return String.Empty; - } - - /// - /// Appends text at the end of the current code. - /// - public void Append(string text) - { - codeBuilder.Append(text); - } - - /// - /// Appends carriage return and line feed to the existing text. - /// - public void AppendLine() - { - Append("\r\n"); - } - - /// - /// Appends the text indented. - /// - public void AppendIndented(string text) - { - codeBuilder.Append(GetIndentString()); - codeBuilder.Append(text); - } - - /// - /// Inserts a new line at the start of the code before everything else. - /// - public void InsertIndentedLine(string text) - { - text = GetIndentString() + text + "\r\n"; - codeBuilder.Insert(0, text, 1); - } - - /// - /// Inserts the following line of code before all the other lines of code: - /// - /// "self._components = System.ComponentModel.Container()" - /// - /// This line will only be inserted once. Multiple calls to this method will only result in one - /// line of code being inserted. - /// - public void InsertCreateComponentsContainer() - { - if (!insertedCreateComponentsContainer) { - InsertIndentedLine("self._components = " + typeof(Container).FullName + "()"); - insertedCreateComponentsContainer = true; - } - } - - /// - /// Inserts the text with a carriage return and newline at the end. - /// - public void AppendIndentedLine(string text) - { - AppendIndented(text + "\r\n"); - } - - public void AppendLineIfPreviousLineIsCode() - { - if (PreviousLineIsCode) { - codeBuilder.AppendLine(); - } } public void AppendLineIfPreviousLineIsEndStatement() @@ -142,70 +29,6 @@ namespace ICSharpCode.RubyBinding if (previousLine.Equals("end", StringComparison.InvariantCultureIgnoreCase)) { AppendLine(); } - } - - /// - /// Appends the specified text to the end of the previous line. - /// - public void AppendToPreviousLine(string text) - { - string code = ToString(); - int end = MoveToPreviousLineEnd(code, code.Length - 1); - if (end > 0) { - codeBuilder.Insert(end + 1, text); - } - } - - public void TrimEnd() - { - string trimmedText = codeBuilder.ToString().TrimEnd(); - codeBuilder = new StringBuilder(); - codeBuilder.Append(trimmedText); - } - - public void IncreaseIndent() - { - indent++; - } - - public void DecreaseIndent() - { - indent--; - } - - public int Indent { - get { return indent; } - } - - /// - /// Gets the length of the current code string. - /// - public int Length { - get { return codeBuilder.Length; } - } - - string GetIndentString() - { - StringBuilder currentIndentString = new StringBuilder(); - for (int i = 0; i < indent; ++i) { - currentIndentString.Append(indentString); - } - return currentIndentString.ToString(); - } - - /// - /// Returns the index of the end of the previous line. - /// - /// This is the index to start working backwards from. - int MoveToPreviousLineEnd(string code, int index) - { - while (index >= 0) { - if (code[index] == '\r') { - return index - 1; - } - --index; - } - return -1; - } + } } } diff --git a/src/AddIns/BackendBindings/Ruby/RubyBinding/Test/Designer/RubyCodeBuilderTests.cs b/src/AddIns/BackendBindings/Ruby/RubyBinding/Test/Designer/RubyCodeBuilderTests.cs index 4095ebd8ea..98c7bfe18e 100644 --- a/src/AddIns/BackendBindings/Ruby/RubyBinding/Test/Designer/RubyCodeBuilderTests.cs +++ b/src/AddIns/BackendBindings/Ruby/RubyBinding/Test/Designer/RubyCodeBuilderTests.cs @@ -23,187 +23,6 @@ namespace RubyBinding.Tests.Designer codeBuilder.IndentString = "\t"; } - [Test] - public void AppendNewLine() - { - codeBuilder.AppendLine(); - Assert.AreEqual("\r\n", codeBuilder.ToString()); - } - - [Test] - public void AppendText() - { - codeBuilder.Append("abc"); - Assert.AreEqual("abc", codeBuilder.ToString()); - } - - [Test] - public void AppendIndentedText() - { - codeBuilder.IncreaseIndent(); - codeBuilder.AppendIndented("abc"); - Assert.AreEqual("\tabc", codeBuilder.ToString()); - } - - [Test] - public void IncreaseIndentTwice() - { - codeBuilder.IncreaseIndent(); - codeBuilder.IncreaseIndent(); - codeBuilder.AppendIndented("abc"); - Assert.AreEqual("\t\tabc", codeBuilder.ToString()); - } - - [Test] - public void DecreaseIndent() - { - codeBuilder.IncreaseIndent(); - codeBuilder.AppendIndented("abc"); - codeBuilder.AppendLine(); - codeBuilder.DecreaseIndent(); - codeBuilder.AppendIndented("abc"); - Assert.AreEqual("\tabc\r\nabc", codeBuilder.ToString()); - } - - [Test] - public void AppendIndentedLine() - { - codeBuilder.IncreaseIndent(); - codeBuilder.AppendIndentedLine("abc"); - Assert.AreEqual("\tabc\r\n", codeBuilder.ToString()); - } - - [Test] - public void InitialIndentWhenCodeBuilderCreatedIsZero() - { - Assert.AreEqual(0, codeBuilder.Indent); - } - - [Test] - public void IncreaseIndentByOne() - { - codeBuilder.IncreaseIndent(); - Assert.AreEqual(1, codeBuilder.Indent); - } - - [Test] - public void LengthAfterAddingText() - { - codeBuilder.Append("abc"); - Assert.AreEqual(3, codeBuilder.Length); - } - - [Test] - public void IndentPassedToConstructor() - { - codeBuilder = new RubyCodeBuilder(2); - codeBuilder.AppendIndented("abc"); - Assert.AreEqual("\t\tabc", codeBuilder.ToString()); - } - - [Test] - public void InsertIndentedLine() - { - codeBuilder.IncreaseIndent(); - codeBuilder.AppendIndentedLine("def"); - codeBuilder.InsertIndentedLine("abc"); - Assert.AreEqual("\tabc\r\n\tdef\r\n", codeBuilder.ToString()); - } - - /// - /// Check that the "self._components = System.ComponentModel.Container()" line is generated - /// the once and before any other lines of code. - /// - [Test] - public void AppendCreateComponentsContainerTwice() - { - codeBuilder.IndentString = " "; - codeBuilder.IncreaseIndent(); - codeBuilder.AppendIndentedLine("self._listView = System.Windows.Forms.ListView()"); - codeBuilder.InsertCreateComponentsContainer(); - codeBuilder.InsertCreateComponentsContainer(); - - string expectedCode = " self._components = System.ComponentModel.Container()\r\n" + - " self._listView = System.Windows.Forms.ListView()\r\n"; - - Assert.AreEqual(expectedCode, codeBuilder.ToString()); - } - - [Test] - public void PreviousLineIsEmptyNewLine() - { - codeBuilder.AppendLine(); - Assert.IsFalse(codeBuilder.PreviousLineIsCode); - } - - [Test] - public void PreviousLineIsComment() - { - codeBuilder.AppendIndentedLine("# comment"); - Assert.IsFalse(codeBuilder.PreviousLineIsCode); - } - - [Test] - public void PreviousLineIsNotEmptyNewLine() - { - codeBuilder.AppendIndentedLine("abc"); - Assert.IsTrue(codeBuilder.PreviousLineIsCode); - } - - [Test] - public void PreviousLineDoesNotExist() - { - Assert.IsFalse(codeBuilder.PreviousLineIsCode); - } - - [Test] - public void PreviousLineIsEmptyAndCurrentLineHasText() - { - codeBuilder.AppendLine(); - codeBuilder.Append("abc"); - Assert.IsFalse(codeBuilder.PreviousLineIsCode); - } - - [Test] - public void PreviousLineIsMadeUpOfWhiteSpace() - { - codeBuilder.AppendIndentedLine(" \t "); - Assert.IsFalse(codeBuilder.PreviousLineIsCode); - } - - [Test] - public void TwoLinesWithPreviousLineMadeUpOfWhiteSpace() - { - codeBuilder.AppendIndentedLine("1st"); - codeBuilder.AppendIndentedLine(" \t "); - Assert.IsFalse(codeBuilder.PreviousLineIsCode); - } - - [Test] - public void TwoLinesWithPreviousEmptyLine() - { - codeBuilder.AppendIndentedLine("1st"); - codeBuilder.AppendLine(); - codeBuilder.Append("abc"); - Assert.IsFalse(codeBuilder.PreviousLineIsCode); - } - - [Test] - public void TwoLinesWithNoPreviousEmptyLine() - { - codeBuilder.AppendIndentedLine("First"); - codeBuilder.AppendIndentedLine("Second"); - Assert.IsTrue(codeBuilder.PreviousLineIsCode); - } - - [Test] - public void AppendToPreviousLine() - { - codeBuilder.AppendIndentedLine("abc"); - codeBuilder.AppendToPreviousLine(" # comment"); - Assert.AreEqual("abc # comment\r\n", codeBuilder.ToString()); - } - [Test] public void TrimEnd() { @@ -215,21 +34,6 @@ namespace RubyBinding.Tests.Designer Assert.AreEqual("abc\r\ndef", codeBuilder.ToString()); } - [Test] - public void GetFirstLineOfCode() - { - codeBuilder.IncreaseIndent(); - codeBuilder.AppendIndentedLine("abc"); - Assert.AreEqual("\tabc", codeBuilder.GetPreviousLine()); - } - - [Test] - public void GetPreviousLineReturnsEmptyStringIfNoPreviousLine() - { - codeBuilder.AppendIndented("def"); - Assert.AreEqual(String.Empty, codeBuilder.GetPreviousLine()); - } - [Test] public void AppendLineIfPreviousLineIsEndStatementAppendsNewLineIfPreviousLineIsEndStatement() { diff --git a/src/AddIns/BackendBindings/Scripting/Project/ICSharpCode.Scripting.csproj b/src/AddIns/BackendBindings/Scripting/Project/ICSharpCode.Scripting.csproj index 6233d7ba13..a4af838993 100644 --- a/src/AddIns/BackendBindings/Scripting/Project/ICSharpCode.Scripting.csproj +++ b/src/AddIns/BackendBindings/Scripting/Project/ICSharpCode.Scripting.csproj @@ -72,6 +72,7 @@ + diff --git a/src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingCodeBuilder.cs b/src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingCodeBuilder.cs new file mode 100644 index 0000000000..96c3b9e394 --- /dev/null +++ b/src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingCodeBuilder.cs @@ -0,0 +1,185 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Text; + +namespace ICSharpCode.Scripting +{ + public class ScriptingCodeBuilder + { + StringBuilder codeBuilder = new StringBuilder(); + string indentString = "\t"; + int indent; + + public ScriptingCodeBuilder() + { + } + + public ScriptingCodeBuilder(int initialIndent) + { + indent = initialIndent; + } + + /// + /// Gets or sets the string used for indenting. + /// + public string IndentString { + get { return indentString; } + set { indentString = value; } + } + + /// + /// Returns the code. + /// + public override string ToString() + { + return codeBuilder.ToString(); + } + + /// + /// Returns true if the previous line contains code. If the previous line contains a + /// comment or is an empty line then it returns false; + /// + public bool PreviousLineIsCode { + get { + string code = ToString(); + int end = MoveToPreviousLineEnd(code, code.Length - 1); + if (end > 0) { + int start = MoveToPreviousLineEnd(code, end); + string line = code.Substring(start + 1, end - start).Trim(); + return (line.Length > 0) && (!line.Trim().StartsWith("#")); + } + return false; + } + } + + public string GetPreviousLine() + { + string code = ToString(); + int end = MoveToPreviousLineEnd(code, code.Length - 1); + if (end > 0) { + int start = MoveToPreviousLineEnd(code, end); + return code.Substring(start + 1, end - start); + } + return String.Empty; + } + + /// + /// Appends text at the end of the current code. + /// + public void Append(string text) + { + codeBuilder.Append(text); + } + + /// + /// Appends carriage return and line feed to the existing text. + /// + public void AppendLine() + { + Append("\r\n"); + } + + /// + /// Appends the text indented. + /// + public void AppendIndented(string text) + { + codeBuilder.Append(GetIndentString()); + codeBuilder.Append(text); + } + + /// + /// Inserts a new line at the start of the code before everything else. + /// + public void InsertIndentedLine(string text) + { + text = GetIndentString() + text + "\r\n"; + codeBuilder.Insert(0, text, 1); + } + + /// + /// Inserts the text with a carriage return and newline at the end. + /// + public void AppendIndentedLine(string text) + { + AppendIndented(text + "\r\n"); + } + + public void AppendLineIfPreviousLineIsCode() + { + if (PreviousLineIsCode) { + codeBuilder.AppendLine(); + } + } + + /// + /// Appends the specified text to the end of the previous line. + /// + public void AppendToPreviousLine(string text) + { + string code = ToString(); + int end = MoveToPreviousLineEnd(code, code.Length - 1); + if (end > 0) { + codeBuilder.Insert(end + 1, text); + } + } + + public void TrimEnd() + { + string trimmedText = codeBuilder.ToString().TrimEnd(); + codeBuilder = new StringBuilder(); + codeBuilder.Append(trimmedText); + } + + public void IncreaseIndent() + { + indent++; + } + + public void DecreaseIndent() + { + indent--; + } + + public int Indent { + get { return indent; } + } + + /// + /// Gets the length of the current code string. + /// + public int Length { + get { return codeBuilder.Length; } + } + + string GetIndentString() + { + StringBuilder currentIndentString = new StringBuilder(); + for (int i = 0; i < indent; ++i) { + currentIndentString.Append(indentString); + } + return currentIndentString.ToString(); + } + + /// + /// Returns the index of the end of the previous line. + /// + /// This is the index to start working backwards from. + int MoveToPreviousLineEnd(string code, int index) + { + while (index >= 0) { + if (code[index] == '\r') { + return index - 1; + } + --index; + } + return -1; + } + } +} diff --git a/src/AddIns/BackendBindings/Scripting/Test/Designer/ScriptingCodeBuilderTests.cs b/src/AddIns/BackendBindings/Scripting/Test/Designer/ScriptingCodeBuilderTests.cs new file mode 100644 index 0000000000..19755fa84e --- /dev/null +++ b/src/AddIns/BackendBindings/Scripting/Test/Designer/ScriptingCodeBuilderTests.cs @@ -0,0 +1,223 @@ +// +// +// +// +// $Revision$ +// + +using System; +using ICSharpCode.Scripting; +using NUnit.Framework; + +namespace ICSharpCode.Scripting.Tests.Designer +{ + [TestFixture] + public class ScriptingCodeBuilderTests + { + ScriptingCodeBuilder codeBuilder; + + [SetUp] + public void Init() + { + codeBuilder = new ScriptingCodeBuilder(); + codeBuilder.IndentString = "\t"; + } + + [Test] + public void AppendNewLine() + { + codeBuilder.AppendLine(); + string text = codeBuilder.ToString(); + Assert.AreEqual("\r\n", text); + } + + [Test] + public void AppendText() + { + codeBuilder.Append("abc"); + string text = codeBuilder.ToString(); + Assert.AreEqual("abc", text); + } + + [Test] + public void AppendIndentedText() + { + codeBuilder.IncreaseIndent(); + codeBuilder.AppendIndented("abc"); + string text = codeBuilder.ToString(); + Assert.AreEqual("\tabc", text); + } + + [Test] + public void IncreaseIndentTwice() + { + codeBuilder.IncreaseIndent(); + codeBuilder.IncreaseIndent(); + codeBuilder.AppendIndented("abc"); + string text = codeBuilder.ToString(); + Assert.AreEqual("\t\tabc", text); + } + + [Test] + public void DecreaseIndent() + { + codeBuilder.IncreaseIndent(); + codeBuilder.AppendIndented("abc"); + codeBuilder.AppendLine(); + codeBuilder.DecreaseIndent(); + codeBuilder.AppendIndented("abc"); + string text = codeBuilder.ToString(); + Assert.AreEqual("\tabc\r\nabc", text); + } + + [Test] + public void AppendIndentedLine() + { + codeBuilder.IncreaseIndent(); + codeBuilder.AppendIndentedLine("abc"); + string text = codeBuilder.ToString(); + Assert.AreEqual("\tabc\r\n", text); + } + + [Test] + public void InitialIndentWhenCodeBuilderCreatedIsZero() + { + Assert.AreEqual(0, codeBuilder.Indent); + } + + [Test] + public void IncreaseIndentByOne() + { + codeBuilder.IncreaseIndent(); + Assert.AreEqual(1, codeBuilder.Indent); + } + + [Test] + public void LengthAfterAddingText() + { + codeBuilder.Append("abc"); + Assert.AreEqual(3, codeBuilder.Length); + } + + [Test] + public void IndentPassedToConstructor() + { + codeBuilder = new ScriptingCodeBuilder(2); + codeBuilder.AppendIndented("abc"); + string text = codeBuilder.ToString(); + Assert.AreEqual("\t\tabc", text); + } + + [Test] + public void InsertIndentedLine() + { + codeBuilder.IncreaseIndent(); + codeBuilder.AppendIndentedLine("def"); + codeBuilder.InsertIndentedLine("abc"); + string text = codeBuilder.ToString(); + Assert.AreEqual("\tabc\r\n\tdef\r\n", text); + } + + [Test] + public void PreviousLineIsEmptyNewLine() + { + codeBuilder.AppendLine(); + Assert.IsFalse(codeBuilder.PreviousLineIsCode); + } + + [Test] + public void PreviousLineIsComment() + { + codeBuilder.AppendIndentedLine("# comment"); + Assert.IsFalse(codeBuilder.PreviousLineIsCode); + } + + [Test] + public void PreviousLineIsNotEmptyNewLine() + { + codeBuilder.AppendIndentedLine("abc"); + Assert.IsTrue(codeBuilder.PreviousLineIsCode); + } + + [Test] + public void PreviousLineDoesNotExist() + { + Assert.IsFalse(codeBuilder.PreviousLineIsCode); + } + + [Test] + public void PreviousLineIsEmptyAndCurrentLineHasText() + { + codeBuilder.AppendLine(); + codeBuilder.Append("abc"); + Assert.IsFalse(codeBuilder.PreviousLineIsCode); + } + + [Test] + public void PreviousLineIsMadeUpOfWhiteSpace() + { + codeBuilder.AppendIndentedLine(" \t "); + Assert.IsFalse(codeBuilder.PreviousLineIsCode); + } + + [Test] + public void TwoLinesWithPreviousLineMadeUpOfWhiteSpace() + { + codeBuilder.AppendIndentedLine("1st"); + codeBuilder.AppendIndentedLine(" \t "); + Assert.IsFalse(codeBuilder.PreviousLineIsCode); + } + + [Test] + public void TwoLinesWithPreviousEmptyLine() + { + codeBuilder.AppendIndentedLine("1st"); + codeBuilder.AppendLine(); + codeBuilder.Append("abc"); + Assert.IsFalse(codeBuilder.PreviousLineIsCode); + } + + [Test] + public void TwoLinesWithNoPreviousEmptyLine() + { + codeBuilder.AppendIndentedLine("First"); + codeBuilder.AppendIndentedLine("Second"); + Assert.IsTrue(codeBuilder.PreviousLineIsCode); + } + + [Test] + public void AppendToPreviousLine() + { + codeBuilder.AppendIndentedLine("abc"); + codeBuilder.AppendToPreviousLine(" # comment"); + string text = codeBuilder.ToString(); + Assert.AreEqual("abc # comment\r\n", text); + } + + [Test] + public void TrimEnd() + { + codeBuilder.Append("abc"); + codeBuilder.AppendLine(); + codeBuilder.Append("def"); + codeBuilder.AppendLine(); + codeBuilder.TrimEnd(); + Assert.AreEqual("abc\r\ndef", codeBuilder.ToString()); + } + + [Test] + public void GetFirstLineOfCode() + { + codeBuilder.IncreaseIndent(); + codeBuilder.AppendIndentedLine("abc"); + Assert.AreEqual("\tabc", codeBuilder.GetPreviousLine()); + } + + [Test] + public void GetPreviousLineReturnsEmptyStringIfNoPreviousLine() + { + codeBuilder.AppendIndented("def"); + Assert.AreEqual(String.Empty, codeBuilder.GetPreviousLine()); + } + } +} diff --git a/src/AddIns/BackendBindings/Scripting/Test/ICSharpCode.Scripting.Tests.csproj b/src/AddIns/BackendBindings/Scripting/Test/ICSharpCode.Scripting.Tests.csproj index b7db292b00..62b3100778 100644 --- a/src/AddIns/BackendBindings/Scripting/Test/ICSharpCode.Scripting.Tests.csproj +++ b/src/AddIns/BackendBindings/Scripting/Test/ICSharpCode.Scripting.Tests.csproj @@ -76,6 +76,7 @@ +