Browse Source

Merge branch 'master' into envdte-nrefactory

pull/375/head
Matt Ward 12 years ago
parent
commit
825be03066
  1. 2
      .tgitconfig
  2. 6
      README.txt
  3. 6
      data/resources/StringResources.nl.resx
  4. 6
      data/resources/StringResources.resx
  5. 2
      src/AddIns/Analysis/CodeCoverage/Project/CodeCoverage.csproj
  6. 19
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageBranchPoint.cs
  7. 13
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageClassTreeNode.cs
  8. 28
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageControl.cs
  9. 27
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageHighlighter.cs
  10. 23
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageMethod.cs
  11. 396
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageMethodElement.cs
  12. 4
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageMethodTreeNode.cs
  13. 10
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageMethodsTreeNode.cs
  14. 15
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageModule.cs
  15. 19
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageOptions.cs
  16. 1
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageOptionsPanel.xaml.cs
  17. 53
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageResults.cs
  18. 6
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageSequencePoint.cs
  19. 217
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageStringTextSource.cs
  20. 35
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageTreeNode.cs
  21. 1
      src/AddIns/Analysis/CodeCoverage/Project/Src/ICodeCoverageWithVisits.cs
  22. 17
      src/AddIns/Analysis/CodeCoverage/Test/Coverage/CodeCoverageResultsMissingFileIdTestFixture.cs
  23. 6
      src/AddIns/Analysis/CodeCoverage/Test/Coverage/CodeCoverageResultsTestFixture.cs
  24. 8
      src/AddIns/Analysis/CodeCoverage/Test/Coverage/ModuleVisitedSequencePointsTestFixture.cs
  25. 1
      src/AddIns/Analysis/CodeQuality/Gui/MainView.xaml
  26. 18
      src/AddIns/Analysis/CodeQuality/Gui/MainView.xaml.cs
  27. 95
      src/AddIns/Analysis/UnitTesting/Interfaces/UnitTestDebuggerService.cs
  28. 2
      src/AddIns/Analysis/UnitTesting/NUnit/NUnitTestDebugger.cs
  29. 11
      src/AddIns/Analysis/UnitTesting/Pad/TestTreeView.cs
  30. 10
      src/AddIns/Analysis/UnitTesting/TestRunner/TestDebuggerBase.cs
  31. 3
      src/AddIns/Analysis/UnitTesting/UnitTesting.csproj
  32. 10
      src/AddIns/BackendBindings/AspNet.Mvc/Project/Src/WebBehavior.cs
  33. 1
      src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin
  34. 1
      src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj
  35. 13
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs
  36. 294
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/CodeManipulation.cs
  37. 59
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpCompletionBinding.cs
  38. 32
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpCompletionContext.cs
  39. 46
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingStrategy.cs
  40. 18
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/Parser.cs
  41. 274
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/EditorScript.cs
  42. 311
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertionCursorLayer.cs
  43. 4
      src/AddIns/BackendBindings/Scripting/Project/Src/RunScriptingConsoleApplicationCommand.cs
  44. 5
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs
  45. 31
      src/AddIns/Debugger/Debugger.AddIn/Breakpoints/BreakpointBookmark.cs
  46. 2
      src/AddIns/Debugger/Debugger.AddIn/Breakpoints/BreakpointBookmarkEventArgs.cs
  47. 38
      src/AddIns/Debugger/Debugger.AddIn/Breakpoints/BreakpointEditorPopup.xaml
  48. 65
      src/AddIns/Debugger/Debugger.AddIn/Breakpoints/BreakpointEditorPopup.xaml.cs
  49. 18
      src/AddIns/Debugger/Debugger.AddIn/Breakpoints/CurrentLineBookmark.cs
  50. 49
      src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin
  51. 14
      src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj
  52. 76
      src/AddIns/Debugger/Debugger.AddIn/NRefactory/ExpressionEvaluationVisitor.cs
  53. 71
      src/AddIns/Debugger/Debugger.AddIn/Pads/AutoCompleteTextBox.cs
  54. 3
      src/AddIns/Debugger/Debugger.AddIn/Pads/BreakPointsPad.cs
  55. 58
      src/AddIns/Debugger/Debugger.AddIn/Pads/ConsolePad.cs
  56. 201
      src/AddIns/Debugger/Debugger.AddIn/Pads/DebuggerDotCompletion.cs
  57. 10
      src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs
  58. 2
      src/AddIns/Debugger/Debugger.AddIn/Service/AttachToProcessForm.cs
  59. 22
      src/AddIns/Debugger/Debugger.AddIn/Service/DebuggerCommands.cs
  60. 10
      src/AddIns/Debugger/Debugger.AddIn/Service/EditBreakpointScriptWindow.xaml
  61. 84
      src/AddIns/Debugger/Debugger.AddIn/Service/EditBreakpointScriptWindow.xaml.cs
  62. 128
      src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs
  63. 3
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/GraphVisualizer/ObjectGraphControl.xaml.cs
  64. 3
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/GraphVisualizer/ObjectGraphWindow.xaml.cs
  65. 2
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ClipboardRing.cs
  66. 155
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/IconBarMargin.cs
  67. 3
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Options/GeneralEditorOptions.xaml
  68. 13
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Options/HighlightingOptions.xaml.cs
  69. 4
      src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerViewContent.cs
  70. 1
      src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.addin
  71. 13
      src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyParser.cs
  72. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ModelTools.cs
  73. 3
      src/AddIns/DisplayBindings/XmlEditor/Project/XmlEditor.addin
  74. 2
      src/AddIns/Misc/AddInManager2/AddInManager2.Tests/Fakes/FakeCorePackageRepository.cs
  75. 3
      src/AddIns/Misc/AddInManager2/AddInManager2.Tests/Fakes/FakeNuGetCorePackageManager.cs
  76. 2
      src/AddIns/Misc/AddInManager2/AddInManager2.Tests/Fakes/FakePackage.cs
  77. 3
      src/AddIns/Misc/AddInManager2/Project/Src/Model/NuGetPackageManager.cs
  78. 2
      src/AddIns/Misc/AddInManager2/Project/Src/View/AddInManagerView.xaml
  79. 146
      src/AddIns/Misc/AddInManager2/Project/Src/View/AddInsView.xaml
  80. 2
      src/AddIns/Misc/AddInManager2/Project/Src/ViewModel/InstalledAddInsViewModel.cs
  81. 2
      src/AddIns/Misc/AddInManager2/Project/Src/ViewModel/NuGetAddInsViewModelBase.cs
  82. 4
      src/AddIns/Misc/AddInManager2/Project/Src/ViewModel/OfflineAddInViewModel.cs
  83. 2
      src/AddIns/Misc/PackageManagement/Cmdlets/Project/Src/GetPackageCmdlet.cs
  84. 4
      src/AddIns/Misc/PackageManagement/Packages/AvalonEdit.Sample/AvalonEdit.Sample.nuspec
  85. 7
      src/AddIns/Misc/PackageManagement/Packages/AvalonEdit/AvalonEdit.nuspec
  86. BIN
      src/AddIns/Misc/PackageManagement/Packages/NuGet.exe
  87. 8
      src/AddIns/Misc/PackageManagement/Packages/buildpackages.cmd
  88. 4
      src/AddIns/Misc/PackageManagement/Project/Src/AvailablePackagesViewModel.cs
  89. 13
      src/AddIns/Misc/PackageManagement/Project/Src/Design/FakeFileSystem.cs
  90. 2
      src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackage.cs
  91. 18
      src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManager.cs
  92. 2
      src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageRepository.cs
  93. 23
      src/AddIns/Misc/PackageManagement/Project/Src/Design/FakeProjectManager.cs
  94. 4
      src/AddIns/Misc/PackageManagement/Project/Src/PackageFromRepository.cs
  95. 4
      src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementSolution.cs
  96. 6
      src/AddIns/Misc/PackageManagement/Project/Src/PackageOperationsResolverFactory.cs
  97. 2
      src/AddIns/Misc/PackageManagement/Project/Src/RecentPackageRepository.cs
  98. 2
      src/AddIns/Misc/PackageManagement/Project/Src/SharpDevelopPackageManager.cs
  99. 2
      src/AddIns/Misc/PackageManagement/Project/Src/UpdatedPackages.cs
  100. BIN
      src/AddIns/Misc/PackageManagement/RequiredLibraries/Microsoft.Web.XmlTransform.dll
  101. Some files were not shown because too many files have changed in this diff Show More

2
.tgitconfig

@ -1,2 +1,2 @@ @@ -1,2 +1,2 @@
[tgit]
icon = src/Main/StartUp/Project/Resources/SharpDevelop.ico
icon = src/Main/SharpDevelop/Resources/SharpDevelop.ico

6
README.txt

@ -33,14 +33,14 @@ Extended Requirements (building SharpDevelop) @@ -33,14 +33,14 @@ Extended Requirements (building SharpDevelop)
- if you have cloned the SD git repository: git must be available on your PATH
Libraries and integrated tools:
AvalonDock: New BSD License (BSD) (thanks to Adolfo Marinucci)
AvalonDock: New BSD License (BSD) (thanks to Adolfo Marinucci) - http://avalondock.codeplex.com/
GraphSharp
IQToolkit
Irony
ITextSharp
log4net
Mono T4
Mono.Cecil: MIT License (thanks to Jb Evain)
Mono.Cecil: MIT License (thanks to Jb Evain) - https://github.com/jbevain/cecil
SharpSvn
SQLite
WPFToolkit
@ -50,7 +50,7 @@ Integrated Tools (shipping with SharpDevelop): @@ -50,7 +50,7 @@ Integrated Tools (shipping with SharpDevelop):
IronRuby
NuGet
NUnit
PartCover
OpenCover - https://github.com/OpenCover/opencover
WiX
Reusable Libraries (developed as part of SharpDevelop):

6
data/resources/StringResources.nl.resx

@ -2353,6 +2353,9 @@ Wilt u het nieuwe bestand toevoegen aan project ${CurrentProjectName}?</value> @@ -2353,6 +2353,9 @@ Wilt u het nieuwe bestand toevoegen aan project ${CurrentProjectName}?</value>
<data name="Dialog.Options.IDEOptions.TextEditor.Markers.HighlightBracketCheckBox" xml:space="preserve">
<value>&amp;Markeren passend haakje</value>
</data>
<data name="Dialog.Options.IDEOptions.TextEditor.Markers.HighlightCurrentLineCheckBox" xml:space="preserve">
<value>Benadruk momentele regel</value>
</data>
<data name="Dialog.Options.IDEOptions.TextEditor.Markers.HighlightSymbolCheckBox" xml:space="preserve">
<value>Markeer symbolen</value>
</data>
@ -6093,6 +6096,9 @@ Microsoft.Tools.WindowsInstallerXml.Extenties.NetFxCompiler, WixNetFxExtentie</v @@ -6093,6 +6096,9 @@ Microsoft.Tools.WindowsInstallerXml.Extenties.NetFxCompiler, WixNetFxExtentie</v
<data name="SharpDevelop.Refactoring.ClassesDerivingFrom" xml:space="preserve">
<value>Van ${Name} afgeleidde klassen</value>
</data>
<data name="SharpDevelop.Refactoring.ClipboardRingCommand" xml:space="preserve">
<value>Voeg in vanaf klembord ring...</value>
</data>
<data name="SharpDevelop.Refactoring.ConvertToAutomaticProperty" xml:space="preserve">
<value>Converteer naar automatische eigenschap</value>
</data>

6
data/resources/StringResources.resx

@ -3418,10 +3418,16 @@ You can also choose to store the setting in the .user-file instead of the projec @@ -3418,10 +3418,16 @@ You can also choose to store the setting in the .user-file instead of the projec
<value>Code Not Covered</value>
<comment>One of the display items that exists in the Code Coverage Options Panel. Selecting this one allows the user to configure the colours for the code that has NOT been covered by the unit tests.</comment>
</data>
<data name="ICSharpCode.CodeCoverage.CodePartCovered" xml:space="preserve">
<value>Code Partially Covered</value>
</data>
<data name="ICSharpCode.CodeCoverage.Column" xml:space="preserve">
<value>Column</value>
<comment>List view column header holding the code coverage start column number.</comment>
</data>
<data name="ICSharpCode.CodeCoverage.Content" xml:space="preserve">
<value>Content</value>
</data>
<data name="ICSharpCode.CodeCoverage.DisplayOptions" xml:space="preserve">
<value>Display Options</value>
</data>

2
src/AddIns/Analysis/CodeCoverage/Project/CodeCoverage.csproj

@ -67,6 +67,7 @@ @@ -67,6 +67,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Src\CodeCoverageBranchPoint.cs" />
<Compile Include="Src\CodeCoverageControl.cs">
<SubType>UserControl</SubType>
</Compile>
@ -89,6 +90,7 @@ @@ -89,6 +90,7 @@
<Compile Include="Src\CodeCoverageMethod.cs" />
<Compile Include="Src\CodeCoverageResultsReader.cs" />
<Compile Include="Src\CodeCoverageSequencePoint.cs" />
<Compile Include="Src\CodeCoverageStringTextSource.cs" />
<Compile Include="Src\CodeCoverageTestRunner.cs" />
<Compile Include="Src\CodeCoverageTestRunnerContext.cs" />
<Compile Include="Src\CodeCoverageTestRunnerFactory.cs" />

19
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageBranchPoint.cs

@ -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; }
}
}

13
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageClassTreeNode.cs

@ -66,11 +66,14 @@ namespace ICSharpCode.CodeCoverage @@ -66,11 +66,14 @@ namespace ICSharpCode.CodeCoverage
// Add methods.
CodeCoveragePropertyCollection properties = new CodeCoveragePropertyCollection();
foreach (CodeCoverageMethod method in Methods) {
if (method.IsProperty) {
properties.Add(method);
} else {
CodeCoverageMethodTreeNode node = new CodeCoverageMethodTreeNode(method);
node.AddTo(this);
// method name that is generated by compiler, contains "__" (double underscore)
if ( !method.Name.Contains("__") ) {
if (method.IsProperty) {
properties.Add(method);
} else {
CodeCoverageMethodTreeNode node = new CodeCoverageMethodTreeNode(method);
node.AddTo(this);
}
}
}

28
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageControl.cs

@ -19,9 +19,9 @@ @@ -19,9 +19,9 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Windows.Forms.Integration;
using ICSharpCode.AvalonEdit;
using ICSharpCode.AvalonEdit.AddIn;
using ICSharpCode.AvalonEdit.Document;
@ -50,6 +50,7 @@ namespace ICSharpCode.CodeCoverage @@ -50,6 +50,7 @@ namespace ICSharpCode.CodeCoverage
ColumnHeader endLineColumnHeader;
ColumnHeader startColumnColumnHeader;
ColumnHeader endColumnColumnHeader;
ColumnHeader contentColumnHeader;
ToolStrip toolStrip;
bool showSourceCodePanel;
bool showVisitCountPanel = true;
@ -316,11 +317,14 @@ namespace ICSharpCode.CodeCoverage @@ -316,11 +317,14 @@ namespace ICSharpCode.CodeCoverage
item.SubItems.Add(sequencePoint.Column.ToString());
item.SubItems.Add(sequencePoint.EndLine.ToString());
item.SubItems.Add(sequencePoint.EndColumn.ToString());
item.SubItems.Add(sequencePoint.Content.Length>80?sequencePoint.Content.Substring(0,80):sequencePoint.Content);
item.BackColor = CodeCoverageHighlighter.GetSequencePointBackColor(sequencePoint);
item.ForeColor = CodeCoverageHighlighter.GetSequencePointForeColor(sequencePoint);
item.Tag = sequencePoint;
listView.Items.Add(item);
}
void ListViewItemActivate(object sender, EventArgs e)
{
if (listView.SelectedItems.Count > 0) {
@ -408,32 +412,40 @@ namespace ICSharpCode.CodeCoverage @@ -408,32 +412,40 @@ namespace ICSharpCode.CodeCoverage
listView.FullRowSelect = true;
listView.HideSelection = false;
listView.ItemActivate += ListViewItemActivate;
listView.Font = Core.WinForms.WinFormsResourceService.DefaultMonospacedFont;
visitCountColumnHeader = new ColumnHeader();
visitCountColumnHeader.Text = StringParser.Parse("${res:ICSharpCode.CodeCoverage.VisitCount}");
visitCountColumnHeader.Width = 80;
visitCountColumnHeader.Width = -2;
startLineColumnHeader = new ColumnHeader();
startLineColumnHeader.Text = StringParser.Parse("${res:Global.TextLine}");
startLineColumnHeader.Width = 80;
startLineColumnHeader.Width = -2;
startColumnColumnHeader = new ColumnHeader();
startColumnColumnHeader.Text = StringParser.Parse("${res:ICSharpCode.CodeCoverage.Column}");
startColumnColumnHeader.Width = 80;
startColumnColumnHeader.Width = -2;
endLineColumnHeader = new ColumnHeader();
endLineColumnHeader.Text = StringParser.Parse("${res:ICSharpCode.CodeCoverage.EndLine}");
endLineColumnHeader.Width = 80;
endLineColumnHeader.Width = -2;
endColumnColumnHeader = new ColumnHeader();
endColumnColumnHeader.Text = StringParser.Parse("${res:ICSharpCode.CodeCoverage.EndColumn}");
endColumnColumnHeader.Width = 80;
endColumnColumnHeader.Width = -2;
contentColumnHeader = new ColumnHeader();
contentColumnHeader.Text = StringParser.Parse("${res:ICSharpCode.CodeCoverage.Content}");
contentColumnHeader.Width = 500;
listView.Columns.AddRange(new ColumnHeader[] {visitCountColumnHeader,
startLineColumnHeader,
startColumnColumnHeader,
endLineColumnHeader,
endColumnColumnHeader});
endColumnColumnHeader,
contentColumnHeader
});
// Create custom list view sorter.
sequencePointListViewSorter = new SequencePointListViewSorter(listView);

27
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageHighlighter.cs

@ -56,8 +56,8 @@ namespace ICSharpCode.CodeCoverage @@ -56,8 +56,8 @@ namespace ICSharpCode.CodeCoverage
int endOffset = document.PositionToOffset(sequencePoint.EndLine, sequencePoint.EndColumn);
ITextMarker marker = markerService.Create(startOffset, endOffset - startOffset);
marker.Tag = typeof(CodeCoverageHighlighter);
marker.BackgroundColor = GetSequencePointColor(sequencePoint);
marker.ForegroundColor = GetSequencePointForeColor(sequencePoint);
marker.BackgroundColor = GetSequencePointBackColor(sequencePoint).ToWpf();
marker.ForegroundColor = GetSequencePointForeColor(sequencePoint).ToWpf();
}
}
@ -107,21 +107,26 @@ namespace ICSharpCode.CodeCoverage @@ -107,21 +107,26 @@ namespace ICSharpCode.CodeCoverage
}
return true;
}
public static Color GetSequencePointColor(CodeCoverageSequencePoint sequencePoint)
{
public static System.Drawing.Color GetSequencePointBackColor(CodeCoverageSequencePoint sequencePoint) {
if (sequencePoint.VisitCount > 0) {
return CodeCoverageOptions.VisitedColor.ToWpf();
if ( sequencePoint.BranchCoverage == true ) {
return CodeCoverageOptions.VisitedColor;
}
return CodeCoverageOptions.PartVisitedColor;
}
return CodeCoverageOptions.NotVisitedColor.ToWpf();
return CodeCoverageOptions.NotVisitedColor;
}
public static Color GetSequencePointForeColor(CodeCoverageSequencePoint sequencePoint)
{
public static System.Drawing.Color GetSequencePointForeColor(CodeCoverageSequencePoint sequencePoint) {
if (sequencePoint.VisitCount > 0) {
return CodeCoverageOptions.VisitedForeColor.ToWpf();
if ( sequencePoint.BranchCoverage == true ) {
return CodeCoverageOptions.VisitedForeColor;
}
return CodeCoverageOptions.PartVisitedForeColor;
}
return CodeCoverageOptions.NotVisitedForeColor.ToWpf();
return CodeCoverageOptions.NotVisitedForeColor;
}
}
}

23
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageMethod.cs

