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
path: root/main/src
diff options
context:
space:
mode:
authorLluis Sanchez <llsan@microsoft.com>2019-02-15 20:57:44 +0300
committerLluis Sanchez <llsan@microsoft.com>2019-02-15 21:12:42 +0300
commitca94e4851759c70a3f44e6ed4d2d1f3296ed0bcf (patch)
tree5247748423d0211b13b2dbd1c219a95f8602cb34 /main/src
parent3f08768e1c48470d3c77365bf1225e2f48ad8fbc (diff)
Convert several IDE services into Service instances
The new IdeServices class has references to the core IDE services. Revamped the IDE initialization code. The UI loop is started earlier and that allows starting the services asynchronously. Code that previously was referencing static service classes or services available in IdeApp now reference IdeServices.
Diffstat (limited to 'main/src')
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Composition/CompositionManager.cs50
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Composition/PlatformCatalog.cs30
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/RecentOpen.cs19
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlightingService.cs48
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/DefaultSourceEditorOptions.cs35
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Extensions/IdeCustomizer.cs4
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Fonts/FontService.cs71
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/ProgressMonitorManager.cs158
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/ProgressMonitors.cs132
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/StartupInfo.cs115
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Navigation/NavigationHistoryService.cs378
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksProvider.Legacy.cs100
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksProvider.cs44
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskService.cs84
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskSeverity.cs39
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskStore.cs89
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TextEditing/TextEditorService.cs109
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.MetadataReferenceHandler.cs10
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.ProjectSystemHandler.cs18
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs214
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService.cs262
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService_WorkspaceHandling.cs141
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/AddinError.cs66
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/DesktopService.cs171
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs153
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeInstanceConnection.cs141
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdePreferences.cs69
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeServices.cs113
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeStartup.cs318
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/MonoDevelopOptions.cs96
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs317
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/RootWorkspace.cs333
32 files changed, 2277 insertions, 1650 deletions
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Composition/CompositionManager.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Composition/CompositionManager.cs
index cacad176b2..39e3eaaf25 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Composition/CompositionManager.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Composition/CompositionManager.cs
@@ -45,10 +45,10 @@ namespace MonoDevelop.Ide.Composition
{
/// <summary>
/// The host of the MonoDevelop MEF composition. Uses https://github.com/Microsoft/vs-mef.
- /// </summary>
- public partial class CompositionManager
+ /// </summary>
+ [DefaultServiceImplementation]
+ public partial class CompositionManager: Service
{
- static Task<CompositionManager> creationTask;
static CompositionManager instance;
static readonly Resolver StandardResolver = Resolver.DefaultInstance;
@@ -56,55 +56,44 @@ namespace MonoDevelop.Ide.Composition
new AttributedPartDiscoveryV1 (StandardResolver),
new AttributedPartDiscovery (StandardResolver, true));
- public static CompositionManager Instance {
+ public static CompositionManager Instance {
get {
if (instance == null) {
- var task = InitializeAsync ();
+ var task = Runtime.GetService<CompositionManager> ();
if (!task.IsCompleted && Runtime.IsMainThread) {
LoggingService.LogInfo ("UI thread queried MEF while it was still being built:{0}{1}", Environment.NewLine, Environment.StackTrace);
}
- instance = task.Result;
- }
-
- return instance;
- }
+ instance = task.WaitAndGetResult ();
+ }
+
+ return instance;
+ }
}
- /// <summary>
- /// Starts initializing the MEF composition on a background thread. Thread-safe.
- /// </summary>
- public static Task<CompositionManager> InitializeAsync ()
+ protected override Task OnInitialize (ServiceProvider serviceProvider)
{
- if (creationTask == null) {
- lock (typeof (CompositionManager)) {
- if (creationTask == null) {
- creationTask = Task.Run (() => CreateInstanceAsync ());
- }
- }
- }
-
- return creationTask;
+ return Task.Run (async () => await InitializeInstanceAsync ());
}
/// <summary>
/// Returns an instance of type T that is exported by some composition part. The instance is shared (singleton).
/// </summary>
- public static T GetExportedValue<T> () => Instance.ExportProvider.GetExportedValue<T> ();
+ public T GetExportedValue<T> () => ExportProvider.GetExportedValue<T> ();
/// <summary>
/// Returns all instances of type T that are exported by some composition part. The instances are shared (singletons).
/// </summary>
- public static IEnumerable<T> GetExportedValues<T> () => Instance.ExportProvider.GetExportedValues<T> ();
+ public IEnumerable<T> GetExportedValues<T> () => ExportProvider.GetExportedValues<T> ();
/// <summary>
/// Returns a lazy holding the instance of type T that is exported by some composition part. The instance is shared (singleton).
/// </summary>
- public static Lazy<T> GetExport<T> () => new Lazy<T> (() => Instance.ExportProvider.GetExportedValue<T> ());
+ public static Lazy<T> GetExport<T> () => new Lazy<T> (() => Instance.ExportProvider.GetExportedValue<T> ());
/// <summary>
/// Returns a lazy holding all instances of type T that are exported by some composition part. The instances are shared (singletons).
/// </summary>
- public static Lazy<IEnumerable<T>> GetExports<T> () => new Lazy<IEnumerable<T>> (() => Instance.ExportProvider.GetExportedValues<T> ());
+ public static Lazy<IEnumerable<T>> GetExports<T> () => new Lazy<IEnumerable<T>> (() => Instance.ExportProvider.GetExportedValues<T> ());
public RuntimeComposition RuntimeComposition { get; private set; }
public IExportProviderFactory ExportProviderFactory { get; private set; }
@@ -116,13 +105,6 @@ namespace MonoDevelop.Ide.Composition
{
}
- static async Task<CompositionManager> CreateInstanceAsync ()
- {
- var compositionManager = new CompositionManager ();
- await compositionManager.InitializeInstanceAsync ();
- return compositionManager;
- }
-
async Task InitializeInstanceAsync ()
{
var assemblies = ReadAssembliesFromAddins ();
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Composition/PlatformCatalog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Composition/PlatformCatalog.cs
index 2cd0faaae1..d26e9d4644 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Composition/PlatformCatalog.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Composition/PlatformCatalog.cs
@@ -1,42 +1,30 @@
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-//
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+//
using System;
-using System.Linq;
-using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel.Composition;
-using System.ComponentModel.Composition.Hosting;
-using System.Reflection;
-using System.Diagnostics;
-using System.ComponentModel;
using System.IO;
using System.Threading;
-using System.Threading.Tasks;
-
-using Mono.Addins;
-using MonoDevelop.Core;
-using MonoDevelop.Core.AddIns;
-using MonoDevelop.Ide.Editor.Highlighting;
-using MonoDevelop.Ide.Composition;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Tagging;
using Microsoft.VisualStudio.Utilities;
-
+using MonoDevelop.Ide.Composition;
+
namespace Microsoft.VisualStudio.Platform
-{
- [Export]
+{
+ [Export]
public class PlatformCatalog
{
static PlatformCatalog instance;
public static PlatformCatalog Instance {
get {
if (instance == null) {
- instance = CompositionManager.GetExportedValue<PlatformCatalog> ();
+ instance = CompositionManager.Instance.GetExportedValue<PlatformCatalog> ();
}
return instance;
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/RecentOpen.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/RecentOpen.cs
index 84ec664cb0..286b85f889 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/RecentOpen.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/RecentOpen.cs
@@ -1,4 +1,4 @@
-//
+//
// RecentOpen.cs
//
// Author:
@@ -34,6 +34,7 @@ using System.IO;
using MonoDevelop.Core;
using System.Linq;
+using MonoDevelop.Projects;
namespace MonoDevelop.Ide.Desktop
{
@@ -84,7 +85,7 @@ namespace MonoDevelop.Ide.Desktop
IList<RecentFile> Get (string grp)
{
var gp = recentFiles.GetItemsInGroup (grp);
- return gp.Select (i => new RecentFile (i.LocalPath, i.Private, i.Timestamp)).ToList ();
+ return gp.Select (i => new RecentFile (this, i.LocalPath, i.Private, i.Timestamp)).ToList ();
}
public override void ClearProjects ()
@@ -163,6 +164,8 @@ namespace MonoDevelop.Ide.Desktop
favoriteFiles = PropertyService.Get (FavoritesConfigKey, new List<string> ());
}
+ internal DesktopService DesktopService { get; set; }
+
public IList<RecentFile> GetProjects ()
{
var projects = OnGetProjects ();
@@ -172,7 +175,7 @@ namespace MonoDevelop.Ide.Desktop
if (entry != null)
result.Add (entry);
else
- result.Add (new RecentFile (f, Path.GetFileNameWithoutExtension (f), DateTime.Now));
+ result.Add (new RecentFile (this, f, Path.GetFileNameWithoutExtension (f), DateTime.Now));
}
foreach (var e in projects)
if (!result.Contains (e))
@@ -202,7 +205,7 @@ namespace MonoDevelop.Ide.Desktop
protected abstract IList<RecentFile> OnGetProjects ();
protected abstract IList<RecentFile> OnGetFiles ();
- public void AddFile (string fileName, MonoDevelop.Projects.Project project)
+ public void AddFile (string fileName, WorkspaceObject project)
{
var projectName = project != null? project.Name : null;
var displayName = projectName != null?
@@ -234,9 +237,11 @@ namespace MonoDevelop.Ide.Desktop
{
string displayName, fileName;
DateTime timestamp;
+ RecentFiles recenFiles;
- public RecentFile (string fileName, string displayName, DateTime timestamp)
+ public RecentFile (RecentFiles recenFiles, string fileName, string displayName, DateTime timestamp)
{
+ this.recenFiles = recenFiles;
this.fileName = fileName;
this.displayName = displayName;
this.timestamp = timestamp;
@@ -244,10 +249,10 @@ namespace MonoDevelop.Ide.Desktop
public bool IsFavorite {
get {
- return DesktopService.RecentFiles.IsFavoriteFile (fileName);
+ return recenFiles.IsFavoriteFile (fileName);
}
set {
- DesktopService.RecentFiles.SetFavoriteFile (fileName, value);
+ recenFiles.SetFavoriteFile (fileName, value);
}
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlightingService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlightingService.cs
index 216d3b88e2..63f28b5746 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlightingService.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlightingService.cs
@@ -1,4 +1,4 @@
-// SyntaxModeService.cs
+// SyntaxModeService.cs
//
// Author:
// Mike Krüger <mkrueger@novell.com>
@@ -51,15 +51,24 @@ namespace MonoDevelop.Ide.Editor.Highlighting
static LanguageBundle extensionBundle = new LanguageBundle ("extensions", null) { BuiltInBundle = true };
internal static LanguageBundle userThemeBundle = new LanguageBundle ("userThemes", null) { BuiltInBundle = true };
static List<LanguageBundle> languageBundles = new List<LanguageBundle> ();
+ static bool stylesInitialized;
+
+ public static FilePath SyntaxModePath {
+ get {
+ return UserProfile.Current.UserDataRoot.Combine ("ColorThemes");
+ }
+ }
internal static IEnumerable<LanguageBundle> AllBundles {
get {
+ InitializeStylesAndModes ();
return languageBundles;
}
}
public static string[] Styles {
get {
+ InitializeStylesAndModes ();
var result = new List<string> ();
foreach (var bundle in languageBundles) {
for (int i = 0; i < bundle.EditorThemes.Count; ++i) {
@@ -73,7 +82,8 @@ namespace MonoDevelop.Ide.Editor.Highlighting
}
public static bool ContainsStyle (string styleName)
- {
+ {
+ InitializeStylesAndModes ();
foreach (var bundle in languageBundles) {
for (int i = 0; i < bundle.EditorThemes.Count; ++i) {
var style = bundle.EditorThemes[i];
@@ -146,6 +156,7 @@ namespace MonoDevelop.Ide.Editor.Highlighting
internal static IEnumerable<TmSetting> GetSettings (ScopeStack scope)
{
+ InitializeStylesAndModes ();
foreach (var bundle in languageBundles) {
foreach (var setting in bundle.Settings) {
if (!setting.Scopes.Any (s => TmSetting.IsSettingMatch (scope, s)))
@@ -156,6 +167,7 @@ namespace MonoDevelop.Ide.Editor.Highlighting
}
internal static IEnumerable<TmSnippet> GetSnippets (ScopeStack scope)
{
+ InitializeStylesAndModes ();
foreach (var bundle in languageBundles) {
foreach (var setting in bundle.Snippets) {
if (!setting.Scopes.Any (s => TmSetting.IsSettingMatch (scope, s)))
@@ -167,6 +179,7 @@ namespace MonoDevelop.Ide.Editor.Highlighting
public static EditorTheme GetEditorTheme (string name)
{
+ InitializeStylesAndModes ();
foreach (var bundle in languageBundles) {
for (int i = 0; i < bundle.EditorThemes.Count; ++i) {
var style = bundle.EditorThemes[i];
@@ -187,11 +200,13 @@ namespace MonoDevelop.Ide.Editor.Highlighting
internal static void Remove (EditorTheme style)
{
+ InitializeStylesAndModes ();
userThemeBundle.Remove (style);
}
internal static void Remove (LanguageBundle style)
{
+ InitializeStylesAndModes ();
languageBundles.Remove (style);
}
@@ -201,6 +216,29 @@ namespace MonoDevelop.Ide.Editor.Highlighting
return result;
}
+ static void InitializeStylesAndModes ()
+ {
+ if (!stylesInitialized) {
+ stylesInitialized = true;
+ LoadCustomStylesAndModes ();
+ }
+ }
+
+ public static void LoadCustomStylesAndModes ()
+ {
+ bool success = true;
+ if (!Directory.Exists (SyntaxModePath)) {
+ try {
+ Directory.CreateDirectory (SyntaxModePath);
+ } catch (Exception e) {
+ success = false;
+ LoggingService.LogError ("Can't create syntax mode directory", e);
+ }
+ }
+ if (success)
+ SyntaxHighlightingService.LoadStylesAndModesInPath (SyntaxModePath);
+ }
+
internal static void LoadStylesAndModesInPath (string path)
{
foreach (string file in Directory.GetFiles (path)) {
@@ -738,7 +776,7 @@ namespace MonoDevelop.Ide.Editor.Highlighting
static SyntaxHighlightingDefinition GetSyntaxHighlightingDefinitionByMimeType (string mimeType)
{
- foreach (string mt in DesktopService.GetMimeTypeInheritanceChain (mimeType)) {
+ foreach (string mt in IdeServices.DesktopService.GetMimeTypeInheritanceChain (mimeType)) {
if (mimeType == "application/octet-stream" || mimeType == "text/plain")
return null;
@@ -746,7 +784,7 @@ namespace MonoDevelop.Ide.Editor.Highlighting
foreach (var h in bundle.Highlightings) {
foreach (var fe in h.FileTypes) {
var uri = fe.StartsWith (".", StringComparison.Ordinal) ? "a" + fe : "a." + fe;
- var mime = DesktopService.GetMimeTypeForUri (uri);
+ var mime = IdeServices.DesktopService.GetMimeTypeForUri (uri);
if (mimeType == mime) {
return h.GetSyntaxHighlightingDefinition ();
}
@@ -766,7 +804,7 @@ namespace MonoDevelop.Ide.Editor.Highlighting
}
if (mimeType == null) {
- mimeType = DesktopService.GetMimeTypeForUri (fileName);
+ mimeType = IdeServices.DesktopService.GetMimeTypeForUri (fileName);
}
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/DefaultSourceEditorOptions.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/DefaultSourceEditorOptions.cs
index 332b67a09e..db7317a9ee 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/DefaultSourceEditorOptions.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/DefaultSourceEditorOptions.cs
@@ -30,6 +30,7 @@ using MonoDevelop.Ide.Fonts;
using MonoDevelop.Ide.Editor.Extension;
using Microsoft.VisualStudio.CodingConventions;
using System.Threading.Tasks;
+using MonoDevelop.Ide.TypeSystem;
namespace MonoDevelop.Ide.Editor
{
@@ -52,25 +53,25 @@ namespace MonoDevelop.Ide.Editor
public sealed class DefaultSourceEditorOptions : ITextEditorOptions
{
static DefaultSourceEditorOptions instance;
- //static TextStylePolicy defaultPolicy;
+ static ITextEditorOptions plainEditor;
static bool inited;
ICodingConventionContext context;
public static DefaultSourceEditorOptions Instance {
- get { return instance; }
+ get {
+ Init ();
+ return instance;
+ }
}
public static ITextEditorOptions PlainEditor {
- get;
- private set;
- }
-
- static DefaultSourceEditorOptions ()
- {
- Init ();
+ get {
+ Init ();
+ return plainEditor;
+ }
}
- public static void Init ()
+ static void Init ()
{
if (inited)
return;
@@ -80,7 +81,7 @@ namespace MonoDevelop.Ide.Editor
instance = new DefaultSourceEditorOptions (policy);
MonoDevelop.Projects.Policies.PolicyService.DefaultPolicies.PolicyChanged += instance.HandlePolicyChanged;
- PlainEditor = new PlainEditorOptions ();
+ plainEditor = new PlainEditorOptions ();
}
internal void FireChange ()
@@ -266,8 +267,10 @@ namespace MonoDevelop.Ide.Editor
wordNavigationStyle = ConfigurationProperty.Create ("WordNavigationStyle", WordNavigationStyle.Windows);
UpdateStylePolicy (currentPolicy);
- FontService.RegisterFontChangedCallback ("Editor", UpdateFont);
- FontService.RegisterFontChangedCallback ("MessageBubbles", UpdateFont);
+ Runtime.ServiceProvider.WhenServiceInitialized<FontService> (s => {
+ s.RegisterFontChangedCallback ("Editor", UpdateFont);
+ s.RegisterFontChangedCallback ("MessageBubbles", UpdateFont);
+ });
IdeApp.Preferences.ColorScheme.Changed += OnColorSchemeChanged;
}
@@ -745,7 +748,7 @@ namespace MonoDevelop.Ide.Editor
public string FontName {
get {
- return FontService.FilterFontName (FontService.GetUnderlyingFontName ("Editor"));
+ return IdeApp.FontService.FilterFontName (IdeApp.FontService.GetUnderlyingFontName ("Editor"));
}
set {
throw new InvalidOperationException ("Set font through font service");
@@ -754,7 +757,7 @@ namespace MonoDevelop.Ide.Editor
public string GutterFontName {
get {
- return FontService.FilterFontName (FontService.GetUnderlyingFontName ("Editor"));
+ return IdeApp.FontService.FilterFontName (IdeApp.FontService.GetUnderlyingFontName ("Editor"));
}
set {
throw new InvalidOperationException ("Set font through font service");
@@ -848,7 +851,7 @@ namespace MonoDevelop.Ide.Editor
public void Dispose ()
{
- FontService.RemoveCallback (UpdateFont);
+ IdeApp.FontService.RemoveCallback (UpdateFont);
IdeApp.Preferences.ColorScheme.Changed -= OnColorSchemeChanged;
if (context != null)
context.CodingConventionsChangedAsync -= UpdateContextOptions;
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Extensions/IdeCustomizer.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Extensions/IdeCustomizer.cs
index ad13837725..52dadbbabf 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Extensions/IdeCustomizer.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Extensions/IdeCustomizer.cs
@@ -40,7 +40,7 @@ namespace MonoDevelop.Ide.Extensions
/// <summary>
/// Called just after the initializer is created
/// </summary>
- internal protected virtual void Initialize ()
+ internal protected virtual void Initialize (StartupInfo startupInfo)
{
}
@@ -54,7 +54,7 @@ namespace MonoDevelop.Ide.Extensions
/// <summary>
/// Called when the Ide has been initialized
/// </summary>
- internal protected virtual void OnIdeInitialized (bool hideWelcomePage)
+ internal protected virtual void OnIdeInitialized ()
{
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Fonts/FontService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Fonts/FontService.cs
index 815c4360c5..df7eab8d2e 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Fonts/FontService.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Fonts/FontService.cs
@@ -1,5 +1,5 @@
-//
-// FontService.cs
+//
+// IdeApp.FontService.cs
//
// Author:
// Mike Krüger <mkrueger@novell.com>
@@ -27,44 +27,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading.Tasks;
using Mono.Addins;
using MonoDevelop.Core;
using Pango;
namespace MonoDevelop.Ide.Fonts
{
- public static class FontService
+ [DefaultServiceImplementation]
+ public class FontService: Service
{
- static List<FontDescriptionCodon> fontDescriptions = new List<FontDescriptionCodon> ();
- static Dictionary<string, FontDescription> loadedFonts = new Dictionary<string, FontDescription> ();
- static Properties fontProperties;
+ List<FontDescriptionCodon> fontDescriptions = new List<FontDescriptionCodon> ();
+ Dictionary<string, FontDescription> loadedFonts = new Dictionary<string, FontDescription> ();
+ Properties fontProperties;
+ DesktopService desktopService;
- static string defaultMonospaceFontName = String.Empty;
- static FontDescription defaultMonospaceFont = new FontDescription ();
+ string defaultMonospaceFontName = String.Empty;
+ FontDescription defaultMonospaceFont = new FontDescription ();
- static void LoadDefaults ()
+ void LoadDefaults ()
{
if (defaultMonospaceFont != null) {
defaultMonospaceFont.Dispose ();
}
#pragma warning disable 618
- defaultMonospaceFontName = DesktopService.DefaultMonospaceFont;
+ defaultMonospaceFontName = desktopService.DefaultMonospaceFont;
defaultMonospaceFont = FontDescription.FromString (defaultMonospaceFontName);
#pragma warning restore 618
}
- internal static IEnumerable<FontDescriptionCodon> FontDescriptions {
+ internal IEnumerable<FontDescriptionCodon> FontDescriptions {
get {
return fontDescriptions;
}
}
-
- internal static void Initialize ()
- {
- if (fontProperties != null)
- throw new InvalidOperationException ("Already initialized");
+ protected override async Task OnInitialize (ServiceProvider serviceProvider)
+ {
+ desktopService = await serviceProvider.GetService<DesktopService> ();
fontProperties = PropertyService.Get ("FontProperties", new Properties ());
AddinManager.AddExtensionNodeHandler ("/MonoDevelop/Ide/Fonts", delegate(object sender, ExtensionNodeEventArgs args) {
@@ -84,28 +85,28 @@ namespace MonoDevelop.Ide.Fonts
LoadDefaults ();
}
- public static FontDescription MonospaceFont { get { return defaultMonospaceFont; } }
- public static FontDescription SansFont { get { return Gui.Styles.DefaultFont; } }
+ public FontDescription MonospaceFont { get { return defaultMonospaceFont; } }
+ public FontDescription SansFont { get { return Gui.Styles.DefaultFont; } }
- public static string MonospaceFontName { get { return defaultMonospaceFontName; } }
- public static string SansFontName { get { return Gui.Styles.DefaultFontName; } }
+ public string MonospaceFontName { get { return defaultMonospaceFontName; } }
+ public string SansFontName { get { return Gui.Styles.DefaultFontName; } }
[Obsolete ("Use MonospaceFont")]
- public static FontDescription DefaultMonospaceFontDescription {
+ public FontDescription DefaultMonospaceFontDescription {
get {
if (defaultMonospaceFont == null)
- defaultMonospaceFont = LoadFont (DesktopService.DefaultMonospaceFont);
+ defaultMonospaceFont = LoadFont (desktopService.DefaultMonospaceFont);
return defaultMonospaceFont;
}
}
- static FontDescription LoadFont (string name)
+ FontDescription LoadFont (string name)
{
var fontName = FilterFontName (name);
return FontDescription.FromString (fontName);
}
- public static string FilterFontName (string name)
+ public string FilterFontName (string name)
{
switch (name) {
case "_DEFAULT_MONOSPACE":
@@ -117,7 +118,7 @@ namespace MonoDevelop.Ide.Fonts
}
}
- public static string GetUnderlyingFontName (string name)
+ public string GetUnderlyingFontName (string name)
{
var result = fontProperties.Get<string> (name);
@@ -142,14 +143,14 @@ namespace MonoDevelop.Ide.Fonts
/// <param name='createDefaultFont'>
/// If set to <c>false</c> and no custom font has been set, the method will return null.
/// </param>
- public static FontDescription GetFontDescription (string name, bool createDefaultFont = true)
+ public FontDescription GetFontDescription (string name, bool createDefaultFont = true)
{
if (loadedFonts.ContainsKey (name))
return loadedFonts [name];
return loadedFonts [name] = LoadFont (GetUnderlyingFontName (name));
}
- internal static FontDescriptionCodon GetFont (string name)
+ internal FontDescriptionCodon GetFont (string name)
{
foreach (var d in fontDescriptions) {
if (d.Name == name)
@@ -159,7 +160,7 @@ namespace MonoDevelop.Ide.Fonts
return null;
}
- public static void SetFont (string name, string value)
+ public void SetFont (string name, string value)
{
if (loadedFonts.ContainsKey (name))
loadedFonts.Remove (name);
@@ -176,20 +177,20 @@ namespace MonoDevelop.Ide.Fonts
}
}
- internal static ConfigurationProperty<FontDescription> GetFontProperty (string name)
+ internal ConfigurationProperty<FontDescription> GetFontProperty (string name)
{
return new FontConfigurationProperty (name);
}
- static Dictionary<string, List<Action>> fontChangeCallbacks = new Dictionary<string, List<Action>> ();
- public static void RegisterFontChangedCallback (string fontName, Action callback)
+ Dictionary<string, List<Action>> fontChangeCallbacks = new Dictionary<string, List<Action>> ();
+ public void RegisterFontChangedCallback (string fontName, Action callback)
{
if (!fontChangeCallbacks.ContainsKey (fontName))
fontChangeCallbacks [fontName] = new List<Action> ();
fontChangeCallbacks [fontName].Add (callback);
}
- public static void RemoveCallback (Action callback)
+ public void RemoveCallback (Action callback)
{
foreach (var list in fontChangeCallbacks.Values.ToList ())
list.Remove (callback);
@@ -203,17 +204,17 @@ namespace MonoDevelop.Ide.Fonts
public FontConfigurationProperty (string name)
{
this.name = name;
- FontService.RegisterFontChangedCallback (name, OnChanged);
+ IdeApp.FontService.RegisterFontChangedCallback (name, OnChanged);
}
protected override FontDescription OnGetValue ()
{
- return FontService.GetFontDescription (name);
+ return IdeApp.FontService.GetFontDescription (name);
}
protected override bool OnSetValue (FontDescription value)
{
- FontService.SetFont (name, value.ToString ());
+ IdeApp.FontService.SetFont (name, value.ToString ());
return true;
}
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/ProgressMonitorManager.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/ProgressMonitorManager.cs
new file mode 100644
index 0000000000..1bef639297
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/ProgressMonitorManager.cs
@@ -0,0 +1,158 @@
+//
+// ProgressMonitorManager.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
+//
+// 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.Core;
+using MonoDevelop.Core.Execution;
+using MonoDevelop.Ide.FindInFiles;
+using System.Threading;
+
+namespace MonoDevelop.Ide.Gui
+{
+ [DefaultServiceImplementation(typeof(IdeProgressMonitorManager))]
+ public abstract class ProgressMonitorManager : Service
+ {
+ public ProgressMonitor GetBuildProgressMonitor ()
+ {
+ return OnGetBuildProgressMonitor ();
+ }
+
+ public ProgressMonitor GetCleanProgressMonitor ()
+ {
+ return OnGetCleanProgressMonitor ();
+ }
+
+ public ProgressMonitor GetRebuildProgressMonitor ()
+ {
+ return OnGetRebuildProgressMonitor ();
+ }
+
+ public OutputProgressMonitor GetRunProgressMonitor ()
+ {
+ return GetRunProgressMonitor (null);
+ }
+
+ public OutputProgressMonitor GetRunProgressMonitor (string titleSuffix)
+ {
+ return OnGetRunProgressMonitor (titleSuffix);
+ }
+
+ public OutputProgressMonitor GetToolOutputProgressMonitor (bool bringToFront, CancellationTokenSource cs = null)
+ {
+ return OnGetToolOutputProgressMonitor (bringToFront, cs);
+ }
+
+ public ProgressMonitor GetLoadProgressMonitor (bool lockGui)
+ {
+ return OnGetLoadProgressMonitor (lockGui);
+ }
+
+ public ProgressMonitor GetProjectLoadProgressMonitor (bool lockGui)
+ {
+ return OnGetProjectLoadProgressMonitor (lockGui);
+ }
+
+ public ProgressMonitor GetSaveProgressMonitor (bool lockGui)
+ {
+ return OnGetSaveProgressMonitor (lockGui);
+ }
+
+ public OperationConsole CreateConsole (bool closeOnDispose, CancellationToken cancellationToken)
+ {
+ return OnCreateConsole (closeOnDispose, cancellationToken);
+ }
+
+ public ProgressMonitor GetStatusProgressMonitor (string title, IconId icon, bool showErrorDialogs, bool showTaskTitle, bool lockGui, Pad statusSourcePad, bool showCancelButton)
+ {
+ return OnGetStatusProgressMonitor (title, icon, showErrorDialogs, showTaskTitle, lockGui, statusSourcePad, showCancelButton);
+ }
+
+ public ProgressMonitor GetStatusProgressMonitor (string title, IconId icon, bool showErrorDialogs, bool showTaskTitle = true, bool lockGui = false, Pad statusSourcePad = null)
+ {
+ return GetStatusProgressMonitor (title, icon, showErrorDialogs, showTaskTitle, lockGui, statusSourcePad, showCancelButton: false);
+ }
+
+ public ProgressMonitor GetBackgroundProgressMonitor (string title, IconId icon)
+ {
+ return OnGetBackgroundProgressMonitor (title, icon);
+ }
+
+ public OutputProgressMonitor GetOutputProgressMonitor (string title, IconId icon, bool bringToFront, bool allowMonitorReuse, bool visible = true)
+ {
+ return GetOutputProgressMonitor (null, title, icon, bringToFront, allowMonitorReuse, visible);
+ }
+
+ public OutputProgressMonitor GetOutputProgressMonitor (string id, string title, IconId icon, bool bringToFront, bool allowMonitorReuse, bool visible = true)
+ {
+ return GetOutputProgressMonitor (id, title, icon, bringToFront, allowMonitorReuse, null, visible);
+ }
+
+ public OutputProgressMonitor GetOutputProgressMonitor (string id, string title, IconId icon, bool bringToFront, bool allowMonitorReuse, string titleSuffix, bool visible = true)
+ {
+ return OnGetOutputProgressMonitor (id, title, icon, bringToFront, allowMonitorReuse, titleSuffix, visible);
+ }
+
+ public SearchProgressMonitor GetSearchProgressMonitor (bool bringToFront, bool focusPad = false, CancellationTokenSource cancellationTokenSource = null)
+ {
+ return OnGetSearchProgressMonitor (bringToFront, focusPad, cancellationTokenSource);
+ }
+
+ public OperationConsoleFactory ConsoleFactory {
+ get { return OnGetConsoleFactory (); }
+ }
+
+ protected abstract OperationConsoleFactory OnGetConsoleFactory ();
+
+ protected abstract ProgressMonitor OnGetBuildProgressMonitor ();
+
+ protected abstract ProgressMonitor OnGetCleanProgressMonitor ();
+
+ protected abstract ProgressMonitor OnGetRebuildProgressMonitor ();
+
+ protected abstract OutputProgressMonitor OnGetRunProgressMonitor (string titleSuffix);
+
+ protected abstract OutputProgressMonitor OnGetToolOutputProgressMonitor (bool bringToFront, CancellationTokenSource cs);
+
+ protected abstract ProgressMonitor OnGetLoadProgressMonitor (bool lockGui);
+
+ protected abstract ProgressMonitor OnGetProjectLoadProgressMonitor (bool lockGui);
+
+ protected abstract ProgressMonitor OnGetSaveProgressMonitor (bool lockGui);
+
+ protected abstract OperationConsole OnCreateConsole (bool closeOnDispose, CancellationToken cancellationToken);
+
+ protected abstract ProgressMonitor OnGetStatusProgressMonitor (string title, IconId icon, bool showErrorDialogs, bool showTaskTitle, bool lockGui, Pad statusSourcePad, bool showCancelButton);
+
+ protected abstract ProgressMonitor OnGetBackgroundProgressMonitor (string title, IconId icon);
+
+ protected abstract OutputProgressMonitor OnGetOutputProgressMonitor (string id, string title, IconId icon, bool bringToFront, bool allowMonitorReuse, string titleSuffix, bool visible);
+
+ protected abstract SearchProgressMonitor OnGetSearchProgressMonitor (bool bringToFront, bool focusPad, CancellationTokenSource cancellationTokenSource);
+ }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/ProgressMonitors.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/ProgressMonitors.cs
index ea0811283e..7c18b46f77 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/ProgressMonitors.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/ProgressMonitors.cs
@@ -40,126 +40,119 @@ using MonoDevelop.Ide.FindInFiles;
using MonoDevelop.Components.Docking;
using System.Threading;
using MonoDevelop.Ide.Gui.Components;
+using System.Threading.Tasks;
namespace MonoDevelop.Ide.Gui
{
- public class ProgressMonitorManager : GuiSyncObject
+ public class IdeProgressMonitorManager : ProgressMonitorManager
{
List<Pad> searchMonitors = new List<Pad> ();
List<Pad> outputMonitors = new List<Pad> ();
-
+
/******************************/
- internal void Initialize ()
+ protected override Task OnInitialize (ServiceProvider serviceProvider)
{
+ return Task.CompletedTask;
}
-
- public ProgressMonitor GetBuildProgressMonitor ()
+
+ protected override ProgressMonitor OnGetBuildProgressMonitor ()
{
return GetBuildProgressMonitor (GettextCatalog.GetString ("Building..."));
}
-
- public ProgressMonitor GetCleanProgressMonitor ()
+
+ protected override ProgressMonitor OnGetCleanProgressMonitor ()
{
return GetBuildProgressMonitor (GettextCatalog.GetString ("Cleaning..."));
}
-
- public ProgressMonitor GetRebuildProgressMonitor ()
+
+ protected override ProgressMonitor OnGetRebuildProgressMonitor ()
{
return GetBuildProgressMonitor (GettextCatalog.GetString ("Rebuilding..."));
}
- private ProgressMonitor GetBuildProgressMonitor (string statusText)
+ ProgressMonitor GetBuildProgressMonitor (string statusText)
{
- Pad pad = IdeApp.Workbench.GetPad<ErrorListPad> ();
- ErrorListPad errorPad = (ErrorListPad) pad.Content;
- AggregatedProgressMonitor mon = new AggregatedProgressMonitor (errorPad.GetBuildProgressMonitor ());
- mon.AddFollowerMonitor (GetStatusProgressMonitor (statusText, Stock.StatusBuild, false, true, false, pad, true));
- return mon;
+ return Runtime.RunInMainThread (() => {
+ Pad pad = IdeApp.Workbench.GetPad<ErrorListPad> ();
+ ErrorListPad errorPad = (ErrorListPad)pad.Content;
+ AggregatedProgressMonitor mon = new AggregatedProgressMonitor (errorPad.GetBuildProgressMonitor ());
+ mon.AddFollowerMonitor (GetStatusProgressMonitor (statusText, Stock.StatusBuild, false, true, false, pad, true));
+ return mon;
+ }).Result;
}
- public OutputProgressMonitor GetRunProgressMonitor ()
- {
- return GetRunProgressMonitor (null);
- }
-
- public OutputProgressMonitor GetRunProgressMonitor (string titleSuffix)
+ protected override OutputProgressMonitor OnGetRunProgressMonitor (string titleSuffix)
{
return GetOutputProgressMonitor ("MonoDevelop.Ide.ApplicationOutput", GettextCatalog.GetString ("Application Output"), Stock.PadExecute, false, true, titleSuffix);
}
-
- public OutputProgressMonitor GetToolOutputProgressMonitor (bool bringToFront, CancellationTokenSource cs = null)
+
+ protected override OutputProgressMonitor OnGetToolOutputProgressMonitor (bool bringToFront, CancellationTokenSource cs = null)
{
return GetOutputProgressMonitor ("MonoDevelop.Ide.ToolOutput", GettextCatalog.GetString ("Tool Output"), Stock.PadExecute, bringToFront, true);
}
-
- public ProgressMonitor GetLoadProgressMonitor (bool lockGui)
+
+ protected override ProgressMonitor OnGetLoadProgressMonitor (bool lockGui)
{
return GetStatusProgressMonitor (GettextCatalog.GetString ("Loading..."), Stock.StatusSolutionOperation, true, false, lockGui);
}
-
- public ProgressMonitor GetProjectLoadProgressMonitor (bool lockGui)
+
+ protected override ProgressMonitor OnGetProjectLoadProgressMonitor (bool lockGui)
{
- return new GtkProjectLoadProgressMonitor (GetLoadProgressMonitor (lockGui));
+ return Runtime.RunInMainThread (() => {
+ return new GtkProjectLoadProgressMonitor (GetLoadProgressMonitor (lockGui));
+ }).Result;
}
-
- public ProgressMonitor GetSaveProgressMonitor (bool lockGui)
+
+ protected override ProgressMonitor OnGetSaveProgressMonitor (bool lockGui)
{
return GetStatusProgressMonitor (GettextCatalog.GetString ("Saving..."), Stock.StatusSolutionOperation, true, false, lockGui);
}
-
- public OperationConsole CreateConsole (bool closeOnDispose, CancellationToken cancellationToken)
+
+ protected override OperationConsole OnCreateConsole (bool closeOnDispose, CancellationToken cancellationToken)
{
return ((OutputProgressMonitor)GetOutputProgressMonitor ("MonoDevelop.Ide.ApplicationOutput", GettextCatalog.GetString ("Application Output"), Stock.MessageLog, false, true)).Console;
}
- CustomConsoleFactory customConsoleFactory = new CustomConsoleFactory ();
- public OperationConsoleFactory ConsoleFactory {
- get { return customConsoleFactory; }
- }
-
- class CustomConsoleFactory: OperationConsoleFactory
+ protected override ProgressMonitor OnGetStatusProgressMonitor (string title, IconId icon, bool showErrorDialogs, bool showTaskTitle, bool lockGui, Pad statusSourcePad, bool showCancelButton)
{
- protected override OperationConsole OnCreateConsole (CreateConsoleOptions options)
- {
- return ((OutputProgressMonitor)IdeApp.Workbench.ProgressMonitors.GetOutputProgressMonitor ("MonoDevelop.Ide.ApplicationOutput", GettextCatalog.GetString ("Application Output"), Stock.MessageLog, options.BringToFront, true, titleSuffix:options.Title)).Console;
- }
+ return Runtime.RunInMainThread (() => {
+ return new StatusProgressMonitor (title, icon, showErrorDialogs, showTaskTitle, lockGui, statusSourcePad, showCancelButton);
+ }).Result;
}
- /******************************/
- public ProgressMonitor GetStatusProgressMonitor (string title, IconId icon, bool showErrorDialogs, bool showTaskTitle, bool lockGui, Pad statusSourcePad, bool showCancelButton)
- {
- return new StatusProgressMonitor (title, icon, showErrorDialogs, showTaskTitle, lockGui, statusSourcePad, showCancelButton);
- }
-
- public ProgressMonitor GetStatusProgressMonitor (string title, IconId icon, bool showErrorDialogs, bool showTaskTitle = true, bool lockGui = false, Pad statusSourcePad = null)
- {
- return GetStatusProgressMonitor (title, icon, showErrorDialogs, showTaskTitle, lockGui, statusSourcePad, showCancelButton: false);
- }
-
- public ProgressMonitor GetBackgroundProgressMonitor (string title, IconId icon)
+ protected override ProgressMonitor OnGetBackgroundProgressMonitor (string title, IconId icon)
{
- return new BackgroundProgressMonitor (title, icon);
+ return Runtime.RunInMainThread (() => {
+ return new BackgroundProgressMonitor (title, icon);
+ }).Result;
}
- public OutputProgressMonitor GetOutputProgressMonitor (string title, IconId icon, bool bringToFront, bool allowMonitorReuse, bool visible = true)
+ protected override OutputProgressMonitor OnGetOutputProgressMonitor (string id, string title, IconId icon, bool bringToFront, bool allowMonitorReuse, string titleSuffix, bool visible)
{
- return GetOutputProgressMonitor (null, title, icon, bringToFront, allowMonitorReuse, visible);
+ return Runtime.RunInMainThread (() => {
+ if (!string.IsNullOrEmpty (titleSuffix)) {
+ title += " - " + titleSuffix;
+ }
+ Pad pad = CreateMonitorPad (id, title, icon, bringToFront, allowMonitorReuse, true);
+ pad.Visible = visible;
+ return ((DefaultMonitorPad)pad.Content).BeginProgress (title);
+ }).Result;
}
- public OutputProgressMonitor GetOutputProgressMonitor (string id, string title, IconId icon, bool bringToFront, bool allowMonitorReuse, bool visible = true)
+ CustomConsoleFactory customConsoleFactory = new CustomConsoleFactory ();
+
+ protected override OperationConsoleFactory OnGetConsoleFactory ()
{
- return GetOutputProgressMonitor (id, title, icon, bringToFront, allowMonitorReuse, null, visible);
+ return customConsoleFactory;
}
-
- public OutputProgressMonitor GetOutputProgressMonitor (string id, string title, IconId icon, bool bringToFront, bool allowMonitorReuse, string titleSuffix, bool visible = true)
+
+ class CustomConsoleFactory : OperationConsoleFactory
{
- if (!string.IsNullOrEmpty (titleSuffix)) {
- title += " - " + titleSuffix;
+ protected override OperationConsole OnCreateConsole (CreateConsoleOptions options)
+ {
+ return ((OutputProgressMonitor)IdeApp.Workbench.ProgressMonitors.GetOutputProgressMonitor ("MonoDevelop.Ide.ApplicationOutput", GettextCatalog.GetString ("Application Output"), Stock.MessageLog, options.BringToFront, true, titleSuffix: options.Title)).Console;
}
- Pad pad = CreateMonitorPad (id, title, icon, bringToFront, allowMonitorReuse, true);
- pad.Visible = visible;
- return ((DefaultMonitorPad) pad.Content).BeginProgress (title);
}
/// <summary>
@@ -186,6 +179,8 @@ namespace MonoDevelop.Ide.Gui
internal Pad CreateMonitorPad (string id, string title, string icon, bool bringToFront, bool allowMonitorReuse, bool show)
{
+ Runtime.AssertMainThread ();
+
Pad pad = null;
if (icon == null)
icon = Stock.OutputIcon;
@@ -280,8 +275,11 @@ namespace MonoDevelop.Ide.Gui
pad.Destroy ();
}
- public SearchProgressMonitor GetSearchProgressMonitor (bool bringToFront, bool focusPad = false, CancellationTokenSource cancellationTokenSource = null)
+ protected override SearchProgressMonitor OnGetSearchProgressMonitor (bool bringToFront, bool focusPad, CancellationTokenSource cancellationTokenSource)
{
+ if (!Runtime.IsMainThread)
+ return Runtime.RunInMainThread (() => GetSearchProgressMonitor (bringToFront, focusPad, cancellationTokenSource)).Result;
+
Pad pad = null;
string title = GettextCatalog.GetString ("Search Results");
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/StartupInfo.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/StartupInfo.cs
deleted file mode 100644
index 40b6be2273..0000000000
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/StartupInfo.cs
+++ /dev/null
@@ -1,115 +0,0 @@
-//
-// StartupInfo.cs:
-//
-// Authors:
-// Christian Hergert <christian.hergert@gmail.com>
-// Todd Berman <tberman@off.net>
-// John Luke <john.luke@gmail.com>
-//
-// Copyright (C) 2005, Christian Hergert
-//
-// 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.IO;
-using System.Collections.Generic;
-using System.Text.RegularExpressions;
-using System.Linq;
-
-namespace MonoDevelop.Ide.Gui
-{
- internal class StartupInfo
- {
- List<FileOpenInformation> requestedFileList = new List<FileOpenInformation> ();
- List<string> parameterList = new List<string> ();
-
- public IList<string> ParameterList {
- get { return parameterList; }
- }
-
- public IEnumerable<FileOpenInformation> RequestedFileList {
- get { return requestedFileList; }
- }
-
- public bool HasFiles {
- get { return requestedFileList.Count > 0; }
- }
-
- public bool HasSolutionFile {
- get {
- return requestedFileList.Any (f => File.Exists (f.FileName) && (Services.ProjectService.IsWorkspaceItemFile (f.FileName) || Services.ProjectService.IsSolutionItemFile (f.FileName)));
- }
- }
-
- internal bool Restarted { get; set; }
-
- /// <summary>
- /// Set to true if a project was opened on startup.
- /// </summary>
- internal bool OpenedRecentProject { get; set; }
-
- /// <summary>
- /// Set to true if files were opened on startup.
- /// </summary>
- internal bool OpenedFiles { get; set; }
-
- /// <summary>
- /// Matches a filename string with optional line and column
- /// (/foo/bar/blah.cs;22;31)
- /// </summary>
- public static readonly Regex FileExpression = new Regex (@"^(?<filename>[^;]+)(;(?<line>\d+))?(;(?<column>\d+))?$", RegexOptions.Compiled);
-
- public StartupInfo (IEnumerable<string> args)
- {
- foreach (string arg in args) {
- string a = arg;
- Match fileMatch = FileExpression.Match (a);
-
- // this does not yet work with relative paths
- if (a[0] == '~') {
- var sf = MonoDevelop.Core.Platform.IsWindows ? Environment.SpecialFolder.UserProfile : Environment.SpecialFolder.Personal;
- a = Path.Combine (Environment.GetFolderPath (sf), a.Substring (1));
- }
-
- if (fileMatch != null && fileMatch.Success) {
- string filename = fileMatch.Groups["filename"].Value;
- if (File.Exists (filename)) {
- int line = 1, column = 1;
- filename = Path.GetFullPath (filename);
- if (fileMatch.Groups["line"].Success)
- int.TryParse (fileMatch.Groups["line"].Value, out line);
- if (fileMatch.Groups["column"].Success)
- int.TryParse (fileMatch.Groups["column"].Value, out column);
- var file = new FileOpenInformation (filename, null, line, column, OpenDocumentOptions.Default);
- requestedFileList.Add (file);
- }
- } else if (a[0] == '-' || a[0] == '/') {
- int markerLength = 1;
-
- if (a.Length >= 2 && a[0] == '-' && a[1] == '-') {
- markerLength = 2;
- }
-
- parameterList.Add(a.Substring (markerLength));
- }
- }
- }
- }
-}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Navigation/NavigationHistoryService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Navigation/NavigationHistoryService.cs
index 1189a325a3..91ad434dac 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Navigation/NavigationHistoryService.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Navigation/NavigationHistoryService.cs
@@ -1,120 +1,150 @@
-//
-// NavigationHistoryService.cs
-//
+//
+// NavigationHistoryManager.cs
+//
// Author:
-// Michael Hutchinson <mhutchinson@novell.com>
-// Lluis Sanchez Gual <lluis@novell.com>
-//
-// Copyright (C) 2008 Novell, Inc (http://www.novell.com)
-//
-// 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.
+// Lluis Sanchez <llsan@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;
using System.Collections.Generic;
-using System.Linq;
-
-using MonoDevelop.Ide.Gui.Content;
+using System.Threading.Tasks;
+using MonoDevelop.Core;
using MonoDevelop.Ide.Gui;
-using MonoDevelop.Projects;
+using MonoDevelop.Ide.Gui.Content;
+using MonoDevelop.Ide.Gui.Documents;
using MonoDevelop.Ide.TextEditing;
+using MonoDevelop.Projects;
namespace MonoDevelop.Ide.Navigation
{
- public static class NavigationHistoryService
+ [DefaultServiceImplementation]
+ public class NavigationHistoryService: IService
{
- static HistoryList history = new HistoryList ();
- static List<Tuple<NavigationPoint, int>> closedHistory = new List<Tuple<NavigationPoint, int>> ();
+ HistoryList history = new HistoryList ();
+ List<Tuple<NavigationPoint, int>> closedHistory = new List<Tuple<NavigationPoint, int>> ();
+ DocumentManager documentManager;
+ RootWorkspace workspace;
+ TextEditorService textEditorService;
//used to prevent re-logging the current point during a switch
- static bool switching;
-
+ bool switching;
+
//whethor the current node is transient. Prevents excession automatic logging when switching rapidly between
//documents
- static bool currentIsTransient;
-
- //the amount of time until a "transient" current node bevomes "permanent"
- static uint TRANSIENT_TIMEOUT = 10000; //ms
-
- static Document currentDoc;
-
- static NavigationHistoryService ()
+ bool currentIsTransient;
+
+ //the amount of time until a "transient" current node becomes "permanent"
+ uint TRANSIENT_TIMEOUT = 10000; //ms
+
+ Document currentDoc;
+
+ Task IService.Dispose ()
{
- IdeApp.Workspace.LastWorkspaceItemClosed += delegate {
- history.Clear ();
- OnHistoryChanged ();
- closedHistory.Clear ();
- OnClosedHistoryChanged ();
- };
-
- IdeApp.Workbench.DocumentOpened += delegate (object sender, DocumentEventArgs e) {
- closedHistory.RemoveAll(np => (np.Item1 as DocumentNavigationPoint)?.FileName == e.Document.FileName);
- OnClosedHistoryChanged ();
- };
-
- IdeApp.Workbench.DocumentClosing += delegate(object sender, DocumentEventArgs e) {
- NavigationPoint point = GetNavPointForDoc (e.Document, true) as DocumentNavigationPoint;
- if (point == null)
- return;
-
- closedHistory.Add (new Tuple<NavigationPoint, int> (point, IdeApp.Workbench.Documents.IndexOf (e.Document)));
- OnClosedHistoryChanged ();
- };
+ workspace.LastWorkspaceItemClosed -= Workspace_LastWorkspaceItemClosed;
+ workspace.FileRenamedInProject -= FileRenamed;
+
+ documentManager.DocumentOpened -= DocumentManager_DocumentOpened;
+ documentManager.DocumentClosing -= DocumentManager_DocumentClosing;
+ documentManager.ActiveDocumentChanged -= ActiveDocChanged;
+
+ textEditorService.LineCountChanged -= LineCountChanged;
+ textEditorService.LineCountChangesCommitted -= CommitCountChanges;
+ textEditorService.LineCountChangesReset -= ResetCountChanges;
+ return Task.CompletedTask;
+ }
+
+ async Task IService.Initialize (ServiceProvider serviceProvider)
+ {
+ workspace = await serviceProvider.GetService<RootWorkspace> ();
+ workspace.LastWorkspaceItemClosed += Workspace_LastWorkspaceItemClosed;
+ workspace.FileRenamedInProject += FileRenamed;
+
+ documentManager = await serviceProvider.GetService<DocumentManager> ();
+ documentManager.DocumentOpened += DocumentManager_DocumentOpened;
+ documentManager.DocumentClosing += DocumentManager_DocumentClosing;
+ documentManager.ActiveDocumentChanged += ActiveDocChanged;
//keep nav points up to date
- TextEditorService.LineCountChanged += LineCountChanged;
- TextEditorService.LineCountChangesCommitted += CommitCountChanges;
- TextEditorService.LineCountChangesReset += ResetCountChanges;
- IdeApp.Workspace.FileRenamedInProject += FileRenamed;
-
- IdeApp.Workbench.ActiveDocumentChanged += ActiveDocChanged;
- }
-
- public static void LogActiveDocument ()
+ textEditorService = await serviceProvider.GetService<TextEditorService> ();
+ textEditorService.LineCountChanged += LineCountChanged;
+ textEditorService.LineCountChangesCommitted += CommitCountChanges;
+ textEditorService.LineCountChangesReset += ResetCountChanges;
+ }
+
+ void Workspace_LastWorkspaceItemClosed (object sender, EventArgs e)
+ {
+ Reset ();
+ }
+
+ void DocumentManager_DocumentOpened (object sender, DocumentEventArgs e)
+ {
+ closedHistory.RemoveAll (np => (np.Item1 as DocumentNavigationPoint)?.FileName == e.Document.FileName);
+ OnClosedHistoryChanged ();
+ }
+
+ Task DocumentManager_DocumentClosing (object sender, DocumentCloseEventArgs e)
+ {
+ NavigationPoint point = GetNavPointForDoc (e.Document, true) as DocumentNavigationPoint;
+ if (point == null)
+ return Task.CompletedTask;
+
+ closedHistory.Add (new Tuple<NavigationPoint, int> (point, documentManager.Documents.IndexOf (e.Document)));
+ OnClosedHistoryChanged ();
+ return Task.CompletedTask;
+ }
+
+ public void LogActiveDocument ()
{
LogActiveDocument (false);
}
-
- public static void LogActiveDocument (bool transient)
+
+ public void Reset ()
+ {
+ history.Clear ();
+ OnHistoryChanged ();
+ closedHistory.Clear ();
+ OnClosedHistoryChanged ();
+ }
+
+ public void LogActiveDocument (bool transient)
{
if (switching)
return;
-
- NavigationPoint point = GetNavPointForActiveDoc (false);
+
+ var point = GetNavPointForActiveDoc (false);
if (point == null)
return;
-
- NavigationHistoryItem item = new NavigationHistoryItem (point);
-
+
+ var item = new NavigationHistoryItem (point);
+
//if the current node's transient but has been around for a while, consider making it permanent
if (Current == null ||
- (currentIsTransient && DateTime.Now.Subtract (Current.Created).TotalMilliseconds > TRANSIENT_TIMEOUT))
- {
+ (currentIsTransient && DateTime.Now.Subtract (Current.Created).TotalMilliseconds > TRANSIENT_TIMEOUT)) {
currentIsTransient = false;
}
-
+
//if the current point's transient, always replace it
- if (currentIsTransient)
- {
+ if (currentIsTransient) {
//collapse down possible extra point in history
- NavigationHistoryItem backOne = history[-1];
+ var backOne = history [-1];
if (backOne != null && point.ShouldReplace (backOne.NavigationPoint)) {
// The new node is the same as the last permanent, so we can discard it
history.RemoveCurrent ();
@@ -126,71 +156,68 @@ namespace MonoDevelop.Ide.Navigation
}
}
//if the new point wants to replace the old one, let it
- else if (Current != null && !transient && point.ShouldReplace (Current.NavigationPoint))
- {
+ else if (Current != null && !transient && point.ShouldReplace (Current.NavigationPoint)) {
history.ReplaceCurrent (item);
-
+
//but in this case, the point should not be transient -- unless the old point was,
//but that's handled earlier
currentIsTransient = false;
}
//final choice: append the the node
//BUT only if the existing current node would not want to replace the new node
- else if (Current == null || !Current.NavigationPoint.ShouldReplace (point))
- {
+ else if (Current == null || !Current.NavigationPoint.ShouldReplace (point)) {
history.AddPoint (item);
currentIsTransient = transient;
- }
- else
+ } else
item.Dispose ();
-
+
OnHistoryChanged ();
}
-
- static NavigationPoint GetNavPointForActiveDoc (bool forClosedHistory)
+
+ NavigationPoint GetNavPointForActiveDoc (bool forClosedHistory)
{
- return GetNavPointForDoc (IdeApp.Workbench.ActiveDocument, forClosedHistory);
+ return GetNavPointForDoc (documentManager.ActiveDocument, forClosedHistory);
}
-
- static NavigationPoint GetNavPointForDoc (Document doc, bool forClosedHistory)
+
+ NavigationPoint GetNavPointForDoc (Document doc, bool forClosedHistory)
{
if (doc == null)
return null;
-
+
NavigationPoint point = null;
-
+
INavigable navigable = doc.GetContent<INavigable> ();
if (navigable != null) {
point = navigable.BuildNavigationPoint ();
if (point != null)
return point;
}
-
+
var editBuf = doc.Editor;
if (editBuf != null) {
- if (forClosedHistory) {
- point = new TextFileNavigationPoint (doc.FileName, editBuf.CaretLine, editBuf.CaretColumn);
- } else {
- point = new TextFileNavigationPoint (doc, editBuf);
+ if (forClosedHistory) {
+ point = new TextFileNavigationPoint (doc.FileName, editBuf.CaretLine, editBuf.CaretColumn);
+ } else {
+ point = new TextFileNavigationPoint (doc, editBuf);
}
if (point != null)
return point;
}
-
+
return new DocumentNavigationPoint (doc);
}
-
+
#region Navigation
-
- public static bool CanMoveForward {
+
+ public bool CanMoveForward {
get { return history.CanMoveForward; }
}
-
- public static bool CanMoveBack {
+
+ public bool CanMoveBack {
get { return history.CanMoveBack; }
}
-
- public static void MoveForward ()
+
+ public void MoveForward ()
{
LogActiveDocument ();
if (history.CanMoveForward) {
@@ -199,8 +226,8 @@ namespace MonoDevelop.Ide.Navigation
OnHistoryChanged ();
}
}
-
- public static void MoveBack ()
+
+ public void MoveBack ()
{
// Log current point before moving back, to make sure a MoveForward will return to the same position
LogActiveDocument ();
@@ -210,15 +237,15 @@ namespace MonoDevelop.Ide.Navigation
OnHistoryChanged ();
}
}
-
- public static void MoveTo (NavigationHistoryItem item)
+
+ public void MoveTo (NavigationHistoryItem item)
{
history.MoveTo (item);
SwitchToCurrent ();
OnHistoryChanged ();
}
-
- static void SwitchToCurrent ()
+
+ void SwitchToCurrent ()
{
currentIsTransient = false;
switching = true;
@@ -226,19 +253,20 @@ namespace MonoDevelop.Ide.Navigation
history.Current.Show ();
switching = false;
}
-
+
#endregion
#region Closed Document List
- public static bool HasClosedDocuments {
+ public bool HasClosedDocuments {
get { return closedHistory.Count != 0; }
}
- public static async void OpenLastClosedDocument () {
+ public async void OpenLastClosedDocument ()
+ {
if (HasClosedDocuments) {
int closedHistoryIndex = closedHistory.Count - 1;
- var tuple = closedHistory[closedHistoryIndex];
+ var tuple = closedHistory [closedHistoryIndex];
closedHistory.RemoveAt (closedHistoryIndex);
OnClosedHistoryChanged ();
var doc = await tuple.Item1.ShowDocument ();
@@ -248,120 +276,120 @@ namespace MonoDevelop.Ide.Navigation
}
#endregion
-
- public static IList<NavigationHistoryItem> GetNavigationList (int desiredLength)
+
+ public IList<NavigationHistoryItem> GetNavigationList (int desiredLength)
{
return history.GetList (desiredLength);
}
-
- public static IList<NavigationHistoryItem> GetNavigationList (int desiredLength, out int currentIndex)
+
+ public IList<NavigationHistoryItem> GetNavigationList (int desiredLength, out int currentIndex)
{
return history.GetList (desiredLength, out currentIndex);
}
-
- public static NavigationHistoryItem Current { get { return history.Current; } }
-
- public static bool IsCurrent (NavigationHistoryItem point)
+
+ public NavigationHistoryItem Current { get { return history.Current; } }
+
+ public bool IsCurrent (NavigationHistoryItem point)
{
return history.IsCurrent (point);
}
-
- public static void Clear ()
+
+ public void Clear ()
{
history.Clear ();
LogActiveDocument ();
}
-
- public static event EventHandler HistoryChanged;
- public static event EventHandler ClosedHistoryChanged;
-
- static void OnHistoryChanged ()
+
+ public event EventHandler HistoryChanged;
+ public event EventHandler ClosedHistoryChanged;
+
+ void OnHistoryChanged ()
{
HistoryChanged?.Invoke (null, EventArgs.Empty);
}
- static void OnClosedHistoryChanged ()
+ void OnClosedHistoryChanged ()
{
ClosedHistoryChanged?.Invoke (null, EventArgs.Empty);
}
-
+
#region Handling active doc change events
-
- static void ActiveDocChanged (object sender, EventArgs args)
+
+ void ActiveDocChanged (object sender, EventArgs args)
{
LogActiveDocument (true);
- AttachToDoc (IdeApp.Workbench.ActiveDocument);
+ AttachToDoc (documentManager.ActiveDocument);
}
-
- static void AttachToDoc (Document document)
+
+ void AttachToDoc (Document document)
{
DetachFromCurrentDoc ();
if (document == null)
return;
-
+
currentDoc = document;
-
+
currentDoc.Closed += HandleCurrentDocClosed;
-
+
if (currentDoc.Editor != null) {
currentDoc.Editor.TextChanged += BufferTextChanged;
currentDoc.Editor.CaretPositionChanged += BufferCaretPositionChanged;
}
}
- static void HandleCurrentDocClosed (object sender, EventArgs e)
+ void HandleCurrentDocClosed (object sender, EventArgs e)
{
DetachFromCurrentDoc ();
}
-
- static void DetachFromCurrentDoc ()
+
+ void DetachFromCurrentDoc ()
{
if (currentDoc == null)
return;
-
- currentDoc.Closed -= HandleCurrentDocClosed;
+
+ currentDoc.Closed -= HandleCurrentDocClosed;
if (currentDoc.Editor != null) {
currentDoc.Editor.TextChanged -= BufferTextChanged;
currentDoc.Editor.CaretPositionChanged -= BufferCaretPositionChanged;
}
currentDoc = null;
}
-
- static void BufferCaretPositionChanged (object sender, EventArgs args)
+
+ void BufferCaretPositionChanged (object sender, EventArgs args)
{
LogActiveDocument (true);
}
-
- static void BufferTextChanged (object sender, EventArgs args)
+
+ void BufferTextChanged (object sender, EventArgs args)
{
LogActiveDocument ();
}
-
+
#endregion
-
+
#region Text file line number and snippet updating
-
- static void LineCountChanged (object sender, LineCountEventArgs args)
+
+ void LineCountChanged (object sender, LineCountEventArgs args)
{
-// MonoDevelop.Projects.Text.ITextFile textFile = (MonoDevelop.Projects.Text.ITextFile) sender;
+ // MonoDevelop.Projects.Text.ITextFile textFile = (MonoDevelop.Projects.Text.ITextFile) sender;
}
-
- static void CommitCountChanges (object sender, TextFileEventArgs args)
+
+ void CommitCountChanges (object sender, TextFileEventArgs args)
{
-// MonoDevelop.Projects.Text.ITextFile textFile = (MonoDevelop.Projects.Text.ITextFile) sender;
+ // MonoDevelop.Projects.Text.ITextFile textFile = (MonoDevelop.Projects.Text.ITextFile) sender;
}
-
- static void ResetCountChanges (object sender, TextFileEventArgs args)
+
+ void ResetCountChanges (object sender, TextFileEventArgs args)
{
-// MonoDevelop.Projects.Text.ITextFile textFile = (MonoDevelop.Projects.Text.ITextFile) sender;
+ // MonoDevelop.Projects.Text.ITextFile textFile = (MonoDevelop.Projects.Text.ITextFile) sender;
}
-
- static void FileRenamed (object sender, ProjectFileRenamedEventArgs e)
+
+ void FileRenamed (object sender, ProjectFileRenamedEventArgs e)
{
bool historyChanged = false, closedHistoryChanged = false;
- foreach (NavigationHistoryItem point in history) {
- foreach (ProjectFileRenamedEventInfo args in e) {
+ foreach (var point in history) {
+ foreach (var args in e) {
var dp = point.NavigationPoint as DocumentNavigationPoint;
historyChanged |= (dp?.HandleRenameEvent (args.OldName, args.NewName)).GetValueOrDefault ();
}
@@ -371,7 +399,7 @@ namespace MonoDevelop.Ide.Navigation
OnHistoryChanged ();
foreach (var point in closedHistory) {
- foreach (ProjectFileRenamedEventInfo args in e) {
+ foreach (var args in e) {
var dp = point.Item1 as DocumentNavigationPoint;
closedHistoryChanged |= (dp?.HandleRenameEvent (args.OldName, args.NewName)).GetValueOrDefault ();
}
@@ -380,7 +408,7 @@ namespace MonoDevelop.Ide.Navigation
if (closedHistoryChanged)
OnClosedHistoryChanged ();
}
-
+
#endregion
}
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksProvider.Legacy.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksProvider.Legacy.cs
index b9bc822f3d..1c126a7337 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksProvider.Legacy.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksProvider.Legacy.cs
@@ -29,23 +29,32 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MonoDevelop.Core;
+using MonoDevelop.Ide.Editor;
using MonoDevelop.Ide.Gui;
using MonoDevelop.Projects;
+using MonoDevelop.Ide.Gui.Documents;
namespace MonoDevelop.Ide.Tasks
{
- static partial class CommentTasksProvider
+ partial class CommentTasksProvider
{
internal static class Legacy
{
+ static Dictionary<Project, ProjectCommentTags> projectTags = new Dictionary<Project, ProjectCommentTags> ();
+ static CancellationTokenSource src = new CancellationTokenSource ();
+
internal static void Initialize ()
{
- IdeApp.Workspace.LastWorkspaceItemClosed += LastWorkspaceItemClosed;
- IdeApp.Workspace.WorkspaceItemUnloaded += OnWorkspaceItemUnloaded;
- IdeApp.Workbench.DocumentOpened += WorkbenchDocumentOpened;
- IdeApp.Workbench.DocumentClosed += WorkbenchDocumentClosed;
+ Runtime.ServiceProvider.WhenServiceInitialized<RootWorkspace> (s => {
+ s.LastWorkspaceItemClosed += LastWorkspaceItemClosed;
+ s.WorkspaceItemUnloaded += OnWorkspaceItemUnloaded;
+ });
}
+ public static Dictionary<Project, ProjectCommentTags> ProjectTags => projectTags;
+
+ public static CancellationToken CancellationToken => src.Token;
+
static void LastWorkspaceItemClosed (object sender, EventArgs e)
{
projectTags.Clear ();
@@ -59,8 +68,6 @@ namespace MonoDevelop.Ide.Tasks
}
}
- static Dictionary<Project, ProjectCommentTags> projectTags = new Dictionary<Project, ProjectCommentTags> ();
- static CancellationTokenSource src = new CancellationTokenSource ();
static void UpdateCommentTagsForProject (Project project, CancellationToken token)
{
if (token.IsCancellationRequested)
@@ -72,7 +79,7 @@ namespace MonoDevelop.Ide.Tasks
}
var files = project.Files.Where (x => {
- var mt = DesktopService.GetMimeTypeForUri (x.FilePath);
+ var mt = IdeServices.DesktopService.GetMimeTypeForUri (x.FilePath);
// FIXME: Handle all language services.
// Discard files with known IToDoCommentService implementations
@@ -118,41 +125,60 @@ namespace MonoDevelop.Ide.Tasks
}
});
}
+ }
+ }
- static void WorkbenchDocumentClosed (object sender, DocumentEventArgs e)
- {
- e.Document.DocumentParsed -= HandleDocumentParsed;
- }
+ [ExportDocumentControllerExtension (MimeType = "*")]
+ class LegacyDocumentExtension: DocumentControllerExtension
+ {
+ DocumentContext context;
- static void WorkbenchDocumentOpened (object sender, DocumentEventArgs e)
- {
- e.Document.DocumentParsed += HandleDocumentParsed;
+ public override async Task<bool> SupportsController (DocumentController controller)
+ {
+ if (!await base.SupportsController (controller) || !(controller is FileDocumentController))
+ return false;
+
+ if (controller is FileDocumentController file) {
+ // C# uses the roslyn-provided todo comments system.
+ //if (file.MimeType == "text/x-csharp")
+ // return false;
}
+ var s = controller.GetContent<DocumentContext> () != null;
+ return s;
+ }
- static void HandleDocumentParsed (object sender, EventArgs e)
- {
- var doc = (Document)sender;
+ public override Task Initialize (Properties status)
+ {
+ context = Controller.GetContent<DocumentContext> ();
+ context.DocumentParsed += Context_DocumentParsed;
+ return base.Initialize (status);
+ }
- // C# uses the roslyn-provided todo comments system.
- if (doc.Editor.MimeType == "text/x-csharp")
- return;
+ public override void Dispose ()
+ {
+ if (context != null)
+ context.DocumentParsed -= Context_DocumentParsed;
+ base.Dispose ();
+ }
- var pd = doc.ParsedDocument;
- var project = doc.Project;
- if (pd == null || project == null)
- return;
- ProjectCommentTags tags;
- if (!projectTags.TryGetValue (project, out tags))
- return;
- var token = src.Token;
- var file = doc.FileName;
- Task.Run (async () => {
- try {
- tags.UpdateTags (project, file, await pd.GetTagCommentsAsync (token).ConfigureAwait (false));
- } catch (OperationCanceledException) {
- }
- });
- }
+ void Context_DocumentParsed (object sender, EventArgs e)
+ {
+ var pd = context.ParsedDocument;
+ var project = Controller.Owner as Project;
+ if (project == null || !(Controller is FileDocumentController fileController))
+ return;
+ ProjectCommentTags tags;
+ if (!CommentTasksProvider.Legacy.ProjectTags.TryGetValue (project, out tags))
+ return;
+ var token = CommentTasksProvider.Legacy.CancellationToken;
+ var file = fileController.FilePath;
+ Task.Run (async () => {
+ try {
+ tags.UpdateTags (project, file, await pd.GetTagCommentsAsync (token).ConfigureAwait (false));
+ } catch (OperationCanceledException) {
+ }
+ });
}
+
}
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksProvider.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksProvider.cs
index 7ebf74d055..6a3b3e5172 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksProvider.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksProvider.cs
@@ -1,4 +1,4 @@
-//
+//
// CommentTasksProvider.cs
//
// Author:
@@ -30,29 +30,31 @@ using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor;
using Microsoft.CodeAnalysis.Editor.Implementation.TodoComments;
+using MonoDevelop.Core;
using MonoDevelop.Ide.TypeSystem;
using MonoDevelop.Projects;
using System.Linq;
+using System.Threading.Tasks;
+using MonoDevelop.Ide.Composition;
namespace MonoDevelop.Ide.Tasks
{
- static partial class CommentTasksProvider
+ partial class CommentTasksProvider
{
- internal static void Initialize ()
- {
- var todoListProvider = Composition.CompositionManager.GetExportedValue<ITodoListProvider> ();
- todoListProvider.TodoListUpdated += OnTodoListUpdated;
- }
+ TaskService taskService;
- static CommentTasksProvider()
+ public static void Initialize ()
{
- IdeApp.Initialized += (sender, args) => {
- IdeApp.Workspace.SolutionLoaded += OnSolutionLoaded;
- IdeApp.Workspace.WorkspaceItemClosed += OnWorkspaceItemClosed;
-
+ Runtime.ServiceProvider.WhenServiceInitialized<CompositionManager> (compositionManager => {
+ var todoListProvider = compositionManager.GetExportedValue<ITodoListProvider> ();
+ todoListProvider.TodoListUpdated += OnTodoListUpdated;
+ });
+
+ Runtime.ServiceProvider.WhenServiceInitialized<RootWorkspace> (workspace => {
+ workspace.SolutionLoaded += OnSolutionLoaded;
+ workspace.WorkspaceItemClosed += OnWorkspaceItemClosed;
Legacy.Initialize ();
- };
-
+ });
CommentTag.SpecialCommentTagsChanged += OnSpecialTagsChanged;
}
@@ -85,15 +87,15 @@ namespace MonoDevelop.Ide.Tasks
return;
if (triggerLoad == null || triggerLoad.Invoke (cachedUntilViewCreated.Count)) {
- var changes = cachedUntilViewCreated.Values.Select (x => x.ToCommentTaskChange ()).Where (x => x != null).ToList ();
- TaskService.InformCommentTasks (new CommentTasksChangedEventArgs (changes));
+ var changes = cachedUntilViewCreated.Values.Select (x => ToCommentTaskChange (x)).Where (x => x != null).ToList ();
+ IdeServices.TaskService.InformCommentTasks (new CommentTasksChangedEventArgs (changes));
cachedUntilViewCreated = null;
triggerLoad = null;
}
}
}
- public static CommentTaskChange ToCommentTaskChange (this TodoItemsUpdatedArgs args)
+ public static CommentTaskChange ToCommentTaskChange (TodoItemsUpdatedArgs args)
{
if (!TryGetDocument (args, out var doc, out var project))
return null;
@@ -149,19 +151,19 @@ namespace MonoDevelop.Ide.Tasks
var change = ToCommentTaskChange (args);
if (change != null)
- TaskService.InformCommentTasks (new CommentTasksChangedEventArgs (new [] { change }));
+ IdeServices.TaskService.InformCommentTasks (new CommentTasksChangedEventArgs (new [] { change }));
}
static async void OnSolutionLoaded (object sender, SolutionEventArgs args)
{
- var ws = await TypeSystemService.GetWorkspaceAsync (args.Solution);
+ var ws = await IdeApp.TypeSystemService.GetWorkspaceAsync (args.Solution);
UpdateWorkspaceOptions (ws);
}
static async void OnWorkspaceItemClosed (object sender, WorkspaceItemEventArgs args)
{
if (args.Item is MonoDevelop.Projects.Solution sol) {
- var ws = await TypeSystemService.GetWorkspaceAsync (sol);
+ var ws = await IdeApp.TypeSystemService.GetWorkspaceAsync (sol);
lock (lockObject) {
if (cachedUntilViewCreated == null)
@@ -180,7 +182,7 @@ namespace MonoDevelop.Ide.Tasks
static void OnSpecialTagsChanged (object sender, EventArgs args)
{
- foreach (var ws in TypeSystemService.AllWorkspaces)
+ foreach (var ws in IdeApp.TypeSystemService.AllWorkspaces)
UpdateWorkspaceOptions (ws);
}
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskService.cs
index 6f61d562fe..5ac4e99d7f 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskService.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskService.cs
@@ -1,5 +1,5 @@
//
-// TaskService.cs
+// IdeServices.TaskService.cs
//
// Author:
// Lluis Sanchez Gual <lluis@novell.com>
@@ -27,51 +27,57 @@
using System;
using System.IO;
using System.Collections.Generic;
-using System.Xml.Serialization;
using MonoDevelop.Core;
using MonoDevelop.Core.Serialization;
using MonoDevelop.Projects;
using MonoDevelop.Ide.Gui;
+using System.Threading.Tasks;
namespace MonoDevelop.Ide.Tasks
{
- public enum TaskSeverity
+ [DefaultServiceImplementation]
+ public class TaskService: Service
{
- Error,
- Warning,
- Information,
- Comment
- }
-
- public static class TaskService
- {
- static TaskStore errors = new TaskStore ();
- static TaskStore userTasks = new TaskStore ();
-
- static bool errorBubblesVisible = true;
- static bool warningBubblesVisible = true;
+ TaskStore errors = new TaskStore ();
+ TaskStore userTasks = new TaskStore ();
- static TaskService ()
+ bool errorBubblesVisible = true;
+ bool warningBubblesVisible = true;
+
+ RootWorkspace rootWorkspace;
+
+ protected override Task OnInitialize (ServiceProvider serviceProvider)
{
- if (IdeApp.Workspace != null) {
- IdeApp.Workspace.WorkspaceItemLoaded += OnWorkspaceItemLoaded;
- IdeApp.Workspace.WorkspaceItemUnloaded += OnWorkspaceItemUnloaded;
+ serviceProvider.WhenServiceInitialized<RootWorkspace> (s => {
+ rootWorkspace = s;
+ rootWorkspace.WorkspaceItemLoaded += OnWorkspaceItemLoaded;
+ rootWorkspace.WorkspaceItemUnloaded += OnWorkspaceItemUnloaded;
CommentTasksProvider.Legacy.Initialize ();
- }
+ });
errors.ItemName = GettextCatalog.GetString ("Warning/Error");
userTasks.ItemName = GettextCatalog.GetString ("User Task");
+ return Task.CompletedTask;
}
-
- public static TaskStore Errors {
+
+ protected override Task OnDispose ()
+ {
+ if (rootWorkspace != null) {
+ rootWorkspace.WorkspaceItemLoaded -= OnWorkspaceItemLoaded;
+ rootWorkspace.WorkspaceItemUnloaded -= OnWorkspaceItemUnloaded;
+ }
+ return base.OnDispose ();
+ }
+
+ public TaskStore Errors {
get { return errors; }
}
- public static TaskStore UserTasks {
+ public TaskStore UserTasks {
get { return userTasks; }
}
- public static bool ErrorBubblesVisible {
+ public bool ErrorBubblesVisible {
get { return errorBubblesVisible; }
set {
if (errorBubblesVisible != value) {
@@ -82,7 +88,7 @@ namespace MonoDevelop.Ide.Tasks
}
}
- public static bool WarningBubblesVisible {
+ public bool WarningBubblesVisible {
get { return warningBubblesVisible; }
set {
if (warningBubblesVisible != value) {
@@ -93,9 +99,9 @@ namespace MonoDevelop.Ide.Tasks
}
}
- public static event EventHandler BubblesVisibilityChanged;
+ public event EventHandler BubblesVisibilityChanged;
- public static void ShowErrors ()
+ public void ShowErrors ()
{
Pad errorsPad = IdeApp.Workbench.GetPad<MonoDevelop.Ide.Gui.Pads.ErrorListPad> ();
if (errorsPad != null) {
@@ -107,7 +113,7 @@ namespace MonoDevelop.Ide.Tasks
/// <summary>
/// Shows a description of the task in the status bar
/// </summary>
- public static void ShowStatus (TaskListEntry t)
+ public void ShowStatus (TaskListEntry t)
{
if (t == null)
IdeApp.Workbench.StatusBar.ShowMessage (GettextCatalog.GetString ("No more errors or warnings"));
@@ -119,7 +125,7 @@ namespace MonoDevelop.Ide.Tasks
IdeApp.Workbench.StatusBar.ShowMessage (t.Description);
}
- static void OnWorkspaceItemLoaded (object sender, WorkspaceItemEventArgs e)
+ void OnWorkspaceItemLoaded (object sender, WorkspaceItemEventArgs e)
{
string fileToLoad = GetUserTasksFilename (e.Item);
@@ -143,7 +149,7 @@ namespace MonoDevelop.Ide.Tasks
}
}
- static void OnWorkspaceItemUnloaded (object sender, WorkspaceItemEventArgs e)
+ void OnWorkspaceItemUnloaded (object sender, WorkspaceItemEventArgs e)
{
// Save UserTasks to xml file
SaveUserTasks (e.Item);
@@ -154,13 +160,13 @@ namespace MonoDevelop.Ide.Tasks
userTasks.RemoveItemTasks (e.Item, true);
}
- static FilePath GetUserTasksFilename (WorkspaceItem item)
+ FilePath GetUserTasksFilename (WorkspaceItem item)
{
FilePath combinePath = item.FileName.ParentDirectory;
return combinePath.Combine (item.FileName.FileNameWithoutExtension + ".usertasks");
}
- internal static void SaveUserTasks (WorkspaceObject item)
+ internal void SaveUserTasks (WorkspaceObject item)
{
string fileToSave = GetUserTasksFilename ((WorkspaceItem)item);
try {
@@ -178,16 +184,16 @@ namespace MonoDevelop.Ide.Tasks
}
- public static event EventHandler<TaskEventArgs> JumpedToTask;
+ public event EventHandler<TaskEventArgs> JumpedToTask;
- internal static void InformJumpToTask (TaskListEntry task)
+ internal void InformJumpToTask (TaskListEntry task)
{
EventHandler<TaskEventArgs> handler = JumpedToTask;
if (handler != null)
handler (null, new TaskEventArgs (task));
}
- internal static void InformCommentTasks (CommentTasksChangedEventArgs args)
+ internal void InformCommentTasks (CommentTasksChangedEventArgs args)
{
if (args.Changes.Count == 0)
return;
@@ -197,11 +203,11 @@ namespace MonoDevelop.Ide.Tasks
handler (null, args);
}
- public static event EventHandler<CommentTasksChangedEventArgs> CommentTasksChanged;
+ public event EventHandler<CommentTasksChangedEventArgs> CommentTasksChanged;
- public static event EventHandler<TaskEventArgs> TaskToggled;
+ public event EventHandler<TaskEventArgs> TaskToggled;
- public static void FireTaskToggleEvent (object sender, TaskEventArgs e)
+ public void FireTaskToggleEvent (object sender, TaskEventArgs e)
{
var handler = TaskToggled;
if (handler != null)
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskSeverity.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskSeverity.cs
new file mode 100644
index 0000000000..b029de5edb
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskSeverity.cs
@@ -0,0 +1,39 @@
+//
+// IdeServices.TaskService.cs
+//
+// Author:
+// Lluis Sanchez Gual <lluis@novell.com>
+//
+// Copyright (c) 2009 Novell, Inc (http://www.novell.com)
+//
+// 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.
+
+
+
+namespace MonoDevelop.Ide.Tasks
+{
+ public enum TaskSeverity
+ {
+ Error,
+ Warning,
+ Information,
+ Comment
+ }
+}
+
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskStore.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskStore.cs
index 35abbfcb97..5ec1c1d7a3 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskStore.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskStore.cs
@@ -1,4 +1,4 @@
-//
+//
// TaskStore.cs
//
// Author:
@@ -59,47 +59,52 @@ namespace MonoDevelop.Ide.Tasks
List<TaskListEntry> tasksAdded;
List<TaskListEntry> tasksRemoved;
-
+
public TaskStore ()
{
- if (IdeApp.Workspace != null) {
- IdeApp.Workspace.FileRenamedInProject += ProjectFileRenamed;
- IdeApp.Workspace.FileRemovedFromProject += ProjectFileRemoved;
- }
+ IdeServices.Workspace.FileRenamedInProject += ProjectFileRenamed;
+ IdeServices.Workspace.FileRemovedFromProject += ProjectFileRemoved;
- TextEditorService.LineCountChangesCommitted += delegate (object sender, TextFileEventArgs args) {
- foreach (TaskListEntry task in GetFileTasks (args.TextFile.Name.FullPath))
+ IdeServices.TextEditorService.LineCountChangesCommitted += TextEditorService_LineCountChangesCommitted;
+ IdeServices.TextEditorService.LineCountChangesReset += TextEditorService_LineCountChangesReset;
+ IdeServices.TextEditorService.LineCountChanged += TextEditorService_LineCountChanged;
+ }
+
+ void TextEditorService_LineCountChangesCommitted (object sender, TextFileEventArgs args)
+ {
+ foreach (TaskListEntry task in GetFileTasks (args.TextFile.Name.FullPath))
+ task.SavedLine = -1;
+ }
+
+ void TextEditorService_LineCountChangesReset (object sender, TextFileEventArgs args)
+ {
+ Runtime.AssertMainThread ();
+ TaskListEntry [] ctasks = GetFileTasks (args.TextFile.Name.FullPath);
+ foreach (TaskListEntry task in ctasks) {
+ if (task.SavedLine != -1) {
+ task.Line = task.SavedLine;
task.SavedLine = -1;
- };
-
- TextEditorService.LineCountChangesReset += delegate (object sender, TextFileEventArgs args) {
- Runtime.AssertMainThread ();
- TaskListEntry[] ctasks = GetFileTasks (args.TextFile.Name.FullPath);
- foreach (TaskListEntry task in ctasks) {
- if (task.SavedLine != -1) {
- task.Line = task.SavedLine;
- task.SavedLine = -1;
- }
}
- NotifyTasksChanged (ctasks);
- };
-
- TextEditorService.LineCountChanged += delegate (object sender, LineCountEventArgs args) {
- Runtime.AssertMainThread ();
- if (args.TextFile == null || args.TextFile.Name.IsNullOrEmpty)
- return;
- TaskListEntry[] ctasks = GetFileTasks (args.TextFile.Name.FullPath);
- foreach (TaskListEntry task in ctasks) {
- if (task.Line > args.LineNumber || (task.Line == args.LineNumber && task.Column >= args.Column)) {
- if (task.SavedLine == -1)
- task.SavedLine = task.Line;
- task.Line += args.LineCount;
- }
+ }
+ NotifyTasksChanged (ctasks);
+ }
+
+ void TextEditorService_LineCountChanged (object sender, LineCountEventArgs args)
+ {
+ Runtime.AssertMainThread ();
+ if (args.TextFile == null || args.TextFile.Name.IsNullOrEmpty)
+ return;
+ TaskListEntry [] ctasks = GetFileTasks (args.TextFile.Name.FullPath);
+ foreach (TaskListEntry task in ctasks) {
+ if (task.Line > args.LineNumber || (task.Line == args.LineNumber && task.Column >= args.Column)) {
+ if (task.SavedLine == -1)
+ task.SavedLine = task.Line;
+ task.Line += args.LineCount;
}
- NotifyTasksChanged (ctasks);
- };
+ }
+ NotifyTasksChanged (ctasks);
}
-
+
public void Add (TaskListEntry task)
{
Runtime.AssertMainThread ();
@@ -396,7 +401,7 @@ namespace MonoDevelop.Ide.Tasks
protected override async Task<Document> DoShow ()
{
Document result = await base.DoShow ();
- TaskService.InformJumpToTask (task);
+ IdeServices.TaskService.InformJumpToTask (task);
return result;
}
}
@@ -434,7 +439,7 @@ namespace MonoDevelop.Ide.Tasks
CurrentLocationTaskChanged (this, EventArgs.Empty);
if (currentLocationTask != null) {
- TaskService.ShowStatus (currentLocationTask);
+ IdeServices.TaskService.ShowStatus (currentLocationTask);
return new TaskNavigationPoint (currentLocationTask);
}
else {
@@ -459,12 +464,12 @@ namespace MonoDevelop.Ide.Tasks
return false;
//only text files
- var mimeType = DesktopService.GetMimeTypeForUri (t.FileName);
- if (!DesktopService.GetMimeTypeIsText (mimeType))
+ var mimeType = IdeServices.DesktopService.GetMimeTypeForUri (t.FileName);
+ if (!IdeServices.DesktopService.GetMimeTypeIsText (mimeType))
return false;
//only files for which we have a default internal display binding
- var binding = DisplayBindingService.GetDefaultBinding (t.FileName, mimeType, p);
+ var binding = IdeApp.Services.DisplayBindingService.GetDefaultBinding (t.FileName, mimeType, p);
if (binding == null || !binding.CanUseAsDefault || binding is IExternalDisplayBinding)
return false;
@@ -508,7 +513,7 @@ namespace MonoDevelop.Ide.Tasks
CurrentLocationTaskChanged (this, EventArgs.Empty);
if (currentLocationTask != null) {
- TaskService.ShowStatus (currentLocationTask);
+ IdeServices.TaskService.ShowStatus (currentLocationTask);
return new TaskNavigationPoint (currentLocationTask);
}
else {
@@ -525,7 +530,7 @@ namespace MonoDevelop.Ide.Tasks
}
return -1;
}
-
+
public string ItemName {
get; set;
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TextEditing/TextEditorService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TextEditing/TextEditorService.cs
index 74385431b9..a7fe3e89f0 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TextEditing/TextEditorService.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TextEditing/TextEditorService.cs
@@ -29,51 +29,17 @@ using System.Linq;
using MonoDevelop.Core;
using System.Collections.Generic;
using MonoDevelop.Projects.Text;
+using System.Threading.Tasks;
namespace MonoDevelop.Ide.TextEditing
{
/// <summary>
/// Offers several methods for tracking changes being done in edited files
/// </summary>
- public static class TextEditorService
+ [DefaultServiceImplementation]
+ public class TextEditorService: Service
{
- static Dictionary<FilePath,List<FileExtension>> fileExtensions = new Dictionary<FilePath,List<FileExtension>> ();
-
- static TextEditorService ()
- {
- LineCountChanged += delegate(object sender, LineCountEventArgs e) {
- foreach (var ext in GetFileLineExtensions (e.TextFile.Name).Where (ex => ex.TrackLinePosition).ToList ()) {
- if (ext.Line > e.LineNumber) {
- if (ext.Line + e.LineCount < e.LineNumber)
- ext.NotifyDeleted ();
- if (ext.OriginalLine == -1)
- ext.OriginalLine = ext.Line;
- ext.Line += e.LineCount;
- ext.Refresh ();
- }
- else if (ext.Line == e.LineNumber && e.LineCount < 0) {
- ext.NotifyDeleted ();
- if (ext.OriginalLine == -1)
- ext.OriginalLine = ext.Line;
- ext.Line += e.LineCount;
- ext.Refresh ();
- }
- }
- };
- LineCountChangesCommitted += delegate(object sender, TextFileEventArgs e) {
- foreach (var ext in GetFileLineExtensions (e.TextFile.Name).Where (ex => ex.TrackLinePosition))
- ext.OriginalLine = -1;
- };
- LineCountChangesReset += delegate(object sender, TextFileEventArgs e) {
- foreach (var ext in GetFileLineExtensions (e.TextFile.Name).Where (ex => ex.TrackLinePosition)) {
- if (ext.OriginalLine != -1) {
- ext.Line = ext.OriginalLine;
- ext.OriginalLine = -1;
- ext.Refresh ();
- }
- }
- };
- }
+ Dictionary<FilePath,List<FileExtension>> fileExtensions = new Dictionary<FilePath,List<FileExtension>> ();
/// <summary>
/// Notifies to the text editor service that there has been a line count change in a file being edited
@@ -90,8 +56,25 @@ namespace MonoDevelop.Ide.TextEditing
/// <param name='column'>
/// Column.
/// </param>
- public static void NotifyLineCountChanged (ITextFile textFile, int lineNumber, int lineCount, int column)
+ public void NotifyLineCountChanged (ITextFile textFile, int lineNumber, int lineCount, int column)
{
+ foreach (var ext in GetFileLineExtensions (textFile.Name).Where (ex => ex.TrackLinePosition).ToList ()) {
+ if (ext.Line > lineNumber) {
+ if (ext.Line + lineCount < lineNumber)
+ ext.NotifyDeleted ();
+ if (ext.OriginalLine == -1)
+ ext.OriginalLine = ext.Line;
+ ext.Line += lineCount;
+ ext.Refresh ();
+ } else if (ext.Line == lineNumber && lineCount < 0) {
+ ext.NotifyDeleted ();
+ if (ext.OriginalLine == -1)
+ ext.OriginalLine = ext.Line;
+ ext.Line += lineCount;
+ ext.Refresh ();
+ }
+ }
+
if (LineCountChanged != null)
LineCountChanged (textFile, new LineCountEventArgs (textFile, lineNumber, lineCount, column));
}
@@ -102,8 +85,15 @@ namespace MonoDevelop.Ide.TextEditing
/// <param name='textFile'>
/// Text file.
/// </param>
- public static void NotifyLineCountChangesReset (ITextFile textFile)
+ public void NotifyLineCountChangesReset (ITextFile textFile)
{
+ foreach (var ext in GetFileLineExtensions (textFile.Name).Where (ex => ex.TrackLinePosition)) {
+ if (ext.OriginalLine != -1) {
+ ext.Line = ext.OriginalLine;
+ ext.OriginalLine = -1;
+ ext.Refresh ();
+ }
+ }
if (LineCountChangesReset != null)
LineCountChangesReset (textFile, new TextFileEventArgs (textFile));
}
@@ -114,13 +104,16 @@ namespace MonoDevelop.Ide.TextEditing
/// <param name='textFile'>
/// Text file.
/// </param>
- public static void NotifyLineCountChangesCommitted (ITextFile textFile)
+ public void NotifyLineCountChangesCommitted (ITextFile textFile)
{
+ foreach (var ext in GetFileLineExtensions (textFile.Name).Where (ex => ex.TrackLinePosition))
+ ext.OriginalLine = -1;
+
if (LineCountChangesCommitted != null)
LineCountChangesCommitted (textFile, new TextFileEventArgs (textFile));
}
- static IEnumerable<FileLineExtension> GetFileLineExtensions (FilePath file)
+ IEnumerable<FileLineExtension> GetFileLineExtensions (FilePath file)
{
file = file.CanonicalPath;
return fileExtensions.Values.SelectMany (e => e).OfType<FileLineExtension> ().Where (e => e.File.CanonicalPath == file);
@@ -132,8 +125,9 @@ namespace MonoDevelop.Ide.TextEditing
/// <param name='extension'>
/// The extension.
/// </param>
- public static void RegisterExtension (FileExtension extension)
+ public void RegisterExtension (FileExtension extension)
{
+ extension.TextEditorService = this;
List<FileExtension> list;
if (!fileExtensions.TryGetValue (extension.File, out list))
list = fileExtensions [extension.File] = new List<FileExtension> ();
@@ -147,7 +141,7 @@ namespace MonoDevelop.Ide.TextEditing
/// <param name='extension'>
/// Extension.
/// </param>
- public static void UnregisterExtension (FileExtension extension)
+ public void UnregisterExtension (FileExtension extension)
{
List<FileExtension> list;
if (!fileExtensions.TryGetValue (extension.File, out list))
@@ -156,13 +150,13 @@ namespace MonoDevelop.Ide.TextEditing
NotifyExtensionRemoved (extension);
}
- static void NotifyExtensionAdded (FileExtension extension)
+ void NotifyExtensionAdded (FileExtension extension)
{
if (FileExtensionAdded != null)
FileExtensionAdded (null, new FileExtensionEventArgs () { Extension = extension });
}
- static void NotifyExtensionRemoved (FileExtension extension)
+ void NotifyExtensionRemoved (FileExtension extension)
{
if (FileExtensionRemoved != null)
FileExtensionRemoved (null, new FileExtensionEventArgs () { Extension = extension });
@@ -177,7 +171,7 @@ namespace MonoDevelop.Ide.TextEditing
/// <param name='file'>
/// File.
/// </param>
- public static FileExtension[] GetFileExtensions (FilePath file)
+ public FileExtension[] GetFileExtensions (FilePath file)
{
List<FileExtension> list;
if (!fileExtensions.TryGetValue (file, out list))
@@ -186,7 +180,7 @@ namespace MonoDevelop.Ide.TextEditing
return list.ToArray ();
}
- internal static void Refresh (FileExtension ext)
+ internal void Refresh (FileExtension ext)
{
NotifyExtensionRemoved (ext);
NotifyExtensionAdded (ext);
@@ -195,36 +189,27 @@ namespace MonoDevelop.Ide.TextEditing
/// <summary>
/// Occurs when there has been a line count change in a file being edited
/// </summary>
- public static event EventHandler<LineCountEventArgs> LineCountChanged;
+ public event EventHandler<LineCountEventArgs> LineCountChanged;
/// <summary>
/// Occurs when all previous line change notifications for a file have to be discarded
/// </summary>
- public static event EventHandler<TextFileEventArgs> LineCountChangesReset;
+ public event EventHandler<TextFileEventArgs> LineCountChangesReset;
/// <summary>
/// Occurs when all previous line change notifications for a file have to be committed
/// </summary>
- public static event EventHandler<TextFileEventArgs> LineCountChangesCommitted;
+ public event EventHandler<TextFileEventArgs> LineCountChangesCommitted;
/// <summary>
/// Occurs when a text editor extension has been added
/// </summary>
- public static event EventHandler<FileExtensionEventArgs> FileExtensionAdded;
+ public event EventHandler<FileExtensionEventArgs> FileExtensionAdded;
/// <summary>
/// Occurs when a text editor extension has been removed
/// </summary>
- public static event EventHandler<FileExtensionEventArgs> FileExtensionRemoved;
+ public event EventHandler<FileExtensionEventArgs> FileExtensionRemoved;
}
-
-
-
-
-
-
-
-
-
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.MetadataReferenceHandler.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.MetadataReferenceHandler.cs
index b070146e50..999d6d6164 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.MetadataReferenceHandler.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.MetadataReferenceHandler.cs
@@ -1,4 +1,4 @@
-//
+//
// MonoDevelopWorkspace.MetadataReferenceHandler.cs
//
// Author:
@@ -86,7 +86,7 @@ namespace MonoDevelop.Ide.TypeSystem
Result = new List<MonoDevelopMetadataReference> (),
Project = netProject,
Visited = new HashSet<string> (FilePath.PathComparer),
- ConfigurationSelector = IdeApp.Workspace?.ActiveConfiguration ?? MonoDevelop.Projects.ConfigurationSelector.Default,
+ ConfigurationSelector = IdeApp.IsInitialized ? IdeApp.Workspace.ActiveConfiguration : MonoDevelop.Projects.ConfigurationSelector.Default,
Token = token,
};
@@ -140,7 +140,7 @@ namespace MonoDevelop.Ide.TypeSystem
if (data.Token.IsCancellationRequested)
return false;
- if (!(pr is MonoDevelop.Projects.DotNetProject referencedProject) || !TypeSystemService.IsOutputTrackedProject (referencedProject))
+ if (!(pr is MonoDevelop.Projects.DotNetProject referencedProject) || !IdeApp.TypeSystemService.IsOutputTrackedProject (referencedProject))
continue;
var fileName = referencedProject.GetOutputFileName (data.ConfigurationSelector);
@@ -167,7 +167,7 @@ namespace MonoDevelop.Ide.TypeSystem
List<MonoDevelop.Projects.AssemblyReference> references;
try {
- var config = IdeApp.Workspace?.ActiveConfiguration ?? MonoDevelop.Projects.ConfigurationSelector.Default;
+ var config = IdeApp.IsInitialized ? IdeApp.Workspace.ActiveConfiguration : MonoDevelop.Projects.ConfigurationSelector.Default;
references = await netProj.GetReferences (config, token).ConfigureAwait (false);
} catch (Exception e) {
LoggingService.LogError ("Error while getting referenced projects.", e);
@@ -191,7 +191,7 @@ namespace MonoDevelop.Ide.TypeSystem
if (!addedProjects.Add (referencedProject))
continue;
- if (TypeSystemService.IsOutputTrackedProject (referencedProject))
+ if (IdeApp.TypeSystemService.IsOutputTrackedProject (referencedProject))
continue;
var aliases = pr.EnumerateAliases ();
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 1293ad41d8..b059f08a0e 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
@@ -1,4 +1,4 @@
-//
+//
// MonoDevelopWorkspace.ProjectSystemHandler.cs
//
// Author:
@@ -61,7 +61,7 @@ namespace MonoDevelop.Ide.TypeSystem
this.projections = projections;
metadataHandler = new Lazy<MetadataReferenceHandler> (() => new MetadataReferenceHandler (workspace.MetadataReferenceManager, projectMap));
- hostDiagnosticUpdateSource = new Lazy<HostDiagnosticUpdateSource> (() => new HostDiagnosticUpdateSource (workspace, Composition.CompositionManager.GetExportedValue<IDiagnosticUpdateSourceRegistrationService> ()));
+ hostDiagnosticUpdateSource = new Lazy<HostDiagnosticUpdateSource> (() => new HostDiagnosticUpdateSource (workspace, workspace.compositionManager.GetExportedValue<IDiagnosticUpdateSourceRegistrationService> ()));
}
#region Solution mapping
@@ -84,7 +84,7 @@ namespace MonoDevelop.Ide.TypeSystem
static async void OnSolutionModified (object sender, MonoDevelop.Projects.WorkspaceItemEventArgs args)
{
var sol = (MonoDevelop.Projects.Solution)args.Item;
- var workspace = await TypeSystemService.GetWorkspaceAsync (sol, CancellationToken.None);
+ var workspace = await IdeApp.TypeSystemService.GetWorkspaceAsync (sol, CancellationToken.None);
var solId = workspace.ProjectHandler.GetSolutionId (sol);
if (solId == null)
return;
@@ -111,9 +111,9 @@ namespace MonoDevelop.Ide.TypeSystem
{
var projectId = projectMap.GetOrCreateId (p, oldProject);
- var config = IdeApp.Workspace != null ? p.GetConfiguration (IdeApp.Workspace.ActiveConfiguration) as MonoDevelop.Projects.DotNetProjectConfiguration : null;
+ var config = IdeApp.IsInitialized ? p.GetConfiguration (IdeApp.Workspace.ActiveConfiguration) as MonoDevelop.Projects.DotNetProjectConfiguration : null;
MonoDevelop.Projects.DotNetCompilerParameters cp = config?.CompilationParameters;
- FilePath fileName = IdeApp.Workspace != null ? p.GetOutputFileName (IdeApp.Workspace.ActiveConfiguration) : (FilePath)"";
+ FilePath fileName = IdeApp.IsInitialized ? p.GetOutputFileName (IdeApp.Workspace.ActiveConfiguration) : (FilePath)"";
if (fileName.IsNullOrEmpty)
fileName = new FilePath (p.Name + ".dll");
@@ -291,8 +291,8 @@ namespace MonoDevelop.Ide.TypeSystem
static bool CanGenerateAnalysisContextForNonCompileable (MonoDevelop.Projects.Project p, MonoDevelop.Projects.ProjectFile f)
{
- var mimeType = DesktopService.GetMimeTypeForUri (f.FilePath);
- var node = TypeSystemService.GetTypeSystemParserNode (mimeType, f.BuildAction);
+ var mimeType = IdeServices.DesktopService.GetMimeTypeForUri (f.FilePath);
+ var node = IdeApp.TypeSystemService.GetTypeSystemParserNode (mimeType, f.BuildAction);
if (node?.Parser == null)
return false;
return node.Parser.CanGenerateAnalysisDocument (mimeType, f.BuildAction, p.SupportedLanguages);
@@ -339,8 +339,8 @@ namespace MonoDevelop.Ide.TypeSystem
IEnumerable<DocumentInfo> GenerateProjections (MonoDevelop.Projects.ProjectFile f, DocumentMap documentMap, MonoDevelop.Projects.Project p, ProjectData oldProjectData, HashSet<DocumentId> duplicates)
{
- var mimeType = DesktopService.GetMimeTypeForUri (f.FilePath);
- var node = TypeSystemService.GetTypeSystemParserNode (mimeType, f.BuildAction);
+ var mimeType = IdeServices.DesktopService.GetMimeTypeForUri (f.FilePath);
+ var node = IdeApp.TypeSystemService.GetTypeSystemParserNode (mimeType, f.BuildAction);
if (node == null || !node.Parser.CanGenerateProjection (mimeType, f.BuildAction, p.SupportedLanguages))
yield break;
var options = new ParseOptions {
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 753abf5af7..14f66e6d0d 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs
@@ -1,29 +1,29 @@
-//
-// MonoDevelopWorkspace.cs
-//
-// Author:
-// Mike Krüger <mkrueger@xamarin.com>
-//
-// Copyright (c) 2014 Xamarin Inc. (http://xamarin.com)
-//
-// 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.
-
+//
+// MonoDevelopWorkspace.cs
+//
+// Author:
+// Mike Krüger <mkrueger@xamarin.com>
+//
+// Copyright (c) 2014 Xamarin Inc. (http://xamarin.com)
+//
+// 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 Microsoft.CodeAnalysis;
using System.Linq;
@@ -36,17 +36,10 @@ using System.Threading.Tasks;
using MonoDevelop.Ide.Editor;
using Microsoft.CodeAnalysis.Host;
using MonoDevelop.Core.Text;
-using System.Collections.Concurrent;
using MonoDevelop.Ide.CodeFormatting;
-using Gtk;
using MonoDevelop.Ide.Editor.Projection;
-using System.Reflection;
-using Microsoft.CodeAnalysis.Host.Mef;
-using System.Text;
-using System.Collections.Immutable;
using System.ComponentModel;
using Mono.Addins;
-using MonoDevelop.Core.AddIns;
using Microsoft.CodeAnalysis.Extensions;
using Microsoft.CodeAnalysis.Internal.Log;
using Microsoft.CodeAnalysis.Shared.Options;
@@ -55,6 +48,9 @@ using Microsoft.CodeAnalysis.SolutionCrawler;
using MonoDevelop.Ide.Composition;
using MonoDevelop.Ide.RoslynServices;
using MonoDevelop.Core.Assemblies;
+using MonoDevelop.Ide.Gui.Documents;
+using MonoDevelop.Ide.Gui;
+using Document = Microsoft.CodeAnalysis.Document;
namespace MonoDevelop.Ide.TypeSystem
{
@@ -62,11 +58,18 @@ namespace MonoDevelop.Ide.TypeSystem
{
public const string ServiceLayer = nameof(MonoDevelopWorkspace);
- // Background compiler is used to trigger compilations in the background for the solution and hold onto them
- // so in case nothing references the solution in current stacks, they're not collected.
- // We previously used to experience pathological GC times on large solutions, and this was caused
- // by the compilations being freed out of memory due to only being weakly referenced, and recomputing them on
- // a case by case basis.
+ private readonly ServiceProvider serviceProvider;
+ TypeSystemService typeSystemService;
+ DesktopService desktopService;
+ DocumentManager documentManager;
+ RootWorkspace workspace;
+ CompositionManager compositionManager;
+
+ // Background compiler is used to trigger compilations in the background for the solution and hold onto them
+ // so in case nothing references the solution in current stacks, they're not collected.
+ // We previously used to experience pathological GC times on large solutions, and this was caused
+ // by the compilations being freed out of memory due to only being weakly referenced, and recomputing them on
+ // a case by case basis.
BackgroundCompiler backgroundCompiler;
internal readonly WorkspaceId Id;
@@ -83,13 +86,12 @@ namespace MonoDevelop.Ide.TypeSystem
public MonoDevelop.Projects.Solution MonoDevelopSolution { get; }
internal MonoDevelopMetadataReferenceManager MetadataReferenceManager => manager.Value;
- internal static HostServices HostServices => CompositionManager.Instance.HostServices;
-
- static MonoDevelopWorkspace ()
- {
- Tasks.CommentTasksProvider.Initialize ();
- }
-
+
+ static MonoDevelopWorkspace ()
+ {
+ Tasks.CommentTasksProvider.Initialize ();
+ }
+
/// <summary>
/// This bypasses the type system service. Use with care.
/// </summary>
@@ -99,9 +101,11 @@ namespace MonoDevelop.Ide.TypeSystem
OnSolutionAdded (sInfo);
}
- internal MonoDevelopWorkspace (MonoDevelop.Projects.Solution solution) : base (HostServices, WorkspaceKind.Host)
- {
+ internal MonoDevelopWorkspace (HostServices hostServices, MonoDevelop.Projects.Solution solution, TypeSystemService typeSystemService) : base (hostServices, WorkspaceKind.Host)
+ {
this.MonoDevelopSolution = solution;
+ this.serviceProvider = typeSystemService.ServiceProvider ?? Runtime.ServiceProvider;
+ this.typeSystemService = typeSystemService;
this.Id = WorkspaceId.Next ();
Projections = new ProjectionData ();
@@ -109,19 +113,25 @@ namespace MonoDevelop.Ide.TypeSystem
ProjectMap = new ProjectDataMap (this);
ProjectHandler = new ProjectSystemHandler (this, ProjectMap, Projections);
manager = new Lazy<MonoDevelopMetadataReferenceManager> (() => Services.GetService<MonoDevelopMetadataReferenceManager> ());
- metadataHandler = new Lazy<MetadataReferenceHandler> (() => new MetadataReferenceHandler (MetadataReferenceManager, ProjectMap));
-
- if (IdeApp.Workspace != null && solution != null) {
- IdeApp.Workspace.ActiveConfigurationChanged += HandleActiveConfigurationChanged;
- }
+ metadataHandler = new Lazy<MetadataReferenceHandler> (() => new MetadataReferenceHandler (MetadataReferenceManager, ProjectMap));
+ }
+
+ internal async Task Initialize ()
+ {
+ serviceProvider.WhenServiceInitialized<RootWorkspace> (s => {
+ workspace = s;
+ if (MonoDevelopSolution != null)
+ workspace.ActiveConfigurationChanged += HandleActiveConfigurationChanged;
+ });
+
backgroundCompiler = new BackgroundCompiler (this);
var cacheService = Services.GetService<IWorkspaceCacheService> ();
if (cacheService != null)
- cacheService.CacheFlushRequested += OnCacheFlushRequested;
-
- // Trigger running compiler syntax and semantic errors via the diagnostic analyzer engine
- IdeApp.Preferences.Roslyn.FullSolutionAnalysisRuntimeEnabled = true;
+ cacheService.CacheFlushRequested += OnCacheFlushRequested;
+
+ // Trigger running compiler syntax and semantic errors via the diagnostic analyzer engine
+ TypeSystemService.Preferences.FullSolutionAnalysisRuntimeEnabled = true;
Options = Options.WithChangedOption (Microsoft.CodeAnalysis.Diagnostics.InternalRuntimeDiagnosticOptions.Syntax, true)
.WithChangedOption (Microsoft.CodeAnalysis.Diagnostics.InternalRuntimeDiagnosticOptions.Semantic, true)
// Turn on FSA on a new workspace addition
@@ -132,21 +142,26 @@ namespace MonoDevelop.Ide.TypeSystem
// https://github.com/mono/monodevelop/issues/4149 https://github.com/dotnet/roslyn/issues/25453
.WithChangedOption (Microsoft.CodeAnalysis.Storage.StorageOptions.SolutionSizeThreshold, MonoDevelop.Core.Platform.IsLinux ? int.MaxValue : 0);
- if (IdeApp.Preferences.EnableSourceAnalysis) {
+ if (TypeSystemService.EnableSourceAnalysis) {
var solutionCrawler = Services.GetService<ISolutionCrawlerRegistrationService> ();
solutionCrawler.Register (this);
}
- IdeApp.Preferences.EnableSourceAnalysis.Changed += OnEnableSourceAnalysisChanged;
-
- // TODO: Unhack C# here when monodevelop workspace supports more than C#
- IdeApp.Preferences.Roslyn.FullSolutionAnalysisRuntimeEnabledChanged += OnEnableFullSourceAnalysisChanged;
+ TypeSystemService.EnableSourceAnalysis.Changed += OnEnableSourceAnalysisChanged;
+
+ // TODO: Unhack C# here when monodevelop workspace supports more than C#
+ TypeSystemService.Preferences.FullSolutionAnalysisRuntimeEnabledChanged += OnEnableFullSourceAnalysisChanged;
foreach (var factory in AddinManager.GetExtensionObjects<Microsoft.CodeAnalysis.Options.IDocumentOptionsProviderFactory>("/MonoDevelop/Ide/TypeService/OptionProviders"))
Services.GetRequiredService<Microsoft.CodeAnalysis.Options.IOptionService> ().RegisterDocumentOptionsProvider (factory.Create (this));
- if (solution != null)
- DesktopService.MemoryMonitor.StatusChanged += OnMemoryStatusChanged;
+ desktopService = await serviceProvider.GetService<DesktopService> ().ConfigureAwait (false);
+ documentManager = await serviceProvider.GetService<DocumentManager> ().ConfigureAwait (false);
+ compositionManager = await serviceProvider.GetService<CompositionManager> ().ConfigureAwait (false);
+
+ if (MonoDevelopSolution != null) {
+ Runtime.RunInMainThread (() => desktopService.MemoryMonitor.StatusChanged += OnMemoryStatusChanged).Ignore ();
+ }
}
bool lowMemoryLogged;
@@ -173,7 +188,7 @@ namespace MonoDevelop.Ide.TypeSystem
return;
Options = Options.WithChangedOption (RuntimeOptions.FullSolutionAnalysis, false);
- IdeApp.Preferences.Roslyn.FullSolutionAnalysisRuntimeEnabled = false;
+ TypeSystemService.Preferences.FullSolutionAnalysisRuntimeEnabled = false;
if (IsUserOptionOn ()) {
// let user know full analysis is turned off due to memory concern.
// make sure we show info bar only once for the same solution.
@@ -182,7 +197,7 @@ namespace MonoDevelop.Ide.TypeSystem
const string LowVMMoreInfoLink = "https://go.microsoft.com/fwlink/?linkid=2003417&clcid=0x409";
Services.GetService<IErrorReportingService> ().ShowGlobalErrorInfo (
GettextCatalog.GetString ("{0} has suspended some advanced features to improve performance", BrandingService.ApplicationName),
- new InfoBarUI ("Learn more", InfoBarUI.UIKind.HyperLink, () => DesktopService.ShowUrl (LowVMMoreInfoLink), closeAfterAction: false),
+ new InfoBarUI ("Learn more", InfoBarUI.UIKind.HyperLink, () => desktopService.ShowUrl (LowVMMoreInfoLink), closeAfterAction: false),
new InfoBarUI ("Restore", InfoBarUI.UIKind.Button, () => Options = Options.WithChangedOption (RuntimeOptions.FullSolutionAnalysis, true))
);
}
@@ -214,7 +229,7 @@ namespace MonoDevelop.Ide.TypeSystem
// check languages currently on solution. since we only show info bar once, we don't need to track solution changes.
var languages = CurrentSolution.Projects.Select (p => p.Language).Distinct ();
foreach (var language in languages) {
- if (IdeApp.Preferences.Roslyn.For (language).SolutionCrawlerClosedFileDiagnostic) {
+ if (TypeSystemService.Preferences.For (language).SolutionCrawlerClosedFileDiagnostic) {
return true;
}
}
@@ -225,12 +240,12 @@ namespace MonoDevelop.Ide.TypeSystem
void OnEnableSourceAnalysisChanged(object sender, EventArgs args)
{
var solutionCrawler = Services.GetService<ISolutionCrawlerRegistrationService> ();
- if (IdeApp.Preferences.EnableSourceAnalysis)
+ if (TypeSystemService.EnableSourceAnalysis)
solutionCrawler.Register (this);
else
solutionCrawler.Unregister (this);
- var diagnosticAnalyzer = CompositionManager.GetExportedValue<Microsoft.CodeAnalysis.Diagnostics.IDiagnosticAnalyzerService> ();
+ var diagnosticAnalyzer = compositionManager.GetExportedValue<Microsoft.CodeAnalysis.Diagnostics.IDiagnosticAnalyzerService> ();
diagnosticAnalyzer.Reanalyze (this);
}
@@ -238,7 +253,7 @@ namespace MonoDevelop.Ide.TypeSystem
{
// we only want to turn on FSA if the option is explicitly enabled,
// we don't want to turn it off here.
- if (IdeApp.Preferences.Roslyn.FullSolutionAnalysisRuntimeEnabled) {
+ if (TypeSystemService.Preferences.FullSolutionAnalysisRuntimeEnabled) {
Options = Options.WithChangedOption (RuntimeOptions.FullSolutionAnalysis, true);
}
}
@@ -255,14 +270,15 @@ namespace MonoDevelop.Ide.TypeSystem
MetadataReferenceManager.ClearCache ();
- IdeApp.Preferences.EnableSourceAnalysis.Changed -= OnEnableSourceAnalysisChanged;
- IdeApp.Preferences.Roslyn.FullSolutionAnalysisRuntimeEnabledChanged -= OnEnableFullSourceAnalysisChanged;
- DesktopService.MemoryMonitor.StatusChanged -= OnMemoryStatusChanged;
+ TypeSystemService.EnableSourceAnalysis.Changed -= OnEnableSourceAnalysisChanged;
+ TypeSystemService.Preferences.FullSolutionAnalysisRuntimeEnabledChanged -= OnEnableFullSourceAnalysisChanged;
+ desktopService.MemoryMonitor.StatusChanged -= OnMemoryStatusChanged;
CancelLoad ();
- if (IdeApp.Workspace != null) {
- IdeApp.Workspace.ActiveConfigurationChanged -= HandleActiveConfigurationChanged;
- }
+
+ if (workspace != null)
+ workspace.ActiveConfigurationChanged -= HandleActiveConfigurationChanged;
+
if (MonoDevelopSolution != null) {
foreach (var prj in MonoDevelopSolution.GetAllProjects ()) {
UnloadMonoProject (prj);
@@ -293,7 +309,7 @@ namespace MonoDevelop.Ide.TypeSystem
internal void HideStatusIcon ()
{
- TypeSystemService.HideTypeInformationGatheringIcon (() => {
+ typeSystemService.HideTypeInformationGatheringIcon (() => {
LoadingFinished?.Invoke (this, EventArgs.Empty);
WorkspaceLoaded?.Invoke (this, EventArgs.Empty);
});
@@ -303,7 +319,7 @@ namespace MonoDevelop.Ide.TypeSystem
internal void ShowStatusIcon ()
{
- TypeSystemService.ShowTypeInformationGatheringIcon ();
+ typeSystemService.ShowTypeInformationGatheringIcon ();
}
async void HandleActiveConfigurationChanged (object sender, EventArgs e)
@@ -357,7 +373,7 @@ namespace MonoDevelop.Ide.TypeSystem
if (doc != null) {
var mdProject = GetMonoProject (doc.Project);
if (doc != null) {
- IdeApp.Workbench.OpenDocument (doc.FilePath, mdProject, activate);
+ documentManager.OpenDocument (new FileOpenInformation (doc.FilePath, mdProject, activate)).Ignore ();
}
}
}
@@ -535,9 +551,9 @@ namespace MonoDevelop.Ide.TypeSystem
}
} else {
var formatter = CodeFormatterService.GetFormatter (data.MimeType);
- var documentContext = IdeApp.Workbench.Documents.FirstOrDefault (d => FilePath.PathComparer.Compare (d.FileName, filePath) == 0);
+ var documentContext = documentManager.Documents.FirstOrDefault (d => FilePath.PathComparer.Compare (d.FileName, filePath) == 0)?.DocumentContext;
var root = await projectChanges.NewProject.GetDocument (id).GetSyntaxRootAsync ();
- var annotatedNode = root.DescendantNodesAndSelf ().FirstOrDefault (n => n.HasAnnotation (TypeSystemService.InsertionModeAnnotation));
+ var annotatedNode = root.DescendantNodesAndSelf ().FirstOrDefault (n => n.HasAnnotation (typeSystemService.InsertionModeAnnotation));
SyntaxToken? renameTokenOpt = root.GetAnnotatedNodesAndTokens (Microsoft.CodeAnalysis.CodeActions.RenameAnnotation.Kind)
.Where (s => s.IsToken)
.Select (s => s.AsToken ())
@@ -568,7 +584,7 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
if (annotatedNode != null && GetInsertionPoints != null) {
- IdeApp.Workbench.Documents.First (d => d.FileName == editor.FileName).Select ();
+ documentManager.Documents.First (d => d.FileName == editor.FileName).Select ();
var formattedVersion = editor.Version;
int startOffset = versionBeforeFormat.MoveOffsetTo (editor.Version, annotatedNode.Span.Start);
@@ -677,9 +693,9 @@ namespace MonoDevelop.Ide.TypeSystem
async Task UpdateProjectionsDocuments (Document document, ITextDocument data)
{
- var project = TypeSystemService.GetMonoProject (document.Project);
+ var project = typeSystemService.GetMonoProject (document.Project);
var file = project.Files.GetFile (data.FileName);
- var node = TypeSystemService.GetTypeSystemParserNode (data.MimeType, file.BuildAction);
+ var node = typeSystemService.GetTypeSystemParserNode (data.MimeType, file.BuildAction);
if (node != null && node.Parser.CanGenerateProjection (data.MimeType, file.BuildAction, project.SupportedLanguages)) {
var options = new ParseOptions {
FileName = file.FilePath,
@@ -747,20 +763,17 @@ namespace MonoDevelop.Ide.TypeSystem
} catch (Exception ex) {
LoggingService.LogError ("Error applying changes to documents", ex);
}
- if (IdeApp.Workbench != null) {
- var changedFiles = new HashSet<string> (tryApplyState_documentTextChangedContents.Keys, FilePath.PathComparer);
- foreach (var w in IdeApp.Workbench.Documents) {
- if (w.IsFile && changedFiles.Contains (w.FileName)) {
- w.StartReparseThread ();
- }
+ var changedFiles = new HashSet<string> (tryApplyState_documentTextChangedContents.Keys, FilePath.PathComparer);
+ foreach (var w in documentManager.Documents) {
+ if (w.IsFile && changedFiles.Contains (w.FileName)) {
+ w.DocumentContext.ReparseDocument ();
}
}
}, CancellationToken.None, TaskContinuationOptions.None, Runtime.MainTaskScheduler);
}
- if (tryApplyState_changedProjects.Count > 0) {
- ProjectSaveTask = IdeApp.ProjectOperations.SaveAsync (tryApplyState_changedProjects);
- }
+ if (tryApplyState_changedProjects.Count > 0)
+ ProjectSaveTask = IdeApp.IsInitialized ? IdeApp.ProjectOperations.SaveAsync (tryApplyState_changedProjects) : Task.WhenAll (tryApplyState_changedProjects.Select (p => p.SaveAsync (new ProgressMonitor ())));
return ret;
} finally {
@@ -817,7 +830,7 @@ namespace MonoDevelop.Ide.TypeSystem
info = info.WithFilePath (path).WithTextLoader (new MonoDevelopTextLoader (path));
string formattedText;
- var formatter = CodeFormatterService.GetFormatter (DesktopService.GetMimeTypeForUri (path));
+ var formatter = CodeFormatterService.GetFormatter (desktopService.GetMimeTypeForUri (path));
if (formatter != null && mdProject != null) {
formattedText = formatter.FormatText (mdProject.Policies, text.ToString ());
} else {
@@ -857,10 +870,10 @@ namespace MonoDevelop.Ide.TypeSystem
}
//force-close the old doc even if it's dirty
- var openDoc = IdeApp.Workbench.Documents.FirstOrDefault (d => d.IsFile && filePath.Equals (d.FileName));
+ var openDoc = documentManager.Documents.FirstOrDefault (d => d.IsFile && filePath.Equals (d.FileName));
if (openDoc != null && openDoc.IsDirty) {
- openDoc.Save ();
- ((Gui.SdiWorkspaceWindow)openDoc.Window).CloseWindow (true, true).Wait ();
+ openDoc.Save ().Wait ();
+ openDoc.Close ().Wait ();
}
//this will fire a OnDocumentRemoved event via OnFileRemoved
@@ -1080,10 +1093,10 @@ namespace MonoDevelop.Ide.TypeSystem
if (monoProject != null) {
var pf = monoProject.GetProjectFile (fileName);
if (pf != null) {
- var mimeType = DesktopService.GetMimeTypeForUri (fileName);
- if (TypeSystemService.CanParseProjections (monoProject, mimeType, fileName)) {
+ var mimeType = desktopService.GetMimeTypeForUri (fileName);
+ if (typeSystemService.CanParseProjections (monoProject, mimeType, fileName)) {
var parseOptions = new ParseOptions { Project = monoProject, FileName = fileName, Content = new StringTextSource (text), BuildAction = pf.BuildAction };
- var task = TypeSystemService.ParseProjection (parseOptions, mimeType);
+ var task = typeSystemService.ParseProjection (parseOptions, mimeType);
tasks.Add (task);
}
}
@@ -1112,9 +1125,10 @@ namespace MonoDevelop.Ide.TypeSystem
#region Project modification handlers
List<MonoDevelop.Projects.DotNetProject> modifiedProjects = new List<MonoDevelop.Projects.DotNetProject> ();
- readonly object projectModifyLock = new object ();
+ readonly object projectModifyLock = new object ();
bool freezeProjectModify;
Dictionary<MonoDevelop.Projects.DotNetProject, CancellationTokenSource> projectModifiedCts = new Dictionary<MonoDevelop.Projects.DotNetProject, CancellationTokenSource> ();
+
void OnProjectModified (object sender, MonoDevelop.Projects.SolutionItemModifiedEventArgs args)
{
lock (projectModifyLock) {
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService.cs
index bb351a6601..56c189d674 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService.cs
@@ -1,5 +1,5 @@
-//
-// TypeSystemService.cs
+//
+// IdeApp.TypeSystemService.cs
//
// Author:
// Mike Krüger <mkrueger@novell.com>
@@ -30,31 +30,42 @@ using System.IO;
using MonoDevelop.Projects;
using Mono.Addins;
using MonoDevelop.Core;
-using MonoDevelop.Ide;
using System.Threading;
using System.Xml;
using ICSharpCode.NRefactory.Utils;
using System.Threading.Tasks;
using MonoDevelop.Ide.Extensions;
using MonoDevelop.Core.Assemblies;
-using System.Text;
using MonoDevelop.Ide.Editor;
using MonoDevelop.Core.Text;
-using Microsoft.CodeAnalysis.Text;
-using Mono.Posix;
+using MonoDevelop.Ide.RoslynServices.Options;
+using MonoDevelop.Ide.Gui.Documents;
+using MonoDevelop.Ide.Composition;
namespace MonoDevelop.Ide.TypeSystem
{
- public static partial class TypeSystemService
+ [DefaultServiceImplementation]
+ public partial class TypeSystemService: Service
{
const string CurrentVersion = "1.1.9";
- static IEnumerable<TypeSystemParserNode> parsers;
- static string[] filesSkippedInParseThread = new string[0];
- public static Microsoft.CodeAnalysis.SyntaxAnnotation InsertionModeAnnotation = new Microsoft.CodeAnalysis.SyntaxAnnotation();
- internal static MonoDevelopRuleSetManager RuleSetManager { get; } = new MonoDevelopRuleSetManager ();
+ DocumentManager documentManager;
+ DesktopService desktopService;
+ RootWorkspace rootWorkspace;
+ CompositionManager compositionManager;
+
+ IEnumerable<TypeSystemParserNode> parsers;
+ string[] filesSkippedInParseThread = new string[0];
+
+ public Microsoft.CodeAnalysis.SyntaxAnnotation InsertionModeAnnotation { get; } = new Microsoft.CodeAnalysis.SyntaxAnnotation();
- internal static IEnumerable<TypeSystemParserNode> Parsers {
+ // Preferences
+ internal static RoslynPreferences Preferences { get; } = new RoslynPreferences ();
+ internal static ConfigurationProperty<bool> EnableSourceAnalysis = ConfigurationProperty.Create ("MonoDevelop.AnalysisCore.AnalysisEnabled_V2", true);
+
+ internal MonoDevelopRuleSetManager RuleSetManager { get; } = new MonoDevelopRuleSetManager ();
+
+ internal IEnumerable<TypeSystemParserNode> Parsers {
get {
return parsers;
}
@@ -63,20 +74,16 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
- public static void RemoveSkippedfile (FilePath fileName)
+ protected override async Task OnInitialize (ServiceProvider serviceProvider)
{
- filesSkippedInParseThread = filesSkippedInParseThread.Where (f => f != fileName).ToArray ();
- }
+ IntitializeTrackedProjectHandling ();
- public static void AddSkippedFile (FilePath fileName)
- {
- if (filesSkippedInParseThread.Any (f => f == fileName))
- return;
- filesSkippedInParseThread = filesSkippedInParseThread.Concat (new string[] { fileName }).ToArray ();
- }
+ serviceProvider.WhenServiceInitialized<DocumentManager> (s => documentManager = s);
+ serviceProvider.WhenServiceInitialized<RootWorkspace> (s => {
+ rootWorkspace = s;
+ rootWorkspace.ActiveConfigurationChanged += HandleActiveConfigurationChanged;
+ });
- static TypeSystemService ()
- {
RoslynServices.RoslynService.Initialize ();
CleanupCache ();
parsers = AddinManager.GetExtensionNodes<TypeSystemParserNode> ("/MonoDevelop/TypeSystem/Parser");
@@ -89,64 +96,95 @@ namespace MonoDevelop.Ide.TypeSystem
initialLoad = false;
try {
- emptyWorkspace = new MonoDevelopWorkspace (null);
+ compositionManager = await serviceProvider.GetService<CompositionManager> ().ConfigureAwait (false);
+ emptyWorkspace = new MonoDevelopWorkspace (compositionManager.HostServices, null, this);
+ await emptyWorkspace.Initialize ().ConfigureAwait (false);
} catch (Exception e) {
LoggingService.LogFatalError ("Can't create roslyn workspace", e);
}
- FileService.FileChanged += delegate(object sender, FileEventArgs e) {
- // if (!TrackFileChanges)
- // return;
-
- var filesToUpdate = new List<string> ();
- foreach (var file in e) {
- // Open documents are handled by the Document class itself.
- if (IdeApp.Workbench != null && IdeApp.Workbench.GetDocument (file.FileName) != null)
- continue;
-
- foreach (var w in workspaces) {
- foreach (var p in w.CurrentSolution.ProjectIds) {
- if (w.GetDocumentId (p, file.FileName) != null) {
- filesToUpdate.Add (file.FileName);
- goto found;
- }
+ FileService.FileChanged += FileService_FileChanged;
+
+ desktopService = await serviceProvider.GetService<DesktopService> ();
+ }
+
+ protected override Task OnDispose ()
+ {
+ FileService.FileChanged -= FileService_FileChanged;
+ if (rootWorkspace != null)
+ rootWorkspace.ActiveConfigurationChanged -= HandleActiveConfigurationChanged;
+ FinalizeTrackedProjectHandling ();
+ return Task.CompletedTask;
+ }
+
+ void FileService_FileChanged (object sender, FileEventArgs e)
+ {
+ var filesToUpdate = new List<string> ();
+ foreach (var file in e) {
+ // Open documents are handled by the Document class itself.
+ if (documentManager?.GetDocument (file.FileName) != null)
+ continue;
+
+ foreach (var w in workspaces) {
+ foreach (var p in w.CurrentSolution.ProjectIds) {
+ if (w.GetDocumentId (p, file.FileName) != null) {
+ filesToUpdate.Add (file.FileName);
+ goto found;
}
}
- found:;
-
}
- if (filesToUpdate.Count == 0)
- return;
+ found:;
- Task.Run (async delegate {
- try {
- foreach (var file in filesToUpdate) {
- var text = MonoDevelop.Core.Text.StringTextSource.ReadFrom (file).Text;
- foreach (var w in workspaces)
- await w.UpdateFileContent (file, text);
+ }
+ if (filesToUpdate.Count == 0)
+ return;
+
+ Task.Run (async delegate {
+ try {
+ foreach (var file in filesToUpdate) {
+ var text = MonoDevelop.Core.Text.StringTextSource.ReadFrom (file).Text;
+ foreach (var w in workspaces)
+ await w.UpdateFileContent (file, text);
+ }
+
+ Gtk.Application.Invoke ((o, args) => {
+ if (documentManager != null) {
+ foreach (var w in documentManager.Documents)
+ w.DocumentContext?.ReparseDocument ();
}
+ });
+ } catch (Exception) { }
+ });
+ }
- Gtk.Application.Invoke ((o, args) => {
- if (IdeApp.Workbench != null)
- foreach (var w in IdeApp.Workbench.Documents)
- w.StartReparseThread ();
- });
- } catch (Exception) {}
- });
- };
+ public void RemoveSkippedFile (FilePath fileName)
+ {
+ filesSkippedInParseThread = filesSkippedInParseThread.Where (f => f != fileName).ToArray ();
+ }
- IntitializeTrackedProjectHandling ();
+ public void AddSkippedFile (FilePath fileName)
+ {
+ if (filesSkippedInParseThread.Any (f => f == fileName))
+ return;
+ filesSkippedInParseThread = filesSkippedInParseThread.Concat (new string [] { fileName }).ToArray ();
}
- public static TypeSystemParser GetParser (string mimeType, string buildAction = BuildAction.Compile)
+ internal async Task<MonoDevelopWorkspace> CreateEmptyWorkspace ()
+ {
+ var ws = new MonoDevelopWorkspace (compositionManager.HostServices, null, this);
+ await ws.Initialize ();
+ return ws;
+ }
+
+ public TypeSystemParser GetParser (string mimeType, string buildAction = BuildAction.Compile)
{
var n = GetTypeSystemParserNode (mimeType, buildAction);
return n != null ? n.Parser : null;
}
- internal static TypeSystemParserNode GetTypeSystemParserNode (string mimeType, string buildAction)
+ internal TypeSystemParserNode GetTypeSystemParserNode (string mimeType, string buildAction)
{
- foreach (var mt in DesktopService.GetMimeTypeInheritanceChain (mimeType)) {
+ foreach (var mt in desktopService.GetMimeTypeInheritanceChain (mimeType)) {
var provider = Parsers.FirstOrDefault (p => p.CanParse (mt, buildAction));
if (provider != null)
return provider;
@@ -154,7 +192,7 @@ namespace MonoDevelop.Ide.TypeSystem
return null;
}
- public static Task<ParsedDocument> ParseFile (Project project, string fileName, CancellationToken cancellationToken = default(CancellationToken))
+ public Task<ParsedDocument> ParseFile (Project project, string fileName, CancellationToken cancellationToken = default(CancellationToken))
{
StringTextSource text;
@@ -166,10 +204,10 @@ namespace MonoDevelop.Ide.TypeSystem
return TaskUtil.Default<ParsedDocument>();
}
- return ParseFile (project, fileName, DesktopService.GetMimeTypeForUri (fileName), text, cancellationToken);
+ return ParseFile (project, fileName, desktopService.GetMimeTypeForUri (fileName), text, cancellationToken);
}
- public static Task<ParsedDocument> ParseFile (ParseOptions options, string mimeType, CancellationToken cancellationToken = default(CancellationToken))
+ public Task<ParsedDocument> ParseFile (ParseOptions options, string mimeType, CancellationToken cancellationToken = default(CancellationToken))
{
if (options == null)
throw new ArgumentNullException (nameof(options));
@@ -194,7 +232,7 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
- internal static bool CanParseProjections (Project project, string mimeType, string fileName)
+ internal bool CanParseProjections (Project project, string mimeType, string fileName)
{
var projectFile = project.GetProjectFile (fileName);
if (projectFile == null)
@@ -205,22 +243,22 @@ namespace MonoDevelop.Ide.TypeSystem
return parser.CanGenerateProjection (mimeType, projectFile.BuildAction, project.SupportedLanguages);
}
- public static Task<ParsedDocument> ParseFile (Project project, string fileName, string mimeType, ITextSource content, CancellationToken cancellationToken = default(CancellationToken))
+ public Task<ParsedDocument> ParseFile (Project project, string fileName, string mimeType, ITextSource content, CancellationToken cancellationToken = default(CancellationToken))
{
return ParseFile (new ParseOptions { FileName = fileName, Project = project, Content = content }, mimeType, cancellationToken);
}
- public static Task<ParsedDocument> ParseFile (Project project, string fileName, string mimeType, TextReader content, CancellationToken cancellationToken = default(CancellationToken))
+ public Task<ParsedDocument> ParseFile (Project project, string fileName, string mimeType, TextReader content, CancellationToken cancellationToken = default(CancellationToken))
{
return ParseFile (project, fileName, mimeType, new StringTextSource (content.ReadToEnd ()), cancellationToken);
}
- public static Task<ParsedDocument> ParseFile (Project project, IReadonlyTextDocument data, CancellationToken cancellationToken = default(CancellationToken))
+ public Task<ParsedDocument> ParseFile (Project project, IReadonlyTextDocument data, CancellationToken cancellationToken = default(CancellationToken))
{
return ParseFile (project, data.FileName, data.MimeType, data, cancellationToken);
}
- internal static async Task<ParsedDocumentProjection> ParseProjection (ParseOptions options, string mimeType, CancellationToken cancellationToken = default(CancellationToken))
+ internal async Task<ParsedDocumentProjection> ParseProjection (ParseOptions options, string mimeType, CancellationToken cancellationToken = default(CancellationToken))
{
if (options == null)
throw new ArgumentNullException (nameof(options));
@@ -268,26 +306,26 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
- internal static Task<ParsedDocumentProjection> ParseProjection (Project project, string fileName, string mimeType, ITextSource content, CancellationToken cancellationToken = default(CancellationToken))
+ internal Task<ParsedDocumentProjection> ParseProjection (Project project, string fileName, string mimeType, ITextSource content, CancellationToken cancellationToken = default(CancellationToken))
{
return ParseProjection (new ParseOptions { FileName = fileName, Project = project, Content = content }, mimeType, cancellationToken);
}
- internal static Task<ParsedDocumentProjection> ParseProjection (Project project, string fileName, string mimeType, TextReader content, CancellationToken cancellationToken = default(CancellationToken))
+ internal Task<ParsedDocumentProjection> ParseProjection (Project project, string fileName, string mimeType, TextReader content, CancellationToken cancellationToken = default(CancellationToken))
{
return ParseProjection (project, fileName, mimeType, new StringTextSource (content.ReadToEnd ()), cancellationToken);
}
- internal static Task<ParsedDocumentProjection> ParseProjection (Project project, IReadonlyTextDocument data, CancellationToken cancellationToken = default(CancellationToken))
+ internal Task<ParsedDocumentProjection> ParseProjection (Project project, IReadonlyTextDocument data, CancellationToken cancellationToken = default(CancellationToken))
{
return ParseProjection (project, data.FileName, data.MimeType, data, cancellationToken);
}
#region Folding parsers
- static List<MimeTypeExtensionNode> foldingParsers;
+ List<MimeTypeExtensionNode> foldingParsers;
- static IEnumerable<MimeTypeExtensionNode> FoldingParsers {
+ IEnumerable<MimeTypeExtensionNode> FoldingParsers {
get {
if (foldingParsers == null) {
foldingParsers = new List<MimeTypeExtensionNode> ();
@@ -306,9 +344,9 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
- public static IFoldingParser GetFoldingParser (string mimeType)
+ public IFoldingParser GetFoldingParser (string mimeType)
{
- foreach (var mt in DesktopService.GetMimeTypeInheritanceChain (mimeType)) {
+ foreach (var mt in desktopService.GetMimeTypeInheritanceChain (mimeType)) {
var node = FoldingParsers.FirstOrDefault (n => n.MimeType == mt);
if (node != null)
return node.CreateInstance () as IFoldingParser;
@@ -319,7 +357,7 @@ namespace MonoDevelop.Ide.TypeSystem
#region Parser Database Handling
- static string GetCacheDirectory (TargetFramework framework)
+ string GetCacheDirectory (TargetFramework framework)
{
var derivedDataPath = UserProfile.Current.CacheDir.Combine ("DerivedData");
@@ -342,7 +380,7 @@ namespace MonoDevelop.Ide.TypeSystem
return result;
}
- static string InternalGetCacheDirectory (FilePath filename)
+ string InternalGetCacheDirectory (FilePath filename)
{
CanonicalizePath (ref filename);
var assemblyCacheRoot = GetAssemblyCacheRoot (filename);
@@ -367,14 +405,14 @@ namespace MonoDevelop.Ide.TypeSystem
/// <returns>The cache directory.</returns>
/// <param name="project">The project to get the cache for.</param>
/// <param name="forceCreation">If set to <c>true</c> the creation is forced and the method doesn't return null.</param>
- public static string GetCacheDirectory (Project project, bool forceCreation = false)
+ public string GetCacheDirectory (Project project, bool forceCreation = false)
{
if (project == null)
throw new ArgumentNullException (nameof(project));
return GetCacheDirectory (project.FileName, forceCreation);
}
- static readonly Dictionary<string, object> cacheLocker = new Dictionary<string, object> ();
+ readonly Dictionary<string, object> cacheLocker = new Dictionary<string, object> ();
/// <summary>
/// Gets the cache directory for arbitrary file names.
@@ -383,7 +421,7 @@ namespace MonoDevelop.Ide.TypeSystem
/// <returns>The cache directory.</returns>
/// <param name="fileName">The file name to get the cache for.</param>
/// <param name="forceCreation">If set to <c>true</c> the creation is forced and the method doesn't return null.</param>
- public static string GetCacheDirectory (string fileName, bool forceCreation = false)
+ public string GetCacheDirectory (string fileName, bool forceCreation = false)
{
if (fileName == null)
throw new ArgumentNullException (nameof(fileName));
@@ -416,9 +454,9 @@ namespace MonoDevelop.Ide.TypeSystem
public string Version { get; set; }
}
- static readonly Dictionary<FilePath, CacheDirectoryInfo> cacheDirectoryCache = new Dictionary<FilePath, CacheDirectoryInfo> ();
+ readonly Dictionary<FilePath, CacheDirectoryInfo> cacheDirectoryCache = new Dictionary<FilePath, CacheDirectoryInfo> ();
- static void CanonicalizePath (ref FilePath fileName)
+ void CanonicalizePath (ref FilePath fileName)
{
try {
// There are some situations where that may cause an exception.
@@ -433,7 +471,7 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
- static bool CheckCacheDirectoryIsCorrect (FilePath filename, FilePath candidate, out string result)
+ bool CheckCacheDirectoryIsCorrect (FilePath filename, FilePath candidate, out string result)
{
CanonicalizePath (ref filename);
CanonicalizePath (ref candidate);
@@ -471,7 +509,7 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
- static string GetAssemblyCacheRoot (string filename)
+ string GetAssemblyCacheRoot (string filename)
{
string derivedDataPath = UserProfile.Current.CacheDir.Combine ("DerivedData");
string name = Path.GetFileName (filename);
@@ -485,7 +523,7 @@ namespace MonoDevelop.Ide.TypeSystem
/// Use this method instead of the normal <c>string.GetHashCode</c> if the hash code
/// is persisted to disk.
/// </summary>
- static int GetStableHashCode(string text)
+ int GetStableHashCode(string text)
{
unchecked {
int h = 0;
@@ -496,7 +534,7 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
- static IEnumerable<string> GetPossibleCacheDirNames (string baseName)
+ IEnumerable<string> GetPossibleCacheDirNames (string baseName)
{
int i = 0;
while (i < 999999) {
@@ -506,12 +544,12 @@ namespace MonoDevelop.Ide.TypeSystem
throw new Exception ("Too many cache directories");
}
- static string EscapeToXml (string txt)
+ string EscapeToXml (string txt)
{
return new System.Xml.Linq.XText (txt).ToString ();
}
- static string CreateCacheDirectory (FilePath fileName)
+ string CreateCacheDirectory (FilePath fileName)
{
CanonicalizePath (ref fileName);
try {
@@ -532,9 +570,9 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
- static readonly FastSerializer sharedSerializer = new FastSerializer ();
+ readonly FastSerializer sharedSerializer = new FastSerializer ();
- static T DeserializeObject<T> (string path) where T : class
+ T DeserializeObject<T> (string path) where T : class
{
var t = Counters.ParserService.ObjectDeserialized.BeginTiming (path);
try {
@@ -553,7 +591,7 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
- static void SerializeObject (string path, object obj)
+ void SerializeObject (string path, object obj)
{
if (obj == null)
throw new ArgumentNullException (nameof(obj));
@@ -579,7 +617,7 @@ namespace MonoDevelop.Ide.TypeSystem
/// <summary>
/// Removes all cache directories which are older than 30 days.
/// </summary>
- static void CleanupCache ()
+ void CleanupCache ()
{
string derivedDataPath = UserProfile.Current.CacheDir.Combine ("DerivedData");
IEnumerable<string> cacheDirectories;
@@ -610,7 +648,7 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
- static void RemoveCache (string cacheDir)
+ void RemoveCache (string cacheDir)
{
try {
Directory.Delete (cacheDir, true);
@@ -619,7 +657,7 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
- static void TouchCache (string cacheDir)
+ void TouchCache (string cacheDir)
{
try {
Directory.SetLastWriteTime (cacheDir, DateTime.Now);
@@ -628,7 +666,7 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
- static void StoreExtensionObject (string cacheDir, object extensionObject)
+ void StoreExtensionObject (string cacheDir, object extensionObject)
{
if (cacheDir == null)
throw new ArgumentNullException (nameof(cacheDir));
@@ -649,7 +687,7 @@ namespace MonoDevelop.Ide.TypeSystem
#endregion
- internal static void InformDocumentClose (Microsoft.CodeAnalysis.DocumentId analysisDocument, FilePath fileName)
+ internal void InformDocumentClose (Microsoft.CodeAnalysis.DocumentId analysisDocument, FilePath fileName)
{
foreach (var w in workspaces) {
if (w.GetOpenDocumentIds (analysisDocument.ProjectId).Contains (analysisDocument) )
@@ -658,7 +696,7 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
- internal static void InformDocumentOpen (Microsoft.CodeAnalysis.DocumentId analysisDocument, TextEditor editor, DocumentContext context)
+ internal void InformDocumentOpen (Microsoft.CodeAnalysis.DocumentId analysisDocument, TextEditor editor, DocumentContext context)
{
foreach (var w in workspaces) {
if (w.Contains (analysisDocument.ProjectId)) {
@@ -672,7 +710,7 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
- internal static void InformDocumentOpen (Microsoft.CodeAnalysis.Workspace ws, Microsoft.CodeAnalysis.DocumentId analysisDocument, TextEditor editor, DocumentContext context)
+ internal void InformDocumentOpen (Microsoft.CodeAnalysis.Workspace ws, Microsoft.CodeAnalysis.DocumentId analysisDocument, TextEditor editor, DocumentContext context)
{
if (ws == null)
throw new ArgumentNullException (nameof (ws));
@@ -685,7 +723,7 @@ namespace MonoDevelop.Ide.TypeSystem
static bool gotDocumentRequestError = false;
- public static Microsoft.CodeAnalysis.ProjectId GetProjectId (MonoDevelop.Projects.Project project)
+ public Microsoft.CodeAnalysis.ProjectId GetProjectId (MonoDevelop.Projects.Project project)
{
if (project == null)
throw new ArgumentNullException (nameof(project));
@@ -698,7 +736,7 @@ namespace MonoDevelop.Ide.TypeSystem
return null;
}
- public static Microsoft.CodeAnalysis.Document GetCodeAnalysisDocument (Microsoft.CodeAnalysis.DocumentId docId, CancellationToken cancellationToken = default (CancellationToken))
+ public Microsoft.CodeAnalysis.Document GetCodeAnalysisDocument (Microsoft.CodeAnalysis.DocumentId docId, CancellationToken cancellationToken = default (CancellationToken))
{
if (docId == null)
throw new ArgumentNullException (nameof(docId));
@@ -711,7 +749,7 @@ namespace MonoDevelop.Ide.TypeSystem
return null;
}
- public static MonoDevelop.Projects.Project GetMonoProject (Microsoft.CodeAnalysis.Project project)
+ public MonoDevelop.Projects.Project GetMonoProject (Microsoft.CodeAnalysis.Project project)
{
if (project == null)
throw new ArgumentNullException (nameof(project));
@@ -725,7 +763,7 @@ namespace MonoDevelop.Ide.TypeSystem
}
- public static MonoDevelop.Projects.Project GetMonoProject (Microsoft.CodeAnalysis.DocumentId documentId)
+ public MonoDevelop.Projects.Project GetMonoProject (Microsoft.CodeAnalysis.DocumentId documentId)
{
foreach (var w in workspaces) {
var doc = w.GetDocument (documentId);
@@ -739,10 +777,10 @@ namespace MonoDevelop.Ide.TypeSystem
return null;
}
- static StatusBarIcon statusIcon = null;
- static int workspacesLoading = 0;
+ StatusBarIcon statusIcon = null;
+ int workspacesLoading = 0;
- internal static void ShowTypeInformationGatheringIcon ()
+ internal void ShowTypeInformationGatheringIcon ()
{
Gtk.Application.Invoke ((o, args) => {
workspacesLoading++;
@@ -756,13 +794,15 @@ namespace MonoDevelop.Ide.TypeSystem
});
}
- internal static void HideTypeInformationGatheringIcon (Action callback = null)
+ internal void HideTypeInformationGatheringIcon (Action callback = null)
{
Gtk.Application.Invoke ((o, args) => {
workspacesLoading--;
- if (workspacesLoading == 0 && statusIcon != null) {
- statusIcon.Dispose ();
- statusIcon = null;
+ if (workspacesLoading == 0) {
+ if (statusIcon != null) {
+ statusIcon.Dispose ();
+ statusIcon = null;
+ }
callback?.Invoke ();
}
});
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 66780c4c5b..a9b2ed71f5 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
@@ -1,5 +1,5 @@
//
-// TypeSystemService.cs
+// IdeApp.TypeSystemService.cs
//
// Author:
// Mike Krüger <mkrueger@xamarin.com>
@@ -39,23 +39,23 @@ using System.ComponentModel;
namespace MonoDevelop.Ide.TypeSystem
{
- public static partial class TypeSystemService
+ public partial class TypeSystemService
{
//Internal for unit test
- internal static readonly MonoDevelopWorkspace emptyWorkspace;
+ internal MonoDevelopWorkspace emptyWorkspace;
- static object workspaceLock = new object();
- static ImmutableList<MonoDevelopWorkspace> workspaces = ImmutableList<MonoDevelopWorkspace>.Empty;
- static ConcurrentDictionary<MonoDevelop.Projects.Solution, TaskCompletionSource<MonoDevelopWorkspace>> workspaceRequests = new ConcurrentDictionary<MonoDevelop.Projects.Solution, TaskCompletionSource<MonoDevelopWorkspace>> ();
+ object workspaceLock = new object();
+ ImmutableList<MonoDevelopWorkspace> workspaces = ImmutableList<MonoDevelopWorkspace>.Empty;
+ ConcurrentDictionary<MonoDevelop.Projects.Solution, TaskCompletionSource<MonoDevelopWorkspace>> workspaceRequests = new ConcurrentDictionary<MonoDevelop.Projects.Solution, TaskCompletionSource<MonoDevelopWorkspace>> ();
- public static ImmutableArray<Microsoft.CodeAnalysis.Workspace> AllWorkspaces {
+ public ImmutableArray<Microsoft.CodeAnalysis.Workspace> AllWorkspaces {
get {
return workspaces.ToImmutableArray<Microsoft.CodeAnalysis.Workspace> ();
}
}
- public static MonoDevelopWorkspace GetWorkspace (MonoDevelop.Projects.Solution solution)
+ public MonoDevelopWorkspace GetWorkspace (MonoDevelop.Projects.Solution solution)
{
if (solution == null)
throw new ArgumentNullException (nameof(solution));
@@ -66,7 +66,7 @@ namespace MonoDevelop.Ide.TypeSystem
return emptyWorkspace;
}
- public static async Task<MonoDevelopWorkspace> GetWorkspaceAsync (MonoDevelop.Projects.Solution solution, CancellationToken cancellationToken = default (CancellationToken))
+ public async Task<MonoDevelopWorkspace> GetWorkspaceAsync (MonoDevelop.Projects.Solution solution, CancellationToken cancellationToken = default (CancellationToken))
{
var workspace = GetWorkspace (solution);
if (workspace != emptyWorkspace)
@@ -85,7 +85,7 @@ namespace MonoDevelop.Ide.TypeSystem
return workspace;
}
- internal static MonoDevelopWorkspace GetWorkspace (WorkspaceId id)
+ internal MonoDevelopWorkspace GetWorkspace (WorkspaceId id)
{
foreach (var ws in workspaces) {
if (ws.Id.Equals (id))
@@ -94,9 +94,9 @@ namespace MonoDevelop.Ide.TypeSystem
return emptyWorkspace;
}
- public static Microsoft.CodeAnalysis.Workspace Workspace {
+ public Microsoft.CodeAnalysis.Workspace Workspace {
get {
- var solution = IdeApp.ProjectOperations?.CurrentSelectedSolution;
+ var solution = rootWorkspace?.CurrentSelectedSolution;
if (solution == null)
return emptyWorkspace;
return GetWorkspace (solution);
@@ -104,7 +104,7 @@ namespace MonoDevelop.Ide.TypeSystem
}
- public static void NotifyFileChange (string fileName, string text)
+ public void NotifyFileChange (string fileName, string text)
{
try {
foreach (var ws in workspaces)
@@ -114,37 +114,36 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
- internal static async Task<List<MonoDevelopWorkspace>> Load (WorkspaceItem item, ProgressMonitor progressMonitor, CancellationToken cancellationToken = default (CancellationToken), bool showStatusIcon = true)
+ internal async Task<List<MonoDevelopWorkspace>> Load (WorkspaceItem item, ProgressMonitor progressMonitor, CancellationToken cancellationToken = default (CancellationToken), bool showStatusIcon = true)
{
using (Counters.ParserService.WorkspaceItemLoaded.BeginTiming ()) {
- var wsList = CreateWorkspaces (item).ToList();
+ var wsList = new List<MonoDevelopWorkspace> ();
+ await CreateWorkspaces (item, wsList);
//If we want BeginTiming to work correctly we need to `await`
await InternalLoad (wsList, progressMonitor, cancellationToken, showStatusIcon).ConfigureAwait (false);
- return wsList.ToList ();
+ return wsList;
}
}
- static IEnumerable<MonoDevelopWorkspace> CreateWorkspaces (WorkspaceItem item)
+ async Task CreateWorkspaces (WorkspaceItem item, List<MonoDevelopWorkspace> result)
{
if (item is MonoDevelop.Projects.Workspace ws) {
- foreach (var wsItem in ws.Items) {
- foreach (var mdWorkspace in CreateWorkspaces (wsItem)) {
- yield return mdWorkspace;
- }
- }
+ foreach (var wsItem in ws.Items)
+ await CreateWorkspaces (wsItem, result);
ws.ItemAdded += OnWorkspaceItemAdded;
ws.ItemRemoved += OnWorkspaceItemRemoved;
} else if (item is MonoDevelop.Projects.Solution solution) {
- var workspace = new MonoDevelopWorkspace (solution);
+ var workspace = new MonoDevelopWorkspace (compositionManager.HostServices, solution, this);
+ await workspace.Initialize ();
lock (workspaceLock)
workspaces = workspaces.Add (workspace);
solution.SolutionItemAdded += OnSolutionItemAdded;
solution.SolutionItemRemoved += OnSolutionItemRemoved;
- yield return workspace;
+ result.Add (workspace);
}
}
- static async Task InternalLoad (List<MonoDevelopWorkspace> mdWorkspaces, ProgressMonitor progressMonitor, CancellationToken cancellationToken = default (CancellationToken), bool showStatusIcon = true)
+ async Task InternalLoad (List<MonoDevelopWorkspace> mdWorkspaces, ProgressMonitor progressMonitor, CancellationToken cancellationToken = default (CancellationToken), bool showStatusIcon = true)
{
foreach (var workspace in mdWorkspaces) {
if (showStatusIcon)
@@ -160,7 +159,7 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
- internal static void Unload (MonoDevelop.Projects.WorkspaceItem item)
+ internal void Unload (MonoDevelop.Projects.WorkspaceItem item)
{
var ws = item as MonoDevelop.Projects.Workspace;
if (ws != null) {
@@ -186,7 +185,7 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
- public static DocumentId GetDocumentId (MonoDevelop.Projects.Project project, string fileName)
+ public DocumentId GetDocumentId (MonoDevelop.Projects.Project project, string fileName)
{
if (project == null)
throw new ArgumentNullException (nameof(project));
@@ -201,7 +200,7 @@ namespace MonoDevelop.Ide.TypeSystem
return null;
}
- public static DocumentId GetDocumentId (Microsoft.CodeAnalysis.Workspace workspace, MonoDevelop.Projects.Project project, string fileName)
+ public DocumentId GetDocumentId (Microsoft.CodeAnalysis.Workspace workspace, MonoDevelop.Projects.Project project, string fileName)
{
if (project == null)
throw new ArgumentNullException (nameof(project));
@@ -218,7 +217,7 @@ namespace MonoDevelop.Ide.TypeSystem
}
- public static DocumentId GetDocumentId (ProjectId projectId, string fileName)
+ public DocumentId GetDocumentId (ProjectId projectId, string fileName)
{
if (projectId == null)
throw new ArgumentNullException (nameof(projectId));
@@ -231,7 +230,7 @@ namespace MonoDevelop.Ide.TypeSystem
return null;
}
- public static IEnumerable<DocumentId> GetDocuments (string fileName)
+ public IEnumerable<DocumentId> GetDocuments (string fileName)
{
if (fileName == null)
throw new ArgumentNullException (nameof(fileName));
@@ -245,7 +244,7 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
- public static Microsoft.CodeAnalysis.Project GetCodeAnalysisProject (MonoDevelop.Projects.Project project)
+ public Microsoft.CodeAnalysis.Project GetCodeAnalysisProject (MonoDevelop.Projects.Project project)
{
if (project == null)
throw new ArgumentNullException (nameof(project));
@@ -257,7 +256,7 @@ namespace MonoDevelop.Ide.TypeSystem
return null;
}
- public static async Task<Microsoft.CodeAnalysis.Project> GetCodeAnalysisProjectAsync (MonoDevelop.Projects.Project project, CancellationToken cancellationToken = default (CancellationToken))
+ public async Task<Microsoft.CodeAnalysis.Project> GetCodeAnalysisProjectAsync (MonoDevelop.Projects.Project project, CancellationToken cancellationToken = default (CancellationToken))
{
var parentSolution = project.ParentSolution;
var workspace = await GetWorkspaceAsync (parentSolution, cancellationToken);
@@ -287,7 +286,7 @@ namespace MonoDevelop.Ide.TypeSystem
return proj;
}
- public static Task<Compilation> GetCompilationAsync (MonoDevelop.Projects.Project project, CancellationToken cancellationToken = default(CancellationToken))
+ public Task<Compilation> GetCompilationAsync (MonoDevelop.Projects.Project project, CancellationToken cancellationToken = default(CancellationToken))
{
if (project == null)
throw new ArgumentNullException (nameof(project));
@@ -298,7 +297,7 @@ namespace MonoDevelop.Ide.TypeSystem
return Task.FromResult (default(Compilation));
}
- internal static Microsoft.CodeAnalysis.Project GetProject (MonoDevelop.Projects.Project project, CancellationToken cancellationToken = default (CancellationToken))
+ internal Microsoft.CodeAnalysis.Project GetProject (MonoDevelop.Projects.Project project, CancellationToken cancellationToken = default (CancellationToken))
{
foreach (var w in workspaces) {
var projectId = w.GetProjectId (project);
@@ -312,17 +311,17 @@ namespace MonoDevelop.Ide.TypeSystem
return null;
}
- static void OnWorkspaceItemAdded (object s, MonoDevelop.Projects.WorkspaceItemEventArgs args)
+ void OnWorkspaceItemAdded (object s, MonoDevelop.Projects.WorkspaceItemEventArgs args)
{
- TypeSystemService.Load (args.Item, null).Ignore ();
+ Load (args.Item, null).Ignore ();
}
- static void OnWorkspaceItemRemoved (object s, MonoDevelop.Projects.WorkspaceItemEventArgs args)
+ void OnWorkspaceItemRemoved (object s, MonoDevelop.Projects.WorkspaceItemEventArgs args)
{
Unload (args.Item);
}
- static async void OnSolutionItemAdded (object sender, MonoDevelop.Projects.SolutionItemChangeEventArgs args)
+ async void OnSolutionItemAdded (object sender, MonoDevelop.Projects.SolutionItemChangeEventArgs args)
{
try {
var project = args.SolutionItem as MonoDevelop.Projects.Project;
@@ -354,7 +353,7 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
- static void OnSolutionItemRemoved (object sender, MonoDevelop.Projects.SolutionItemChangeEventArgs args)
+ void OnSolutionItemRemoved (object sender, MonoDevelop.Projects.SolutionItemChangeEventArgs args)
{
if (args.Reloading) {
return;
@@ -369,37 +368,46 @@ namespace MonoDevelop.Ide.TypeSystem
}
#region Tracked project handling
- static readonly List<TypeSystemOutputTrackingNode> outputTrackedProjects = new List<TypeSystemOutputTrackingNode> ();
+ readonly List<TypeSystemOutputTrackingNode> outputTrackedProjects = new List<TypeSystemOutputTrackingNode> ();
- static void IntitializeTrackedProjectHandling ()
+ void IntitializeTrackedProjectHandling ()
{
- AddinManager.AddExtensionNodeHandler ("/MonoDevelop/TypeSystem/OutputTracking", delegate (object sender, ExtensionNodeEventArgs args) {
- var node = (TypeSystemOutputTrackingNode)args.ExtensionNode;
- switch (args.Change) {
- case ExtensionChange.Add:
- AddOutputTrackingNode (node);
- break;
- case ExtensionChange.Remove:
- outputTrackedProjects.Remove (node);
- break;
- }
- });
- if (IdeApp.ProjectOperations != null)
+ AddinManager.AddExtensionNodeHandler ("/MonoDevelop/TypeSystem/OutputTracking", OutputTrackingExtensionChanged);
+ IdeApp.Initialized += (sender, e) => {
IdeApp.ProjectOperations.EndBuild += HandleEndBuild;
- if (IdeApp.Workspace != null)
- IdeApp.Workspace.ActiveConfigurationChanged += HandleActiveConfigurationChanged;
+ };
+ }
+
+ void FinalizeTrackedProjectHandling ()
+ {
+ AddinManager.RemoveExtensionNodeHandler ("/MonoDevelop/TypeSystem/OutputTracking", OutputTrackingExtensionChanged);
+ if (IdeApp.IsInitialized)
+ IdeApp.ProjectOperations.EndBuild -= HandleEndBuild;
+ }
+
+ void OutputTrackingExtensionChanged (object sender, ExtensionNodeEventArgs args)
+ {
+ var node = (TypeSystemOutputTrackingNode)args.ExtensionNode;
+ switch (args.Change) {
+ case ExtensionChange.Add:
+ AddOutputTrackingNode (node);
+ break;
+ case ExtensionChange.Remove:
+ outputTrackedProjects.Remove (node);
+ break;
+ }
}
/// <summary>
/// Adds an output tracking node for unit testing purposes.
/// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- internal static void AddOutputTrackingNode (TypeSystemOutputTrackingNode node)
+ [EditorBrowsable (EditorBrowsableState.Never)]
+ internal void AddOutputTrackingNode (TypeSystemOutputTrackingNode node)
{
outputTrackedProjects.Add (node);
}
- static void HandleEndBuild (object sender, BuildEventArgs args)
+ void HandleEndBuild (object sender, BuildEventArgs args)
{
var project = args.SolutionItem as DotNetProject;
if (project == null)
@@ -407,10 +415,10 @@ namespace MonoDevelop.Ide.TypeSystem
CheckProjectOutput (project, true);
}
- static void HandleActiveConfigurationChanged (object sender, EventArgs e)
+ void HandleActiveConfigurationChanged (object sender, EventArgs e)
{
- if (IdeApp.ProjectOperations.CurrentSelectedSolution != null) {
- foreach (var pr in IdeApp.ProjectOperations.CurrentSelectedSolution.GetAllProjects ()) {
+ if (rootWorkspace?.CurrentSelectedSolution != null) {
+ foreach (var pr in rootWorkspace.CurrentSelectedSolution.GetAllProjects ()) {
var project = pr as DotNetProject;
if (project != null)
CheckProjectOutput (project, true);
@@ -418,23 +426,24 @@ namespace MonoDevelop.Ide.TypeSystem
}
}
- internal static bool IsOutputTrackedProject (DotNetProject project)
+ internal bool IsOutputTrackedProject (DotNetProject project)
{
if (project == null)
- throw new ArgumentNullException (nameof(project));
+ throw new ArgumentNullException (nameof(project));
return outputTrackedProjects.Any (otp => string.Equals (otp.LanguageName, project.LanguageName, StringComparison.OrdinalIgnoreCase)) ||
project.GetTypeTags().Any (tag => outputTrackedProjects.Any (otp => string.Equals (otp.ProjectType, tag, StringComparison.OrdinalIgnoreCase)));
}
- static void CheckProjectOutput (DotNetProject project, bool autoUpdate)
+ void CheckProjectOutput (DotNetProject project, bool autoUpdate)
{
if (project == null)
throw new ArgumentNullException (nameof(project));
if (IsOutputTrackedProject (project)) {
if (autoUpdate) {
// update documents
- foreach (var openDocument in IdeApp.Workbench.Documents) {
- openDocument.ReparseDocument ();
+ if (documentManager != null) {
+ foreach (var openDocument in documentManager.Documents)
+ openDocument.DocumentContext.ReparseDocument ();
}
}
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/AddinError.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/AddinError.cs
new file mode 100644
index 0000000000..466ef7e3ce
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/AddinError.cs
@@ -0,0 +1,66 @@
+//
+// IdeStartup.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2011 Xamarin Inc (http://xamarin.com)
+// Copyright (C) 2005-2011 Novell, Inc (http://www.novell.com)
+//
+// 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;
+
+namespace MonoDevelop.Ide
+{
+ public class AddinError
+ {
+ string addinFile;
+ Exception exception;
+ bool fatal;
+ string message;
+
+ public AddinError (string addin, string message, Exception exception, bool fatal)
+ {
+ this.addinFile = addin;
+ this.message = message;
+ this.exception = exception;
+ this.fatal = fatal;
+ }
+
+ public string AddinFile {
+ get { return addinFile; }
+ }
+
+ public string Message {
+ get { return message; }
+ }
+
+ public Exception Exception {
+ get { return exception; }
+ }
+
+ public bool Fatal {
+ get { return fatal; }
+ }
+ }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/DesktopService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/DesktopService.cs
index c44c8ddcc9..27fb9ebda6 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/DesktopService.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/DesktopService.cs
@@ -1,5 +1,5 @@
-//
-// DesktopService.cs
+//
+// IdeApp.DesktopService.cs
//
// Author:
// Lluis Sanchez Gual <lluis@novell.com>
@@ -32,17 +32,17 @@ using MonoDevelop.Core;
using System.IO;
using MonoDevelop.Components;
using MonoDevelop.Components.MainToolbar;
-using MonoDevelop.Ide.Fonts;
using System.Threading.Tasks;
namespace MonoDevelop.Ide
{
- public static class DesktopService
+ [DefaultServiceImplementation]
+ public class DesktopService : Service
{
- static PlatformService platformService;
- static Xwt.Toolkit nativeToolkit;
+ PlatformService platformService;
+ Xwt.Toolkit nativeToolkit;
- static PlatformService PlatformService {
+ PlatformService PlatformService {
get {
if (platformService == null)
throw new InvalidOperationException ("Not initialized");
@@ -50,18 +50,17 @@ namespace MonoDevelop.Ide
}
}
- public static void Initialize ()
+ protected override Task OnInitialize (ServiceProvider serviceProvider)
{
- if (platformService != null)
- return;
- object[] platforms = AddinManager.GetExtensionObjects ("/MonoDevelop/Core/PlatformService");
+ object [] platforms = AddinManager.GetExtensionObjects ("/MonoDevelop/Core/PlatformService");
if (platforms.Length > 0)
- platformService = (PlatformService) platforms [0];
+ platformService = (PlatformService)platforms [0];
else {
platformService = new DefaultPlatformService ();
LoggingService.LogFatalError ("A platform service implementation has not been found.");
}
PlatformService.Initialize ();
+
if (PlatformService.CanOpenTerminal)
Runtime.ProcessService.SetExternalConsoleHandler (PlatformService.StartConsoleProcess);
@@ -78,15 +77,29 @@ namespace MonoDevelop.Ide
ThermalMonitor = platformService.CreateThermalMonitor ();
ThermalMonitor.StatusChanged += OnThermalStatusChanged;
- FontService.Initialize ();
+ return Task.CompletedTask;
}
- static void OnMemoryStatusChanged (object sender, PlatformMemoryStatusEventArgs args)
+ protected override Task OnDispose ()
+ {
+ if (PlatformService.CanOpenTerminal)
+ Runtime.ProcessService.SetExternalConsoleHandler (null);
+
+ FileService.FileRemoved -= NotifyFileRemoved;
+ FileService.FileRenamed -= NotifyFileRenamed;
+
+ MemoryMonitor.StatusChanged -= OnMemoryStatusChanged;
+ ThermalMonitor.StatusChanged -= OnThermalStatusChanged;
+
+ return Task.CompletedTask;
+ }
+
+ void OnMemoryStatusChanged (object sender, PlatformMemoryStatusEventArgs args)
{
Counters.MemoryPressure.Inc (args.CounterMetadata);
}
- static void OnThermalStatusChanged (object sender, PlatformThermalStatusEventArgs args)
+ void OnThermalStatusChanged (object sender, PlatformThermalStatusEventArgs args)
{
Counters.ThermalNotification.Inc (args.CounterMetadata);
}
@@ -95,7 +108,7 @@ namespace MonoDevelop.Ide
/// Returns the XWT toolkit for the native toolkit (Cocoa on Mac, WPF on Windows)
/// </summary>
/// <returns>The native toolkit.</returns>
- public static Xwt.Toolkit NativeToolkit {
+ public Xwt.Toolkit NativeToolkit {
get {
if (nativeToolkit == null)
nativeToolkit = platformService.LoadNativeToolkit ();
@@ -103,63 +116,62 @@ namespace MonoDevelop.Ide
}
}
- public static void SetGlobalProgress (double progress)
+ public void SetGlobalProgress (double progress)
{
platformService.SetGlobalProgressBar (progress);
}
- public static void ShowGlobalProgressIndeterminate ()
+ public void ShowGlobalProgressIndeterminate ()
{
platformService.ShowGlobalProgressBarIndeterminate ();
}
- public static void ShowGlobalProgressError ()
+ public void ShowGlobalProgressError ()
{
platformService.ShowGlobalProgressBarError ();
}
- public static IEnumerable<DesktopApplication> GetApplications (string filename)
+ public IEnumerable<DesktopApplication> GetApplications (string filename)
{
return PlatformService.GetApplications (filename);
}
- [Obsolete ("Use FontService")]
- public static string DefaultMonospaceFont {
+ internal string DefaultMonospaceFont {
get { return PlatformService.DefaultMonospaceFont; }
}
- public static string PlatformName {
+ public string PlatformName {
get { return PlatformService.Name; }
}
[Obsolete]
- public static string DefaultControlLeftRightBehavior {
+ public string DefaultControlLeftRightBehavior {
get {
return PlatformService.DefaultControlLeftRightBehavior;
}
}
- public static void ShowUrl (string url)
+ public void ShowUrl (string url)
{
PlatformService.ShowUrl (url);
}
- public static void OpenFile (string filename)
+ public void OpenFile (string filename)
{
PlatformService.OpenFile (filename);
}
- public static void OpenFolder (FilePath folderPath, params FilePath[] selectFiles)
+ public void OpenFolder (FilePath folderPath, params FilePath [] selectFiles)
{
PlatformService.OpenFolder (folderPath, selectFiles);
}
- public static string GetMimeTypeForRoslynLanguage (string language)
+ public string GetMimeTypeForRoslynLanguage (string language)
{
return PlatformService.GetMimeTypeForRoslynLanguage (language);
}
- public static IEnumerable<string> GetMimeTypeInheritanceChainForRoslynLanguage (string language)
+ public IEnumerable<string> GetMimeTypeInheritanceChainForRoslynLanguage (string language)
{
var mime = GetMimeTypeForRoslynLanguage (language);
if (mime == null) {
@@ -168,22 +180,22 @@ namespace MonoDevelop.Ide
return GetMimeTypeInheritanceChain (mime);
}
- public static string GetMimeTypeForUri (string uri)
+ public string GetMimeTypeForUri (string uri)
{
return PlatformService.GetMimeTypeForUri (uri);
}
- public static string GetMimeTypeDescription (string mimeType)
+ public string GetMimeTypeDescription (string mimeType)
{
return PlatformService.GetMimeTypeDescription (mimeType);
}
- public static bool GetMimeTypeIsText (string mimeType)
+ public bool GetMimeTypeIsText (string mimeType)
{
return PlatformService.GetMimeTypeIsText (mimeType);
}
- public static bool GetFileIsText (string file, string mimeType = null)
+ public bool GetFileIsText (string file, string mimeType = null)
{
if (mimeType == null) {
mimeType = GetMimeTypeForUri (file);
@@ -198,7 +210,7 @@ namespace MonoDevelop.Ide
return !MonoDevelop.Core.Text.TextFileUtility.IsBinary (file);
}
- public async static Task<bool> GetFileIsTextAsync (string file, string mimeType = null)
+ public async Task<bool> GetFileIsTextAsync (string file, string mimeType = null)
{
if (mimeType == null) {
mimeType = GetMimeTypeForUri (file);
@@ -213,7 +225,7 @@ namespace MonoDevelop.Ide
return false;
using (var f = File.OpenRead (file)) {
- var buf = new byte[8192];
+ var buf = new byte [8192];
var read = f.Read (buf, 0, buf.Length);
for (int i = 0; i < read; i++)
if (buf [i] == 0)
@@ -223,42 +235,42 @@ namespace MonoDevelop.Ide
});
}
- public static bool GetMimeTypeIsSubtype (string subMimeType, string baseMimeType)
+ public bool GetMimeTypeIsSubtype (string subMimeType, string baseMimeType)
{
return PlatformService.GetMimeTypeIsSubtype (subMimeType, baseMimeType);
}
- public static IEnumerable<string> GetMimeTypeInheritanceChain (string mimeType)
+ public IEnumerable<string> GetMimeTypeInheritanceChain (string mimeType)
{
return PlatformService.GetMimeTypeInheritanceChain (mimeType);
}
- public static IEnumerable<string> GetMimeTypeInheritanceChainForFile (string filename)
+ public IEnumerable<string> GetMimeTypeInheritanceChainForFile (string filename)
{
return GetMimeTypeInheritanceChain (GetMimeTypeForUri (filename));
}
- public static Xwt.Drawing.Image GetIconForFile (string filename)
+ public Xwt.Drawing.Image GetIconForFile (string filename)
{
return PlatformService.GetIconForFile (filename);
}
- public static Xwt.Drawing.Image GetIconForFile (string filename, Gtk.IconSize size)
+ public Xwt.Drawing.Image GetIconForFile (string filename, Gtk.IconSize size)
{
return PlatformService.GetIconForFile (filename).WithSize (size);
}
- public static Xwt.Drawing.Image GetIconForType (string mimeType)
+ public Xwt.Drawing.Image GetIconForType (string mimeType)
{
return PlatformService.GetIconForType (mimeType);
}
- public static Xwt.Drawing.Image GetIconForType (string mimeType, Gtk.IconSize size)
+ public Xwt.Drawing.Image GetIconForType (string mimeType, Gtk.IconSize size)
{
return PlatformService.GetIconForType (mimeType).WithSize (size);
}
- internal static bool SetGlobalMenu (MonoDevelop.Components.Commands.CommandManager commandManager,
+ internal bool SetGlobalMenu (MonoDevelop.Components.Commands.CommandManager commandManager,
string commandMenuAddinPath, string appMenuAddinPath)
{
return PlatformService.SetGlobalMenu (commandManager, commandMenuAddinPath, appMenuAddinPath);
@@ -266,22 +278,22 @@ namespace MonoDevelop.Ide
// Used for preserve the file attributes when monodevelop opens & writes a file.
// This should work on unix & mac platform.
- public static object GetFileAttributes (string fileName)
+ public object GetFileAttributes (string fileName)
{
return PlatformService.GetFileAttributes (fileName);
}
- public static void SetFileAttributes (string fileName, object attributes)
+ public void SetFileAttributes (string fileName, object attributes)
{
PlatformService.SetFileAttributes (fileName, attributes);
}
- public static Xwt.Rectangle GetUsableMonitorGeometry (int screenNumber, int monitorNumber)
+ public Xwt.Rectangle GetUsableMonitorGeometry (int screenNumber, int monitorNumber)
{
return PlatformService.GetUsableMonitorGeometry (screenNumber, monitorNumber);
}
- public static bool CanOpenTerminal {
+ public bool CanOpenTerminal {
get {
return PlatformService.CanOpenTerminal;
}
@@ -293,7 +305,7 @@ namespace MonoDevelop.Ide
/// <param name="workingDirectory">Working directory.</param>
/// <param name="environmentVariables">Environment variables.</param>
/// <param name="windowTitle">Window title.</param>
- public static void OpenTerminal (
+ public void OpenTerminal (
FilePath workingDirectory,
IDictionary<string, string> environmentVariables = null,
string windowTitle = null)
@@ -301,13 +313,14 @@ namespace MonoDevelop.Ide
PlatformService.OpenTerminal (workingDirectory, environmentVariables, windowTitle);
}
- public static RecentFiles RecentFiles {
+ public RecentFiles RecentFiles {
get {
+ PlatformService.RecentFiles.DesktopService = this;
return PlatformService.RecentFiles;
}
}
- static void NotifyFileRemoved (object sender, FileEventArgs args)
+ void NotifyFileRemoved (object sender, FileEventArgs args)
{
foreach (FileEventInfo e in args) {
if (!e.IsDirectory) {
@@ -316,7 +329,7 @@ namespace MonoDevelop.Ide
}
}
- static void NotifyFileRenamed (object sender, FileCopyEventArgs args)
+ void NotifyFileRenamed (object sender, FileCopyEventArgs args)
{
if (args.IsExternal)
return;
@@ -328,17 +341,17 @@ namespace MonoDevelop.Ide
}
}
- internal static string GetUpdaterUrl ()
+ internal string GetUpdaterUrl ()
{
return PlatformService.GetUpdaterUrl ();
}
- internal static IEnumerable<string> GetUpdaterEnvironmentFlags ()
+ internal IEnumerable<string> GetUpdaterEnvironmentFlags ()
{
return PlatformService.GetUpdaterEnviromentFlags ();
}
- internal static void StartUpdatesInstaller (FilePath installerDataFile, FilePath updatedInstallerPath)
+ internal void StartUpdatesInstaller (FilePath installerDataFile, FilePath updatedInstallerPath)
{
PlatformService.StartUpdatesInstaller (installerDataFile, updatedInstallerPath);
}
@@ -346,65 +359,65 @@ namespace MonoDevelop.Ide
/// <summary>
/// Grab the desktop focus for the window.
/// </summary>
- internal static void GrabDesktopFocus (Gtk.Window window)
+ internal void GrabDesktopFocus (Gtk.Window window)
{
PlatformService.GrabDesktopFocus (window);
}
- public static void FocusWindow (Window window)
+ public void FocusWindow (Window window)
{
- if (window != null)
+ if (window != null)
PlatformService.FocusWindow (window);
}
- public static void RemoveWindowShadow (Window window)
+ public void RemoveWindowShadow (Window window)
{
PlatformService.RemoveWindowShadow (window);
}
- public static void SetMainWindowDecorations (Window window)
+ public void SetMainWindowDecorations (Window window)
{
PlatformService.SetMainWindowDecorations (window);
}
- internal static MainToolbarController CreateMainToolbar (Gtk.Window window)
+ internal MainToolbarController CreateMainToolbar (Gtk.Window window)
{
return new MainToolbarController (PlatformService.CreateMainToolbar (window));
}
- internal static void AttachMainToolbar (Gtk.VBox parent, MainToolbarController toolbar)
+ internal void AttachMainToolbar (Gtk.VBox parent, MainToolbarController toolbar)
{
PlatformService.AttachMainToolbar (parent, toolbar.ToolbarView);
toolbar.Initialize ();
}
- public static bool GetIsFullscreen (Window window)
+ public bool GetIsFullscreen (Window window)
{
return PlatformService.GetIsFullscreen (window);
}
- public static void SetIsFullscreen (Window window, bool isFullscreen)
+ public void SetIsFullscreen (Window window, bool isFullscreen)
{
PlatformService.SetIsFullscreen (window, isFullscreen);
}
- public static bool IsModalDialogRunning ()
+ public bool IsModalDialogRunning ()
{
return PlatformService.IsModalDialogRunning ();
}
- internal static void AddChildWindow (Gtk.Window parent, Gtk.Window child)
+ internal void AddChildWindow (Gtk.Window parent, Gtk.Window child)
{
PlatformService.AddChildWindow (parent, child);
}
- internal static void RemoveChildWindow (Gtk.Window parent, Gtk.Window child)
+ internal void RemoveChildWindow (Gtk.Window parent, Gtk.Window child)
{
PlatformService.RemoveChildWindow (parent, child);
}
- internal static void PlaceWindow (Gtk.Window window, int x, int y, int width, int height)
+ internal void PlaceWindow (Gtk.Window window, int x, int y, int width, int height)
{
PlatformService.PlaceWindow (window, x, y, width, height);
}
@@ -414,28 +427,36 @@ namespace MonoDevelop.Ide
/// </summary>
/// <returns> false if the user cancels exiting. </returns>
/// <param name="reopenWorkspace"> true to reopen current workspace. </param>
- internal static void RestartIde (bool reopenWorkspace)
+ internal void RestartIde (bool reopenWorkspace)
{
PlatformService.RestartIde (reopenWorkspace);
}
- public static bool AccessibilityInUse {
+ public bool AccessibilityInUse {
get {
return PlatformService.AccessibilityInUse;
}
}
- public static bool AccessibilityKeyboardFocusInUse {
+ public bool AccessibilityKeyboardFocusInUse {
get {
return PlatformService.AccessibilityKeyboardFocusInUse;
}
}
- internal static string GetNativeRuntimeDescription () => PlatformService.GetNativeRuntimeDescription ();
+ internal string GetNativeRuntimeDescription () => PlatformService.GetNativeRuntimeDescription ();
+
+ public ThermalMonitor ThermalMonitor { get; private set; }
+ public MemoryMonitor MemoryMonitor { get; private set; }
+
+ IPlatformTelemetryDetails platformTelemetryDetails;
- public static ThermalMonitor ThermalMonitor { get; private set; }
- public static MemoryMonitor MemoryMonitor { get; private set; }
- static readonly Lazy<IPlatformTelemetryDetails> platformTelemetryDetails = new Lazy<IPlatformTelemetryDetails> (() => PlatformService.CreatePlatformTelemetryDetails ());
- public static IPlatformTelemetryDetails PlatformTelemetry => platformTelemetryDetails.Value;
+ public IPlatformTelemetryDetails PlatformTelemetry {
+ get {
+ if (platformTelemetryDetails == null)
+ platformTelemetryDetails = PlatformService.CreatePlatformTelemetryDetails ();
+ return platformTelemetryDetails;
+ }
+ }
}
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs
index 8327ba0b14..4eaf87b1f9 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs
@@ -1,4 +1,4 @@
-//
+//
// IdeApp.cs
//
// Author:
@@ -38,19 +38,21 @@ using Mono.Addins.Setup;
using MonoDevelop.Components.Commands;
using MonoDevelop.Projects;
-using MonoDevelop.Ide.Gui.Pads;
using MonoDevelop.Ide.CustomTools;
using System.Linq;
using MonoDevelop.Ide.Gui;
-using MonoDevelop.Ide.Desktop;
using System.Collections.Generic;
using MonoDevelop.Components.AutoTest;
using MonoDevelop.Ide.TypeSystem;
using MonoDevelop.Ide.Extensions;
using MonoDevelop.Ide.Templates;
using System.Threading.Tasks;
-using MonoDevelop.Ide.RoslynServices.Options;
using MonoDevelop.Ide.RoslynServices;
+using MonoDevelop.Ide.Tasks;
+using MonoDevelop.Ide.TextEditing;
+using MonoDevelop.Ide.Navigation;
+using MonoDevelop.Ide.Fonts;
+using MonoDevelop.Ide.Composition;
namespace MonoDevelop.Ide
{
@@ -58,14 +60,10 @@ namespace MonoDevelop.Ide
{
static bool isInitialized;
static Workbench workbench;
- static ProjectOperations projectOperations;
static HelpOperations helpOperations;
static CommandManager commandService;
- static IdeServices ideServices;
- static RootWorkspace workspace;
- readonly static IdePreferences preferences;
+ static TypeSystemService typeSystemService;
- static bool isMainRunning;
static bool isInitialRun;
static bool isInitialRunAfterUpgrade;
static Version upgradedFromVersion;
@@ -131,23 +129,14 @@ namespace MonoDevelop.Ide
get { return CommandService.ApplicationHasFocus; }
}
- static IdeApp ()
- {
- preferences = new IdePreferences ();
- }
-
public static Workbench Workbench {
get { return workbench; }
}
-
- public static ProjectOperations ProjectOperations {
- get { return projectOperations; }
- }
-
- public static RootWorkspace Workspace {
- get { return workspace; }
- }
-
+
+ public static ProjectOperations ProjectOperations => IdeServices.ProjectOperations;
+
+ public static RootWorkspace Workspace => IdeServices.Workspace;
+
public static HelpOperations HelpOperations {
get { return helpOperations; }
}
@@ -155,12 +144,16 @@ namespace MonoDevelop.Ide
public static CommandManager CommandService {
get { return commandService; }
}
-
- public static IdeServices Services {
- get { return ideServices; }
+
+ public static TypeSystemService TypeSystemService {
+ get {
+ if (typeSystemService == null)
+ typeSystemService = Runtime.GetService<TypeSystemService> ().Result;
+ return typeSystemService;
+ }
}
- public static IdePreferences Preferences => preferences;
+ public static IdePreferences Preferences { get; } = new IdePreferences ();
public static bool IsInitialized {
get {
@@ -203,22 +196,30 @@ namespace MonoDevelop.Ide
}
}
- public static void Initialize (ProgressMonitor monitor) => Initialize (monitor, false);
-
- internal static void Initialize (ProgressMonitor monitor, bool hideWelcomePage)
+ public static async Task Initialize (ProgressMonitor monitor)
{
// Already done in IdeSetup, but called again since unit tests don't use IdeSetup.
DispatchService.Initialize ();
+ commandService = await Runtime.GetService<CommandManager> ();
+ await Runtime.GetService<DesktopService> ();
+ await Runtime.GetService<FontService> ();
+ await Runtime.GetService<TaskService> ();
+
Counters.Initialization.Trace ("Creating Workbench");
workbench = new Workbench ();
+
Counters.Initialization.Trace ("Creating Root Workspace");
- workspace = new RootWorkspace ();
+ await Runtime.GetService<RootWorkspace> ();
+
Counters.Initialization.Trace ("Creating Services");
- projectOperations = new ProjectOperations ();
+ await Runtime.GetService<ProjectOperations> ();
helpOperations = new HelpOperations ();
- commandService = new CommandManager ();
- ideServices = new IdeServices ();
+
+ await Runtime.GetService<TextEditorService> ();
+ await Runtime.GetService<NavigationHistoryService> ();
+ await Runtime.GetService<DisplayBindingService> ();
+
CustomToolService.Init ();
commandService.CommandTargetScanStarted += CommandServiceCommandTargetScanStarted;
@@ -246,7 +247,7 @@ namespace MonoDevelop.Ide
monitor.Step (1);
Counters.Initialization.Trace ("Initializing Workbench");
- workbench.Initialize (monitor);
+ await workbench.Initialize (monitor);
monitor.Step (1);
Counters.Initialization.Trace ("Initializing WelcomePage service");
@@ -263,13 +264,7 @@ namespace MonoDevelop.Ide
commandService.EnableIdleUpdate = true;
if (Customizer != null)
- Customizer.OnIdeInitialized (hideWelcomePage);
-
- // Startup commands
- Counters.Initialization.Trace ("Running Startup Commands");
- AddinManager.AddExtensionNodeHandler ("/MonoDevelop/Ide/StartupHandlers", OnExtensionChanged);
- monitor.Step (1);
- monitor.EndTask ();
+ Customizer.OnIdeInitialized ();
// Set initial run flags
Counters.Initialization.Trace ("Upgrading Settings");
@@ -290,16 +285,9 @@ namespace MonoDevelop.Ide
PropertyService.Set ("MonoDevelop.Core.LastRunVersion", Runtime.Version.ToString ());
PropertyService.SaveProperties ();
}
-
- // The ide is now initialized
- isInitialized = true;
-
- if (initializedEvent != null) {
- initializedEvent (null, EventArgs.Empty);
- initializedEvent = null;
- }
-
+ monitor.EndTask ();
+
//FIXME: we should really make this on-demand. consumers can display a "loading help cache" message like VS
MonoDevelop.Projects.HelpService.AsyncInitialize ();
@@ -311,6 +299,28 @@ namespace MonoDevelop.Ide
AutoTestService.NotifyEvent ("MonoDevelop.Ide.IdeStart");
Gtk.LinkButton.SetUriHook ((button, uri) => Xwt.Desktop.OpenUrl (uri));
+
+ // Start initializing the type system service in the background
+ Runtime.GetService<TypeSystemService> ().Ignore ();
+
+ // The ide is now initialized
+ OnInitialized ();
+ }
+
+ static void OnInitialized ()
+ {
+ // The ide is now initialized
+
+ isInitialized = true;
+
+ if (initializedEvent != null) {
+ initializedEvent (null, EventArgs.Empty);
+ initializedEvent = null;
+ }
+
+ // Startup commands
+ Counters.Initialization.Trace ("Running Startup Commands");
+ AddinManager.AddExtensionNodeHandler ("/MonoDevelop/Ide/StartupHandlers", OnExtensionChanged);
}
static void KeyBindingFailed (object sender, KeyBindingFailedEventArgs e)
@@ -334,6 +344,14 @@ namespace MonoDevelop.Ide
return false;
}
+ public static void BringToFront ()
+ {
+ Initialized += (sender, e) => {
+ if (!Ide.WelcomePage.WelcomePageService.HasWindowImplementation)
+ Workbench.Present ();
+ };
+ }
+
//this method is MIT/X11, 2009, Michael Hutchinson / (c) Novell
public static void OpenFiles (IEnumerable<FileOpenInformation> files)
{
@@ -427,16 +445,7 @@ namespace MonoDevelop.Ide
}
}
- public static void Run ()
- {
- // finally run the workbench window ...
- isMainRunning = true;
- Gtk.Application.Run ();
- }
-
- public static bool IsRunning {
- get { return isMainRunning; }
- }
+ public static bool IsRunning { get; internal set; }
public static bool IsExiting { get; private set; }
@@ -448,7 +457,6 @@ namespace MonoDevelop.Ide
IsExiting = true;
if (await workbench.Close ()) {
Gtk.Application.Quit ();
- isMainRunning = false;
return true;
}
IsExiting = false;
@@ -471,11 +479,11 @@ namespace MonoDevelop.Ide
PropertyService.Set ("MonoDevelop.Core.RestartRequested", true);
try {
- DesktopService.RestartIde (reopenWorkspace);
+ IdeServices.DesktopService.RestartIde (reopenWorkspace);
} catch (Exception ex) {
LoggingService.LogError ("Restarting IDE failed", ex);
}
- // return true here even if DesktopService.RestartIde has failed,
+ // return true here even if IdeServices.DesktopService.RestartIde has failed,
// because the Ide has already been closed.
return true;
}
@@ -542,7 +550,7 @@ namespace MonoDevelop.Ide
return;
// If a modal dialog is open, try again later
- if (DesktopService.IsModalDialogRunning ()) {
+ if (IdeServices.DesktopService.IsModalDialogRunning ()) {
DispatchIdleActions (1000);
return;
}
@@ -627,19 +635,4 @@ namespace MonoDevelop.Ide
}
}
}
-
- public class IdeServices
- {
- readonly Lazy<TemplatingService> templatingService = new Lazy<TemplatingService> (() => new TemplatingService ());
-
- public ProjectService ProjectService {
- get { return MonoDevelop.Projects.Services.ProjectService; }
- }
-
- public TemplatingService TemplatingService {
- get { return templatingService.Value; }
- }
-
- internal RoslynService RoslynService { get; } = new RoslynService ();
- }
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeInstanceConnection.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeInstanceConnection.cs
new file mode 100644
index 0000000000..8e476b33c9
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeInstanceConnection.cs
@@ -0,0 +1,141 @@
+//
+// IdeInstanceConnection.cs
+//
+// Author:
+// Lluis Sanchez <llsan@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;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using Mono.Unix;
+using MonoDevelop.Core;
+using MonoDevelop.Ide.Extensions;
+using MonoDevelop.Ide.Gui;
+
+namespace MonoDevelop.Ide
+{
+ class IdeInstanceConnection
+ {
+ const int ipcBasePort = 40000;
+
+ string socket_filename;
+ Socket listen_socket = null;
+ EndPoint ep;
+
+ public event EventHandler<FileEventArgs> FileOpenRequested;
+
+ public void Initialize (bool ipcTcp)
+ {
+ if (ipcTcp) {
+ listen_socket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
+ ep = new IPEndPoint (IPAddress.Loopback, ipcBasePort + HashSdbmBounded (Environment.UserName));
+ } else {
+ socket_filename = "/tmp/md-" + Environment.GetEnvironmentVariable ("USER") + "-socket";
+ listen_socket = new Socket (AddressFamily.Unix, SocketType.Stream, ProtocolType.IP);
+ ep = new UnixEndPoint (socket_filename);
+ }
+ }
+
+ public bool TryConnect (StartupInfo startupInfo)
+ {
+ try {
+ StringBuilder builder = new StringBuilder ();
+ foreach (var file in startupInfo.RequestedFileList) {
+ builder.AppendFormat ("{0};{1};{2}\n", file.FileName, file.Line, file.Column);
+ }
+ listen_socket.Connect (ep);
+ listen_socket.Send (Encoding.UTF8.GetBytes (builder.ToString ()));
+ return true;
+ } catch {
+ // Reset the socket
+ if (null != socket_filename && File.Exists (socket_filename))
+ File.Delete (socket_filename);
+ return false;
+ }
+ }
+
+ public void StartListening ()
+ {
+ // FIXME: we should probably track the last 'selected' one
+ // and do this more cleanly
+ try {
+ listen_socket.Bind (ep);
+ listen_socket.Listen (5);
+ listen_socket.BeginAccept (new AsyncCallback (ListenCallback), listen_socket);
+ } catch {
+ // Socket already in use
+ }
+ }
+
+ void ListenCallback (IAsyncResult state)
+ {
+ var files = new List<FilePath> ();
+
+ Socket sock = (Socket)state.AsyncState;
+
+ Socket client = sock.EndAccept (state);
+ ((Socket)state.AsyncState).BeginAccept (new AsyncCallback (ListenCallback), sock);
+ byte [] buf = new byte [1024];
+ client.Receive (buf);
+ foreach (string filename in Encoding.UTF8.GetString (buf).Split ('\n')) {
+ string trimmed = filename.Trim ();
+ string file = "";
+ foreach (char c in trimmed) {
+ if (c == 0x0000)
+ continue;
+ file += c;
+ }
+ files.Add (file);
+ }
+ if (files.Count > 0) {
+ GLib.Idle.Add (() => {
+ FileOpenRequested?.Invoke (this, new FileEventArgs (files, false));
+ return false;
+ });
+ }
+ }
+
+ public void Dispose ()
+ {
+ // unloading services
+ if (null != socket_filename)
+ File.Delete (socket_filename);
+ }
+
+ /// <summary>SDBM-style hash, bounded to a range of 1000.</summary>
+ static int HashSdbmBounded (string input)
+ {
+ ulong hash = 0;
+ for (int i = 0; i < input.Length; i++) {
+ unchecked {
+ hash = ((ulong)input [i]) + (hash << 6) + (hash << 16) - hash;
+ }
+ }
+
+ return (int)(hash % 1000);
+ }
+
+ }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdePreferences.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdePreferences.cs
index a83a27648a..aa19d3d248 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdePreferences.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdePreferences.cs
@@ -34,6 +34,7 @@ using MonoDevelop.Ide.Editor;
using MonoDevelop.Ide.Editor.Highlighting;
using System.Linq;
using MonoDevelop.Ide.RoslynServices.Options;
+using MonoDevelop.Ide.TypeSystem;
namespace MonoDevelop.Ide
{
@@ -67,12 +68,12 @@ namespace MonoDevelop.Ide
public class IdePreferences
{
- internal RoslynPreferences Roslyn { get; }
internal IdePreferences ()
{
- Roslyn = new RoslynPreferences ();
}
+ internal RoslynPreferences Roslyn => TypeSystemService.Preferences;
+
public readonly ConfigurationProperty<bool> EnableInstrumentation = Runtime.Preferences.EnableInstrumentation;
public readonly ConfigurationProperty<bool> EnableAutomatedTesting = Runtime.Preferences.EnableAutomatedTesting;
@@ -89,39 +90,14 @@ namespace MonoDevelop.Ide
public readonly ConfigurationProperty<bool> DefaultHideMessageBubbles = ConfigurationProperty.Create ("MonoDevelop.Ide.DefaultHideMessageBubbles", false);
public readonly ConfigurationProperty<ShowMessageBubbles> ShowMessageBubbles = ConfigurationProperty.Create ("MonoDevelop.Ide.NewShowMessageBubbles", MonoDevelop.Ide.ShowMessageBubbles.ForErrorsAndWarnings);
- public readonly ConfigurationProperty<TargetRuntime> DefaultTargetRuntime = new DefaultTargetRuntimeProperty ();
-
- class DefaultTargetRuntimeProperty: ConfigurationProperty<TargetRuntime>
- {
- ConfigurationProperty<string> defaultTargetRuntimeText = ConfigurationProperty.Create ("MonoDevelop.Ide.DefaultTargetRuntime", "__current");
-
- public DefaultTargetRuntimeProperty ()
- {
- defaultTargetRuntimeText.Changed += (s,e) => OnChanged ();
- }
-
- protected override TargetRuntime OnGetValue ()
- {
- string id = defaultTargetRuntimeText.Value;
- if (id == "__current")
- return Runtime.SystemAssemblyService.CurrentRuntime;
- TargetRuntime tr = Runtime.SystemAssemblyService.GetTargetRuntime (id);
- return tr ?? Runtime.SystemAssemblyService.CurrentRuntime;
- }
-
- protected override bool OnSetValue (TargetRuntime value)
- {
- defaultTargetRuntimeText.Value = value.IsRunning ? "__current" : value.Id;
- return true;
- }
- }
+ public ConfigurationProperty<TargetRuntime> DefaultTargetRuntime => RootWorkspace.DefaultTargetRuntime;
public readonly ConfigurationProperty<string> UserInterfaceLanguage = Runtime.Preferences.UserInterfaceLanguage;
public readonly ConfigurationProperty<string> UserInterfaceThemeName = ConfigurationProperty.Create ("MonoDevelop.Ide.UserInterfaceTheme", Platform.IsLinux ? "" : "Light");
public readonly ConfigurationProperty<WorkbenchCompactness> WorkbenchCompactness = ConfigurationProperty.Create ("MonoDevelop.Ide.WorkbenchCompactness", MonoDevelop.Ide.WorkbenchCompactness.Normal);
public readonly ConfigurationProperty<bool> LoadPrevSolutionOnStartup = ConfigurationProperty.Create ("SharpDevelop.LoadPrevProjectOnStartup", false);
public readonly ConfigurationProperty<bool> CreateFileBackupCopies = ConfigurationProperty.Create ("SharpDevelop.CreateBackupCopy", false);
- public readonly ConfigurationProperty<bool> LoadDocumentUserProperties = ConfigurationProperty.Create ("SharpDevelop.LoadDocumentProperties", true);
+ public ConfigurationProperty<bool> LoadDocumentUserProperties => IdeApp.Workbench.DocumentManager.Preferences.LoadDocumentUserProperties;
public readonly ConfigurationProperty<bool> EnableDocumentSwitchDialog = ConfigurationProperty.Create ("MonoDevelop.Core.Gui.EnableDocumentSwitchDialog", true);
public readonly ConfigurationProperty<bool> ShowTipsAtStartup = ConfigurationProperty.Create ("MonoDevelop.Core.Gui.Dialog.TipOfTheDayView.ShowTipsAtStartup", false);
@@ -130,12 +106,14 @@ namespace MonoDevelop.Ide
/// <summary>
/// Font to use for treeview pads. Returns null if no custom font is set.
/// </summary>
- public readonly ConfigurationProperty<Pango.FontDescription> CustomPadFont = FontService.GetFontProperty ("Pad");
+ public ConfigurationProperty<Pango.FontDescription> CustomPadFont => customPadFont.Value;
+ readonly Lazy<ConfigurationProperty<Pango.FontDescription>> customPadFont = new Lazy<ConfigurationProperty<Pango.FontDescription>> (() => IdeApp.FontService.GetFontProperty ("Pad"));
/// <summary>
/// Font to use for output pads. Returns null if no custom font is set.
/// </summary>
- public readonly ConfigurationProperty<Pango.FontDescription> CustomOutputPadFont = FontService.GetFontProperty ("OutputPad");
+ public ConfigurationProperty<Pango.FontDescription> CustomOutputPadFont => customOutputPadFont.Value;
+ readonly Lazy<ConfigurationProperty<Pango.FontDescription>> customOutputPadFont = new Lazy<ConfigurationProperty<Pango.FontDescription>> (() => IdeApp.FontService.GetFontProperty ("OutputPad"));
public readonly ConfigurationProperty<bool> EnableCompletionCategoryMode = ConfigurationProperty.Create ("EnableCompletionCategoryMode", false);
public readonly ConfigurationProperty<bool> ForceSuggestionMode = ConfigurationProperty.Create ("ForceCompletionSuggestionMode", false);
@@ -158,7 +136,7 @@ namespace MonoDevelop.Ide
internal static readonly string DefaultLightColorScheme = "Light";
internal static readonly string DefaultDarkColorScheme = "Dark";
- public readonly ConfigurationProperty<bool> EnableSourceAnalysis = ConfigurationProperty.Create ("MonoDevelop.AnalysisCore.AnalysisEnabled_V2", true);
+ public ConfigurationProperty<bool> EnableSourceAnalysis => TypeSystemService.EnableSourceAnalysis;
public readonly ConfigurationProperty<bool> EnableUnitTestEditorIntegration = ConfigurationProperty.Create ("Testing.EnableUnitTestEditorIntegration", false);
public readonly SchemeConfigurationProperty ColorScheme = new SchemeConfigurationProperty ("ColorScheme", DefaultLightColorScheme, DefaultDarkColorScheme);
@@ -231,7 +209,32 @@ namespace MonoDevelop.Ide
}
}
}
-
+
+ class DefaultTargetRuntimeProperty : ConfigurationProperty<TargetRuntime>
+ {
+ ConfigurationProperty<string> defaultTargetRuntimeText = ConfigurationProperty.Create ("MonoDevelop.Ide.DefaultTargetRuntime", "__current");
+
+ public DefaultTargetRuntimeProperty ()
+ {
+ defaultTargetRuntimeText.Changed += (s, e) => OnChanged ();
+ }
+
+ protected override TargetRuntime OnGetValue ()
+ {
+ string id = defaultTargetRuntimeText.Value;
+ if (id == "__current")
+ return Runtime.SystemAssemblyService.CurrentRuntime;
+ TargetRuntime tr = Runtime.SystemAssemblyService.GetTargetRuntime (id);
+ return tr ?? Runtime.SystemAssemblyService.CurrentRuntime;
+ }
+
+ protected override bool OnSetValue (TargetRuntime value)
+ {
+ defaultTargetRuntimeText.Value = value.IsRunning ? "__current" : value.Id;
+ return true;
+ }
+ }
+
public enum BeforeCompileAction {
Nothing,
SaveAllFiles,
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeServices.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeServices.cs
new file mode 100644
index 0000000000..a6db7a3067
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeServices.cs
@@ -0,0 +1,113 @@
+//
+// IdeApp.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
+//
+// 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 MonoDevelop.Core;
+
+using MonoDevelop.Projects;
+using MonoDevelop.Ide.Gui;
+using MonoDevelop.Ide.Templates;
+using System.Threading.Tasks;
+using MonoDevelop.Ide.RoslynServices;
+using MonoDevelop.Ide.Tasks;
+using MonoDevelop.Ide.TextEditing;
+using MonoDevelop.Ide.Navigation;
+using MonoDevelop.Ide.Fonts;
+using MonoDevelop.Ide.TypeSystem;
+using MonoDevelop.Ide.Gui.Documents;
+
+namespace MonoDevelop.Ide
+{
+ public static class IdeServices
+ {
+ static TextEditorService textEditorService;
+ static NavigationHistoryService navigationHistoryManager;
+ static DisplayBindingService displayBindingService;
+ static FontService fontService;
+ static TypeSystemService typeSystemService;
+ static DesktopService desktopService;
+ static DocumentManager documentManager;
+ static RootWorkspace workspace;
+ static ProgressMonitorManager progressMonitorManager;
+ static TaskService taskService;
+ static ProjectOperations projectOperations;
+
+ static IdeServices ()
+ {
+ Runtime.ServiceProvider.WhenServiceInitialized<TextEditorService> (s => textEditorService = s);
+ Runtime.ServiceProvider.WhenServiceInitialized<NavigationHistoryService> (s => navigationHistoryManager = s);
+ Runtime.ServiceProvider.WhenServiceInitialized<DisplayBindingService> (s => displayBindingService = s);
+ Runtime.ServiceProvider.WhenServiceInitialized<FontService> (s => fontService = s);
+ Runtime.ServiceProvider.WhenServiceInitialized<TypeSystemService> (s => typeSystemService = s);
+ Runtime.ServiceProvider.WhenServiceInitialized<DesktopService> (s => desktopService = s);
+ Runtime.ServiceProvider.WhenServiceInitialized<DocumentManager> (s => documentManager = s);
+ Runtime.ServiceProvider.WhenServiceInitialized<RootWorkspace> (s => workspace = s);
+ Runtime.ServiceProvider.WhenServiceInitialized<ProgressMonitorManager> (s => progressMonitorManager = s);
+ Runtime.ServiceProvider.WhenServiceInitialized<TaskService> (s => taskService = s);
+ Runtime.ServiceProvider.WhenServiceInitialized<ProjectOperations> (s => projectOperations = s);
+ }
+
+ public static TextEditorService TextEditorService => Initialized (textEditorService);
+
+ public static NavigationHistoryService NavigationHistoryService => Initialized (navigationHistoryManager);
+
+ public static DisplayBindingService DisplayBindingService => Initialized (displayBindingService);
+
+ public static FontService FontService => Initialized (fontService);
+
+ public static TypeSystemService TypeSystemService => Initialized (typeSystemService);
+
+ public static DesktopService DesktopService => Initialized (desktopService);
+
+ public static RootWorkspace Workspace => Initialized (workspace);
+
+ public static ProgressMonitorManager ProgressMonitorManager => Initialized (progressMonitorManager);
+
+ static Lazy<TemplatingService> templatingService = new Lazy<TemplatingService> (() => new TemplatingService ());
+
+ public static ProjectService ProjectService => MonoDevelop.Projects.Services.ProjectService;
+
+ public static TemplatingService TemplatingService => templatingService.Value;
+
+ public static DocumentManager DocumentManager => Initialized (documentManager);
+
+ public static TaskService TaskService => Initialized (taskService);
+
+ public static ProjectOperations ProjectOperations => Initialized (projectOperations);
+
+ static T Initialized<T> (T s) where T : class
+ {
+ if (s == null)
+ throw new InvalidOperationException ("Service " + typeof (T) + " not initialized");
+ return s;
+ }
+ }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeStartup.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeStartup.cs
index 0b8064d536..f02398a7d7 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeStartup.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeStartup.cs
@@ -1,4 +1,4 @@
-//
+//
// IdeStartup.cs
//
// Author:
@@ -30,20 +30,13 @@
using System;
using System.IO;
-using System.Collections;
using System.Reflection;
using System.Threading;
-using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Linq;
-using Microsoft.CodeAnalysis.Utilities;
-using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
-
-using Mono.Unix;
-
using Mono.Addins;
using MonoDevelop.Components.Commands;
using MonoDevelop.Core;
@@ -58,15 +51,17 @@ using MonoDevelop.Components.Extensions;
using MonoDevelop.Ide.Desktop;
using System.Threading.Tasks;
using MonoDevelop.Components;
+using MonoDevelop.Ide.Gui.Shell;
+using MonoDevelop.Ide.Composition;
namespace MonoDevelop.Ide
{
public class IdeStartup: IApplication
{
- Socket listen_socket = null;
+ static IdeInstanceConnection instanceConnection;
+
List<AddinError> errorsList = new List<AddinError> ();
bool initialized;
- static readonly int ipcBasePort = 40000;
static Stopwatch startupTimer = new Stopwatch ();
static Stopwatch startupSectionTimer = new Stopwatch ();
static Stopwatch timeToCodeTimer = new Stopwatch ();
@@ -82,7 +77,7 @@ namespace MonoDevelop.Ide
return Task.FromResult (options.Error != null? -1 : 0);
return Task.FromResult (Run (options));
}
-
+
int Run (MonoDevelopOptions options)
{
LoggingService.LogInfo ("Starting {0} {1}", BrandingService.ApplicationLongName, IdeVersionInfo.MonoDevelopVersion);
@@ -100,13 +95,11 @@ namespace MonoDevelop.Ide
LoggingService.LogInfo ("Operating System: {0}", SystemInformation.GetOperatingSystemDescription ());
- if (!Platform.IsWindows) {
- // The assembly resolver for MSBuild 15 assemblies needs to be defined early on.
- // Whilst Runtime.Initialize loads the MSBuild 15 assemblies from Mono this seems
- // to be too late to prevent the MEF composition and the static registrar from
- // failing to load the MonoDevelop.Ide assembly which now uses MSBuild 15 assemblies.
- ResolveMSBuildAssemblies ();
- }
+ // The assembly resolver for MSBuild 15 assemblies needs to be defined early on.
+ // Whilst Runtime.Initialize loads the MSBuild 15 assemblies from Mono this seems
+ // to be too late to prevent the MEF composition and the static registrar from
+ // failing to load the MonoDevelop.Ide assembly which now uses MSBuild 15 assemblies.
+ ResolveMSBuildAssemblies ();
Counters.Initialization.BeginTiming ();
@@ -124,9 +117,15 @@ namespace MonoDevelop.Ide
// explicit GLib type system initialization for GLib < 2.36 before any other type system access
GLib.GType.Init ();
+ var args = options.RemainingArgs.ToArray ();
+
+ IdeTheme.InitializeGtk (BrandingService.ApplicationName, ref args);
+
+ var startupInfo = new StartupInfo (options, args);
+
IdeApp.Customizer = options.IdeCustomizer ?? new IdeCustomizer ();
try {
- IdeApp.Customizer.Initialize ();
+ IdeApp.Customizer.Initialize (startupInfo);
} catch (UnauthorizedAccessException ua) {
LoggingService.LogError ("Unauthorized access: " + ua.Message);
return 1;
@@ -138,22 +137,19 @@ namespace MonoDevelop.Ide
LoggingService.LogError ("Error initialising GLib logging.", ex);
}
- var args = options.RemainingArgs.ToArray ();
- IdeTheme.InitializeGtk (BrandingService.ApplicationName, ref args);
-
- sectionTimings["GtkInitialization"] = startupSectionTimer.ElapsedMilliseconds;
+ sectionTimings ["GtkInitialization"] = startupSectionTimer.ElapsedMilliseconds;
startupSectionTimer.Restart ();
LoggingService.LogInfo ("Using GTK+ {0}", IdeVersionInfo.GetGtkVersion ());
// XWT initialization
- FilePath p = typeof(IdeStartup).Assembly.Location;
- Runtime.LoadAssemblyFrom (p.ParentDirectory.Combine("Xwt.Gtk.dll"));
+ FilePath p = typeof (IdeStartup).Assembly.Location;
+ Runtime.LoadAssemblyFrom (p.ParentDirectory.Combine ("Xwt.Gtk.dll"));
Xwt.Application.InitializeAsGuest (Xwt.ToolkitType.Gtk);
- Xwt.Toolkit.CurrentEngine.RegisterBackend<IExtendedTitleBarWindowBackend,GtkExtendedTitleBarWindowBackend> ();
- Xwt.Toolkit.CurrentEngine.RegisterBackend<IExtendedTitleBarDialogBackend,GtkExtendedTitleBarDialogBackend> ();
+ Xwt.Toolkit.CurrentEngine.RegisterBackend<IExtendedTitleBarWindowBackend, GtkExtendedTitleBarWindowBackend> ();
+ Xwt.Toolkit.CurrentEngine.RegisterBackend<IExtendedTitleBarDialogBackend, GtkExtendedTitleBarDialogBackend> ();
IdeTheme.SetupXwtTheme ();
- sectionTimings["XwtInitialization"] = startupSectionTimer.ElapsedMilliseconds;
+ sectionTimings ["XwtInitialization"] = startupSectionTimer.ElapsedMilliseconds;
startupSectionTimer.Restart ();
//default to Windows IME on Windows
@@ -163,34 +159,34 @@ namespace MonoDevelop.Ide
if (string.IsNullOrEmpty (val.Val as string))
GtkWorkarounds.SetProperty (settings, "gtk-im-module", new GLib.Value ("ime"));
}
-
- string socket_filename = null;
- EndPoint ep = null;
-
+
DispatchService.Initialize ();
// Set a synchronization context for the main gtk thread
SynchronizationContext.SetSynchronizationContext (DispatchService.SynchronizationContext);
Runtime.MainSynchronizationContext = SynchronizationContext.Current;
- sectionTimings["DispatchInitialization"] = startupSectionTimer.ElapsedMilliseconds;
+ sectionTimings ["DispatchInitialization"] = startupSectionTimer.ElapsedMilliseconds;
startupSectionTimer.Restart ();
// Initialize Roslyn's synchronization context
RoslynServices.RoslynService.Initialize ();
- sectionTimings["RoslynInitialization"] = startupSectionTimer.ElapsedMilliseconds;
+ sectionTimings ["RoslynInitialization"] = startupSectionTimer.ElapsedMilliseconds;
startupSectionTimer.Restart ();
AddinManager.AddinLoadError += OnAddinError;
- var startupInfo = new StartupInfo (args);
+ Counters.Initialization.Trace ("Initializing Runtime");
+ Runtime.Initialize (true);
+
+ // Register services used by the IDE
+
+ RegisterServices ();
// If a combine was specified, force --newwindow.
if (!options.NewWindow && startupInfo.HasFiles) {
- Counters.Initialization.Trace ("Pre-Initializing Runtime to load files in existing window");
- Runtime.Initialize (true);
foreach (var file in startupInfo.RequestedFileList) {
if (MonoDevelop.Projects.Services.ProjectService.IsWorkspaceItemFile (file.FileName)) {
options.NewWindow = true;
@@ -198,9 +194,13 @@ namespace MonoDevelop.Ide
}
}
}
-
- Counters.Initialization.Trace ("Initializing Runtime");
- Runtime.Initialize (true);
+
+ instanceConnection = new IdeInstanceConnection ();
+ instanceConnection.Initialize (options.IpcTcp);
+
+ // If not opening a combine, connect to existing monodevelop and pass filename(s) and exit
+ if (!options.NewWindow && startupInfo.HasFiles && instanceConnection.TryConnect (startupInfo))
+ return 0;
sectionTimings ["RuntimeInitialization"] = startupSectionTimer.ElapsedMilliseconds;
startupSectionTimer.Restart ();
@@ -209,54 +209,56 @@ namespace MonoDevelop.Ide
startupInfo.Restarted = restartRequested;
PropertyService.Set ("MonoDevelop.Core.RestartRequested", false);
- IdeApp.Customizer.OnCoreInitialized ();
-
Counters.Initialization.Trace ("Initializing theme");
IdeTheme.SetupGtkTheme ();
- sectionTimings["ThemeInitialized"] = startupSectionTimer.ElapsedMilliseconds;
+ IdeApp.Customizer.OnCoreInitialized ();
+
+ sectionTimings ["ThemeInitialized"] = startupSectionTimer.ElapsedMilliseconds;
startupSectionTimer.Restart ();
+ IdeApp.IsRunning = true;
+
+ // Run the main loop
+ Gtk.Application.Invoke ((s, e) => {
+ MainLoop (options, startupInfo).Ignore ();
+ });
+ Gtk.Application.Run ();
+
+ IdeApp.IsRunning = false;
+
+ IdeApp.Customizer.OnIdeShutdown ();
+
+ instanceConnection.Dispose ();
+
+ lockupCheckRunning = false;
+ Runtime.Shutdown ();
+
+ IdeApp.Customizer.OnCoreShutdown ();
+
+ InstrumentationService.Stop ();
+
+ MonoDevelop.Components.GtkWorkarounds.Terminate ();
+
+ return 0;
+ }
+
+ async Task<int> MainLoop (MonoDevelopOptions options, StartupInfo startupInfo)
+ {
ProgressMonitor monitor = new MonoDevelop.Core.ProgressMonitoring.ConsoleProgressMonitor ();
monitor.BeginTask (GettextCatalog.GetString ("Starting {0}", BrandingService.ApplicationName), 2);
//make sure that the platform service is initialised so that the Mac platform can subscribe to open-document events
Counters.Initialization.Trace ("Initializing Platform Service");
- DesktopService.Initialize ();
+ await Runtime.GetService<DesktopService> ();
sectionTimings["PlatformInitialization"] = startupSectionTimer.ElapsedMilliseconds;
startupSectionTimer.Restart ();
monitor.Step (1);
- if (options.IpcTcp) {
- listen_socket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
- ep = new IPEndPoint (IPAddress.Loopback, ipcBasePort + HashSdbmBounded (Environment.UserName));
- } else {
- socket_filename = "/tmp/md-" + Environment.GetEnvironmentVariable ("USER") + "-socket";
- listen_socket = new Socket (AddressFamily.Unix, SocketType.Stream, ProtocolType.IP);
- ep = new UnixEndPoint (socket_filename);
- }
-
- // If not opening a combine, connect to existing monodevelop and pass filename(s) and exit
- if (!options.NewWindow && startupInfo.HasFiles) {
- try {
- StringBuilder builder = new StringBuilder ();
- foreach (var file in startupInfo.RequestedFileList) {
- builder.AppendFormat ("{0};{1};{2}\n", file.FileName, file.Line, file.Column);
- }
- listen_socket.Connect (ep);
- listen_socket.Send (Encoding.UTF8.GetBytes (builder.ToString ()));
- return 0;
- } catch {
- // Reset the socket
- if (null != socket_filename && File.Exists (socket_filename))
- File.Delete (socket_filename);
- }
- }
-
Counters.Initialization.Trace ("Checking System");
CheckFileWatcher ();
@@ -281,7 +283,7 @@ namespace MonoDevelop.Ide
Counters.Initialization.Trace ("Initializing IdeApp");
hideWelcomePage = startupInfo.HasFiles;
- IdeApp.Initialize (monitor, hideWelcomePage);
+ await IdeApp.Initialize (monitor);
sectionTimings ["AppInitialization"] = startupSectionTimer.ElapsedMilliseconds;
startupSectionTimer.Restart ();
@@ -302,10 +304,10 @@ namespace MonoDevelop.Ide
// load previous combine
RecentFile openedProject = null;
if (IdeApp.Preferences.LoadPrevSolutionOnStartup && !startupInfo.HasSolutionFile && !IdeApp.Workspace.WorkspaceItemIsOpening && !IdeApp.Workspace.IsOpen) {
- openedProject = DesktopService.RecentFiles.MostRecentlyUsedProject;
+ openedProject = IdeServices.DesktopService.RecentFiles.MostRecentlyUsedProject;
if (openedProject != null) {
var metadata = GetOpenWorkspaceOnStartupMetadata ();
- IdeApp.Workspace.OpenWorkspaceItem (openedProject.FileName, true, true, metadata).ContinueWith (t => IdeApp.OpenFiles (startupInfo.RequestedFileList, metadata), TaskScheduler.FromCurrentSynchronizationContext ());
+ IdeApp.Workspace.OpenWorkspaceItem (openedProject.FileName, true, true, metadata).ContinueWith (t => IdeApp.OpenFiles (startupInfo.RequestedFileList, metadata), TaskScheduler.FromCurrentSynchronizationContext ()).Ignore();
startupInfo.OpenedRecentProject = true;
}
}
@@ -341,15 +343,12 @@ namespace MonoDevelop.Ide
sectionTimings["BasicInitializationCompleted"] = startupSectionTimer.ElapsedMilliseconds;
startupSectionTimer.Restart ();
- // FIXME: we should probably track the last 'selected' one
- // and do this more cleanly
- try {
- listen_socket.Bind (ep);
- listen_socket.Listen (5);
- listen_socket.BeginAccept (new AsyncCallback (ListenCallback), listen_socket);
- } catch {
- // Socket already in use
- }
+ instanceConnection.FileOpenRequested += (sender, a) => {
+ foreach (var e in a)
+ OpenFile (e.FileName);
+ };
+
+ instanceConnection.StartListening ();
sectionTimings["SocketInitialization"] = startupSectionTimer.ElapsedMilliseconds;
startupSectionTimer.Restart ();
@@ -392,25 +391,16 @@ namespace MonoDevelop.Ide
CreateStartupMetadata (startupInfo, sectionTimings);
GLib.Idle.Add (OnIdle);
- IdeApp.Run ();
-
- IdeApp.Customizer.OnIdeShutdown ();
-
- // unloading services
- if (null != socket_filename)
- File.Delete (socket_filename);
- lockupCheckRunning = false;
- Runtime.Shutdown ();
- IdeApp.Customizer.OnCoreShutdown ();
-
- InstrumentationService.Stop ();
-
- MonoDevelop.Components.GtkWorkarounds.Terminate ();
-
return 0;
}
+ void RegisterServices ()
+ {
+ Runtime.RegisterServiceType<ProgressMonitorManager, IdeProgressMonitorManager> ();
+ Runtime.RegisterServiceType<IShell, DefaultWorkbench> ();
+ }
+
void FMOpenTimerExpired ()
{
IdeApp.Workspace.FirstWorkspaceItemOpened -= CompleteSolutionTimeToCode;
@@ -427,6 +417,9 @@ namespace MonoDevelop.Ide
/// </summary>
void ResolveMSBuildAssemblies ()
{
+ if (Platform.IsWindows)
+ return;
+
var currentRuntime = MonoRuntimeInfo.FromCurrentRuntime ();
if (currentRuntime != null) {
msbuildBinDir = Path.Combine (currentRuntime.Prefix, "lib", "mono", "msbuild", "15.0", "bin");
@@ -462,7 +455,8 @@ namespace MonoDevelop.Ide
static bool OnIdle ()
{
- Composition.CompositionManager.InitializeAsync ().Ignore ();
+ // Make sure the composition manager started initializing
+ Runtime.GetService<CompositionManager> ();
// OpenDocuments appears when the app is idle.
if (!hideWelcomePage && !WelcomePage.WelcomePageService.HasWindowImplementation) {
@@ -476,7 +470,7 @@ namespace MonoDevelop.Ide
void CreateStartupMetadata (StartupInfo startupInfo, Dictionary<string, long> timings)
{
- var result = DesktopService.PlatformTelemetry;
+ var result = IdeServices.DesktopService.PlatformTelemetry;
if (result == null) {
return;
}
@@ -647,26 +641,6 @@ namespace MonoDevelop.Ide
if (errorsList != null)
errorsList.Add (new AddinError (args.AddinId, args.Message, args.Exception, false));
}
-
- void ListenCallback (IAsyncResult state)
- {
- Socket sock = (Socket)state.AsyncState;
-
- Socket client = sock.EndAccept (state);
- ((Socket)state.AsyncState).BeginAccept (new AsyncCallback (ListenCallback), sock);
- byte[] buf = new byte[1024];
- client.Receive (buf);
- foreach (string filename in Encoding.UTF8.GetString (buf).Split ('\n')) {
- string trimmed = filename.Trim ();
- string file = "";
- foreach (char c in trimmed) {
- if (c == 0x0000)
- continue;
- file += c;
- }
- GLib.Idle.Add (() => OpenFile (file));
- }
- }
static bool OpenFile (string file)
{
@@ -739,7 +713,7 @@ namespace MonoDevelop.Ide
return false;
}
if (res == info)
- DesktopService.ShowUrl ("https://bugzilla.xamarin.com/show_bug.cgi?id=21755");
+ IdeServices.DesktopService.ShowUrl ("https://bugzilla.xamarin.com/show_bug.cgi?id=21755");
if (res == cont) {
bool exists = Directory.Exists ("/Library/Contextual Menu Items/SCFinderPlugin.plugin");
LoggingService.LogInternalError ("SCPlugin detected", new Exception ("SCPlugin detected. Continuing " + (exists ? "Installed." : "Uninstalled.")));
@@ -791,19 +765,6 @@ namespace MonoDevelop.Ide
}
}
- /// <summary>SDBM-style hash, bounded to a range of 1000.</summary>
- static int HashSdbmBounded (string input)
- {
- ulong hash = 0;
- for (int i = 0; i < input.Length; i++) {
- unchecked {
- hash = ((ulong)input[i]) + (hash << 6) + (hash << 16) - hash;
- }
- }
-
- return (int)(hash % 1000);
- }
-
public static int Main (string[] args, IdeCustomizer customizer = null)
{
// Using a Stopwatch instead of a TimerCounter since calling
@@ -931,95 +892,4 @@ namespace MonoDevelop.Ide
return metadata;
}
}
-
- public class MonoDevelopOptions
- {
- MonoDevelopOptions ()
- {
- IpcTcp = (PlatformID.Unix != Environment.OSVersion.Platform);
- RedirectOutput = true;
- }
-
- Mono.Options.OptionSet GetOptionSet ()
- {
- return new Mono.Options.OptionSet {
- { "no-splash", "Do not display splash screen (deprecated).", s => {} },
- { "ipc-tcp", "Use the Tcp channel for inter-process communication.", s => IpcTcp = true },
- { "new-window", "Do not open in an existing instance of " + BrandingService.ApplicationName, s => NewWindow = true },
- { "h|?|help", "Show help", s => ShowHelp = true },
- { "perf-log", "Enable performance counter logging", s => PerfLog = true },
- { "no-redirect", "Disable redirection of stdout/stderr to a log file", s => RedirectOutput = false },
- };
- }
-
- public static MonoDevelopOptions Parse (string[] args)
- {
- var opt = new MonoDevelopOptions ();
- var optSet = opt.GetOptionSet ();
-
- try {
- opt.RemainingArgs = optSet.Parse (args);
- } catch (Mono.Options.OptionException ex) {
- opt.Error = ex.ToString ();
- }
-
- if (opt.Error != null) {
- Console.WriteLine ("ERROR: {0}", opt.Error);
- Console.WriteLine ("Pass --help for usage information.");
- }
-
- if (opt.ShowHelp) {
- Console.WriteLine (BrandingService.ApplicationName + " " + BuildInfo.VersionLabel);
- Console.WriteLine ("Options:");
- optSet.WriteOptionDescriptions (Console.Out);
- const string openFileText = " file.ext;line;column";
- Console.Write (openFileText);
- Console.Write (new string (' ', 29 - openFileText.Length));
- Console.WriteLine ("Opens a file at specified integer line and column");
- }
-
- return opt;
- }
-
- public bool IpcTcp { get; set; }
- public bool NewWindow { get; set; }
- public bool ShowHelp { get; set; }
- public bool PerfLog { get; set; }
- public bool RedirectOutput { get; set; }
- public string Error { get; set; }
- public IList<string> RemainingArgs { get; set; }
- public IdeCustomizer IdeCustomizer { get; set; }
- }
-
- public class AddinError
- {
- string addinFile;
- Exception exception;
- bool fatal;
- string message;
-
- public AddinError (string addin, string message, Exception exception, bool fatal)
- {
- this.addinFile = addin;
- this.message = message;
- this.exception = exception;
- this.fatal = fatal;
- }
-
- public string AddinFile {
- get { return addinFile; }
- }
-
- public string Message {
- get { return message; }
- }
-
- public Exception Exception {
- get { return exception; }
- }
-
- public bool Fatal {
- get { return fatal; }
- }
- }
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/MonoDevelopOptions.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/MonoDevelopOptions.cs
new file mode 100644
index 0000000000..b3a54c6ba4
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/MonoDevelopOptions.cs
@@ -0,0 +1,96 @@
+//
+// IdeStartup.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2011 Xamarin Inc (http://xamarin.com)
+// Copyright (C) 2005-2011 Novell, Inc (http://www.novell.com)
+//
+// 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 MonoDevelop.Core;
+using MonoDevelop.Ide.Gui;
+using System.Collections.Generic;
+using MonoDevelop.Ide.Extensions;
+
+namespace MonoDevelop.Ide
+{
+ public class MonoDevelopOptions
+ {
+ MonoDevelopOptions ()
+ {
+ IpcTcp = (PlatformID.Unix != Environment.OSVersion.Platform);
+ RedirectOutput = true;
+ }
+
+ Mono.Options.OptionSet GetOptionSet ()
+ {
+ return new Mono.Options.OptionSet {
+ { "ipc-tcp", "Use the Tcp channel for inter-process communication.", s => IpcTcp = true },
+ { "new-window", "Do not open in an existing instance of " + BrandingService.ApplicationName, s => NewWindow = true },
+ { "h|?|help", "Show help", s => ShowHelp = true },
+ { "perf-log", "Enable performance counter logging", s => PerfLog = true },
+ { "no-redirect", "Disable redirection of stdout/stderr to a log file", s => RedirectOutput = false },
+ };
+ }
+
+ public static MonoDevelopOptions Parse (string [] args)
+ {
+ var opt = new MonoDevelopOptions ();
+ var optSet = opt.GetOptionSet ();
+
+ try {
+ opt.RemainingArgs = optSet.Parse (args);
+ } catch (Mono.Options.OptionException ex) {
+ opt.Error = ex.ToString ();
+ }
+
+ if (opt.Error != null) {
+ Console.WriteLine ("ERROR: {0}", opt.Error);
+ Console.WriteLine ("Pass --help for usage information.");
+ }
+
+ if (opt.ShowHelp) {
+ Console.WriteLine (BrandingService.ApplicationName + " " + BuildInfo.VersionLabel);
+ Console.WriteLine ("Options:");
+ optSet.WriteOptionDescriptions (Console.Out);
+ const string openFileText = " file.ext;line;column";
+ Console.Write (openFileText);
+ Console.Write (new string (' ', 29 - openFileText.Length));
+ Console.WriteLine ("Opens a file at specified integer line and column");
+ }
+
+ return opt;
+ }
+
+ public bool IpcTcp { get; set; }
+ public bool NewWindow { get; set; }
+ public bool ShowHelp { get; set; }
+ public bool PerfLog { get; set; }
+ public bool RedirectOutput { get; set; }
+ public string Error { get; set; }
+ public IList<string> RemainingArgs { get; set; }
+ public IdeCustomizer IdeCustomizer { get; set; }
+ }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs
index a95c85d240..e20d881b26 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs
@@ -1,4 +1,4 @@
-//
+//
// ProjectOperations.cs
//
// Author:
@@ -48,14 +48,18 @@ using MonoDevelop.Ide.TypeSystem;
using MonoDevelop.Projects;
using MonoDevelop.Projects.MSBuild;
using ExecutionContext = MonoDevelop.Projects.ExecutionContext;
+using MonoDevelop.Ide.Gui.Documents;
namespace MonoDevelop.Ide
{
/// <summary>
/// This is the basic interface to the workspace.
- /// </summary>
- public partial class ProjectOperations
- {
+ /// </summary>
+ [DefaultServiceImplementation]
+ public partial class ProjectOperations: Service
+ {
+ RootWorkspace workspace;
+
AsyncOperation<BuildResult> currentBuildOperation = new AsyncOperation<BuildResult> (Task.FromResult (BuildResult.CreateSuccess ()), null);
MultipleAsyncOperation currentRunOperation = MultipleAsyncOperation.CompleteMultipleOperation;
IBuildTarget currentBuildOperationOwner;
@@ -63,86 +67,77 @@ namespace MonoDevelop.Ide
SelectReferenceDialog selDialog = null;
- SolutionFolderItem currentSolutionItem = null;
- WorkspaceItem currentWorkspaceItem = null;
- object currentItem;
-
- BuildResult lastResult = new BuildResult ();
-
internal ProjectOperations ()
{
- IdeApp.Workspace.WorkspaceItemUnloaded += OnWorkspaceItemUnloaded;
- IdeApp.Workspace.ItemUnloading += IdeAppWorkspaceItemUnloading;
-
- }
+ }
+
+ protected override async Task OnInitialize (ServiceProvider serviceProvider)
+ {
+ workspace = await serviceProvider.GetService<RootWorkspace> ();
+ workspace.WorkspaceItemUnloaded += OnWorkspaceItemUnloaded;
+ workspace.ItemUnloading += IdeAppWorkspaceItemUnloading;
+ await Task.WhenAll (new Task [] {
+ serviceProvider.GetService<DocumentManager> (),
+ serviceProvider.GetService<ProgressMonitorManager> (),
+ serviceProvider.GetService<TaskService> ()
+ });
+ }
+
+ protected override Task OnDispose ()
+ {
+ workspace.WorkspaceItemUnloaded -= OnWorkspaceItemUnloaded;
+ workspace.ItemUnloading -= IdeAppWorkspaceItemUnloading;
+ return base.OnDispose ();
+ }
- [Obsolete ("This property will be removed.")]
- public BuildResult LastCompilerResult {
- get { return lastResult; }
- }
-
public Project CurrentSelectedProject {
get {
- return currentSolutionItem as Project;
+ return workspace.CurrentSelectedProject;
}
}
public Solution CurrentSelectedSolution {
get {
- return currentWorkspaceItem as Solution;
+ return workspace.CurrentSelectedSolution;
}
}
public IBuildTarget CurrentSelectedBuildTarget {
get {
- if (currentSolutionItem is IBuildTarget)
- return (IBuildTarget) currentSolutionItem;
- return currentWorkspaceItem as IBuildTarget;
+ return workspace.CurrentSelectedBuildTarget;
}
}
public WorkspaceObject CurrentSelectedObject {
get {
- return (WorkspaceObject)currentSolutionItem ?? (WorkspaceObject) currentWorkspaceItem;
+ return workspace.CurrentSelectedObject;
}
}
public WorkspaceItem CurrentSelectedWorkspaceItem {
get {
- return currentWorkspaceItem;
+ return workspace.CurrentSelectedWorkspaceItem;
}
- set {
- if (value != currentWorkspaceItem) {
- WorkspaceItem oldValue = currentWorkspaceItem;
- currentWorkspaceItem = value;
- if (oldValue is Solution || value is Solution)
- OnCurrentSelectedSolutionChanged(new SolutionEventArgs (currentWorkspaceItem as Solution));
- }
+ set {
+ workspace.CurrentSelectedWorkspaceItem = value;
}
}
public SolutionFolderItem CurrentSelectedSolutionItem {
- get {
- if (currentSolutionItem == null && CurrentSelectedSolution != null)
- return CurrentSelectedSolution.RootFolder;
- return currentSolutionItem;
+ get {
+ return workspace.CurrentSelectedSolutionItem;
}
- set {
- if (value != currentSolutionItem) {
- SolutionFolderItem oldValue = currentSolutionItem;
- currentSolutionItem = value;
- if (oldValue is Project || value is Project)
- OnCurrentProjectChanged (new ProjectEventArgs(currentSolutionItem as Project));
- }
+ set {
+ workspace.CurrentSelectedSolutionItem = value;
}
}
public object CurrentSelectedItem {
get {
- return currentItem;
+ return workspace.CurrentSelectedItem;
}
set {
- currentItem = value;
+ workspace.CurrentSelectedItem = value;
}
}
@@ -191,45 +186,12 @@ namespace MonoDevelop.Ide
if (owner == target)
return true;
else if (target is RootWorkspace)
- return ContainsTarget (owner, IdeApp.ProjectOperations.CurrentSelectedSolution);
+ return ContainsTarget (owner, IdeServices.ProjectOperations.CurrentSelectedSolution);
else if (owner is WorkspaceItem)
return ((WorkspaceItem)owner).ContainsItem (target);
return false;
}
- /*
- string GetDeclaredFile(IMember item)
- {
- if (item is IMember) {
- IMember mem = (IMember) item;
- if (mem.Region == null)
- return null;
- else if (mem.Region.FileName != null)
- return mem.Region.FileName;
- else if (mem.DeclaringType != null) {
- foreach (IType c in mem.DeclaringType.Parts) {
- if ((mem is IField && c.Fields.Contains((IField)mem)) ||
- (mem is IEvent && c.Events.Contains((IEvent)mem)) ||
- (mem is IProperty && c.Properties.Contains((IProperty)mem)) ||
- (mem is IMethod && c.Methods.Contains((IMethod)mem))) {
- return GetClassFileName(c);
- }
- }
- }
- } else if (item is IType) {
- IType cls = (IType) item;
- return GetClassFileName (cls);
- } else if (item is MonoDevelop.Projects.Parser.LocalVariable) {
- MonoDevelop.Projects.Parser.LocalVariable cls = (MonoDevelop.Projects.Parser.LocalVariable) item;
- return cls.Region.FileName;
- }
- return null;
- }
-
- public bool CanJumpToDeclaration (IMember item)
- {
- return (GetDeclaredFile(item) != null);
- }*/
-
+
public bool CanJumpToDeclaration (Microsoft.CodeAnalysis.ISymbol symbol)
{
if (symbol == null)
@@ -264,7 +226,7 @@ namespace MonoDevelop.Ide
return new MonoDevelop.Ide.FindInFiles.SearchResult (provider, position, part.Name.Length);
}
- public async void JumpTo (Microsoft.CodeAnalysis.ISymbol symbol, Microsoft.CodeAnalysis.Location location, Project project = null)
+ public async void JumpTo (Microsoft.CodeAnalysis.ISymbol symbol, Microsoft.CodeAnalysis.Location location, WorkspaceObject project = null)
{
if (location == null)
return;
@@ -276,7 +238,7 @@ namespace MonoDevelop.Ide
var metadataDllName = location.MetadataModule.Name;
if (metadataDllName == "CommonLanguageRuntimeLibrary")
metadataDllName = "corlib.dll";
- foreach (var assembly in await dn.GetReferencedAssemblies (IdeApp.Workspace.ActiveConfiguration)) {
+ foreach (var assembly in await dn.GetReferencedAssemblies (workspace.ActiveConfiguration)) {
if (assembly.FilePath.ToString ().IndexOf (metadataDllName, StringComparison.Ordinal) > 0) {
fileName = dn.GetAbsoluteChildPath (assembly.FilePath);
break;
@@ -284,11 +246,11 @@ namespace MonoDevelop.Ide
}
if (fileName == null)
return;
- var doc = await IdeApp.Workbench.OpenDocument (new FileOpenInformation (fileName, project));
+ var doc = await IdeServices.DocumentManager.OpenDocument (new FileOpenInformation (fileName, project as Project));
if (doc != null) {
doc.RunWhenLoaded (delegate {
- var handler = doc.PrimaryView.GetContent<MonoDevelop.Ide.Gui.Content.IOpenNamedElementHandler> ();
+ var handler = doc.GetContent<MonoDevelop.Ide.Gui.Content.IOpenNamedElementHandler> ();
if (handler != null)
handler.Open (symbol);
});
@@ -298,27 +260,27 @@ namespace MonoDevelop.Ide
}
var filePath = location.SourceTree.FilePath;
var offset = location.SourceSpan.Start;
- if (project?.ParentSolution != null) {
+ if (project is SolutionFolderItem item && item.ParentSolution != null) {
string projectedName;
int projectedOffset;
- if (TypeSystemService.GetWorkspace (project.ParentSolution).TryGetOriginalFileFromProjection (filePath, offset, out projectedName, out projectedOffset)) {
+ if (IdeServices.TypeSystemService.GetWorkspace (item.ParentSolution).TryGetOriginalFileFromProjection (filePath, offset, out projectedName, out projectedOffset)) {
filePath = projectedName;
offset = projectedOffset;
}
}
- await IdeApp.Workbench.OpenDocument (new FileOpenInformation (filePath, project) {
+ await IdeServices.DocumentManager.OpenDocument (new FileOpenInformation (filePath, project as Project) {
Offset = offset
});
}
- public void JumpToDeclaration (Microsoft.CodeAnalysis.ISymbol symbol, Project project = null, bool askIfMultipleLocations = true)
+ public void JumpToDeclaration (Microsoft.CodeAnalysis.ISymbol symbol, WorkspaceObject project = null, bool askIfMultipleLocations = true)
{
if (symbol == null)
throw new ArgumentNullException ("symbol");
var locations = symbol.Locations;
if (askIfMultipleLocations && locations.Length > 1) {
- using (var monitor = IdeApp.Workbench.ProgressMonitors.GetSearchProgressMonitor (true, true)) {
+ using (var monitor = IdeServices.ProgressMonitorManager.GetSearchProgressMonitor (true, true)) {
foreach (var part in locations) {
if (monitor.CancellationToken.IsCancellationRequested)
return;
@@ -341,7 +303,7 @@ namespace MonoDevelop.Ide
metadataDllName = "corlib.dll";
var dn = project as DotNetProject;
if (dn != null) {
- foreach (var assembly in await dn.GetReferencedAssemblies (IdeApp.Workspace.ActiveConfiguration)) {
+ foreach (var assembly in await dn.GetReferencedAssemblies (workspace.ActiveConfiguration)) {
if (assembly.FilePath.ToString ().IndexOf(metadataDllName, StringComparison.Ordinal) > 0) {
fileName = dn.GetAbsoluteChildPath (assembly.FilePath);
break;
@@ -350,10 +312,10 @@ namespace MonoDevelop.Ide
}
if (fileName == null || !File.Exists (fileName))
return;
- var doc = await IdeApp.Workbench.OpenDocument (new FileOpenInformation (fileName));
+ var doc = await IdeServices.DocumentManager.OpenDocument (new FileOpenInformation (fileName));
if (doc != null) {
doc.RunWhenLoaded (delegate {
- var handler = doc.PrimaryView.GetContent<MonoDevelop.Ide.Gui.Content.IOpenNamedElementHandler> ();
+ var handler = doc.GetContent<MonoDevelop.Ide.Gui.Content.IOpenNamedElementHandler> ();
if (handler != null)
handler.Open (documentationCommentId, openInPublicOnlyMode);
});
@@ -366,8 +328,8 @@ namespace MonoDevelop.Ide
if (item is SolutionFolderItem) {
await SaveAsync (((SolutionFolderItem)item).ParentSolution);
} else {
- await IdeApp.Workspace.SaveAsync ();
- IdeApp.Workspace.SavePreferences ();
+ await workspace.SaveAsync ();
+ workspace.SavePreferences ();
}
}
@@ -382,7 +344,7 @@ namespace MonoDevelop.Ide
try {
if (MessageService.RunCustomDialog (dlg) == (int) Gtk.ResponseType.Ok) {
- using (ProgressMonitor monitor = IdeApp.Workbench.ProgressMonitors.GetToolOutputProgressMonitor (true)) {
+ using (ProgressMonitor monitor = IdeServices.ProgressMonitorManager.GetToolOutputProgressMonitor (true)) {
await Services.ProjectService.Export (monitor, item.FileName, dlg.TargetFolder, dlg.Format);
}
}
@@ -417,7 +379,7 @@ namespace MonoDevelop.Ide
if (!AllowSave (entry))
return;
- ProgressMonitor monitor = IdeApp.Workbench.ProgressMonitors.GetSaveProgressMonitor (true);
+ ProgressMonitor monitor = IdeServices.ProgressMonitorManager.GetSaveProgressMonitor (true);
try {
await entry.SaveAsync (monitor);
monitor.ReportSuccess (GettextCatalog.GetString ("Project saved."));
@@ -443,7 +405,7 @@ namespace MonoDevelop.Ide
if (!AllowSave (item))
return;
- ProgressMonitor monitor = IdeApp.Workbench.ProgressMonitors.GetSaveProgressMonitor (true);
+ ProgressMonitor monitor = IdeServices.ProgressMonitorManager.GetSaveProgressMonitor (true);
try {
await item.SaveAsync (monitor);
monitor.ReportSuccess (GettextCatalog.GetString ("Solution saved."));
@@ -498,7 +460,7 @@ namespace MonoDevelop.Ide
items = notSavedEntries;
}
- ProgressMonitor monitor = IdeApp.Workbench.ProgressMonitors.GetSaveProgressMonitor (true);
+ ProgressMonitor monitor = IdeServices.ProgressMonitorManager.GetSaveProgressMonitor (true);
try {
var tasks = new List<Task> ();
monitor.BeginTask (null, count);
@@ -545,7 +507,7 @@ namespace MonoDevelop.Ide
if (!AllowSave (item))
return;
- ProgressMonitor monitor = IdeApp.Workbench.ProgressMonitors.GetSaveProgressMonitor (true);
+ ProgressMonitor monitor = IdeServices.ProgressMonitorManager.GetSaveProgressMonitor (true);
try {
await item.SaveAsync (monitor);
monitor.ReportSuccess (GettextCatalog.GetString ("Item saved."));
@@ -632,7 +594,7 @@ namespace MonoDevelop.Ide
var selectedProject = (SolutionItem) entry;
var optionsDialog = new ProjectOptionsDialog (IdeApp.Workbench.RootWindow, selectedProject);
- var conf = selectedProject.GetConfiguration (IdeApp.Workspace.ActiveConfiguration);
+ var conf = selectedProject.GetConfiguration (workspace.ActiveConfiguration);
optionsDialog.CurrentConfig = conf != null ? conf.Name : null;
optionsDialog.CurrentPlatform = conf != null ? conf.Platform : null;
try {
@@ -647,7 +609,7 @@ namespace MonoDevelop.Ide
}
}
await SaveAsync (selectedProject);
- IdeApp.Workspace.SavePreferences ();
+ workspace.SavePreferences ();
IdeApp.Workbench.ReparseOpenDocuments ();
}
} finally {
@@ -658,13 +620,13 @@ namespace MonoDevelop.Ide
Solution solution = (Solution) entry;
var optionsDialog = new CombineOptionsDialog (IdeApp.Workbench.RootWindow, solution);
- optionsDialog.CurrentConfig = IdeApp.Workspace.ActiveConfigurationId;
+ optionsDialog.CurrentConfig = workspace.ActiveConfigurationId;
try {
if (panelId != null)
optionsDialog.SelectPanel (panelId);
if (MessageService.RunCustomDialog (optionsDialog) == (int) Gtk.ResponseType.Ok) {
await SaveAsync (solution);
- await IdeApp.Workspace.SavePreferences (solution);
+ await workspace.SavePreferences (solution);
}
} finally {
optionsDialog.Destroy ();
@@ -684,7 +646,7 @@ namespace MonoDevelop.Ide
if (si.ParentSolution != null)
await SaveAsync (si.ParentSolution);
}
- IdeApp.Workspace.SavePreferences ();
+ workspace.SavePreferences ();
}
} finally {
optionsDialog.Destroy ();
@@ -771,7 +733,7 @@ namespace MonoDevelop.Ide
public async Task<WorkspaceItem> AddWorkspaceItem (Workspace parentWorkspace, string itemFileName)
{
- using (ProgressMonitor monitor = IdeApp.Workbench.ProgressMonitors.GetProjectLoadProgressMonitor (true)) {
+ using (ProgressMonitor monitor = IdeServices.ProgressMonitorManager.GetProjectLoadProgressMonitor (true)) {
WorkspaceItem it = await Services.ProjectService.ReadWorkspaceItem (monitor, itemFileName);
if (it != null) {
parentWorkspace.Items.Add (it);
@@ -841,7 +803,7 @@ namespace MonoDevelop.Ide
}
if (res != null)
- await IdeApp.Workspace.SaveAsync ();
+ await workspace.SaveAsync ();
return res;
}
@@ -859,7 +821,7 @@ namespace MonoDevelop.Ide
AddingEntryToCombine (this, args);
if (args.Cancel)
return null;
- using (ProgressMonitor monitor = IdeApp.Workbench.ProgressMonitors.GetProjectLoadProgressMonitor (true)) {
+ using (ProgressMonitor monitor = IdeServices.ProgressMonitorManager.GetProjectLoadProgressMonitor (true)) {
return await folder.AddItem (monitor, args.FileName, true);
}
}
@@ -938,7 +900,7 @@ namespace MonoDevelop.Ide
SolutionItem prj = item as SolutionItem;
if (prj == null) {
- if (MessageService.Confirm (question, AlertButton.Remove) && IdeApp.Workspace.RequestItemUnload (item))
+ if (MessageService.Confirm (question, AlertButton.Remove) && workspace.RequestItemUnload (item))
RemoveItemFromSolution (prj).Ignore();
return;
}
@@ -947,7 +909,7 @@ namespace MonoDevelop.Ide
AlertButton result = MessageService.AskQuestion (question, secondaryText,
delete, AlertButton.Cancel, AlertButton.Remove);
if (result == delete) {
- if (!IdeApp.Workspace.RequestItemUnload (prj))
+ if (!workspace.RequestItemUnload (prj))
return;
ConfirmProjectDeleteDialog dlg = new ConfirmProjectDeleteDialog (prj);
try {
@@ -978,19 +940,19 @@ namespace MonoDevelop.Ide
dlg.Dispose ();
}
}
- else if (result == AlertButton.Remove && IdeApp.Workspace.RequestItemUnload (prj)) {
+ else if (result == AlertButton.Remove && workspace.RequestItemUnload (prj)) {
RemoveItemFromSolution (prj).Ignore();
}
}
async Task RemoveItemFromSolution (SolutionFolderItem prj)
{
- foreach (var doc in IdeApp.Workbench.Documents.Where (d => d.Project == prj).ToArray ())
+ foreach (var doc in IdeServices.DocumentManager.Documents.Where (d => d.Owner == prj).ToArray ())
await doc.Close ();
Solution sol = prj.ParentSolution;
prj.ParentFolder.Items.Remove (prj);
prj.Dispose ();
- await IdeApp.ProjectOperations.SaveAsync (sol);
+ await SaveAsync (sol);
}
/// <summary>
@@ -1018,19 +980,19 @@ namespace MonoDevelop.Ide
public bool CanExecute (IBuildTarget entry)
{
- ExecutionContext context = new ExecutionContext (Runtime.ProcessService.DefaultExecutionHandler, IdeApp.Workbench.ProgressMonitors.ConsoleFactory, IdeApp.Workspace.ActiveExecutionTarget);
+ ExecutionContext context = new ExecutionContext (Runtime.ProcessService.DefaultExecutionHandler, IdeServices.ProgressMonitorManager.ConsoleFactory, workspace.ActiveExecutionTarget);
return CanExecute (entry, context);
}
public bool CanExecute (IBuildTarget entry, IExecutionHandler handler)
{
- ExecutionContext context = new ExecutionContext (handler, IdeApp.Workbench.ProgressMonitors.ConsoleFactory, IdeApp.Workspace.ActiveExecutionTarget);
- return entry.CanExecute (context, IdeApp.Workspace.ActiveConfiguration);
+ ExecutionContext context = new ExecutionContext (handler, IdeServices.ProgressMonitorManager.ConsoleFactory, workspace.ActiveExecutionTarget);
+ return entry.CanExecute (context, workspace.ActiveConfiguration);
}
public bool CanExecute (IBuildTarget entry, ExecutionContext context)
{
- return entry.CanExecute (context, IdeApp.Workspace.ActiveConfiguration);
+ return entry.CanExecute (context, workspace.ActiveConfiguration);
}
public AsyncOperation Execute (IBuildTarget entry, bool buildBeforeExecuting = true)
@@ -1040,20 +1002,20 @@ namespace MonoDevelop.Ide
public AsyncOperation Execute (IBuildTarget entry, IExecutionHandler handler, bool buildBeforeExecuting = true)
{
- ExecutionContext context = new ExecutionContext (handler, IdeApp.Workbench.ProgressMonitors.ConsoleFactory, IdeApp.Workspace.ActiveExecutionTarget);
+ ExecutionContext context = new ExecutionContext (handler, IdeServices.ProgressMonitorManager.ConsoleFactory, workspace.ActiveExecutionTarget);
return Execute (entry, context, buildBeforeExecuting);
}
public AsyncOperation Execute (IBuildTarget entry, IExecutionHandler handler, ConfigurationSelector configuration = null, RunConfiguration runConfiguration = null, bool buildBeforeExecuting = true)
{
- ExecutionContext context = new ExecutionContext (handler, IdeApp.Workbench.ProgressMonitors.ConsoleFactory, IdeApp.Workspace.ActiveExecutionTarget);
+ ExecutionContext context = new ExecutionContext (handler, IdeServices.ProgressMonitorManager.ConsoleFactory, workspace.ActiveExecutionTarget);
return Execute (entry, context, configuration, runConfiguration, buildBeforeExecuting);
}
public AsyncOperation Execute (IBuildTarget entry, ExecutionContext context, bool buildBeforeExecuting = true)
{
var cs = new CancellationTokenSource ();
- return new AsyncOperation (ExecuteAsync (entry, context, cs, IdeApp.Workspace.ActiveConfiguration, null, buildBeforeExecuting), cs);
+ return new AsyncOperation (ExecuteAsync (entry, context, cs, workspace.ActiveConfiguration, null, buildBeforeExecuting), cs);
}
public AsyncOperation Execute (IBuildTarget entry, ExecutionContext context, ConfigurationSelector configuration = null, RunConfiguration runConfiguration = null, bool buildBeforeExecuting = true)
@@ -1093,7 +1055,7 @@ namespace MonoDevelop.Ide
Counters.TrackingBuildAndDeploy = true;
if (configuration == null)
- configuration = IdeApp.Workspace.ActiveConfiguration;
+ configuration = workspace.ActiveConfiguration;
var bth = context.ExecutionHandler as IConfigurableExecutionHandler;
var rt = entry as IRunTarget;
@@ -1162,7 +1124,7 @@ namespace MonoDevelop.Ide
public bool CanExecuteFile (string file, IExecutionHandler handler)
{
- ExecutionContext context = new ExecutionContext (handler, IdeApp.Workbench.ProgressMonitors.ConsoleFactory, IdeApp.Workspace.ActiveExecutionTarget);
+ ExecutionContext context = new ExecutionContext (handler, IdeServices.ProgressMonitorManager.ConsoleFactory, workspace.ActiveExecutionTarget);
return CanExecuteFile (file, context);
}
@@ -1176,7 +1138,7 @@ namespace MonoDevelop.Ide
public AsyncOperation ExecuteFile (string file, IExecutionHandler handler)
{
- ExecutionContext context = new ExecutionContext (handler, IdeApp.Workbench.ProgressMonitors.ConsoleFactory, IdeApp.Workspace.ActiveExecutionTarget);
+ ExecutionContext context = new ExecutionContext (handler, IdeServices.ProgressMonitorManager.ConsoleFactory, workspace.ActiveExecutionTarget);
return ExecuteFile (file, context);
}
@@ -1199,7 +1161,7 @@ namespace MonoDevelop.Ide
ITimeTracker tt = Counters.BuildItemTimer.BeginTiming ("Cleaning " + entry.Name);
try {
var cs = new CancellationTokenSource ();
- ProgressMonitor monitor = IdeApp.Workbench.ProgressMonitors.GetCleanProgressMonitor ().WithCancellationSource (cs);
+ ProgressMonitor monitor = IdeServices.ProgressMonitorManager.GetCleanProgressMonitor ().WithCancellationSource (cs);
OnStartClean (monitor, tt);
@@ -1227,7 +1189,7 @@ namespace MonoDevelop.Ide
BuildResult res = null;
try {
tt.Trace ("Cleaning item");
- res = await entry.Clean (monitor, IdeApp.Workspace.ActiveConfiguration, InitOperationContext (entry, operationContext));
+ res = await entry.Clean (monitor, workspace.ActiveConfiguration, InitOperationContext (entry, operationContext));
} catch (Exception ex) {
monitor.ReportError (GettextCatalog.GetString ("Clean failed."), ex);
} finally {
@@ -1301,9 +1263,10 @@ namespace MonoDevelop.Ide
tasks [n].Owner = this;
}
- TaskService.Errors.AddRange (tasks);
- TaskService.Errors.ResetLocationList ();
- IdeApp.Workbench.ActiveLocationList = TaskService.Errors;
+ IdeServices.TaskService.Errors.AddRange (tasks);
+ IdeServices.TaskService.Errors.ResetLocationList ();
+ if (IdeApp.IsInitialized)
+ IdeApp.Workbench.ActiveLocationList = IdeServices.TaskService.Errors;
return tasks;
}
@@ -1319,11 +1282,11 @@ namespace MonoDevelop.Ide
errorsPad.BringToFront ();
break;
case BuildResultStates.OnErrors:
- if (TaskService.Errors.Any (task => task.Severity == TaskSeverity.Error))
+ if (IdeServices.TaskService.Errors.Any (task => task.Severity == TaskSeverity.Error))
goto case BuildResultStates.Always;
break;
case BuildResultStates.OnErrorsOrWarnings:
- if (TaskService.Errors.Any (task => task.Severity == TaskSeverity.Error || task.Severity == TaskSeverity.Warning))
+ if (IdeServices.TaskService.Errors.Any (task => task.Severity == TaskSeverity.Error || task.Severity == TaskSeverity.Warning))
goto case BuildResultStates.Always;
break;
}
@@ -1340,7 +1303,7 @@ namespace MonoDevelop.Ide
if (currentBuildOperation != null && !currentBuildOperation.IsCompleted) return currentBuildOperation;
var cs = new CancellationTokenSource ();
- ProgressMonitor monitor = IdeApp.Workbench.ProgressMonitors.GetRebuildProgressMonitor ().WithCancellationSource (cs);
+ ProgressMonitor monitor = IdeServices.ProgressMonitorManager.GetRebuildProgressMonitor ().WithCancellationSource (cs);
var t = RebuildAsync (entry, monitor, operationContext);
t = t.ContinueWith (ta => {
@@ -1639,7 +1602,7 @@ namespace MonoDevelop.Ide
var cs = new CancellationTokenSource ();
if (cancellationToken != null)
cs = CancellationTokenSource.CreateLinkedTokenSource (cs.Token, cancellationToken.Value);
- ProgressMonitor monitor = IdeApp.Workbench.ProgressMonitors.GetBuildProgressMonitor ().WithCancellationSource (cs);
+ ProgressMonitor monitor = IdeServices.ProgressMonitorManager.GetBuildProgressMonitor ().WithCancellationSource (cs);
BeginBuild (monitor, tt, false);
var t = BuildSolutionItemAsync (entry, monitor, tt, skipPrebuildCheck, operationContext);
currentBuildOperation = new AsyncOperation<BuildResult> (t, cs);
@@ -1666,7 +1629,7 @@ namespace MonoDevelop.Ide
if (skipPrebuildCheck || result.ErrorCount == 0) {
tt.Trace ("Building item");
- result = await entry.Build (monitor, IdeApp.Workspace.ActiveConfiguration, true, InitOperationContext (entry, operationContext));
+ result = await entry.Build (monitor, workspace.ActiveConfiguration, true, InitOperationContext (entry, operationContext));
}
} catch (Exception ex) {
monitor.ReportError (GettextCatalog.GetString ("Build failed."), ex);
@@ -1696,9 +1659,9 @@ namespace MonoDevelop.Ide
if (ctx.ExecutionTarget == null) {
var item = target as SolutionItem;
if (item != null)
- ctx.ExecutionTarget = IdeApp.Workspace.GetActiveExecutionTarget (item);
+ ctx.ExecutionTarget = IdeServices.Workspace.GetActiveExecutionTarget (item);
else
- ctx.ExecutionTarget = IdeApp.Workspace.ActiveExecutionTarget;
+ ctx.ExecutionTarget = IdeServices.Workspace.ActiveExecutionTarget;
}
return (T)ctx;
}
@@ -1708,8 +1671,8 @@ namespace MonoDevelop.Ide
{
var couldNotSaveError = "The build has been aborted as the file '{0}' could not be saved";
- foreach (var doc in IdeApp.Workbench.Documents) {
- if (doc.IsDirty && doc.Project != null) {
+ foreach (var doc in IdeServices.DocumentManager.Documents) {
+ if (doc.IsDirty && doc.Owner != null) {
if (MessageService.AskQuestion (GettextCatalog.GetString ("Save changed documents before building?"),
GettextCatalog.GetString ("Some of the open documents have unsaved changes."),
AlertButton.BuildWithoutSave, AlertButton.Save) == AlertButton.Save) {
@@ -1728,8 +1691,8 @@ namespace MonoDevelop.Ide
{
var couldNotSaveError = "The build has been aborted as the file '{0}' could not be saved";
- foreach (var doc in new List<MonoDevelop.Ide.Gui.Document> (IdeApp.Workbench.Documents)) {
- if (doc.IsDirty && doc.Project != null) {
+ foreach (var doc in new List<MonoDevelop.Ide.Gui.Document> (IdeServices.DocumentManager.Documents)) {
+ if (doc.IsDirty && doc.Owner != null) {
await doc.Save ();
if (doc.IsDirty) {
doc.Select ();
@@ -1763,7 +1726,7 @@ namespace MonoDevelop.Ide
{
tt.Trace ("Start build event");
if (!isRebuilding) {
- MonoDevelop.Ide.Tasks.TaskService.Errors.ClearByOwner (this);
+ IdeServices.TaskService.Errors.ClearByOwner (this);
}
if (StartBuild != null) {
StartBuild (this, new BuildEventArgs (monitor, true));
@@ -1776,7 +1739,7 @@ namespace MonoDevelop.Ide
tt.Trace ("Begin reporting build result");
try {
if (result != null) {
- lastResult = result;
+ var lastResult = result;
monitor.Log.WriteLine ();
var msg = GettextCatalog.GetString (
@@ -2473,7 +2436,7 @@ namespace MonoDevelop.Ide
void OnStartClean (ProgressMonitor monitor, ITimeTracker tt)
{
tt.Trace ("Start clean event");
- TaskService.Errors.ClearByOwner (this);
+ IdeServices.TaskService.Errors.ClearByOwner (this);
if (StartClean != null) {
StartClean (this, new CleanEventArgs (monitor));
}
@@ -2504,39 +2467,39 @@ namespace MonoDevelop.Ide
void OnWorkspaceItemUnloaded (object s, WorkspaceItemEventArgs args)
{
- if (ContainsTarget (args.Item, currentSolutionItem))
+ if (ContainsTarget (args.Item, workspace.CurrentSelectedSolutionItem))
CurrentSelectedSolutionItem = null;
- if (ContainsTarget (args.Item, currentWorkspaceItem))
+ if (ContainsTarget (args.Item, CurrentSelectedWorkspaceItem))
CurrentSelectedWorkspaceItem = null;
- if ((currentItem is IBuildTarget) && ContainsTarget (args.Item, ((WorkspaceObject)currentItem)))
+ if ((CurrentSelectedItem is WorkspaceObject) && ContainsTarget (args.Item, ((WorkspaceObject)CurrentSelectedItem)))
CurrentSelectedItem = null;
}
- protected virtual void OnCurrentSelectedSolutionChanged(SolutionEventArgs e)
- {
- if (CurrentSelectedSolutionChanged != null) {
- CurrentSelectedSolutionChanged (this, e);
- }
- }
-
- protected virtual void OnCurrentProjectChanged(ProjectEventArgs e)
- {
- if (CurrentSelectedProject != null) {
- StringParserService.Properties["PROJECTNAME"] = CurrentSelectedProject.Name;
- }
- if (CurrentProjectChanged != null) {
- CurrentProjectChanged (this, e);
- }
- }
-
public event BuildEventHandler StartBuild;
public event BuildEventHandler EndBuild;
public event EventHandler BeforeStartProject;
public event CleanEventHandler StartClean;
public event CleanEventHandler EndClean;
-
- public event EventHandler<SolutionEventArgs> CurrentSelectedSolutionChanged;
- public event ProjectEventHandler CurrentProjectChanged;
+
+ public event EventHandler<SolutionEventArgs> CurrentSelectedSolutionChanged {
+ add {
+ workspace.CurrentSelectedSolutionChanged += value;
+ }
+ remove {
+ workspace.CurrentSelectedSolutionChanged -= value;
+ }
+ }
+
+ public event ProjectEventHandler CurrentProjectChanged {
+ add {
+ workspace.CurrentProjectChanged += value;
+ }
+
+ remove {
+ workspace.CurrentProjectChanged -= value;
+ }
+ }
+
public event EventHandler<ProjectCreatedEventArgs> ProjectCreated;
// Fired just before an entry is added to a combine
@@ -2619,12 +2582,10 @@ namespace MonoDevelop.Ide
public ITextDocument GetEditableTextFile (FilePath filePath)
{
- if (IdeApp.IsInitialized) {
- foreach (var doc in IdeApp.Workbench.Documents) {
- if (doc.FileName == filePath) {
- var ef = doc.Editor;
- if (ef != null) return ef;
- }
+ foreach (var doc in IdeServices.DocumentManager.Documents) {
+ if (doc.FileName == filePath) {
+ var ef = doc.Editor;
+ if (ef != null) return ef;
}
}
@@ -2665,7 +2626,7 @@ namespace MonoDevelop.Ide
{
if (filePath.IsNullOrEmpty)
throw new ArgumentNullException ("filePath");
- foreach (var doc in IdeApp.Workbench.Documents) {
+ foreach (var doc in IdeServices.DocumentManager.Documents) {
if (IsSearchedDocument (doc, filePath)) {
return doc.Editor;
}
@@ -2676,16 +2637,14 @@ namespace MonoDevelop.Ide
public ITextDocument GetTextEditorData (FilePath filePath, out bool isOpen)
{
- if (IdeApp.Workbench != null) {
- foreach (var doc in IdeApp.Workbench.Documents) {
- if (IsSearchedDocument (doc, filePath)) {
- isOpen = true;
- return doc.Editor;
- }
+ foreach (var doc in IdeServices.DocumentManager.Documents) {
+ if (IsSearchedDocument (doc, filePath)) {
+ isOpen = true;
+ return doc.Editor;
}
}
- var data = TextEditorFactory.CreateNewDocument (filePath, DesktopService.GetMimeTypeForUri(filePath));
+ var data = TextEditorFactory.CreateNewDocument (filePath, IdeServices.DesktopService.GetMimeTypeForUri(filePath));
isOpen = false;
return data;
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/RootWorkspace.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/RootWorkspace.cs
index 97a5eb8144..f0c5f31fc3 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/RootWorkspace.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/RootWorkspace.cs
@@ -1,4 +1,4 @@
-// RootWorkspace.cs
+// RootWorkspace.cs
//
// Author:
// Lluis Sanchez Gual <lluis@novell.com>
@@ -44,15 +44,23 @@ using MonoDevelop.Ide.Gui;
using MonoDevelop.Ide.Projects;
using MonoDevelop.Core.Execution;
using System.Threading.Tasks;
+using MonoDevelop.Ide.TypeSystem;
+using MonoDevelop.Ide.Gui.Documents;
namespace MonoDevelop.Ide
{
- public sealed class RootWorkspace: WorkspaceObject, IBuildTarget
+ [DefaultServiceImplementation]
+ public sealed class RootWorkspace: WorkspaceObject, IBuildTarget, IService
{
+ ServiceProvider serviceProvider;
RootWorkspaceItemCollection items;
-// IParserDatabase parserDatabase;
string activeConfiguration;
bool useDefaultRuntime;
+ DocumentManager documentManager;
+
+ SolutionFolderItem currentSolutionItem = null;
+ WorkspaceItem currentWorkspaceItem = null;
+ object currentItem;
internal RootWorkspace ()
{
@@ -60,20 +68,121 @@ namespace MonoDevelop.Ide
currentWorkspaceLoadTask = new TaskCompletionSource<bool> ();
currentWorkspaceLoadTask.SetResult (true);
+ }
+ Task IService.Initialize (ServiceProvider serviceProvider)
+ {
+ this.serviceProvider = serviceProvider;
FileService.FileRenamed += CheckFileRename;
-
+
+ serviceProvider.WhenServiceInitialized<DocumentManager> (s => {
+ documentManager = s;
+ });
+
// Set the initial active runtime
UseDefaultRuntime = true;
- IdeApp.Preferences.DefaultTargetRuntime.Changed += delegate {
+ DefaultTargetRuntime.Changed += delegate {
// If the default runtime changes and current active is default, update it
if (UseDefaultRuntime) {
- Runtime.SystemAssemblyService.DefaultRuntime = IdeApp.Preferences.DefaultTargetRuntime;
+ Runtime.SystemAssemblyService.DefaultRuntime = DefaultTargetRuntime;
useDefaultRuntime = true;
}
};
+ return Task.CompletedTask;
}
-
+
+ Task IService.Dispose ()
+ {
+ return Task.CompletedTask;
+ }
+
+ internal static ConfigurationProperty<TargetRuntime> DefaultTargetRuntime = new DefaultTargetRuntimeProperty ();
+
+ public Project CurrentSelectedProject {
+ get {
+ return currentSolutionItem as Project;
+ }
+ }
+
+ public Solution CurrentSelectedSolution {
+ get {
+ return currentWorkspaceItem as Solution;
+ }
+ }
+
+ public IBuildTarget CurrentSelectedBuildTarget {
+ get {
+ if (currentSolutionItem is IBuildTarget)
+ return (IBuildTarget)currentSolutionItem;
+ return currentWorkspaceItem as IBuildTarget;
+ }
+ }
+
+ public WorkspaceObject CurrentSelectedObject {
+ get {
+ return (WorkspaceObject)currentSolutionItem ?? (WorkspaceObject)currentWorkspaceItem;
+ }
+ }
+
+ public WorkspaceItem CurrentSelectedWorkspaceItem {
+ get {
+ return currentWorkspaceItem;
+ }
+ set {
+ if (value != currentWorkspaceItem) {
+ WorkspaceItem oldValue = currentWorkspaceItem;
+ currentWorkspaceItem = value;
+ if (oldValue is Solution || value is Solution)
+ OnCurrentSelectedSolutionChanged (new SolutionEventArgs (currentWorkspaceItem as Solution));
+ }
+ }
+ }
+
+ public SolutionFolderItem CurrentSelectedSolutionItem {
+ get {
+ if (currentSolutionItem == null && CurrentSelectedSolution != null)
+ return CurrentSelectedSolution.RootFolder;
+ return currentSolutionItem;
+ }
+ set {
+ if (value != currentSolutionItem) {
+ SolutionFolderItem oldValue = currentSolutionItem;
+ currentSolutionItem = value;
+ if (oldValue is Project || value is Project)
+ OnCurrentProjectChanged (new ProjectEventArgs (currentSolutionItem as Project));
+ }
+ }
+ }
+
+ void OnCurrentSelectedSolutionChanged (SolutionEventArgs e)
+ {
+ if (CurrentSelectedSolutionChanged != null) {
+ CurrentSelectedSolutionChanged (this, e);
+ }
+ }
+
+ void OnCurrentProjectChanged (ProjectEventArgs e)
+ {
+ if (CurrentSelectedProject != null) {
+ StringParserService.Properties ["PROJECTNAME"] = CurrentSelectedProject.Name;
+ }
+ if (CurrentProjectChanged != null) {
+ CurrentProjectChanged (this, e);
+ }
+ }
+
+ public event EventHandler<SolutionEventArgs> CurrentSelectedSolutionChanged;
+ public event ProjectEventHandler CurrentProjectChanged;
+
+ public object CurrentSelectedItem {
+ get {
+ return currentItem;
+ }
+ set {
+ currentItem = value;
+ }
+ }
+
public RootWorkspaceItemCollection Items {
get {
return items;
@@ -151,7 +260,7 @@ namespace MonoDevelop.Ide
if (useDefaultRuntime != value) {
useDefaultRuntime = value;
if (value)
- Runtime.SystemAssemblyService.DefaultRuntime = IdeApp.Preferences.DefaultTargetRuntime;
+ Runtime.SystemAssemblyService.DefaultRuntime = DefaultTargetRuntime;
}
}
}
@@ -183,8 +292,8 @@ namespace MonoDevelop.Ide
public IEnumerable<IBuildTarget> GetExecutionDependencies ()
{
- if (IdeApp.ProjectOperations.CurrentSelectedSolution != null)
- return IdeApp.ProjectOperations.CurrentSelectedSolution.GetExecutionDependencies ();
+ if (CurrentSelectedSolution != null)
+ return CurrentSelectedSolution.GetExecutionDependencies ();
else
return new IBuildTarget [0];
}
@@ -216,13 +325,42 @@ namespace MonoDevelop.Ide
}
}
-#endregion
-
-#region Build and run operations
-
+ // When looking for the project to which the file belongs, look first
+ // in the active project, then the active solution, and so on
+ public Project GetProjectContainingFile (FilePath fileName)
+ {
+ Project project = null;
+ if (CurrentSelectedProject != null) {
+ if (CurrentSelectedProject.Files.GetFile (fileName) != null)
+ project = CurrentSelectedProject;
+ else if (CurrentSelectedProject.FileName == fileName)
+ project = CurrentSelectedProject;
+ }
+ if (project == null && CurrentSelectedWorkspaceItem != null) {
+ project = CurrentSelectedWorkspaceItem.GetProjectsContainingFile (fileName).FirstOrDefault ();
+ if (project == null) {
+ WorkspaceItem it = CurrentSelectedWorkspaceItem.ParentWorkspace;
+ while (it != null && project == null) {
+ project = it.GetProjectsContainingFile (fileName).FirstOrDefault ();
+ it = it.ParentWorkspace;
+ }
+ }
+ }
+ if (project == null) {
+ project = GetProjectsContainingFile (fileName).FirstOrDefault ();
+ }
+ return project;
+ }
+
+
+ #endregion
+
+ #region Build and run operations
+
public async Task SaveAsync ()
{
- ProgressMonitor monitor = IdeApp.Workbench.ProgressMonitors.GetSaveProgressMonitor (true);
+ var monitorManager = await Runtime.GetService<ProgressMonitorManager> ();
+ ProgressMonitor monitor = monitorManager.GetSaveProgressMonitor (true);
try {
await SaveAsync (monitor);
monitor.ReportSuccess (GettextCatalog.GetString ("Workspace saved."));
@@ -240,8 +378,8 @@ namespace MonoDevelop.Ide
bool IBuildTarget.CanExecute (ExecutionContext context, ConfigurationSelector configuration)
{
- if (IdeApp.ProjectOperations.CurrentSelectedSolution != null)
- return IdeApp.ProjectOperations.CurrentSelectedSolution.CanExecute (context, configuration);
+ if (CurrentSelectedSolution != null)
+ return CurrentSelectedSolution.CanExecute (context, configuration);
else {
return false;
}
@@ -295,7 +433,7 @@ namespace MonoDevelop.Ide
public Task Execute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
{
- Solution sol = IdeApp.ProjectOperations.CurrentSelectedSolution ?? GetAllSolutions ().FirstOrDefault ();
+ Solution sol = CurrentSelectedSolution ?? GetAllSolutions ().FirstOrDefault ();
if (sol != null)
return sol.Execute (monitor, context, configuration);
else
@@ -321,9 +459,11 @@ namespace MonoDevelop.Ide
bool IsDirtyFileInCombine {
get {
+ if (documentManager == null)
+ return false;
foreach (Project projectEntry in GetAllProjects()) {
foreach (ProjectFile fInfo in projectEntry.Files) {
- foreach (Document doc in IdeApp.Workbench.Documents) {
+ foreach (Document doc in documentManager.Documents) {
if (doc.IsDirty && doc.FileName == fInfo.FilePath) {
return true;
}
@@ -362,26 +502,28 @@ namespace MonoDevelop.Ide
public async Task<bool> Close (bool saveWorkspacePreferencies)
{
- return await Close (saveWorkspacePreferencies, true);
+ return await Close (saveWorkspacePreferencies, true, false);
}
-
- internal async Task<bool> Close (bool saveWorkspacePreferencies, bool closeProjectFiles)
+
+ internal async Task<bool> Close (bool saveWorkspacePreferencies, bool closeProjectFiles, bool force = false)
{
if (Items.Count > 0) {
ITimeTracker timer = Counters.CloseWorkspaceTimer.BeginTiming ();
try {
- // Request permission for unloading the items
- foreach (WorkspaceItem it in new List<WorkspaceItem> (Items)) {
- if (!RequestItemUnload (it))
- return false;
+ if (!force) {
+ // Request permission for unloading the items
+ foreach (WorkspaceItem it in new List<WorkspaceItem> (Items)) {
+ if (!RequestItemUnload (it))
+ return false;
+ }
}
if (saveWorkspacePreferencies)
SavePreferences ();
- if (closeProjectFiles) {
- foreach (Document doc in IdeApp.Workbench.Documents.ToArray ()) {
- if (!await doc.Close ())
+ if (closeProjectFiles && documentManager != null) {
+ foreach (Document doc in documentManager.Documents.ToArray ()) {
+ if (!await doc.Close (force))
return false;
}
}
@@ -392,6 +534,7 @@ namespace MonoDevelop.Ide
it.Dispose ();
} catch (Exception ex) {
MessageService.ShowError (GettextCatalog.GetString ("Could not close solution '{0}'.", it.Name), ex);
+ return false;
}
}
} finally {
@@ -413,9 +556,9 @@ namespace MonoDevelop.Ide
}
if (RequestItemUnload (item)) {
- if (closeItemFiles) {
+ if (closeItemFiles && documentManager != null) {
var projects = item.GetAllItems<Project> ();
- foreach (Document doc in IdeApp.Workbench.Documents.Where (d => d.Project != null && projects.Contains (d.Project)).ToArray ()) {
+ foreach (Document doc in documentManager.Documents.Where (d => d.Owner != null && projects.Contains (d.Owner)).ToArray ()) {
if (!await doc.Close ())
return;
}
@@ -514,8 +657,9 @@ namespace MonoDevelop.Ide
{
var item = GetAllItems<WorkspaceItem> ().FirstOrDefault (w => w.FileName == file.FullPath);
if (item != null) {
- IdeApp.ProjectOperations.CurrentSelectedWorkspaceItem = item;
- IdeApp.Workbench.StatusBar.ShowWarning (GettextCatalog.GetString ("{0} is already opened", item.FileName.FileName));
+ CurrentSelectedWorkspaceItem = item;
+ if (IdeApp.IsInitialized)
+ IdeApp.Workbench.StatusBar.ShowWarning (GettextCatalog.GetString ("{0} is already opened", item.FileName.FileName));
return true;
}
@@ -524,12 +668,14 @@ namespace MonoDevelop.Ide
return false;
}
- var monitor = loadMonitor ?? IdeApp.Workbench.ProgressMonitors.GetProjectLoadProgressMonitor (true);
+ var monitorManager = await Runtime.GetService<ProgressMonitorManager> ();
+ var monitor = loadMonitor ?? monitorManager.GetProjectLoadProgressMonitor (true);
bool reloading = IsReloading;
monitor = monitor.WithCancellationSource (openingItemCancellationSource);
- IdeApp.Workbench.LockGui ();
+ if (IdeApp.IsInitialized)
+ IdeApp.Workbench.LockGui ();
metadata = GetOpenWorkspaceItemMetadata (metadata);
ITimeTracker timer = Counters.OpenWorkspaceItemTimer.BeginTiming (metadata);
@@ -540,22 +686,26 @@ namespace MonoDevelop.Ide
timer.End ();
monitor.Dispose ();
- IdeApp.Workbench.UnlockGui ();
+
+ if (IdeApp.IsInitialized)
+ IdeApp.Workbench.UnlockGui ();
}
}
void ReattachDocumentProjects (IEnumerable<string> closedDocs)
{
- foreach (Document doc in IdeApp.Workbench.Documents) {
- if (doc.Project == null && doc.IsFile) {
- Project p = GetProjectsContainingFile (doc.FileName).FirstOrDefault ();
- if (p != null)
- doc.SetProject (p);
+ if (documentManager != null) {
+ foreach (Document doc in documentManager.Documents) {
+ if (doc.Owner == null && doc.IsFile) {
+ Project p = GetProjectsContainingFile (doc.FileName).FirstOrDefault ();
+ if (p != null)
+ doc.AttachToProject (p);
+ }
}
- }
- if (closedDocs != null) {
- foreach (string doc in closedDocs) {
- IdeApp.Workbench.OpenDocument (doc, null, false);
+ if (closedDocs != null) {
+ foreach (string doc in closedDocs) {
+ documentManager.OpenDocument (new FileOpenInformation (doc, null, false)).Ignore ();
+ }
}
}
}
@@ -588,7 +738,7 @@ namespace MonoDevelop.Ide
}
timer.Trace ("Getting wrapper solution");
- item = await IdeApp.Services.ProjectService.GetWrapperSolution (monitor, file);
+ item = await IdeServices.ProjectService.GetWrapperSolution (monitor, file);
}
if (item == null) {
@@ -599,7 +749,7 @@ namespace MonoDevelop.Ide
}
timer.Trace ("Registering to recent list");
- DesktopService.RecentFiles.AddProject (item.FileName, item.Name);
+ Runtime.PeekService<DesktopService> ()?.RecentFiles.AddProject (item.FileName, item.Name);
} catch (Exception ex) {
LoggingService.LogError ("Load operation failed", ex);
@@ -630,10 +780,10 @@ namespace MonoDevelop.Ide
item.Dispose ();
return false;
}
- if (IdeApp.ProjectOperations.CurrentSelectedWorkspaceItem == null)
- IdeApp.ProjectOperations.CurrentSelectedWorkspaceItem = GetAllSolutions ().FirstOrDefault ();
+ if (CurrentSelectedWorkspaceItem == null)
+ CurrentSelectedWorkspaceItem = GetAllSolutions ().FirstOrDefault ();
- Document.IsInProjectSettingLoadingProcess = true;
+ RoslynDocumentContext.IsInProjectSettingLoadingProcess = true;
try {
if (Items.Count == 1 && loadPreferences) {
timer.Trace ("Restoring workspace preferences");
@@ -649,7 +799,7 @@ namespace MonoDevelop.Ide
UpdateOpenWorkspaceItemMetadata (metadata, item);
} finally {
- Document.IsInProjectSettingLoadingProcess = false;
+ RoslynDocumentContext.IsInProjectSettingLoadingProcess = false;
}
}
return true;
@@ -772,22 +922,6 @@ namespace MonoDevelop.Ide
return item.SaveUserProperties ();
}
- [Obsolete ("FileService will generate events for all workspace files.")]
- public FileStatusTracker GetFileStatusTracker ()
- {
- FileStatusTracker fs = new FileStatusTracker ();
- fs.AddFiles (GetKnownFiles ());
- return fs;
- }
-
- static IEnumerable<FilePath> GetKnownFiles ()
- {
- foreach (WorkspaceItem item in IdeApp.Workspace.Items) {
- foreach (FilePath file in item.GetItemFiles (true))
- yield return file;
- }
- }
-
int reloadingCount;
internal bool IsReloading {
@@ -831,7 +965,8 @@ namespace MonoDevelop.Ide
}
}
else {
- using (ProgressMonitor m = IdeApp.Workbench.ProgressMonitors.GetSaveProgressMonitor (true)) {
+ var monitorManager = await Runtime.GetService<ProgressMonitorManager> ();
+ using (ProgressMonitor m = monitorManager.GetSaveProgressMonitor (true)) {
await item.ParentWorkspace.ReloadItem (m, item);
if (closedDocs != null)
ReattachDocumentProjects (closedDocs);
@@ -870,7 +1005,8 @@ namespace MonoDevelop.Ide
IEnumerable<string> closedDocs = result.Item2;
if (allowReload) {
- using (ProgressMonitor m = IdeApp.Workbench.ProgressMonitors.GetProjectLoadProgressMonitor (true)) {
+ var monitorManager = await Runtime.GetService<ProgressMonitorManager> ();
+ using (ProgressMonitor m = monitorManager.GetProjectLoadProgressMonitor (true)) {
// Root folders never need to reload
await entry.ParentFolder.ReloadItem (m, entry);
if (closedDocs != null)
@@ -945,7 +1081,7 @@ namespace MonoDevelop.Ide
break;
}
if (msg != null) {
- if (!MessageService.Confirm (GettextCatalog.GetString ("The project '{0}' has been modified by an external application. Do you want to reload it?", docs[0].Project.Name), msg, AlertButton.Reload))
+ if (!MessageService.Confirm (GettextCatalog.GetString ("The project '{0}' has been modified by an external application. Do you want to reload it?", docs[0].Owner.Name), msg, AlertButton.Reload))
return Tuple.Create (true, closedDocs);
}
@@ -955,7 +1091,7 @@ namespace MonoDevelop.Ide
if (doc.IsDirty)
hasUnsaved = true;
if (doc.ProjectReloadCapability != ProjectReloadCapability.None)
- doc.SetProject (null);
+ doc.AttachToProject (null);
else {
FilePath file = doc.IsFile ? doc.FileName : FilePath.Null;
EventHandler saved = delegate {
@@ -978,12 +1114,14 @@ namespace MonoDevelop.Ide
return Tuple.Create (true, closedDocs);
}
- internal static List<Document> GetOpenDocuments (Project project, bool modifiedOnly)
+ List<Document> GetOpenDocuments (Project project, bool modifiedOnly)
{
List<Document> docs = new List<Document> ();
- foreach (Document doc in IdeApp.Workbench.Documents) {
- if (doc.Project == project && (!modifiedOnly || doc.IsDirty)) {
- docs.Add (doc);
+ if (documentManager != null) {
+ foreach (Document doc in documentManager.Documents) {
+ if (doc.Owner == project && (!modifiedOnly || doc.IsDirty)) {
+ docs.Add (doc);
+ }
}
}
return docs;
@@ -996,10 +1134,7 @@ namespace MonoDevelop.Ide
internal void NotifyItemAdded (WorkspaceItem item)
{
- MonoDevelop.Ide.TypeSystem.TypeSystemService.Load (item, null).ContinueWith(t => {
- if (t.IsFaulted)
- LoggingService.LogError("Could not load parser database.", t.Exception);
- });
+ LoadWorkspaceTypeSystem (item).Ignore ();
if (Runtime.IsMainThread)
NotifyItemAddedGui (item, IsReloading);
else {
@@ -1024,14 +1159,25 @@ namespace MonoDevelop.Ide
NotifyConfigurationsChanged (null, args);
if (Items.Count == 1 && !reloading) {
- IdeApp.Workbench.CurrentLayout = "Solution";
+ if (IdeApp.IsInitialized)
+ IdeApp.Workbench.CurrentLayout = "Solution";
if (FirstWorkspaceItemOpened != null)
FirstWorkspaceItemOpened (this, args);
}
if (WorkspaceItemOpened != null)
WorkspaceItemOpened (this, args);
}
-
+
+ async Task LoadWorkspaceTypeSystem (WorkspaceItem item)
+ {
+ try {
+ var typeSystem = await serviceProvider.GetService<TypeSystemService> ();
+ await typeSystem.Load (item, null);
+ } catch (Exception ex) {
+ LoggingService.LogError ("Could not load parser database.", ex);
+ };
+ }
+
internal void NotifyItemRemoved (WorkspaceItem item)
{
if (Runtime.IsMainThread)
@@ -1064,11 +1210,18 @@ namespace MonoDevelop.Ide
if (LastWorkspaceItemClosed != null)
LastWorkspaceItemClosed (this, EventArgs.Empty);
}
- MonoDevelop.Ide.TypeSystem.TypeSystemService.Unload (item);
+
+ UnloadWorkspaceTypeSystem (item).Ignore ();
NotifyDescendantItemRemoved (this, args);
}
-
+
+ async Task UnloadWorkspaceTypeSystem (WorkspaceItem item)
+ {
+ var typeSystem = await serviceProvider.GetService<TypeSystemService> ();
+ typeSystem.Unload (item);
+ }
+
void SubscribeSolution (Solution sol)
{
sol.FileAddedToProject += NotifyFileAddedToProject;
@@ -1169,11 +1322,11 @@ namespace MonoDevelop.Ide
{
NotifyItemRemovedFromSolutionRec (sender, args.SolutionItem, args.Solution, args);
}
-
+
void NotifyItemRemovedFromSolutionRec (object sender, SolutionFolderItem e, Solution sol, SolutionItemChangeEventArgs originalArgs)
{
- if (e == IdeApp.ProjectOperations.CurrentSelectedSolutionItem)
- IdeApp.ProjectOperations.CurrentSelectedSolutionItem = null;
+ if (e == CurrentSelectedSolutionItem)
+ CurrentSelectedSolutionItem = null;
if (e is SolutionFolder) {
foreach (SolutionFolderItem ce in ((SolutionFolder)e).Items)
@@ -1243,11 +1396,11 @@ namespace MonoDevelop.Ide
sol.RootFolder.RenameFileInProjects (e.SourceFile, e.TargetFile);
}
}
-
-#endregion
-#region Event declaration
-
+ #endregion
+
+ #region Event declaration
+
/// <summary>
/// Fired when a file is removed from a project.
/// </summary>