Browse Source

Added an Console Pad in which debugging expressions can be evaluated

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3187 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 18 years ago
parent
commit
91d4a13837
  1. 7
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.addin
  2. 1
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.csproj
  3. 23
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Expressions/AstEvaluator.cs
  4. 123
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/ConsolePad.cs
  5. 29
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/WindowsDebugger.cs

7
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.addin

@ -72,6 +72,13 @@ @@ -72,6 +72,13 @@
icon = "PadIcons.LocalVariables"
shortcut = "Control|Alt|V"
class = "ICSharpCode.SharpDevelop.Gui.Pads.LocalVarPad"/>
<Pad id = "ConsolePad"
category = "Debugger"
title = "${res:MainWindow.Windows.Debug.Console}"
icon = "PadIcons.Output"
shortcut = "Control|Alt|N"
class = "ICSharpCode.SharpDevelop.Gui.Pads.ConsolePad"/>
</Path>
<Path name = "/SharpDevelop/Dialogs/OptionsDialog">

1
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.csproj

@ -57,6 +57,7 @@ @@ -57,6 +57,7 @@
</Compile>
<Compile Include="Src\Pads\BreakPointsPad.cs" />
<Compile Include="Src\Pads\CallStackPad.cs" />
<Compile Include="Src\Pads\ConsolePad.cs" />
<Compile Include="Src\Pads\LoadedModulesPad.cs" />
<Compile Include="Src\Pads\LocalVarPad.cs" />
<Compile Include="Src\Pads\RunningThreadsPad.cs" />

23
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Expressions/AstEvaluator.cs

@ -15,25 +15,24 @@ namespace Debugger.AddIn @@ -15,25 +15,24 @@ namespace Debugger.AddIn
{
public static class AstEvaluator
{
public static Debugger.AddIn.TreeModel.AbstractNode Evaluate(string code, SupportedLanguage language, StackFrame context)
/// <returns> Returned value or null for statements </returns>
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");
}
}
}

123
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/ConsolePad.cs

@ -0,0 +1,123 @@ @@ -0,0 +1,123 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
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;
}
}
}
}

29
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/WindowsDebugger.cs

@ -323,7 +323,7 @@ namespace ICSharpCode.SharpDevelop.Services @@ -323,7 +323,7 @@ namespace ICSharpCode.SharpDevelop.Services
/// Gets variable of given name.
/// Returns null if unsuccessful.
/// </summary>
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 @@ -351,12 +351,12 @@ namespace ICSharpCode.SharpDevelop.Services
/// </summary>
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 @@ -366,15 +366,18 @@ namespace ICSharpCode.SharpDevelop.Services
/// </summary>
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)

Loading…
Cancel
Save