@ -48,7 +48,9 @@ namespace ICSharpCode.CodeCoverage @@ -48,7 +48,9 @@ namespace ICSharpCode.CodeCoverage
}
public CodeCoverageMethod(string className, XElement reader)
: this(className, new CodeCoverageMethodElement(reader))
: this (className, reader, null) {}
public CodeCoverageMethod(string className, XElement reader, CodeCoverageResults parent)
: this(className, new CodeCoverageMethodElement(reader, parent))
{
}
@ -58,6 +60,13 @@ namespace ICSharpCode.CodeCoverage @@ -58,6 +60,13 @@ namespace ICSharpCode.CodeCoverage
IsProperty = element.IsProperty && IsPropertyMethodName();
IsGetter = element.IsGetter;
IsSetter = element.IsSetter;
this.IsVisited = element.IsVisited;
this.BranchCoverage = element.BranchCoverage;
this.BranchCoverageRatio = element.BranchCoverageRatio;
this.SequencePointsCount = element.SequencePointsCount;
this.sequencePoints = element.SequencePoints;
}
/// <summary>
@ -67,6 +76,11 @@ namespace ICSharpCode.CodeCoverage @@ -67,6 +76,11 @@ namespace ICSharpCode.CodeCoverage
public bool IsGetter { get; private set; }
public bool IsSetter { get; private set; }
public bool IsVisited { get; private set; }
public decimal BranchCoverage { get; private set; }
public Tuple<int,int> BranchCoverageRatio { get; private set; }
public int SequencePointsCount { get; private set; }
bool IsPropertyMethodName()
{
return name.Contains("get_") || name.Contains("set_");
@ -112,7 +126,7 @@ namespace ICSharpCode.CodeCoverage @@ -112,7 +126,7 @@ namespace ICSharpCode.CodeCoverage
get {
int count = 0;
foreach (CodeCoverageSequencePoint sequencePoint in sequencePoints) {
if (sequencePoint.VisitCount > 0) {
if (sequencePoint.VisitCount != 0) {
count++;
}
}
@ -136,7 +150,7 @@ namespace ICSharpCode.CodeCoverage @@ -136,7 +150,7 @@ namespace ICSharpCode.CodeCoverage
{
int total = 0;
foreach (CodeCoverageSequencePoint sequencePoint in sequencePoints) {
if (sequencePoint.VisitCount > 0) {
if (sequencePoint.VisitCount != 0) {
total += sequencePoint.Length;
}
}
@ -214,8 +228,9 @@ namespace ICSharpCode.CodeCoverage @@ -214,8 +228,9 @@ namespace ICSharpCode.CodeCoverage
public static List<CodeCoverageMethod> GetAllMethods(List<CodeCoverageMethod> methods, string namespaceStartsWith)
{
List<CodeCoverageMethod> matchedMethods = new List<CodeCoverageMethod>();
namespaceStartsWith += ".";
foreach (CodeCoverageMethod method in methods) {
if (method.ClassNamespace.StartsWith(namespaceStartsWith)) {
if ((method.ClassNamespace+".").StartsWith(namespaceStartsWith)) {
matchedMethods.Add(method);
}
}

396
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageMethodElement.cs

@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
// 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
@ -17,6 +17,12 @@ @@ -17,6 +17,12 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml.Linq;
namespace ICSharpCode.CodeCoverage
@ -24,13 +30,36 @@ namespace ICSharpCode.CodeCoverage @@ -24,13 +30,36 @@ namespace ICSharpCode.CodeCoverage
public class CodeCoverageMethodElement
{
XElement element;
CodeCoverageResults parent;
public CodeCoverageMethodElement(XElement element)
: this (element, null) {}
public CodeCoverageMethodElement(XElement element, CodeCoverageResults parent)
{
this.parent = parent;
this.element = element;
this.SequencePoints = new List<CodeCoverageSequencePoint>();
this.BranchPoints = new List<CodeCoverageBranchPoint>();
Init();
}
private static string cacheFileName = String.Empty;
private static CodeCoverageStringTextSource cacheDocument = null;
public string FileID { get; private set; }
public string FileName { get; private set; }
public bool IsVisited { get; private set; }
public int CyclomaticComplexity { get; private set; }
public decimal SequenceCoverage { get; private set; }
public int SequencePointsCount { get; private set; }
public decimal BranchCoverage { get; private set; }
public Tuple<int,int> BranchCoverageRatio { get; private set; }
public bool IsConstructor { get; private set; }
public bool IsStatic { get; private set; }
public List<CodeCoverageSequencePoint> SequencePoints { get; private set; }
public CodeCoverageSequencePoint BodyStartSP { get; private set; }
public CodeCoverageSequencePoint BodyFinalSP { get; private set; }
public List<CodeCoverageBranchPoint> BranchPoints { get; private set; }
public bool IsGetter { get; private set; }
public bool IsSetter { get; private set; }
public string MethodName { get; private set; }
@ -38,12 +67,355 @@ namespace ICSharpCode.CodeCoverage @@ -38,12 +67,355 @@ namespace ICSharpCode.CodeCoverage
public bool IsProperty {
get { return IsGetter || IsSetter; }
}
void Init()
{
MethodName = GetMethodName();
IsGetter = GetBooleanAttributeValue("isGetter");
IsSetter = GetBooleanAttributeValue("isSetter");
MethodName = GetMethodName();
this.FileID = GetFileRef();
this.FileName = String.Empty;
if (!String.IsNullOrEmpty(this.FileID)) {
if (parent != null) {
this.FileName = parent.GetFileName(this.FileID);
if ( File.Exists(this.FileName) ) {
if (cacheFileName != this.FileName) {
cacheFileName = this.FileName;
cacheDocument = null;
try {
using (Stream stream = new FileStream(this.FileName, FileMode.Open, FileAccess.Read)) {
try {
stream.Position = 0;
string textSource = ICSharpCode.AvalonEdit.Utils.FileReader.ReadFileContent(stream, Encoding.Default);
cacheDocument = new CodeCoverageStringTextSource(textSource);
} catch {}
}
} catch {}
}
}
}
}
this.IsVisited = this.GetBooleanAttributeValue("visited");
this.CyclomaticComplexity = (int)this.GetDecimalAttributeValue("cyclomaticComplexity");
this.SequencePointsCount = this.GetSequencePointsCount();
this.SequenceCoverage = (int)this.GetDecimalAttributeValue("sequenceCoverage");
this.IsConstructor = this.GetBooleanAttributeValue("isConstructor");
this.IsStatic = this.GetBooleanAttributeValue("isStatic");
if ( !String.IsNullOrEmpty( this.FileID ) ) {
this.GetSequencePoints();
this.GetSequencePointsContent();
this.getBodyStartSP(); // before OrderBy Line/Col
this.getBodyFinalSP(); // before orderBy Line/Col
this.FilterSequencePoints(); // before orderBy Line/Col
this.GetBranchPoints();
this.GetBranchRatio();
this.GetBranchCoverage();
// SP's are originaly ordered by CIL offset
// but ccrewrite can move offset of
// Contract.Requires before method signature SP { and
// Contract.Ensures after method closing SP }
// So sort SP's back by line/column
this.SequencePoints.OrderBy(item => item.Line).OrderBy(item => item.Column);
}
}
void GetSequencePoints() {
var xSPoints = this.element
.Elements("SequencePoints")
.Elements("SequencePoint");
foreach (XElement xSPoint in xSPoints) {
CodeCoverageSequencePoint sp = new CodeCoverageSequencePoint();
sp.FileID = this.FileID;
sp.Document = this.FileName;
sp.Line = (int)GetDecimalAttributeValue(xSPoint.Attribute("sl"));
sp.EndLine = (int)GetDecimalAttributeValue(xSPoint.Attribute("el"));
sp.Column = (int)GetDecimalAttributeValue(xSPoint.Attribute("sc"));
sp.EndColumn = (int)GetDecimalAttributeValue(xSPoint.Attribute("ec"));
sp.VisitCount = (int)GetDecimalAttributeValue(xSPoint.Attribute("vc"));
sp.Offset = (int)GetDecimalAttributeValue(xSPoint.Attribute("offset"));
sp.BranchCoverage = true;
sp.Content = String.Empty;
sp.Length = 0;
this.SequencePoints.Add(sp);
}
}
void GetSequencePointsContent()
{
if (cacheFileName == this.FileName && cacheDocument != null) {
foreach (var sp in this.SequencePoints) {
GetSequencePointContent(sp);
}
}
}
void GetSequencePointContent(CodeCoverageSequencePoint sp)
{
// ccrewrite will cause lots of invalid calls to GetText()!
if (cacheFileName == sp.Document && cacheDocument != null) {
sp.Content = cacheDocument.GetText(sp); // never returns null
if (sp.Content != String.Empty) {
if (sp.Line != sp.EndLine) {
// merge lines to single line
sp.Content = Regex.Replace(sp.Content, @"\s+", " ");
}
// SequencePoint.Length counts all but whitespace
sp.Length = Regex.Replace(sp.Content, @"\s", "").Length;
}
}
}
// Find method-body start SequencePoint "{" (sp.Content required)
// Sequence points expected to be ordered by Offset
// Cannot just get first one because of ccrewrite&ContractClassFor
void getBodyStartSP() {
bool startPointFound = false;
CodeCoverageSequencePoint startSeqPoint = null;
foreach (CodeCoverageSequencePoint sp in this.SequencePoints) {
if ( sp.Content == "{") {
if ( this.IsConstructor ) {
// take previous/last one if not null
startSeqPoint = startSeqPoint?? sp;
}
else {
startSeqPoint = sp;
}
startPointFound = true;
break;
}
startSeqPoint = sp;
}
this.BodyStartSP = startPointFound? startSeqPoint: null;
}
// Find method-body final SequencePoint "}" (sp.Content required)
// Sequence points expected to be ordered by Offset
void getBodyFinalSP() {
CodeCoverageSequencePoint finalSeqPoint = null;
foreach (CodeCoverageSequencePoint sp in ((IEnumerable<CodeCoverageSequencePoint>)this.SequencePoints).Reverse()) {
if ( sp.Content == "}") {
if (finalSeqPoint == null) {
finalSeqPoint = sp;
}
// check for ccrewrite duplicate
else if (sp.Line == finalSeqPoint.Line &&
sp.Column == finalSeqPoint.Column &&
sp.EndLine == finalSeqPoint.EndLine &&
sp.EndColumn == finalSeqPoint.EndColumn &&
sp.Offset < finalSeqPoint.Offset) {
finalSeqPoint = sp;
// duplicate found, so far no reason to expect "triplicate" :)
break;
}
}
}
this.BodyFinalSP = finalSeqPoint;
}
void FilterSequencePoints() {
if (this.SequencePoints.Count != 0 &&
this.BodyStartSP != null &&
this.BodyFinalSP != null ) {
// After ccrewrite ContractClass/ContractClassFor
// sequence point(s) from another file/class/method
// is inserted into this method sequence points
//
// To remove alien sequence points, all sequence points on lines
// before method signature and after end-brackets xxx{} are removed
// If ContractClassFor is in another file but interleaves this method lines
// then, afaik, not much can be done to remove inserted alien SP's
var selected = new List<CodeCoverageSequencePoint>();
foreach (var point in this.SequencePoints) {
// if Content.Length is 0, GetText() is failed by ccrewrite inserted invalid SequencePoint
if (point.Content.Length != 0
&& (point.Line > BodyStartSP.Line || (point.Line == BodyStartSP.Line && point.Column >= BodyStartSP.Column))
&& (point.Line < BodyFinalSP.Line || (point.Line == BodyFinalSP.Line && point.Column < BodyFinalSP.Column))
) {
selected.Add (point);
}
// After ccrewrite ContractClass/ContractClassFor
// duplicate method end-sequence-point "}" is added
//
// Add only first finalSP (can be a duplicate)
// Note: IL.Offset of second duplicate finalSP will
// extend branch coverage outside method-end "}",
// and that can lead to wrong branch coverage display!
if (object.ReferenceEquals (point, this.BodyFinalSP)) {
selected.Add (point);
}
}
this.SequencePoints = selected;
}
}
int GetSequencePointsCount() {
XElement summary = this.element.Element("Summary");
if ( summary != null ) {
XAttribute nsp = summary.Attribute("numSequencePoints");
if ( nsp != null ) {
return (int)GetDecimalAttributeValue( nsp );
}
}
return 0;
}
void GetBranchPoints() {
// get all BranchPoints
var xBPoints = this.element
.Elements("BranchPoints")
.Elements("BranchPoint");
foreach (XElement xBPoint in xBPoints) {
CodeCoverageBranchPoint bp = new CodeCoverageBranchPoint();
bp.VisitCount = (int)GetDecimalAttributeValue(xBPoint.Attribute("vc"));
bp.Offset = (int)GetDecimalAttributeValue(xBPoint.Attribute("offset"));
bp.Path = (int)GetDecimalAttributeValue(xBPoint.Attribute("path"));
bp.OffsetEnd = (int)GetDecimalAttributeValue(xBPoint.Attribute("offsetend"));
this.BranchPoints.Add(bp);
}
}
void GetBranchRatio () {
// goal: Get branch ratio, merge branch-exits and exclude (rewriten) Code Contracts branches
this.BranchCoverageRatio = null;
if ( this.BranchPoints == null
|| this.BranchPoints.Count == 0
|| this.SequencePoints == null
|| this.SequencePoints.Count == 0
)
{
return;
}
// This sequence point offset is used to skip CCRewrite(n) BranchPoint's (Requires)
// and '{' branches at static methods
if (this.BodyStartSP == null) { return; } // empty body
// This sequence point offset is used to skip CCRewrite(n) BranchPoint's (Ensures)
if (this.BodyFinalSP == null) { return; } // empty body
// Connect Sequence & Branches
IEnumerator<CodeCoverageSequencePoint> SPEnumerator = this.SequencePoints.GetEnumerator();
CodeCoverageSequencePoint currSeqPoint = this.BodyStartSP;
int nextSeqPointOffset = BodyStartSP.Offset;
foreach (var bp in this.BranchPoints) {
// ignore branches outside of method body offset range
if (bp.Offset < BodyStartSP.Offset)
continue;
if (bp.Offset > BodyFinalSP.Offset)
break;
// Sync with SequencePoint
while ( nextSeqPointOffset < bp.Offset ) {
currSeqPoint = SPEnumerator.Current;
if ( SPEnumerator.MoveNext() ) {
nextSeqPointOffset = SPEnumerator.Current.Offset;
} else {
nextSeqPointOffset = int.MaxValue;
}
}
if (currSeqPoint.Branches == null) {
currSeqPoint.Branches = new List<CodeCoverageBranchPoint>();
}
// Add Branch to Branches
currSeqPoint.Branches.Add(bp);
}
// Merge sp.Branches on exit-offset
// Calculate Method Branch coverage
int totalBranchVisit = 0;
int totalBranchCount = 0;
int pointBranchVisit = 0;
int pointBranchCount = 0;
Dictionary<int, CodeCoverageBranchPoint> bpExits = new Dictionary<int, CodeCoverageBranchPoint>();
foreach (var sp in this.SequencePoints) {
// SequencePoint covered & has branches?
if (sp.VisitCount != 0 && sp.Branches != null) {
// 1) Generated "in" code for IEnumerables contains hidden "try/catch/finally" branches that
// one do not want or cannot cover by test-case because is handled earlier at same method.
// ie: NullReferenceException in foreach loop is pre-handled at method entry, ie. by Contract.Require(items!=null)
// 2) Branches within sequence points "{" and "}" are not source branches but compiler generated branches
// ie: static methods start sequence point "{" contains compiler generated branches
// 3) Exclude Contract class (EnsuresOnThrow/Assert/Assume is inside method body)
// 4) Exclude NUnit Assert(.Throws) class
if (sp.Content == "in" || sp.Content == "{" || sp.Content == "}" ||
sp.Content.StartsWith("Assert.") ||
sp.Content.StartsWith("Assert ") ||
sp.Content.StartsWith("Contract.") ||
sp.Content.StartsWith("Contract ")
) {
sp.Branches = null;
continue; // skip
}
// Merge sp.Branches on OffsetEnd using bpExits key
bpExits.Clear();
foreach (var bp in sp.Branches) {
if (!bpExits.ContainsKey(bp.OffsetEnd)) {
bpExits[bp.OffsetEnd] = bp; // insert branch
} else {
bpExits[bp.OffsetEnd].VisitCount += bp.VisitCount; // update branch
}
}
// Compute branch coverage
pointBranchVisit = 0;
pointBranchCount = 0;
foreach (var bp in bpExits.Values) {
pointBranchVisit += bp.VisitCount == 0? 0 : 1 ;
pointBranchCount += 1;
}
// Not full coverage?
if (pointBranchVisit != pointBranchCount) {
sp.BranchCoverage = false; // => part-covered
}
totalBranchVisit += pointBranchVisit;
totalBranchCount += pointBranchCount;
}
if (sp.Branches != null)
sp.Branches = null; // release memory
}
this.BranchCoverageRatio = (totalBranchCount!=0) ? new Tuple<int,int>(totalBranchVisit,totalBranchCount) : null;
}
void GetBranchCoverage () {
this.BranchCoverage = this.BranchCoverageRatio == null ? 0m : ((decimal)(this.BranchCoverageRatio.Item1*100))/((decimal)this.BranchCoverageRatio.Item2);
}
decimal GetDecimalAttributeValue(string name)
{
return GetDecimalAttributeValue(element.Attribute(name));
}
decimal GetDecimalAttributeValue(XAttribute attribute)
{
if (attribute != null) {
decimal value = 0;
if (Decimal.TryParse(attribute.Value, out value)) {
return value;
}
}
return 0;
}
bool GetBooleanAttributeValue(string name)
@ -61,7 +433,15 @@ namespace ICSharpCode.CodeCoverage @@ -61,7 +433,15 @@ namespace ICSharpCode.CodeCoverage
}
return false;
}
string GetFileRef() {
XElement fileId = element.Element("FileRef");
if (fileId != null) {
return fileId.Attribute("uid").Value;
}
return String.Empty;
}
string GetMethodName()
{
XElement nameElement = element.Element("Name");

4
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageMethodTreeNode.cs

@ -30,7 +30,9 @@ namespace ICSharpCode.CodeCoverage @@ -30,7 +30,9 @@ namespace ICSharpCode.CodeCoverage
: base(method.Name,
CodeCoverageImageListIndex.Method,
method.GetVisitedCodeLength(),
method.GetUnvisitedCodeLength())
method.GetUnvisitedCodeLength(),
method.BranchCoverage
)
{
this.method = method;
}

10
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageMethodsTreeNode.cs

@ -38,14 +38,24 @@ namespace ICSharpCode.CodeCoverage @@ -38,14 +38,24 @@ namespace ICSharpCode.CodeCoverage
int visitedCodeLength = 0;
int unvisitedCodeLength = 0;
decimal branchCoverage = 0;
int branchCoverageCount = 0;
foreach (CodeCoverageMethod method in methods) {
if (method.Name.Contains("__")) {
continue;
}
visitedCodeLength += method.GetVisitedCodeLength();
unvisitedCodeLength += method.GetUnvisitedCodeLength();
if ( method.IsVisited ) {
branchCoverageCount += 1;
branchCoverage += method.BranchCoverage == 0 ? 100 : method.BranchCoverage ;
}
}
Name = name;
VisitedCodeLength = visitedCodeLength;
UnvisitedCodeLength = unvisitedCodeLength;
VisitedBranchCoverage = branchCoverageCount == 0 ? 100 : branchCoverage/branchCoverageCount;
}
void AddDummyNodeIfHasNoMethods()

15
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageModule.cs

@ -61,6 +61,21 @@ namespace ICSharpCode.CodeCoverage @@ -61,6 +61,21 @@ namespace ICSharpCode.CodeCoverage
return total;
}
public decimal GetVisitedBranchCoverage() {
decimal total = 0;
int count = 0;
foreach (CodeCoverageMethod method in methods) {
if (method.IsVisited) {
++count;
total += method.BranchCoverage == 0 ? 100 : method.BranchCoverage ;
}
}
if (count!=0) {
return total/count;
}
return 0;
}
public List<CodeCoverageSequencePoint> GetSequencePoints(string fileName)
{
List<CodeCoverageSequencePoint> sequencePoints = new List<CodeCoverageSequencePoint>();

19
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageOptions.cs

@ -29,6 +29,8 @@ namespace ICSharpCode.CodeCoverage @@ -29,6 +29,8 @@ namespace ICSharpCode.CodeCoverage
#region Property names
public static readonly string VisitedColorProperty = "VisitedColor";
public static readonly string VisitedForeColorProperty = "VisitedForeColor";
public static readonly string PartVisitedColorProperty = "PartVisitedColor";
public static readonly string PartVisitedForeColorProperty = "PartVisitedForeColor";
public static readonly string NotVisitedColorProperty = "NotVisitedColor";
public static readonly string NotVisitedForeColorProperty = "NotVisitedForeColor";
@ -90,6 +92,23 @@ namespace ICSharpCode.CodeCoverage @@ -90,6 +92,23 @@ namespace ICSharpCode.CodeCoverage
set { Properties.Set<Color>(VisitedForeColorProperty, value); }
}
/// <summary>
/// Gets the colour that will be used when highlighting visited code.
/// </summary>
public static Color PartVisitedColor {
get { return Properties.Get<Color>(PartVisitedColorProperty, Color.Yellow); }
set { Properties.Set<Color>(PartVisitedColorProperty, value); }
}
/// <summary>
/// Gets the foreground colour that will be used when highlighting
/// visited code.
/// </summary>
public static Color PartVisitedForeColor {
get { return Properties.Get<Color>(PartVisitedForeColorProperty, Color.Black); }
set { Properties.Set<Color>(PartVisitedForeColorProperty, value); }
}
/// <summary>
/// Gets the colour that will be used when highlighting code that has not
/// been visited.

1
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageOptionsPanel.xaml.cs

@ -47,6 +47,7 @@ namespace ICSharpCode.CodeCoverage @@ -47,6 +47,7 @@ namespace ICSharpCode.CodeCoverage
DataContext = this;
DisplayItems = new ObservableCollection<CodeCoverageDisplayItem>();
DisplayItems.Add(new CodeCoverageDisplayItem(StringParser.Parse("${res:ICSharpCode.CodeCoverage.CodeCovered}"), CodeCoverageOptions.VisitedColorProperty, CodeCoverageOptions.VisitedColor, CodeCoverageOptions.VisitedForeColorProperty, CodeCoverageOptions.VisitedForeColor));
DisplayItems.Add(new CodeCoverageDisplayItem(StringParser.Parse("${res:ICSharpCode.CodeCoverage.CodePartCovered}"), CodeCoverageOptions.PartVisitedColorProperty, CodeCoverageOptions.PartVisitedColor, CodeCoverageOptions.PartVisitedForeColorProperty, CodeCoverageOptions.PartVisitedForeColor));
DisplayItems.Add(new CodeCoverageDisplayItem(StringParser.Parse("${res:ICSharpCode.CodeCoverage.CodeNotCovered}"), CodeCoverageOptions.NotVisitedColorProperty, CodeCoverageOptions.NotVisitedColor, CodeCoverageOptions.NotVisitedForeColorProperty, CodeCoverageOptions.NotVisitedForeColor));
DisplayItem = DisplayItems[0];
}

53
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageResults.cs

@ -78,8 +78,9 @@ namespace ICSharpCode.CodeCoverage @@ -78,8 +78,9 @@ namespace ICSharpCode.CodeCoverage
var classNames =
assembly.Elements("Classes").Elements("Class").Where(
c =>
!c.Element("FullName").Value.Contains("__") && !c.Element("FullName").Value.Contains("<") &&
!c.Element("FullName").Value.Contains("/") && c.Attribute("skippedDueTo") == null).Select(
!c.Element("FullName").Value.Contains("__") &&
//!c.Element("FullName").Value.Contains("<") &&
c.Attribute("skippedDueTo") == null).Select(
c => c.Element("FullName").Value).Distinct().OrderBy(name => name);
foreach (string className in classNames) {
AddModule(assembly, className);
@ -110,7 +111,7 @@ namespace ICSharpCode.CodeCoverage @@ -110,7 +111,7 @@ namespace ICSharpCode.CodeCoverage
.Elements("Methods")
.Elements("Method");
foreach (XElement method in methods) {
AddMethod(module, className, method);
AddMethod(module, className.Replace('/','.'), method);
}
return module;
}
@ -120,51 +121,37 @@ namespace ICSharpCode.CodeCoverage @@ -120,51 +121,37 @@ namespace ICSharpCode.CodeCoverage
string id = reader.Attribute("hash").Value;
return GetAssembly(id);
}
CodeCoverageMethod AddMethod(CodeCoverageModule module, string className, XElement reader)
{
CodeCoverageMethod method = new CodeCoverageMethod(className, reader);
module.Methods.Add(method);
var points = reader
.Elements("SequencePoints")
.Elements("SequencePoint");
foreach (XElement point in points) {
AddSequencePoint(method, point, reader);
}
return method;
}
/// <summary>
/// Sequence points that do not have a file id are not
/// added to the code coverage method. Typically these are
/// for types that are not part of the project but types from
/// the .NET framework.
/// </summary>
void AddSequencePoint(CodeCoverageMethod method, XElement reader, XElement methodNode)
{
string fileName = GetFileName(methodNode);
CodeCoverageSequencePoint sequencePoint =
new CodeCoverageSequencePoint(fileName, reader);
method.SequencePoints.Add(sequencePoint);
}
string GetFileName(XElement reader)
CodeCoverageMethod AddMethod(CodeCoverageModule module, string className, XElement reader)
{
XElement fileId = reader.Element("FileRef");
if (fileId != null) {
return GetFileName(fileId.Attribute("uid").Value);
CodeCoverageMethod method = new CodeCoverageMethod(className, reader, this);
if (!method.Name.Contains("__")) {
module.Methods.Add(method);
}
return String.Empty;
return method;
}
/// <summary>
/// Cache result because same FileID is repeated for all (class.)method(s).SequencePoints
/// </summary>
private static Tuple<string,string> fileIdNameCache = new Tuple<string, string>(String.Empty,String.Empty);
/// <summary>
/// Returns a filename based on the file id. The filenames are stored in the
/// PartCover results xml at the start of the file each with its own id.
/// </summary>
string GetFileName(string id)
public string GetFileName(string id)
{
return GetDictionaryValue(fileNames, id);
if (fileIdNameCache.Item1 != id) {
fileIdNameCache = new Tuple<string, string>(id, GetDictionaryValue(fileNames, id));
}
return fileIdNameCache.Item2;
}
/// <summary>

6
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageSequencePoint.cs

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Xml.Linq;
namespace ICSharpCode.CodeCoverage
@ -79,13 +80,18 @@ namespace ICSharpCode.CodeCoverage @@ -79,13 +80,18 @@ namespace ICSharpCode.CodeCoverage
return !String.IsNullOrEmpty(Document);
}
public string FileID { get; set; }
public string Document { get; set; }
public string Content { get; set; }
public int VisitCount { get; set; }
public int Line { get; set; }
public int Column { get; set; }
public int EndLine { get; set; }
public int EndColumn { get; set; }
public int Length { get; set; }
public int Offset { get; set; }
public bool BranchCoverage { get; set; }
public List<CodeCoverageBranchPoint> Branches { get; set; }
public override bool Equals(object obj)
{

217
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageStringTextSource.cs

@ -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;
}
}
}

