187 changed files with 3905 additions and 1955 deletions
@ -1,2 +1,2 @@
@@ -1,2 +1,2 @@
|
||||
[tgit] |
||||
icon = src/Main/StartUp/Project/Resources/SharpDevelop.ico |
||||
icon = src/Main/SharpDevelop/Resources/SharpDevelop.ico |
||||
|
||||
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) https://github.com/ddur
|
||||
// This code is distributed under the MIT license
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.CodeCoverage |
||||
{ |
||||
/// <summary>
|
||||
/// Description of CodeCoverageBranchPoint.
|
||||
/// </summary>
|
||||
public class CodeCoverageBranchPoint |
||||
{ |
||||
public int VisitCount { get; set; } |
||||
public int Path { get; set; } |
||||
public int Offset { get; set; } |
||||
public int OffsetEnd { get; set; } |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,217 @@
@@ -0,0 +1,217 @@
|
||||
// Copyright (c) https://github.com/ddur
|
||||
// This code is distributed under MIT license
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Diagnostics; |
||||
using System.Text; |
||||
|
||||
namespace ICSharpCode.CodeCoverage |
||||
{ |
||||
/// <summary>StringTextSource (ReadOnly)
|
||||
/// <remarks>Line and column counting starts at 1.</remarks>
|
||||
/// <remarks>IDocument/ITextBuffer/ITextSource fails returning single char "{"?</remarks>
|
||||
/// </summary>
|
||||
public class CodeCoverageStringTextSource |
||||
{ |
||||
private readonly string textSource; |
||||
private struct lineInfo { |
||||
public int Offset; |
||||
public int Length; |
||||
} |
||||
private readonly lineInfo[] lines; |
||||
public CodeCoverageStringTextSource(string source) |
||||
{ |
||||
this.textSource = source; |
||||
|
||||
lineInfo line; |
||||
var lineInfoList = new List<lineInfo>(); |
||||
int offset = 0; |
||||
int counter = 0; |
||||
bool newLine = false; |
||||
bool cr = false; |
||||
bool lf = false; |
||||
|
||||
foreach ( ushort ch in textSource ) { |
||||
switch (ch) { |
||||
case 0xD: |
||||
if (lf||cr) { |
||||
newLine = true; // cr after cr|lf
|
||||
} else { |
||||
cr = true; // cr found
|
||||
} |
||||
break; |
||||
case 0xA: |
||||
if (lf) { |
||||
newLine = true; // lf after lf
|
||||
} else { |
||||
lf = true; // lf found
|
||||
} |
||||
break; |
||||
default: |
||||
if (cr||lf) { |
||||
newLine = true; // any non-line-end char after any line-end
|
||||
} |
||||
break; |
||||
} |
||||
if (newLine) { // newLine detected - add line
|
||||
line = new lineInfo(); |
||||
line.Offset = offset; |
||||
line.Length = counter - offset; |
||||
lineInfoList.Add(line); |
||||
offset = counter; |
||||
cr = false; |
||||
lf = false; |
||||
newLine = false; |
||||
} |
||||
++counter; |
||||
} |
||||
|
||||
// Add last line
|
||||
line = new lineInfo(); |
||||
line.Offset = offset; |
||||
line.Length = counter - offset; |
||||
lineInfoList.Add(line); |
||||
|
||||
// Store to readonly field
|
||||
lines = lineInfoList.ToArray(); |
||||
} |
||||
|
||||
/// <summary>Return text/source using SequencePoint line/col info
|
||||
/// </summary>
|
||||
/// <param name="sp"></param>
|
||||
/// <returns></returns>
|
||||
public string GetText(CodeCoverageSequencePoint sp) { |
||||
return this.GetText(sp.Line, sp.Column, sp.EndLine, sp.EndColumn ); |
||||
} |
||||
|
||||
/// <summary>Return text at Line/Column/EndLine/EndColumn position
|
||||
/// <remarks>Line and Column counting starts at 1.</remarks>
|
||||
/// </summary>
|
||||
/// <param name="Line"></param>
|
||||
/// <param name="Column"></param>
|
||||
/// <param name="EndLine"></param>
|
||||
/// <param name="EndColumn"></param>
|
||||
/// <returns></returns>
|
||||
public string GetText(int Line, int Column, int EndLine, int EndColumn) { |
||||
|
||||
var text = new StringBuilder(); |
||||
string line; |
||||
bool argOutOfRange; |
||||
|
||||
if (Line==EndLine) { |
||||
|
||||
#region One-Line request
|
||||
line = GetLine(Line); |
||||
|
||||
//Debug.Assert(!(Column < 1), "Column < 1");
|
||||
//Debug.Assert(!(Column > EndColumn), "Column > EndColumn");
|
||||
//Debug.Assert(!(EndColumn > line.Length + 1), string.Format ("Single Line EndColumn({0}) > line.Length({1})",EndColumn, line.Length ));
|
||||
//Debug.Assert(!(EndColumn > line.Length + 1), line);
|
||||
|
||||
argOutOfRange = Column < 1 |
||||
|| Column > EndColumn |
||||
|| EndColumn > line.Length; |
||||
if (!argOutOfRange) { |
||||
text.Append(line.Substring(Column-1,EndColumn-Column)); |
||||
} |
||||
#endregion
|
||||
|
||||
} else if (Line<EndLine) { |
||||
|
||||
#region Multi-line request
|
||||
|
||||
#region First line
|
||||
line = GetLine(Line); |
||||
|
||||
//Debug.Assert(!(Column < 1), "Column < 1");
|
||||
//Debug.Assert(!(Column > line.Length), string.Format ("First MultiLine EndColumn({0}) > line.Length({1})",EndColumn, line.Length ));
|
||||
|
||||
argOutOfRange = Column < 1 |
||||
|| Column > line.Length; |
||||
if (!argOutOfRange) { |
||||
text.Append(line.Substring(Column-1)); |
||||
} |
||||
#endregion
|
||||
|
||||
#region More than two lines
|
||||
for ( int lineIndex = Line+1; lineIndex < EndLine; lineIndex++ ) { |
||||
text.Append ( GetLine ( lineIndex ) ); |
||||
} |
||||
#endregion
|
||||
|
||||
#region Last line
|
||||
line = GetLine(EndLine); |
||||
|
||||
//Debug.Assert(!(EndColumn < 1), "EndColumn < 1");
|
||||
//Debug.Assert(!(EndColumn > line.Length), string.Format ("Last MultiLine EndColumn({0}) > line.Length({1})",EndColumn, line.Length ));
|
||||
|
||||
argOutOfRange = EndColumn < 1 |
||||
|| EndColumn > line.Length; |
||||
if (!argOutOfRange) { |
||||
text.Append(line.Substring(0,EndColumn)); |
||||
} |
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
} else { |
||||
//Debug.Fail("Line > EndLine");
|
||||
} |
||||
return text.ToString(); |
||||
} |
||||
|
||||
public int LinesCount { |
||||
get { |
||||
return lines.Length; |
||||
} |
||||
} |
||||
|
||||
/// <summary>Return SequencePoint enumerated line
|
||||
/// </summary>
|
||||
/// <param name="LineNo"></param>
|
||||
/// <returns></returns>
|
||||
public string GetLine ( int LineNo ) { |
||||
|
||||
string retString = String.Empty; |
||||
|
||||
if ( LineNo > 0 && LineNo <= lines.Length ) { |
||||
lineInfo lineInfo = lines[LineNo-1]; |
||||
retString = textSource.Substring(lineInfo.Offset, lineInfo.Length); |
||||
} else { |
||||
//Debug.Fail( "Line number out of range" );
|
||||
} |
||||
|
||||
return retString; |
||||
} |
||||
|
||||
public static string IndentTabs ( string ToIndent, int TabSize ) { |
||||
|
||||
string retString = ToIndent; |
||||
if ( ToIndent.Contains ( "\t" ) ) { |
||||
int counter = 0; |
||||
int remains = 0; |
||||
int repeat = 0; |
||||
char prevChar = char.MinValue; |
||||
var indented = new StringBuilder(); |
||||
foreach ( char currChar in ToIndent ) { |
||||
if ( currChar == '\t' ) { |
||||
remains = counter % TabSize; |
||||
repeat = remains == 0 ? TabSize : remains; |
||||
indented.Append( ' ', repeat ); |
||||
} else { |
||||
indented.Append ( currChar, 1 ); |
||||
if ( char.IsLowSurrogate(currChar) |
||||
&& char.IsHighSurrogate(prevChar) |
||||
) { --counter; } |
||||
} |
||||
prevChar = currChar; |
||||
++counter; |
||||
} |
||||
retString = indented.ToString(); |
||||
} |
||||
return retString; |
||||
} |
||||
|
||||
} |
||||
} |
||||
@ -0,0 +1,311 @@
@@ -0,0 +1,311 @@
|
||||
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Documents; |
||||
using System.Windows.Input; |
||||
using System.Windows.Media; |
||||
using ICSharpCode.AvalonEdit; |
||||
using ICSharpCode.AvalonEdit.Editing; |
||||
using ICSharpCode.AvalonEdit.Rendering; |
||||
using ICSharpCode.AvalonEdit.Utils; |
||||
using ICSharpCode.NRefactory; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Editor; |
||||
namespace CSharpBinding.Refactoring |
||||
{ |
||||
class InsertionCursorLayer : Canvas, IDisposable |
||||
{ |
||||
readonly string operation; |
||||
|
||||
readonly InsertionPoint[] insertionPoints; |
||||
|
||||
readonly TextArea editor; |
||||
|
||||
public int CurrentInsertionPoint { |
||||
get; |
||||
set; |
||||
} |
||||
|
||||
int insertionPointNextToMouse = -1; |
||||
|
||||
public event EventHandler<InsertionCursorEventArgs> Exited; |
||||
|
||||
public static readonly RoutedCommand ExitCommand = new RoutedCommand("Exit", typeof(InsertionCursorLayer), new InputGestureCollection { |
||||
new KeyGesture(Key.Escape) |
||||
}); |
||||
|
||||
public InsertionCursorLayer(TextArea editor, string operation, IList<InsertionPoint> insertionPoints) |
||||
{ |
||||
if (editor == null) |
||||
throw new ArgumentNullException("editor"); |
||||
this.editor = editor; |
||||
this.operation = operation; |
||||
this.insertionPoints = insertionPoints.ToArray(); |
||||
this.editor.ActiveInputHandler = new InputHandler(this); |
||||
this.editor.TextView.InsertLayer(this, KnownLayer.Text, LayerInsertionPosition.Above); |
||||
this.editor.TextView.ScrollOffsetChanged += TextViewScrollOffsetChanged; |
||||
AddGroupBox(); |
||||
ScrollToInsertionPoint(); |
||||
} |
||||
|
||||
static readonly Pen markerPen = new Pen(Brushes.Blue, 2); |
||||
|
||||
static readonly Pen tempMarkerPen = new Pen(Brushes.Gray, 2); |
||||
|
||||
protected override void OnRender(DrawingContext drawingContext) |
||||
{ |
||||
DrawLineForInsertionPoint(CurrentInsertionPoint, markerPen, drawingContext); |
||||
if (insertionPointNextToMouse > -1 && insertionPointNextToMouse != CurrentInsertionPoint) |
||||
DrawLineForInsertionPoint(insertionPointNextToMouse, tempMarkerPen, drawingContext); |
||||
SetGroupBoxPosition(); |
||||
// HACK: why OnRender() override? we could just use Line objects instead
|
||||
} |
||||
|
||||
Point GetLinePosition(int index) |
||||
{ |
||||
var currentInsertionPoint = insertionPoints[index]; |
||||
var textViewPosition = new TextViewPosition(currentInsertionPoint.Location); |
||||
bool isEmptyLine = DocumentUtilities.IsEmptyLine(editor.Document, textViewPosition.Line); |
||||
var pos = editor.TextView.GetVisualPosition(textViewPosition, isEmptyLine ? VisualYPosition.LineMiddle : VisualYPosition.LineTop); |
||||
return pos - editor.TextView.ScrollOffset; |
||||
} |
||||
|
||||
void DrawLineForInsertionPoint(int index, Pen pen, DrawingContext drawingContext) |
||||
{ |
||||
var pos = GetLinePosition(index); |
||||
var endPos = new Point(pos.X + editor.TextView.ActualWidth * 0.6, pos.Y); |
||||
var pixelSize = PixelSnapHelpers.GetPixelSize(this); |
||||
drawingContext.DrawLine(pen, PixelSnapHelpers.Round(pos, pixelSize), PixelSnapHelpers.Round(endPos, pixelSize)); |
||||
} |
||||
|
||||
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) |
||||
{ |
||||
return new PointHitTestResult(this, hitTestParameters.HitPoint); |
||||
} |
||||
|
||||
protected override void OnMouseMove(MouseEventArgs e) |
||||
{ |
||||
insertionPointNextToMouse = FindNextInsertionPoint(e.GetPosition(this)); |
||||
// don't set e.Handled = true; so that the event continues bubbling
|
||||
InvalidateVisual(); |
||||
base.OnMouseMove(e); |
||||
} |
||||
|
||||
protected override void OnQueryCursor(QueryCursorEventArgs e) |
||||
{ |
||||
if (FindNextInsertionPoint(e.GetPosition(this)) >= 0) |
||||
e.Cursor = Cursors.UpArrow; |
||||
else |
||||
e.Cursor = Cursors.Arrow; |
||||
e.Handled = true; |
||||
} |
||||
|
||||
protected override void OnMouseDown(MouseButtonEventArgs e) |
||||
{ |
||||
if (e.LeftButton == MouseButtonState.Pressed) { |
||||
if (e.ClickCount > 1) { |
||||
FireExited(true); |
||||
} |
||||
else { |
||||
insertionPointNextToMouse = FindNextInsertionPoint(e.GetPosition(this)); |
||||
if (insertionPointNextToMouse >= 0) |
||||
CurrentInsertionPoint = insertionPointNextToMouse; |
||||
InvalidateVisual(); |
||||
} |
||||
e.Handled = true; |
||||
} |
||||
base.OnMouseDown(e); |
||||
} |
||||
|
||||
int FindNextInsertionPoint(Point point) |
||||
{ |
||||
var position = editor.TextView.GetPosition(point + editor.TextView.ScrollOffset); |
||||
if (position == null) |
||||
return -1; |
||||
int insertionPoint = -1; |
||||
int mouseLocationLine = position.Value.Location.Line; |
||||
int currentLocationLine = -10; |
||||
for (int i = 0; i < insertionPoints.Length; i++) { |
||||
var line = insertionPoints[i].Location.Line; |
||||
var diff = Math.Abs(line - mouseLocationLine); |
||||
if (Math.Abs(currentLocationLine - mouseLocationLine) > diff && diff < 2) { |
||||
insertionPoint = i; |
||||
currentLocationLine = line; |
||||
} |
||||
} |
||||
return insertionPoint; |
||||
} |
||||
|
||||
void TextViewScrollOffsetChanged(object sender, EventArgs e) |
||||
{ |
||||
InvalidateVisual(); |
||||
} |
||||
|
||||
class InputHandler : TextAreaDefaultInputHandler |
||||
{ |
||||
readonly InsertionCursorLayer layer; |
||||
|
||||
internal InputHandler(InsertionCursorLayer layer) : base(layer.editor) |
||||
{ |
||||
this.layer = layer; |
||||
AddBinding(EditingCommands.MoveDownByLine, ModifierKeys.None, Key.Down, MoveMarker(false)); |
||||
AddBinding(EditingCommands.MoveUpByLine, ModifierKeys.None, Key.Up, MoveMarker(true)); |
||||
AddBinding(EditingCommands.MoveDownByPage, ModifierKeys.None, Key.PageDown, MoveMarkerPage(false)); |
||||
AddBinding(EditingCommands.MoveUpByPage, ModifierKeys.None, Key.PageUp, MoveMarkerPage(true)); |
||||
AddBinding(EditingCommands.MoveToLineStart, ModifierKeys.None, Key.Home, MoveMarkerFull(true)); |
||||
AddBinding(EditingCommands.MoveToLineEnd, ModifierKeys.None, Key.End, MoveMarkerFull(false)); |
||||
AddBinding(EditingCommands.EnterParagraphBreak, ModifierKeys.None, Key.Enter, layer.InsertCode); |
||||
AddBinding(ExitCommand, ModifierKeys.None, Key.Escape, layer.Cancel); |
||||
} |
||||
|
||||
ExecutedRoutedEventHandler MoveMarker(bool up) |
||||
{ |
||||
return (sender, e) => { |
||||
if (up) |
||||
layer.CurrentInsertionPoint = Math.Max(0, layer.CurrentInsertionPoint - 1); |
||||
else |
||||
layer.CurrentInsertionPoint = Math.Min(layer.insertionPoints.Length - 1, layer.CurrentInsertionPoint + 1); |
||||
layer.InvalidateVisual(); |
||||
layer.ScrollToInsertionPoint(); |
||||
}; |
||||
} |
||||
|
||||
ExecutedRoutedEventHandler MoveMarkerPage(bool up) |
||||
{ |
||||
return (sender, e) => { |
||||
TextLocation current = layer.insertionPoints[layer.CurrentInsertionPoint].Location; |
||||
double currentVPos = layer.editor.TextView.GetVisualTopByDocumentLine(current.Line); |
||||
int newIndex = layer.CurrentInsertionPoint; |
||||
double newVPos; |
||||
do { |
||||
if (up) { |
||||
newIndex--; |
||||
if (newIndex < 0) { |
||||
newIndex = 0; |
||||
break; |
||||
} |
||||
} |
||||
else { |
||||
newIndex++; |
||||
if (newIndex >= layer.insertionPoints.Length) { |
||||
newIndex = layer.insertionPoints.Length - 1; |
||||
break; |
||||
} |
||||
} |
||||
newVPos = layer.editor.TextView.GetVisualTopByDocumentLine(layer.insertionPoints[newIndex].Location.Line); |
||||
} |
||||
while (Math.Abs(currentVPos - newVPos) < layer.editor.ActualHeight); |
||||
layer.CurrentInsertionPoint = newIndex; |
||||
layer.InvalidateVisual(); |
||||
layer.ScrollToInsertionPoint(); |
||||
}; |
||||
} |
||||
|
||||
ExecutedRoutedEventHandler MoveMarkerFull(bool up) |
||||
{ |
||||
return (sender, e) => { |
||||
if (up) |
||||
layer.CurrentInsertionPoint = 0; |
||||
else |
||||
layer.CurrentInsertionPoint = layer.insertionPoints.Length - 1; |
||||
layer.InvalidateVisual(); |
||||
layer.ScrollToInsertionPoint(); |
||||
}; |
||||
} |
||||
} |
||||
|
||||
public void Dispose() |
||||
{ |
||||
editor.TextView.Layers.Remove(this); |
||||
editor.ActiveInputHandler = editor.DefaultInputHandler; |
||||
editor.TextView.ScrollOffsetChanged -= TextViewScrollOffsetChanged; |
||||
} |
||||
|
||||
void InsertCode(object sender, ExecutedRoutedEventArgs e) |
||||
{ |
||||
FireExited(true); |
||||
} |
||||
|
||||
void ScrollToInsertionPoint() |
||||
{ |
||||
var location = insertionPoints[CurrentInsertionPoint].Location; |
||||
editor.GetService<TextEditor>().ScrollTo(location.Line, location.Column); |
||||
SetGroupBoxPosition(); |
||||
} |
||||
|
||||
void SetGroupBoxPosition() |
||||
{ |
||||
var boxPosition = GetLinePosition(CurrentInsertionPoint) + new Vector(editor.TextView.ActualWidth * 0.6 - 5, -groupBox.ActualHeight / 2.0); |
||||
Canvas.SetTop(groupBox, boxPosition.Y); |
||||
Canvas.SetLeft(groupBox, boxPosition.X); |
||||
} |
||||
|
||||
void Cancel(object sender, ExecutedRoutedEventArgs e) |
||||
{ |
||||
FireExited(false); |
||||
} |
||||
|
||||
void FireExited(bool success) |
||||
{ |
||||
if (Exited != null) { |
||||
Exited(this, new InsertionCursorEventArgs(insertionPoints[CurrentInsertionPoint], success)); |
||||
} |
||||
} |
||||
|
||||
GroupBox groupBox; |
||||
|
||||
void AddGroupBox() |
||||
{ |
||||
var content = new StackPanel { |
||||
Children = { |
||||
new TextBlock { |
||||
Text = "Use Up/Down to move to another location.\r\n" + "Press Enter to select the location.\r\n" + "Press Esc to cancel this operation." |
||||
} |
||||
} |
||||
}; |
||||
groupBox = new GroupBox { |
||||
Background = Brushes.White, |
||||
BorderBrush = Brushes.Blue, |
||||
BorderThickness = new Thickness(1), |
||||
Header = operation, |
||||
Content = content |
||||
}; |
||||
Children.Add(groupBox); |
||||
} |
||||
} |
||||
|
||||
class InsertionCursorEventArgs : EventArgs |
||||
{ |
||||
public InsertionPoint InsertionPoint { get; private set; } |
||||
public bool Success { get; private set; } |
||||
|
||||
public InsertionCursorEventArgs(InsertionPoint insertionPoint, bool success) |
||||
{ |
||||
if (insertionPoint == null) |
||||
throw new ArgumentNullException("insertionPoint"); |
||||
this.InsertionPoint = insertionPoint; |
||||
this.Success = success; |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
<Popup x:Class="Debugger.AddIn.Breakpoints.BreakpointEditorPopup" |
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
xmlns:sd="http://icsharpcode.net/sharpdevelop/core" |
||||
xmlns:controls="clr-namespace:Debugger.AddIn.Pads.Controls" |
||||
xmlns:widgets="http://icsharpcode.net/sharpdevelop/widgets" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
||||
<Popup.Resources> |
||||
<widgets:BoolToVisibilityConverter x:Key="showWhenTrue" TrueValue="Visible" FalseValue="Collapsed" /> |
||||
</Popup.Resources> |
||||
<Border BorderBrush="Black" BorderThickness="1" |
||||
Background="LightGray"> |
||||
<StackPanel Orientation="Vertical" Background="White"> |
||||
<ToolBar ToolBarTray.IsLocked="True" ToolBar.OverflowMode="Never"> |
||||
<RadioButton x:Name="breakAction" |
||||
Checked="TypeChecked" |
||||
Content="Break" |
||||
ToolTip="Break" /> |
||||
<RadioButton x:Name="conditionalAction" |
||||
Checked="TypeChecked" |
||||
Content="Conditional" |
||||
ToolTip="Conditional" /> |
||||
<Separator /> |
||||
<CheckBox Content="Enabled" |
||||
IsChecked="{Binding IsEnabled}" |
||||
ToolTip="Enabled" /> |
||||
</ToolBar> |
||||
<Border |
||||
Margin="2" |
||||
CornerRadius="2" |
||||
BorderBrush="DarkGray" |
||||
Padding="2" |
||||
Visibility="{Binding IsChecked, ElementName=conditionalAction, Converter={StaticResource showWhenTrue}}" |
||||
BorderThickness="1"> |
||||
<controls:AutoCompleteTextBox x:Name="condition" Text="{Binding Condition}" /> |
||||
</Border> |
||||
</StackPanel> |
||||
</Border> |
||||
</Popup> |
||||
@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
|
||||
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Text; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Controls.Primitives; |
||||
using System.Windows.Data; |
||||
using System.Windows.Documents; |
||||
using System.Windows.Input; |
||||
using System.Windows.Media; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Editor; |
||||
using Debugger.AddIn.Pads.Controls; |
||||
|
||||
namespace Debugger.AddIn.Breakpoints |
||||
{ |
||||
/// <summary>
|
||||
/// Interaction logic for BreakpointEditorPopup.xaml
|
||||
/// </summary>
|
||||
public partial class BreakpointEditorPopup : Popup, ITooltip |
||||
{ |
||||
public BreakpointEditorPopup(BreakpointBookmark target) |
||||
{ |
||||
InitializeComponent(); |
||||
this.DataContext = target; |
||||
condition.DebugContext = new DebuggerCompletionContext(target.FileName, target.Location); |
||||
condition.FontFamily = new FontFamily(SD.EditorControlService.GlobalOptions.FontFamily); |
||||
condition.FontSize = SD.EditorControlService.GlobalOptions.FontSize; |
||||
if (target.Condition == null) |
||||
breakAction.IsChecked = true; |
||||
else |
||||
conditionalAction.IsChecked = true; |
||||
} |
||||
|
||||
public bool CloseWhenMouseMovesAway { |
||||
get { return !IsKeyboardFocusWithin && !IsFocused; } |
||||
} |
||||
|
||||
void TypeChecked(object sender, System.Windows.RoutedEventArgs e) |
||||
{ |
||||
if (sender == breakAction) |
||||
((BreakpointBookmark)DataContext).Condition = null; |
||||
if (sender == conditionalAction && ((BreakpointBookmark)DataContext).Condition == null) |
||||
((BreakpointBookmark)DataContext).Condition = ""; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,201 @@
@@ -0,0 +1,201 @@
|
||||
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.NRefactory; |
||||
using ICSharpCode.NRefactory.CSharp; |
||||
using ICSharpCode.NRefactory.CSharp.Refactoring; |
||||
using ICSharpCode.NRefactory.CSharp.Resolver; |
||||
using ICSharpCode.NRefactory.Editor; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Editor.CodeCompletion; |
||||
|
||||
namespace Debugger.AddIn.Pads.Controls |
||||
{ |
||||
static class DebuggerDotCompletion |
||||
{ |
||||
public static bool CheckSyntax(string expression, out Error[] errors) |
||||
{ |
||||
var p = new CSharpParser(); |
||||
p.ParseExpression(expression); |
||||
errors = p.Errors.ToArray(); |
||||
return !errors.Any(); |
||||
} |
||||
|
||||
public static ICodeCompletionBinding PrepareDotCompletion(string expressionToComplete, DebuggerCompletionContext context) |
||||
{ |
||||
var lang = SD.LanguageService.GetLanguageByFileName(context.FileName); |
||||
if (lang == null) |
||||
return null; |
||||
string content = GeneratePartialClassContextStub(context); |
||||
const string caretPoint = "$__Caret_Point__$;"; |
||||
int caretOffset = content.IndexOf(caretPoint, StringComparison.Ordinal) + expressionToComplete.Length; |
||||
SD.Log.DebugFormatted("context used for dot completion: {0}", content.Replace(caretPoint, "$" + expressionToComplete + "|$")); |
||||
var doc = new ReadOnlyDocument(content.Replace(caretPoint, expressionToComplete)); |
||||
return lang.CreateCompletionBinding(context.FileName, doc.GetLocation(caretOffset), doc.CreateSnapshot()); |
||||
} |
||||
|
||||
static string GeneratePartialClassContextStub(DebuggerCompletionContext context) |
||||
{ |
||||
var compilation = SD.ParserService.GetCompilationForFile(context.FileName); |
||||
var file = SD.ParserService.GetExistingUnresolvedFile(context.FileName); |
||||
if (compilation == null || file == null) |
||||
return ""; |
||||
var member = file.GetMember(context.Location); |
||||
if (member == null) |
||||
return ""; |
||||
var builder = new TypeSystemAstBuilder(); |
||||
EntityDeclaration decl = builder.ConvertEntity(member.Resolve(new SimpleTypeResolveContext(compilation.MainAssembly))); |
||||
decl.Name = "__DebuggerStub_" + decl.Name; |
||||
decl.Modifiers &= (Modifiers.Static); |
||||
switch (member.SymbolKind) { |
||||
case SymbolKind.Property: |
||||
break; |
||||
case SymbolKind.Indexer: |
||||
break; |
||||
case SymbolKind.Event: |
||||
break; |
||||
case SymbolKind.Method: |
||||
GenerateBodyFromContext(builder, context, (MethodDeclaration)decl); |
||||
break; |
||||
case SymbolKind.Operator: |
||||
break; |
||||
case SymbolKind.Constructor: |
||||
break; |
||||
case SymbolKind.Destructor: |
||||
break; |
||||
case SymbolKind.Accessor: |
||||
break; |
||||
default: |
||||
throw new ArgumentOutOfRangeException(); |
||||
} |
||||
return WrapInType(member.DeclaringTypeDefinition, decl.ToString()); |
||||
} |
||||
|
||||
static void GenerateBodyFromContext(TypeSystemAstBuilder builder, DebuggerCompletionContext context, MethodDeclaration methodDeclaration) |
||||
{ |
||||
methodDeclaration.Body = new BlockStatement(); |
||||
foreach (var v in context.Variables) |
||||
methodDeclaration.Body.Statements.Add(new VariableDeclarationStatement(builder.ConvertType(v.Type), v.Name)); |
||||
methodDeclaration.Body.Statements.Add(new ExpressionStatement(new IdentifierExpression("$__Caret_Point__$"))); |
||||
} |
||||
|
||||
static string WrapInType(IUnresolvedTypeDefinition entity, string code) |
||||
{ |
||||
if (entity == null) |
||||
return code; |
||||
code = WrapInType(entity.DeclaringTypeDefinition, GetHeader(entity) + code + "\r\n}"); |
||||
if (entity.DeclaringTypeDefinition == null) { |
||||
return "namespace " + entity.Namespace + " {\r\n" + code + "\r\n}"; |
||||
} |
||||
return code; |
||||
} |
||||
|
||||
static string GetHeader(IUnresolvedTypeDefinition entity) |
||||
{ |
||||
StringBuilder builder = new StringBuilder(); |
||||
builder.Append("partial "); |
||||
switch (entity.Kind) { |
||||
case TypeKind.Class: |
||||
builder.Append("class "); |
||||
break; |
||||
case TypeKind.Interface: |
||||
builder.Append("interface "); |
||||
break; |
||||
case TypeKind.Struct: |
||||
builder.Append("struct "); |
||||
break; |
||||
default: |
||||
throw new NotSupportedException(); |
||||
} |
||||
builder.Append(entity.Name); |
||||
builder.AppendLine(" {"); |
||||
return builder.ToString(); |
||||
} |
||||
} |
||||
|
||||
public class LocalVariable |
||||
{ |
||||
readonly IType type; |
||||
|
||||
public IType Type { |
||||
get { |
||||
return type; |
||||
} |
||||
} |
||||
|
||||
readonly string name; |
||||
|
||||
public string Name { |
||||
get { |
||||
return name; |
||||
} |
||||
} |
||||
|
||||
public LocalVariable(IType type, string name) |
||||
{ |
||||
this.type = type; |
||||
this.name = name; |
||||
} |
||||
} |
||||
|
||||
public class DebuggerCompletionContext |
||||
{ |
||||
readonly FileName fileName; |
||||
TextLocation location; |
||||
readonly LocalVariable[] variables; |
||||
|
||||
public DebuggerCompletionContext(StackFrame frame) |
||||
{ |
||||
fileName = new FileName(frame.NextStatement.Filename); |
||||
location = new TextLocation(frame.NextStatement.StartLine, frame.NextStatement.StartColumn); |
||||
variables = frame.GetLocalVariables().Select(v => new LocalVariable(v.Type, v.Name)).ToArray(); |
||||
} |
||||
|
||||
public DebuggerCompletionContext(FileName fileName, TextLocation location) |
||||
{ |
||||
this.fileName = fileName; |
||||
this.location = location; |
||||
this.variables = SD.ParserService.ResolveContext(fileName, location) |
||||
.LocalVariables.Select(v => new LocalVariable(v.Type, v.Name)).ToArray(); |
||||
} |
||||
|
||||
public FileName FileName { |
||||
get { |
||||
return fileName; |
||||
} |
||||
} |
||||
|
||||
public TextLocation Location { |
||||
get { |
||||
return location; |
||||
} |
||||
} |
||||
|
||||
public LocalVariable[] Variables { |
||||
get { |
||||
return variables; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -1,10 +0,0 @@
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<Window x:Class="Debugger.AddIn.EditBreakpointScriptWindow" xmlns:sd="http://icsharpcode.net/sharpdevelop/core" xmlns:widgets="http://icsharpcode.net/sharpdevelop/widgets" xmlns:avalonedit="http://icsharpcode.net/sharpdevelop/avalonedit" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="{sd:Localize MainWindow.Windows.Debug.Conditional.Breakpoints.ScriptingWindow.Title}" Width="500" Style="{x:Static sd:GlobalStyles.DialogWindowStyle}" WindowStartupLocation="CenterScreen" Height="400"> |
||||
<DockPanel> |
||||
<widgets:UniformGridWithSpacing DockPanel.Dock="Bottom" Columns="2" HorizontalAlignment="Center" Margin="3"> |
||||
<Button Name="btnOK" Content="{sd:Localize Global.OKButtonText}" Click="BtnOKClick" IsDefault="True" Style="{x:Static sd:GlobalStyles.ButtonStyle}" /> |
||||
<Button Name="btnCancel" Content="{sd:Localize Global.CancelButtonText}" Click="BtnCancelClick" IsCancel="True" Style="{x:Static sd:GlobalStyles.ButtonStyle}" /> |
||||
</widgets:UniformGridWithSpacing> |
||||
<avalonedit:TextEditor x:Name="codeEditor" /> |
||||
</DockPanel> |
||||
</Window> |
||||
@ -1,84 +0,0 @@
@@ -1,84 +0,0 @@
|
||||
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
using System.Text; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Data; |
||||
using System.Windows.Documents; |
||||
using System.Windows.Input; |
||||
using System.Windows.Media; |
||||
using ICSharpCode.AvalonEdit.Highlighting; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.NRefactory; |
||||
using ICSharpCode.SharpDevelop.Debugging; |
||||
|
||||
namespace Debugger.AddIn |
||||
{ |
||||
/// <summary>
|
||||
/// Interaction logic for EditBreakpointScriptWindow.xaml
|
||||
/// </summary>
|
||||
public partial class EditBreakpointScriptWindow : Window |
||||
{ |
||||
BreakpointBookmark data; |
||||
|
||||
public EditBreakpointScriptWindow(BreakpointBookmark data) |
||||
{ |
||||
InitializeComponent(); |
||||
|
||||
this.data = data; |
||||
|
||||
string language = ProjectService.CurrentProject != null ? ProjectService.CurrentProject.Language : "C#"; |
||||
this.codeEditor.Document.Text = data.Condition ?? string.Empty; |
||||
this.codeEditor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition(language); |
||||
} |
||||
|
||||
bool CheckSyntax() |
||||
{ |
||||
#warning reimplement this!
|
||||
// SupportedLanguage language = (SupportedLanguage)Enum.Parse(typeof(SupportedLanguage), this.cmbLanguage.SelectedItem.ToString(), true);
|
||||
// using (var parser = ParserFactory.CreateParser(language, new StringReader(this.codeEditor.Document.Text))) {
|
||||
// parser.ParseExpression();
|
||||
// if (parser.Errors.Count > 0) {
|
||||
// MessageService.ShowError(parser.Errors.ErrorOutput);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
return true; |
||||
} |
||||
|
||||
void BtnOKClick(object sender, RoutedEventArgs e) |
||||
{ |
||||
if (!this.CheckSyntax()) |
||||
return; |
||||
|
||||
this.data.Condition = this.codeEditor.Document.Text; |
||||
DialogResult = true; |
||||
} |
||||
|
||||
void BtnCancelClick(object sender, RoutedEventArgs e) |
||||
{ |
||||
DialogResult = false; |
||||
} |
||||
} |
||||
} |
||||
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue