diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.addin b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.addin index 7a27b4ad58..3ded0e261a 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.addin +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.addin @@ -72,6 +72,13 @@ icon = "PadIcons.LocalVariables" shortcut = "Control|Alt|V" class = "ICSharpCode.SharpDevelop.Gui.Pads.LocalVarPad"/> + + diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.csproj b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.csproj index 5f7553e540..d1519bcfe3 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.csproj +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.csproj @@ -57,6 +57,7 @@ + diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Expressions/AstEvaluator.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Expressions/AstEvaluator.cs index 8521f76fd1..8aaac076af 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Expressions/AstEvaluator.cs +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Expressions/AstEvaluator.cs @@ -15,25 +15,24 @@ namespace Debugger.AddIn { public static class AstEvaluator { - public static Debugger.AddIn.TreeModel.AbstractNode Evaluate(string code, SupportedLanguage language, StackFrame context) + /// Returned value or null for statements + public static Value Evaluate(string code, SupportedLanguage language, StackFrame context) { SnippetParser parser = new SnippetParser(language); INode astRoot = parser.Parse(code); if (parser.SnippetType == SnippetType.Expression || parser.SnippetType == SnippetType.Statements) { - if (parser.Errors.Count == 0) { - try { - EvaluateAstVisitor visitor = new EvaluateAstVisitor(context); - Value result = (Value)astRoot.AcceptVisitor(visitor, null); - return new ValueNode(result); - } catch (NotImplementedException) { - return null; - } catch (GetValueException e) { - return new ErrorNode(new EmptyExpression(), e); - } + if (parser.Errors.Count > 0) { + throw new GetValueException(parser.Errors.ErrorOutput); + } + try { + EvaluateAstVisitor visitor = new EvaluateAstVisitor(context); + return astRoot.AcceptVisitor(visitor, null) as Value; + } catch (NotImplementedException) { + throw new GetValueException("Syntax feature not implemented"); } } - return null; + throw new GetValueException("Code must be expression or statement"); } } } diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/ConsolePad.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/ConsolePad.cs new file mode 100644 index 0000000000..fcebc9edc0 --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/ConsolePad.cs @@ -0,0 +1,123 @@ +// +// +// +// +// $Revision$ +// +using Debugger.AddIn.TreeModel; +using System; +using System.Windows.Forms; +using Debugger; +using Debugger.AddIn; +using ICSharpCode.NRefactory; +using ICSharpCode.TextEditor; +using ICSharpCode.TextEditor.Document; + +namespace ICSharpCode.SharpDevelop.Gui.Pads +{ + public class ConsolePad: DebuggerPad + { + ConsoleControl editor; + + public override Control Control { + get { + return editor; + } + } + + protected override void InitializeComponents() + { + editor = new ConsoleControl(); + } + + protected override void SelectProcess(Debugger.Process process) + { + editor.Process = process; + } + } + + class ConsoleControl: TextEditorControl + { + Process process; + + public Process Process { + get { return process; } + set { process = value; } + } + + public ConsoleControl() + { + SetHighlighting("C#"); + PrintPrompt(); + } + + protected override void InitializeTextAreaControl(TextAreaControl newControl) + { + newControl.TextArea.DoProcessDialogKey += HandleDialogKey; + newControl.TextArea.KeyEventHandler += HandleKey; + } + + void PrintPrompt() + { + this.Document.Insert(this.Document.TextLength, "> "); + this.ActiveTextAreaControl.Caret.Position = this.Document.OffsetToPosition(this.Document.TextLength); + } + + string GetLastLineText() + { + LineSegment seg = this.Document.LineSegmentCollection[this.Document.LineSegmentCollection.Count - 1]; + return this.Document.GetText(seg.Offset, seg.Length).Substring(2); + } + + bool HandleDialogKey(Keys keys) + { + // All lines except the last one are read-only + int codeStart = this.Document.PositionToOffset(new TextLocation(2, this.Document.LineSegmentCollection.Count - 1)); + this.Document.ReadOnly = (this.ActiveTextAreaControl.Caret.Offset < codeStart); + + if (keys == Keys.Back) { + if (this.ActiveTextAreaControl.Caret.Offset <= codeStart) { + return true; + } + } + if (keys == Keys.Enter) { + string code = GetLastLineText(); + if (string.IsNullOrEmpty(code)) return true; + string result = Evaluate(code); + if (string.IsNullOrEmpty(result)) { + this.Document.Insert(this.Document.TextLength, Environment.NewLine); + } else { + this.Document.Insert(this.Document.TextLength, Environment.NewLine + result + Environment.NewLine); + } + PrintPrompt(); + return true; + } + return false; + } + + bool HandleKey(char ch) + { + return false; + } + + string Evaluate(string code) + { + if (process == null) { + return "No process is being debugged"; + } + if (process.IsRunning) { + return "The process is running"; + } + try { + Value val = AstEvaluator.Evaluate(code, SupportedLanguage.CSharp, process.SelectedStackFrame); + if (val != null) { + return string.Format("{0} ({1})", val.AsString, val.Type.FullName); + } else { + return string.Empty; + } + } catch (GetValueException e) { + return e.Message; + } + } + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/WindowsDebugger.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/WindowsDebugger.cs index ddc05ac255..82e0036aa6 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/WindowsDebugger.cs +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/WindowsDebugger.cs @@ -323,7 +323,7 @@ namespace ICSharpCode.SharpDevelop.Services /// Gets variable of given name. /// Returns null if unsuccessful. /// - public AbstractNode GetValueFromName(string variableName) + public Value GetValueFromName(string variableName) { if (debuggedProcess == null || debuggedProcess.IsRunning || debuggedProcess.SelectedStackFrame == null) { return null; @@ -351,12 +351,12 @@ namespace ICSharpCode.SharpDevelop.Services /// public string GetValueAsString(string variableName) { - ValueNode node = GetValueFromName(variableName) as ValueNode; - - if (node == null) { + try { + Value val = GetValueFromName(variableName); + if (val == null) return null; + return val.AsString; + } catch (GetValueException) { return null; - } else { - return node.Text; } } @@ -366,15 +366,18 @@ namespace ICSharpCode.SharpDevelop.Services /// public DebuggerGridControl GetTooltipControl(string variableName) { - AbstractNode node = GetValueFromName(variableName); - - if (node == null) { + ValueNode valueNode; + try { + Value val = GetValueFromName(variableName); + if (val == null) return null; + valueNode = new ValueNode(val); + } catch (GetValueException) { return null; - } else { - currentTooltipRow = new DynamicTreeDebuggerRow(DebuggedProcess, node); - currentTooltipExpression = node is ValueNode ? ((ValueNode)node).Expression : null; - return new DebuggerGridControl(currentTooltipRow); } + + currentTooltipRow = new DynamicTreeDebuggerRow(DebuggedProcess, valueNode); + currentTooltipExpression = valueNode.Expression; + return new DebuggerGridControl(currentTooltipRow); } public bool CanSetInstructionPointer(string filename, int line, int column)