Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLluis Sanchez <llsan@microsoft.com>2019-06-07 17:24:45 +0300
committerLluis Sanchez <llsan@microsoft.com>2019-06-07 17:24:45 +0300
commitadc0c4e33b695c315488262c3c09112e87800111 (patch)
treee4c93ea740a9d3b691e14fd04878c98adc4c34de /main/src/addins
parent526ae087002e5e8aba0c5430fea9142942f85635 (diff)
parentb19a7bf2d6a71057f0820de1c12b9a5faa7d9b53 (diff)
Merge remote-tracking branch 'origin/master' into release-8.2monodevelop-8.2.0.707
Diffstat (limited to 'main/src/addins')
-rw-r--r--main/src/addins/CSharpBinding/CSharpBinding.csproj1
-rw-r--r--main/src/addins/CSharpBinding/Gui/MonoDevelop.CSharp.Project.CompilerOptionsPanelWidget.cs15
-rw-r--r--main/src/addins/CSharpBinding/MonoDevelop.CSharp.Debugger/CSharpBreakpointSpanResolver.cs58
-rw-r--r--main/src/addins/CSharpBinding/MonoDevelop.CSharp.Project/CSharpCompilerParameters.cs8
-rw-r--r--main/src/addins/CSharpBinding/MonoDevelop.CSharp.Project/CompilerOptionsPanelWidget.cs62
-rw-r--r--main/src/addins/MacPlatform/MacPlatform.cs2
-rw-r--r--main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserViewContent.cs69
-rw-r--r--main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserWidget.cs196
-rw-r--r--main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyLoader.cs33
-rw-r--r--main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/MetadataExtensions.cs5
-rw-r--r--main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/AssemblyBrowserTypeNodeBuilder.cs12
-rw-r--r--main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/AssemblyReferenceNodeBuilder.cs2
-rw-r--r--main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/BaseTypeFolderNodeBuilder.cs4
-rw-r--r--main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Cecil/AssemblyNodeBuilder.cs35
-rw-r--r--main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Cecil/MethodDefinitionNodeBuilder.cs4
-rw-r--r--main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Cecil/TypeDefinitionNodeBuilder.cs44
-rw-r--r--main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/ModuleReferenceNodeBuilder.cs2
-rw-r--r--main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/NamespaceBuilder.cs14
-rw-r--r--main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/NamespaceData.cs49
-rw-r--r--main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Roslyn/ProjectNodeBuilder.cs38
-rw-r--r--main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Roslyn/RoslynMemberNodeBuilder.cs47
-rw-r--r--main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Roslyn/RoslynTypeNodeBuilder.cs36
-rw-r--r--main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.VSTextView/BreakpointManager.cs43
-rw-r--r--main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.csproj2
-rw-r--r--main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs25
-rw-r--r--main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DefaultBreakpointSpanResolver.cs47
-rw-r--r--main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/IBreakpointSpanResolver.cs48
-rw-r--r--main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs8
-rw-r--r--main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/SourceCodeLookup.cs56
-rw-r--r--main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectExtension.cs20
-rw-r--r--main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/PackagesCommandHandler.cs56
-rw-r--r--main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/RestorePackagesHandler.cs2
-rw-r--r--main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/RestorePackagesInProjectHandler.cs2
-rw-r--r--main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetAwareProject.cs5
-rw-r--r--main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/TestableRestorePackagesHandler.cs54
-rw-r--r--main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/TestableRestorePackagesInProjectHandler.cs54
-rw-r--r--main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.csproj3
-rw-r--r--main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetProjectExtensionsTests.cs6
-rw-r--r--main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/PackagesCommandHandlerTests.cs257
-rw-r--r--main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetProjectExtensions.cs11
-rw-r--r--main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/SolutionExtensions.cs12
-rw-r--r--main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs35
-rw-r--r--main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/GitRepository.cs8
-rw-r--r--main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/GitSelectRevisionDialog.cs8
-rw-r--r--main/src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl/Repository.cs2
45 files changed, 1037 insertions, 463 deletions
diff --git a/main/src/addins/CSharpBinding/CSharpBinding.csproj b/main/src/addins/CSharpBinding/CSharpBinding.csproj
index 2027c0db24..3766cbf2b2 100644
--- a/main/src/addins/CSharpBinding/CSharpBinding.csproj
+++ b/main/src/addins/CSharpBinding/CSharpBinding.csproj
@@ -291,6 +291,7 @@
<Compile Include="MonoDevelop.CSharp.Refactoring\CommandArgsFactories.cs" />
<Compile Include="MonoDevelop.CSharp.Debugger\DebuggerCompletionController.cs" />
<Compile Include="MonoDevelop.CSharp.ClassOutline\CSharpOutlineTextEditorExtensionProvider.cs" />
+ <Compile Include="MonoDevelop.CSharp.Debugger\CSharpBreakpointSpanResolver.cs" />
</ItemGroup>
<ItemGroup>
<None Include="MonoDevelop.CSharp.CodeRefactorings\ConvertToEnum\ConvertToEnumCodeRefactoringProvider.cs" />
diff --git a/main/src/addins/CSharpBinding/Gui/MonoDevelop.CSharp.Project.CompilerOptionsPanelWidget.cs b/main/src/addins/CSharpBinding/Gui/MonoDevelop.CSharp.Project.CompilerOptionsPanelWidget.cs
index 232893c387..15aaf60a49 100644
--- a/main/src/addins/CSharpBinding/Gui/MonoDevelop.CSharp.Project.CompilerOptionsPanelWidget.cs
+++ b/main/src/addins/CSharpBinding/Gui/MonoDevelop.CSharp.Project.CompilerOptionsPanelWidget.cs
@@ -1,5 +1,7 @@
// This file has been generated by the GUI designer. Do not modify.
+using MonoDevelop.Ide.Gui;
+
namespace MonoDevelop.CSharp.Project
{
partial class CompilerOptionsPanelWidget
@@ -47,6 +49,8 @@ namespace MonoDevelop.CSharp.Project
private global::Gtk.VBox vbox3;
private global::Gtk.Table table2;
+
+ private MonoDevelop.Components.ImageView langVersionWarningIcon;
private global::Gtk.Label label2;
@@ -254,14 +258,21 @@ namespace MonoDevelop.CSharp.Project
this.table2.RowSpacing = ((uint)(6));
this.table2.ColumnSpacing = ((uint)(6));
// Container child table2.Gtk.Table+TableChild
+ this.langVersionWarningIcon = new MonoDevelop.Components.ImageView (Stock.Warning, Gtk.IconSize.Menu);
+ this.langVersionWarningIcon.Visible = false;
+ var langVersionHbox = new global::Gtk.HBox (false, 0);
+ langVersionHbox.Name = "langVersionHbox";
+ langVersionHbox.PackStart (this.langVersionWarningIcon, false, false, 0);
this.label2 = new global::Gtk.Label ();
this.label2.Name = "label2";
this.label2.Xalign = 0F;
this.label2.LabelProp = global::Mono.Unix.Catalog.GetString ("C# Language Version:");
- this.table2.Add (this.label2);
- global::Gtk.Table.TableChild w19 = ((global::Gtk.Table.TableChild)(this.table2 [this.label2]));
+ langVersionHbox.PackStart (this.label2, false, false, 6);
+ this.table2.Add (langVersionHbox);
+ global::Gtk.Table.TableChild w19 = ((global::Gtk.Table.TableChild)(this.table2 [langVersionHbox]));
w19.XOptions = ((global::Gtk.AttachOptions)(4));
w19.YOptions = ((global::Gtk.AttachOptions)(4));
+ w19.XPadding = 6;
// Container child table2.Gtk.Table+TableChild
this.langVerCombo = global::Gtk.ComboBox.NewText ();
this.langVerCombo.Name = "langVerCombo";
diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Debugger/CSharpBreakpointSpanResolver.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Debugger/CSharpBreakpointSpanResolver.cs
new file mode 100644
index 0000000000..f21971dc9f
--- /dev/null
+++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Debugger/CSharpBreakpointSpanResolver.cs
@@ -0,0 +1,58 @@
+//
+// CSharpBreakpointSpanResolver.cs
+//
+// Author:
+// Jeffrey Stedfast <jestedfa@microsoft.com>
+//
+// Copyright (c) 2019 Microsoft Corp.
+//
+// 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.Threading;
+using System.Threading.Tasks;
+
+using Microsoft.CodeAnalysis.Text;
+using Microsoft.VisualStudio.Text;
+using Microsoft.CodeAnalysis.CSharp.EditAndContinue;
+
+using MonoDevelop.Debugger;
+using MonoDevelop.Ide.Gui.Documents;
+
+namespace MonoDevelop.CSharp.Debugger
+{
+ [ExportDocumentControllerExtension (MimeType = "text/x-csharp")]
+ class CSharpBreakpointSpanResolver : DocumentControllerExtension, IBreakpointSpanResolver
+ {
+ public override Task<bool> SupportsController (DocumentController controller)
+ {
+ return Task.FromResult (controller.GetContent<ITextBuffer> () != null);
+ }
+
+ public async Task<Span> GetBreakpointSpanAsync (ITextBuffer buffer, int position, CancellationToken cancellationToken)
+ {
+ var document = buffer.AsTextContainer ().GetOpenDocumentInCurrentContext ();
+ var tree = await document.GetSyntaxTreeAsync (cancellationToken);
+
+ BreakpointSpans.TryGetBreakpointSpan (tree, position, cancellationToken, out var span);
+
+ return new Span (span.Start, span.Length);
+ }
+ }
+}
diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Project/CSharpCompilerParameters.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Project/CSharpCompilerParameters.cs
index 9d30f7a21c..ef73cbd84e 100644
--- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Project/CSharpCompilerParameters.cs
+++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Project/CSharpCompilerParameters.cs
@@ -227,9 +227,11 @@ namespace MonoDevelop.CSharp.Project
return val;
}
set {
- if (LangVersion == value) {
- return;
- }
+ try {
+ if (LangVersion == value) {
+ return;
+ }
+ } catch (Exception) { }
langVersion = LanguageVersionToString (value);
NotifyChange ();
diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Project/CompilerOptionsPanelWidget.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Project/CompilerOptionsPanelWidget.cs
index 396dc158c6..99525f77db 100644
--- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Project/CompilerOptionsPanelWidget.cs
+++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Project/CompilerOptionsPanelWidget.cs
@@ -29,6 +29,8 @@
using System;
using System.Linq;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
using Gtk;
using MonoDevelop.Components;
@@ -55,7 +57,7 @@ namespace MonoDevelop.CSharp.Project
LanguageVersion.LatestMajor,
LanguageVersion.Preview
};
-
+
public CompilerOptionsPanelWidget (DotNetProject project)
{
this.Build();
@@ -98,26 +100,51 @@ namespace MonoDevelop.CSharp.Project
iconEntry.DefaultPath = project.BaseDirectory;
allowUnsafeCodeCheckButton.Active = compilerParameters.UnsafeCode;
noStdLibCheckButton.Active = compilerParameters.NoStdLib;
+ langVersionWarningIcon.Visible = false;
- var langVerStore = new ListStore (typeof (string), typeof(LanguageVersion));
- foreach (var (text, version) in CSharpLanguageVersionHelper.GetKnownLanguageVersions ()) {
- if (unsupportedLanguageVersions.Contains (version) && compilerParameters.LangVersion != version) {
- // Mono's MSBuild does not currently support C# 8.
+ var langVerStore = new ListStore (typeof (string), typeof(LanguageVersion), typeof (bool));
+ var langVersions = CSharpLanguageVersionHelper.GetKnownLanguageVersions ();
+ string badVersion = null;
+ LanguageVersion? langVersion = null;
+
+ try {
+ langVersion = compilerParameters.LangVersion;
+ } catch (Exception) {
+ badVersion = configuration.Properties.GetProperty ("LangVersion").Value;
+ }
+
+ foreach (var (text, version) in langVersions) {
+ if (unsupportedLanguageVersions.Contains (version)) {
+ if (langVersion == version) {
+ if (badVersion == null)
+ badVersion = text;
+ } else {
+ // Otherwise if it's an unsupported language but it's not the current project's
+ // version then it must be an unsupported version of Mono. Let's not add that to
+ // the list store.
+ }
} else {
- langVerStore.AppendValues (text, version);
+ langVerStore.AppendValues (text, version, false);
}
}
+
langVerCombo.Model = langVerStore;
- TreeIter iter;
- if (langVerStore.GetIterFirst (out iter)) {
- do {
- var val = (LanguageVersion)(int)langVerStore.GetValue (iter, 1);
- if (val == compilerParameters.LangVersion) {
- langVerCombo.SetActiveIter (iter);
- break;
- }
- } while (langVerStore.IterNext (ref iter));
+ if (badVersion != null) {
+ var badIter = langVerStore.AppendValues (GettextCatalog.GetString ("{0} (Unknown Version)", badVersion), LanguageVersion.Default, true);
+ langVerCombo.SetActiveIter (badIter);
+ langVersionWarningIcon.Visible = true;
+ } else {
+ TreeIter iter;
+ if (langVerStore.GetIterFirst (out iter)) {
+ do {
+ var val = (LanguageVersion)(int)langVerStore.GetValue (iter, 1);
+ if (val == compilerParameters.LangVersion) {
+ langVerCombo.SetActiveIter (iter);
+ break;
+ }
+ } while (langVerStore.IterNext (ref iter));
+ }
}
SetupAccessibility ();
@@ -175,11 +202,13 @@ namespace MonoDevelop.CSharp.Project
public void Store (ItemConfigurationCollection<ItemConfiguration> configs)
{
int codePage;
+ bool isBadVersion = false;
var langVersion = LanguageVersion.Default;
TreeIter iter;
if (langVerCombo.GetActiveIter (out iter)) {
langVersion = (LanguageVersion)langVerCombo.Model.GetValue (iter, 1);
+ isBadVersion = (bool)langVerCombo.Model.GetValue (iter, 2);
}
if (codepageEntry.Entry.Text.Length > 0) {
@@ -218,7 +247,8 @@ namespace MonoDevelop.CSharp.Project
CSharpCompilerParameters compilerParameters = (CSharpCompilerParameters) configuration.CompilationParameters;
compilerParameters.UnsafeCode = allowUnsafeCodeCheckButton.Active;
compilerParameters.NoStdLib = noStdLibCheckButton.Active;
- compilerParameters.LangVersion = langVersion;
+ if (!isBadVersion)
+ compilerParameters.LangVersion = langVersion;
}
}
diff --git a/main/src/addins/MacPlatform/MacPlatform.cs b/main/src/addins/MacPlatform/MacPlatform.cs
index d60c4f79c8..90116f6d53 100644
--- a/main/src/addins/MacPlatform/MacPlatform.cs
+++ b/main/src/addins/MacPlatform/MacPlatform.cs
@@ -1281,7 +1281,7 @@ namespace MonoDevelop.MacIntegration
y += GetTitleBarHeight (w);
var dr = FromDesktopRect (new Gdk.Rectangle (x, y, width, height));
var r = w.FrameRectFor (dr);
- w.SetFrame (r, true);
+
base.PlaceWindow (window, x, y, width, height);
}
diff --git a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserViewContent.cs b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserViewContent.cs
index 15a38cfc9f..c4afa8c1b6 100644
--- a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserViewContent.cs
+++ b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserViewContent.cs
@@ -40,6 +40,7 @@ using System.Collections.Immutable;
using MonoDevelop.Ide;
using Microsoft.CodeAnalysis.CodeRefactorings;
using MonoDevelop.Ide.Gui.Documents;
+using System.Threading;
namespace MonoDevelop.AssemblyBrowser
{
@@ -47,7 +48,8 @@ namespace MonoDevelop.AssemblyBrowser
{
readonly static string[] defaultAssemblies = new string[] { "mscorlib", "System", "System.Core", "System.Xml" };
AssemblyBrowserWidget widget;
-
+ CancellationTokenSource cts = new CancellationTokenSource ();
+
protected override Control OnGetViewControl (DocumentViewContent view)
{
widget.SetToolbar (view.GetToolbar ());
@@ -67,11 +69,13 @@ namespace MonoDevelop.AssemblyBrowser
FillWidget ();
}
- protected override async Task OnInitialize (ModelDescriptor modelDescriptor, Properties status)
+ protected override Task OnInitialize (ModelDescriptor modelDescriptor, Properties status)
{
if (modelDescriptor is FileDescriptor fileDescriptor) {
Load (fileDescriptor.FilePath);
}
+
+ return Task.CompletedTask;
}
protected override bool OnTryReuseDocument (ModelDescriptor modelDescriptor)
@@ -92,9 +96,9 @@ namespace MonoDevelop.AssemblyBrowser
{
var loader = widget.AddReferenceByFileName (filePath);
if (loader != null) {
- loader.LoadingTask.ContinueWith (delegate {
- widget.SelectAssembly (loader);
- });
+ loader.LoadingTask
+ .ContinueWith (t => widget.SelectAssembly (t.Result), Runtime.MainTaskScheduler)
+ .Ignore ();
}
}
@@ -105,12 +109,14 @@ namespace MonoDevelop.AssemblyBrowser
protected override void OnDispose ()
{
- if (currentWs != null)
- currentWs.WorkspaceLoaded -= Handle_WorkspaceLoaded;
+ if (cts != null) {
+ cts.Cancel ();
+ cts.Dispose ();
+ cts = null;
+ }
widget = null;
- if (Disposed != null)
- Disposed (this, EventArgs.Empty);
+ Disposed?.Invoke (this, EventArgs.Empty);
base.OnDispose ();
}
@@ -162,40 +168,29 @@ namespace MonoDevelop.AssemblyBrowser
//FindDerivedClassesHandler.FindDerivedClasses (type);
}
- void Handle_WorkspaceLoaded (object sender, EventArgs e)
- {
- foreach (var project in Ide.IdeApp.ProjectOperations.CurrentSelectedSolution.GetAllProjects ()) {
- var nav = Widget.TreeView.GetNodeAtObject (project);
- if (nav != null)
- Widget.TreeView.RefreshNode (nav);
- }
- }
-
- Ide.TypeSystem.MonoDevelopWorkspace currentWs;
- public async void FillWidget ()
+ public void FillWidget ()
{
if (Ide.IdeApp.ProjectOperations.CurrentSelectedSolution == null) {
foreach (var assembly in defaultAssemblies) {
- Widget.AddReferenceByAssemblyName (assembly);
+ Widget.AddReferenceByAssemblyName (assembly);
}
} else {
- var alreadyAdded = new HashSet<string> ();
- currentWs = IdeApp.TypeSystemService.GetWorkspace (IdeApp.ProjectOperations.CurrentSelectedSolution);
- if (currentWs != null)
- currentWs.WorkspaceLoaded += Handle_WorkspaceLoaded;
- var allTasks = new List<Task> ();
- foreach (var project in Ide.IdeApp.ProjectOperations.CurrentSelectedSolution.GetAllProjects ()) {
- try {
- Widget.AddProject (project, false);
- } catch (Exception e) {
- LoggingService.LogError ("Error while adding project " + project.Name + " to the tree.", e);
- }
- }
- await Task.WhenAll (allTasks).ContinueWith (delegate {
- Runtime.RunInMainThread (delegate {
+ var token = cts.Token;
+
+ var workspace = IdeApp.TypeSystemService.GetWorkspaceAsync (IdeApp.ProjectOperations.CurrentSelectedSolution)
+ .ContinueWith (t => {
+ if (token.IsCancellationRequested)
+ return;
+
+ foreach (var project in IdeApp.ProjectOperations.CurrentSelectedSolution.GetAllProjects ()) {
+ try {
+ Widget.AddProject (project, false);
+ } catch (Exception e) {
+ LoggingService.LogError ("Error while adding project " + project.Name + " to the tree.", e);
+ }
+ }
widget.StartSearch ();
- });
- });
+ }, token, TaskContinuationOptions.DenyChildAttach, Runtime.MainTaskScheduler);
}
}
}
diff --git a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserWidget.cs b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserWidget.cs
index fc47e392e0..681fdac935 100644
--- a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserWidget.cs
+++ b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserWidget.cs
@@ -880,19 +880,19 @@ namespace MonoDevelop.AssemblyBrowser
inspectEditor.Options = assemblyBrowserEditorOptions;
this.inspectEditor.MimeType = "text/x-csharp";
builder.DecompileAsync (inspectEditor, nav, new DecompileFlags { PublicOnly = PublicApiOnly, MethodBodies = false })
- .ContinueWith (l => SetReferencedSegments (l.Result), Runtime.MainTaskScheduler);
+ .ContinueWith (l => SetReferencedSegments (l.Result), Runtime.MainTaskScheduler).Ignore ();
break;
case 1:
inspectEditor.Options = assemblyBrowserEditorOptions;
this.inspectEditor.MimeType = "text/x-ilasm";
builder.DisassembleAsync (inspectEditor, nav)
- .ContinueWith (l => SetReferencedSegments (l.Result), Runtime.MainTaskScheduler);
+ .ContinueWith (l => SetReferencedSegments (l.Result), Runtime.MainTaskScheduler).Ignore ();
break;
case 2:
inspectEditor.Options = assemblyBrowserEditorOptions;
this.inspectEditor.MimeType = "text/x-csharp";
builder.DecompileAsync (inspectEditor, nav, new DecompileFlags { PublicOnly = PublicApiOnly, MethodBodies = true })
- .ContinueWith (l => SetReferencedSegments (l.Result), Runtime.MainTaskScheduler);
+ .ContinueWith (l => SetReferencedSegments (l.Result), Runtime.MainTaskScheduler).Ignore ();
break;
default:
inspectEditor.Options = assemblyBrowserEditorOptions;
@@ -914,24 +914,30 @@ namespace MonoDevelop.AssemblyBrowser
internal void Open (string url, AssemblyLoader currentAssembly = null, bool expandNode = true)
{
Task.WhenAll (this.definitions.Select (d => d.LoadingTask)).ContinueWith (d => {
- Application.Invoke ((o, args) => {
- suspendNavigation = false;
- ITreeNavigator nav = SearchMember (url, expandNode);
- if (definitions.Count == 0) // we've been disposed
- return;
- if (nav != null)
- return;
- try {
- if (currentAssembly != null) {
- OpenFromAssembly (url, currentAssembly);
- } else {
- OpenFromAssemblyNames (url);
- }
- } catch (Exception e) {
- LoggingService.LogError ("Error while opening the assembly browser with id:" + url, e);
+ // At least one of them failed.
+ if (d.IsFaulted) {
+ LoggingService.LogError ("Failed to load assemblies", d.Exception);
+
+ // It's possible the assembly in which the type we're looking for exists
+ // so try probing for it regardless.
+ }
+
+ suspendNavigation = false;
+ ITreeNavigator nav = SearchMember (url, expandNode);
+ if (definitions.Count == 0) // we've been disposed
+ return;
+ if (nav != null)
+ return;
+ try {
+ if (currentAssembly != null) {
+ OpenFromAssembly (url, currentAssembly);
+ } else {
+ OpenFromAssemblyNames (url);
}
- });
- });
+ } catch (Exception e) {
+ LoggingService.LogError ("Error while opening the assembly browser with id:" + url, e);
+ }
+ }, Runtime.MainTaskScheduler).Ignore ();
}
void OpenFromAssembly (string url, AssemblyLoader currentAssembly, bool expandNode = true)
@@ -960,16 +966,14 @@ namespace MonoDevelop.AssemblyBrowser
result.LoadingTask.ContinueWith (t2 => {
if (definitions.Count == 0) // disposed
return;
- Application.Invoke ((o, args) => {
- var nav = SearchMember (url, expandNode);
- if (nav == null) {
- if (++i == references.Length)
- LoggingService.LogError ("Assembly browser: Can't find: " + url + ".");
- else
- loadNext ();
- }
- });
- }, TaskScheduler.Current);
+ var nav = SearchMember (url, expandNode);
+ if (nav == null) {
+ if (++i == references.Length)
+ LoggingService.LogError ("Assembly browser: Can't find: " + url + ".");
+ else
+ loadNext ();
+ }
+ }, Runtime.MainTaskScheduler).Ignore ();
};
}
@@ -997,51 +1001,44 @@ namespace MonoDevelop.AssemblyBrowser
LoggingService.LogError ("Assembly browser: Can't find: " + url + ".");
}
return;
- };
- Task.Factory.ContinueWhenAll (tasks.ToArray (), tarr => {
- var exceptions = tarr.Where (t => t.IsFaulted).Select (t => t.Exception).ToArray ();
- if (exceptions != null) {
- var ex = new AggregateException (exceptions).Flatten ();
- if (ex.InnerExceptions.Count > 0) {
- foreach (var inner in ex.InnerExceptions) {
- LoggingService.LogError ("Error while loading assembly in the browser.", inner);
- }
- throw ex;
+ }
+
+ Task.WhenAll (tasks.ToArray ())
+ .ContinueWith (t => {
+ if (t.IsFaulted) {
+ LoggingService.LogError ("Error while loading assemblies in the browser", t.Exception);
+ return;
}
- }
- if (definitions.Count == 0) // disposed
- return;
- Application.Invoke ((o, args) => {
+
+ if (definitions.Count == 0) // disposed
+ return;
+
var nav = SearchMember (url);
if (nav == null) {
LoggingService.LogError ("Assembly browser: Can't find: " + url + ".");
}
- });
- }, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current);
+ }, Runtime.MainTaskScheduler).Ignore ();
}
- internal void SelectAssembly (AssemblyLoader loader)
+ internal void SelectAssembly (PEFile cu)
{
- PEFile cu = loader.Assembly;
- Application.Invoke ((o, args) => {
- ITreeNavigator nav = TreeView.GetRootNode ();
- if (nav == null)
- return;
+ ITreeNavigator nav = TreeView.GetRootNode ();
+ if (nav == null)
+ return;
+
+ if (expandedMember) {
+ expandedMember = false;
+ return;
+ }
- if (expandedMember) {
- expandedMember = false;
+ do {
+ if (nav.DataItem == cu || (nav.DataItem as AssemblyLoader)?.Assembly == cu) {
+ nav.ExpandToNode ();
+ nav.Selected = true;
+ nav.ScrollToNode ();
return;
}
-
- do {
- if (nav.DataItem == cu || (nav.DataItem as AssemblyLoader)?.Assembly == cu) {
- nav.ExpandToNode ();
- nav.Selected = true;
- nav.ScrollToNode ();
- return;
- }
- } while (nav.MoveNext ());
- });
+ } while (nav.MoveNext ());
}
void Dispose<T> (ITreeNavigator nav) where T:class, IDisposable
@@ -1095,6 +1092,8 @@ namespace MonoDevelop.AssemblyBrowser
def.Dispose ();
definitions = definitions.Clear ();
}
+
+ projects.Clear ();
ActiveMember = null;
resultListStore = null;
@@ -1124,7 +1123,7 @@ namespace MonoDevelop.AssemblyBrowser
ImmutableList<AssemblyLoader> definitions = ImmutableList<AssemblyLoader>.Empty;
- List<Project> projects = new List<Project> ();
+ HashSet<Project> projects = new HashSet<Project> ();
internal AssemblyLoader AddReferenceByAssemblyName (PEFile reference, bool expand = false)
{
@@ -1158,38 +1157,36 @@ namespace MonoDevelop.AssemblyBrowser
var result = new AssemblyLoader (this, fileName);
definitions = definitions.Add (result);
result.LoadingTask = result.LoadingTask.ContinueWith (task => {
- Application.Invoke ((o, args) => {
- if (TreeView == null || definitions.Count == 0)
- return;
- var fullName = result.Assembly.FullName;
-
- // filter duplicate assemblies, can happen on opening the same assembly at different locations.
- foreach (var d in definitions) {
- if (!d.IsLoaded || d == result)
- continue;
- if (d.Assembly.FullName == fullName) {
- definitions = definitions.Remove (result);
- LoggingService.LogInfo ("AssemblyBrowser: Loaded duplicate assembly : " + fullName); // Write a log info in case that happens, shouldn't happen often.
- return;
- }
+ if (TreeView == null || definitions.Count == 0)
+ return task.Result;
+ var fullName = result.Assembly.FullName;
+
+ // filter duplicate assemblies, can happen on opening the same assembly at different locations.
+ foreach (var d in definitions) {
+ if (!d.IsLoaded || d == result)
+ continue;
+ if (d.Assembly.FullName == fullName) {
+ definitions = definitions.Remove (result);
+ LoggingService.LogInfo ("AssemblyBrowser: Loaded duplicate assembly : " + fullName); // Write a log info in case that happens, shouldn't happen often.
+ return task.Result;
}
-
- try {
- ITreeBuilder builder;
- if (definitions.Count + projects.Count == 1) {
- builder = TreeView.LoadTree (result);
- } else {
- builder = TreeView.AddChild (result, false);
- }
- if (TreeView.GetSelectedNode () == null)
- builder.Selected = builder.Expanded = expand;
- } catch (Exception e) {
- LoggingService.LogError ("Error while adding assembly to the assembly list", e);
+ }
+
+ try {
+ ITreeBuilder builder;
+ if (definitions.Count + projects.Count == 1) {
+ builder = TreeView.LoadTree (result);
+ } else {
+ builder = TreeView.AddChild (result, expand);
}
- });
+ if (TreeView.GetSelectedNode () == null)
+ builder.Selected = builder.Expanded = expand;
+ } catch (Exception e) {
+ LoggingService.LogError ("Error while adding assembly to the assembly list", e);
+ }
return task.Result;
- }
- );
+ }, Runtime.MainTaskScheduler);
+
return result;
}
@@ -1198,7 +1195,7 @@ namespace MonoDevelop.AssemblyBrowser
if (project == null)
throw new ArgumentNullException ("project");
- if (projects.Contains (project)) {
+ if (!projects.Add (project)) {
// Select the project.
if (selectReference) {
ITreeNavigator navigator = TreeView.GetNodeAtObject (project);
@@ -1209,14 +1206,16 @@ namespace MonoDevelop.AssemblyBrowser
return;
}
- projects.Add (project);
+
ITreeBuilder builder;
if (definitions.Count + projects.Count == 1) {
builder = TreeView.LoadTree (project);
} else {
- builder = TreeView.AddChild (project);
+ builder = TreeView.AddChild (project, false);
}
- builder.Selected = builder.Expanded = selectReference;
+
+ if (TreeView.GetSelectedNode () == null || selectReference)
+ builder.Selected = builder.Expanded = selectReference;
}
//MonoDevelop.Components.RoundedFrame popupWidgetFrame;
@@ -1258,6 +1257,7 @@ namespace MonoDevelop.AssemblyBrowser
foreach (var def in ensuredDefinitions) {
if (!definitions.Contains (def)) {
definitions = definitions.Add (def);
+
Application.Invoke ((o, args) => {
if (ensuredDefinitions.Count + projects.Count == 1) {
TreeView.LoadTree (def.LoadingTask.Result);
diff --git a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyLoader.cs b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyLoader.cs
index 31d7aed461..8baaf723a1 100644
--- a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyLoader.cs
+++ b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyLoader.cs
@@ -35,6 +35,7 @@ using ICSharpCode.Decompiler.Metadata;
using System.Reflection.Metadata;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
+using ICSharpCode.Decompiler.CSharp.Transforms;
namespace MonoDevelop.AssemblyBrowser
{
@@ -63,18 +64,13 @@ namespace MonoDevelop.AssemblyBrowser
public PEFile Assembly => AssemblyTask.Result;
public Task<PEFile> AssemblyTask => assemblyDefinitionTaskSource.Task;
- public MetadataReader ModuleDefinition {
- get {
- return assemblyLoaderTask.Result.Metadata;
- }
- }
-
CSharpDecompiler csharpDecompiler;
public CSharpDecompiler CSharpDecompiler {
get {
if (csharpDecompiler == null) {
- csharpDecompiler = new CSharpDecompiler (DecompilerTypeSystem, new ICSharpCode.Decompiler.DecompilerSettings ());
+ csharpDecompiler = new CSharpDecompiler (DecompilerTypeSystem, new ICSharpCode.Decompiler.DecompilerSettings (LanguageVersion.Latest));
+ csharpDecompiler.AstTransforms.Add (new EscapeInvalidIdentifiers ());
}
return csharpDecompiler;
@@ -84,16 +80,13 @@ namespace MonoDevelop.AssemblyBrowser
DecompilerTypeSystem decompilerTypeSystem;
public DecompilerTypeSystem DecompilerTypeSystem {
get {
- LoadTypeSystem (Assembly);
+ if (decompilerTypeSystem == null) {
+ decompilerTypeSystem = new DecompilerTypeSystem (Assembly, new AssemblyResolver (Assembly, widget));
+ }
return decompilerTypeSystem;
}
}
- void LoadTypeSystem (PEFile peFile)
- {
- decompilerTypeSystem = new DecompilerTypeSystem (peFile, new AssemblyResolver (Assembly, widget));
- }
-
public Error Error { get; internal set; }
public bool IsLoaded { get; private set; }
@@ -122,19 +115,7 @@ namespace MonoDevelop.AssemblyBrowser
assemblyDefinitionTaskSource.SetResult (null);
return null;
} finally { IsLoaded = true; }
- });
- }
-
- ICompilation typeSystem;
-
- public ICompilation GetMinimalTypeSystem ()
- {
- if (typeSystem != null)
- return typeSystem;
- var assembly = Assembly;
- if (assembly == null)
- return null;
- return typeSystem = new SimpleCompilation (assembly.WithOptions (TypeSystemOptions.Default | TypeSystemOptions.Uncached | TypeSystemOptions.KeepModifiers), MinimalCorlib.Instance);
+ }, src.Token);
}
class MyUniversalAssemblyResolver : UniversalAssemblyResolver
diff --git a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/MetadataExtensions.cs b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/MetadataExtensions.cs
index 197fb93c08..df992f6f8c 100644
--- a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/MetadataExtensions.cs
+++ b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/MetadataExtensions.cs
@@ -40,6 +40,11 @@ namespace MonoDevelop.AssemblyBrowser
entity.Accessibility == Accessibility.ProtectedOrInternal ||
entity.Accessibility == Accessibility.Public;
+ public static bool IsPublic (this Microsoft.CodeAnalysis.ISymbol entity) =>
+ entity.DeclaredAccessibility == Microsoft.CodeAnalysis.Accessibility.Protected ||
+ entity.DeclaredAccessibility == Microsoft.CodeAnalysis.Accessibility.ProtectedOrInternal ||
+ entity.DeclaredAccessibility == Microsoft.CodeAnalysis.Accessibility.Public;
+
public static string GetStockIcon (this Accessibility attributes)
{
switch (attributes) {
diff --git a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/AssemblyBrowserTypeNodeBuilder.cs b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/AssemblyBrowserTypeNodeBuilder.cs
index 9e9ed85e07..58aa2b9a6f 100644
--- a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/AssemblyBrowserTypeNodeBuilder.cs
+++ b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/AssemblyBrowserTypeNodeBuilder.cs
@@ -34,6 +34,7 @@ using MonoDevelop.Ide.TypeSystem;
using ICSharpCode.Decompiler.CSharp.OutputVisitor;
using System.Threading.Tasks;
using System.Collections.Generic;
+using System.Linq;
namespace MonoDevelop.AssemblyBrowser
{
@@ -79,5 +80,16 @@ namespace MonoDevelop.AssemblyBrowser
return treeBuilder.GetParentDataItem (typeof(AssemblyLoader), true) != null;
}
+ protected static void AddFilteredChildren<T> (ITreeBuilder builder, IReadOnlyCollection<T> collection, bool publicApiOnly) where T:IEntity
+ {
+ if (collection.Count == 0)
+ return;
+
+ var children = publicApiOnly
+ ? collection.Where (x => x.IsPublic ())
+ : collection;
+
+ builder.AddChildren (collection);
+ }
}
}
diff --git a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/AssemblyReferenceNodeBuilder.cs b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/AssemblyReferenceNodeBuilder.cs
index 98d83e6e94..641aa3412d 100644
--- a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/AssemblyReferenceNodeBuilder.cs
+++ b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/AssemblyReferenceNodeBuilder.cs
@@ -82,7 +82,7 @@ namespace MonoDevelop.AssemblyBrowser
if (e2 == null)
return -1;
- return e1.Name.CompareTo (e2.Name);
+ return string.Compare(e1.Name, e2.Name, StringComparison.Ordinal);
} catch (Exception e) {
LoggingService.LogError ("Exception in assembly browser sort function.", e);
return -1;
diff --git a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/BaseTypeFolderNodeBuilder.cs b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/BaseTypeFolderNodeBuilder.cs
index dc17aa56b6..fc1f30d49d 100644
--- a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/BaseTypeFolderNodeBuilder.cs
+++ b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/BaseTypeFolderNodeBuilder.cs
@@ -67,9 +67,7 @@ namespace MonoDevelop.AssemblyBrowser
public override int CompareObjects (ITreeNavigator thisNode, ITreeNavigator otherNode)
{
- var r1 = thisNode.DataItem as ITypeReference;
- var r2 = thisNode.DataItem as ITypeReference;
- return r1.ToString ().CompareTo (r2.ToString ());
+ return string.Compare (thisNode.NodeName, otherNode.NodeName, StringComparison.Ordinal);
}
}
diff --git a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Cecil/AssemblyNodeBuilder.cs b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Cecil/AssemblyNodeBuilder.cs
index 0e2c3fd73a..d4ac415ec8 100644
--- a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Cecil/AssemblyNodeBuilder.cs
+++ b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Cecil/AssemblyNodeBuilder.cs
@@ -100,26 +100,23 @@ namespace MonoDevelop.AssemblyBrowser
var resources = new AssemblyResourceFolder (assemblyLoader.Assembly);
if (resources.Resources.Any ())
treeBuilder.AddChild (resources);
-
- var namespaces = new Dictionary<string, NamespaceData> ();
- bool publicOnly = Widget.PublicApiOnly;
-
- foreach (var type in assemblyLoader.GetMinimalTypeSystem ().MainModule.TopLevelTypeDefinitions) {
- string namespaceName = string.IsNullOrEmpty (type.Namespace) ? "" : type.Namespace;
- if (!namespaces.ContainsKey (namespaceName))
- namespaces [namespaceName] = new NamespaceData (namespaceName);
-
- var ns = namespaces [namespaceName];
- ns.Types.Add ((type.IsPublic (), type));
- }
- treeBuilder.AddChildren (namespaces.Where (ns => ns.Key != "" && (!publicOnly || ns.Value.Types.Any (t => t.isPublic))).Select (n => n.Value));
- if (namespaces.ContainsKey ("")) {
- foreach (var child in namespaces [""].Types) {
- if (((INamedElement)child.typeObject).Name == "<Module>")
- continue;
- treeBuilder.AddChild (child);
- }
+ var mainModule = assemblyLoader.DecompilerTypeSystem.MainModule;
+ var rootData = new NamespaceData (mainModule.RootNamespace);
+ if (rootData.Types.Length > 0)
+ treeBuilder.AddChild (rootData);
+
+ var allNamespaces = new List<NamespaceData> (32);
+ CollectNamespaces (allNamespaces, mainModule.RootNamespace.ChildNamespaces);
+ treeBuilder.AddChildren (allNamespaces);
+ }
+
+ void CollectNamespaces (List<NamespaceData> accumulator, IEnumerable<INamespace> namespaces)
+ {
+ accumulator.AddRange (namespaces.Select (x => new NamespaceData(x)));
+
+ foreach (var ns in namespaces) {
+ CollectNamespaces (accumulator, ns.ChildNamespaces);
}
}
diff --git a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Cecil/MethodDefinitionNodeBuilder.cs b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Cecil/MethodDefinitionNodeBuilder.cs
index 81b1fa822b..e9b28c36dd 100644
--- a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Cecil/MethodDefinitionNodeBuilder.cs
+++ b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Cecil/MethodDefinitionNodeBuilder.cs
@@ -124,14 +124,14 @@ namespace MonoDevelop.AssemblyBrowser
}
- public static async Task<List<ReferenceSegment>> DecompileAsync (TextEditor data, AssemblyLoader assemblyLoader, Func<CSharpDecompiler, SyntaxTree> decompile, DecompilerSettings settings = null, DecompileFlags flags = null)
+ public static Task<List<ReferenceSegment>> DecompileAsync (TextEditor data, AssemblyLoader assemblyLoader, Func<CSharpDecompiler, SyntaxTree> decompile, DecompilerSettings settings = null, DecompileFlags flags = null)
{
if (data == null)
throw new ArgumentNullException (nameof (data));
if (assemblyLoader == null)
throw new ArgumentNullException (nameof (assemblyLoader));
- return await Task.Run (async delegate {
+ return Task.Run (async delegate {
settings = settings ?? GetDecompilerSettings (data, publicOnly: flags.PublicOnly);
var csharpDecompiler = assemblyLoader.CSharpDecompiler;
try {
diff --git a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Cecil/TypeDefinitionNodeBuilder.cs b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Cecil/TypeDefinitionNodeBuilder.cs
index b875def8f7..90f83a0e73 100644
--- a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Cecil/TypeDefinitionNodeBuilder.cs
+++ b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Cecil/TypeDefinitionNodeBuilder.cs
@@ -98,46 +98,28 @@ namespace MonoDevelop.AssemblyBrowser
public override void BuildChildNodes (ITreeBuilder builder, object dataObject)
{
var type = (ITypeDefinition)dataObject;
- var list = new System.Collections.ArrayList ();
if (type.DirectBaseTypes.Any ())
- list.Add (new BaseTypeFolder (type));
- bool publicOnly = Widget.PublicApiOnly;
-
- foreach (var field in type.Fields.OrderBy (m => m.Name, StringComparer.InvariantCulture)) {
- if (publicOnly && !field.IsPublic ())
- continue;
- builder.AddChild (field);
- }
-
- foreach (var property in type.Properties.OrderBy (m => m.Name, StringComparer.InvariantCulture)) {
- var accessor = property.Getter ?? property.Setter;
- if (publicOnly && !accessor.IsPublic ())
- continue;
- builder.AddChild (property);
- }
+ builder.AddChild (new BaseTypeFolder (type));
- foreach (var evt in type.Events.OrderBy (m => m.Name, StringComparer.InvariantCulture)) {
- var accessor = evt.AddAccessor ?? evt.RemoveAccessor;
- if (publicOnly && !accessor.IsPublic ())
- continue;
- builder.AddChild (evt);
- }
+ bool publicOnly = Widget.PublicApiOnly;
- var accessorMethods = type.GetAccessors ();
- foreach (var method in type.Methods.OrderBy (m => m.Name, StringComparer.InvariantCulture)) {
- if (publicOnly && !method.IsPublic ())
- continue;
- if (!accessorMethods.Contains (method)) {
- builder.AddChild (method);
- }
- }
+ // PERF: We can take advantage of the fact that AddChildren is faster than AddChild, due to not processing
+ // sorting of child nodes. Avoid creating additional collection, as TreeBuilder does not optimize for ICollection implementors,
+ // thus the overhead of creating a IEnumerable is not that big.
+ AddFilteredChildren (builder, type.Members, publicOnly);
+ AddFilteredChildren (builder, type.NestedTypes, publicOnly);
}
public override bool HasChildNodes (ITreeBuilder builder, object dataObject)
{
return true;
}
-
+
+ public override int GetSortIndex (ITreeNavigator node)
+ {
+ return -50;
+ }
+
#region IAssemblyBrowserNodeBuilder
internal static void PrintAssembly (StringBuilder result, ITreeNavigator navigator)
{
diff --git a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/ModuleReferenceNodeBuilder.cs b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/ModuleReferenceNodeBuilder.cs
index e9a6b593a2..9262f9612f 100644
--- a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/ModuleReferenceNodeBuilder.cs
+++ b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/ModuleReferenceNodeBuilder.cs
@@ -70,7 +70,7 @@ namespace MonoDevelop.AssemblyBrowser
if (e2 == null)
return 1;
- return e1.Name.CompareTo (e2.Name);
+ return string.Compare (e1.Name, e2.Name, StringComparison.Ordinal);
} catch (Exception e) {
LoggingService.LogError ("Exception in assembly browser sort function.", e);
return -1;
diff --git a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/NamespaceBuilder.cs b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/NamespaceBuilder.cs
index 89c848dc27..0307db2738 100644
--- a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/NamespaceBuilder.cs
+++ b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/NamespaceBuilder.cs
@@ -64,7 +64,7 @@ namespace MonoDevelop.AssemblyBrowser
if (e2 == null)
return -1;
- return e1.Name.CompareTo (e2.Name);
+ return string.Compare (e1.Name, e2.Name, StringComparison.Ordinal);
} catch (Exception e) {
LoggingService.LogError ("Exception in assembly browser sort function.", e);
return -1;
@@ -87,12 +87,12 @@ namespace MonoDevelop.AssemblyBrowser
public override void BuildChildNodes (ITreeBuilder ctx, object dataObject)
{
NamespaceData ns = (NamespaceData)dataObject;
- bool publicOnly = Widget.PublicApiOnly;
- foreach (var type in ns.Types) {
- if (publicOnly && !type.isPublic)
- continue;
- ctx.AddChild (type.typeObject);
- }
+
+ IEnumerable<object> result = ns.Types;
+ if (Widget.PublicApiOnly)
+ result = result.Where (x => NamespaceData.IsPublic (x));
+
+ ctx.AddChildren (result);
}
public override bool HasChildNodes (ITreeBuilder builder, object dataObject)
diff --git a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/NamespaceData.cs b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/NamespaceData.cs
index 56950b7d79..47a2f0f7f7 100644
--- a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/NamespaceData.cs
+++ b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/NamespaceData.cs
@@ -28,42 +28,61 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using ICSharpCode.Decompiler.TypeSystem;
+using MonoDevelop.Ide.TypeSystem;
namespace MonoDevelop.AssemblyBrowser
{
class NamespaceData : IDisposable
{
- List<(bool, object)> types = new List<(bool, object)> ();
-
- public string Name {
- get;
- private set;
+ public string Name { get; }
+ INamespace decompilerNs;
+ Microsoft.CodeAnalysis.INamespaceSymbol roslynNamespace;
+
+ public static bool IsPublic (object typeObject)
+ {
+ return (typeObject is ITypeDefinition typeDefinition && typeDefinition.IsPublic ())
+ || (typeObject is Microsoft.CodeAnalysis.INamedTypeSymbol symbol && symbol.IsPublic ());
}
- public List<(bool isPublic, object typeObject)> Types {
+ object [] types;
+ public object[] Types {
get {
+ if (types == null) {
+ types = decompilerNs?.Types.ToArray ()
+ ?? roslynNamespace?.GetTypeMembers ().ToArray ()
+ ?? Array.Empty<object> ();
+ }
return types;
}
}
-
- public NamespaceData (string name)
+
+ public NamespaceData(INamespace ns)
{
- this.Name = name;
+ Name = ns.FullName;
+ decompilerNs = ns;
+
+ // Remove <Module> from root namespace.
+ if (ns.ParentNamespace == null) {
+ types = decompilerNs.Types.Where (x => x.Name != "<Module>").ToArray ();
+ }
+ }
+
+ public NamespaceData(Microsoft.CodeAnalysis.INamespaceSymbol namespaceSymbol)
+ {
+ Name = namespaceSymbol.GetFullName ();
+ roslynNamespace = namespaceSymbol;
}
public void Dispose ()
{
- if (types != null) {
- // types.ForEach (t => t.Dispose ());
- types.Clear ();
- types = null;
- }
+ types = null;
}
public override string ToString ()
{
- return string.Format ("[Namespace: Name={0}, #Types={1}]", Name, Types.Count);
+ return string.Format ("[Namespace: Name={0}, #Types={1}]", Name, Types.Length);
}
}
}
diff --git a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Roslyn/ProjectNodeBuilder.cs b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Roslyn/ProjectNodeBuilder.cs
index e65bfd01da..15487176c0 100644
--- a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Roslyn/ProjectNodeBuilder.cs
+++ b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Roslyn/ProjectNodeBuilder.cs
@@ -58,7 +58,7 @@ namespace MonoDevelop.AssemblyBrowser
var project = (Project)dataObject;
return project.Name;
}
-
+
public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, NodeInfo nodeInfo)
{
var project = (Project)dataObject;
@@ -74,27 +74,27 @@ namespace MonoDevelop.AssemblyBrowser
var dom = IdeApp.TypeSystemService.GetCompilationAsync (project).Result;
if (dom == null)
return;
- bool nestedNamespaces = builder.Options ["NestedNamespaces"];
- HashSet<string> addedNames = new HashSet<string> ();
- foreach (var ns in dom.Assembly.GlobalNamespace.GetNamespaceMembers ()) {
- FillNamespaces (builder, project, ns);
+
+ var data = new List<NamespaceData> (32);
+ CollectNamespaces (data, dom.Assembly.GlobalNamespace.GetNamespaceMembers ());
+ builder.AddChildren (data);
+
+ var types = dom.Assembly.GlobalNamespace.GetTypeMembers ();
+ if (types.Length > 0) {
+ var children = publicOnly
+ ? types.Where (t => t.IsPublic ())
+ : types;
+
+ builder.AddChildren (children);
}
- builder.AddChildren (dom.Assembly.GlobalNamespace.GetTypeMembers ()
- .Where (type => !publicOnly || type.DeclaredAccessibility == Microsoft.CodeAnalysis.Accessibility.Public));
}
- public static void FillNamespaces (ITreeBuilder builder, Project project, Microsoft.CodeAnalysis.INamespaceSymbol ns)
+ static void CollectNamespaces (List<NamespaceData> acc, IEnumerable<Microsoft.CodeAnalysis.INamespaceSymbol> namespaces)
{
- var members = ns.GetTypeMembers ();
- //IParserContext ctx = IdeApp.Workspace.ParserDatabase.GetProjectParserContext (project);
- if (members.Any ()) {
- var data = new NamespaceData (ns.Name);
- foreach (var member in members)
- data.Types.Add ((member.DeclaredAccessibility == Microsoft.CodeAnalysis.Accessibility.Public, member));
- builder.AddChild (data);
- }
- foreach (var nSpace in ns.GetNamespaceMembers ()) {
- FillNamespaces (builder, project, nSpace);
+ acc.AddRange (namespaces.Select (x => new NamespaceData (x)));
+
+ foreach (var ns in namespaces) {
+ CollectNamespaces (acc, ns.GetNamespaceMembers ());
}
}
@@ -118,7 +118,7 @@ namespace MonoDevelop.AssemblyBrowser
if (e2 == null)
return 1;
- return e1.Name.CompareTo (e2.Name);
+ return string.Compare (e1.Name, e2.Name, StringComparison.Ordinal);
} catch (Exception e) {
LoggingService.LogError ("Exception in assembly browser sort function.", e);
return -1;
diff --git a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Roslyn/RoslynMemberNodeBuilder.cs b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Roslyn/RoslynMemberNodeBuilder.cs
index 57b2f79562..3707a94029 100644
--- a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Roslyn/RoslynMemberNodeBuilder.cs
+++ b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Roslyn/RoslynMemberNodeBuilder.cs
@@ -45,39 +45,14 @@ namespace MonoDevelop.AssemblyBrowser
public override int CompareObjects (ITreeNavigator thisNode, ITreeNavigator otherNode)
{
- if (!(otherNode.DataItem is ISymbol)) return 1;
-
- if (thisNode.Options ["GroupByType"]) {
- int v1 = GetTypeSortValue (thisNode.DataItem);
- int v2 = GetTypeSortValue (otherNode.DataItem);
- if (v1 < v2) return -1;
- else if (v1 > v2) return 1;
- }
- if (thisNode.Options ["GroupByAccess"]) {
- int v1 = GetAccessSortValue (((ISymbol)thisNode.DataItem).DeclaredAccessibility);
- int v2 = GetAccessSortValue (((ISymbol)otherNode.DataItem).DeclaredAccessibility);
- if (v1 < v2) return -1;
- else if (v1 > v2) return 1;
+ try {
+ if (thisNode == null || otherNode == null)
+ return -1;
+ return string.Compare (thisNode.NodeName, otherNode.NodeName, StringComparison.OrdinalIgnoreCase);
+ } catch (Exception e) {
+ LoggingService.LogError ("Exception in assembly browser sort function.", e);
+ return -1;
}
- return DefaultSort;
- }
-
- int GetTypeSortValue (object member)
- {
- if (member is IFieldSymbol) return 0;
- if (member is IEventSymbol) return 1;
- if (member is IPropertySymbol) return 2;
- if (member is IMethodSymbol) return 3;
- return 4;
- }
-
- int GetAccessSortValue (Accessibility mods)
- {
- if ((mods & Accessibility.Private) != 0) return 0;
- if ((mods & Accessibility.Internal) != 0) return 1;
- if ((mods & Accessibility.Protected) != 0) return 2;
- if ((mods & Accessibility.Public) != 0) return 3;
- return 4;
}
public Task<List<ReferenceSegment>> DecompileAsync (TextEditor data, ITreeNavigator navigator, DecompileFlags flags)
@@ -85,17 +60,17 @@ namespace MonoDevelop.AssemblyBrowser
return DisassembleAsync (data, navigator);
}
- public Task<List<ReferenceSegment>> DisassembleAsync (TextEditor data, ITreeNavigator navigator)
+ public async Task<List<ReferenceSegment>> DisassembleAsync (TextEditor data, ITreeNavigator navigator)
{
var symbol = navigator.DataItem as ISymbol;
if (symbol == null) {
data.Text = "// DataItem is no symbol " + navigator.DataItem; // should never happen
LoggingService.LogError ("DataItem is no symbol " + navigator.DataItem);
- return AssemblyBrowserTypeNodeBuilder.EmptyReferenceSegmentTask;
+ return new List<ReferenceSegment> ();
}
var location = symbol.Locations [0];
if (location.IsInSource) {
- var root = location.SourceTree.GetRoot ();
+ var root = await location.SourceTree.GetRootAsync ();
var node = root.FindNode (location.SourceSpan);
if (node != null) {
data.Text = node.ToFullString ();
@@ -106,7 +81,7 @@ namespace MonoDevelop.AssemblyBrowser
data.Text = "// Error: Symbol " + symbol.MetadataName + " is not in source."; // should never happen
LoggingService.LogError ("Symbol " + symbol.MetadataName + " is not in source.");
}
- return AssemblyBrowserTypeNodeBuilder.EmptyReferenceSegmentTask;
+ return new List<ReferenceSegment> ();
}
diff --git a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Roslyn/RoslynTypeNodeBuilder.cs b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Roslyn/RoslynTypeNodeBuilder.cs
index 81b74424aa..b798484b31 100644
--- a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Roslyn/RoslynTypeNodeBuilder.cs
+++ b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/TreeNodes/Roslyn/RoslynTypeNodeBuilder.cs
@@ -88,30 +88,24 @@ namespace MonoDevelop.AssemblyBrowser
if (classData.TypeKind == TypeKind.Delegate)
return;
- builder.AddChildren (classData.GetTypeMembers ()
- .Where (innerClass => innerClass.DeclaredAccessibility == Accessibility.Public ||
- (innerClass.DeclaredAccessibility == Accessibility.Protected && publicProtectedOnly) ||
- !publicOnly));
+ Func<ISymbol, bool> filter = symbol => !MethodPropertyFilter (symbol);
+ if (Widget.PublicApiOnly)
+ filter = symbol => symbol.IsPublic () && !MethodPropertyFilter (symbol);
- builder.AddChildren (classData.GetMembers ().OfType<IMethodSymbol> ().Where (m => m.MethodKind != MethodKind.PropertyGet && m.MethodKind != MethodKind.PropertySet)
- .Where (method => method.DeclaredAccessibility == Accessibility.Public ||
- (method.DeclaredAccessibility == Accessibility.Protected && publicProtectedOnly) ||
- !publicOnly));
+ var typeMembers = classData.GetTypeMembers ();
+ if (typeMembers.Length > 0) {
+ builder.AddChildren (Enumerable.Where (typeMembers, filter));
+ }
- builder.AddChildren (classData.GetMembers ().OfType<IPropertySymbol> ()
- .Where (property => property.DeclaredAccessibility == Accessibility.Public ||
- (property.DeclaredAccessibility == Accessibility.Protected && publicProtectedOnly) ||
- !publicOnly));
+ var members = classData.GetMembers ();
+ if (members.Length > 0) {
+ builder.AddChildren (members.Where (filter));
+ }
- builder.AddChildren (classData.GetMembers ().OfType<IFieldSymbol> ()
- .Where (field => field.DeclaredAccessibility == Accessibility.Public ||
- (field.DeclaredAccessibility == Accessibility.Protected && publicProtectedOnly) ||
- !publicOnly));
-
- builder.AddChildren (classData.GetMembers ().OfType<IEventSymbol> ()
- .Where (e => e.DeclaredAccessibility == Accessibility.Public ||
- (e.DeclaredAccessibility == Accessibility.Protected && publicProtectedOnly) ||
- !publicOnly));
+ bool MethodPropertyFilter (ISymbol symbol)
+ {
+ return symbol is IMethodSymbol method && (method.MethodKind == MethodKind.PropertyGet || method.MethodKind == MethodKind.PropertySet);
+ }
}
public override bool HasChildNodes (ITreeBuilder builder, object dataObject)
diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.VSTextView/BreakpointManager.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.VSTextView/BreakpointManager.cs
index f3f690e450..93058fe629 100644
--- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.VSTextView/BreakpointManager.cs
+++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.VSTextView/BreakpointManager.cs
@@ -37,15 +37,17 @@ namespace MonoDevelop.Debugger
void TextBuffer_Changed (object sender, TextContentChangedEventArgs e)
{
foreach (var breakpoint in breakpoints.Values) {
- var newSpan = breakpoint.TrackingSpan.GetSpan (e.After);
- if (newSpan.IsEmpty) {
+ var span = breakpoint.TrackingSpan.GetSpan (e.After);
+
+ if (span.IsEmpty || string.IsNullOrWhiteSpace (span.GetText ())) {
DebuggingService.Breakpoints.Remove (breakpoint.Breakpoint);
continue;
}
- var newLineNumber = e.After.GetLineFromPosition (newSpan.Start).LineNumber + 1;
- if (breakpoint.Breakpoint.Line != newLineNumber) {
+
+ var newLineNumber = e.After.GetLineFromPosition (span.Start).LineNumber + 1;
+
+ if (breakpoint.Breakpoint.Line != newLineNumber)
DebuggingService.Breakpoints.UpdateBreakpointLine (breakpoint.Breakpoint, newLineNumber);
- }
}
}
@@ -58,38 +60,47 @@ namespace MonoDevelop.Debugger
private Dictionary<Breakpoint, ManagerBreakpoint> breakpoints = new Dictionary<Breakpoint, ManagerBreakpoint> ();
- private void OnBreakpointsChanged (object sender, EventArgs eventArgs)
+ private async void OnBreakpointsChanged (object sender, EventArgs eventArgs)
{
- var snapshot = textBuffer.CurrentSnapshot;
var newBreakpoints = new Dictionary<Breakpoint, ManagerBreakpoint> ();
- bool needsUpdate = false;
+ var snapshot = textBuffer.CurrentSnapshot;
+ var needsUpdate = false;
+
foreach (var breakpoint in DebuggingService.Breakpoints.GetBreakpointsAtFile (textDocument.FilePath)) {
if (breakpoint.Line > snapshot.LineCount)
continue;
+
if (eventArgs is BreakpointEventArgs breakpointEventArgs && breakpointEventArgs.Breakpoint == breakpoint)
needsUpdate = true;
- var newSpan = snapshot.GetLineFromLineNumber (breakpoint.Line - 1).Extent;
+
+ var line = snapshot.GetLineFromLineNumber (breakpoint.Line - 1);
+ var position = line.Start.Position + breakpoint.Column;
+ var span = await DebuggingService.GetBreakpointSpanAsync (textDocument, position);
+
if (breakpoints.TryGetValue (breakpoint, out var existingBreakpoint)) {
newBreakpoints.Add (breakpoint, existingBreakpoint);
- if (existingBreakpoint.Span != newSpan.Span) {
- // Update if anything was modifed
+ if (existingBreakpoint.Span != span) {
+ // Update if anything was modified
+ existingBreakpoint.Span = span;
needsUpdate = true;
- existingBreakpoint.Span = newSpan.Span;
}
} else {
// Update if anything was added
- needsUpdate = true;
- newBreakpoints.Add (breakpoint, new ManagerBreakpoint () {
+ newBreakpoints.Add (breakpoint, new ManagerBreakpoint {
Breakpoint = breakpoint,
- TrackingSpan = snapshot.CreateTrackingSpan (newSpan, SpanTrackingMode.EdgeExclusive),
- Span = newSpan.Span
+ TrackingSpan = snapshot.CreateTrackingSpan (span, SpanTrackingMode.EdgeExclusive),
+ Span = span
});
+ needsUpdate = true;
}
}
+
// Update if anything was removed
if (needsUpdate || breakpoints.Keys.Except (newBreakpoints.Keys).Any ())
needsUpdate = true;
+
breakpoints = newBreakpoints;
+
if (needsUpdate)
BreakpointsChanged?.Invoke (this, new SnapshotSpanEventArgs (new SnapshotSpan (snapshot, 0, snapshot.Length)));
}
diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.csproj b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.csproj
index 12b7e203fb..bdecc781e7 100644
--- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.csproj
+++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.csproj
@@ -174,6 +174,8 @@
<Compile Include="MonoDevelop.Debugger.VSTextView\QuickInfo\IDebugInfoProvider.cs" />
<Compile Include="MonoDevelop.Debugger.VSTextView\BreakpointManagerService.cs" />
<Compile Include="MonoDevelop.Debugger.VSTextView\BreakpointManager.cs" />
+ <Compile Include="MonoDevelop.Debugger\IBreakpointSpanResolver.cs" />
+ <Compile Include="MonoDevelop.Debugger\DefaultBreakpointSpanResolver.cs" />
</ItemGroup>
<ItemGroup Condition="$(OS) != 'Windows_NT'">
<Compile Include="MonoDevelop.Debugger.VSTextView\ExceptionCaught\ExceptionCaughtProvider.cs" />
diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs
index 950385ee18..9e19487fc4 100644
--- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs
+++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs
@@ -1331,11 +1331,19 @@ namespace MonoDevelop.Debugger
static void OnLineCountChanged (object ob, LineCountEventArgs a)
{
lock (breakpoints) {
- foreach (Breakpoint bp in breakpoints.GetBreakpoints ()) {
+ foreach (var bp in breakpoints.GetBreakpoints ()) {
if (bp.FileName == a.TextFile.Name) {
if (bp.Line > a.LineNumber) {
+ var startIndex = a.TextFile.GetPositionFromLineColumn (bp.Line, bp.Column);
+ var endIndex = a.TextFile.GetPositionFromLineColumn (bp.Line + 1, 0) - 1;
+
+ if (endIndex < startIndex)
+ endIndex = startIndex;
+
+ var text = a.TextFile.GetText (startIndex, endIndex);
+
// If the line that has the breakpoint is deleted, delete the breakpoint, otherwise update the line #.
- if (bp.Line + a.LineCount >= a.LineNumber)
+ if (bp.Line + a.LineCount >= a.LineNumber && !string.IsNullOrWhiteSpace (text))
breakpoints.UpdateBreakpointLine (bp, bp.Line + a.LineCount);
else
breakpoints.Remove (bp);
@@ -1482,6 +1490,19 @@ namespace MonoDevelop.Debugger
return result;
return frame.GetExpressionCompletionData (exp);
}
+
+ public static Task<Span> GetBreakpointSpanAsync (ITextDocument document, int position, CancellationToken cancellationToken = default (CancellationToken))
+ {
+ var doc = IdeApp.Workbench.GetDocument (document.FilePath);
+ IBreakpointSpanResolver resolver = null;
+
+ if (doc != null)
+ resolver = doc.GetContent<IBreakpointSpanResolver> ();
+
+ resolver = resolver ?? new DefaultBreakpointSpanResolver ();
+
+ return resolver.GetBreakpointSpanAsync (document.TextBuffer, position, cancellationToken);
+ }
}
class FeatureCheckerHandlerFactory : IExecutionHandler
diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DefaultBreakpointSpanResolver.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DefaultBreakpointSpanResolver.cs
new file mode 100644
index 0000000000..19c245fafb
--- /dev/null
+++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DefaultBreakpointSpanResolver.cs
@@ -0,0 +1,47 @@
+//
+// DefaultBreakpointSpanResolver.cs
+//
+// Author:
+// Jeffrey Stedfast <jestedfa@microsoft.com>
+//
+// Copyright (c) 2019 Microsoft Corp.
+//
+// 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.Threading;
+using System.Threading.Tasks;
+
+using Microsoft.VisualStudio.Text;
+
+namespace MonoDevelop.Debugger
+{
+ public class DefaultBreakpointSpanResolver : IBreakpointSpanResolver
+ {
+ public Task<Span> GetBreakpointSpanAsync (ITextBuffer buffer, int position, CancellationToken cancellationToken)
+ {
+ try {
+ var line = buffer.CurrentSnapshot.GetLineFromPosition (position);
+
+ return Task.FromResult (Span.FromBounds (line.Start.Position, line.End.Position));
+ } catch {
+ return Task.FromResult (default (Span));
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/IBreakpointSpanResolver.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/IBreakpointSpanResolver.cs
new file mode 100644
index 0000000000..25f337ac54
--- /dev/null
+++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/IBreakpointSpanResolver.cs
@@ -0,0 +1,48 @@
+//
+// IBreakpointSpanResolver.cs
+//
+// Author:
+// Jeffrey Stedfast <jestedfa@microsoft.com>
+//
+// Copyright (c) 2019 Microsoft Corp.
+//
+// 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.Threading;
+using System.Threading.Tasks;
+
+using Microsoft.VisualStudio.Text;
+
+namespace MonoDevelop.Debugger
+{
+ /// <summary>
+ /// An interface for resolving the span of a breakpoint.
+ /// </summary>
+ public interface IBreakpointSpanResolver
+ {
+ /// <summary>
+ /// Resolve the span of a breakpoint.
+ /// </summary>
+ /// <param name="buffer">The text buffer.</param>
+ /// <param name="position">The cursor position.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>The span of the breakpoint.</returns>
+ Task<Span> GetBreakpointSpanAsync (ITextBuffer buffer, int position, CancellationToken cancellationToken);
+ }
+}
diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs
index a7f5cb353d..afceba6802 100644
--- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs
+++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs
@@ -947,15 +947,15 @@ namespace MonoDevelop.Debugger
}
int numberOfChildren = store.IterNChildren (iter);
- Task.Factory.StartNew<ObjectValue[]> (delegate (object arg) {
+ Task.Run (() => {
try {
- return ((ObjectValue)arg).GetRangeOfChildren (numberOfChildren - 1, 20);
+ return value.GetRangeOfChildren (numberOfChildren - 1, 20);
} catch (Exception ex) {
// Note: this should only happen if someone breaks ObjectValue.GetAllChildren()
LoggingService.LogError ("Failed to get ObjectValue children.", ex);
return new ObjectValue[0];
}
- }, value, cancellationTokenSource.Token).ContinueWith (t => {
+ }, cancellationTokenSource.Token).ContinueWith (t => {
TreeIter it;
if (disposed)
return;
@@ -975,7 +975,7 @@ namespace MonoDevelop.Debugger
if (compact)
RecalculateWidth ();
enumerableLoading.Remove (value);
- }, cancellationTokenSource.Token, TaskContinuationOptions.NotOnCanceled, Xwt.Application.UITaskScheduler);
+ }, cancellationTokenSource.Token, TaskContinuationOptions.NotOnCanceled, Runtime.MainTaskScheduler).Ignore ();
}
void RefreshRow (TreeIter iter, ObjectValue val)
diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/SourceCodeLookup.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/SourceCodeLookup.cs
index bd69d29c79..91cc41a8e8 100644
--- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/SourceCodeLookup.cs
+++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/SourceCodeLookup.cs
@@ -23,15 +23,17 @@
// 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 MonoDevelop.Core;
-using System.Collections.Generic;
using System.IO;
-using System.Security.Cryptography;
using System.Linq;
+using System.Collections.Generic;
+
+using Mono.Debugging.Client;
+
using MonoDevelop.Ide;
+using MonoDevelop.Core;
using MonoDevelop.Projects;
-using Mono.Debugging.Client;
namespace MonoDevelop.Debugger
{
@@ -120,50 +122,9 @@ namespace MonoDevelop.Debugger
return FilePath.Null;
}
- public static bool CheckFileHash (FilePath file, byte[] hash)
+ public static bool CheckFileHash (FilePath path, byte[] checksum)
{
- if (hash == null)
- return false;
- if (File.Exists (file)) {
- using (var fs = File.OpenRead (file)) {
- // Roslyn SHA1 checksum always starts with 20
- if (hash.Length > 0 && hash [0] == 20)
- using (var sha1 = SHA1.Create ()) {
- if (sha1.ComputeHash (fs).Take (15).SequenceEqual (hash.Skip (1))) {
- return true;
- }
- }
- if (hash.Length > 0 && hash [0] == 32)
- using (var sha1 = SHA256.Create ()) {
- if (sha1.ComputeHash (fs).Take (15).SequenceEqual (hash.Skip (1))) {
- return true;
- }
- }
- if (hash.Length == 20) {
- using (var sha1 = SHA1.Create ()) {
- fs.Position = 0;
- if (sha1.ComputeHash (fs).SequenceEqual (hash)) {
- return true;
- }
- }
- }
- if (hash.Length == 32) {
- using (var sha256 = SHA256.Create ()) {
- fs.Position = 0;
- if (sha256.ComputeHash (fs).SequenceEqual (hash)) {
- return true;
- }
- }
- }
- fs.Position = 0;
- using (var md5 = MD5.Create ()) {
- if (md5.ComputeHash (fs).SequenceEqual (hash)) {
- return true;
- }
- }
- }
- }
- return false;
+ return SourceLocation.CheckFileHash (path, checksum);
}
/// <summary>
@@ -223,4 +184,3 @@ namespace MonoDevelop.Debugger
}
}
}
-
diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectExtension.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectExtension.cs
index 984c13692c..df43588e79 100644
--- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectExtension.cs
+++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectExtension.cs
@@ -58,15 +58,19 @@ namespace MonoDevelop.DotNetCore
void FileService_FileChanged (object sender, FileEventArgs e)
{
- var globalJson = e.FirstOrDefault (x => x.FileName.FileName.IndexOf ("global.json", StringComparison.OrdinalIgnoreCase) == 0 && !x.FileName.IsDirectory);
- if (globalJson == null)
- return;
-
- // make sure the global.json file that has been changed is the one we got when loading the project
- if (Project.ParentSolution.ExtendedProperties [GlobalJsonPathExtendedPropertyName] is string globalJsonPath
- && globalJsonPath.IndexOf (globalJson.FileName, StringComparison.OrdinalIgnoreCase) == 0) {
- DetectSDK (restore: true);
+ foreach (var arg in e) {
+ if (arg.IsDirectory || !arg.FileName.HasExtension (".json"))
+ continue;
+
+ // avoid allocation caused by not querying .FileName
+ string fileName = arg.FileName;
+ // make sure the global.json file that has been changed is the one we got when loading the project
+ if (Project.ParentSolution.ExtendedProperties [GlobalJsonPathExtendedPropertyName] is string globalJsonPath
+ && globalJsonPath.Equals (fileName, StringComparison.OrdinalIgnoreCase)) {
+ DetectSDK (restore: true);
+ }
}
+
}
protected override bool SupportsObject (WorkspaceObject item)
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/PackagesCommandHandler.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/PackagesCommandHandler.cs
index 8c3540eacd..be0378ce09 100644
--- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/PackagesCommandHandler.cs
+++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/PackagesCommandHandler.cs
@@ -56,38 +56,34 @@ namespace MonoDevelop.PackageManagement.Commands
protected DotNetProject GetSelectedDotNetProject ()
{
- return IdeApp.ProjectOperations.CurrentSelectedProject as DotNetProject;
- }
-
- protected bool SelectedDotNetProjectHasPackages ()
- {
- DotNetProject project = GetSelectedDotNetProject ();
- return (project != null) && project.HasPackages ();
+ return CurrentSelectedProject as DotNetProject;
}
protected bool IsDotNetSolutionSelected ()
{
- return IdeApp.ProjectOperations.CurrentSelectedSolution != null;
+ return CurrentSelectedSolution != null;
}
- protected bool SelectedDotNetSolutionHasPackages ()
- {
- Solution solution = IdeApp.ProjectOperations.CurrentSelectedSolution;
- if (solution == null) {
- return false;
+ protected bool CanRestoreSelectedDotNetProjectOrSolution ()
+ {
+ if (IsDotNetProjectSelected ()) {
+ return CanRestorePackagesForSelectedDotNetProject ();
+ } else if (IsDotNetSolutionSelected ()) {
+ return CanRestorePackagesForSelectedSolution ();
}
+ return false;
+ }
- return solution.HasAnyProjectWithPackages ();
+ protected bool CanRestorePackagesForSelectedDotNetProject ()
+ {
+ DotNetProject project = GetSelectedDotNetProject ();
+ return project?.CanRestorePackages () == true;
}
- protected bool SelectedDotNetProjectOrSolutionHasPackages ()
+ bool CanRestorePackagesForSelectedSolution ()
{
- if (IsDotNetProjectSelected ()) {
- return SelectedDotNetProjectHasPackages ();
- } else if (IsDotNetSolutionSelected ()) {
- return SelectedDotNetSolutionHasPackages ();
- }
- return false;
+ Solution solution = CurrentSelectedSolution;
+ return solution?.CanRestorePackages () == true;
}
protected Solution GetSelectedSolution ()
@@ -96,7 +92,7 @@ namespace MonoDevelop.PackageManagement.Commands
if (project != null) {
return project.ParentSolution;
}
- return IdeApp.ProjectOperations.CurrentSelectedSolution;
+ return CurrentSelectedSolution;
}
protected bool CanUpdatePackagesForSelectedDotNetProject ()
@@ -107,7 +103,7 @@ namespace MonoDevelop.PackageManagement.Commands
bool CanUpdatePackagesForSelectedDotNetSolution ()
{
- Solution solution = IdeApp.ProjectOperations.CurrentSelectedSolution;
+ Solution solution = CurrentSelectedSolution;
return solution?.CanUpdatePackages () == true;
}
@@ -120,5 +116,19 @@ namespace MonoDevelop.PackageManagement.Commands
}
return false;
}
+
+ /// <summary>
+ /// Used by unit tests to avoid having to initialize the IDE workspace.
+ /// </summary>
+ protected virtual Solution CurrentSelectedSolution {
+ get { return IdeApp.ProjectOperations.CurrentSelectedSolution; }
+ }
+
+ /// <summary>
+ /// Used by unit tests to avoid having to initialize the IDE workspace.
+ /// </summary>
+ protected virtual Project CurrentSelectedProject {
+ get { return IdeApp.ProjectOperations.CurrentSelectedProject; }
+ }
}
}
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/RestorePackagesHandler.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/RestorePackagesHandler.cs
index de29788d4b..0264cae53e 100644
--- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/RestorePackagesHandler.cs
+++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/RestorePackagesHandler.cs
@@ -42,7 +42,7 @@ namespace MonoDevelop.PackageManagement.Commands
protected override void Update (CommandInfo info)
{
- info.Enabled = SelectedDotNetProjectOrSolutionHasPackages ();
+ info.Enabled = CanRestoreSelectedDotNetProjectOrSolution ();
}
public static void Run (Solution solution)
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/RestorePackagesInProjectHandler.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/RestorePackagesInProjectHandler.cs
index 73731d3bc4..93dadeff7e 100644
--- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/RestorePackagesInProjectHandler.cs
+++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/RestorePackagesInProjectHandler.cs
@@ -40,7 +40,7 @@ namespace MonoDevelop.PackageManagement.Commands
protected override void Update (CommandInfo info)
{
- info.Enabled = SelectedDotNetProjectHasPackages ();
+ info.Enabled = CanRestorePackagesForSelectedDotNetProject ();
}
public static void Run (DotNetProject project)
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetAwareProject.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetAwareProject.cs
index abe4cce276..33cd30fbb5 100644
--- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetAwareProject.cs
+++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetAwareProject.cs
@@ -33,6 +33,11 @@ namespace MonoDevelop.PackageManagement.Tests.Helpers
{
class FakeNuGetAwareProject : DummyDotNetProject, INuGetAwareProject
{
+ public FakeNuGetAwareProject ()
+ {
+ Initialize (this);
+ }
+
public NuGetProject CreateNuGetProject ()
{
throw new NotImplementedException ();
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/TestableRestorePackagesHandler.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/TestableRestorePackagesHandler.cs
new file mode 100644
index 0000000000..dfb6272a16
--- /dev/null
+++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/TestableRestorePackagesHandler.cs
@@ -0,0 +1,54 @@
+//
+// TestableRestorePackagesHandler.cs
+//
+// Author:
+// Matt Ward <matt.ward@microsoft.com>
+//
+// Copyright (c) 2019 Microsoft
+//
+// 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 MonoDevelop.Components.Commands;
+using MonoDevelop.PackageManagement.Commands;
+using MonoDevelop.Projects;
+
+namespace MonoDevelop.PackageManagement.Tests.Helpers
+{
+ class TestableRestorePackagesHandler : RestorePackagesHandler
+ {
+ CommandInfo info = new CommandInfo ();
+ Project project;
+ Solution solution;
+
+ public bool Enabled {
+ get { return info.Enabled; }
+ }
+
+ public void RunUpdate (Solution solution, Project project)
+ {
+ this.solution = solution;
+ this.project = project;
+
+ base.Update (info);
+ }
+
+ protected override Project CurrentSelectedProject => project;
+ protected override Solution CurrentSelectedSolution => solution;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/TestableRestorePackagesInProjectHandler.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/TestableRestorePackagesInProjectHandler.cs
new file mode 100644
index 0000000000..64304cb624
--- /dev/null
+++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/TestableRestorePackagesInProjectHandler.cs
@@ -0,0 +1,54 @@
+//
+// TestableRestorePackagesInProjectHandler.cs
+//
+// Author:
+// Matt Ward <matt.ward@microsoft.com>
+//
+// Copyright (c) 2019 Microsoft
+//
+// 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 MonoDevelop.Components.Commands;
+using MonoDevelop.PackageManagement.Commands;
+using MonoDevelop.Projects;
+
+namespace MonoDevelop.PackageManagement.Tests.Helpers
+{
+ class TestableRestorePackagesInProjectHandler : RestorePackagesInProjectHandler
+ {
+ CommandInfo info = new CommandInfo ();
+ Project project;
+ Solution solution;
+
+ public bool Enabled {
+ get { return info.Enabled; }
+ }
+
+ public void RunUpdate (Solution solution, Project project)
+ {
+ this.solution = solution;
+ this.project = project;
+
+ base.Update (info);
+ }
+
+ protected override Project CurrentSelectedProject => project;
+ protected override Solution CurrentSelectedSolution => solution;
+ }
+}
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.csproj b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.csproj
index 25d8ffd69f..db41a064a4 100644
--- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.csproj
+++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.csproj
@@ -151,6 +151,9 @@
<Compile Include="MonoDevelop.PackageManagement.Tests\FullyQualifiedReferencePathTests.cs" />
<Compile Include="MonoDevelop.PackageManagement.Tests\MSBuildPackageSpecCreatorTests.cs" />
<Compile Include="MonoDevelop.PackageManagement.Tests\InstallPackageWithAvailableItemNameTests.cs" />
+ <Compile Include="MonoDevelop.PackageManagement.Tests\PackagesCommandHandlerTests.cs" />
+ <Compile Include="MonoDevelop.PackageManagement.Tests.Helpers\TestableRestorePackagesHandler.cs" />
+ <Compile Include="MonoDevelop.PackageManagement.Tests.Helpers\TestableRestorePackagesInProjectHandler.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\core\MonoDevelop.Core\MonoDevelop.Core.csproj">
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetProjectExtensionsTests.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetProjectExtensionsTests.cs
index 422d599e35..4843451775 100644
--- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetProjectExtensionsTests.cs
+++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetProjectExtensionsTests.cs
@@ -49,6 +49,12 @@ namespace MonoDevelop.PackageManagement.Tests
DotNetProjectExtensions.FileExists = existingFiles.Contains;
}
+ [TearDown]
+ public void TearDown ()
+ {
+ DotNetProjectExtensions.FileExists = File.Exists;
+ }
+
void CreateProject (string fileName, string projectName)
{
project = new FakeDotNetProject (fileName.ToNativePath ()) {
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/PackagesCommandHandlerTests.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/PackagesCommandHandlerTests.cs
new file mode 100644
index 0000000000..7cec48b14d
--- /dev/null
+++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/PackagesCommandHandlerTests.cs
@@ -0,0 +1,257 @@
+//
+// PackagesCommandHandlerTests.cs
+//
+// Author:
+// Matt Ward <matt.ward@microsoft.com>
+//
+// Copyright (c) 2019 Microsoft
+//
+// 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.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using MonoDevelop.Core;
+using MonoDevelop.PackageManagement.Tests.Helpers;
+using MonoDevelop.Projects;
+using NUnit.Framework;
+using UnitTests;
+
+namespace MonoDevelop.PackageManagement.Tests
+{
+ [TestFixture]
+ public class PackagesCommandHandlerTests : RestoreTestBase
+ {
+ TestableRestorePackagesHandler restorePackagesHandler;
+ TestableRestorePackagesInProjectHandler restorePackagesInProjectHandler;
+
+ [SetUp]
+ public void Init ()
+ {
+ restorePackagesHandler = new TestableRestorePackagesHandler ();
+ restorePackagesInProjectHandler = new TestableRestorePackagesInProjectHandler ();
+ }
+
+ [Test]
+ public async Task ProjectWithNoPackages ()
+ {
+ FilePath solutionFileName = Util.GetSampleProject ("csharp-console", "csharp-console.sln");
+
+ solution = (Solution)await Services.ProjectService.ReadWorkspaceItem (Util.GetMonitor (), solutionFileName);
+ var project = solution.GetAllDotNetProjects ().Single ();
+
+ // Project selected.
+ restorePackagesHandler.RunUpdate (solution, project);
+ Assert.IsFalse (restorePackagesHandler.Enabled);
+
+ restorePackagesInProjectHandler.RunUpdate (solution, project);
+ Assert.IsFalse (restorePackagesInProjectHandler.Enabled);
+
+ // Solution only selected
+ restorePackagesHandler.RunUpdate (solution, project: null);
+ Assert.IsFalse (restorePackagesHandler.Enabled);
+
+ restorePackagesInProjectHandler.RunUpdate (solution, project: null);
+ Assert.IsFalse (restorePackagesInProjectHandler.Enabled);
+ }
+
+ [Test]
+ public async Task ProjectWithPackagesConfig ()
+ {
+ FilePath solutionFileName = Util.GetSampleProject ("csharp-console", "csharp-console.sln");
+
+ solution = (Solution)await Services.ProjectService.ReadWorkspaceItem (Util.GetMonitor (), solutionFileName);
+ var project = solution.GetAllDotNetProjects ().Single ();
+
+ var packagesConfigFileName = project.BaseDirectory.Combine ("packages.config");
+ File.WriteAllText (packagesConfigFileName, "<packages />");
+
+ // Project selected.
+ restorePackagesHandler.RunUpdate (solution, project);
+ Assert.IsTrue (restorePackagesHandler.Enabled);
+
+ restorePackagesInProjectHandler.RunUpdate (solution, project);
+ Assert.IsTrue (restorePackagesInProjectHandler.Enabled);
+
+ // Solution only selected
+ restorePackagesHandler.RunUpdate (solution, project: null);
+ Assert.IsTrue (restorePackagesHandler.Enabled);
+
+ restorePackagesInProjectHandler.RunUpdate (solution, project: null);
+ Assert.IsFalse (restorePackagesInProjectHandler.Enabled, "Should be false - no project selected");
+ }
+
+ [Test]
+ public async Task SdkProject_PackageReference ()
+ {
+ FilePath solutionFileName = Util.GetSampleProject ("NetStandardXamarinForms", "NetStandardXamarinForms.sln");
+
+ solution = (Solution)await Services.ProjectService.ReadWorkspaceItem (Util.GetMonitor (), solutionFileName);
+ var project = solution.GetAllDotNetProjects ().Single ();
+
+ // Project selected.
+ restorePackagesHandler.RunUpdate (solution, project);
+ Assert.IsTrue (restorePackagesHandler.Enabled);
+
+ restorePackagesInProjectHandler.RunUpdate (solution, project);
+ Assert.IsTrue (restorePackagesInProjectHandler.Enabled);
+
+ // Solution only selected
+ restorePackagesHandler.RunUpdate (solution, project: null);
+ Assert.IsTrue (restorePackagesHandler.Enabled);
+
+ restorePackagesInProjectHandler.RunUpdate (solution, project: null);
+ Assert.IsFalse (restorePackagesInProjectHandler.Enabled, "Should be false - no project selected");
+ }
+
+ [Test]
+ public async Task SdkProject_NoPackageReferences ()
+ {
+ FilePath solutionFileName = Util.GetSampleProject ("netstandard-sdk", "netstandard-sdk.sln");
+
+ solution = (Solution)await Services.ProjectService.ReadWorkspaceItem (Util.GetMonitor (), solutionFileName);
+ var project = solution.GetAllDotNetProjects ().Single ();
+
+ // Project selected.
+ restorePackagesHandler.RunUpdate (solution, project);
+ Assert.IsTrue (restorePackagesHandler.Enabled);
+
+ restorePackagesInProjectHandler.RunUpdate (solution, project);
+ Assert.IsTrue (restorePackagesInProjectHandler.Enabled);
+
+ // Solution only selected
+ restorePackagesHandler.RunUpdate (solution, project: null);
+ Assert.IsTrue (restorePackagesHandler.Enabled);
+
+ restorePackagesInProjectHandler.RunUpdate (solution, project: null);
+ Assert.IsFalse (restorePackagesInProjectHandler.Enabled, "Should be false - no project selected");
+ }
+
+ [Test]
+ public async Task SdkProject_NetFramework472 ()
+ {
+ FilePath solutionFileName = Util.GetSampleProject ("netframework-sdk", "netframework-sdk.sln");
+
+ solution = (Solution)await Services.ProjectService.ReadWorkspaceItem (Util.GetMonitor (), solutionFileName);
+ var project = solution.GetAllDotNetProjects ().Single ();
+
+ // Project selected.
+ restorePackagesHandler.RunUpdate (solution, project);
+ Assert.IsTrue (restorePackagesHandler.Enabled);
+
+ restorePackagesInProjectHandler.RunUpdate (solution, project);
+ Assert.IsTrue (restorePackagesInProjectHandler.Enabled);
+
+ // Solution only selected
+ restorePackagesHandler.RunUpdate (solution, project: null);
+ Assert.IsTrue (restorePackagesHandler.Enabled);
+
+ restorePackagesInProjectHandler.RunUpdate (solution, project: null);
+ Assert.IsFalse (restorePackagesInProjectHandler.Enabled, "Should be false - no project selected");
+ }
+
+ [Test]
+ public async Task PackageReferenceProject_NonSdk ()
+ {
+ FilePath solutionFileName = Util.GetSampleProject ("package-reference", "package-reference.sln");
+
+ solution = (Solution)await Services.ProjectService.ReadWorkspaceItem (Util.GetMonitor (), solutionFileName);
+ var project = solution.GetAllDotNetProjects ().Single ();
+
+ // Project selected.
+ restorePackagesHandler.RunUpdate (solution, project);
+ Assert.IsTrue (restorePackagesHandler.Enabled);
+
+ restorePackagesInProjectHandler.RunUpdate (solution, project);
+ Assert.IsTrue (restorePackagesInProjectHandler.Enabled);
+
+ // Solution only selected
+ restorePackagesHandler.RunUpdate (solution, project: null);
+ Assert.IsTrue (restorePackagesHandler.Enabled);
+
+ restorePackagesInProjectHandler.RunUpdate (solution, project: null);
+ Assert.IsFalse (restorePackagesInProjectHandler.Enabled, "Should be false - no project selected");
+ }
+
+ [Test]
+ public async Task RestoreProjectStyle_NoPackageReferences ()
+ {
+ FilePath solutionFileName = Util.GetSampleProject ("RestoreStylePackageReference", "RestoreStylePackageReference.sln");
+
+ solution = (Solution)await Services.ProjectService.ReadWorkspaceItem (Util.GetMonitor (), solutionFileName);
+ var project = solution.GetAllDotNetProjects ().Single ();
+
+ // Project selected.
+ restorePackagesHandler.RunUpdate (solution, project);
+ Assert.IsTrue (restorePackagesHandler.Enabled);
+
+ restorePackagesInProjectHandler.RunUpdate (solution, project);
+ Assert.IsTrue (restorePackagesInProjectHandler.Enabled);
+
+ // Solution only selected
+ restorePackagesHandler.RunUpdate (solution, project: null);
+ Assert.IsTrue (restorePackagesHandler.Enabled);
+
+ restorePackagesInProjectHandler.RunUpdate (solution, project: null);
+ Assert.IsFalse (restorePackagesInProjectHandler.Enabled, "Should be false - no project selected");
+ }
+
+ [Test]
+ public void NuGetAwareProject ()
+ {
+ var project = new FakeNuGetAwareProject ();
+ var solution = new Solution ();
+ solution.RootFolder.AddItem (project);
+
+ // No packages in project.
+ project.HasPackagesReturnValue = false;
+
+ // Project selected.
+ restorePackagesHandler.RunUpdate (solution, project);
+ Assert.IsFalse (restorePackagesHandler.Enabled);
+
+ restorePackagesInProjectHandler.RunUpdate (solution, project);
+ Assert.IsFalse (restorePackagesInProjectHandler.Enabled);
+
+ // Solution only selected
+ restorePackagesHandler.RunUpdate (solution, project: null);
+ Assert.IsFalse (restorePackagesHandler.Enabled);
+
+ restorePackagesInProjectHandler.RunUpdate (solution, project: null);
+ Assert.IsFalse (restorePackagesInProjectHandler.Enabled, "Should be false - no project selected");
+
+ // Project has packages.
+ project.HasPackagesReturnValue = true;
+
+ // Project selected.
+ restorePackagesHandler.RunUpdate (solution, project);
+ Assert.IsTrue (restorePackagesHandler.Enabled);
+
+ restorePackagesInProjectHandler.RunUpdate (solution, project);
+ Assert.IsTrue (restorePackagesInProjectHandler.Enabled);
+
+ // Solution only selected
+ restorePackagesHandler.RunUpdate (solution, project: null);
+ Assert.IsTrue (restorePackagesHandler.Enabled);
+
+ restorePackagesInProjectHandler.RunUpdate (solution, project: null);
+ Assert.IsFalse (restorePackagesInProjectHandler.Enabled, "Should be false - no project selected");
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetProjectExtensions.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetProjectExtensions.cs
index dcc1d5a80b..1954713237 100644
--- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetProjectExtensions.cs
+++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetProjectExtensions.cs
@@ -312,5 +312,16 @@ namespace MonoDevelop.PackageManagement
return HasPackages (project.BaseDirectory, project.Name) || project.Items.OfType<ProjectPackageReference> ().Any ();
}
+
+ public static bool CanRestorePackages (this DotNetProject project)
+ {
+ var nugetAwareProject = project as INuGetAwareProject;
+ if (nugetAwareProject != null)
+ return nugetAwareProject.HasPackages ();
+
+ return HasPackages (project.BaseDirectory, project.Name) ||
+ DotNetCoreNuGetProject.CanCreate (project) ||
+ PackageReferenceNuGetProject.CanCreate (project);
+ }
}
}
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/SolutionExtensions.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/SolutionExtensions.cs
index d63b3831f6..717a1b1e2a 100644
--- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/SolutionExtensions.cs
+++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/SolutionExtensions.cs
@@ -48,16 +48,18 @@ namespace MonoDevelop.PackageManagement
.Where (project => project.HasPackages ());
}
- public static bool HasAnyProjectWithPackages (this Solution solution)
- {
- return solution.GetAllProjectsWithPackages ().Any ();
- }
-
public static bool CanUpdatePackages (this Solution solution)
{
return solution
.GetAllDotNetProjects ()
.Any (project => project.CanUpdatePackages ());
}
+
+ public static bool CanRestorePackages (this Solution solution)
+ {
+ return solution
+ .GetAllDotNetProjects ()
+ .Any (project => project.CanRestorePackages ());
+ }
}
}
diff --git a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs
index 6754d0b0ce..6fb760ace8 100644
--- a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs
+++ b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs
@@ -1957,7 +1957,7 @@ namespace Mono.TextEditor
}
}
- var metrics = new LineMetrics {
+ var metrics = new LineMetrics {
LineSegment = line,
Layout = layout,
@@ -1980,18 +1980,26 @@ namespace Mono.TextEditor
if (!marker.IsVisible)
continue;
- if (marker.DrawBackground (textEditor, cr, metrics)) {
- isSelectionDrawn |= (marker.Flags & TextLineMarkerFlags.DrawsSelection) == TextLineMarkerFlags.DrawsSelection;
+ try {
+ if (marker.DrawBackground (textEditor, cr, metrics)) {
+ isSelectionDrawn |= (marker.Flags & TextLineMarkerFlags.DrawsSelection) == TextLineMarkerFlags.DrawsSelection;
+ }
+ } catch (Exception e) {
+ LoggingService.LogInternalError ("Error while drawing backround marker " + marker, e);
}
}
var textSegmentMarkers = TextDocument.OrderTextSegmentMarkersByInsertion (Document.GetVisibleTextSegmentMarkersAt (line)).ToList ();
foreach (var marker in textSegmentMarkers) {
- if (layout.Layout != null)
+ if (layout.Layout == null)
+ continue;
+ try {
marker.DrawBackground (textEditor, cr, metrics, offset, offset + length);
+ } catch (Exception e) {
+ LoggingService.LogInternalError ("Error while drawing backround marker " + marker, e);
+ }
}
-
if (DecorateLineBg != null)
DecorateLineBg (cr, layout, offset, length, xPos, y, selectionStartOffset, selectionEndOffset);
@@ -2175,17 +2183,24 @@ namespace Mono.TextEditor
}
}
}
- foreach (TextLineMarker marker in textEditor.Document.GetMarkers (line)) {
- if (!marker.IsVisible)
+ foreach (var marker in textEditor.Document.GetMarkers (line)) {
+ if (!marker.IsVisible || layout.Layout == null)
continue;
-
- if (layout.Layout != null)
+ try {
marker.Draw (textEditor, cr, metrics);
+ } catch (Exception e) {
+ LoggingService.LogInternalError ("Error while drawing line marker " + marker, e);
+ }
}
foreach (var marker in textSegmentMarkers) {
- if (layout.Layout != null)
+ if (layout.Layout == null)
+ continue;
+ try {
marker.Draw (textEditor, cr, metrics, offset, offset + length);
+ } catch (Exception e) {
+ LoggingService.LogInternalError ("Error while drawing segment marker " + marker, e);
+ }
}
position += System.Math.Floor (layout.LastLineWidth);
diff --git a/main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/GitRepository.cs b/main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/GitRepository.cs
index 3b22615cab..301d8a6b92 100644
--- a/main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/GitRepository.cs
+++ b/main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/GitRepository.cs
@@ -107,8 +107,8 @@ namespace MonoDevelop.VersionControl.Git
{
if (scheduler == null) {
scheduler = new ConcurrentExclusiveSchedulerPair ();
- blockingOperationFactory = new TaskFactory (scheduler.ExclusiveScheduler);
- readingOperationFactory = new TaskFactory (scheduler.ConcurrentScheduler);
+ blockingOperationFactory = new TaskFactory (default, TaskCreationOptions.PreferFairness, TaskContinuationOptions.PreferFairness, scheduler.ExclusiveScheduler);
+ readingOperationFactory = new TaskFactory (default, TaskCreationOptions.PreferFairness, TaskContinuationOptions.PreferFairness, scheduler.ConcurrentScheduler);
}
}
@@ -431,10 +431,12 @@ namespace MonoDevelop.VersionControl.Git
var submoduleWriteTime = File.GetLastWriteTimeUtc (RootPath.Combine (".gitmodules"));
if (cachedSubmoduleTime != submoduleWriteTime) {
cachedSubmoduleTime = submoduleWriteTime;
- cachedSubmodules = RootRepository.Submodules.Select (s => {
+ lock (this) {
+ cachedSubmodules = RootRepository.Submodules.Select (s => {
var fp = new FilePath (Path.Combine (RootRepository.Info.WorkingDirectory, s.Path.Replace ('/', Path.DirectorySeparatorChar))).CanonicalPath;
return new Tuple<FilePath, LibGit2Sharp.Repository> (fp, new LibGit2Sharp.Repository (fp));
}).ToArray ();
+ }
}
return cachedSubmodules;
}
diff --git a/main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/GitSelectRevisionDialog.cs b/main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/GitSelectRevisionDialog.cs
index 3947f48909..50bf7e6136 100644
--- a/main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/GitSelectRevisionDialog.cs
+++ b/main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/GitSelectRevisionDialog.cs
@@ -105,7 +105,9 @@ namespace MonoDevelop.VersionControl.Git
};
revisionList.Columns.Add (shaColumn);
- Task.Factory.StartNew (async () => {
+ var token = cts.Token;
+
+ Task.Run (async () => {
const int sliceSize = 150;
var history = repo.GetHistory (repo.RootPath, null);
@@ -114,7 +116,7 @@ namespace MonoDevelop.VersionControl.Git
for (int i = 0; i < slices; ++i) {
await Runtime.RunInMainThread (() => {
for (int n = 0; n < sliceSize; ++n) {
- if (cts.IsCancellationRequested)
+ if (token.IsCancellationRequested)
return;
int row = revisionStore.AddRow ();
@@ -128,7 +130,7 @@ namespace MonoDevelop.VersionControl.Git
}
});
}
- }, cts.Token);
+ }, token).Ignore ();
revisionList.SelectionChanged += delegate {
CheckSensitive ();
diff --git a/main/src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl/Repository.cs b/main/src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl/Repository.cs
index 8ac398f2a8..7ec8059025 100644
--- a/main/src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl/Repository.cs
+++ b/main/src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl/Repository.cs
@@ -281,7 +281,7 @@ namespace MonoDevelop.VersionControl
RecursiveDirectoryInfoQuery rq;
bool query = false;
lock (queryLock) {
- rq = recursiveDirectoryQueryQueue.FirstOrDefault (q => q.Directory == path);
+ rq = recursiveDirectoryQueryQueue.FirstOrDefault (q => q.Directory == path || path.IsChildPathOf (q.Directory));
if (rq == null) {
query = true;
var mre = new ManualResetEvent (false);