diff options
Diffstat (limited to 'main')
38 files changed, 541 insertions, 210 deletions
diff --git a/main/external/vs-editor-api b/main/external/vs-editor-api -Subproject 0306a5f676a0fbf184328aa932abe37a4923af1 +Subproject b7084eed75e9ed72b6c594624b2927ffba28cd7 diff --git a/main/msbuild/RoslynVersion.props b/main/msbuild/RoslynVersion.props index ed342702ac..e1f669a22c 100644 --- a/main/msbuild/RoslynVersion.props +++ b/main/msbuild/RoslynVersion.props @@ -1,5 +1,5 @@ <Project> <PropertyGroup> - <NuGetVersionRoslyn>3.4.0-beta3-19518-02</NuGetVersionRoslyn> + <NuGetVersionRoslyn>3.4.0-beta4-19556-02</NuGetVersionRoslyn> </PropertyGroup> </Project> diff --git a/main/src/addins/MacPlatform/Dialogs/MacOpenFileDialogHandler.cs b/main/src/addins/MacPlatform/Dialogs/MacOpenFileDialogHandler.cs index fa0d0d2b3b..35ee7fff1f 100644 --- a/main/src/addins/MacPlatform/Dialogs/MacOpenFileDialogHandler.cs +++ b/main/src/addins/MacPlatform/Dialogs/MacOpenFileDialogHandler.cs @@ -73,7 +73,7 @@ namespace MonoDevelop.MacIntegration public bool Run (OpenFileDialogData data) { - var panelClosedSource = MacSystemInformation.OsVersion < MacSystemInformation.Catalina ? new CancellationTokenSource () : null; + using var panelClosedSource = new CancellationTokenSource (); try { using (var panel = CreatePanel (data, out var state)) { bool pathAlreadySet = false; @@ -119,11 +119,11 @@ namespace MonoDevelop.MacIntegration // TODO: support for data.CenterToParent, we could use sheeting. if (panel.RunModal () == 0 && !pathAlreadySet) { - panelClosedSource?.Cancel (); + panelClosedSource.Cancel (); IdeServices.DesktopService.FocusWindow (parent); return false; } - panelClosedSource?.Cancel (); + panelClosedSource.Cancel (); if (!pathAlreadySet) data.SelectedFiles = MacSelectFileDialogHandler.GetSelectedFiles (panel); @@ -141,8 +141,6 @@ namespace MonoDevelop.MacIntegration } } catch (Exception ex) { LoggingService.LogInternalError ("Error in Open File dialog", ex); - } finally { - panelClosedSource?.Dispose (); } return true; } diff --git a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Commands/ScaffoldCommandHandler.cs b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Commands/ScaffoldCommandHandler.cs index e7a6b9f987..2124ba57d3 100644 --- a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Commands/ScaffoldCommandHandler.cs +++ b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Commands/ScaffoldCommandHandler.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using MonoDevelop.AspNetCore.Scaffolding; using MonoDevelop.Components.Commands; using MonoDevelop.Ide; diff --git a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Dialogs/PublishToFolderDialog.cs b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Dialogs/PublishToFolderDialog.cs index 5e4124b5be..e1b8ac0a63 100644 --- a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Dialogs/PublishToFolderDialog.cs +++ b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Dialogs/PublishToFolderDialog.cs @@ -106,6 +106,7 @@ namespace MonoDevelop.AspNetCore.Dialogs Name = "pathEntry", Text = defaultDirectory }; + pathEntry.Accessible.LabelWidget = chooseLabel; pathEntry.Changed += pathEntry_Changed; pathEntry.LostFocus += PathEntry_LostFocus; browseEntryHBox.PackStart (pathEntry, expand: true); diff --git a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/Fields/ComboField.cs b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/Fields/ComboField.cs index 341aa360fd..9a1354a1ea 100644 --- a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/Fields/ComboField.cs +++ b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/Fields/ComboField.cs @@ -24,19 +24,20 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -using System.Linq; +using System.Collections.Generic;
+using System.Threading.Tasks; namespace MonoDevelop.AspNetCore.Scaffolding { class ComboField : ScaffolderField { - public ComboField (string commandLineName, string displayName, string [] options, bool isEditable = false) : base (commandLineName, displayName) + public ComboField (string commandLineName, string displayName, Task<IEnumerable<string>> options, bool isEditable = false) : base (commandLineName, displayName) { Options = options; IsEditable = isEditable; } public bool IsEditable { get; } - public string [] Options { get; } + public Task<IEnumerable<string>> Options { get; } } } diff --git a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ModelVisitor.cs b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ModelVisitor.cs index c5b00c27d1..bccd289aa3 100644 --- a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ModelVisitor.cs +++ b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ModelVisitor.cs @@ -23,13 +23,40 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +using System;
using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; using Microsoft.CodeAnalysis; +using MonoDevelop.Ide.TypeSystem; namespace MonoDevelop.AspNetCore.Scaffolding { + /// <summary> + /// Return any type that doesn't have one of the filtered base classes, or one of the filtered assembly + /// public keys + /// </summary> class ModelVisitor : SymbolVisitor { + static readonly string [] _filteredBaseClasses = new string [] { + "System.Web.WebPages.WebPageExecutingBase", // Base class for Razor views + "System.Web.UI.TemplateControl", // Base class for ASPX views + "System.Web.HttpApplication", // Base class for Global.asax + "System.Web.Mvc.Controller", // Base class for MVC controllers + "System.Web.Http.ApiController" // Base class for API controllers + }; + + static readonly string [] _filteredPublicKeys = new string [] { + "b77a5c561934e089", // CLR types (mscorlib, System.dll, System.Core.dll, etc.) + "b03f5f7f11d50a3a", // System.Web and friends + "31bf3856ad364e35", // System.ComponentModel.DataAnnotations and friends + "89845dcd8080cc91", // System.Data.SqlServerCE + "30ad4fe6b2a6aeed", // Newtonsoft.Json + "2780ccd10d57b246", // DotNetOpenAuth + }; + + static readonly Dictionary<AssemblyIdentity, bool> _assemblyKeyFilteredCache = new Dictionary<AssemblyIdentity, bool> (); + public static List<ITypeSymbol> FindModelTypes (IAssemblySymbol assembly) { var visitor = new ModelVisitor (); @@ -37,9 +64,9 @@ namespace MonoDevelop.AspNetCore.Scaffolding return visitor._types; } - private readonly List<ITypeSymbol> _types; + readonly List<ITypeSymbol> _types; - private ModelVisitor () + ModelVisitor () { _types = new List<ITypeSymbol> (); } @@ -62,7 +89,46 @@ namespace MonoDevelop.AspNetCore.Scaffolding public override void VisitNamedType (INamedTypeSymbol symbol) { - _types.Add (symbol); + foreach (var type in symbol.GetTypeMembers ()) { + Visit (type); + } + + if (IncludeTypeInAddViewModelClassDropdown (symbol)) + _types.Add (symbol); + } + + public static bool IncludeTypeInAddViewModelClassDropdown (INamedTypeSymbol symbol) + { + return symbol.DeclaredAccessibility == Accessibility.Public + && !symbol.IsStatic + && !symbol.IsGenericType + && !symbol.IsImplicitClass + && !symbol.IsAnonymousType + && !symbol.GetAttributes ().OfType<CompilerGeneratedAttribute> ().Any () + && !IsSignedWithFilteredPublicKey (symbol) + && !IsDerivedFromFilteredBaseClass (symbol); + } + + static bool IsDerivedFromFilteredBaseClass (INamedTypeSymbol t) + { + if (_filteredBaseClasses.Any (baseClass => t.GetFullMetadataName ().Equals (baseClass, StringComparison.Ordinal))) { + return true; + } + if (t.BaseType != null) { + return IsDerivedFromFilteredBaseClass (t.BaseType); + } + return false; + } + + static bool IsSignedWithFilteredPublicKey (INamedTypeSymbol t) + { + var assembly = t.ContainingAssembly; + if (!_assemblyKeyFilteredCache.TryGetValue (assembly.Identity, out var isFilteredKey)) { + string publicKeyToken = BitConverter.ToString (assembly.Identity.PublicKeyToken.ToArray ()).Replace ("-", string.Empty); + isFilteredKey = _filteredPublicKeys.Any (key => publicKeyToken.Equals (key, StringComparison.OrdinalIgnoreCase)); + _assemblyKeyFilteredCache [assembly.Identity] = isFilteredKey; + } + return isFilteredKey; } } } diff --git a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderArgs.cs b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderArgs.cs index 0cc3d8bdca..9b752e1ac7 100644 --- a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderArgs.cs +++ b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderArgs.cs @@ -23,10 +23,7 @@ // 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.Collections.ObjectModel; -using System.ComponentModel; -using System.Reflection; -using MonoDevelop.Components; +using System.Threading; using MonoDevelop.Core; using MonoDevelop.Projects; @@ -43,5 +40,6 @@ namespace MonoDevelop.AspNetCore.Scaffolding public DotNetProject Project { get; internal set; } public FilePath ParentFolder { get; internal set; } + public CancellationToken CancellationToken { get; internal set; } } } diff --git a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderDialogController.cs b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderDialogController.cs index e84da51697..68d197680c 100644 --- a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderDialogController.cs +++ b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderDialogController.cs @@ -40,8 +40,7 @@ namespace MonoDevelop.AspNetCore.Scaffolding readonly ScaffolderArgs args; readonly IWizardDialogPage firstPage; - - Dictionary<ScaffolderArgs, ScaffolderTemplateConfigurePage> cachedPages + readonly Dictionary<ScaffolderArgs, ScaffolderTemplateConfigurePage> cachedPages = new Dictionary<ScaffolderArgs, ScaffolderTemplateConfigurePage> (); public override bool CanGoBack { @@ -61,13 +60,13 @@ namespace MonoDevelop.AspNetCore.Scaffolding this.args = args; } - ScaffolderTemplateConfigurePage GetConfigurePage (ScaffolderArgs args) + ScaffolderTemplateConfigurePage GetConfigurePage (ScaffolderArgs args, CancellationToken token) { // we want to return the same instance for the same args if (cachedPages.ContainsKey (args)) { return cachedPages [args]; } else { - var page = new ScaffolderTemplateConfigurePage (args); + var page = new ScaffolderTemplateConfigurePage (args, token); cachedPages.Add (args, page); return page; } @@ -77,7 +76,7 @@ namespace MonoDevelop.AspNetCore.Scaffolding { switch (CurrentPage) { case ScaffolderTemplateSelectPage _: - IWizardDialogPage configPage = GetConfigurePage (args); + IWizardDialogPage configPage = GetConfigurePage (args, token); return Task.FromResult (configPage); } return Task.FromException<IWizardDialogPage> (new InvalidOperationException ()); diff --git a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderTemplateConfigurePage.cs b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderTemplateConfigurePage.cs index f873ce6980..d487a06490 100644 --- a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderTemplateConfigurePage.cs +++ b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderTemplateConfigurePage.cs @@ -24,18 +24,22 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System.Linq;
+using System.Threading; +using System.Threading.Tasks; +using MonoDevelop.Core; using Xwt; namespace MonoDevelop.AspNetCore.Scaffolding { class ScaffolderTemplateConfigurePage : ScaffolderWizardPageBase { - ScaffolderBase scaffolder; + readonly ScaffolderBase scaffolder; - public ScaffolderTemplateConfigurePage (ScaffolderArgs args) : base (args) + public ScaffolderTemplateConfigurePage (ScaffolderArgs args, CancellationToken token) : base (args) { scaffolder = args.Scaffolder; - this.SubSubTitle = scaffolder.Name; + SubSubTitle = scaffolder.Name; + args.CancellationToken = token; } protected override Widget GetMainControl () @@ -45,16 +49,16 @@ namespace MonoDevelop.AspNetCore.Scaffolding var rowCount = fields.Count (); int rowAdditionCount = 0; - for(int fieldIndex = 0; fieldIndex < rowCount; fieldIndex++) { + for (int fieldIndex = 0; fieldIndex < rowCount; fieldIndex++) { int rowIndex = fieldIndex + rowAdditionCount; - var field = fields[fieldIndex]; + var field = fields [fieldIndex]; var label = new Label (); switch (field) { case StringField s: var input = new TextEntry (); label.Text = s.DisplayName; - table.Add (label, 0, rowIndex, hpos:WidgetPlacement.End); + table.Add (label, 0, rowIndex, hpos: WidgetPlacement.End); table.Add (input, 1, rowIndex); input.Changed += (sender, args) => s.SelectedValue = input.Text; input.SetFocus (); @@ -65,38 +69,50 @@ namespace MonoDevelop.AspNetCore.Scaffolding var comboBoxEntry = new ComboBoxEntry (); comboBoxEntry.TextEntry.Changed += (sender, args) => comboField.SelectedValue = comboBoxEntry.TextEntry.Text; comboBox = comboBoxEntry; - } else { + } else { comboBox = new ComboBox (); - } - - foreach (var option in comboField.Options) { - comboBox.Items.Add (option); } + Task.Run (async () => { + var options = await comboField.Options; + await Runtime.RunInMainThread (() => { + if (Args.CancellationToken.IsCancellationRequested) { + return; + } + Xwt.Toolkit.NativeEngine.Invoke (() => { + foreach (var option in options) { + comboBox.Items.Add (option); + } + comboField.SelectedValue = options.FirstOrDefault (); + if (comboBox.Items.Count > 0) + comboBox.SelectedIndex = 0; + }); + + }); + }, Args.CancellationToken); + label.Text = comboField.DisplayName; - table.Add (label, 0, rowIndex, hpos:WidgetPlacement.End); + table.Add (label, 0, rowIndex, hpos: WidgetPlacement.End); table.Add (comboBox, 1, rowIndex); - comboField.SelectedValue = comboField.Options.FirstOrDefault (); comboBox.TextInput += (sender, args) => comboField.SelectedValue = comboBox.SelectedText; comboBox.SelectionChanged += (sender, args) => comboField.SelectedValue = comboBox.SelectedText; - if (comboBox.Items.Count > 0) - comboBox.SelectedIndex = 0; break; case BoolFieldList boolFieldList: label.Text = boolFieldList.DisplayName; - table.Add (label, 0, rowIndex, hpos:WidgetPlacement.End, vpos:WidgetPlacement.Start); + table.Add (label, 0, rowIndex, hpos: WidgetPlacement.End, vpos: WidgetPlacement.Start); var vbox = new VBox (); - for(int i = 0; i < boolFieldList.Options.Count; i++) { + for (int i = 0; i < boolFieldList.Options.Count; i++) { var boolField = boolFieldList.Options [i]; - var checkbox = new CheckBox (boolField.DisplayName); - checkbox.Active = boolField.Selected; - checkbox.Sensitive = boolField.Enabled; + var checkbox = new CheckBox (boolField.DisplayName) { + Active = boolField.Selected, + Sensitive = boolField.Enabled + }; checkbox.Toggled += (sender, args) => boolField.Selected = checkbox.Active; vbox.PackStart (checkbox); - } + } table.Add (vbox, 1, rowIndex); break; case FileField fileField: @@ -105,15 +121,15 @@ namespace MonoDevelop.AspNetCore.Scaffolding // This doesn't work with native toolkit! var filter = new FileDialogFilter (fileField.FilterWildcard, fileField.FilterWildcard); fileSelector.Filters.Add (filter); - } - table.Add (fileSelector, 0, rowIndex, colspan:2); + } + table.Add (fileSelector, 0, rowIndex, colspan: 2); label.Text = fileField.DisplayName; - table.Add (label, 0, rowIndex + 1, colspan:2); + table.Add (label, 0, rowIndex + 1, colspan: 2); rowAdditionCount++; fileSelector.FileChanged += (sender, args) => fileField.SelectedValue = fileSelector.FileName; break; } - + } return table; } diff --git a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderTemplateSelectPage.cs b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderTemplateSelectPage.cs index faaafca386..b126465540 100644 --- a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderTemplateSelectPage.cs +++ b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderTemplateSelectPage.cs @@ -24,6 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; +using System.Threading; using Xwt; using Xwt.Drawing; diff --git a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderWizard.cs b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderWizard.cs index 5d91c82b18..97621aecfa 100644 --- a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderWizard.cs +++ b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderWizard.cs @@ -1,4 +1,4 @@ -// +// // Scaffolder.cs // // Author: @@ -26,6 +26,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using MonoDevelop.Components; using MonoDevelop.Core; @@ -153,7 +154,7 @@ namespace MonoDevelop.AspNetCore.Scaffolding argBuilder.AddQuoted (project.FileName); argBuilder.Add (args.Scaffolder.CommandLineName); - foreach(var field in args.Scaffolder.Fields) { + foreach (var field in args.Scaffolder.Fields) { argBuilder.Add (field.CommandLineName); argBuilder.Add (field.SelectedValue); } diff --git a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderWizardPageBase.cs b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderWizardPageBase.cs index 10e5395cae..376ee1ae8f 100644 --- a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderWizardPageBase.cs +++ b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/ScaffolderWizardPageBase.cs @@ -44,7 +44,7 @@ namespace MonoDevelop.AspNetCore.Scaffolding protected set => subSubTitle = value; } - public ScaffolderArgs Args { get; } + protected ScaffolderArgs Args { get; } protected override Control CreateControl () { diff --git a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/Scaffolders/ApiControllerEntityFrameworkScaffolder.cs b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/Scaffolders/ApiControllerEntityFrameworkScaffolder.cs index 838bf08aaa..c7a3221f43 100644 --- a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/Scaffolders/ApiControllerEntityFrameworkScaffolder.cs +++ b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/Scaffolders/ApiControllerEntityFrameworkScaffolder.cs @@ -44,8 +44,8 @@ namespace MonoDevelop.AspNetCore.Scaffolding IEnumerable<ScaffolderField> GetFields () { fields = new ScaffolderField [] { - GetModelField(args.Project), - GetDbContextField(args.Project), + GetModelField(args), + GetDbContextField(args), new StringField ("-name", "Controller name:"), }; diff --git a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/Scaffolders/RazorPageEntityFrameworkCrudScaffolder.cs b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/Scaffolders/RazorPageEntityFrameworkCrudScaffolder.cs index 2b624194f7..f0a836cd83 100644 --- a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/Scaffolders/RazorPageEntityFrameworkCrudScaffolder.cs +++ b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/Scaffolders/RazorPageEntityFrameworkCrudScaffolder.cs @@ -24,6 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System.Collections.Generic; +using System.Threading; namespace MonoDevelop.AspNetCore.Scaffolding { @@ -49,8 +50,8 @@ namespace MonoDevelop.AspNetCore.Scaffolding }; fields = new ScaffolderField [] { - GetModelField(args.Project), - GetDbContextField(args.Project), + GetModelField(args), + GetDbContextField(args), new BoolFieldList(options), CustomLayoutField }; diff --git a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/Scaffolders/RazorPageEntityFrameworkScaffolder.cs b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/Scaffolders/RazorPageEntityFrameworkScaffolder.cs index b3c2587552..4b73ea4ae4 100644 --- a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/Scaffolders/RazorPageEntityFrameworkScaffolder.cs +++ b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/Scaffolders/RazorPageEntityFrameworkScaffolder.cs @@ -24,6 +24,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; namespace MonoDevelop.AspNetCore.Scaffolding { @@ -49,13 +51,13 @@ namespace MonoDevelop.AspNetCore.Scaffolding LayoutPageField }; - string [] viewTemplateOptions = new [] { "Empty", "Create", "Edit", "Delete", "Details", "List" }; + IEnumerable<string> viewTemplateOptions = new [] { "Empty", "Create", "Edit", "Delete", "Details", "List" }; fields = new ScaffolderField [] { NameField, - new ComboField ("", "The template to use, supported view templates", viewTemplateOptions), - GetModelField(args.Project), - GetDbContextField(args.Project), + new ComboField ("", "The template to use, supported view templates", Task.FromResult(viewTemplateOptions)), + GetModelField(args), + GetDbContextField(args), new BoolFieldList(options), CustomLayoutField }; diff --git a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/Scaffolders/ScaffolderBase.cs b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/Scaffolders/ScaffolderBase.cs index fff2fc8b51..c0b445255c 100644 --- a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/Scaffolders/ScaffolderBase.cs +++ b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Scaffolding/Scaffolders/ScaffolderBase.cs @@ -23,8 +23,11 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +using System;
using System.Collections.Generic; using System.Linq; +using System.Threading; +using System.Threading.Tasks; using Microsoft.CodeAnalysis.FindSymbols; using MonoDevelop.Ide; using MonoDevelop.Projects; @@ -44,43 +47,41 @@ namespace MonoDevelop.AspNetCore.Scaffolding public virtual IEnumerable<ScaffolderField> Fields { get; } - protected ComboField GetDbContextField (DotNetProject project) + protected ComboField GetDbContextField (ScaffolderArgs args) { - var dbContexts = GetDbContextClasses (project); - return new ComboField ("--dataContext", "DbContext class to use", dbContexts.ToArray (), isEditable: true); + return new ComboField ("--dataContext", "DbContext class to use", GetDbContextClassesAsync(args.Project, args.CancellationToken), isEditable: true); } - protected ComboField GetModelField (DotNetProject project) + protected ComboField GetModelField (ScaffolderArgs args) { - var dbModels = GetModelClasses (project); - return new ComboField ("--model", "Model class to use", dbModels.ToArray (), isEditable: true); + return new ComboField ("--model", "Model class to use", GetModelClassesAsync(args.Project, args.CancellationToken), isEditable: true); } - IEnumerable<string> GetDbContextClasses (DotNetProject project) + async Task<IEnumerable<string>> GetDbContextClassesAsync (DotNetProject project, CancellationToken token) { - //TODO: make async - var compilation = IdeApp.TypeSystemService.GetCompilationAsync (project).Result; + var compilation = await IdeApp.TypeSystemService.GetCompilationAsync (project, token); if (compilation != null) { var dbContext = compilation.GetTypeByMetadataName (EFCDbContextTypeName) ?? compilation.GetTypeByMetadataName (DbContextTypeName) ?? compilation.GetTypeByMetadataName (EF7DbContextTypeName); if (dbContext != null) { - var result = SymbolFinder.FindDerivedClassesAsync (dbContext, IdeApp.TypeSystemService.Workspace.CurrentSolution).Result; - return result.Select (c => c.MetadataName); + var result = await SymbolFinder.FindDerivedClassesAsync (dbContext, IdeApp.TypeSystemService.Workspace.CurrentSolution); + + return result.Where (ModelVisitor.IncludeTypeInAddViewModelClassDropdown).Select (c => c.MetadataName).Distinct().OrderBy (x => x); } } + return Enumerable.Empty<string> (); } - IEnumerable<string> GetModelClasses (DotNetProject project) + async Task<IEnumerable<string>> GetModelClassesAsync (DotNetProject project, CancellationToken token) { - //TODO: make async - var compilation = IdeApp.TypeSystemService.GetCompilationAsync (project).Result; + var compilation = await IdeApp.TypeSystemService.GetCompilationAsync (project, token); if (compilation != null) { - var modelTypes = ModelVisitor.FindModelTypes (compilation.Assembly); - return modelTypes.Select (t => t.MetadataName); + var dbContextTypes = await GetDbContextClassesAsync (project, token); + return modelTypes.Select (t => t.MetadataName).Except(dbContextTypes).Distinct().OrderBy (x => x); } return Enumerable.Empty<string> (); } diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.VSTextView/QuickInfo/DebuggerQuickInfoSource.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.VSTextView/QuickInfo/DebuggerQuickInfoSource.cs index f8b9d63283..78a482c692 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.VSTextView/QuickInfo/DebuggerQuickInfoSource.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.VSTextView/QuickInfo/DebuggerQuickInfoSource.cs @@ -177,7 +177,7 @@ namespace MonoDevelop.Debugger.VSTextView.QuickInfo var bounds = view.TextViewLines.GetCharacterBounds (point); var rect = new CoreGraphics.CGRect (bounds.Left - view.ViewportLeft, bounds.Top - view.ViewportTop, bounds.Width, bounds.Height); - if (cocoaView.IsClosed) { + if (cocoaView.IsClosed || cocoaView.VisualElement.Window == null) { LoggingService.LogWarning ("Editor window has been closed before debugger tooltip was shown. How did this happen?"); return; } diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ExceptionCaughtDialog.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ExceptionCaughtDialog.cs index 220fbc011c..1f1867de34 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ExceptionCaughtDialog.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ExceptionCaughtDialog.cs @@ -401,7 +401,7 @@ widget ""*.exception_dialog_expander"" style ""exception-dialog-expander"" } var actionArea = new HBox (false, 0) { BorderWidth = 14 }; - onlyShowMyCodeCheckbox = new CheckButton (GettextCatalog.GetString ("_Only show my code.")); + onlyShowMyCodeCheckbox = new CheckButton (GettextCatalog.GetString ("_Only show my code")); onlyShowMyCodeCheckbox.Toggled += OnlyShowMyCodeToggled; onlyShowMyCodeCheckbox.Show (); onlyShowMyCodeCheckbox.Active = DebuggingService.GetUserOptions ().ProjectAssembliesOnly; diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectValueView.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectValueView.cs index 2ea16551a4..88993bfcbc 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectValueView.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectValueView.cs @@ -67,7 +67,8 @@ namespace MonoDevelop.Debugger }; colorPreview = new NSView (new CGRect (0, 0, ImageSize, ImageSize)) { - TranslatesAutoresizingMaskIntoConstraints = false + TranslatesAutoresizingMaskIntoConstraints = false, + WantsLayer = true }; valueButton = new NSButton { diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/ToolboxPad.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/ToolboxPad.cs index 3f066010b5..63a1c6a0db 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/ToolboxPad.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/ToolboxPad.cs @@ -130,10 +130,12 @@ namespace MonoDevelop.DesignerSupport // Gtk.Application.CurrentEvent and other copied gdk_events seem to have a problem // when used as they use gdk_event_copy which seems to crash on de-allocating the private slice. IntPtr currentEvent = GtkWorkarounds.GetCurrentEventHandle (); - Gtk.Drag.Begin (widget, targets, Gdk.DragAction.Copy | Gdk.DragAction.Move, 1, new Gdk.Event (currentEvent, false)); + if (currentEvent != IntPtr.Zero) { + Gtk.Drag.Begin (widget, targets, Gdk.DragAction.Copy | Gdk.DragAction.Move, 1, new Gdk.Event (currentEvent, false)); - // gtk_drag_begin does not store the event, so we're okay - GtkWorkarounds.FreeEvent (currentEvent); + // gtk_drag_begin does not store the event, so we're okay + GtkWorkarounds.FreeEvent (currentEvent); + } } } diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/LicenseAcceptanceService.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/LicenseAcceptanceService.cs index 08df5ac457..bd66949c15 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/LicenseAcceptanceService.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/LicenseAcceptanceService.cs @@ -49,7 +49,7 @@ namespace MonoDevelop.PackageManagement IdeApp.RunWhenIdle (() => {
Xwt.Toolkit.NativeEngine.Invoke (delegate {
using (LicenseAcceptanceDialog dialog = CreateLicenseAcceptanceDialog (licenses)) {
- res.SetResult (dialog.Run (Xwt.MessageDialog.RootWindow));
+ res.SetResult (dialog.Run (MessageService.RootWindow));
}
});
});
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 d7d43e4dd0..05db51bee6 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 @@ -1888,15 +1888,17 @@ namespace MonoDevelop.VersionControl.Git public async Task<string> GetCurrentRemoteAsync (CancellationToken cancellationToken = default) { - var headRemote = await RunOperationAsync (() => RootRepository.Head?.RemoteName).ConfigureAwait (false); - if (!string.IsNullOrEmpty (headRemote)) - return headRemote; + using (LinkTokenToDispose (ref cancellationToken)) { + var headRemote = await RunOperationAsync (() => RootRepository.Head?.RemoteName).ConfigureAwait (false); + if (!string.IsNullOrEmpty (headRemote)) + return headRemote; - var remotes = await GetRemoteNamesAsync (cancellationToken).ConfigureAwait (false); - if (remotes.Count == 0) - return null; + var remotes = await GetRemoteNamesAsync (cancellationToken).ConfigureAwait (false); + if (remotes.Count == 0) + return null; - return remotes.Contains ("origin") ? "origin" : remotes [0]; + return remotes.Contains ("origin") ? "origin" : remotes [0]; + } } public async Task PushAsync (ProgressMonitor monitor, string remote, string remoteBranch) diff --git a/main/src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl.Dialogs/CommitDialog.cs b/main/src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl.Dialogs/CommitDialog.cs index 9f4a167a0f..d5e196c631 100644 --- a/main/src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl.Dialogs/CommitDialog.cs +++ b/main/src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl.Dialogs/CommitDialog.cs @@ -44,6 +44,7 @@ namespace MonoDevelop.VersionControl.Dialogs { partial class CommitDialog : Gtk.Dialog { + Repository vc; ListStore store; HashSet<FilePath> selected = new HashSet<FilePath> (); List<CommitDialogExtension> extensions = new List<CommitDialogExtension> (); @@ -51,8 +52,9 @@ namespace MonoDevelop.VersionControl.Dialogs string oldMessage; bool responseSensitive; - public CommitDialog (ChangeSet changeSet) + public CommitDialog (Repository vc, ChangeSet changeSet) { + this.vc = vc; Build (); store = new ListStore(typeof (Xwt.Drawing.Image), typeof (string), typeof (string), typeof(bool), typeof(object)); @@ -205,12 +207,20 @@ namespace MonoDevelop.VersionControl.Dialogs protected override void OnResponse (Gtk.ResponseType type) { + base.OnResponse (type); + if (type != Gtk.ResponseType.Ok) { changeSet.GlobalComment = oldMessage; - } else if (!ButtonCommitClicked ()) + EndCommit (false); + } else if (!ButtonCommitClicked ()) { return; + } - base.OnResponse (type); + if (type == Gtk.ResponseType.Ok) { + VersionControlService.NotifyBeforeCommit (vc, changeSet); + new CommitWorker (vc, changeSet, this).StartAsync (); + return; + } } CancellationTokenSource destroyTokenSource = new CancellationTokenSource (); @@ -342,5 +352,60 @@ namespace MonoDevelop.VersionControl.Dialogs else selected.Remove (vinfo.LocalPath); } + + private class CommitWorker : VersionControlTask + { + Repository vc; + ChangeSet changeSet; + CommitDialog dlg; + bool success; + + public CommitWorker (Repository vc, ChangeSet changeSet, CommitDialog dlg) + { + this.vc = vc; + this.changeSet = changeSet; + this.dlg = dlg; + OperationType = VersionControlOperationType.Push; + } + + protected override string GetDescription () + { + return GettextCatalog.GetString ("Committing {0}...", changeSet.BaseLocalPath); + } + + protected override async Task RunAsync () + { + success = true; + try { + // store global comment before commit. + VersionControlService.SetCommitComment (changeSet.BaseLocalPath, changeSet.GlobalComment, true); + + await vc.CommitAsync (changeSet, Monitor); + Monitor.ReportSuccess (GettextCatalog.GetString ("Commit operation completed.")); + + // Reset the global comment on successful commit. + VersionControlService.SetCommitComment (changeSet.BaseLocalPath, "", true); + } catch (Exception ex) { + LoggingService.LogError ("Commit operation failed", ex); + Monitor.ReportError (ex.Message, null); + success = false; + throw; + } + } + + protected override void Finished () + { + dlg.EndCommit (success); + dlg.Destroy (); + FileUpdateEventArgs args = new FileUpdateEventArgs (); + foreach (ChangeSetItem it in changeSet.Items) + args.Add (new FileUpdateEventInfo (vc, it.LocalPath, it.IsDirectory)); + + if (args.Count > 0) + VersionControlService.NotifyFileStatusChanged (args); + + VersionControlService.NotifyAfterCommit (vc, changeSet, success); + } + } } } diff --git a/main/src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl/CommitCommand.cs b/main/src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl/CommitCommand.cs index fd36780e72..1b43fa50a2 100644 --- a/main/src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl/CommitCommand.cs +++ b/main/src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl/CommitCommand.cs @@ -20,14 +20,9 @@ namespace MonoDevelop.VersionControl VersionControlService.NotifyPrepareCommit (vc, changeSet); if (!await VerifyUnsavedChangesAsync (changeSet)) return; - CommitDialog dlg = new CommitDialog (changeSet); + CommitDialog dlg = new CommitDialog (vc, changeSet); try { - if (MessageService.RunCustomDialog (dlg) == (int) Gtk.ResponseType.Ok) { - VersionControlService.NotifyBeforeCommit (vc, changeSet); - new CommitWorker (vc, changeSet, dlg).StartAsync(); - return; - } - dlg.EndCommit (false); + MessageService.RunCustomDialog (dlg); } finally { dlg.Destroy (); dlg.Dispose (); @@ -91,59 +86,6 @@ namespace MonoDevelop.VersionControl return allowCommit; } - private class CommitWorker : VersionControlTask - { - Repository vc; - ChangeSet changeSet; - CommitDialog dlg; - bool success; - - public CommitWorker (Repository vc, ChangeSet changeSet, CommitDialog dlg) - { - this.vc = vc; - this.changeSet = changeSet; - this.dlg = dlg; - OperationType = VersionControlOperationType.Push; - } - - protected override string GetDescription() - { - return GettextCatalog.GetString ("Committing {0}...", changeSet.BaseLocalPath); - } - - protected override async Task RunAsync () - { - success = true; - try { - // store global comment before commit. - VersionControlService.SetCommitComment (changeSet.BaseLocalPath, changeSet.GlobalComment, true); - - await vc.CommitAsync (changeSet, Monitor); - Monitor.ReportSuccess (GettextCatalog.GetString ("Commit operation completed.")); - - // Reset the global comment on successful commit. - VersionControlService.SetCommitComment (changeSet.BaseLocalPath, "", true); - } catch (Exception ex) { - LoggingService.LogError ("Commit operation failed", ex); - Monitor.ReportError (ex.Message, null); - success = false; - throw; - } - } - - protected override void Finished () - { - dlg.EndCommit (success); - dlg.Destroy (); - FileUpdateEventArgs args = new FileUpdateEventArgs (); - foreach (ChangeSetItem it in changeSet.Items) - args.Add (new FileUpdateEventInfo (vc, it.LocalPath, it.IsDirectory)); - - if (args.Count > 0) - VersionControlService.NotifyFileStatusChanged (args); - - VersionControlService.NotifyAfterCommit (vc, changeSet, success); - } - } + } } 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 29ff8afe57..2ee3353c0e 100644 --- a/main/src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl/Repository.cs +++ b/main/src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl/Repository.cs @@ -135,8 +135,15 @@ namespace MonoDevelop.VersionControl } } + CancellationTokenSource disposeTokenSource = new CancellationTokenSource (); + public void Dispose () { + if (disposeTokenSource != null) { + disposeTokenSource.Cancel (); + disposeTokenSource.Dispose (); + disposeTokenSource = null; + } Dispose (true); GC.SuppressFinalize (this); } @@ -292,49 +299,50 @@ namespace MonoDevelop.VersionControl /// </param> public async Task<IReadOnlyList<VersionInfo>> GetVersionInfoAsync (IEnumerable<FilePath> paths, VersionInfoQueryFlags queryFlags = VersionInfoQueryFlags.None, CancellationToken cancellationToken = default) { - if ((queryFlags & VersionInfoQueryFlags.IgnoreCache) != 0) { - var task = await ExclusiveOperationFactory.StartNew (delegate { - // We shouldn't use IEnumerable because elements don't save property modifications. - return OnGetVersionInfoAsync (paths, (queryFlags & VersionInfoQueryFlags.IncludeRemoteStatus) != 0, cancellationToken); - }).ConfigureAwait (false); - - var res = await task.ConfigureAwait (false); - foreach (var vi in res) - if (!vi.IsInitialized) await vi.InitAsync (this, cancellationToken).ConfigureAwait (false); - await infoCache.SetStatusAsync (res, cancellationToken: cancellationToken).ConfigureAwait (false); - return res; - } - var pathsToQuery = new List<FilePath> (); - var result = new List<VersionInfo> (); - foreach (var path in paths) { - var vi = infoCache.GetStatus (path); - if (vi != null) { - result.Add (vi); - // This status has been invalidated, query it asynchronously - if (vi.RequiresRefresh) - pathsToQuery.Add (path); + using (LinkTokenToDispose (ref cancellationToken)) { + if ((queryFlags & VersionInfoQueryFlags.IgnoreCache) != 0) { + var task = await ExclusiveOperationFactory.StartNew (delegate { + // We shouldn't use IEnumerable because elements don't save property modifications. + return OnGetVersionInfoAsync (paths, (queryFlags & VersionInfoQueryFlags.IncludeRemoteStatus) != 0, cancellationToken); + }).ConfigureAwait (false); + + var res = await task.ConfigureAwait (false); + foreach (var vi in res) + if (!vi.IsInitialized) await vi.InitAsync (this, cancellationToken).ConfigureAwait (false); + await infoCache.SetStatusAsync (res, cancellationToken: cancellationToken).ConfigureAwait (false); + return res; } - else { - // If there is no cached status, query it asynchronously - vi = new VersionInfo (path, "", Directory.Exists (path), VersionStatus.Versioned, null, VersionStatus.Versioned, null); - await infoCache.SetStatusAsync (vi, false).ConfigureAwait (false); - result.Add (vi); - pathsToQuery.Add (path); + var pathsToQuery = new List<FilePath> (); + var result = new List<VersionInfo> (); + foreach (var path in paths) { + var vi = infoCache.GetStatus (path); + if (vi != null) { + result.Add (vi); + // This status has been invalidated, query it asynchronously + if (vi.RequiresRefresh) + pathsToQuery.Add (path); + } else { + // If there is no cached status, query it asynchronously + vi = new VersionInfo (path, "", Directory.Exists (path), VersionStatus.Versioned, null, VersionStatus.Versioned, null); + await infoCache.SetStatusAsync (vi, false).ConfigureAwait (false); + result.Add (vi); + pathsToQuery.Add (path); + } + // Console.WriteLine ("GetVersionInfo " + string.Join (", ", paths.Select (p => p.FullPath))); } -// Console.WriteLine ("GetVersionInfo " + string.Join (", ", paths.Select (p => p.FullPath))); - } - if (pathsToQuery.Count > 0) { - ExclusiveOperationFactory.StartNew (async delegate { - var status = await OnGetVersionInfoAsync (pathsToQuery, (queryFlags & VersionInfoQueryFlags.IncludeRemoteStatus) != 0, cancellationToken).ConfigureAwait (false); - foreach (var vi in status) { - if (!vi.IsInitialized) { - await vi.InitAsync (this, cancellationToken).ConfigureAwait (false); + if (pathsToQuery.Count > 0) { + ExclusiveOperationFactory.StartNew (async delegate { + var status = await OnGetVersionInfoAsync (pathsToQuery, (queryFlags & VersionInfoQueryFlags.IncludeRemoteStatus) != 0, cancellationToken).ConfigureAwait (false); + foreach (var vi in status) { + if (!vi.IsInitialized) { + await vi.InitAsync (this, cancellationToken).ConfigureAwait (false); + } } - } - await infoCache.SetStatusAsync (status, cancellationToken).ConfigureAwait (false); - }).Ignore (); + await infoCache.SetStatusAsync (status, cancellationToken).ConfigureAwait (false); + }).Ignore (); + } + return result; } - return result; } public bool TryGetVersionInfo (IEnumerable<FilePath> paths, out IReadOnlyList<VersionInfo> infos) @@ -360,16 +368,17 @@ namespace MonoDevelop.VersionControl } } if (pathsToQuery.Count > 0) { + var token = disposeTokenSource.Token; ExclusiveOperationFactory.StartNew (async delegate { // we don't care about initialization and setstatus async to happen on the exclusive thread, as we're not running a query here. - var status = await OnGetVersionInfoAsync (paths, (queryFlags & VersionInfoQueryFlags.IncludeRemoteStatus) != 0).ConfigureAwait (false); + var status = await OnGetVersionInfoAsync (paths, (queryFlags & VersionInfoQueryFlags.IncludeRemoteStatus) != 0, token).ConfigureAwait (false); foreach (var vi in status) { if (!vi.IsInitialized) { - await vi.InitAsync (this).ConfigureAwait (false); + await vi.InitAsync (this, token).ConfigureAwait (false); } } - await infoCache.SetStatusAsync (status).ConfigureAwait (false); - }).Ignore (); + await infoCache.SetStatusAsync (status, token).ConfigureAwait (false); + }, token).Ignore (); } if (getVersionInfoFailed) { infos = null; @@ -379,8 +388,16 @@ namespace MonoDevelop.VersionControl return true; } + protected IDisposable LinkTokenToDispose (ref CancellationToken originalToken) + { + var combinedTokenSource = CancellationTokenSource.CreateLinkedTokenSource (originalToken, disposeTokenSource.Token); + originalToken = combinedTokenSource.Token; + return combinedTokenSource; + } + public async Task<VersionInfo[]> GetDirectoryVersionInfoAsync (FilePath localDirectory, bool getRemoteStatus, bool recursive, CancellationToken cancellationToken = default) { + var combinedTokenSource = LinkTokenToDispose (ref cancellationToken); try { if (recursive) { return await OnGetDirectoryVersionInfoAsync (localDirectory, getRemoteStatus, true, cancellationToken).ConfigureAwait (false); @@ -402,6 +419,7 @@ namespace MonoDevelop.VersionControl return status.FileInfo; return Array.Empty<VersionInfo> (); } finally { + combinedTokenSource.Dispose (); //Console.WriteLine ("GetDirectoryVersionInfo " + localDirectory + " - " + (DateTime.Now - now).TotalMilliseconds); } } @@ -440,6 +458,7 @@ namespace MonoDevelop.VersionControl /// </param> public async Task<RevisionPath []> GetRevisionChangesAsync (Revision revision, CancellationToken cancellationToken = default) { + using (LinkTokenToDispose (ref cancellationToken)) using (var tracker = Instrumentation.GetRevisionChangesCounter.BeginTiming (new RepositoryMetadata (VersionControlSystem))) { try { return await OnGetRevisionChangesAsync (revision, cancellationToken).ConfigureAwait (false); @@ -457,6 +476,7 @@ namespace MonoDevelop.VersionControl // Returns the revision history of a file public async Task<Revision[]> GetHistoryAsync (FilePath localFile, Revision since, CancellationToken cancellationToken = default) { + using (LinkTokenToDispose (ref cancellationToken)) using (var tracker = Instrumentation.GetHistoryCounter.BeginTiming (new RepositoryMetadata (VersionControlSystem))) { try { return await OnGetHistoryAsync (localFile, since, cancellationToken).ConfigureAwait (false); diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/TextDocument.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/TextDocument.cs index 9351121911..8416b4493d 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/TextDocument.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/TextDocument.cs @@ -343,7 +343,7 @@ namespace Mono.TextEditor this.mimeType = mimeType;
var doc = PlatformCatalog.Instance.TextDocumentFactoryService.CreateTextDocument (
PlatformCatalog.Instance.TextBufferFactoryService.CreateTextBuffer (
- text ?? string.Empty,
+ new StringReader(text ?? string.Empty),
GetContentTypeFromMimeType (fileName, mimeType)
),
fileName ?? string.Empty
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AutoTest.Results/NSObjectResult.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AutoTest.Results/NSObjectResult.cs index 3de4949abf..d60dfaaf3c 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AutoTest.Results/NSObjectResult.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AutoTest.Results/NSObjectResult.cs @@ -317,7 +317,66 @@ namespace MonoDevelop.Components.AutoTest.Results SetProperty (ResultObject, propertyName, value); } -#region MacPlatform.MacIntegration.MainToolbar.SelectorView + #region MacPlatform.MacIntegration.MainToolbar.SelectorView + PropertyInfo GetPropertyInfo (string propertyName) + { + var type = ResultObject.GetType (); + return type.GetProperty (propertyName); + } + + object GetModelObject (PropertyInfo propertyInfo) + { + return propertyInfo.GetValue (ResultObject, null); + } + + public IConfigurationModel[] GetConfigurationModels () + { + var pinfo = GetPropertyInfo ("ConfigurationModel"); + if (pinfo == null) { + return null; + } + var models = (IEnumerable<IConfigurationModel>)GetModelObject (pinfo); + + return models?.ToArray (); + } + + public IRuntimeMutableModel[] GetRuntimeModels () + { + var pinfo = GetPropertyInfo ("RuntimeModel"); + if (pinfo == null) { + return null; + } + var topModels = (IEnumerable<IRuntimeModel>)GetModelObject (pinfo); + return AllRuntimes (topModels).Where (x => !x.IsSeparator && x.IsIndented).Select (x => x.GetMutableModel ()).ToArray (); + } + + public IConfigurationModel GetActiveConfiguration () + { + var pinfo = GetPropertyInfo ("ActiveConfiguration"); + return (IConfigurationModel)pinfo.GetValue (ResultObject); + } + + public string GetActiveStartupProject () + { + var pinfo = GetPropertyInfo ("ActiveRunConfiguration"); + var activeRuntime = (IRunConfigurationModel)pinfo.GetValue (ResultObject); + return activeRuntime.DisplayString; + } + + public IRuntimeMutableModel GetActiveRuntime () + { + var pinfo = GetPropertyInfo ("ActiveRuntime"); + var activeRuntime = (IRuntimeModel)pinfo.GetValue (ResultObject); + return activeRuntime.GetMutableModel (); + } + + public string[] GetStartupProjectNames () + { + var pinfo = GetPropertyInfo ("RunConfigurationModel"); + var runConfigs = (IEnumerable<IRunConfigurationModel>)pinfo.GetValue (ResultObject); + return runConfigs.Select (x => x.DisplayString).ToArray (); + } + public override bool SetActiveConfiguration (string configurationName) { LoggingService.LogDebug ($"Set Active configuration with name as '{configurationName}'"); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AutoTest/AutoTestClientSession.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AutoTest/AutoTestClientSession.cs index 67e8ab99d6..f86b66da86 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AutoTest/AutoTestClientSession.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AutoTest/AutoTestClientSession.cs @@ -59,7 +59,13 @@ namespace MonoDevelop.Components.AutoTest } } } - + + public AutoTestToolbar AutoTestToolbar { + get { + return new AutoTestToolbar (session); + } + } + public int StartApplication (string file = null, string args = null, IDictionary<string, string> environment = null) { if (file == null) { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AutoTest/AutoTestToolbar.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AutoTest/AutoTestToolbar.cs new file mode 100644 index 0000000000..63efdf65f3 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AutoTest/AutoTestToolbar.cs @@ -0,0 +1,129 @@ +// +// AutoTestToolbar.cs +// +// Author: +// olgaboiarshynova <v-olboia@microsoft.com> +// +// Copyright (c) 2019 +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using System.Collections.Generic; +using System.Linq; +using MonoDevelop.Components.AutoTest.Results; + +namespace MonoDevelop.Components.AutoTest +{ + public class AutoTestToolbar : MarshalByRefObject + { + AutoTestSession session; + readonly Func<AppQuery, AppQuery> selectorViewQuery = c => c.Marked ("MonoDevelop.MacIntegration.MainToolbar.SelectorView+PathSelectorView"); + + public AutoTestToolbar (AutoTestSession session) + { + this.session = session; + } + + public AppResult SelectorViewControl { + get { + var c = session.CreateNewQuery (); + c = selectorViewQuery (c); + var queryResult = session.ExecuteQuery (c); + + return queryResult [0]; + } + } + + public string GetActiveConfiguration () + { + #if MAC + return (SelectorViewControl as NSObjectResult).GetActiveConfiguration ()?.DisplayString; + #else + return null; + #endif + + } + + public string GetActiveExecutionTarget () + { + #if MAC + return (SelectorViewControl as NSObjectResult).GetActiveRuntime ()?.DisplayString; + #else + return null; + #endif + } + + public string[] GetConfigurations () + { + #if MAC + return (SelectorViewControl as NSObjectResult).GetConfigurationModels ().Select (m => $"{m.DisplayString}").ToArray(); + #else + return null; + #endif + } + + public string[] GetExecutionTargets () + { + #if MAC + return (SelectorViewControl as NSObjectResult).GetRuntimeModels ().Select (m => $"{m.FullDisplayString}").ToArray (); + #else + return null; + #endif + } + + public string[] GetStartupProjects () + { + #if MAC + return (SelectorViewControl as NSObjectResult).GetStartupProjectNames (); + #else + return null; + #endif + } + + public string GetStatusMessage () + { + return (string)session.GetGlobalValue ("MonoDevelop.Ide.IdeApp.Workbench.RootWindow.StatusBar.text"); + } + + public string GetActiveStartupProject () + { + #if MAC + return (SelectorViewControl as NSObjectResult).GetActiveStartupProject (); + #else + return null; + #endif + } + + public Dictionary<ExecutionInfoKeys, string> GetExecutionInfo () + { + var info = new Dictionary<ExecutionInfoKeys, string> (3); + info.Add (ExecutionInfoKeys.StartupProject, GetActiveStartupProject ()); + info.Add (ExecutionInfoKeys.ActiveConfiguration, GetActiveConfiguration ()); + info.Add (ExecutionInfoKeys.ActiveExecitionTarget, GetActiveExecutionTarget ()); + return info; + } + + public enum ExecutionInfoKeys + { + StartupProject, + ActiveConfiguration, + ActiveExecitionTarget + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/CommandManager.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/CommandManager.cs index 59acd526a8..f2bafbd922 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/CommandManager.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/CommandManager.cs @@ -2426,7 +2426,8 @@ namespace MonoDevelop.Components.Commands Gtk.Widget GetFocusedChild (Control widget) { Gtk.Container container; - + if (widget?.nativeWidget is AppKit.NSWindow window) + widget = Mac.GtkMacInterop.GetGtkWindow (window)?.Child; do { container = widget?.nativeWidget is Gtk.Container ? widget.GetNativeWidget<Gtk.Container> () : null; if (container != null) { @@ -2438,7 +2439,7 @@ namespace MonoDevelop.Components.Commands } } while (container != null); - return widget.nativeWidget is Gtk.Widget ? widget : null; + return widget?.nativeWidget is Gtk.Widget ? widget : null; } #if MAC diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/MainToolbarController.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/MainToolbarController.cs index a9763a1510..c73b1972b1 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/MainToolbarController.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/MainToolbarController.cs @@ -41,6 +41,7 @@ using MonoDevelop.Projects; namespace MonoDevelop.Components.MainToolbar { + [Serializable] class MainToolbarController : ICommandBar { const string ToolbarExtensionPath = "/MonoDevelop/Ide/CommandBar"; @@ -983,6 +984,7 @@ namespace MonoDevelop.Components.MainToolbar public event EventHandler TitleChanged; } + [Serializable] class RuntimeModel : IRuntimeModel { MainToolbarController Controller { get; set; } @@ -1082,6 +1084,7 @@ namespace MonoDevelop.Components.MainToolbar } } + [Serializable] class RuntimeMutableModel : IRuntimeMutableModel { public RuntimeMutableModel(string text) @@ -1154,6 +1157,7 @@ namespace MonoDevelop.Components.MainToolbar } } + [Serializable] class ConfigurationModel : IConfigurationModel { public ConfigurationModel (string originalId) @@ -1166,6 +1170,7 @@ namespace MonoDevelop.Components.MainToolbar public string DisplayString { get; private set; } } + [Serializable] class RunConfigurationModel : IRunConfigurationModel { public RunConfigurationModel (SolutionRunConfiguration config) diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Mac/GtkNSViewHost.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Mac/GtkNSViewHost.cs index 37c7ded0b0..0e62b4aa56 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Mac/GtkNSViewHost.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Mac/GtkNSViewHost.cs @@ -331,7 +331,7 @@ namespace Gtk try { if (view?.Window?.FirstResponder is NSView firstResponder && view?.AncestorSharedWithView (firstResponder) == view) - firstResponder.Window?.MakeFirstResponder (null); + firstResponder.Window?.MakeFirstResponder (firstResponder.Window.ContentView); return base.OnFocusOutEvent (evnt); } finally { LogExit (); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/FileCommands.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/FileCommands.cs index bc209f4124..1634894e7a 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/FileCommands.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/FileCommands.cs @@ -82,7 +82,7 @@ namespace MonoDevelop.Ide.Commands protected override void Run () { var dlg = new OpenFileDialog (GettextCatalog.GetString ("File to Open"), MonoDevelop.Components.FileChooserAction.Open) { - TransientFor = IdeServices.DesktopService.GetFocusedTopLevelWindow (), + TransientFor = MessageService.RootWindow, ShowEncodingSelector = true, ShowViewerSelector = true, }; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResult.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResult.cs index a3aeae4c40..a2c52d7892 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResult.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResult.cs @@ -85,14 +85,14 @@ namespace MonoDevelop.Ide.FindInFiles internal string GetCopyData (SearchResultWidget widget) { if (copyData == null) - FillCache (widget); + FillCache (widget).Ignore (); return copyData; } internal string GetMarkup(SearchResultWidget widget, bool isSelected) { if (markup == null) - FillCache (widget); + FillCache (widget).Ignore (); return isSelected ? selectedMarkup : markup; } @@ -112,17 +112,18 @@ namespace MonoDevelop.Ide.FindInFiles } } - async void FillCache (SearchResultWidget widget) + async Task FillCache (SearchResultWidget widget) { FillLineCache (widget); copyData = ""; markup = selectedMarkup = ""; - var doc = GetDocument (); - if (doc == null) { - return; - } try { + var doc = GetDocument (); + if (doc == null) { + return; + } + var lineNr = location.Value.Line; var line = doc.GetLine (lineNr); if (line != null) { @@ -274,8 +275,13 @@ namespace MonoDevelop.Ide.FindInFiles TextEditor GetDocument () { - if (cachedEditor == null || cachedEditor.IsDisposed || cachedEditor.FileName != FileName || cachedEditorFileProvider != FileProvider) { + var fileProvider = FileProvider; + if (cachedEditor == null || cachedEditor.IsDisposed || cachedEditor.FileName != FileName || cachedEditorFileProvider != fileProvider) { + if (fileProvider == null) + throw new InvalidOperationException ("FileProvider == null"); var content = FileProvider.ReadString (); + if (content == null) + throw new InvalidOperationException ("FileProvider.ReadString () == null"); cachedEditor?.Dispose (); cachedEditor = TextEditorFactory.CreateNewEditor (TextEditorFactory.CreateNewReadonlyDocument (new Core.Text.StringTextSource (content.ReadToEnd ()), FileName, IdeServices.DesktopService.GetMimeTypeForUri (FileName))); cachedEditorFileProvider = FileProvider; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/TextBufferFileModel.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/TextBufferFileModel.cs index 2941b70049..f2e496e342 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/TextBufferFileModel.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/TextBufferFileModel.cs @@ -80,7 +80,7 @@ namespace MonoDevelop.Ide.Gui.Documents ThawChangeEvent (); } } else { - var buffer = PlatformCatalog.Instance.TextBufferFactoryService.CreateTextBuffer (text.Text, contentType); + var buffer = PlatformCatalog.Instance.TextBufferFactoryService.CreateTextBuffer (new System.IO.StringReader (text.Text), contentType); var doc = PlatformCatalog.Instance.TextDocumentFactoryService.CreateTextDocument (buffer, FilePath); doc.Encoding = text.Encoding; SetTextDocument (doc); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/MicrosoftTemplateEngineProjectTemplatingProvider.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/MicrosoftTemplateEngineProjectTemplatingProvider.cs index 1f5c406177..3a27ca6b42 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/MicrosoftTemplateEngineProjectTemplatingProvider.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/MicrosoftTemplateEngineProjectTemplatingProvider.cs @@ -105,6 +105,12 @@ namespace MonoDevelop.Ide.Templates //TODO: Once templates support "D396686C-DE0E-4DE6-906D-291CD29FC5DE" use that to load projects foreach (var path in result.ResultInfo.PrimaryOutputs) { var fullPath = Path.Combine (config.ProjectLocation, GetPath (path)); + if (!File.Exists (fullPath)) { + // Work around a bug in the templating engine with multi project templates + // See https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1016597 + fullPath = fullPath.Replace ("NewApp", config.ProjectName); + } + if (Services.ProjectService.IsSolutionItemFile (fullPath)) workspaceItems.Add (await MonoDevelop.Projects.Services.ProjectService.ReadSolutionItem (new Core.ProgressMonitor (), fullPath)); } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj index 4ec9672141..1136d83ce5 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj @@ -4343,6 +4343,7 @@ <Compile Include="MonoDevelop.Components\Mac\VerticalAlignmentTextCell.cs" /> <Compile Include="MonoDevelop.Ide.TypeSystem\TypeSystemService_WorkspaceRequestRegistration.cs" /> <Compile Include="MonoDevelop.Ide.Gui.Dialogs\NewConfigurationDialog.cs" /> + <Compile Include="MonoDevelop.Components.AutoTest\AutoTestToolbar.cs" /> </ItemGroup> <ItemGroup Condition="'$(Configuration)' == 'DebugMac' OR '$(Configuration)' == 'ReleaseMac'"> <Compile Include="MonoDevelop.Components\Mac\KeyCodes.cs" /> |