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
parent526ae087002e5e8aba0c5430fea9142942f85635 (diff)
parentb19a7bf2d6a71057f0820de1c12b9a5faa7d9b53 (diff)
Merge remote-tracking branch 'origin/master' into release-8.2monodevelop-8.2.0.707
-rw-r--r--main/build/MacOSX/Makefile.am2
-rwxr-xr-xmain/build/MacOSX/make-dmg-bundle.sh34
-rw-r--r--main/build/MacOSX/monostub.mm6
m---------main/external/debugger-libs0
m---------main/external/vs-editor-api0
-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
-rw-r--r--main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/TextSegmentMarker.cs34
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetRuntime.cs15
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.Setup/UpdateChannel.cs2
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProject.cs2
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/SlnFileFormat.cs2
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs16
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SdkProjectExtension.cs9
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.DockNotebook/DockNotebookContainer.cs13
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/PObject.cs4
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResultWidget.cs14
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Shell/DefaultWorkbench.cs9
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopMetadataReference.cs6
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopMetadataReferenceManager.cs5
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.ProjectSystemHandler.cs4
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs33
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService_WorkspaceHandling.cs8
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/RootWorkspace.cs6
-rw-r--r--main/tests/test-projects/netframework-sdk/Class1.cs8
-rw-r--r--main/tests/test-projects/netframework-sdk/netframework-sdk.csproj7
-rw-r--r--main/tests/test-projects/netframework-sdk/netframework-sdk.sln17
-rw-r--r--main/tests/test-projects/package-reference/library/library.csproj36
-rw-r--r--main/tests/test-projects/package-reference/package-reference.sln17
-rw-r--r--version-checks2
73 files changed, 1248 insertions, 563 deletions
diff --git a/main/build/MacOSX/Makefile.am b/main/build/MacOSX/Makefile.am
index 37d22f0e65..e662ab92d5 100644
--- a/main/build/MacOSX/Makefile.am
+++ b/main/build/MacOSX/Makefile.am
@@ -12,7 +12,7 @@ EXTERNAL=../../external
MONOSTUB_STATIC_LINK=$(EXTERNAL)/Xamarin.Mac.registrar.full.a
if !RELEASE_BUILDS
-HYBRID_SUSPEND_ABORT=-DHYBRID_SUSPEND_ABORT
+HYBRID_SUSPEND_ABORT_DEBUG=-DHYBRID_SUSPEND_ABORT_DEBUG
endif
#SDK_PATH=$(shell xcrun --sdk macosx10.8 --show-sdk-path)
diff --git a/main/build/MacOSX/make-dmg-bundle.sh b/main/build/MacOSX/make-dmg-bundle.sh
index 1170152801..748aceaf4d 100755
--- a/main/build/MacOSX/make-dmg-bundle.sh
+++ b/main/build/MacOSX/make-dmg-bundle.sh
@@ -32,22 +32,9 @@ MOUNT_POINT="$VOLUME_NAME.mounted"
rm -f "$DMG_FILE"
rm -f "$DMG_FILE.master"
-# Compute an approximated image size in MB, and bloat by double
-# codesign adds a unknown amount of extra size requirements and there are some
-# files where the additional size required is even more "unknown". doubling
-# is a brute force approach, but doesn't really impact final distribution size
-# because the empty space is compressed to nothing.
-image_size=$(du -ck "$DMG_APP" | tail -n1 | cut -f1)
-image_size=$((($image_size *2) / 1000))
-
-echo "Creating disk image (${image_size}MB)..."
-hdiutil create "$DMG_FILE" -megabytes $image_size -volname "$VOLUME_NAME" -fs HFS+ -quiet || exit $?
-
-echo "Attaching to disk image..."
-hdiutil attach "$DMG_FILE" -readwrite -noautoopen -mountpoint "$MOUNT_POINT" -quiet || exit $?
-
echo "Populating image..."
+mkdir -p "$MOUNT_POINT/.background"
# this used to be mv, but we need to preserve the bundle directory to do more checks on the contents
# such as compatibility-check
ditto "$DMG_APP" "$MOUNT_POINT/$DMG_APP"
@@ -74,20 +61,19 @@ if [ -e VolumeIcon.icns ] ; then
fi
SetFile -a C "$MOUNT_POINT"
-echo "Detaching from disk image..."
-hdiutil detach "$MOUNT_POINT" -quiet || exit $?
-
-mv "$DMG_FILE" "$DMG_FILE.master"
+# Compute an approximated image size in MB, and bloat by double
+# codesign adds a unknown amount of extra size requirements and there are some
+# files where the additional size required is even more "unknown". doubling
+# is a brute force approach, but doesn't really impact final distribution size
+# because the empty space is compressed to nothing.
+image_size=$(du -ck "$DMG_APP" | tail -n1 | cut -f1)
+image_size=$((($image_size *2) / 1000))
-echo "Creating distributable image..."
-hdiutil convert -quiet -format UDBZ -o "$DMG_FILE" "$DMG_FILE.master" || exit $?
+echo "Creating disk image (${image_size}MB)..."
+hdiutil create -srcfolder "$MOUNT_POINT" -megabytes $image_size -ov "$DMG_FILE" -volname "$VOLUME_NAME" -fs HFS+ -format UDBZ || exit $?
echo "Built disk image $DMG_FILE"
-if [ ! "x$1" = "x-m" ]; then
-rm "$DMG_FILE.master"
-fi
-
rm -rf "$MOUNT_POINT"
echo "Done."
diff --git a/main/build/MacOSX/monostub.mm b/main/build/MacOSX/monostub.mm
index d6bd254556..600a161d2e 100644
--- a/main/build/MacOSX/monostub.mm
+++ b/main/build/MacOSX/monostub.mm
@@ -277,13 +277,11 @@ main (int argc, char **argv)
// prevents the code from running correctly, so unset it here.
// See https://devdiv.visualstudio.com/DevDiv/_workitems/edit/896438
unsetenv ("MONO_REGISTRY_PATH");
-#if HYBRID_SUSPEND_ABORT
+
+#if HYBRID_SUSPEND_ABORT_DEBUG
setenv ("MONO_SLEEP_ABORT_LIMIT", "5000", 0);
#endif
- // To be removed: https://github.com/mono/monodevelop/issues/6326
- setenv ("MONO_THREADS_SUSPEND", "preemptive", 0);
-
setenv ("MONO_GC_PARAMS", "major=marksweep-conc,nursery-size=8m", 0);
void *libmono = dlopen ("libmonosgen-2.0.dylib", RTLD_LAZY);
diff --git a/main/external/debugger-libs b/main/external/debugger-libs
-Subproject 7bca91a582a8161b0765e9121abb61b2aa28541
+Subproject 0ab6b6eb9331f4dcbda476d5652584ed8feeac2
diff --git a/main/external/vs-editor-api b/main/external/vs-editor-api
-Subproject 5bd38ee6dcf9c128fe2e890711b1e1d2030cf99
+Subproject 1bc2074f35ff1df5500d5b9d86de4f4417206e4
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);
diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/TextSegmentMarker.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/TextSegmentMarker.cs
index b53bc41e2f..2a688e976e 100644
--- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/TextSegmentMarker.cs
+++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/TextSegmentMarker.cs
@@ -1,4 +1,4 @@
-//
+//
// TextSegmentMarker.cs
//
// Author:
@@ -152,18 +152,26 @@ namespace Mono.TextEditor
int /*lineNr,*/ x_pos;
uint curIndex = 0;
uint byteIndex = 0;
- uint idx = (uint)Math.Min (Math.Max (0, start - startOffset), metrics.Layout.Text.Length - 1);
- metrics.Layout.TranslateToUTF8Index (idx, ref curIndex, ref byteIndex);
-
- x_pos = layout.IndexToPos (System.Math.Max (0, (int)byteIndex)).X;
- @from = startXPos + (int)(x_pos / Pango.Scale.PangoScale);
-
- idx = (uint)Math.Min (Math.Max (0, end - startOffset), metrics.Layout.Text.Length - 1);
- metrics.Layout.TranslateToUTF8Index (idx, ref curIndex, ref byteIndex);
-
- x_pos = layout.IndexToPos (System.Math.Max (0, (int)byteIndex)).X;
-
- to = startXPos + (int)(x_pos / Pango.Scale.PangoScale);
+
+ var textLength = metrics.Layout.Text.Length;
+ if (textLength > 0) {
+ uint idx = (uint)Math.Min (Math.Max (0, start - startOffset), textLength - 1);
+ metrics.Layout.TranslateToUTF8Index (idx, ref curIndex, ref byteIndex);
+
+ x_pos = layout.IndexToPos (System.Math.Max (0, (int)byteIndex)).X;
+ @from = startXPos + (int)(x_pos / Pango.Scale.PangoScale);
+
+ idx = (uint)Math.Min (Math.Max (0, end - startOffset), textLength - 1);
+ metrics.Layout.TranslateToUTF8Index (idx, ref curIndex, ref byteIndex);
+
+ x_pos = layout.IndexToPos (System.Math.Max (0, (int)byteIndex)).X;
+
+ to = startXPos + (int)(x_pos / Pango.Scale.PangoScale);
+ } else {
+ @from = startXPos;
+ to = startXPos + editor.TextViewMargin.CharWidth;
+ }
+
var line = editor.GetLineByOffset (endOffset);
if (markerEnd > endOffset || @from == to) {
to += editor.TextViewMargin.CharWidth;
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetRuntime.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetRuntime.cs
index 6ec1e3b665..d4f6439cf8 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetRuntime.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetRuntime.cs
@@ -37,6 +37,7 @@ using MonoDevelop.Core.AddIns;
using MonoDevelop.Core.Execution;
using MonoDevelop.Core.Instrumentation;
using System.Runtime.CompilerServices;
+using System.Collections.Immutable;
namespace MonoDevelop.Core.Assemblies
{
@@ -268,14 +269,19 @@ namespace MonoDevelop.Core.Assemblies
return GetBackend (fx).GetFrameworkFolders ();
}
+ // You can't really delete Facade assemblies while running the app.
+ static ImmutableDictionary<TargetFramework, string []> cachedFacadeAssemblies = ImmutableDictionary<TargetFramework, string []>.Empty;
public IEnumerable<string> FindFacadeAssembliesForPCL (TargetFramework tx)
{
+ if (cachedFacadeAssemblies.TryGetValue (tx, out var value))
+ return value;
+
foreach (var folder in GetFrameworkFolders (tx)) {
var facades = Path.Combine (folder, "Facades");
if (!Directory.Exists (facades))
continue;
- return Directory.EnumerateFiles (facades, "*.dll");
+ return ImmutableInterlocked.GetOrAdd (ref cachedFacadeAssemblies, tx, (_, dir) => Directory.GetFiles (dir, "*.dll"), facades);
}
//MonoDroid is special case because it's keeping Fascades in v1.0 folder
@@ -283,12 +289,13 @@ namespace MonoDevelop.Core.Assemblies
var frameworkFolder = GetFrameworkFolders (tx).FirstOrDefault ();
if (frameworkFolder != null) {
var facades = Path.Combine (Path.Combine (Path.GetDirectoryName (frameworkFolder), "v1.0"), "Facades");
- if (Directory.Exists (facades))
- return Directory.EnumerateFiles (facades, "*.dll");
+ if (Directory.Exists (facades)) {
+ return ImmutableInterlocked.GetOrAdd (ref cachedFacadeAssemblies, tx, (_, dir) => Directory.GetFiles (dir, "*.dll"), facades);
+ }
}
}
- return new string[0];
+ return ImmutableInterlocked.GetOrAdd (ref cachedFacadeAssemblies, tx, Array.Empty<string> ());
}
/// <summary>
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Setup/UpdateChannel.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Setup/UpdateChannel.cs
index 0b0cee17f1..c09a12c469 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Setup/UpdateChannel.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Setup/UpdateChannel.cs
@@ -116,7 +116,7 @@ namespace MonoDevelop.Core.Setup
public override int GetHashCode ()
{
- return Idx;
+ return Id.GetHashCode();
}
public override string ToString ()
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProject.cs
index fbf568f9d1..1f92b20b4f 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProject.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProject.cs
@@ -207,7 +207,7 @@ namespace MonoDevelop.Projects.MSBuild
public static Task<MSBuildProject> LoadAsync (string file)
{
- return Task<MSBuildProject>.Factory.StartNew (delegate {
+ return Task.Run (delegate {
var p = new MSBuildProject ();
p.Load (file);
return p;
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/SlnFileFormat.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/SlnFileFormat.cs
index 536216a261..742edb3d99 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/SlnFileFormat.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/SlnFileFormat.cs
@@ -381,7 +381,7 @@ namespace MonoDevelop.Projects.MSBuild
var projectLoadMonitor = monitor as ProjectLoadProgressMonitor;
if (projectLoadMonitor != null)
projectLoadMonitor.CurrentSolution = sol;
- await Task.Factory.StartNew (() => {
+ await Task.Run (() => {
sol.ReadSolution (monitor);
});
} catch (Exception ex) {
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs
index 298d2e8f3f..cf85618ebe 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs
@@ -914,11 +914,11 @@ namespace MonoDevelop.Projects
internal protected virtual async Task<List<AssemblyReference>> OnGetReferencedAssemblies (ConfigurationSelector configuration)
{
- List<AssemblyReference> result = new List<AssemblyReference> ();
+ var result = new List<AssemblyReference> ();
if (MSBuildProject.UseMSBuildEngine) {
// Get the references list from the msbuild project
using (Counters.ResolveMSBuildReferencesTimer.BeginTiming (GetProjectEventMetadata (configuration)))
- result.AddRange (await RunResolveAssemblyReferencesTarget (configuration));
+ result.AddRange (await RunResolveAssemblyReferencesTarget (configuration).ConfigureAwait (false));
} else {
foreach (ProjectReference pref in References) {
if (pref.ReferenceType != ReferenceType.Project) {
@@ -979,7 +979,7 @@ namespace MonoDevelop.Projects
} else {
fullPath = Path.GetFullPath (refFilename.FilePath);
}
- if (await SystemAssemblyService.RequiresFacadeAssembliesAsync (fullPath)) {
+ if (await SystemAssemblyService.RequiresFacadeAssembliesAsync (fullPath).ConfigureAwait (false)) {
addFacadeAssemblies = true;
break;
}
@@ -987,7 +987,7 @@ namespace MonoDevelop.Projects
}
if (addFacadeAssemblies) {
- var facades = await ProjectExtension.OnGetFacadeAssemblies ();
+ var facades = await ProjectExtension.OnGetFacadeAssemblies ().ConfigureAwait (false);
if (facades != null) {
foreach (var facade in facades) {
if (!result.Contains (facade))
@@ -1022,15 +1022,11 @@ namespace MonoDevelop.Projects
var property = new MSBuildPropertyEvaluated (null, "ResolvedFrom", resolvedFrom, resolvedFrom);
sharedProperties.SetProperty (property.Name, property);
- List<AssemblyReference> result = null;
var runtime = TargetRuntime ?? Runtime.SystemAssemblyService.DefaultRuntime;
var facades = runtime.FindFacadeAssembliesForPCL (TargetFramework);
- foreach (var facade in facades) {
- if (!File.Exists (facade))
- continue;
- if (result == null)
- result = new List<AssemblyReference> ();
+ var result = facades is ICollection<string> collection ? new List<AssemblyReference> (collection.Count) : new List<AssemblyReference> ();
+ foreach (var facade in facades) {
var ar = new AssemblyReference (facade, sharedProperties);
result.Add (ar);
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SdkProjectExtension.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SdkProjectExtension.cs
index e2838d0ed6..e7514fe8f1 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SdkProjectExtension.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SdkProjectExtension.cs
@@ -274,7 +274,7 @@ namespace MonoDevelop.Projects
{
var references = new List<AssemblyReference> ();
- var traversedProjects = new HashSet<string> ();
+ var traversedProjects = new HashSet<string> (StringComparer.OrdinalIgnoreCase);
traversedProjects.Add (Project.ItemId);
await GetTransitiveAssemblyReferences (traversedProjects, references, configuration, true, token);
@@ -302,7 +302,7 @@ namespace MonoDevelop.Projects
bool includeNonProjectReferences,
System.Threading.CancellationToken token)
{
- foreach (var reference in await base.OnGetReferences (configuration, token)) {
+ foreach (var reference in await base.OnGetReferences (configuration, token).ConfigureAwait (false)) {
if (!reference.IsProjectReference) {
if (includeNonProjectReferences) {
references.Add (reference);
@@ -322,15 +322,14 @@ namespace MonoDevelop.Projects
if (project == null)
continue;
- if (traversedProjects.Contains (project.ItemId))
+ if (!traversedProjects.Add (project.ItemId))
continue;
references.Add (reference);
- traversedProjects.Add (project.ItemId);
var extension = project.AsFlavor<SdkProjectExtension> ();
if (extension != null)
- await extension.GetTransitiveAssemblyReferences (traversedProjects, references, configuration, false, token);
+ await extension.GetTransitiveAssemblyReferences (traversedProjects, references, configuration, false, token).ConfigureAwait (false);
}
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.DockNotebook/DockNotebookContainer.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.DockNotebook/DockNotebookContainer.cs
index 5de2ec2472..71019c3cfc 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.DockNotebook/DockNotebookContainer.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.DockNotebook/DockNotebookContainer.cs
@@ -224,10 +224,19 @@ namespace MonoDevelop.Components.DockNotebook
return newNotebook;
}
+ static HPaned CreatePaned ()
+ {
+ // FIXME: Bug #910879: HPanedThin is not functional with the new editor,
+ // fall-back to the regular Gtk paned until we find the right solution
+ if (Ide.Editor.DefaultSourceEditorOptions.Instance.EnableNewEditor)
+ return new HPaned ();
+ return new HPanedThin { GrabAreaSize = 6 };
+ }
+
public DockNotebook InsertLeft (SdiWorkspaceWindow window)
{
return Insert (window, container => {
- var box = new HPanedThin { GrabAreaSize = 6 };
+ var box = CreatePaned ();
var new_container = new DockNotebookContainer (tabControl);
box.Pack1 (container, true, true);
@@ -239,7 +248,7 @@ namespace MonoDevelop.Components.DockNotebook
public DockNotebook InsertRight (SdiWorkspaceWindow window)
{
return Insert (window, container => {
- var box = new HPanedThin () { GrabAreaSize = 6 };
+ var box = CreatePaned ();
var new_container = new DockNotebookContainer (tabControl);
box.Pack1 (new_container, true, true);
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/PObject.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/PObject.cs
index b4616c511c..74bddf2a75 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/PObject.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/PObject.cs
@@ -330,7 +330,7 @@ namespace MonoDevelop.Ide.Editor.Highlighting
public Task SaveAsync (string filename, bool atomic = false, bool binary = false)
{
- return Task.Factory.StartNew (() => Save (filename, atomic, binary));
+ return Task.Run (() => Save (filename, atomic, binary));
}
public void Save (string filename, bool atomic = false, bool binary = false)
@@ -675,7 +675,7 @@ namespace MonoDevelop.Ide.Editor.Highlighting
public static Task<PDictionary> FromFileAsync (string fileName)
{
- return Task<PDictionary>.Factory.StartNew (() => {
+ return Task.Run (() => {
bool isBinary;
return FromFile (fileName, out isBinary);
});
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResultWidget.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResultWidget.cs
index 062551c243..c183d688ea 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResultWidget.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResultWidget.cs
@@ -630,14 +630,18 @@ namespace MonoDevelop.Ide.FindInFiles
var sb = new StringBuilder ();
foreach (TreePath p in treeviewSearchResults.Selection.GetSelectedRows (out model)) {
TreeIter iter;
- if (!model.GetIter (out iter, p))
+ if (!model.GetIter (out iter, p)) {
continue;
+ }
var result = store.GetValue (iter, SearchResultColumn) as SearchResult;
- if (result == null)
+ if (result == null) {
continue;
-
- sb.AppendFormat (result.GetCopyData (this));
- sb.AppendLine ();
+ }
+ try {
+ sb.AppendLine (result.GetCopyData (this));
+ } catch (Exception e) {
+ LoggingService.LogInternalError ("Error while getting copy data from search results", e);
+ }
}
Clipboard clipboard = Clipboard.Get (Atom.Intern ("CLIPBOARD", false));
clipboard.Text = sb.ToString ();
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Shell/DefaultWorkbench.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Shell/DefaultWorkbench.cs
index 94fd3b1208..8ee60288a4 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Shell/DefaultWorkbench.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Shell/DefaultWorkbench.cs
@@ -655,8 +655,13 @@ namespace MonoDevelop.Ide.Gui
Remove (rootWidget);
foreach (PadCodon content in PadContentCollection) {
- if (content.Initialized)
- content.PadContent.Dispose ();
+ if (content.Initialized) {
+ try {
+ content.PadContent.Dispose ();
+ } catch (Exception ex) {
+ LoggingService.LogInternalError ("Failed to dispose pad " + content.PadId, ex);
+ }
+ }
}
rootWidget.Destroy ();
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopMetadataReference.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopMetadataReference.cs
index 6dc0d60440..e38bcb05ce 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopMetadataReference.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopMetadataReference.cs
@@ -32,7 +32,7 @@ namespace MonoDevelop.Ide.TypeSystem
_provider = provider;
_properties = properties;
- FileWatcherService.WatchDirectories (this, new [] { FilePath.ParentDirectory });
+ FileWatcherService.WatchDirectories (this, new [] { FilePath.ParentDirectory }).Ignore ();
FileService.FileChanged += OnUpdatedOnDisk;
}
@@ -50,9 +50,9 @@ namespace MonoDevelop.Ide.TypeSystem
void OnUpdatedOnDisk (object sender, FileEventArgs e)
{
- var args = new MetadataReferenceUpdatedEventArgs (this);
foreach (var file in e) {
if (file.FileName == FilePath) {
+ var args = new MetadataReferenceUpdatedEventArgs (this);
SnapshotUpdated?.Invoke (this, args);
return;
}
@@ -62,7 +62,7 @@ namespace MonoDevelop.Ide.TypeSystem
public void Dispose ()
{
FileService.FileChanged -= OnUpdatedOnDisk;
- FileWatcherService.WatchDirectories (this, null);
+ FileWatcherService.WatchDirectories (this, null).Ignore ();
}
internal void UpdateSnapshot () => _currentSnapshot = new Snapshot (_provider, Properties, FilePath);
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopMetadataReferenceManager.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopMetadataReferenceManager.cs
index 60b644660c..4a9b92eaa0 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopMetadataReferenceManager.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopMetadataReferenceManager.cs
@@ -217,8 +217,11 @@ namespace MonoDevelop.Ide.TypeSystem
public void ClearCache ()
{
- _metadataCache.ClearCache();
+ // Clear the reference cache before the metadata cache
+ // as the FileWatcher updates can technically trigger while the metadata cache
+ // is being cleared, avoiding unnecessary work and possible items not being invalidated.
_metadataReferenceCache.ClearCache ();
+ _metadataCache.ClearCache();
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.ProjectSystemHandler.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.ProjectSystemHandler.cs
index 2e129b53b2..7d05f88336 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.ProjectSystemHandler.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.ProjectSystemHandler.cs
@@ -220,7 +220,7 @@ namespace MonoDevelop.Ide.TypeSystem
var tp = LoadProject (proj, token, null, null).ContinueWith (t => {
if (!t.IsCanceled)
projects.Add (t.Result);
- });
+ }, TaskContinuationOptions.ExecuteSynchronously);
allTasks.Add (tp);
}
@@ -250,7 +250,7 @@ namespace MonoDevelop.Ide.TypeSystem
var tp = LoadProject (proj, token, null, cacheInfo).ContinueWith (t => {
if (!t.IsCanceled)
projects.Add (t.Result);
- });
+ }, TaskContinuationOptions.ExecuteSynchronously);
allTasks.Add (tp);
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs
index e74f295005..aba2c748c8 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs
@@ -450,7 +450,7 @@ namespace MonoDevelop.Ide.TypeSystem
{
try {
BeginLoad ();
- return await InternalLoadSolution (cancellationToken);
+ return await InternalLoadSolution (cancellationToken).ConfigureAwait (false);
} finally {
EndLoad ();
}
@@ -496,13 +496,13 @@ namespace MonoDevelop.Ide.TypeSystem
if (!CurrentSolution.ContainsProject (projectInfo.Id)) {
// Cache did not contain project so add it to the solution.
OnProjectAdded (projectInfo);
- }
-
- lock (projectModifyLock) {
- projectInfo = AddVirtualDocuments (projectInfo);
- OnProjectReloaded (projectInfo);
+ } else {
+ lock (projectModifyLock) {
+ projectInfo = AddVirtualDocuments (projectInfo);
+ OnProjectReloaded (projectInfo);
+ }
}
- await Runtime.RunInMainThread (IdeServices.TypeSystemService.UpdateRegisteredOpenDocuments);
+ await Runtime.RunInMainThread (IdeServices.TypeSystemService.UpdateRegisteredOpenDocuments).ConfigureAwait (false);
}
} catch (Exception ex) {
LoggingService.LogInternalError (ex);
@@ -565,10 +565,21 @@ namespace MonoDevelop.Ide.TypeSystem
if (mdProject == null)
return;
- var task = OpenDocumentWithTextViewAsync (doc, mdProject, activate);
- // Can't wait for the task to finish synchronously since doing so would deadlock the UI thread.
- while (!task.IsCompleted) {
- DispatchService.RunPendingEvents (30);
+ // This method can be called by Roslyn or the editor in a context which is not the GTK UI context
+ // that MonoDevelop uses. In that case, before starting async an operation that may queue
+ // task continuations into the current context, we switch to the GTK context, so that
+ // whatever is queued will be dispatched when we run RunPendingEvents.
+
+ var oldContext = SynchronizationContext.Current;
+ try {
+ SynchronizationContext.SetSynchronizationContext (Runtime.MainSynchronizationContext);
+ var task = OpenDocumentWithTextViewAsync (doc, mdProject, activate);
+ // Can't wait for the task to finish synchronously since doing so would deadlock the UI thread.
+ while (!task.IsCompleted) {
+ DispatchService.RunPendingEvents (30);
+ }
+ } finally {
+ SynchronizationContext.SetSynchronizationContext (oldContext);
}
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService_WorkspaceHandling.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService_WorkspaceHandling.cs
index db503d90ec..a9a6c33112 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService_WorkspaceHandling.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService_WorkspaceHandling.cs
@@ -127,7 +127,7 @@ namespace MonoDevelop.Ide.TypeSystem
{
using (Counters.ParserService.WorkspaceItemLoaded.BeginTiming ()) {
var wsList = new List<MonoDevelopWorkspace> ();
- await CreateWorkspaces (item, wsList);
+ await CreateWorkspaces (item, wsList).ConfigureAwait (false);
//If we want BeginTiming to work correctly we need to `await`
await InternalLoad (wsList, progressMonitor, cancellationToken).ConfigureAwait (false);
return wsList;
@@ -138,12 +138,12 @@ namespace MonoDevelop.Ide.TypeSystem
{
if (item is MonoDevelop.Projects.Workspace ws) {
foreach (var wsItem in ws.Items)
- await CreateWorkspaces (wsItem, result);
+ await CreateWorkspaces (wsItem, result).ConfigureAwait (false);
ws.ItemAdded += OnWorkspaceItemAdded;
ws.ItemRemoved += OnWorkspaceItemRemoved;
} else if (item is MonoDevelop.Projects.Solution solution) {
var workspace = new MonoDevelopWorkspace (compositionManager.HostServices, solution, this);
- await workspace.Initialize ();
+ await workspace.Initialize ().ConfigureAwait (false);
lock (workspaceLock)
workspaces = workspaces.Add (workspace);
solution.SolutionItemAdded += OnSolutionItemAdded;
@@ -617,7 +617,7 @@ namespace MonoDevelop.Ide.TypeSystem
// update documents
if (documentManager != null) {
foreach (var openDocument in documentManager.Documents)
- openDocument.DocumentContext.ReparseDocument ();
+ openDocument.DocumentContext?.ReparseDocument ();
}
}
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/RootWorkspace.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/RootWorkspace.cs
index be6bb6de87..be125d5834 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/RootWorkspace.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/RootWorkspace.cs
@@ -1207,11 +1207,11 @@ namespace MonoDevelop.Ide
async Task LoadWorkspaceTypeSystem (WorkspaceItem item)
{
try {
- var typeSystem = await serviceProvider.GetService<TypeSystemService> ();
- await typeSystem.Load (item, null);
+ var typeSystem = await serviceProvider.GetService<TypeSystemService> ().ConfigureAwait (false);
+ await typeSystem.Load (item, null).ConfigureAwait (false);
} catch (Exception ex) {
LoggingService.LogError ("Could not load parser database.", ex);
- };
+ }
}
internal void NotifyItemRemoved (WorkspaceItem item)
diff --git a/main/tests/test-projects/netframework-sdk/Class1.cs b/main/tests/test-projects/netframework-sdk/Class1.cs
new file mode 100644
index 0000000000..b9a6178638
--- /dev/null
+++ b/main/tests/test-projects/netframework-sdk/Class1.cs
@@ -0,0 +1,8 @@
+using System;
+
+namespace netstandard_sdk
+{
+ public class Class1
+ {
+ }
+}
diff --git a/main/tests/test-projects/netframework-sdk/netframework-sdk.csproj b/main/tests/test-projects/netframework-sdk/netframework-sdk.csproj
new file mode 100644
index 0000000000..424d2a40e5
--- /dev/null
+++ b/main/tests/test-projects/netframework-sdk/netframework-sdk.csproj
@@ -0,0 +1,7 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>net472</TargetFramework>
+ </PropertyGroup>
+
+</Project>
diff --git a/main/tests/test-projects/netframework-sdk/netframework-sdk.sln b/main/tests/test-projects/netframework-sdk/netframework-sdk.sln
new file mode 100644
index 0000000000..41ef1571b0
--- /dev/null
+++ b/main/tests/test-projects/netframework-sdk/netframework-sdk.sln
@@ -0,0 +1,17 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "netframework-sdk", "netframework-sdk.csproj", "{5B443F8D-6C84-443F-A395-5429E8F4A47D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5B443F8D-6C84-443F-A395-5429E8F4A47D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5B443F8D-6C84-443F-A395-5429E8F4A47D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5B443F8D-6C84-443F-A395-5429E8F4A47D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5B443F8D-6C84-443F-A395-5429E8F4A47D}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/main/tests/test-projects/package-reference/library/library.csproj b/main/tests/test-projects/package-reference/library/library.csproj
new file mode 100644
index 0000000000..24a78212d5
--- /dev/null
+++ b/main/tests/test-projects/package-reference/library/library.csproj
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{4E1821DD-EE60-48C1-8552-05B2793263DC}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <RootNamespace>LibraryProject</RootNamespace>
+ <AssemblyName>LibraryProject</AssemblyName>
+ <TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug</OutputPath>
+ <DefineConstants>DEBUG;</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <ConsolePause>false</ConsolePause>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <ConsolePause>false</ConsolePause>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ </ItemGroup>
+ <ItemGroup>
+ <PackageReference Include="Xamarin.Forms" Version="3.0.0.482510" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/main/tests/test-projects/package-reference/package-reference.sln b/main/tests/test-projects/package-reference/package-reference.sln
new file mode 100644
index 0000000000..91c3b1c9e1
--- /dev/null
+++ b/main/tests/test-projects/package-reference/package-reference.sln
@@ -0,0 +1,17 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "library", "library\library.csproj", "{4E1821DD-EE60-48C1-8552-05B2793263DC}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4E1821DD-EE60-48C1-8552-05B2793263DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4E1821DD-EE60-48C1-8552-05B2793263DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4E1821DD-EE60-48C1-8552-05B2793263DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4E1821DD-EE60-48C1-8552-05B2793263DC}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/version-checks b/version-checks
index a674796ebe..bcbb12d0ed 100644
--- a/version-checks
+++ b/version-checks
@@ -17,7 +17,7 @@ DEP[0]=md-addins
DEP_NAME[0]=MDADDINS
DEP_PATH[0]=${top_srcdir}/../md-addins
DEP_MODULE[0]=git@github.com:xamarin/md-addins.git
-DEP_NEEDED_VERSION[0]=6f2cfb80fed85d03eb75a2e74abea5ef9b59b89c
+DEP_NEEDED_VERSION[0]=42c8a0564da96b5b187649617735c87be56c5644
DEP_BRANCH_AND_REMOTE[0]="release-8.2 origin/release-8.2"
# heap-shot