35
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageTreeNode.cs

@ -30,18 +30,24 @@ namespace ICSharpCode.CodeCoverage @@ -30,18 +30,24 @@ namespace ICSharpCode.CodeCoverage
/// Code coverage is less than one hundred percent.
/// </summary>
public static readonly Color PartialCoverageTextColor = Color.Red;
/// <summary>
/// Code coverage is 100% but branch coverage is not 0%(no branches present) or 100%(all branches covered)
/// </summary>
public static readonly Color PartialBranchesTextColor = Color.DarkGreen;
/// <summary>
/// Code coverage is zero.
/// </summary>
public static readonly Color ZeroCoverageTextColor = Color.Gray;
int visitedCodeLength;
int unvisitedCodeLength;
int unvisitedCodeLength;
decimal visitedBranchCoverage;
int baseImageIndex;
public CodeCoverageTreeNode(string name, CodeCoverageImageListIndex index)
: this(name, index, 0, 0)
: this(name, index, 0, 0, 0)
{
}
@ -49,15 +55,18 @@ namespace ICSharpCode.CodeCoverage @@ -49,15 +55,18 @@ namespace ICSharpCode.CodeCoverage
: this(codeCoverageWithVisits.Name,
index,
codeCoverageWithVisits.GetVisitedCodeLength(),
codeCoverageWithVisits.GetUnvisitedCodeLength())
codeCoverageWithVisits.GetUnvisitedCodeLength(),
codeCoverageWithVisits.GetVisitedBranchCoverage()
)
{
}
public CodeCoverageTreeNode(string name, CodeCoverageImageListIndex index, int visitedCodeLength, int unvisitedCodeLength)
public CodeCoverageTreeNode(string name, CodeCoverageImageListIndex index, int visitedCodeLength, int unvisitedCodeLength, decimal visitedBranchCoverage = 100)
{
sortOrder = 10;
this.visitedCodeLength = visitedCodeLength;
this.unvisitedCodeLength = unvisitedCodeLength;
this.visitedBranchCoverage = visitedBranchCoverage;
Name = name;
SetText();
@ -78,6 +87,8 @@ namespace ICSharpCode.CodeCoverage @@ -78,6 +87,8 @@ namespace ICSharpCode.CodeCoverage
ForeColor = ZeroCoverageTextColor;
} else if(TotalCodeLength != visitedCodeLength) {
ForeColor = PartialCoverageTextColor;
} else if(TotalCodeLength == visitedCodeLength && VisitedBranchCoverage != 0 && VisitedBranchCoverage != 100 ) {
ForeColor = PartialBranchesTextColor;
} else {
ForeColor = Color.Empty;
}
@ -91,6 +102,9 @@ namespace ICSharpCode.CodeCoverage @@ -91,6 +102,9 @@ namespace ICSharpCode.CodeCoverage
string GetNodeText()
{
if (TotalCodeLength > 0) {
if ( visitedCodeLength == TotalCodeLength && visitedBranchCoverage != 0 && visitedBranchCoverage != 100 ) {
return String.Format("{0} (100%/{1}%)", Name, decimal.Round (visitedBranchCoverage, 2));
}
int percentage = GetPercentage();
return String.Format("{0} ({1}%)", Name, percentage);
}
@ -99,8 +113,7 @@ namespace ICSharpCode.CodeCoverage @@ -99,8 +113,7 @@ namespace ICSharpCode.CodeCoverage
int GetPercentage()
{
int percentage = (visitedCodeLength * 100) / TotalCodeLength;
return percentage;
return TotalCodeLength == 0? 0 : (int)decimal.Round((((decimal)visitedCodeLength * 100) / (decimal)TotalCodeLength), 0);
}
void SetImageIndex()
@ -133,6 +146,14 @@ namespace ICSharpCode.CodeCoverage @@ -133,6 +146,14 @@ namespace ICSharpCode.CodeCoverage
get { return visitedCodeLength + unvisitedCodeLength; }
}
public decimal VisitedBranchCoverage {
get { return visitedBranchCoverage; }
set {
visitedBranchCoverage = value;
SetText();
}
}
/// <summary>
/// Gets the string to use when sorting the code coverage tree node.
/// </summary>

1
src/AddIns/Analysis/CodeCoverage/Project/Src/ICodeCoverageWithVisits.cs

@ -25,5 +25,6 @@ namespace ICSharpCode.CodeCoverage @@ -25,5 +25,6 @@ namespace ICSharpCode.CodeCoverage
string Name { get; }
int GetVisitedCodeLength();
int GetUnvisitedCodeLength();
decimal GetVisitedBranchCoverage();
}
}

17
src/AddIns/Analysis/CodeCoverage/Test/Coverage/CodeCoverageResultsMissingFileIdTestFixture.cs

