diff --git a/src/Libraries/NRefactory/Project/Src/Ast/General/PrimitiveExpression.cs b/src/Libraries/NRefactory/Project/Src/Ast/General/PrimitiveExpression.cs
index 3e7ea9e753..ae6d22877c 100644
--- a/src/Libraries/NRefactory/Project/Src/Ast/General/PrimitiveExpression.cs
+++ b/src/Libraries/NRefactory/Project/Src/Ast/General/PrimitiveExpression.cs
@@ -5,6 +5,7 @@
// $Revision$
//
+using ICSharpCode.NRefactory.PrettyPrinter;
using System;
namespace ICSharpCode.NRefactory.Ast
@@ -18,13 +19,21 @@ namespace ICSharpCode.NRefactory.Ast
public string StringValue {
get {
- return stringValue;
+ if (stringValue == null)
+ return CSharpOutputVisitor.ToCSharpString(this);
+ else
+ return stringValue;
}
set {
stringValue = value == null ? String.Empty : value;
}
}
+ public PrimitiveExpression(object val)
+ {
+ this.Value = val;
+ }
+
public PrimitiveExpression(object val, string stringValue)
{
this.Value = val;
@@ -39,9 +48,9 @@ namespace ICSharpCode.NRefactory.Ast
public override string ToString()
{
return String.Format("[PrimitiveExpression: Value={1}, ValueType={2}, StringValue={0}]",
- stringValue,
- Value,
- Value == null ? "null" : Value.GetType().FullName
+ this.StringValue,
+ this.Value,
+ this.Value == null ? "null" : this.Value.GetType().FullName
);
}
}
diff --git a/src/Libraries/NRefactory/Project/Src/AstBuilder/ExpressionBuilder.cs b/src/Libraries/NRefactory/Project/Src/AstBuilder/ExpressionBuilder.cs
index 4c0be34acd..49d89dd5bc 100644
--- a/src/Libraries/NRefactory/Project/Src/AstBuilder/ExpressionBuilder.cs
+++ b/src/Libraries/NRefactory/Project/Src/AstBuilder/ExpressionBuilder.cs
@@ -83,6 +83,16 @@ namespace ICSharpCode.NRefactory.AstBuilder
return new PrimitiveExpression(null, "null");
}
}
+
+ ///
+ /// Just calls the BinaryOperatorExpression constructor,
+ /// but being an extension method; this allows for a nicer
+ /// infix syntax in some cases.
+ ///
+ public static BinaryOperatorExpression Operator(this Expression left, BinaryOperatorType op, Expression right)
+ {
+ return new BinaryOperatorExpression(left, op, right);
+ }
}
#endif
}
diff --git a/src/Libraries/NRefactory/Project/Src/AstBuilder/StatementBuilder.cs b/src/Libraries/NRefactory/Project/Src/AstBuilder/StatementBuilder.cs
index 28117b9537..64451cd511 100644
--- a/src/Libraries/NRefactory/Project/Src/AstBuilder/StatementBuilder.cs
+++ b/src/Libraries/NRefactory/Project/Src/AstBuilder/StatementBuilder.cs
@@ -11,7 +11,6 @@ using ICSharpCode.NRefactory.Ast;
namespace ICSharpCode.NRefactory.AstBuilder
{
- #if NET35
///
/// Extension methods for NRefactory.Ast.Expression.
///
@@ -57,5 +56,4 @@ namespace ICSharpCode.NRefactory.AstBuilder
AddStatement(block, new AssignmentExpression(left, AssignmentOperatorType.Assign, right));
}
}
- #endif
}
diff --git a/src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs b/src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs
index 651183206d..74311d582c 100644
--- a/src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs
+++ b/src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs
@@ -1747,70 +1747,69 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
}
public override object TrackedVisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data)
+ {
+ outputFormatter.PrintText(ToCSharpString(primitiveExpression));
+ return null;
+ }
+
+ internal static string ToCSharpString(PrimitiveExpression primitiveExpression)
{
if (primitiveExpression.Value == null) {
- outputFormatter.PrintToken(Tokens.Null);
- return null;
+ return "null";
}
object val = primitiveExpression.Value;
if (val is bool) {
if ((bool)val) {
- outputFormatter.PrintToken(Tokens.True);
+ return "true";
} else {
- outputFormatter.PrintToken(Tokens.False);
+ return "false";
}
- return null;
}
if (val is string) {
- outputFormatter.PrintText('"' + ConvertString(val.ToString()) + '"');
- return null;
+ return "\"" + ConvertString(val.ToString()) + "\"";
}
if (val is char) {
- outputFormatter.PrintText("'" + ConvertCharLiteral((char)val) + "'");
- return null;
+ return "'" + ConvertCharLiteral((char)val) + "'";
}
if (val is decimal) {
- outputFormatter.PrintText(((decimal)val).ToString(NumberFormatInfo.InvariantInfo) + "m");
- return null;
+ return ((decimal)val).ToString(NumberFormatInfo.InvariantInfo) + "m";
}
if (val is float) {
- outputFormatter.PrintText(((float)val).ToString(NumberFormatInfo.InvariantInfo) + "f");
- return null;
+ return ((float)val).ToString(NumberFormatInfo.InvariantInfo) + "f";
}
if (val is double) {
string text = ((double)val).ToString(NumberFormatInfo.InvariantInfo);
if (text.IndexOf('.') < 0 && text.IndexOf('E') < 0)
- outputFormatter.PrintText(text + ".0");
+ return text + ".0";
else
- outputFormatter.PrintText(text);
- return null;
+ return text;
}
if (val is IFormattable) {
+ StringBuilder b = new StringBuilder();
if (primitiveExpression.LiteralFormat == LiteralFormat.HexadecimalNumber) {
- outputFormatter.PrintText("0x");
- outputFormatter.PrintText(((IFormattable)val).ToString("x", NumberFormatInfo.InvariantInfo));
+ b.Append("0x");
+ b.Append(((IFormattable)val).ToString("x", NumberFormatInfo.InvariantInfo));
} else {
- outputFormatter.PrintText(((IFormattable)val).ToString(null, NumberFormatInfo.InvariantInfo));
+ b.Append(((IFormattable)val).ToString(null, NumberFormatInfo.InvariantInfo));
}
if (val is uint || val is ulong) {
- outputFormatter.PrintText("u");
+ b.Append("u");
}
if (val is long || val is ulong) {
- outputFormatter.PrintText("L");
+ b.Append("L");
}
+ return b.ToString();
} else {
- outputFormatter.PrintText(val.ToString());
+ return val.ToString();
}
-
- return null;
}
static bool IsNullLiteralExpression(Expression expr)
diff --git a/src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs b/src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs
index e45bffd686..0b468d2621 100644
--- a/src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs
+++ b/src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs
@@ -236,9 +236,9 @@ namespace ICSharpCode.NRefactory.Visitors
if (methodDeclaration.TypeReference.Type != "System.Void" && methodDeclaration.Body.Children.Count > 0) {
if (IsAssignmentTo(methodDeclaration.Body.Children[methodDeclaration.Body.Children.Count - 1], methodDeclaration.Name))
{
- ReturnStatement rs = new ReturnStatement(GetAssignmentFromStatement(methodDeclaration.Body.Children[methodDeclaration.Body.Children.Count - 1]).Right);
+ Expression returnValue = GetAssignmentFromStatement(methodDeclaration.Body.Children[methodDeclaration.Body.Children.Count - 1]).Right;
methodDeclaration.Body.Children.RemoveAt(methodDeclaration.Body.Children.Count - 1);
- methodDeclaration.Body.AddChild(rs);
+ methodDeclaration.Body.Return(returnValue);
} else {
ReturnStatementForFunctionAssignment visitor = new ReturnStatementForFunctionAssignment(methodDeclaration.Name);
methodDeclaration.Body.AcceptVisitor(visitor, null);
@@ -247,7 +247,7 @@ namespace ICSharpCode.NRefactory.Visitors
init = ExpressionBuilder.CreateDefaultValueForType(methodDeclaration.TypeReference);
methodDeclaration.Body.Children.Insert(0, new LocalVariableDeclaration(new VariableDeclaration(FunctionReturnValueName, init, methodDeclaration.TypeReference)));
methodDeclaration.Body.Children[0].Parent = methodDeclaration.Body;
- methodDeclaration.Body.AddChild(new ReturnStatement(new IdentifierExpression(FunctionReturnValueName)));
+ methodDeclaration.Body.Return(new IdentifierExpression(FunctionReturnValueName));
}
}
}
diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
index 6530ecf132..caa209fb82 100644
--- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
+++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
@@ -497,6 +497,7 @@
Form
+
diff --git a/src/Main/Base/Project/Src/TextEditor/Commands/PasteAsCommands.cs b/src/Main/Base/Project/Src/TextEditor/Commands/PasteAsCommands.cs
new file mode 100644
index 0000000000..5e7aff8368
--- /dev/null
+++ b/src/Main/Base/Project/Src/TextEditor/Commands/PasteAsCommands.cs
@@ -0,0 +1,174 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using ICSharpCode.NRefactory.Ast;
+using ICSharpCode.NRefactory.AstBuilder;
+using System;
+using System.IO;
+using System.Text;
+using ICSharpCode.Core;
+using ICSharpCode.Core.WinForms;
+using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor;
+using ICSharpCode.SharpDevelop.Dom;
+using ICSharpCode.SharpDevelop.Dom.Refactoring;
+using ICSharpCode.SharpDevelop.Gui;
+using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.TextEditor;
+using ICSharpCode.TextEditor.Actions;
+using ICSharpCode.TextEditor.Document;
+
+namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
+{
+ public abstract class PasteAsCommand : AbstractMenuCommand
+ {
+ public override void Run()
+ {
+ string clipboardText = ClipboardWrapper.GetText();
+ if (string.IsNullOrEmpty(clipboardText))
+ return;
+
+ IViewContent viewContent = WorkbenchSingleton.Workbench.ActiveViewContent;
+ if (viewContent == null || !(viewContent is ITextEditorControlProvider)) {
+ return;
+ }
+
+ TextEditorControl textEditor = ((ITextEditorControlProvider)viewContent).TextEditorControl;
+ if (textEditor == null) {
+ return;
+ }
+
+ textEditor.BeginUpdate();
+ textEditor.Document.UndoStack.StartUndoGroup();
+ try {
+ Run(textEditor, clipboardText);
+ } finally {
+ textEditor.Document.UndoStack.EndUndoGroup();
+ textEditor.EndUpdate();
+ }
+ textEditor.Refresh();
+ }
+
+ protected abstract void Run(TextEditorControl editor, string clipboardText);
+
+ protected string GetIndentation(ICSharpCode.TextEditor.Document.IDocument document, int line)
+ {
+ string lineText = document.GetText(document.GetLineSegment(line));
+ return lineText.Substring(0, lineText.Length - lineText.TrimStart().Length);
+ }
+ }
+
+ ///
+ /// Pastes the clipboard text as a comment.
+ ///
+ /// Does the following:
+ /// - Take clipboard text
+ /// - Get current indentation
+ /// - Wrap first line using 'IAmbience.WrapComment'
+ /// - If it's too long (according to the column ruler position), word-break
+ /// - Insert it
+ ///
+ public class PasteAsCommentCommand : PasteAsCommand
+ {
+ protected override void Run(TextEditorControl editor, string clipboardText)
+ {
+ TextArea textArea = editor.ActiveTextAreaControl.TextArea;
+ string indentation = GetIndentation(editor.Document, textArea.Caret.Line);
+ IAmbience ambience = AmbienceService.GetCurrentAmbience();
+ int maxLineLength = textArea.TextEditorProperties.VerticalRulerRow - VisualIndentationLength(textArea, indentation);
+ StringBuilder insertedText = new StringBuilder();
+ using (StringReader reader = new StringReader(clipboardText)) {
+ string line;
+ while ((line = reader.ReadLine()) != null) {
+ AppendTextLine(indentation, ambience, maxLineLength, insertedText, line);
+ }
+ }
+ var document = textArea.Document;
+ int insertionPos = document.GetLineSegment(textArea.Caret.Line).Offset + indentation.Length;
+ document.Insert(insertionPos, insertedText.ToString());
+ }
+
+ void AppendTextLine(string indentation, IAmbience ambience, int maxLineLength, StringBuilder insertedText, string line)
+ {
+ const int minimumLineLength = 10;
+ string commentedLine;
+ while (true) {
+ commentedLine = ambience.WrapComment(line);
+ int commentingOverhead = commentedLine.Length - line.Length;
+ if (commentingOverhead < 0 || (maxLineLength - commentingOverhead) < minimumLineLength)
+ break;
+ if (commentedLine.Length > maxLineLength) {
+ int pos = FindWrapPositionBefore(line, maxLineLength - commentingOverhead);
+ if (pos < minimumLineLength)
+ break;
+ insertedText.AppendLine(ambience.WrapComment(line.Substring(0, pos)));
+ insertedText.Append(indentation);
+ line = line.Substring(pos + 1);
+ } else {
+ break;
+ }
+ }
+ insertedText.AppendLine(commentedLine);
+ insertedText.Append(indentation); // indentation for next line
+ }
+
+ int FindWrapPositionBefore(string line, int pos)
+ {
+ return line.LastIndexOf(' ', pos);
+ }
+
+ int VisualIndentationLength(TextArea textArea, string indentation)
+ {
+ int length = 0;
+ foreach (char c in indentation) {
+ if (c == '\t')
+ length += textArea.TextEditorProperties.TabIndent;
+ else
+ length += 1;
+ }
+ return length;
+ }
+ }
+
+ ///
+ /// Pastes the clipboard text as a string.
+ ///
+ /// Does the following:
+ /// - Take clipboard text
+ /// - Convert to string literal using CodeGenerator
+ /// - Insert it
+ ///
+ public class PasteAsStringCommand : PasteAsCommand
+ {
+ protected override void Run(TextEditorControl editor, string clipboardText)
+ {
+ CodeGenerator codeGenerator = ParserService.CurrentProjectContent.Language.CodeGenerator;
+ if (codeGenerator == null)
+ codeGenerator = LanguageProperties.CSharp.CodeGenerator;
+ Expression expression = null;
+ using (StringReader reader = new StringReader(clipboardText)) {
+ string line;
+ while ((line = reader.ReadLine()) != null) {
+ Expression newExpr = new PrimitiveExpression(line);
+ if (expression == null) {
+ expression = newExpr;
+ } else {
+ expression = expression
+ .Operator(BinaryOperatorType.Concat,
+ ExpressionBuilder.Identifier("Environment").Member("NewLine"))
+ .Operator(BinaryOperatorType.Concat,
+ newExpr);
+ }
+ }
+ }
+ if (expression == null)
+ return;
+ TextArea textArea = editor.ActiveTextAreaControl.TextArea;
+ string indentation = GetIndentation(editor.Document, textArea.Caret.Line);
+ textArea.InsertString(codeGenerator.GenerateCode(expression, indentation).Trim());
+ }
+ }
+}