@ -111,15 +111,28 @@ namespace ICSharpCode.CodeCoverage.Tests.Coverage @@ -111,15 +111,28 @@ namespace ICSharpCode.CodeCoverage.Tests.Coverage
Assert.AreEqual(expectedName, name);
}
[Test]
[Test, Ignore("Replaced by test below")]
public void SequencePointsCount_NUnitNotEqualAssertFailMethod_ReturnsAllSequencePoints()
{
int sequencePointCount = FirstModuleFirstMethod.SequencePoints.Count;
int expectedSequencePointCount = 3;
Assert.AreEqual(expectedSequencePointCount, sequencePointCount);
}
/// <summary> No FileID => No sequence points!
/// SD.CodeCoverage DOES NOT RETURN SequencePoints
/// for assemblies without debug info,
/// =&gt; methods without FileID
/// </summary>
[Test]
public void SequencePointsCount_NUnitNotEqualAssertFailMethod_ReturnsNoSequencePoints()
{
int sequencePointCount = FirstModuleFirstMethod.SequencePoints.Count;
int expectedSequencePointCount = 0;
Assert.AreEqual(expectedSequencePointCount, sequencePointCount);
}
[Test, Ignore("SequencePoint.FileID DOES NOT EXISTS in Fixture above! This must be very OLD test.")]
public void SequencePointsCount_MyClassConstructorHasFourSequencePointsWithOneMissingFileId_ReturnsAllSequencePoints()
{
int sequencePointCount = SecondModule.Methods[0].SequencePoints.Count;

6
src/AddIns/Analysis/CodeCoverage/Test/Coverage/CodeCoverageResultsTestFixture.cs

@ -123,7 +123,7 @@ namespace ICSharpCode.CodeCoverage.Tests.Coverage @@ -123,7 +123,7 @@ namespace ICSharpCode.CodeCoverage.Tests.Coverage
Assert.AreEqual(3, count);
}
[Test]
[Test, Ignore("SequencePoint.Length is not 1 anymore")]
public void SequencePoint_FirstSequencePoint_HasExpectedPropertyValues()
{
CodeCoverageSequencePoint point = base.CreateSequencePoint();
@ -166,14 +166,14 @@ namespace ICSharpCode.CodeCoverage.Tests.Coverage @@ -166,14 +166,14 @@ namespace ICSharpCode.CodeCoverage.Tests.Coverage
Assert.AreEqual(1, count);
}
[Test]
[Test, Ignore("SequencePoint.Length is not 1 anymore")]
public void GetVisitedCodeLength_FirstMethod_ReturnsSummedLengthOfVisitedSequencePoints()
{
int length = FirstModuleFirstMethod.GetVisitedCodeLength();
Assert.AreEqual(2, length);
}
[Test]
[Test, Ignore("SequencePoint.Length is not 1 anymore")]
public void GetUnvisitedCodeLength_FirstMethod_ReturnsSummedLengthOfUnvisitedSequencePoints()
{
int length = FirstModuleFirstMethod.GetUnvisitedCodeLength();

8
src/AddIns/Analysis/CodeCoverage/Test/Coverage/ModuleVisitedSequencePointsTestFixture.cs

@ -110,7 +110,7 @@ namespace ICSharpCode.CodeCoverage.Tests.Coverage @@ -110,7 +110,7 @@ namespace ICSharpCode.CodeCoverage.Tests.Coverage
get { return SecondModule; }
}
[Test]
[Test, Ignore("SequencePoint.Length is not 1 anymore")]
public void ModuleGetVisitedCodeLength_FooModule_ReturnsTotalLengthOfAllVisitedMethodSequencePoints()
{
int length = FooModule.GetVisitedCodeLength();
@ -118,7 +118,7 @@ namespace ICSharpCode.CodeCoverage.Tests.Coverage @@ -118,7 +118,7 @@ namespace ICSharpCode.CodeCoverage.Tests.Coverage
Assert.AreEqual(expectedLength, length);
}
[Test]
[Test, Ignore("SequencePoint.Length is not 1 anymore")]
public void ModuleGetUnvisitedCodeLength_FooModule_ReturnsTotalLengthOfAllNonVisitedMethodSequencePoints()
{
int length = FooModule.GetUnvisitedCodeLength();
@ -126,7 +126,7 @@ namespace ICSharpCode.CodeCoverage.Tests.Coverage @@ -126,7 +126,7 @@ namespace ICSharpCode.CodeCoverage.Tests.Coverage
Assert.AreEqual(expectedLength, length);
}
[Test]
[Test, Ignore("SequencePoint.Length is not 1 anymore")]
public void ModuleGetVisitedCodeLength_BarModule_ReturnsTotalLengthOfAllVisitedMethodSequencePoints()
{
int length = BarModule.GetVisitedCodeLength();
@ -134,7 +134,7 @@ namespace ICSharpCode.CodeCoverage.Tests.Coverage @@ -134,7 +134,7 @@ namespace ICSharpCode.CodeCoverage.Tests.Coverage
Assert.AreEqual(expectedLength, length);
}
[Test]
[Test, Ignore("SequencePoint.Length is not 1 anymore")]
public void ModuleGetUnvisitedCodeLength_BarModule_ReturnsTotalLengthOfAllNonVisitedMethodSequencePoints()
{
int length = BarModule.GetUnvisitedCodeLength();

1
src/AddIns/Analysis/CodeQuality/Gui/MainView.xaml

@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
<DockPanel>
<ToolBar DockPanel.Dock="Top">
<Button Click="AddAssemblyClick">Add Assembly</Button>
<Button Click="AddCurrentProjectAssemblyClick">Add Current Project Assembly</Button>
<Menu Background="White" x:Name="printMenu" Visibility="Hidden">
<MenuItem Header="Reports">

18
src/AddIns/Analysis/CodeQuality/Gui/MainView.xaml.cs

@ -32,6 +32,7 @@ using ICSharpCode.CodeQuality.Engine.Dom; @@ -32,6 +32,7 @@ using ICSharpCode.CodeQuality.Engine.Dom;
using ICSharpCode.CodeQuality.Reporting;
using ICSharpCode.Reports.Core.WpfReportViewer;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
using Microsoft.Win32;
namespace ICSharpCode.CodeQuality.Gui
@ -70,6 +71,23 @@ namespace ICSharpCode.CodeQuality.Gui @@ -70,6 +71,23 @@ namespace ICSharpCode.CodeQuality.Gui
UpdateUI();
}
void AddCurrentProjectAssemblyClick(object sender, RoutedEventArgs e)
{
if (ProjectService.CurrentProject == null)
return;
string fileName = ProjectService.CurrentProject.OutputAssemblyFullPath;
if (string.IsNullOrEmpty(fileName))
{
MessageBox.Show("Project output assembly not found! Please build it first!");
return;
}
introBlock.Visibility = Visibility.Collapsed;
this.fileNames.Add(fileName);
Analyse(new string[] { fileName });
UpdateUI();
}
void Analyse (string[] fileNames)
{

95
src/AddIns/Analysis/UnitTesting/Interfaces/UnitTestDebuggerService.cs

@ -17,18 +17,101 @@ @@ -17,18 +17,101 @@
// DEALINGS IN THE SOFTWARE.
using System;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Debugging;
namespace ICSharpCode.UnitTesting
{
public class UnitTestDebuggerService : IUnitTestDebuggerService
public class UnitTestDebuggerService : BaseDebuggerService
{
public bool IsDebuggerLoaded {
get { return DebuggerService.IsDebuggerLoaded; }
public override bool CanDebug(ICSharpCode.SharpDevelop.Project.IProject project)
{
return SD.Debugger.CanDebug(project);
}
public IDebugger CurrentDebugger {
get { return DebuggerService.CurrentDebugger; }
public override bool Supports(DebuggerFeatures feature)
{
return SD.Debugger.Supports(feature);
}
public override void Start(System.Diagnostics.ProcessStartInfo processStartInfo)
{
SD.Debugger.Start(processStartInfo);
}
public override void StartWithoutDebugging(System.Diagnostics.ProcessStartInfo processStartInfo)
{
SD.Debugger.StartWithoutDebugging(processStartInfo);
}
public override void Stop()
{
SD.Debugger.Stop();
}
public override void Break()
{
SD.Debugger.Break();
}
public override void Continue()
{
SD.Debugger.Continue();
}
public override void StepInto()
{
SD.Debugger.StepInto();
}
public override void StepOver()
{
SD.Debugger.StepOver();
}
public override void StepOut()
{
SD.Debugger.StepOut();
}
public override void ShowAttachDialog()
{
SD.Debugger.ShowAttachDialog();
}
public override void Attach(System.Diagnostics.Process process)
{
SD.Debugger.Attach(process);
}
public override void Detach()
{
SD.Debugger.Detach();
}
public override bool SetInstructionPointer(string filename, int line, int column, bool dryRun)
{
return SD.Debugger.SetInstructionPointer(filename, line, column, dryRun);
}
public override void HandleToolTipRequest(ICSharpCode.SharpDevelop.Editor.ToolTipRequestEventArgs e)
{
SD.Debugger.HandleToolTipRequest(e);
}
public override void ToggleBreakpointAt(ICSharpCode.SharpDevelop.Editor.ITextEditor editor, int lineNumber)
{
SD.Debugger.ToggleBreakpointAt(editor, lineNumber);
}
public override void RemoveCurrentLineMarker()
{
SD.Debugger.RemoveCurrentLineMarker();
}
public override bool IsDebugging {
get { return SD.Debugger.IsDebugging; }
}
public override bool IsProcessRunning {
get {
return SD.Debugger.IsProcessRunning;
}
}
public override bool BreakAtBeginning {
get {
return SD.Debugger.BreakAtBeginning;
}
set {
SD.Debugger.BreakAtBeginning = value;
}
}
public override bool IsAttached {
get {
return SD.Debugger.IsAttached;
}
}
}
}

2
src/AddIns/Analysis/UnitTesting/NUnit/NUnitTestDebugger.cs

@ -38,7 +38,7 @@ namespace ICSharpCode.UnitTesting @@ -38,7 +38,7 @@ namespace ICSharpCode.UnitTesting
{
}
public NUnitTestDebugger(IUnitTestDebuggerService debuggerService,
public NUnitTestDebugger(IDebuggerService debuggerService,
IMessageService messageService,
ITestResultsReader testResultsReader,
UnitTestingOptions options)

11
src/AddIns/Analysis/UnitTesting/Pad/TestTreeView.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using ICSharpCode.Core;
using ICSharpCode.NRefactory.TypeSystem;
@ -52,15 +53,19 @@ namespace ICSharpCode.UnitTesting @@ -52,15 +53,19 @@ namespace ICSharpCode.UnitTesting
testSolution = value;
if (testSolution != null) {
this.Root = new UnitTestNode(testSolution);
this.Root.Children.CollectionChanged += delegate {
this.ShowRoot = this.Root != null && this.Root.Children.Count > 1;
};
this.Root.Children.CollectionChanged += OnRootChildrenCollectionChanged;
OnRootChildrenCollectionChanged(null, null);
} else {
this.Root = null;
}
}
}
void OnRootChildrenCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
this.ShowRoot = this.Root != null && this.Root.Children.Count > 1;
}
public TestTreeView()
{
this.ShowRoot = false;

10
src/AddIns/Analysis/UnitTesting/TestRunner/TestDebuggerBase.cs

@ -28,9 +28,8 @@ namespace ICSharpCode.UnitTesting @@ -28,9 +28,8 @@ namespace ICSharpCode.UnitTesting
{
public abstract class TestDebuggerBase : TestRunnerBase
{
IUnitTestDebuggerService debuggerService;
IMessageService messageService;
IDebugger debugger;
IDebuggerService debugger;
ITestResultsReader testResultsReader;
public TestDebuggerBase()
@ -40,14 +39,13 @@ namespace ICSharpCode.UnitTesting @@ -40,14 +39,13 @@ namespace ICSharpCode.UnitTesting
{
}
public TestDebuggerBase(IUnitTestDebuggerService debuggerService,
public TestDebuggerBase(IDebuggerService debuggerService,
IMessageService messageService,
ITestResultsReader testResultsReader)
{
this.debuggerService = debuggerService;
this.debugger = debuggerService;
this.messageService = messageService;
this.testResultsReader = testResultsReader;
this.debugger = debuggerService.CurrentDebugger;
testResultsReader.TestFinished += OnTestFinished;
}
@ -70,7 +68,7 @@ namespace ICSharpCode.UnitTesting @@ -70,7 +68,7 @@ namespace ICSharpCode.UnitTesting
}
public bool IsDebuggerRunning {
get { return debuggerService.IsDebuggerLoaded && debugger.IsDebugging; }
get { return debugger.IsDebuggerLoaded && debugger.IsDebugging; }
}
bool CanStopDebugging()

3
src/AddIns/Analysis/UnitTesting/UnitTesting.csproj

@ -56,6 +56,7 @@ @@ -56,6 +56,7 @@
<Compile Include="Commands\RunningTestsCondition.cs" />
<Compile Include="Commands\TestableCondition.cs" />
<Compile Include="Commands\UnitTestCommands.cs" />
<Compile Include="Interfaces\UnitTestDebuggerService.cs" />
<Compile Include="Pad\UnitTestNodeFactory.cs" />
<Compile Include="Service\ITestService.cs" />
<Compile Include="Model\ITest.cs" />
@ -64,7 +65,6 @@ @@ -64,7 +65,6 @@
<Compile Include="Model\ITestSolution.cs" />
<Compile Include="Model\TestBase.cs" />
<Compile Include="Interfaces\IBuildOptions.cs" />
<Compile Include="Interfaces\IUnitTestDebuggerService.cs" />
<Compile Include="Interfaces\IUnitTestSaveAllFilesCommand.cs" />
<Compile Include="Interfaces\IUnitTestTaskService.cs" />
<Compile Include="Interfaces\UnitTestBuildOptions.cs" />
@ -82,7 +82,6 @@ @@ -82,7 +82,6 @@
<Compile Include="Pad\TestTreeView.cs" />
<Compile Include="Pad\UnitTestNode.cs" />
<Compile Include="Pad\UnitTestsPad.cs" />
<Compile Include="Interfaces\UnitTestDebuggerService.cs" />
<Compile Include="Interfaces\UnitTestSaveAllFilesCommand.cs" />
<Compile Include="Interfaces\UnitTestTaskService.cs" />
<Compile Include="Model\TestSolution.cs" />

10
src/AddIns/BackendBindings/AspNet.Mvc/Project/Src/WebBehavior.cs

@ -112,7 +112,7 @@ namespace ICSharpCode.AspNet.Mvc @@ -112,7 +112,7 @@ namespace ICSharpCode.AspNet.Mvc
case StartAction.Program:
ProcessStartInfo processInfo = DotNetStartBehavior.CreateStartInfo(StartProgram, Project.Directory, StartWorkingDirectory, StartArguments);
if (withDebugging) {
DebuggerService.CurrentDebugger.Start(processInfo);
SD.Debugger.Start(processInfo);
} else {
Process.Start(processInfo);
}
@ -152,14 +152,14 @@ namespace ICSharpCode.AspNet.Mvc @@ -152,14 +152,14 @@ namespace ICSharpCode.AspNet.Mvc
int index = Array.FindIndex(processes, p => properties.UseIISExpress ? p.Id == LastStartedIISExpressProcessId : p.ProcessName.Equals(processName, StringComparison.OrdinalIgnoreCase));
if (index > -1) {
if (withDebugging)
DebuggerService.CurrentDebugger.Attach(processes[index]);
SD.Debugger.Attach(processes[index]);
} else {
if (properties.UseIISExpress) {
// start IIS express and attach to it
if (WebProjectService.IsIISExpressInstalled) {
ProcessStartInfo processInfo = IISExpressProcessStartInfo.Create(WebProject);
if (withDebugging) {
DebuggerService.CurrentDebugger.Start(processInfo);
SD.Debugger.Start(processInfo);
} else {
var process = Process.Start(processInfo);
LastStartedIISExpressProcessId = process.Id;
@ -192,9 +192,9 @@ namespace ICSharpCode.AspNet.Mvc @@ -192,9 +192,9 @@ namespace ICSharpCode.AspNet.Mvc
if (index == -1)
return;
if (withDebugging) {
DebuggerService.CurrentDebugger.Attach(processes[index]);
SD.Debugger.Attach(processes[index]);
if (!DebuggerService.CurrentDebugger.IsAttached) {
if (!SD.Debugger.IsAttached) {
if(properties.UseIIS) {
string format = ResourceService.GetString("ICSharpCode.WebProjectOptionsPanel.NoIISWP");
MessageService.ShowMessage(string.Format(format, processName));

1
src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin

@ -203,6 +203,7 @@ @@ -203,6 +203,7 @@
<Class class = "ICSharpCode.NRefactory.CSharp.Refactoring.CS0126ReturnMustBeFollowedByAnyExpression" />
<Class class = "ICSharpCode.NRefactory.CSharp.Refactoring.CS0127ReturnMustNotBeFollowedByAnyExpression" />
<Class class = "ICSharpCode.NRefactory.CSharp.Refactoring.CS0152DuplicateCaseLabelValueIssue" />
<Class class = "ICSharpCode.NRefactory.CSharp.Refactoring.CS0169FieldIsNeverUsedIssue" />
<Class class = "ICSharpCode.NRefactory.CSharp.Refactoring.CS0183ExpressionIsAlwaysOfProvidedTypeIssue" />
<Class class = "ICSharpCode.NRefactory.CSharp.Refactoring.CS0618UsageOfObsoleteMemberIssue" />
<Class class = "ICSharpCode.NRefactory.CSharp.Refactoring.CS0659ClassOverrideEqualsWithoutGetHashCode" />

1
src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj

@ -103,6 +103,7 @@ @@ -103,6 +103,7 @@
<DependentUpon>InsertCtorDialog.xaml</DependentUpon>
</Compile>
<Compile Include="Src\Refactoring\InsertCtorSnippetRefactoring.cs" />
<Compile Include="Src\Refactoring\InsertionCursorLayer.cs" />
<Compile Include="Src\Refactoring\InsertionPoint.cs" />
<Compile Include="Src\Refactoring\IssueOptions.xaml.cs">
<DependentUpon>IssueOptions.xaml</DependentUpon>

13
src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs

@ -18,12 +18,12 @@ @@ -18,12 +18,12 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using ICSharpCode.NRefactory;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
using CSharpBinding.Completion;
using CSharpBinding.FormattingStrategy;
using CSharpBinding.Refactoring;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Rendering;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor;
@ -43,6 +43,13 @@ namespace CSharpBinding @@ -43,6 +43,13 @@ namespace CSharpBinding
this.container.AddService(typeof(CodeGenerator), new CSharpCodeGenerator());
this.container.AddService(typeof(System.CodeDom.Compiler.CodeDomProvider), new Microsoft.CSharp.CSharpCodeProvider());
}
public override ICodeCompletionBinding CreateCompletionBinding(FileName fileName, TextLocation currentLocation, ICSharpCode.NRefactory.Editor.ITextSource fileContent)
{
if (fileName == null)
throw new ArgumentNullException("fileName");
return new CSharpCompletionBinding(fileName, currentLocation, fileContent);
}
}
public class CSharpTextEditorExtension : ITextEditorExtension

294
src/AddIns/BackendBindings/CSharpBinding/Project/Src/CodeManipulation.cs

@ -20,7 +20,6 @@ using System; @@ -20,7 +20,6 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Input;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Editing;
using ICSharpCode.Core;
@ -148,188 +147,188 @@ namespace CSharpBinding @@ -148,188 +147,188 @@ namespace CSharpBinding
editor.ClearSelection();
}
// move selection - find outermost node in selection, swap selection with closest child of its parent to the selection
void MoveStatement(ITextEditor editor, MoveStatementDirection direction)
{
IList<AstNode> commentsBlankLines;
var parsedCU = ParseDocument(editor, out commentsBlankLines);
if (parsedCU == null) return;
if (parsedCU == null) return;
// Find the Statement or Definition containing caret -> Extend selection to Statement or Definition
var selectionStart = editor.Document.GetLocation(editor.SelectionStart);
var selectionEnd = editor.Document.GetLocation(editor.SelectionStart + editor.SelectionLength);
AstNode currentStatement;
Selection statementSelection = ExtendSelection(editor, parsedCU, commentsBlankLines, out currentStatement, new Type[] {
typeof(Statement),
typeof(EntityDeclaration) });
AstNode currentStatement = parsedCU.GetNodeContaining(selectionStart, selectionEnd);
if (currentStatement == null)
return;
statementSelection = TryExtendSelectionToComments(editor.Document, statementSelection, commentsBlankLines);
// Take its sibling
if (currentStatement.Parent == null)
var interestingNodeTypes = new[] {
typeof(Statement), typeof(EntityDeclaration), typeof(UsingDeclaration),
typeof(NewLineNode), typeof(Comment), typeof(PreProcessorDirective)
};
if (!IsNodeTypeInteresting(currentStatement, interestingNodeTypes)) {
// Ignore non-interesting nodes in the AST
currentStatement = GetInterestingParent(currentStatement, interestingNodeTypes);
}
if (currentStatement == null)
return;
var siblings = currentStatement.Parent.Children.Where(c => (c.Role.GetType() == currentStatement.Role.GetType())).ToList();
int currentStatementStartPos = siblings.IndexOf(currentStatement);
int currentStatementEndPos = currentStatementStartPos;
AstNode swapStartSibling = null;
AstNode swapEndSibling = null;
// Expand selection to full line, if there is more than one statement in it
AstNode currentSelectionStartNode = currentStatement;
while ((currentSelectionStartNode.PrevSibling != null)
&& !(currentSelectionStartNode.PrevSibling is NewLineNode)
&& (currentSelectionStartNode.Parent == currentSelectionStartNode.PrevSibling.Parent)) {
currentSelectionStartNode = currentSelectionStartNode.PrevSibling;
if (currentSelectionStartNode.EndLocation.Line >= statementSelection.Start.Line) {
statementSelection.Start = currentSelectionStartNode.StartLocation;
if (!(currentSelectionStartNode is Comment))
currentStatementStartPos--;
} else {
// This node won't belong to current selection, so go back to next element
currentSelectionStartNode = currentSelectionStartNode.NextSibling;
break;
}
List<AstNode> currentStatementSiblings = null;
if ((currentStatement is BlockStatement) &&
((currentStatement.Parent is Statement) || (currentStatement.Parent is EntityDeclaration)) &&
!(currentStatement.Parent is BlockStatement)) {
// Extend current statement to owner of this block statement
currentStatement = currentStatement.Parent;
}
AstNode currentSelectionEndNode = currentStatement;
while ((currentSelectionEndNode.NextSibling != null)
&& !(currentSelectionEndNode.NextSibling is NewLineNode)
&& (currentSelectionEndNode.Parent == currentSelectionEndNode.NextSibling.Parent)) {
currentSelectionEndNode = currentSelectionEndNode.NextSibling;
if (currentSelectionEndNode.StartLocation.Line <= statementSelection.End.Line) {
statementSelection.End = currentSelectionEndNode.EndLocation;
if (!(currentSelectionEndNode is Comment))
currentStatementEndPos++;
} else {
// This node won't belong to current selection, so go back to next element
currentSelectionEndNode = currentSelectionEndNode.NextSibling;
break;
}
if ((currentStatement is Comment) && ((Comment) currentStatement).IsDocumentation &&
(currentStatement.Parent is EntityDeclaration)) {
// Documentation comments belong to their method declaration
currentStatement = currentStatement.Parent;
}
int swapIndex = 0;
if (direction == MoveStatementDirection.Down) {
swapIndex = currentStatementEndPos + 1;
currentStatementSiblings = currentStatement.Parent.Children.Where(
c => IsNodeTypeInteresting(c, interestingNodeTypes) && !(c is NewLineNode)
).ToList();
// Collect all statements intersecting with selection lines
Func<AstNode, bool> selectionExpansionPredicate = node =>
((node.EndLocation.Line >= selectionStart.Line) && (node.StartLocation.Line <= selectionEnd.Line));
var selectedStatements = currentStatementSiblings.Where(selectionExpansionPredicate);
if (!selectedStatements.Any())
return;
// Find out which nodes we have to swap selected statements with
AstNode swapSibling = null;
if (direction == MoveStatementDirection.Up) {
int indexOfFirstSelectedSibling = currentStatementSiblings.IndexOf(selectedStatements.First());
swapSibling = (indexOfFirstSelectedSibling > 0) ? currentStatementSiblings[indexOfFirstSelectedSibling - 1] : null;
} else {
swapIndex = currentStatementStartPos - 1;
int indexOfLastSelectedSibling = currentStatementSiblings.IndexOf(selectedStatements.Last());
swapSibling = (indexOfLastSelectedSibling < currentStatementSiblings.Count - 1) ? currentStatementSiblings[indexOfLastSelectedSibling + 1] : null;
}
Func<AstNode, bool> isAllowedGrandParentNode =
(n => (n is IfElseStatement) || (n is ForStatement) || (n is ForeachStatement) || (n is WhileStatement) || (n is DoWhileStatement));
if (swapIndex < 0) {
// This is the 1st statement in block, so swap it with beginning of the block to get it outside of it
var parentNode = currentStatement.Parent as BlockStatement;
if (parentNode != null) {
var grandParentNode = parentNode.Parent;
if ((grandParentNode != null) && isAllowedGrandParentNode(grandParentNode)) {
// Swap with head of grandparent statement
swapStartSibling = grandParentNode;
swapEndSibling = ((BlockStatement) parentNode).LBraceToken;
}
}
} else if (swapIndex >= siblings.Count) {
// This is the last statement in block, so swap it with block end to get the statement outside of it
var parentNode = currentStatement.Parent as BlockStatement;
if (parentNode != null) {
var grandParentNode = parentNode.Parent;
if ((grandParentNode != null) && isAllowedGrandParentNode(grandParentNode)) {
// Swap with rest of grandparent control statement
swapStartSibling = ((BlockStatement) parentNode).RBraceToken;
swapEndSibling = grandParentNode;
}
}
} else {
// In the middle of current block
swapStartSibling = siblings[swapIndex];
swapEndSibling = swapStartSibling;
// Special handling for swap nodes containing blocks: Move current statement into it
if (swapStartSibling is IfElseStatement) {
var ifElseStatement = swapStartSibling as IfElseStatement;
if (direction == MoveStatementDirection.Up) {
BlockStatement swappedIfElseBlock = ifElseStatement.FalseStatement as BlockStatement;
if (swappedIfElseBlock == null)
swappedIfElseBlock = ifElseStatement.TrueStatement as BlockStatement;
if (swappedIfElseBlock != null) {
swapStartSibling = swappedIfElseBlock.RBraceToken;
IEnumerable<AstNode> swapSiblings = null;
if (swapSibling != null) {
Func<AstNode, bool> swapExpansionPredicate = node =>
((node.EndLocation.Line >= swapSibling.StartLocation.Line) && (node.StartLocation.Line <= swapSibling.EndLocation.Line));
swapSiblings = currentStatementSiblings.Where(swapExpansionPredicate);
}
if (!selectedStatements.Any(node => node is PreProcessorDirective)) {
// Handling moving into neighbour block statements or moving the line out of them
if (direction == MoveStatementDirection.Up) {
if (swapSibling != null) {
var lastSwapSibling = swapSiblings.Last();
var innerBlockStatement = GetInnerBlockOfControlNode(lastSwapSibling, direction);
if (innerBlockStatement != null) {
// Swap with end brace
swapSiblings = new[] {
(AstNode) innerBlockStatement.RBraceToken, lastSwapSibling.Children.Last()
};
}
} else {
BlockStatement swappedIfElseBlock = ifElseStatement.TrueStatement as BlockStatement;
if (swappedIfElseBlock == null)
swappedIfElseBlock = ifElseStatement.TrueStatement as BlockStatement;
if (swappedIfElseBlock != null) {
swapEndSibling = swappedIfElseBlock.LBraceToken;
// Check if we are inside of a block statement where we can move the lines out from
var firstSelectedStatement = selectedStatements.First();
if ((firstSelectedStatement.Parent is BlockStatement) &&
NodeSupportsBlockMovement(firstSelectedStatement.Parent.Parent)) {
// Our swap sibling is the starting brace of block statement and head of parent statement
swapSiblings = new[] {
firstSelectedStatement.Parent.Parent.Children.First(),
((BlockStatement) firstSelectedStatement.Parent).LBraceToken
};
}
}
} else {
BlockStatement innerBlockStatement = GetInnerBlockOfControlNode(swapStartSibling);
if (innerBlockStatement != null) {
if (direction == MoveStatementDirection.Up) {
swapStartSibling = innerBlockStatement.RBraceToken;
} else {
swapEndSibling = innerBlockStatement.LBraceToken;
if (swapSibling != null) {
var firstSwapSibling = swapSiblings.First();
var innerBlockStatement = GetInnerBlockOfControlNode(firstSwapSibling, direction);
if (innerBlockStatement != null) {
// Swap with start brace of block statement
swapSiblings = new[] { firstSwapSibling.Children.First(), innerBlockStatement.LBraceToken };
}
} else {
// Check if we are inside of a block statement where we can move the lines out from
var lastSelectedStatement = selectedStatements.Last();
if ((lastSelectedStatement.Parent is BlockStatement) &&
NodeSupportsBlockMovement(lastSelectedStatement.Parent.Parent)) {
// Our swap sibling is the ending brace of block statement (and foot statement, like with do...while loops)
swapSiblings = new[] {
((BlockStatement) lastSelectedStatement.Parent).RBraceToken,
lastSelectedStatement.Parent.Parent.Children.Last()
};
}
}
}
}
if ((swapStartSibling == null) || (swapEndSibling == null))
if (swapSiblings == null)
return;
Selection swapSiblingSelection = ExtendSelectionToComments(editor.Document, swapStartSibling.StartLocation, swapEndSibling.EndLocation, commentsBlankLines);
if (swapSiblingSelection == null)
swapSiblingSelection = new Selection() { Start = swapStartSibling.StartLocation, End = swapEndSibling.EndLocation };
// Swap lines of current and neighbour statements
TextLocation movedTextStart = selectedStatements.First().StartLocation;
TextLocation movedTextEnd = selectedStatements.Last().EndLocation;
TextLocation swappedTextStart = swapSiblings.First().StartLocation;
TextLocation swappedTextEnd = swapSiblings.Last().EndLocation;
// Expand swapSiblingSelection, too, if there are > 1 statements in line
if (direction == MoveStatementDirection.Up) {
AstNode tempNode = swapStartSibling;
while ((tempNode.PrevSibling != null) && !(tempNode.PrevSibling is NewLineNode)) {
tempNode = tempNode.PrevSibling;
if (tempNode.EndLocation.Line >= swapSiblingSelection.Start.Line) {
swapSiblingSelection.Start = tempNode.StartLocation;
} else {
break;
}
}
} else {
AstNode tempNode = swapEndSibling;
while ((tempNode.NextSibling != null) && !(tempNode.NextSibling is NewLineNode)) {
tempNode = tempNode.NextSibling;
if (tempNode.StartLocation.Line <= swapSiblingSelection.End.Line) {
swapSiblingSelection.End = tempNode.EndLocation;
} else {
break;
}
}
}
string currentNodeText = editor.Document.GetText(movedTextStart, movedTextEnd);
string swappedNodeText = editor.Document.GetText(swappedTextStart, swappedTextEnd);
SwapText(editor.Document, movedTextStart, movedTextEnd, swappedTextStart, swappedTextEnd);
// Preserve the indentation of moved statement
if (statementSelection.Start.Column > swapSiblingSelection.Start.Column) {
statementSelection = new Selection {
Start = new TextLocation(statementSelection.Start.Line, swapSiblingSelection.Start.Column),
End = statementSelection.End
};
} else if (statementSelection.Start.Column < swapSiblingSelection.Start.Column) {
swapSiblingSelection = new Selection {
Start = new TextLocation(swapSiblingSelection.Start.Line, statementSelection.Start.Column),
End = swapSiblingSelection.End
};
}
// Select moved text
// editor.Select(editor.Document.GetOffset(swappedTextStart.Line, swappedTextStart.Column), 5);//currentNodeText.Length);
// SelectText(new Selection {
// Start = new TextLocation(swappedTextStart.Line, 0),
// End = new TextLocation(swappedTextStart.Line + (movedTextEnd.Line - movedTextStart.Line), 200) },
// editor);
// currentStatement = parsedCU.GetNodeContaining(selectionStart, selectionEnd);
// Swap them
string currentNodeText = editor.Document.GetText(statementSelection.Start, statementSelection.End);
SwapText(editor.Document, statementSelection.Start, statementSelection.End, swapSiblingSelection.Start, swapSiblingSelection.End);
// Move caret to the start of moved statement
TextLocation upperLocation = new TextLocation[] {statementSelection.Start, swapSiblingSelection.Start}.Min();
if (direction == MoveStatementDirection.Up)
TextLocation upperLocation = new TextLocation[] { movedTextStart, swappedTextStart }.Min();
int currentMovedOffset = editor.Document.Text.IndexOf(currentNodeText, editor.Document.GetOffset(upperLocation));
int swappedMovedOffset = editor.Document.Text.IndexOf(swappedNodeText, editor.Document.GetOffset(upperLocation));
if (direction == MoveStatementDirection.Up) {
editor.Caret.Location = upperLocation;
else {
} else {
// look where current statement ended up because it is hard to calculate it correctly
int currentMovedOffset = editor.Document.Text.IndexOf(currentNodeText, editor.Document.GetOffset(upperLocation));
editor.Caret.Offset = currentMovedOffset;
}
// Correct indentation
editor.Language.FormattingStrategy.IndentLines(
editor,
editor.Document.GetLineForOffset(currentMovedOffset).LineNumber,
editor.Document.GetLineForOffset(currentMovedOffset + currentNodeText.Length).LineNumber);
editor.Language.FormattingStrategy.IndentLines(
editor,
editor.Document.GetLineForOffset(swappedMovedOffset).LineNumber,
editor.Document.GetLineForOffset(swappedMovedOffset + swappedNodeText.Length).LineNumber);
}
BlockStatement GetInnerBlockOfControlNode(AstNode node)
bool NodeSupportsBlockMovement(AstNode node)
{
var blockNodeTypes = new[] {
typeof(IfElseStatement),
typeof(ForStatement),
typeof(ForeachStatement),
typeof(WhileStatement),
typeof(DoWhileStatement),
typeof(UsingStatement)
};
return blockNodeTypes.Contains(node.GetType());
}
BlockStatement GetInnerBlockOfControlNode(AstNode node, MoveStatementDirection direction)
{
if (node is IfElseStatement) {
if (direction == MoveStatementDirection.Up) {
var ifStatement = (IfElseStatement) node;
if (ifStatement.FalseStatement.IsNull)
return ifStatement.TrueStatement as BlockStatement;
return ifStatement.FalseStatement as BlockStatement;
} else {
return ((IfElseStatement) node).TrueStatement as BlockStatement;
}
}
if (node is ForStatement) {
return ((ForStatement) node).EmbeddedStatement as BlockStatement;
}
@ -342,6 +341,9 @@ namespace CSharpBinding @@ -342,6 +341,9 @@ namespace CSharpBinding
if (node is DoWhileStatement) {
return ((DoWhileStatement) node).EmbeddedStatement as BlockStatement;
}
if (node is UsingStatement) {
return ((UsingStatement) node).EmbeddedStatement as BlockStatement;
}
return null;
}

59
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpCompletionBinding.cs

@ -20,10 +20,14 @@ using System; @@ -20,10 +20,14 @@ using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.Core;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.Completion;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.Completion;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
@ -32,6 +36,22 @@ namespace CSharpBinding.Completion @@ -32,6 +36,22 @@ namespace CSharpBinding.Completion
{
public class CSharpCompletionBinding : ICodeCompletionBinding
{
FileName contextFileName;
TextLocation currentLocation;
ITextSource fileContent;
public CSharpCompletionBinding()
: this(null, TextLocation.Empty, null)
{
}
public CSharpCompletionBinding(FileName contextFileName, TextLocation currentLocation, ITextSource fileContent)
{
this.contextFileName = contextFileName;
this.currentLocation = currentLocation;
this.fileContent = fileContent;
}
public CodeCompletionKeyPressResult HandleKeyPress(ITextEditor editor, char ch)
{
// We use HandleKeyPressed instead.
@ -52,36 +72,49 @@ namespace CSharpBinding.Completion @@ -52,36 +72,49 @@ namespace CSharpBinding.Completion
bool ShowCompletion(ITextEditor editor, char completionChar, bool ctrlSpace)
{
var completionContext = CSharpCompletionContext.Get(editor);
CSharpCompletionContext completionContext;
if (fileContent == null) {
completionContext = CSharpCompletionContext.Get(editor);
} else {
completionContext = CSharpCompletionContext.Get(editor, fileContent, currentLocation, contextFileName);
}
if (completionContext == null)
return false;
int caretOffset;
if (fileContent == null) {
caretOffset = editor.Caret.Offset;
currentLocation = editor.Caret.Location;
} else {
caretOffset = completionContext.Document.GetOffset(currentLocation);
}
var completionFactory = new CSharpCompletionDataFactory(completionContext, new CSharpResolver(completionContext.TypeResolveContextAtCaret));
CSharpCompletionEngine cce = new CSharpCompletionEngine(
editor.Document,
completionContext.Document,
completionContext.CompletionContextProvider,
completionFactory,
completionContext.ProjectContent,
completionContext.TypeResolveContextAtCaret
);
cce.FormattingPolicy = FormattingOptionsFactory.CreateSharpDevelop();
cce.EolMarker = DocumentUtilities.GetLineTerminator(editor.Document, editor.Caret.Line);
cce.IndentString = editor.Options.IndentationString;
cce.EolMarker = DocumentUtilities.GetLineTerminator(completionContext.Document, currentLocation.Line);
cce.IndentString = editor.Options.IndentationString;
int startPos, triggerWordLength;
IEnumerable<ICompletionData> completionData;
if (ctrlSpace) {
if (!cce.TryGetCompletionWord(editor.Caret.Offset, out startPos, out triggerWordLength)) {
startPos = editor.Caret.Offset;
if (!cce.TryGetCompletionWord(caretOffset, out startPos, out triggerWordLength)) {
startPos = caretOffset;
triggerWordLength = 0;
}
completionData = cce.GetCompletionData(startPos, true);
completionData = completionData.Concat(cce.GetImportCompletionData(startPos));
} else {
startPos = editor.Caret.Offset;
startPos = caretOffset;
if (char.IsLetterOrDigit (completionChar) || completionChar == '_') {
if (startPos > 1 && char.IsLetterOrDigit (editor.Document.GetCharAt (startPos - 2)))
if (startPos > 1 && char.IsLetterOrDigit (completionContext.Document.GetCharAt (startPos - 2)))
return false;
completionData = cce.GetCompletionData(startPos, false);
startPos--;
@ -96,8 +129,8 @@ namespace CSharpBinding.Completion @@ -96,8 +129,8 @@ namespace CSharpBinding.Completion
list.Items.AddRange(FilterAndAddTemplates(editor, completionData.Cast<ICompletionItem>().ToList()));
if (list.Items.Count > 0) {
list.SortItems();
list.PreselectionLength = editor.Caret.Offset - startPos;
list.PostselectionLength = Math.Max(0, startPos + triggerWordLength - editor.Caret.Offset);
list.PreselectionLength = caretOffset - startPos;
list.PostselectionLength = Math.Max(0, startPos + triggerWordLength - caretOffset);
list.SuggestedItem = list.Items.FirstOrDefault(i => i.Text == cce.DefaultCompletionString);
editor.ShowCompletionWindow(list);
return true;
@ -106,13 +139,13 @@ namespace CSharpBinding.Completion @@ -106,13 +139,13 @@ namespace CSharpBinding.Completion
if (!ctrlSpace) {
// Method Insight
var pce = new CSharpParameterCompletionEngine(
editor.Document,
completionContext.Document,
completionContext.CompletionContextProvider,
completionFactory,
completionContext.ProjectContent,
completionContext.TypeResolveContextAtCaret
);
var newInsight = pce.GetParameterDataProvider(editor.Caret.Offset, completionChar) as CSharpMethodInsight;
var newInsight = pce.GetParameterDataProvider(caretOffset, completionChar) as CSharpMethodInsight;
if (newInsight != null && newInsight.items.Count > 0) {
newInsight.UpdateHighlightedParameter(pce);
newInsight.Show();

32
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpCompletionContext.cs

@ -18,6 +18,10 @@ @@ -18,6 +18,10 @@
using System;
using System.Diagnostics;
using ICSharpCode.Core;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.SharpDevelop.Project;
using CSharpBinding.Parser;
using ICSharpCode.NRefactory.CSharp.Completion;
using ICSharpCode.NRefactory.CSharp.TypeSystem;
@ -30,6 +34,7 @@ namespace CSharpBinding.Completion @@ -30,6 +34,7 @@ namespace CSharpBinding.Completion
sealed class CSharpCompletionContext
{
public readonly ITextEditor Editor;
public readonly IDocument Document;
public readonly CSharpFullParseInformation ParseInformation;
public readonly ICompilation Compilation;
public readonly IProjectContent ProjectContent;
@ -51,21 +56,40 @@ namespace CSharpBinding.Completion @@ -51,21 +56,40 @@ namespace CSharpBinding.Completion
if (projectContent == null)
return null;
return new CSharpCompletionContext(editor, parseInfo, compilation, projectContent);
return new CSharpCompletionContext(editor, parseInfo, compilation, projectContent, editor.Document, editor.Caret.Location);
}
private CSharpCompletionContext(ITextEditor editor, CSharpFullParseInformation parseInfo, ICompilation compilation, IProjectContent projectContent)
public static CSharpCompletionContext Get(ITextEditor editor, ITextSource fileContent, TextLocation currentLocation, FileName fileName)
{
IDocument document = new ReadOnlyDocument(fileContent);
// Don't require the very latest parse information, an older cached version is OK.
var parseInfo = SD.ParserService.Parse(fileName, document) as CSharpFullParseInformation;
if (parseInfo == null)
return null;
ICompilation compilation = SD.ParserService.GetCompilationForFile(fileName);
var projectContent = compilation.MainAssembly.UnresolvedAssembly as IProjectContent;
if (projectContent == null)
return null;
return new CSharpCompletionContext(editor, parseInfo, compilation, projectContent, document, currentLocation);
}
private CSharpCompletionContext(ITextEditor editor, CSharpFullParseInformation parseInfo, ICompilation compilation, IProjectContent projectContent, IDocument document, TextLocation caretLocation)
{
Debug.Assert(editor != null);
Debug.Assert(parseInfo != null);
Debug.Assert(compilation != null);
Debug.Assert(projectContent != null);
Debug.Assert(document != null);
this.Editor = editor;
this.Document = document;
this.ParseInformation = parseInfo;
this.Compilation = compilation;
this.ProjectContent = projectContent;
this.TypeResolveContextAtCaret = parseInfo.UnresolvedFile.GetTypeResolveContext(compilation, editor.Caret.Location);
this.CompletionContextProvider = new DefaultCompletionContextProvider(editor.Document, parseInfo.UnresolvedFile);
this.TypeResolveContextAtCaret = parseInfo.UnresolvedFile.GetTypeResolveContext(compilation, caretLocation);
this.CompletionContextProvider = new DefaultCompletionContextProvider(document, parseInfo.UnresolvedFile);
}
}
}

46
src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingStrategy.cs

@ -24,6 +24,7 @@ using System.Text; @@ -24,6 +24,7 @@ using System.Text;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Indentation.CSharp;
using ICSharpCode.Core;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop;
@ -41,26 +42,39 @@ namespace CSharpBinding.FormattingStrategy @@ -41,26 +42,39 @@ namespace CSharpBinding.FormattingStrategy
#region Smart Indentation
public override void IndentLine(ITextEditor editor, IDocumentLine line)
{
int lineNr = line.LineNumber;
DocumentAccessor acc = new DocumentAccessor(editor.Document, lineNr, lineNr);
CSharpIndentationStrategy indentStrategy = new CSharpIndentationStrategy();
indentStrategy.IndentationString = editor.Options.IndentationString;
indentStrategy.Indent(acc, false);
string t = acc.Text;
if (t.Length == 0) {
// use AutoIndentation for new lines in comments / verbatim strings.
base.IndentLine(editor, line);
}
var document = editor.Document;
var engine = CreateIndentEngine(document, editor.ToEditorOptions());
IndentSingleLine(engine, document, line);
}
public override void IndentLines(ITextEditor editor, int beginLine, int endLine)
{
DocumentAccessor acc = new DocumentAccessor(editor.Document, beginLine, endLine);
CSharpIndentationStrategy indentStrategy = new CSharpIndentationStrategy();
indentStrategy.IndentationString = editor.Options.IndentationString;
indentStrategy.Indent(acc, true);
var document = editor.Document;
var engine = CreateIndentEngine(document, editor.ToEditorOptions());
int currentLine = beginLine;
do {
var line = document.GetLineByNumber(currentLine);
IndentSingleLine(engine, document, line);
} while (++currentLine <= endLine);
}
static void IndentSingleLine(CacheIndentEngine engine, IDocument document, IDocumentLine line)
{
engine.Update(line.EndOffset);
if (engine.NeedsReindent) {
int textOffset = line.Offset;
while (textOffset < line.EndOffset && char.IsWhiteSpace(document.GetCharAt(textOffset)))
textOffset++;
string newText = document.GetText(textOffset, line.Length + line.Offset - textOffset);
document.Replace(line.Offset, line.Length, engine.ThisLineIndent + newText);
engine.ResetEngineToPosition(line.Offset);
}
}
static CacheIndentEngine CreateIndentEngine(IDocument document, TextEditorOptions options)
{
var engine = new CSharpIndentEngine(document, options, FormattingOptionsFactory.CreateSharpDevelop());
return new CacheIndentEngine(engine);
}
#endregion

18
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/Parser.cs

@ -176,6 +176,24 @@ namespace CSharpBinding.Parser @@ -176,6 +176,24 @@ namespace CSharpBinding.Parser
unresolvedFile = null;
return ResolveAtLocation.Resolve(compilation, unresolvedFile, csParseInfo.SyntaxTree, location, cancellationToken);
}
public ICodeContext ResolveContext(ParseInformation parseInfo, TextLocation location, ICompilation compilation, CancellationToken cancellationToken)
{
var csParseInfo = parseInfo as CSharpFullParseInformation;
if (csParseInfo == null)
throw new ArgumentException("Parse info does not have SyntaxTree");
CSharpUnresolvedFile unresolvedFile = csParseInfo.UnresolvedFile;
var projectContents = compilation.Assemblies.Select(asm => asm.UnresolvedAssembly).OfType<IProjectContent>().ToList();
if (projectContents.All(pc => pc.GetFile(unresolvedFile.FileName) != unresolvedFile))
unresolvedFile = null;
var syntaxTree = csParseInfo.SyntaxTree;
var node = syntaxTree.GetNodeAt(location);
if (node == null)
return null; // null result is allowed; the parser service will substitute a dummy context
var resolver = new CSharpAstResolver(compilation, syntaxTree, unresolvedFile);
return resolver.GetResolverStateBefore(node);
}
public void FindLocalReferences(ParseInformation parseInfo, ITextSource fileContent, IVariable variable, ICompilation compilation, Action<SearchResultMatch> callback, CancellationToken cancellationToken)
{

274
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/EditorScript.cs

@ -18,20 +18,11 @@ @@ -18,20 +18,11 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using ICSharpCode.AvalonEdit;
using ICSharpCode.AvalonEdit.Editing;
using ICSharpCode.AvalonEdit.Rendering;
using ICSharpCode.AvalonEdit.Snippets;
using CSharpBinding.Parser;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.CSharp;
@ -39,8 +30,8 @@ using ICSharpCode.NRefactory.CSharp.Refactoring; @@ -39,8 +30,8 @@ using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Parser;
namespace CSharpBinding.Refactoring
{
@ -198,7 +189,13 @@ namespace CSharpBinding.Refactoring @@ -198,7 +189,13 @@ namespace CSharpBinding.Refactoring
var tcs = new TaskCompletionSource<Script>();
if (parentType == null)
return tcs.Task;
var part = parentType.Parts.FirstOrDefault ();
IUnresolvedTypeDefinition part = null;
foreach (var p in parentType.Parts) {
if (part == null || EntityModelContextUtils.IsBetterPart(p, part, ".cs"))
part = p;
}
if (part == null)
return tcs.Task;
@ -297,259 +294,4 @@ namespace CSharpBinding.Refactoring @@ -297,259 +294,4 @@ 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, 1);
static readonly Pen tempMarkerPen = new Pen(Brushes.Gray, 1);
protected override void OnRender(DrawingContext drawingContext)
{
DrawLineForInsertionPoint(CurrentInsertionPoint, markerPen, drawingContext);
if (insertionPointNextToMouse > -1 && insertionPointNextToMouse != CurrentInsertionPoint)
DrawLineForInsertionPoint(insertionPointNextToMouse, tempMarkerPen, drawingContext);
SetGroupBoxPosition(); // HACK
}
void DrawLineForInsertionPoint(int index, Pen pen, DrawingContext drawingContext)
{
var currentInsertionPoint = insertionPoints[index];
var pos = editor.TextView.GetVisualPosition(new TextViewPosition(currentInsertionPoint.Location), VisualYPosition.LineMiddle);
var endPos = new Point(pos.X + editor.TextView.ActualWidth * 0.6, pos.Y);
drawingContext.DrawLine(pen, pos - editor.TextView.ScrollOffset, endPos - editor.TextView.ScrollOffset);
}
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
{
return new PointHitTestResult(this, hitTestParameters.HitPoint);
}
protected override void OnMouseMove(MouseEventArgs e)
{
insertionPointNextToMouse = FindNextInsertionPoint(e.GetPosition(this));
e.Handled = true;
InvalidateVisual();
base.OnMouseMove(e);
}
protected override void OnMouseDown(MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed) {
if (e.ClickCount > 1) {
FireExited(true);
} else {
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 = CurrentInsertionPoint;
int mouseLocationLine = position.Value.Location.Line;
int currentLocationLine = insertionPoints[insertionPoint].Location.Line;
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 location = insertionPoints[CurrentInsertionPoint].Location;
var boxPosition = editor.TextView.GetVisualPosition(new TextViewPosition(location), VisualYPosition.LineMiddle) - editor.TextView.ScrollOffset + 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);
}
}
public 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;
}
}
}

311
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertionCursorLayer.cs

@ -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;
}
}
}

4
src/AddIns/BackendBindings/Scripting/Project/Src/RunScriptingConsoleApplicationCommand.cs

@ -27,12 +27,12 @@ namespace ICSharpCode.Scripting @@ -27,12 +27,12 @@ namespace ICSharpCode.Scripting
{
public class RunScriptingConsoleApplicationCommand : AbstractMenuCommand
{
IDebugger debugger;
IDebuggerService debugger;
IScriptingWorkbench workbench;
ScriptingConsoleApplication scriptingConsoleApplication;
public RunScriptingConsoleApplicationCommand(IScriptingWorkbench workbench,
IDebugger debugger,
IDebuggerService debugger,
ScriptingConsoleApplication scriptingConsoleApplication)
{
this.workbench = workbench;

5
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs

@ -111,6 +111,11 @@ namespace ICSharpCode.XamlBinding @@ -111,6 +111,11 @@ namespace ICSharpCode.XamlBinding
return new XamlAstResolver(compilation, (XamlFullParseInformation)parseInfo)
.ResolveAtLocation(location, cancellationToken);
}
public ICodeContext ResolveContext(ParseInformation parseInfo, TextLocation location, ICompilation compilation, CancellationToken cancellationToken)
{
return null; // null result is allowed; the parser service will substitute a dummy context
}
public void FindLocalReferences(ParseInformation parseInfo, ITextSource fileContent, IVariable variable, ICompilation compilation, Action<SearchResultMatch> callback, CancellationToken cancellationToken)
{

31
src/Main/Base/Project/Src/Services/Debugger/BreakpointBookmark.cs → src/AddIns/Debugger/Debugger.AddIn/Breakpoints/BreakpointBookmark.cs

@ -19,17 +19,21 @@ @@ -19,17 +19,21 @@
using System;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.Core;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor.Bookmarks;
using ICSharpCode.SharpDevelop.Editor;
namespace ICSharpCode.SharpDevelop.Debugging
namespace Debugger.AddIn.Breakpoints
{
public class BreakpointBookmark : SDMarkerBookmark
public class BreakpointBookmark : SDMarkerBookmark, IHaveStateEnabled
{
bool isHealthy = true;
bool isEnabled = true;
@ -95,11 +99,6 @@ namespace ICSharpCode.SharpDevelop.Debugging @@ -95,11 +99,6 @@ namespace ICSharpCode.SharpDevelop.Debugging
this.FileName = fileName;
}
public const string BreakpointMarker = "Breakpoint";
public static readonly Color DefaultBackground = Color.FromRgb(180, 38, 38);
public static readonly Color DefaultForeground = Colors.White;
public static IImage BreakpointImage {
get { return SD.ResourceService.GetImage("Bookmarks.Breakpoint"); }
}
@ -132,16 +131,16 @@ namespace ICSharpCode.SharpDevelop.Debugging @@ -132,16 +131,16 @@ namespace ICSharpCode.SharpDevelop.Debugging
IDocumentLine line = this.Document.GetLineByNumber(this.LineNumber);
ITextMarker marker = markerService.Create(line.Offset, line.Length);
IHighlighter highlighter = this.Document.GetService(typeof(IHighlighter)) as IHighlighter;
marker.BackgroundColor = DefaultBackground;
marker.ForegroundColor = DefaultForeground;
marker.MarkerColor = DefaultBackground;
marker.BackgroundColor = BookmarkBase.BreakpointDefaultBackground;
marker.ForegroundColor = BookmarkBase.BreakpointDefaultForeground;
marker.MarkerColor = BookmarkBase.BreakpointDefaultBackground;
marker.MarkerTypes = TextMarkerTypes.CircleInScrollBar;
if (highlighter != null) {
var color = highlighter.GetNamedColor(BreakpointMarker);
var color = highlighter.GetNamedColor(BookmarkBase.BreakpointMarkerName);
if (color != null) {
marker.BackgroundColor = color.Background.GetColor(null);
marker.MarkerColor = color.Background.GetColor(null) ?? DefaultBackground;
marker.MarkerColor = color.Background.GetColor(null) ?? BookmarkBase.BreakpointDefaultForeground;
marker.ForegroundColor = color.Foreground.GetColor(null);
}
}
@ -152,5 +151,13 @@ namespace ICSharpCode.SharpDevelop.Debugging @@ -152,5 +151,13 @@ namespace ICSharpCode.SharpDevelop.Debugging
{
return string.Format("{0} @{1}", this.FileName, this.LineNumber);
}
public override object CreateTooltipContent()
{
return new BreakpointEditorPopup(this) {
MinWidth = 300,
StaysOpen = false
};
}
}
}

2
src/Main/Base/Project/Src/Services/Debugger/BreakpointBookmarkEventArgs.cs → src/AddIns/Debugger/Debugger.AddIn/Breakpoints/BreakpointBookmarkEventArgs.cs

@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
using System;
namespace ICSharpCode.SharpDevelop.Debugging
namespace Debugger.AddIn.Breakpoints
{
public class BreakpointBookmarkEventArgs : EventArgs
{

38
src/AddIns/Debugger/Debugger.AddIn/Breakpoints/BreakpointEditorPopup.xaml

@ -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>

65
src/AddIns/Debugger/Debugger.AddIn/Breakpoints/BreakpointEditorPopup.xaml.cs

@ -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 = "";
}
}
}

18
src/Main/Base/Project/Src/Services/Debugger/CurrentLineBookmark.cs → src/AddIns/Debugger/Debugger.AddIn/Breakpoints/CurrentLineBookmark.cs

@ -85,11 +85,6 @@ namespace ICSharpCode.SharpDevelop.Debugging @@ -85,11 +85,6 @@ namespace ICSharpCode.SharpDevelop.Debugging
get { return false; }
}
public const string Name = "Current statement";
public static readonly Color DefaultBackground = Colors.Yellow;
public static readonly Color DefaultForeground = Colors.Blue;
public override int ZOrder {
get { return 100; }
}
@ -98,8 +93,9 @@ namespace ICSharpCode.SharpDevelop.Debugging @@ -98,8 +93,9 @@ namespace ICSharpCode.SharpDevelop.Debugging
get { return false; }
}
public override bool IsVisibleInBookmarkPad {
get { return false; }
public override bool ShowInPad(BookmarkPadBase pad)
{
return false;
}
public override IImage Image {
@ -114,11 +110,11 @@ namespace ICSharpCode.SharpDevelop.Debugging @@ -114,11 +110,11 @@ namespace ICSharpCode.SharpDevelop.Debugging
int eOffset = Math.Min(eLine.Offset + endColumn - 1, eLine.EndOffset);
ITextMarker marker = markerService.Create(sOffset, Math.Max(eOffset - sOffset, 1));
IHighlighter highlighter = this.Document.GetService(typeof(IHighlighter)) as IHighlighter;
marker.BackgroundColor = DefaultBackground;
marker.ForegroundColor = DefaultForeground;
marker.BackgroundColor = BookmarkBase.CurrentLineDefaultBackground;
marker.ForegroundColor = BookmarkBase.CurrentLineDefaultForeground;
if (highlighter != null) {
var color = highlighter.GetNamedColor(Name);
var color = highlighter.GetNamedColor(BookmarkBase.CurrentLineBookmarkName);
if (color != null) {
marker.BackgroundColor = color.Background.GetColor(null);
marker.ForegroundColor = color.Foreground.GetColor(null);
@ -136,7 +132,7 @@ namespace ICSharpCode.SharpDevelop.Debugging @@ -136,7 +132,7 @@ namespace ICSharpCode.SharpDevelop.Debugging
// call async because the Debugger seems to use Application.DoEvents(), but we don't want to process events
// because Drag'N'Drop operation has finished
SD.MainThread.InvokeAsyncAndForget(delegate {
DebuggerService.CurrentDebugger.SetInstructionPointer(this.FileName, lineNumber, 1, false);
SD.Debugger.SetInstructionPointer(this.FileName, lineNumber, 1, false);
});
}
}

49
src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin

@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
</Manifest>
<Runtime>
<Import assembly=":ICSharpCode.SharpDevelop" />
<Import assembly="Debugger.AddIn.dll">
<ConditionEvaluator name = "IsBreakpointSet" class = "Debugger.AddIn.IsBreakpointCondition"/>
<ConditionEvaluator name = "IsBreakpointActive" class="Debugger.AddIn.IsActiveBreakpointCondition" />
@ -16,13 +17,9 @@ @@ -16,13 +17,9 @@
<Import assembly="Debugger.Core.dll"/>
</Runtime>
<Path name="/SharpDevelop/Services/DebuggerService/Debugger">
<Debugger id="DefaultDebugger"
supportsStepping = "true"
supportsExecutionControl = "true"
supportsAttaching = "true"
supportsDetaching = "true"
class="ICSharpCode.SharpDevelop.Services.WindowsDebugger"/>
<Path name="/SharpDevelop/Services">
<Service id="ICSharpCode.SharpDevelop.Debugging.IDebuggerService"
class="ICSharpCode.SharpDevelop.Services.WindowsDebugger" />
</Path>
<Path name = "/SharpDevelop/ViewContent/TextEditor/ContextMenu">
@ -44,28 +41,22 @@ @@ -44,28 +41,22 @@
type = "Separator"/>
</Condition>
<MenuItem id="BreakpointSeparator" type = "Separator" />
<MenuItem id="ChangeBreakPoint" label="${res:MainWindow.Windows.Debug.Conditional.Breakpoints.Breakpoint}" type="Menu">
<Include id="SetBreakpoint" item="/SharpDevelop/Workbench/MainMenu/Debug/Toggle Breakpoint" />
<Condition name="IsBreakpointSet">
<Condition name="IsBreakpointActive">
<MenuItem id="DisableBreakpoint"
class="Debugger.AddIn.DisableBreakpointMenuCommand"
label= "${res:MainWindow.Windows.Debug.Conditional.Breakpoints.DisableBreakpoint}" />
</Condition>
<ComplexCondition>
<Not>
<Condition name="IsBreakpointActive" />
</Not>
<MenuItem id="EnableBreakpoint"
class="Debugger.AddIn.EnableBreakpointMenuCommand"
label= "${res:MainWindow.Windows.Debug.Conditional.Breakpoints.EnableBreakpoint}" />
</ComplexCondition>
<MenuItem id="EditCondition"
class="Debugger.AddIn.EditBreakpointMenuCommand"
label= "${res:MainWindow.Windows.Debug.Conditional.Breakpoints.EditCondition}" />
<Include id="SetBreakpoint" item="/SharpDevelop/Workbench/MainMenu/Debug/Toggle Breakpoint" />
<Condition name="IsBreakpointSet">
<Condition name="IsBreakpointActive">
<MenuItem id="DisableBreakpoint"
class="Debugger.AddIn.DisableBreakpointMenuCommand"
label= "${res:MainWindow.Windows.Debug.Conditional.Breakpoints.DisableBreakpoint}" />
</Condition>
</MenuItem>
<ComplexCondition>
<Not>
<Condition name="IsBreakpointActive" />
</Not>
<MenuItem id="EnableBreakpoint"
class="Debugger.AddIn.EnableBreakpointMenuCommand"
label= "${res:MainWindow.Windows.Debug.Conditional.Breakpoints.EnableBreakpoint}" />
</ComplexCondition>
</Condition>
</Path>
<Path name="/SharpDevelop/Workbench/MainMenu/Debug">
@ -75,7 +66,7 @@ @@ -75,7 +66,7 @@
label = "${res:MainWindow.Windows.Debug.DebugExecutable}"
class = "Debugger.AddIn.DebugExecutableMenuCommand"/>
</Condition>
<!-- <MenuItem id="AddExpressionBreakpoint"
<!-- <MenuItem id="AddExpressionBreakpoint"
insertafter="Toggle Breakpoint"
label = "${res:MainWindow.Windows.Debug.AddExpressionBreakpoint}"
shortcut="Shift|F7"

14
src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj

@ -97,6 +97,12 @@ @@ -97,6 +97,12 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Breakpoints\BreakpointBookmark.cs" />
<Compile Include="Breakpoints\BreakpointBookmarkEventArgs.cs" />
<Compile Include="Breakpoints\BreakpointEditorPopup.xaml.cs">
<DependentUpon>BreakpointEditorPopup.xaml</DependentUpon>
</Compile>
<Compile Include="Breakpoints\CurrentLineBookmark.cs" />
<Compile Include="NRefactory\ExpressionEvaluationVisitor.cs" />
<Compile Include="NRefactory\ExpressionExtensionMethods.cs" />
<Compile Include="Options\DebuggingOptionsPanel.xaml.cs">
@ -112,6 +118,7 @@ @@ -112,6 +118,7 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="Pads\ClassBrowserSupport.cs" />
<Compile Include="Pads\DebuggerDotCompletion.cs" />
<Compile Include="Pads\WatchPadCommands.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Options\DebuggingOptions.cs" />
@ -135,10 +142,6 @@ @@ -135,10 +142,6 @@
<Compile Include="Service\DebuggeeExceptionForm.Designer.cs">
<DependentUpon>DebuggeeExceptionForm.cs</DependentUpon>
</Compile>
<Compile Include="Service\EditBreakpointScriptWindow.xaml.cs">
<DependentUpon>EditBreakpointScriptWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Service\ExecuteProcessWindow.xaml.cs">
<DependentUpon>ExecuteProcessWindow.xaml</DependentUpon>
</Compile>
@ -295,6 +298,7 @@ @@ -295,6 +298,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Breakpoints" />
<Folder Include="Tooltips" />
<Folder Include="Visualizers" />
<Folder Include="Visualizers\Commands" />
@ -314,10 +318,10 @@ @@ -314,10 +318,10 @@
<Folder Include="Visualizers\Presentation" />
<Folder Include="Visualizers\TextVisualizer" />
<Folder Include="Visualizers\Utils" />
<Page Include="Breakpoints\BreakpointEditorPopup.xaml" />
<Page Include="Options\DebuggingOptionsPanel.xaml" />
<Page Include="Options\DebuggingSymbolsPanel.xaml" />
<Page Include="Pads\CommonResources.xaml" />
<Page Include="Service\EditBreakpointScriptWindow.xaml" />
<Page Include="Service\ExecuteProcessWindow.xaml" />
<Page Include="Tooltips\DebuggerTooltipControl.xaml" />
<Page Include="Tooltips\VisualizerPicker.xaml" />

76
src/AddIns/Debugger/Debugger.AddIn/NRefactory/ExpressionEvaluationVisitor.cs

@ -29,15 +29,11 @@ using ICSharpCode.NRefactory.CSharp.Resolver; @@ -29,15 +29,11 @@ using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.Utils;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Services;
namespace Debugger.AddIn
{
public enum SupportedLanguage
{
CSharp
}
public static class Extensions
{
public static ResolveResult ToResolveResult(this Value value, StackFrame context)
@ -109,6 +105,8 @@ namespace Debugger.AddIn @@ -109,6 +105,8 @@ namespace Debugger.AddIn
if (result.IsError)
throw new GetValueException("Unknown error");
if (result.ConstantValue == null && result.Type.Equals(SpecialType.NullType))
return Eval.CreateValue(evalThread, null);
throw new GetValueException("Unsupported language construct: " + result.GetType().Name);
}
@ -149,7 +147,7 @@ namespace Debugger.AddIn @@ -149,7 +147,7 @@ namespace Debugger.AddIn
switch (result.OperatorType) {
case ExpressionType.Assign:
if (!allowSetValue)
throw new InvalidOperationException("Setting values is not allowed in the current context!");
throw new GetValueException("Setting values is not allowed in the current context!");
Debug.Assert(result.Operands.Count == 2);
return VisitAssignment((dynamic)result.Operands[0], (dynamic)result.Operands[1]);
case ExpressionType.Add:
@ -242,7 +240,7 @@ namespace Debugger.AddIn @@ -242,7 +240,7 @@ namespace Debugger.AddIn
var val = resolver.ResolveUnaryOperator(operatorType, operand);
if (val.IsCompileTimeConstant)
return Convert(val);
throw new InvalidOperationException();
throw new GetValueException("Operator {0} is not supported for {1}!", operatorType, new CSharpAmbience().ConvertType(operand.Type));
}
Value VisitBinaryOperator(OperatorResolveResult result, BinaryOperatorType operatorType, bool checkForOverflow = false)
@ -259,14 +257,41 @@ namespace Debugger.AddIn @@ -259,14 +257,41 @@ namespace Debugger.AddIn
var val = resolver.ResolveBinaryOperator(operatorType, lhsRR, rhsRR);
if (val.IsCompileTimeConstant)
return Convert(val);
if (operatorType == BinaryOperatorType.Add &&
(lhsRR.Type.IsKnownType(KnownTypeCode.String) || rhsRR.Type.IsKnownType(KnownTypeCode.String))) {
var method = debuggerTypeSystem.FindType(KnownTypeCode.String)
.GetMethods(m => m.Name == "Concat" && m.Parameters.Count == 2)
.Single(m => m.Parameters.All(p => p.Type.IsKnownType(KnownTypeCode.Object)));
return InvokeMethod(null, method, lhs, rhs);
switch (operatorType) {
case BinaryOperatorType.Equality:
case BinaryOperatorType.InEquality:
bool equality = (operatorType == BinaryOperatorType.Equality);
if (lhsRR.Type.IsKnownType(KnownTypeCode.String) && rhsRR.Type.IsKnownType(KnownTypeCode.String)) {
if (lhs.IsNull || rhs.IsNull) {
bool bothNull = lhs.IsNull && rhs.IsNull;
return Eval.CreateValue(evalThread, equality ? bothNull : !bothNull);
} else {
bool equal = (string)lhs.PrimitiveValue == (string)rhs.PrimitiveValue;
return Eval.CreateValue(evalThread, equality ? equal : !equal);
}
}
if (lhsRR.Type.IsReferenceType != false && rhsRR.Type.IsReferenceType != false) {
// Reference comparison
if (lhs.IsNull || rhs.IsNull) {
bool bothNull = lhs.IsNull && rhs.IsNull;
return Eval.CreateValue(evalThread, equality ? bothNull : !bothNull);
} else {
bool equal = lhs.Address == rhs.Address;
return Eval.CreateValue(evalThread, equality ? equal : !equal);
}
}
goto default;
case BinaryOperatorType.Add:
if (lhsRR.Type.IsKnownType(KnownTypeCode.String) || rhsRR.Type.IsKnownType(KnownTypeCode.String)) {
var method = debuggerTypeSystem.FindType(KnownTypeCode.String)
.GetMethods(m => m.Name == "Concat" && m.Parameters.Count == 2)
.Single(m => m.Parameters.All(p => p.Type.IsKnownType(KnownTypeCode.Object)));
return InvokeMethod(null, method, lhs, rhs);
}
goto default;
default:
throw new GetValueException("Operator {0} is not supported for {1} and {2}!", operatorType, new CSharpAmbience().ConvertType(lhsRR.Type), new CSharpAmbience().ConvertType(rhsRR.Type));
}
throw new InvalidOperationException();
}
Value VisitConditionalOperator(OperatorResolveResult result, BinaryOperatorType bitwiseOperatorType)
@ -358,7 +383,9 @@ namespace Debugger.AddIn @@ -358,7 +383,9 @@ namespace Debugger.AddIn
return InvokeMethod(null, result.Conversion.Method, val);
if (result.Conversion.IsReferenceConversion && result.Conversion.IsImplicit)
return val;
throw new NotImplementedException(string.Format("conversion '{0}' not implemented!", result.Conversion));
if (result.Conversion.IsNullLiteralConversion)
return val;
throw new GetValueException("conversion '{0}' not implemented!", result.Conversion);
}
Value Visit(LocalResolveResult result)
@ -456,12 +483,21 @@ namespace Debugger.AddIn @@ -456,12 +483,21 @@ namespace Debugger.AddIn
public class ResolveResultPrettyPrinter
{
public ResolveResultPrettyPrinter()
ResolveResultPrettyPrinter()
{
}
public string Print(ResolveResult result)
public static string Print(ResolveResult result)
{
try {
return new ResolveResultPrettyPrinter().PrintInternal(result);
} catch (NotImplementedException ex) {
SD.Log.Warn(ex);
return "";
}
}
string PrintInternal(ResolveResult result)
{
if (result == null)
return "";
@ -487,7 +523,7 @@ namespace Debugger.AddIn @@ -487,7 +523,7 @@ namespace Debugger.AddIn
string Visit(MemberResolveResult result)
{
string text = Print(result.TargetResult);
string text = PrintInternal(result.TargetResult);
if (!string.IsNullOrWhiteSpace(text))
text += ".";
return text + result.Member.Name;
@ -554,7 +590,7 @@ namespace Debugger.AddIn @@ -554,7 +590,7 @@ namespace Debugger.AddIn
{
StringBuilder sb = new StringBuilder();
sb.Append(Print(result.TargetResult));
sb.Append(PrintInternal(result.TargetResult));
sb.Append('.');
sb.Append(result.Member.Name);

71
src/AddIns/Debugger/Debugger.AddIn/Pads/AutoCompleteTextBox.cs

@ -17,13 +17,22 @@ @@ -17,13 +17,22 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using ICSharpCode.AvalonEdit;
using ICSharpCode.AvalonEdit.Editing;
using ICSharpCode.Core;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.Completion;
using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
@ -54,6 +63,8 @@ namespace Debugger.AddIn.Pads.Controls @@ -54,6 +63,8 @@ namespace Debugger.AddIn.Pads.Controls
get { return (bool)GetValue(IsEditableProperty); }
set { SetValue(IsEditableProperty, value); }
}
public DebuggerCompletionContext DebugContext { get; set; }
static void TextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
@ -92,6 +103,7 @@ namespace Debugger.AddIn.Pads.Controls @@ -92,6 +103,7 @@ namespace Debugger.AddIn.Pads.Controls
this.editor.TextArea.TextEntered += editor_TextArea_TextEntered;
this.Content = this.editor.TextArea;
this.messageView = new ToolTip { PlacementTarget = this, Placement = PlacementMode.Bottom, StaysOpen = true };
HorizontalContentAlignment = HorizontalAlignment.Stretch;
VerticalContentAlignment = VerticalAlignment.Stretch;
@ -109,37 +121,38 @@ namespace Debugger.AddIn.Pads.Controls @@ -109,37 +121,38 @@ namespace Debugger.AddIn.Pads.Controls
}
}
void editor_TextArea_TextEntered(object sender, TextCompositionEventArgs e)
{
StackFrame frame = WindowsDebugger.CurrentStackFrame;
if (e.Text == "." && frame != null)
ShowDotCompletion(frame, this.editor.Text);
}
ToolTip messageView;
private void ShowDotCompletion(StackFrame frame, string currentText)
void editor_TextArea_TextEntered(object sender, TextCompositionEventArgs e)
{
string language = ProjectService.CurrentProject == null ? "C#" : ProjectService.CurrentProject.Language;
#warning reimplement this!
// NRefactoryResolver resolver = new NRefactoryResolver(LanguageProperties.GetLanguage(language));
//
// var seg = frame.NextStatement;
//
// var expressionFinder = ParserService.GetExpressionFinder(seg.Filename);
// var info = ParserService.GetParseInformation(seg.Filename);
//
// string text = ParserService.GetParseableFileContent(seg.Filename).Text;
//
// int currentOffset = this.editor.CaretOffset;
//
// var expr = expressionFinder.FindExpression(currentText, currentOffset);
//
// expr.Region = new DomRegion(seg.StartLine, seg.StartColumn, seg.EndLine, seg.EndColumn);
//
// var rr = resolver.Resolve(expr, info, text);
//
// if (rr != null) {
// editorAdapter.ShowCompletionWindow(new DotCodeCompletionItemProvider().GenerateCompletionListForResolveResult(rr, expr.Context));
// }
if (e.Text == ".") {
DebuggerCompletionContext context = null;
StackFrame frame = WindowsDebugger.CurrentStackFrame;
if (frame == null) {
if (DebugContext != null) {
context = DebugContext;
}
} else {
context = new DebuggerCompletionContext(frame);
}
if (context == null) return;
var binding = DebuggerDotCompletion.PrepareDotCompletion(editor.Text.Substring(0, editor.CaretOffset), context);
if (binding == null) return;
binding.HandleKeyPressed(editorAdapter, '.');
} else {
// TODO : implement automated error checking CSharpParser.ParseExpression does not report useful error messages.
// Error[] errors;
// if (!DebuggerDotCompletion.CheckSyntax(Text, out errors)) {
// StringBuilder output = new StringBuilder();
// foreach (var error in errors) {
// output.AppendLine(error.Message + " at " + error.Region.Begin);
// }
// messageView.Content = output.ToString();
// messageView.IsOpen = true;
// } else {
// messageView.IsOpen = false;
// }
}
}
public void FocusEditor()

3
src/AddIns/Debugger/Debugger.AddIn/Pads/BreakPointsPad.cs

@ -22,6 +22,7 @@ using System.Windows.Controls; @@ -22,6 +22,7 @@ using System.Windows.Controls;
using ICSharpCode.Core.Presentation;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Editor.Bookmarks;
using Debugger.AddIn.Breakpoints;
namespace ICSharpCode.SharpDevelop.Gui.Pads
{
@ -42,7 +43,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -42,7 +43,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
protected override bool ShowBookmarkInThisPad(SDBookmark mark)
{
return mark.IsVisibleInBookmarkPad && mark is BreakpointBookmark;
return mark.ShowInPad(this) && mark is BreakpointBookmark;
}
}
}

58
src/AddIns/Debugger/Debugger.AddIn/Pads/ConsolePad.cs

@ -26,25 +26,15 @@ using ICSharpCode.Core.Presentation; @@ -26,25 +26,15 @@ using ICSharpCode.Core.Presentation;
using ICSharpCode.NRefactory;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
using Debugger.AddIn.Pads.Controls;
using ICSharpCode.SharpDevelop.Services;
namespace ICSharpCode.SharpDevelop.Gui.Pads
{
public class ConsolePad : AbstractConsolePad
{
SupportedLanguage language;
// NRefactoryResolver resolver;
const string debuggerConsoleToolBarTreePath = "/SharpDevelop/Pads/ConsolePad/ToolBar";
public SupportedLanguage SelectedLanguage {
get { return language; }
set {
this.language = value;
OnLanguageChanged();
}
}
protected override bool AcceptCommand(string command)
{
if (!string.IsNullOrEmpty(command)) {
@ -82,30 +72,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -82,30 +72,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
}
}
protected override void InitializeConsole()
{
base.InitializeConsole();
OnLanguageChanged();
}
void OnLanguageChanged()
{
#warning reimplement this!
// switch (SelectedLanguage) {
// case SupportedLanguage.CSharp:
// resolver = new NRefactoryResolver(LanguageProperties.CSharp);
// SetHighlighting("C#");
// break;
// case SupportedLanguage.VBNet:
// resolver = new NRefactoryResolver(LanguageProperties.VBNet);
// SetHighlighting("VBNET");
// break;
// }
}
public ConsolePad()
{
WindowsDebugger debugger = (WindowsDebugger)DebuggerService.CurrentDebugger;
WindowsDebugger debugger = (WindowsDebugger)SD.Debugger;
}
protected override void AbstractConsolePadTextEntered(object sender, TextCompositionEventArgs e)
@ -117,26 +86,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -117,26 +86,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
void ShowDotCompletion(StackFrame frame, string currentText)
{
var seg = frame.NextStatement;
if (seg == null)
return;
#warning reimplement this!
// var expressionFinder = ParserService.GetExpressionFinder(seg.Filename);
// var info = ParserService.GetParseInformation(seg.Filename);
//
// string text = ParserService.GetParseableFileContent(seg.Filename).Text;
//
// int currentOffset = TextEditor.Caret.Offset - console.CommandOffset - 1;
//
// var expr = expressionFinder.FindExpression(currentText, currentOffset);
//
// expr.Region = new DomRegion(seg.StartLine, seg.StartColumn, seg.EndLine, seg.EndColumn);
//
// var rr = resolver.Resolve(expr, info, text);
//
// if (rr != null) {
// TextEditor.ShowCompletionWindow(new DotCodeCompletionItemProvider().GenerateCompletionListForResolveResult(rr, expr.Context));
// }
var binding = DebuggerDotCompletion.PrepareDotCompletion(currentText, new DebuggerCompletionContext(frame));
if (binding == null) return;
binding.HandleKeyPressed(console.TextEditor, '.');
}
protected override ToolBar BuildToolBar()

201
src/AddIns/Debugger/Debugger.AddIn/Pads/DebuggerDotCompletion.cs

@ -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;
}
}
}
}

10
src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs

@ -39,7 +39,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -39,7 +39,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
{
public class WatchPad : AbstractPadContent
{
DockPanel panel;
Grid panel;
ToolBar toolBar;
SharpTreeView tree;
@ -60,10 +60,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -60,10 +60,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
var res = new CommonResources();
res.InitializeComponent();
panel = new DockPanel();
panel = new Grid();
toolBar = ToolBarService.CreateToolBar(toolBar, this, "/SharpDevelop/Pads/WatchPad/ToolBar");
toolBar.SetValue(DockPanel.DockProperty, Dock.Top);
panel.Children.Add(toolBar);
tree = new SharpTreeView();
@ -78,6 +77,11 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -78,6 +77,11 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
};
panel.Children.Add(tree);
panel.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
panel.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
Grid.SetRow(tree, 1);
// ProjectService.SolutionLoaded += delegate { LoadNodes(); };
// SD.ProjectService.CurrentSolution.PreferencesSaving += delegate { SaveNodes(); };
// LoadNodes();

2
src/AddIns/Debugger/Debugger.AddIn/Service/AttachToProcessForm.cs

@ -72,7 +72,7 @@ namespace ICSharpCode.SharpDevelop.Services @@ -72,7 +72,7 @@ namespace ICSharpCode.SharpDevelop.Services
protected override void RefreshProcessList(ListView listView, bool showNonManaged)
{
listView.Items.Clear();
WindowsDebugger debugger = (WindowsDebugger)DebuggerService.CurrentDebugger;
WindowsDebugger debugger = (WindowsDebugger)SD.Debugger;
Process currentProcess = Process.GetCurrentProcess();
foreach (Process process in Process.GetProcesses()) {
try {

22
src/AddIns/Debugger/Debugger.AddIn/Service/DebuggerCommands.cs

@ -26,6 +26,7 @@ using ICSharpCode.SharpDevelop; @@ -26,6 +26,7 @@ using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Editor;
using Microsoft.Win32;
using Debugger.AddIn.Breakpoints;
using ICSharpCode.SharpDevelop.Services;
namespace Debugger.AddIn
@ -47,10 +48,10 @@ namespace Debugger.AddIn @@ -47,10 +48,10 @@ namespace Debugger.AddIn
{
ITextEditor textEditor = SD.GetActiveViewContentService<ITextEditor>();
if (textEditor == null || DebuggerService.CurrentDebugger == null)
if (textEditor == null || SD.Debugger == null)
return;
DebuggerService.CurrentDebugger.SetInstructionPointer(textEditor.FileName, textEditor.Caret.Line, textEditor.Caret.Column, false);
SD.Debugger.SetInstructionPointer(textEditor.FileName, textEditor.Caret.Line, textEditor.Caret.Column, false);
}
}
@ -87,19 +88,6 @@ namespace Debugger.AddIn @@ -87,19 +88,6 @@ namespace Debugger.AddIn
}
}
public class EditBreakpointMenuCommand : AbstractMenuCommand
{
public override void Run()
{
foreach (BreakpointBookmark bp in BreakpointUtil.BreakpointsOnCaret) {
EditBreakpointScriptWindow window = new EditBreakpointScriptWindow(bp) {
Owner = SD.Workbench.MainWindow
};
window.ShowDialog();
}
}
}
public class IsActiveBreakpointCondition : IConditionEvaluator
{
public bool IsValid(object caller, Condition condition)
@ -144,8 +132,8 @@ namespace Debugger.AddIn @@ -144,8 +132,8 @@ namespace Debugger.AddIn
void StartExecutable(string fileName, string workingDirectory = null, string arguments = null)
{
DebuggerService.CurrentDebugger.BreakAtBeginning = DebuggingOptions.Instance.BreakAtBeginning;
DebuggerService.CurrentDebugger.Start(new ProcessStartInfo {
SD.Debugger.BreakAtBeginning = DebuggingOptions.Instance.BreakAtBeginning;
SD.Debugger.Start(new ProcessStartInfo {
FileName = fileName,
WorkingDirectory = workingDirectory ?? Path.GetDirectoryName(fileName),
Arguments = arguments

10
src/AddIns/Debugger/Debugger.AddIn/Service/EditBreakpointScriptWindow.xaml

@ -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>

84
src/AddIns/Debugger/Debugger.AddIn/Service/EditBreakpointScriptWindow.xaml.cs

@ -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;
}
}
}

128
src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs

@ -25,8 +25,10 @@ using System.Linq; @@ -25,8 +25,10 @@ using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Debugger;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Gui.Pads;
using Debugger.AddIn;
using Debugger.AddIn.Breakpoints;
using Debugger.AddIn.Tooltips;
using Debugger.AddIn.TreeModel;
using Debugger.Interop.CorPublish;
@ -43,7 +45,7 @@ using TreeNode = Debugger.AddIn.TreeModel.TreeNode; @@ -43,7 +45,7 @@ using TreeNode = Debugger.AddIn.TreeModel.TreeNode;
namespace ICSharpCode.SharpDevelop.Services
{
public class WindowsDebugger : IDebugger
public class WindowsDebugger : BaseDebuggerService
{
public static WindowsDebugger Instance { get; set; }
@ -97,7 +99,7 @@ namespace ICSharpCode.SharpDevelop.Services @@ -97,7 +99,7 @@ namespace ICSharpCode.SharpDevelop.Services
ICorPublish corPublish;
/// <inheritdoc/>
public bool BreakAtBeginning { get; set; }
public override bool BreakAtBeginning { get; set; }
public bool ServiceInitialized {
get { return CurrentDebugger != null; }
@ -116,30 +118,35 @@ namespace ICSharpCode.SharpDevelop.Services @@ -116,30 +118,35 @@ namespace ICSharpCode.SharpDevelop.Services
// string errorProcessPaused = "${res:XML.MainMenu.DebugMenu.Error.ProcessPaused}";
// string errorCannotStepNoActiveFunction = "${res:MainWindow.Windows.Debug.Threads.CannotStepNoActiveFunction}";
public bool IsDebugging {
public override bool IsDebugging {
get {
return ServiceInitialized && CurrentProcess != null;
}
}
public bool IsAttached {
public override bool IsAttached {
get {
return ServiceInitialized && attached;
}
}
public bool IsProcessRunning {
public override bool IsProcessRunning {
get {
return IsDebugging && CurrentProcess.IsRunning;
}
}
public bool CanDebug(IProject project)
public override bool CanDebug(IProject project)
{
return true;
}
public void Start(ProcessStartInfo processStartInfo)
public override bool Supports(DebuggerFeatures feature)
{
return true;
}
public override void Start(ProcessStartInfo processStartInfo)
{
if (IsDebugging) {
MessageService.ShowMessage(errorDebugging);
@ -162,8 +169,7 @@ namespace ICSharpCode.SharpDevelop.Services @@ -162,8 +169,7 @@ namespace ICSharpCode.SharpDevelop.Services
MessageService.ShowMessage("${res:XML.MainMenu.DebugMenu.Error.KernelDebuggerEnabled}");
} else {
attached = false;
if (DebugStarting != null)
DebugStarting(this, EventArgs.Empty);
OnDebugStarting(EventArgs.Empty);
UpdateBreakpointLines();
@ -186,8 +192,7 @@ namespace ICSharpCode.SharpDevelop.Services @@ -186,8 +192,7 @@ namespace ICSharpCode.SharpDevelop.Services
}
MessageService.ShowMessage(msg);
if (DebugStopped != null)
DebugStopped(this, EventArgs.Empty);
OnDebugStopped(EventArgs.Empty);
} else {
throw;
}
@ -195,7 +200,7 @@ namespace ICSharpCode.SharpDevelop.Services @@ -195,7 +200,7 @@ namespace ICSharpCode.SharpDevelop.Services
}
}
public void ShowAttachDialog()
public override void ShowAttachDialog()
{
using (AttachToProcessForm attachForm = new AttachToProcessForm()) {
if (attachForm.ShowDialog(SD.WinForms.MainWin32Window) == DialogResult.OK) {
@ -204,7 +209,7 @@ namespace ICSharpCode.SharpDevelop.Services @@ -204,7 +209,7 @@ namespace ICSharpCode.SharpDevelop.Services
}
}
public void Attach(System.Diagnostics.Process existingProcess)
public override void Attach(System.Diagnostics.Process existingProcess)
{
if (existingProcess == null)
return;
@ -221,8 +226,7 @@ namespace ICSharpCode.SharpDevelop.Services @@ -221,8 +226,7 @@ namespace ICSharpCode.SharpDevelop.Services
if (version.StartsWith("v1.0")) {
MessageService.ShowMessage("${res:XML.MainMenu.DebugMenu.Error.Net10NotSupported}");
} else {
if (DebugStarting != null)
DebugStarting(this, EventArgs.Empty);
OnDebugStarting(EventArgs.Empty);
UpdateBreakpointLines();
@ -237,8 +241,7 @@ namespace ICSharpCode.SharpDevelop.Services @@ -237,8 +241,7 @@ namespace ICSharpCode.SharpDevelop.Services
string msg = StringParser.Parse("${res:XML.MainMenu.DebugMenu.Error.CannotAttachToProcess}");
MessageService.ShowMessage(msg + " " + e.Message);
if (DebugStopped != null)
DebugStopped(this, EventArgs.Empty);
OnDebugStopped(EventArgs.Empty);
} else {
throw;
}
@ -246,18 +249,18 @@ namespace ICSharpCode.SharpDevelop.Services @@ -246,18 +249,18 @@ namespace ICSharpCode.SharpDevelop.Services
}
}
public void Detach()
public override void Detach()
{
ClassBrowserSupport.Detach(CurrentProcess);
CurrentDebugger.Detach();
}
public void StartWithoutDebugging(ProcessStartInfo processStartInfo)
public override void StartWithoutDebugging(ProcessStartInfo processStartInfo)
{
System.Diagnostics.Process.Start(processStartInfo);
}
public void Stop()
public override void Stop()
{
if (!IsDebugging) {
MessageService.ShowMessage(errorNotDebugging, "${res:XML.MainMenu.DebugMenu.Stop}");
@ -280,53 +283,41 @@ namespace ICSharpCode.SharpDevelop.Services @@ -280,53 +283,41 @@ namespace ICSharpCode.SharpDevelop.Services
}
}
public void Break()
public override void Break()
{
if (CurrentProcess != null && CurrentProcess.IsRunning) {
CurrentProcess.Break();
}
}
public void Continue()
public override void Continue()
{
if (CurrentProcess != null && CurrentProcess.IsPaused) {
CurrentProcess.AsyncContinue();
}
}
public void StepInto()
public override void StepInto()
{
if (CurrentStackFrame != null) {
CurrentStackFrame.AsyncStepInto();
}
}
public void StepOver()
public override void StepOver()
{
if (CurrentStackFrame != null) {
CurrentStackFrame.AsyncStepOver();
}
}
public void StepOut()
public override void StepOut()
{
if (CurrentStackFrame != null) {
CurrentStackFrame.AsyncStepOut();
}
}
public event EventHandler DebugStarting;
public event EventHandler DebugStarted;
public event EventHandler DebugStopped;
public event EventHandler IsProcessRunningChanged;
protected virtual void OnIsProcessRunningChanged(EventArgs e)
{
if (IsProcessRunningChanged != null) {
IsProcessRunningChanged(this, e);
}
}
public bool IsManaged(int processId)
{
corPublish = new CorpubPublishClass();
@ -339,7 +330,7 @@ namespace ICSharpCode.SharpDevelop.Services @@ -339,7 +330,7 @@ namespace ICSharpCode.SharpDevelop.Services
return false;
}
public bool SetInstructionPointer(string filename, int line, int column, bool dryRun)
public override bool SetInstructionPointer(string filename, int line, int column, bool dryRun)
{
if (CurrentStackFrame != null) {
if (CurrentStackFrame.SetIP(filename, line, column, dryRun)) {
@ -350,11 +341,6 @@ namespace ICSharpCode.SharpDevelop.Services @@ -350,11 +341,6 @@ namespace ICSharpCode.SharpDevelop.Services
return false;
}
public void Dispose()
{
Stop();
}
#endregion
public event EventHandler Initialize;
@ -431,7 +417,7 @@ namespace ICSharpCode.SharpDevelop.Services @@ -431,7 +417,7 @@ namespace ICSharpCode.SharpDevelop.Services
return false;
} catch (GetValueException e) {
string errorMessage = "Error while evaluating breakpoint condition " + code + ":\n" + e.Message + "\n";
DebuggerService.PrintDebugMessage(errorMessage);
BaseDebuggerService.PrintDebugMessage(errorMessage);
SD.MainThread.InvokeAsyncAndForget(() => MessageService.ShowWarning(errorMessage));
return true;
}
@ -439,14 +425,12 @@ namespace ICSharpCode.SharpDevelop.Services @@ -439,14 +425,12 @@ namespace ICSharpCode.SharpDevelop.Services
void LogMessage(object sender, MessageEventArgs e)
{
DebuggerService.PrintDebugMessage(e.Message);
BaseDebuggerService.PrintDebugMessage(e.Message);
}
void debugger_ProcessStarted()
{
if (DebugStarted != null) {
DebugStarted(this, EventArgs.Empty);
}
OnDebugStarted(EventArgs.Empty);
CurrentProcess.ModuleLoaded += (s, e) => UpdateBreakpointIcons();
CurrentProcess.ModuleLoaded += (s, e) => RefreshPads();
@ -462,9 +446,7 @@ namespace ICSharpCode.SharpDevelop.Services @@ -462,9 +446,7 @@ namespace ICSharpCode.SharpDevelop.Services
void debugger_ProcessExited()
{
if (DebugStopped != null) {
DebugStopped(this, EventArgs.Empty);
}
OnDebugStopped(EventArgs.Empty);
ClassBrowserSupport.Detach(CurrentProcess);
CurrentProcess = null;
@ -572,7 +554,7 @@ namespace ICSharpCode.SharpDevelop.Services @@ -572,7 +554,7 @@ namespace ICSharpCode.SharpDevelop.Services
} else {
if (EvaluateCondition(bookmark.Condition)) {
breakProcess = true;
DebuggerService.PrintDebugMessage(string.Format(StringParser.Parse("${res:MainWindow.Windows.Debug.Conditional.Breakpoints.BreakpointHitAtBecause}") + "\n", bookmark.LineNumber, bookmark.FileName, bookmark.Condition));
BaseDebuggerService.PrintDebugMessage(string.Format(StringParser.Parse("${res:MainWindow.Windows.Debug.Conditional.Breakpoints.BreakpointHitAtBecause}") + "\n", bookmark.LineNumber, bookmark.FileName, bookmark.Condition));
}
}
}
@ -588,7 +570,7 @@ namespace ICSharpCode.SharpDevelop.Services @@ -588,7 +570,7 @@ namespace ICSharpCode.SharpDevelop.Services
void debuggedProcess_DebuggingResumed(object sender, DebuggerEventArgs e)
{
OnIsProcessRunningChanged(EventArgs.Empty);
DebuggerService.RemoveCurrentLineMarker();
RemoveCurrentLineMarker();
CurrentThread = null;
CurrentStackFrame = null;
@ -612,10 +594,10 @@ namespace ICSharpCode.SharpDevelop.Services @@ -612,10 +594,10 @@ namespace ICSharpCode.SharpDevelop.Services
return;
SD.Workbench.MainWindow.Activate();
DebuggerService.RemoveCurrentLineMarker();
RemoveCurrentLineMarker();
SequencePoint nextStatement = CurrentStackFrame.NextStatement;
if (nextStatement != null) {
DebuggerService.JumpToCurrentLine(nextStatement.Filename, nextStatement.StartLine, nextStatement.StartColumn, nextStatement.EndLine, nextStatement.EndColumn);
JumpToCurrentLine(nextStatement.Filename, nextStatement.StartLine, nextStatement.StartColumn, nextStatement.EndLine, nextStatement.EndColumn);
}
}
@ -637,7 +619,7 @@ namespace ICSharpCode.SharpDevelop.Services @@ -637,7 +619,7 @@ namespace ICSharpCode.SharpDevelop.Services
.ForEach(p => e.Module.LoadSymbolsFromDisk(new []{ Path.GetDirectoryName(p.OutputAssemblyFullPath) }));
}
public void HandleToolTipRequest(ToolTipRequestEventArgs e)
public override void HandleToolTipRequest(ToolTipRequestEventArgs e)
{
if (!(IsDebugging && CurrentProcess.IsPaused))
return;
@ -647,12 +629,7 @@ namespace ICSharpCode.SharpDevelop.Services @@ -647,12 +629,7 @@ namespace ICSharpCode.SharpDevelop.Services
if (resolveResult == null)
return;
if (resolveResult is LocalResolveResult || resolveResult is MemberResolveResult) {
string text = string.Empty;
try {
text = new ResolveResultPrettyPrinter().Print(resolveResult);
} catch (NotImplementedException ex) {
SD.Log.Warn(ex);
}
string text = ResolveResultPrettyPrinter.Print(resolveResult);
Func<Value> getValue = delegate {
ExpressionEvaluationVisitor eval = new ExpressionEvaluationVisitor(CurrentStackFrame, EvalThread, CurrentStackFrame.AppDomain.Compilation);
return eval.Convert(resolveResult);
@ -665,5 +642,32 @@ namespace ICSharpCode.SharpDevelop.Services @@ -665,5 +642,32 @@ namespace ICSharpCode.SharpDevelop.Services
}
}
}
public override void RemoveCurrentLineMarker()
{
CurrentLineBookmark.Remove();
}
public override void ToggleBreakpointAt(ITextEditor editor, int lineNumber)
{
if (editor == null)
throw new ArgumentNullException("editor");
if (!SD.BookmarkManager.RemoveBookmarkAt(editor.FileName, lineNumber, b => b is BreakpointBookmark)) {
SD.BookmarkManager.AddMark(new BreakpointBookmark(), editor.Document, lineNumber);
}
}
public override void JumpToCurrentLine(string sourceFullFilename, int startLine, int startColumn, int endLine, int endColumn)
{
IViewContent viewContent = FileService.OpenFile(sourceFullFilename);
if (viewContent != null) {
IPositionable positionable = viewContent.GetService<IPositionable>();
if (positionable != null) {
positionable.JumpTo(startLine, startColumn);
}
}
CurrentLineBookmark.SetPosition(viewContent, startLine, startColumn, endLine, endColumn);
}
}
}

3
src/AddIns/Debugger/Debugger.AddIn/Visualizers/GraphVisualizer/ObjectGraphControl.xaml.cs

@ -28,6 +28,7 @@ using System.Windows.Documents; @@ -28,6 +28,7 @@ using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using ICSharpCode.SharpDevelop;
using Debugger.AddIn.TreeModel;
using Debugger.AddIn.Visualizers.Graph.Layout;
using ICSharpCode.NRefactory.Ast;
@ -60,7 +61,7 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -60,7 +61,7 @@ namespace Debugger.AddIn.Visualizers.Graph
{
InitializeComponent();
debuggerService = DebuggerService.CurrentDebugger as WindowsDebugger;
debuggerService = SD.Debugger as WindowsDebugger;
if (debuggerService == null) throw new ApplicationException("Only windows debugger is currently supported");
this.layoutViewModel = new EnumViewModel<LayoutDirection>();

3
src/AddIns/Debugger/Debugger.AddIn/Visualizers/GraphVisualizer/ObjectGraphWindow.xaml.cs

@ -29,6 +29,7 @@ using System.Windows.Input; @@ -29,6 +29,7 @@ using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using ICSharpCode.SharpDevelop;
using Debugger.AddIn.Visualizers.Graph.Layout;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Services;
@ -46,7 +47,7 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -46,7 +47,7 @@ namespace Debugger.AddIn.Visualizers.Graph
{
InitializeComponent();
debuggerService = DebuggerService.CurrentDebugger as WindowsDebugger;
debuggerService = SD.Debugger as WindowsDebugger;
if (debuggerService == null) throw new DebuggerVisualizerException("Only windows debugger is currently supported");
}

2
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ClipboardRing.cs

@ -36,7 +36,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.ContextActions @@ -36,7 +36,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.ContextActions
var popupViewModel = new ContextActionsPopupViewModel();
var actions = BuildClipboardRingData(context);
string labelSource = "${res:SharpDevelop.Refactoring.ClipboardRing}";
string labelSource = "${res:SharpDevelop.SideBar.ClipboardRing}";
if (actions == null || actions.Count == 0)
labelSource = "${res:SharpDevelop.Refactoring.ClipboardRingEmpty}";

155
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/IconBarMargin.cs

@ -18,13 +18,17 @@ @@ -18,13 +18,17 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using ICSharpCode.AvalonEdit.Editing;
using ICSharpCode.AvalonEdit.Rendering;
using ICSharpCode.AvalonEdit.Utils;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.Bookmarks;
@ -37,12 +41,17 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -37,12 +41,17 @@ namespace ICSharpCode.AvalonEdit.AddIn
public class IconBarMargin : AbstractMargin, IDisposable
{
readonly IBookmarkMargin manager;
readonly MouseHoverLogic hoverLogic;
public IconBarMargin(IBookmarkMargin manager)
{
if (manager == null)
throw new ArgumentNullException("manager");
this.manager = manager;
this.hoverLogic = new MouseHoverLogic(this);
this.hoverLogic.MouseHover += (sender, e) => MouseHover(this, e);
this.hoverLogic.MouseHoverStopped += (sender, e) => MouseHoverStopped(this, e);
this.Unloaded += OnUnloaded;
}
#region OnTextViewChanged
@ -51,11 +60,13 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -51,11 +60,13 @@ namespace ICSharpCode.AvalonEdit.AddIn
{
if (oldTextView != null) {
oldTextView.VisualLinesChanged -= OnRedrawRequested;
oldTextView.MouseMove -= TextViewMouseMove;
manager.RedrawRequested -= OnRedrawRequested;
}
base.OnTextViewChanged(oldTextView, newTextView);
if (newTextView != null) {
newTextView.VisualLinesChanged += OnRedrawRequested;
newTextView.MouseMove += TextViewMouseMove;
manager.RedrawRequested += OnRedrawRequested;
}
InvalidateVisual();
@ -228,6 +239,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -228,6 +239,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
dragStarted = true;
InvalidateVisual();
}
TextViewMouseMove(TextView, e);
}
protected override void OnMouseUp(MouseButtonEventArgs e)
@ -253,11 +265,152 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -253,11 +265,152 @@ namespace ICSharpCode.AvalonEdit.AddIn
// no bookmark on the line: create a new breakpoint
ITextEditor textEditor = TextView.GetService(typeof(ITextEditor)) as ITextEditor;
if (textEditor != null) {
DebuggerService.ToggleBreakpointAt(textEditor, line);
SD.Debugger.ToggleBreakpointAt(textEditor, line);
return;
}
}
}
}
#region Tooltip
ToolTip toolTip;
Popup popupToolTip;
void MouseHover(object sender, MouseEventArgs e)
{
Debug.Assert(sender == this);
if (!TryCloseExistingPopup(false)) {
return;
}
int line = GetLineFromMousePosition(e);
if (line < 1) return;
IBookmark bm = GetBookmarkFromLine(line);
if (bm == null) return;
object content = bm.CreateTooltipContent();
popupToolTip = content as Popup;
if (popupToolTip != null) {
var popupPosition = GetPopupPosition(line);
popupToolTip.Closed += ToolTipClosed;
popupToolTip.HorizontalOffset = popupPosition.X;
popupToolTip.VerticalOffset = popupPosition.Y;
popupToolTip.StaysOpen = true; // We will close it ourselves
e.Handled = true;
popupToolTip.IsOpen = true;
distanceToPopupLimit = double.PositiveInfinity; // reset limit; we'll re-calculate it on the next mouse movement
} else {
if (toolTip == null) {
toolTip = new ToolTip();
toolTip.Closed += ToolTipClosed;
}
toolTip.PlacementTarget = this; // required for property inheritance
if (content is string) {
toolTip.Content = new TextBlock
{
Text = content as string,
TextWrapping = TextWrapping.Wrap
};
} else toolTip.Content = content;
e.Handled = true;
toolTip.IsOpen = true;
}
}
bool TryCloseExistingPopup(bool mouseClick)
{
if (popupToolTip != null) {
if (popupToolTip.IsOpen && !mouseClick && popupToolTip is ITooltip && !((ITooltip)popupToolTip).CloseWhenMouseMovesAway) {
return false; // Popup does not want to be closed yet
}
popupToolTip.IsOpen = false;
popupToolTip = null;
}
return true;
}
Point GetPopupPosition(int line)
{
Point positionInPixels = TextView.PointToScreen(TextView.GetVisualPosition(new TextViewPosition(line, 1), VisualYPosition.LineBottom) - this.TextView.ScrollOffset);
positionInPixels.X -= 50;
// use device independent units, because Popup Left/Top are in independent units
return positionInPixels.TransformFromDevice(this);
}
void MouseHoverStopped(object sender, MouseEventArgs e)
{
// Non-popup tooltips get closed as soon as the mouse starts moving again
if (toolTip != null) {
toolTip.IsOpen = false;
e.Handled = true;
}
}
double distanceToPopupLimit;
const double MaxMovementAwayFromPopup = 5;
double GetDistanceToPopup(MouseEventArgs e)
{
Point p = popupToolTip.Child.PointFromScreen(PointToScreen(e.GetPosition(this)));
Size size = popupToolTip.Child.RenderSize;
double x = 0;
if (p.X < 0)
x = -p.X;
else if (p.X > size.Width)
x = p.X - size.Width;
double y = 0;
if (p.Y < 0)
y = -p.Y;
else if (p.Y > size.Height)
y = p.Y - size.Height;
return Math.Sqrt(x * x + y * y);
}
protected override void OnMouseLeave(MouseEventArgs e)
{
if (popupToolTip != null && !popupToolTip.IsMouseOver && GetDistanceToPopup(e) > 10) {
// do not close popup if mouse moved from editor to popup
TryCloseExistingPopup(false);
}
}
void TextViewMouseMove(object sender, MouseEventArgs e)
{
if (popupToolTip != null) {
double distanceToPopup = GetDistanceToPopup(e);
if (distanceToPopup > distanceToPopupLimit) {
// Close popup if mouse moved away, exceeding the limit
TryCloseExistingPopup(false);
} else {
// reduce distanceToPopupLimit
distanceToPopupLimit = Math.Min(distanceToPopupLimit, distanceToPopup + MaxMovementAwayFromPopup);
}
}
}
void OnUnloaded(object sender, EventArgs e)
{
// Close popup when another document gets selected
// TextEditorMouseLeave is not sufficient for this because the mouse might be over the popup when the document switch happens (e.g. Ctrl+Tab)
TryCloseExistingPopup(true);
}
void ToolTipClosed(object sender, EventArgs e)
{
if (toolTip == sender) {
toolTip = null;
}
if (popupToolTip == sender) {
// Because popupToolTip instances are created by the tooltip provider,
// they might be reused; so we should detach the event handler
popupToolTip.Closed -= ToolTipClosed;
popupToolTip = null;
}
}
#endregion
}
}

3
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Options/GeneralEditorOptions.xaml

@ -27,9 +27,6 @@ @@ -27,9 +27,6 @@
<CheckBox
IsChecked="{core:OptionBinding local:CodeEditorOptions.ShowHiddenDefinitions}"
Content="{core:Localize Dialog.Options.IDEOptions.TextEditor.Markers.ShowHiddenDefinitionsCheckBox}" />
<CheckBox
IsChecked="{core:OptionBinding local:CodeEditorOptions.AllowToggleOverstrikeMode}"
Content="Allow Overstrike mode" />
</widgets:StackPanelWithSpacing>
</GroupBox>
</StackPanel>

13
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Options/HighlightingOptions.xaml.cs

@ -38,6 +38,7 @@ using ICSharpCode.NRefactory.Utils; @@ -38,6 +38,7 @@ using ICSharpCode.NRefactory.Utils;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.Bookmarks;
using ICSharpCode.SharpDevelop.Gui;
using Microsoft.Win32;
@ -496,7 +497,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Options @@ -496,7 +497,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Options
items.Add(messageMarker);
IHighlightingItem breakpointMarker = new SimpleHighlightingItem(
BreakpointBookmark.BreakpointMarker,
BookmarkBase.BreakpointMarkerName,
ta => {
ta.Document.Text = "some code with a breakpoint";
ITextMarker marker = textMarkerService.Create(0, ta.Document.TextLength);
@ -506,15 +507,15 @@ namespace ICSharpCode.AvalonEdit.AddIn.Options @@ -506,15 +507,15 @@ namespace ICSharpCode.AvalonEdit.AddIn.Options
};
})
{
Background = BreakpointBookmark.DefaultBackground,
Foreground = BreakpointBookmark.DefaultForeground
Background = BookmarkBase.BreakpointDefaultBackground,
Foreground = BookmarkBase.BreakpointDefaultForeground
};
breakpointMarker = new CustomizedHighlightingItem(customizationList, breakpointMarker, language, canSetFont: false);
breakpointMarker.PropertyChanged += item_PropertyChanged;
items.Add(breakpointMarker);
IHighlightingItem currentStatementMarker = new SimpleHighlightingItem(
CurrentLineBookmark.Name,
BookmarkBase.CurrentLineBookmarkName,
ta => {
ta.Document.Text = "current statement line";
ITextMarker marker = textMarkerService.Create(0, ta.Document.TextLength);
@ -524,8 +525,8 @@ namespace ICSharpCode.AvalonEdit.AddIn.Options @@ -524,8 +525,8 @@ namespace ICSharpCode.AvalonEdit.AddIn.Options
};
})
{
Background = CurrentLineBookmark.DefaultBackground,
Foreground = CurrentLineBookmark.DefaultForeground
Background = BookmarkBase.CurrentLineDefaultBackground,
Foreground = BookmarkBase.CurrentLineDefaultForeground
};
currentStatementMarker = new CustomizedHighlightingItem(customizationList, currentStatementMarker, language, canSetFont: false);
currentStatementMarker.PropertyChanged += item_PropertyChanged;

4
src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerViewContent.cs

@ -143,7 +143,7 @@ namespace ICSharpCode.FormsDesigner @@ -143,7 +143,7 @@ namespace ICSharpCode.FormsDesigner
this.IsActiveViewContentChanged += this.IsActiveViewContentChangedHandler;
FileService.FileRemoving += this.FileServiceFileRemoving;
ICSharpCode.SharpDevelop.Debugging.DebuggerService.DebugStarting += this.DebugStarting;
SD.Debugger.DebugStarting += this.DebugStarting;
}
public FormsDesignerViewContent(IViewContent primaryViewContent, IDesignerLoaderProvider loaderProvider)
@ -715,7 +715,7 @@ namespace ICSharpCode.FormsDesigner @@ -715,7 +715,7 @@ namespace ICSharpCode.FormsDesigner
// to SaveInternal which requires the designer to be loaded.
base.Dispose();
} finally {
ICSharpCode.SharpDevelop.Debugging.DebuggerService.DebugStarting -= this.DebugStarting;
SD.Debugger.DebugStarting -= this.DebugStarting;
FileService.FileRemoving -= this.FileServiceFileRemoving;
this.UnloadDesigner();

1
src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.addin

@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
<Manifest>
<Identity name="ICSharpCode.ILSpyAddIn" />
<Dependency addin="ICSharpCode.Debugger" requirePreload="true" />
</Manifest>
<Runtime>

13
src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyParser.cs

@ -67,6 +67,19 @@ namespace ICSharpCode.ILSpyAddIn @@ -67,6 +67,19 @@ namespace ICSharpCode.ILSpyAddIn
return ResolveAtLocation.Resolve(compilation, null, decompiledParseInfo.SyntaxTree, location, cancellationToken);
}
public ICodeContext ResolveContext(ParseInformation parseInfo, TextLocation location, ICompilation compilation, CancellationToken cancellationToken)
{
var decompiledParseInfo = parseInfo as ILSpyFullParseInformation;
if (decompiledParseInfo == null)
throw new ArgumentException("ParseInfo does not have SyntaxTree");
var syntaxTree = decompiledParseInfo.SyntaxTree;
var node = syntaxTree.GetNodeAt(location);
if (node == null)
return null; // null result is allowed; the parser service will substitute a dummy context
var resolver = new CSharpAstResolver(compilation, syntaxTree, null);
return resolver.GetResolverStateBefore(node);
}
public ResolveResult ResolveSnippet(ParseInformation parseInfo, TextLocation location, string codeSnippet, ICompilation compilation, CancellationToken cancellationToken)
{
throw new NotImplementedException();

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ModelTools.cs

@ -150,7 +150,7 @@ namespace ICSharpCode.WpfDesign.Designer @@ -150,7 +150,7 @@ namespace ICSharpCode.WpfDesign.Designer
}
if (double.IsNaN(s.Height) && createdItem.View.DesiredSize.Height > 0)
{
s.Height = createdItem.View.DesiredSize.Width;
s.Height = createdItem.View.DesiredSize.Height;
}
var newS = Metadata.GetDefaultSize(createdItem.ComponentType, true);

3
src/AddIns/DisplayBindings/XmlEditor/Project/XmlEditor.addin

@ -103,8 +103,7 @@ @@ -103,8 +103,7 @@
class="ICSharpCode.XmlEditor.CreateSchemaCommand"/>
<MenuItem id="ValidateXml"
label="${res:ICSharpCode.XmlEditor.ValidateXmlMenuLabel}"
class="ICSharpCode.XmlEditor.ValidateXmlCommand"
shortcut="Control|Shift|V"/>
class="ICSharpCode.XmlEditor.ValidateXmlCommand"/>
<MenuItem id="GoToDefinition"
label="${res:ICSharpCode.NAntAddIn.GotoDefinitionMenuLabel}"
class="ICSharpCode.XmlEditor.GoToSchemaDefinitionCommand"/>

2
src/AddIns/Misc/AddInManager2/AddInManager2.Tests/Fakes/FakeCorePackageRepository.cs

@ -78,5 +78,7 @@ namespace ICSharpCode.AddInManager2.Tests.Fakes @@ -78,5 +78,7 @@ namespace ICSharpCode.AddInManager2.Tests.Fakes
get;
set;
}
public PackageSaveModes PackageSaveMode { get; set; }
}
}

3
src/AddIns/Misc/AddInManager2/AddInManager2.Tests/Fakes/FakeNuGetCorePackageManager.cs

@ -171,5 +171,8 @@ namespace ICSharpCode.AddInManager2.Tests.Fakes @@ -171,5 +171,8 @@ namespace ICSharpCode.AddInManager2.Tests.Fakes
{
throw new NotImplementedException();
}
public DependencyVersion DependencyVersion { get; set; }
public bool WhatIf { get; set; }
}
}

2
src/AddIns/Misc/AddInManager2/AddInManager2.Tests/Fakes/FakePackage.cs

@ -202,5 +202,7 @@ namespace ICSharpCode.AddInManager2.Tests.Fakes @@ -202,5 +202,7 @@ namespace ICSharpCode.AddInManager2.Tests.Fakes
{
return string.Format("[FakePackage Id={0}, Version={1}]", Id, Version);
}
public bool DevelopmentDependency { get; set; }
}
}

3
src/AddIns/Misc/AddInManager2/Project/Src/Model/NuGetPackageManager.cs

@ -109,7 +109,8 @@ namespace ICSharpCode.AddInManager2.Model @@ -109,7 +109,8 @@ namespace ICSharpCode.AddInManager2.Model
null,
_logger,
false,
allowPrereleaseVersions);
allowPrereleaseVersions,
DependencyVersion.Lowest);
}
public void ExecuteOperation(PackageOperation operation)

2
src/AddIns/Misc/AddInManager2/Project/Src/View/AddInManagerView.xaml

@ -56,7 +56,7 @@ @@ -56,7 +56,7 @@
</DataTemplate>
<DataTemplate x:Key="packageRepositoryItemTemplate" DataType="{x:Type model:PackageRepository}">
<TextBlock Text="{Binding Path=NameWithHighlight}">
<TextBlock Text="{Binding Path=NameWithHighlight}" ToolTip="{Binding Path=NameWithHighlight}" TextWrapping="Wrap">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>

146
src/AddIns/Misc/AddInManager2/Project/Src/View/AddInsView.xaml

@ -91,6 +91,8 @@ @@ -91,6 +91,8 @@
<Style x:Key="addInListButtonStyle" TargetType="{x:Type Button}" BasedOn="{x:Static core:GlobalStyles.ButtonStyle}">
<Setter Property="Visibility" Value="Collapsed" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Margin" Value="2,2,2,2" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
@ -128,16 +130,16 @@ @@ -128,16 +130,16 @@
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<!--<Grid.RowDefinitions>
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
</Grid.RowDefinitions>-->
<Image
Grid.Column="0"
Height="32"
VerticalAlignment="Top"
Style="{StaticResource AddInImageStyle}" />
<Image
Grid.Column="0"
@ -159,79 +161,66 @@ @@ -159,79 +161,66 @@
Width="16"
Style="{StaticResource InstalledTickImageStyle}"
Margin="36,0,0,0"/>
<StackPanel
Grid.Column="1"
Margin="4, 0">
<TextBlock
x:Name="nameTextBlock"
Text="{Binding Path=Name}"
FontWeight="Bold"/>
<TextBlock
x:Name="summaryTextBlock"
Text="{Binding Path=Summary}"
TextWrapping="Wrap"
TextTrimming="CharacterEllipsis"
MaxHeight="40"/>
</StackPanel>
<Button
x:Name="addPackageButton"
Grid.Column="2"
Content="{core:Localize AddInManager.ActionInstall}"
IsDefault="True"
Command="{Binding Path=AddPackageCommand}"
VerticalAlignment="Top"
Style="{StaticResource addInListButtonStyle}"
Margin="2,2,2,2"/>
<Button
x:Name="updatePackageButton"
Grid.Column="2"
Content="{core:Localize AddInManager.ActionUpdate}"
IsDefault="True"
Command="{Binding Path=UpdatePackageCommand}"
VerticalAlignment="Top"
Style="{StaticResource addInListButtonStyle}"
Margin="2,2,2,2"/>
<Button
x:Name="disablePackageButton"
Grid.Column="2"
Content="{core:Localize AddInManager.ActionDisable}"
IsDefault="True"
Command="{Binding Path=DisablePackageCommand}"
VerticalAlignment="Top"
Style="{StaticResource addInListButtonStyle}"
Margin="2,2,2,2"/>
<Button
x:Name="removePackageButton"
Grid.Column="2"
Content="{core:Localize AddInManager.ActionUninstall}"
Command="{Binding Path=RemovePackageCommand}"
VerticalAlignment="Bottom"
Style="{StaticResource addInListButtonStyle}"
Margin="2,2,2,2"/>
<Button
x:Name="cancelInstallationButton"
Grid.Column="2"
Content="{core:Localize AddInManager.ActionCancelInstallation}"
Command="{Binding Path=CancelInstallationCommand}"
VerticalAlignment="Bottom"
Style="{StaticResource addInListButtonStyle}"
Margin="2,2,2,2"/>
<Button
x:Name="cancelUpdateButton"
Grid.Column="2"
Content="{core:Localize AddInManager.ActionCancelUpdate}"
Command="{Binding Path=CancelUpdateCommand}"
VerticalAlignment="Bottom"
Style="{StaticResource addInListButtonStyle}"
Margin="2,2,2,2"/>
<Button
x:Name="cancelUninstallationButton"
Grid.Column="2"
Content="{core:Localize AddInManager.ActionCancelDeinstallation}"
Command="{Binding Path=CancelUninstallationCommand}"
VerticalAlignment="Bottom"
Style="{StaticResource addInListButtonStyle}"
Margin="2,2,2,2"/>
<Grid Grid.Column="1" Margin="0,0,0,0" HorizontalAlignment="Left">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="4,4,4,4" HorizontalAlignment="Left">
<TextBlock
x:Name="nameTextBlock"
Text="{Binding Path=Name}"
FontWeight="Bold"
TextWrapping="Wrap"
Margin="0,0,0,6"/>
<TextBlock
x:Name="summaryTextBlock"
Text="{Binding Path=Summary}"
TextWrapping="Wrap"
TextTrimming="CharacterEllipsis"/>
</StackPanel>
<StackPanel Grid.Row="1" Margin="2,2,2,2" Orientation="Horizontal">
<Button
x:Name="addPackageButton"
Content="{core:Localize AddInManager.ActionInstall}"
IsDefault="True"
Command="{Binding Path=AddPackageCommand}"
Style="{StaticResource addInListButtonStyle}"/>
<Button
x:Name="updatePackageButton"
Content="{core:Localize AddInManager.ActionUpdate}"
IsDefault="True"
Command="{Binding Path=UpdatePackageCommand}"
Style="{StaticResource addInListButtonStyle}"/>
<Button
x:Name="disablePackageButton"
Content="{core:Localize AddInManager.ActionDisable}"
IsDefault="True"
Command="{Binding Path=DisablePackageCommand}"
Style="{StaticResource addInListButtonStyle}"/>
<Button
x:Name="removePackageButton"
Content="{core:Localize AddInManager.ActionUninstall}"
Command="{Binding Path=RemovePackageCommand}"
Style="{StaticResource addInListButtonStyle}"/>
<Button
x:Name="cancelInstallationButton"
Content="{core:Localize AddInManager.ActionCancelInstallation}"
Command="{Binding Path=CancelInstallationCommand}"
Style="{StaticResource addInListButtonStyle}"/>
<Button
x:Name="cancelUpdateButton"
Content="{core:Localize AddInManager.ActionCancelUpdate}"
Command="{Binding Path=CancelUpdateCommand}"
Style="{StaticResource addInListButtonStyle}"/>
<Button
x:Name="cancelUninstallationButton"
Content="{core:Localize AddInManager.ActionCancelDeinstallation}"
Command="{Binding Path=CancelUninstallationCommand}"
Style="{StaticResource addInListButtonStyle}"/>
</StackPanel>
</Grid>
</Grid>
<DataTemplate.Triggers>
@ -468,12 +457,11 @@ @@ -468,12 +457,11 @@
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="100"/>
<ColumnDefinition MinWidth="200"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width=".6*" MinWidth="100"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Grid>
<Grid.RowDefinitions>
@ -495,7 +483,7 @@ @@ -495,7 +483,7 @@
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- <TextBlock
<!-- <TextBlock
Grid.Row="0"
Grid.Column="0"
VerticalAlignment="Center"

2
src/AddIns/Misc/AddInManager2/Project/Src/ViewModel/InstalledAddInsViewModel.cs

@ -73,7 +73,7 @@ namespace ICSharpCode.AddInManager2.ViewModel @@ -73,7 +73,7 @@ namespace ICSharpCode.AddInManager2.ViewModel
{
return base.GetFilteredPackagesBeforePagingResults(allPackages)
.Where(package => package.IsReleaseVersion())
.DistinctLast(PackageEqualityComparer.Id);
.DistinctLast<IPackage>(PackageEqualityComparer.Id);
}
protected override void UpdatePackageViewModels(IEnumerable<IPackage> packages)

2
src/AddIns/Misc/AddInManager2/Project/Src/ViewModel/NuGetAddInsViewModelBase.cs

@ -207,7 +207,7 @@ namespace ICSharpCode.AddInManager2.ViewModel @@ -207,7 +207,7 @@ namespace ICSharpCode.AddInManager2.ViewModel
{
return GetBufferedPackages(allPackages)
.Where(package => ShowPrereleases || package.IsReleaseVersion())
.DistinctLast(PackageEqualityComparer.Id);
.DistinctLast<IPackage>(PackageEqualityComparer.Id);
}
private IEnumerable<IPackage> GetBufferedPackages(IQueryable<IPackage> allPackages)

4
src/AddIns/Misc/AddInManager2/Project/Src/ViewModel/OfflineAddInViewModel.cs

@ -267,8 +267,8 @@ namespace ICSharpCode.AddInManager2.ViewModel @@ -267,8 +267,8 @@ namespace ICSharpCode.AddInManager2.ViewModel
{
get
{
// Disabling is only possible if this AddIn has an identity!
return (Id != null);
// Disabling is only possible if this AddIn has an identity and is not the AddInManager itself
return (Id != null) && (_addIn.Manifest.PrimaryIdentity != "ICSharpCode.AddInManager2");
}
}

2
src/AddIns/Misc/PackageManagement/Cmdlets/Project/Src/GetPackageCmdlet.cs

@ -111,7 +111,7 @@ namespace ICSharpCode.PackageManagement.Cmdlets @@ -111,7 +111,7 @@ namespace ICSharpCode.PackageManagement.Cmdlets
IEnumerable<IPackage> DistinctPackagesById(IQueryable<IPackage> packages)
{
if (ListAvailable && !AllVersions) {
return packages.DistinctLast(PackageEqualityComparer.Id);
return packages.DistinctLast<IPackage>(PackageEqualityComparer.Id);
}
return packages;
}

4
src/AddIns/Misc/PackageManagement/Packages/AvalonEdit.Sample/AvalonEdit.Sample.nuspec

@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
<package xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<metadata xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<id>AvalonEdit.Sample</id>
<version>4.3.1.9430</version>
<version>4.4.0.9727</version>
<authors>Daniel Grunwald</authors>
<owners>SharpDevelop</owners>
<licenseUrl>http://opensource.org/licenses/MIT</licenseUrl>
@ -16,7 +16,7 @@ StartupUri="/Samples/AvalonEdit/Window1.xaml"</description> @@ -16,7 +16,7 @@ StartupUri="/Samples/AvalonEdit/Window1.xaml"</description>
<summary>Sample code for AvalonEdit the WPF-based text editor used in SharpDevelop 4.0.</summary>
<language>en-US</language>
<dependencies>
<dependency id="AvalonEdit" version="4.3.1.9430" />
<dependency id="AvalonEdit" version="4.4.0.9727" />
</dependencies>
<frameworkAssemblies>
<frameworkAssembly assemblyName="System.Windows.Forms" />

7
src/AddIns/Misc/PackageManagement/Packages/AvalonEdit/AvalonEdit.nuspec

@ -2,17 +2,16 @@ @@ -2,17 +2,16 @@
<package xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<metadata xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<id>AvalonEdit</id>
<version>4.3.1.9430</version>
<version>4.4.0.9727</version>
<authors>Daniel Grunwald</authors>
<owners>SharpDevelop</owners>
<licenseUrl>http://opensource.org/licenses/MIT</licenseUrl>
<projectUrl>http://www.avalonedit.net</projectUrl>
<iconUrl>http://community.sharpdevelop.net/blogs/mattward/SharpDevelop.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>AvalonEdit is the WPF-based text editor used in SharpDevelop. There are two builds of AvalonEdit included in this package. One that targets .NET 4.0 and one that targets .NET 3.5.</description>
<description>AvalonEdit is the WPF-based text editor used in SharpDevelop. There are two builds of AvalonEdit included in this package. One that targets .NET 4.0 and one that targets .NET 3.5.</description>
<summary>AvalonEdit is the WPF-based text editor used in SharpDevelop</summary>
<releaseNotes>AvalonEdit 4.3 adds support for input method editors (IME); and fixes a major bug that sometimes caused "InvalidOperationException: Trying to build visual line from collapsed line" when updating existing foldings.
AvalonEdit 4.3.1 fixes a bug in IME support - we did not properly re-enable the IME if it was disabled by another WPF control.</releaseNotes>
<releaseNotes>AvalonEdit 4.4 changes the Home/End keys to only act on the current TextLine when word-wrapping is enabled. It also removes the caret stop in the middle of surrogate pairs, making characters outside the basic multilingual plane work as expected.</releaseNotes>
<language>en-US</language>
<tags>WPF Text Editor SharpDevelop AvalonEdit</tags>
</metadata>

BIN
src/AddIns/Misc/PackageManagement/Packages/NuGet.exe

Binary file not shown.

8
src/AddIns/Misc/PackageManagement/Packages/buildpackages.cmd

@ -1,9 +1,12 @@ @@ -1,9 +1,12 @@
@ECHO OFF
SETLOCAL
SET msbuild=%windir%\microsoft.net\framework\v4.0.30319\msbuild
SET documentation=..\..\..\..\Libraries\AvalonEdit\Documentation
SET project=..\..\..\..\Libraries\AvalonEdit\ICSharpCode.AvalonEdit\ICSharpCode.AvalonEdit.csproj
SET buildoptions=/t:Rebuild /p:Configuration=Release /p:DebugType=PdbOnly
@echo Using this script requires nuget.exe to be in the PATH, and that Sandcastle Help File Builder is installed.
@ECHO ON
:Clean debug build
%msbuild% /m %project% /t:Clean /p:Configuration=Debug /p:OutputPath=%~dp0\AvalonEdit\lib\Net40
@ -14,6 +17,11 @@ SET buildoptions=/t:Rebuild /p:Configuration=Release /p:DebugType=PdbOnly @@ -14,6 +17,11 @@ SET buildoptions=/t:Rebuild /p:Configuration=Release /p:DebugType=PdbOnly
:BUILD .NET 3.5 version
%msbuild% /m %project% %buildoptions% "/p:DefineConstants=TRACE" "/p:TargetFrameworkVersion=v3.5" /p:OutputPath=%~dp0\AvalonEdit\lib\Net35
@echo Building documentation with SHFB (for processing <inheritdoc/>)
%msbuild% %documentation%\ICSharpCode.AvalonEdit.shfbproj
copy /Y %documentation%\Help\ICSharpCode.AvalonEdit.xml AvalonEdit\lib\Net35\ICSharpCode.AvalonEdit.xml
copy /Y %documentation%\Help\ICSharpCode.AvalonEdit.xml AvalonEdit\lib\Net40\ICSharpCode.AvalonEdit.xml
nuget.exe pack AvalonEdit\AvalonEdit.nuspec -Symbols -BasePath AvalonEdit -OutputDirectory AvalonEdit
nuget.exe pack AvalonEdit.Sample\AvalonEdit.Sample.nuspec -BasePath AvalonEdit.Sample -OutputDirectory AvalonEdit.Sample

4
src/AddIns/Misc/PackageManagement/Project/Src/AvailablePackagesViewModel.cs

@ -72,11 +72,11 @@ namespace ICSharpCode.PackageManagement @@ -72,11 +72,11 @@ namespace ICSharpCode.PackageManagement
{
if (IncludePrerelease) {
return base.GetFilteredPackagesBeforePagingResults(allPackages)
.DistinctLast(PackageEqualityComparer.Id);
.DistinctLast<IPackage>(PackageEqualityComparer.Id);
}
return base.GetFilteredPackagesBeforePagingResults(allPackages)
.Where(package => package.IsReleaseVersion())
.DistinctLast(PackageEqualityComparer.Id);
.DistinctLast<IPackage>(PackageEqualityComparer.Id);
}
}
}

13
src/AddIns/Misc/PackageManagement/Project/Src/Design/FakeFileSystem.cs

@ -124,5 +124,18 @@ namespace ICSharpCode.PackageManagement.Design @@ -124,5 +124,18 @@ namespace ICSharpCode.PackageManagement.Design
{
throw new NotImplementedException();
}
public void DeleteFiles(IEnumerable<IPackageFile> files, string rootDir)
{
}
public void AddFiles(IEnumerable<IPackageFile> files, string rootDir)
{
}
public void MoveFile(string source, string destination)
{
throw new NotImplementedException();
}
}
}

2
src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackage.cs

@ -210,5 +210,7 @@ namespace ICSharpCode.PackageManagement.Design @@ -210,5 +210,7 @@ namespace ICSharpCode.PackageManagement.Design
public Version MinClientVersion { get; set; }
public Uri GalleryUrl { get; set; }
public bool DevelopmentDependency { get; set; }
}
}

18
src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManager.cs

@ -213,5 +213,23 @@ namespace ICSharpCode.PackageManagement.Design @@ -213,5 +213,23 @@ namespace ICSharpCode.PackageManagement.Design
{
throw new NotImplementedException();
}
public DependencyVersion DependencyVersion {
get {
throw new NotImplementedException();
}
set {
throw new NotImplementedException();
}
}
public bool WhatIf {
get {
throw new NotImplementedException();
}
set {
throw new NotImplementedException();
}
}
}
}

2
src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageRepository.cs

@ -72,5 +72,7 @@ namespace ICSharpCode.PackageManagement.Design @@ -72,5 +72,7 @@ namespace ICSharpCode.PackageManagement.Design
public bool HasRecentPackages { get; set; }
public bool SupportsPrereleasePackages { get; set; }
public PackageSaveModes PackageSaveMode { get; set; }
}
}

23
src/AddIns/Misc/PackageManagement/Project/Src/Design/FakeProjectManager.cs

@ -140,5 +140,28 @@ namespace ICSharpCode.PackageManagement.Design @@ -140,5 +140,28 @@ namespace ICSharpCode.PackageManagement.Design
PackagePassedToHasOlderPackageInstalled = package;
return HasOlderPackageInstalledReturnValue;
}
public DependencyVersion DependencyVersion {
get {
throw new NotImplementedException();
}
set {
throw new NotImplementedException();
}
}
public bool WhatIf {
get {
throw new NotImplementedException();
}
set {
throw new NotImplementedException();
}
}
public void UpdatePackageReference(IPackage remotePackage, bool updateDependencies, bool allowPrereleaseVersions)
{
throw new NotImplementedException();
}
}
}

4
src/AddIns/Misc/PackageManagement/Project/Src/PackageFromRepository.cs

@ -207,5 +207,9 @@ namespace ICSharpCode.PackageManagement @@ -207,5 +207,9 @@ namespace ICSharpCode.PackageManagement
return null;
}
}
public bool DevelopmentDependency {
get { return package.DevelopmentDependency; }
}
}
}

4
src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementSolution.cs

@ -141,7 +141,7 @@ namespace ICSharpCode.PackageManagement @@ -141,7 +141,7 @@ namespace ICSharpCode.PackageManagement
public IEnumerable<IProject> GetMSBuildProjects()
{
return projectService.AllProjects;
return projectService.AllProjects.OfType<MSBuildBasedProject>();;
}
public bool IsOpen {
@ -195,7 +195,7 @@ namespace ICSharpCode.PackageManagement @@ -195,7 +195,7 @@ namespace ICSharpCode.PackageManagement
public IEnumerable<IPackageManagementProject> GetProjects(IPackageRepository sourceRepository)
{
foreach (MSBuildBasedProject msbuildProject in GetMSBuildProjects().OfType<MSBuildBasedProject>()) {
foreach (MSBuildBasedProject msbuildProject in GetMSBuildProjects()) {
yield return projectFactory.CreateProject(sourceRepository, msbuildProject);
}
}

6
src/AddIns/Misc/PackageManagement/Project/Src/PackageOperationsResolverFactory.cs

@ -35,7 +35,8 @@ namespace ICSharpCode.PackageManagement @@ -35,7 +35,8 @@ namespace ICSharpCode.PackageManagement
null,
logger,
installAction.IgnoreDependencies,
installAction.AllowPrereleaseVersions);
installAction.AllowPrereleaseVersions,
DependencyVersion.Lowest);
}
public IPackageOperationResolver CreateUpdatePackageOperationResolver(IPackageRepository localRepository, IPackageRepository sourceRepository, ILogger logger, IUpdatePackageSettings settings)
@ -46,7 +47,8 @@ namespace ICSharpCode.PackageManagement @@ -46,7 +47,8 @@ namespace ICSharpCode.PackageManagement
null,
logger,
!settings.UpdateDependencies,
settings.AllowPrereleaseVersions);
settings.AllowPrereleaseVersions,
DependencyVersion.Lowest);
}
}
}

2
src/AddIns/Misc/PackageManagement/Project/Src/RecentPackageRepository.cs

@ -181,5 +181,7 @@ namespace ICSharpCode.PackageManagement @@ -181,5 +181,7 @@ namespace ICSharpCode.PackageManagement
public bool SupportsPrereleasePackages {
get { return false; }
}
public PackageSaveModes PackageSaveMode { get; set; }
}
}

2
src/AddIns/Misc/PackageManagement/Project/Src/SharpDevelopPackageManager.cs

@ -60,7 +60,7 @@ namespace ICSharpCode.PackageManagement @@ -60,7 +60,7 @@ namespace ICSharpCode.PackageManagement
PackageReferenceRepository CreatePackageReferenceRepository()
{
var sharedRepository = LocalRepository as ISharedPackageRepository;
var packageRefRepository = new PackageReferenceRepository(projectSystem, sharedRepository);
var packageRefRepository = new PackageReferenceRepository(projectSystem, projectSystem.ProjectName, sharedRepository);
packageRefRepository.RegisterIfNecessary();
return packageRefRepository;
}

2
src/AddIns/Misc/PackageManagement/Project/Src/UpdatedPackages.cs

@ -75,7 +75,7 @@ namespace ICSharpCode.PackageManagement @@ -75,7 +75,7 @@ namespace ICSharpCode.PackageManagement
List<IPackage> packages = localPackages.ToList();
if (packages.Any()) {
packages.Sort(PackageComparer.Version);
return packages.Distinct(PackageEqualityComparer.Id).ToList();
return packages.Distinct<IPackage>(PackageEqualityComparer.Id).ToList();
}
return packages;
}

BIN
src/AddIns/Misc/PackageManagement/RequiredLibraries/Microsoft.Web.XmlTransform.dll

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save