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

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/core/MonoDevelop.Ide')
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/CommandManager.cs28
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Control.cs12
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Window.cs3
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFileNodeBuilder.cs67
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/IMonoDevelopHostDocument.cs7
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.MetadataReferenceHandler.cs2
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs208
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService.cs44
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs1
9 files changed, 283 insertions, 89 deletions
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/CommandManager.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/CommandManager.cs
index f2bafbd922..c1be68eb9e 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/CommandManager.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/CommandManager.cs
@@ -2304,10 +2304,18 @@ namespace MonoDevelop.Components.Commands
Window GetActiveWindow (Window win)
{
- Gtk.Window [] wins = Gtk.Window.ListToplevels ();
-
- bool hasFocus = false;
bool lastFocusedExists = lastFocused == null;
+ bool hasFocus = false;
+#if MAC
+ var nsWindow = AppKit.NSApplication.SharedApplication.KeyWindow;
+ hasFocus = nsWindow != null;
+ if (hasFocus) {
+ lastFocusedExists |= lastFocused?.nativeWidget == nsWindow;
+ lastFocused = win = nsWindow;
+ } else {
+#endif
+
+ Gtk.Window [] wins = Gtk.Window.ListToplevels ();
Gtk.Window newFocused = null;
foreach (Gtk.Window w in wins) {
if (w.Visible) {
@@ -2324,18 +2332,9 @@ namespace MonoDevelop.Components.Commands
}
}
+ lastFocused = newFocused;
#if MAC
- if (!hasFocus) {
- var nsWindow = AppKit.NSApplication.SharedApplication.KeyWindow;
- hasFocus = nsWindow != null;
- if (hasFocus) {
- lastFocused = win = nsWindow;
- }
- } else {
- lastFocused = newFocused;
}
-#else
- lastFocused = newFocused;
#endif
UpdateAppFocusStatus (hasFocus, lastFocusedExists);
@@ -2343,8 +2342,7 @@ namespace MonoDevelop.Components.Commands
if (win != null && win.IsRealized) {
RegisterTopWindow (win);
return win;
- }
- else
+ } else
return null;
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Control.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Control.cs
index 842593a939..3a9f8409ed 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Control.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Control.cs
@@ -55,7 +55,7 @@ namespace MonoDevelop.Components
{
throw new NotSupportedException ();
}
-
+
public T GetNativeWidget<T> () where T : class
{
if (nativeWidget == null) {
@@ -92,6 +92,16 @@ namespace MonoDevelop.Components
throw new NotSupportedException ($"Cannot get native widget {typeof (T)}");
}
+ public bool TryGetNativeWidget<T> (out T widget) where T : class
+ {
+ if (nativeWidget is T) {
+ widget = GetNativeWidget<T> ();
+ return true;
+ }
+ widget = null;
+ return false;
+ }
+
void OnGtkDestroyed (object sender, EventArgs args)
{
GC.SuppressFinalize (this);
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Window.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Window.cs
index bd3012bef4..8446f68609 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Window.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Window.cs
@@ -218,8 +218,7 @@ namespace MonoDevelop.Components
{
try {
#if MAC
- var nsWindow = parent.GetNativeWidget<NSWindow> ();
- if (nsWindow != null) {
+ if (parent.TryGetNativeWidget<NSWindow> (out var nsWindow)) {
var myNSWindow = MonoDevelop.Components.Mac.GtkMacInterop.GetNSWindow (window);
myNSWindow.ParentWindow = nsWindow;
} else {
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFileNodeBuilder.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFileNodeBuilder.cs
index 4fe44f4e70..b5d291af29 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFileNodeBuilder.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFileNodeBuilder.cs
@@ -285,35 +285,51 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad
}
string question;
- bool allLinkedFiles = CheckAllLinkedFile (files);
+ bool fileExists = CheckAnyFileExists(files);
- if (allLinkedFiles) {
+ if (CheckAllLinkedFile (files)) {
RemoveFilesFromProject (false, files);
} else {
-
- bool filesExist = CheckAnyFileExists (files);
-
if (hasChildren) {
- if (files.Count == 1)
- question = GettextCatalog.GetString ("Are you sure you want to delete the file {0} and " +
+ if (files.Count == 1) {
+ if (fileExists)
+ question = GettextCatalog.GetString ("Are you sure you want to delete the file {0} and " +
+ "its code-behind children from project {1}?",
+ Path.GetFileName (files [0].Name), files [0].Project.Name);
+ else
+ question = GettextCatalog.GetString ("Are you sure you want to remove the file {0} and " +
"its code-behind children from project {1}?",
Path.GetFileName (files [0].Name), files [0].Project.Name);
- else
- question = GettextCatalog.GetString ("Are you sure you want to delete the selected files and " +
+ } else {
+ if (fileExists)
+ question = GettextCatalog.GetString ("Are you sure you want to delete the selected files and " +
"their code-behind children from the project?");
+ else
+ question = GettextCatalog.GetString ("Are you sure you want to remove the selected files and " +
+ "their code-behind children from the project?");
+ }
} else {
- if (files.Count == 1)
- question = GettextCatalog.GetString ("Are you sure you want to delete file {0} from project {1}?",
+ if (files.Count == 1) {
+ if (fileExists)
+ question = GettextCatalog.GetString ("Are you sure you want to delete file {0} from project {1}?",
Path.GetFileName (files [0].Name), files [0].Project.Name);
- else
- question = GettextCatalog.GetString ("Are you sure you want to delete the selected files from the project?");
+ else
+ question = GettextCatalog.GetString ("Are you sure you want to remove file {0} from project {1}?",
+ Path.GetFileName (files [0].Name), files [0].Project.Name);
+
+ } else {
+ if (fileExists)
+ question = GettextCatalog.GetString ("Are you sure you want to delete the selected files from the project?");
+ else
+ question = GettextCatalog.GetString ("Are you sure you want to remove the selected files from the project?");
+ }
}
-
- var result = MessageService.AskQuestion (question, GetDeleteConfirmationButtons (filesExist));
- if (result != AlertButton.Delete)
- return;
- RemoveFilesFromProject (true, files);
+ var result = MessageService.AskQuestion (question, new [] { AlertButton.Cancel, fileExists ? AlertButton.Delete : AlertButton.Remove });
+ if (result == AlertButton.Cancel)
+ return;
+ else
+ RemoveFilesFromProject (fileExists, files);
}
IdeApp.ProjectOperations.SaveAsync (projects);
@@ -323,18 +339,13 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad
[AllowMultiSelection]
void OnUpdateDeleteMultipleItems (CommandInfo info)
{
+ var files = new List<ProjectFile> ();
foreach (var node in CurrentNodes) {
var pf = (ProjectFile)node.DataItem;
- if (pf.IsLink)
- info.Text = GettextCatalog.GetString ("Remove");
+ files.Add (pf);
}
- }
-
- static AlertButton [] GetDeleteConfirmationButtons (bool includeDelete)
- {
- if (includeDelete)
- return new [] { AlertButton.Cancel, AlertButton.Delete };
- return new [] { AlertButton.Cancel };
+ if (!CheckAnyFileExists(files))
+ info.Text = GettextCatalog.GetString ("Remove");
}
[CommandHandler (ProjectCommands.ExcludeFromProject)]
@@ -379,7 +390,7 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad
// Delete file before removing them from the project to avoid Remove items being added
// if the project is currently being saved in memory or to disk.
- if (delete && !file.IsLink)
+ if (delete && !file.IsLink && File.Exists (file.Name))
FileService.DeleteFile (file.Name);
project.Files.Remove (file);
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/IMonoDevelopHostDocument.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/IMonoDevelopHostDocument.cs
index 0cf42cb198..62cac4ad7c 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/IMonoDevelopHostDocument.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/IMonoDevelopHostDocument.cs
@@ -32,7 +32,12 @@ namespace MonoDevelop.Ide.TypeSystem
textBuffer?.Properties.RemoveProperty (typeof (IMonoDevelopHostDocument));
}
- internal static IMonoDevelopHostDocument FromDocument(Document document)
+ internal static IMonoDevelopHostDocument FromDocument (Document document)
+ {
+ return FromDocument ((TextDocument)document);
+ }
+
+ internal static IMonoDevelopHostDocument FromDocument(TextDocument document)
{
IMonoDevelopHostDocument containedDocument = null;
if (document.TryGetText (out SourceText sourceText)) {
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 30d2903c51..ea3fa26e76 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
@@ -107,6 +107,8 @@ namespace MonoDevelop.Ide.TypeSystem
async Task<bool> AddReferences (AddReferencesData data)
{
try {
+ if (data.Project.ParentSolution == null)
+ return false;
var referencedAssemblies = await data.Project.GetReferencedAssemblies (data.ConfigurationSelector, true).ConfigureAwait (false);
foreach (var file in referencedAssemblies) {
if (file.IsProjectReference) {
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 0032dd5951..da13412e27 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs
@@ -486,7 +486,7 @@ namespace MonoDevelop.Ide.TypeSystem
return await TryLoadSolution (cancellationToken).ConfigureAwait (false);
}
- async Task ReloadProjects (CancellationToken cancellationToken)
+ internal async Task ReloadProjects (CancellationToken cancellationToken)
{
try {
using var cts = CancellationTokenSource.CreateLinkedTokenSource (cancellationToken, src.Token);
@@ -731,9 +731,9 @@ namespace MonoDevelop.Ide.TypeSystem
tryApplyState_documentTextChangedTasks.Add (ApplyDocumentTextChangedCore (id, text));
}
- async Task ApplyDocumentTextChangedCore (DocumentId id, SourceText text)
+ async Task ApplyDocumentTextChangedCore (DocumentId id, SourceText text, bool isAnalyzerConfigFile = false)
{
- var document = GetDocument (id);
+ TextDocument document = isAnalyzerConfigFile ? GetAnalyzerConfigDocument (id) : GetDocument (id);
if (document == null)
return;
@@ -750,12 +750,21 @@ namespace MonoDevelop.Ide.TypeSystem
return;
}
}
- var (projection, filePath) = Projections.Get (document.FilePath);
- var data = TextFileProvider.Instance.GetTextEditorData (filePath, out bool isOpen);
- // Guard against already done changes in linked files.
- // This shouldn't happen but the roslyn merging seems not to be working correctly in all cases :/
- if (document.GetLinkedDocumentIds ().Length > 0 && isOpen && !(text.GetType ().FullName == "Microsoft.CodeAnalysis.Text.ChangedText")) {
- return;
+ Projection projection = null;
+ FilePath filePath;
+ ITextDocument data = null;
+ bool isOpen;
+ if (isAnalyzerConfigFile) {
+ filePath = document.FilePath;
+ data = TextFileProvider.Instance.GetTextEditorData (filePath, out isOpen);
+ } else {
+ (projection, filePath) = Projections.Get (document.FilePath);
+ data = TextFileProvider.Instance.GetTextEditorData (filePath, out isOpen);
+ // Guard against already done changes in linked files.
+ // This shouldn't happen but the roslyn merging seems not to be working correctly in all cases :/
+ if (((Document)document).GetLinkedDocumentIds ().Length > 0 && isOpen && !(text.GetType ().FullName == "Microsoft.CodeAnalysis.Text.ChangedText")) {
+ return;
+ }
}
lock (tryApplyState_documentTextChangedContents) {
@@ -799,20 +808,29 @@ namespace MonoDevelop.Ide.TypeSystem
}
data.Save ();
if (projection != null) {
- await UpdateProjectionsDocuments (document, data);
+ await UpdateProjectionsDocuments ((Document)document, data);
+ } else if (isAnalyzerConfigFile) {
+ OnAnalyzerConfigDocumentTextChanged (id, new MonoDevelopSourceText (data), PreservationMode.PreserveValue);
} else {
OnDocumentTextChanged (id, new MonoDevelopSourceText (data), PreservationMode.PreserveValue);
}
} else {
var formatter = CodeFormatterService.GetFormatter (data.MimeType);
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));
- SyntaxToken? renameTokenOpt = root.GetAnnotatedNodesAndTokens (Microsoft.CodeAnalysis.CodeActions.RenameAnnotation.Kind)
- .Where (s => s.IsToken)
- .Select (s => s.AsToken ())
- .Cast<SyntaxToken?> ()
- .FirstOrDefault ();
+
+ SyntaxNode root = null;
+ SyntaxNode annotatedNode = null;
+ SyntaxToken? renameTokenOpt = null;
+
+ if (!isAnalyzerConfigFile) {
+ root = await projectChanges.NewProject.GetDocument (id).GetSyntaxRootAsync ();
+ annotatedNode = root.DescendantNodesAndSelf ().FirstOrDefault (n => n.HasAnnotation (typeSystemService.InsertionModeAnnotation));
+ renameTokenOpt = root.GetAnnotatedNodesAndTokens (Microsoft.CodeAnalysis.CodeActions.RenameAnnotation.Kind)
+ .Where (s => s.IsToken)
+ .Select (s => s.AsToken ())
+ .Cast<SyntaxToken?> ()
+ .FirstOrDefault ();
+ }
if (documentContext != null) {
var editor = (TextEditor)data;
@@ -936,12 +954,21 @@ namespace MonoDevelop.Ide.TypeSystem
}
if (projection != null) {
- await UpdateProjectionsDocuments (document, data);
+ await UpdateProjectionsDocuments ((Document)document, data);
+ } else if (isAnalyzerConfigFile) {
+ OnAnalyzerConfigDocumentTextChanged (id, new MonoDevelopSourceText (data), PreservationMode.PreserveValue);
} else {
OnDocumentTextChanged (id, new MonoDevelopSourceText (data), PreservationMode.PreserveValue);
}
}
}
+
+ protected override void ApplyAnalyzerConfigDocumentTextChanged (DocumentId id, SourceText text)
+ {
+ lock (projectModifyLock)
+ tryApplyState_documentTextChangedTasks.Add (ApplyDocumentTextChangedCore (id, text, isAnalyzerConfigFile: true));
+ }
+
internal static Func<TextEditor, int, Task<List<InsertionPoint>>> GetInsertionPoints;
internal static Action<TextEditor, DocumentContext, ITextSourceVersion, SyntaxToken?> StartRenameSession;
@@ -992,6 +1019,7 @@ namespace MonoDevelop.Ide.TypeSystem
HashSet<MonoDevelop.Projects.Project> tryApplyState_changedProjects = new HashSet<MonoDevelop.Projects.Project> ();
List<Task> tryApplyState_documentTextChangedTasks = new List<Task> ();
Dictionary<string, SourceText> tryApplyState_documentTextChangedContents = new Dictionary<string, SourceText> ();
+ HashSet<MonoDevelop.Projects.Project> tryApplyState_modifiedProjects = new HashSet<MonoDevelop.Projects.Project> ();
/// <summary>
/// Used by tests to validate that project has been saved.
@@ -1036,17 +1064,36 @@ namespace MonoDevelop.Ide.TypeSystem
tryApplyState_documentTextChangedTasks.Clear ();
tryApplyState_changedProjects.Clear ();
freezeProjectModify = false;
+ if (tryApplyState_modifiedProjects.Count > 0)
+ NotifyProjectsModified ();
FileService.ThawEvents ();
}
}
- }
-
+ }
+
+ void NotifyProjectsModified ()
+ {
+ try {
+ foreach (var project in tryApplyState_modifiedProjects) {
+ // New .editorconfig file added so we need to update the project info.
+ project.NotifyModified ("CoreCompileFiles");
+ }
+ } catch (Exception ex) {
+ LoggingService.LogError ("tryApplyState_modifiedProjects NotifyModifed error", ex);
+ } finally {
+ tryApplyState_modifiedProjects.Clear ();
+ }
+ }
+
public override bool CanApplyChange (ApplyChangesKind feature)
{
switch (feature) {
case ApplyChangesKind.AddDocument:
case ApplyChangesKind.RemoveDocument:
- case ApplyChangesKind.ChangeDocument:
+ case ApplyChangesKind.ChangeDocument:
+ case ApplyChangesKind.AddAnalyzerConfigDocument:
+ case ApplyChangesKind.RemoveAnalyzerConfigDocument:
+ case ApplyChangesKind.ChangeAnalyzerConfigDocument:
//HACK: we don't actually support adding and removing metadata references from project
//however, our MetadataReferenceCache currently depends on (incorrectly) using TryApplyChanges
case ApplyChangesKind.AddMetadataReference:
@@ -1068,24 +1115,88 @@ namespace MonoDevelop.Ide.TypeSystem
protected override void ApplyDocumentAdded (DocumentInfo info, SourceText text)
{
- var id = info.Id;
- MonoDevelop.Projects.Project mdProject = null;
+ var mdProject = GetMonoProject (info);
+
+ var path = DetermineFilePath (info, mdProject, true);
+ // If file is already part of project don't re-add it, example of this is .cshtml
+ if (mdProject?.IsFileInProject (path) == true) {
+ this.OnDocumentAdded (info);
+ return;
+ }
+ info = info.WithFilePath (path).WithTextLoader (new MonoDevelopTextLoader (path));
+
+ FormatFile (text, mdProject, path);
+
+ if (mdProject != null) {
+ var data = ProjectMap.GetData (info.Id.ProjectId);
+ data.DocumentData.Add (info.Id, path);
+ var file = new MonoDevelop.Projects.ProjectFile (path);
+ mdProject.Files.Add (file);
+ tryApplyState_changedProjects.Add (mdProject);
+ }
+ this.OnDocumentAdded (info);
+ }
+
+ MonoDevelop.Projects.Project GetMonoProject (DocumentInfo info)
+ {
+ var id = info.Id;
if (id.ProjectId != null) {
var project = CurrentSolution.GetProject (id.ProjectId);
- mdProject = GetMonoProject (project);
+ var mdProject = GetMonoProject (project);
if (mdProject == null)
- LoggingService.LogWarning ("Couldn't find project for newly generated file {0} (Project {1}).", info.Name, info.Id.ProjectId);
+ LoggingService.LogWarning ("Couldn't find project for document {0} (Project {1}).", info.Name, id.ProjectId);
+ return mdProject;
}
+ return null;
+ }
- var path = DetermineFilePath (info.Id, info.Name, info.FilePath, info.Folders, mdProject?.FileName.ParentDirectory, true);
- // If file is already part of project don't re-add it, example of this is .cshtml
- if (mdProject?.IsFileInProject (path) == true) {
- this.OnDocumentAdded (info);
+ protected override void ApplyAnalyzerConfigDocumentAdded (DocumentInfo info, SourceText text)
+ {
+ var mdProject = GetMonoProject (info);
+
+ var path = DetermineFilePath (info, mdProject, true);
+ // If file is already part of project don't re-add it unless it does not exist.
+ if (mdProject?.IsFileInProject (path) == true && File.Exists (path)) {
+ OnAnalyzerConfigDocumentAdded (info);
return;
}
- info = info.WithFilePath (path).WithTextLoader (new MonoDevelopTextLoader (path));
+ info = info.WithFilePath (path).WithTextLoader (new MonoDevelopTextLoader (path));
+
+ FormatFile (text, mdProject, path);
+ if (mdProject != null) {
+ var data = ProjectMap.GetData (info.Id.ProjectId);
+ data.DocumentData.Add (info.Id, path);
+
+ var file = new MonoDevelop.Projects.ProjectFile (path, MonoDevelop.Projects.BuildAction.None);
+ if (!file.FilePath.IsChildPathOf (mdProject.BaseDirectory)) {
+ // Outside project directory - add it as a solution folder item.
+ var solutionFolder = GetSolutionItemsFolder (mdProject);
+ if (!solutionFolder.Files.Contains (path)) {
+ solutionFolder.Files.Add (path);
+ mdProject.ParentSolution.SaveAsync (new ProgressMonitor ()).Ignore ();
+ }
+ }
+ if (!mdProject.IsFileInProject (file.FilePath)) {
+ mdProject.Files.Add (file);
+ }
+ // Need to trigger Project.Modified event after TryApp is run so project is reloaded by the type system
+ // service. Adding the file to the Files collection will not trigger the modified event since
+ // the build action is not EditorConfigFiles. Also this event would be ignored anyway during TryApply.
+ // Also handles if the link already existed. Need to refresh all projects since the document added
+ // method will only be called once.
+ foreach (var affectedProject in mdProject.ParentSolution.GetAllProjects ()) {
+ tryApplyState_modifiedProjects.Add (affectedProject);
+ }
+ tryApplyState_changedProjects.Add (mdProject);
+ }
+
+ OnAnalyzerConfigDocumentAdded (info);
+ }
+
+ void FormatFile (SourceText text, MonoDevelop.Projects.Project mdProject, string path)
+ {
string formattedText;
var formatter = CodeFormatterService.GetFormatter (desktopService.GetMimeTypeForUri (path));
if (formatter != null && mdProject != null) {
@@ -1100,16 +1211,22 @@ namespace MonoDevelop.Ide.TypeSystem
} catch (Exception e) {
LoggingService.LogError ("Exception while saving file to " + path, e);
}
+ }
- if (mdProject != null) {
- var data = ProjectMap.GetData (id.ProjectId);
- data.DocumentData.Add (info.Id, path);
- var file = new MonoDevelop.Projects.ProjectFile (path);
- mdProject.Files.Add (file);
- tryApplyState_changedProjects.Add (mdProject);
+ MonoDevelop.Projects.SolutionFolder GetSolutionItemsFolder (MonoDevelop.Projects.Project project)
+ {
+ string name = GettextCatalog.GetString ("Solution Items");
+ var folder = project.ParentSolution.RootFolder.Items
+ .OfType <MonoDevelop.Projects.SolutionFolder> ()
+ .FirstOrDefault (item => StringComparer.CurrentCultureIgnoreCase.Equals (item.Name, name));
+ if (folder != null) {
+ return folder;
}
- this.OnDocumentAdded (info);
+ folder = new MonoDevelop.Projects.SolutionFolder ();
+ folder.Name = name;
+ project.ParentSolution.RootFolder.Items.Add (folder);
+ return folder;
}
protected override void ApplyDocumentRemoved (DocumentId documentId)
@@ -1139,16 +1256,23 @@ namespace MonoDevelop.Ide.TypeSystem
tryApplyState_changedProjects.Add (mdProject);
}
- string DetermineFilePath (DocumentId id, string name, string filePath, IReadOnlyList<string> docFolders, string defaultFolder, bool createDirectory = false)
+ protected override void ApplyAnalyzerConfigDocumentRemoved (DocumentId documentId)
+ {
+ LoggingService.LogInfo ("ApplyAnalyzerConfigDocumentRemoved {0}", documentId);
+ base.ApplyAnalyzerConfigDocumentRemoved (documentId);
+ }
+
+ string DetermineFilePath (DocumentInfo info, MonoDevelop.Projects.Project mdProject, bool createDirectory = false)
{
- var path = filePath;
+ var path = info.FilePath;
if (string.IsNullOrEmpty (path)) {
- var monoProject = GetMonoProject (id.ProjectId);
+ var monoProject = GetMonoProject (info.Id.ProjectId);
// If the first namespace name matches the name of the project, then we don't want to
// generate a folder for that. The project is implicitly a folder with that name.
IEnumerable<string> folders;
+ var docFolders = info.Folders;
if (docFolders != null && monoProject != null && docFolders.FirstOrDefault () == monoProject.Name) {
folders = docFolders.Skip (1);
} else {
@@ -1163,9 +1287,9 @@ namespace MonoDevelop.Ide.TypeSystem
} catch (Exception e) {
LoggingService.LogError ("Error while creating directory for a new file : " + baseDirectory, e);
}
- path = Path.Combine (baseDirectory, name);
+ path = Path.Combine (baseDirectory, info.Name);
} else {
- path = Path.Combine (defaultFolder, name);
+ path = Path.Combine (mdProject?.FileName.ParentDirectory, info.Name);
}
}
return path;
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 334d8b88cc..6a7abb20e1 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService.cs
@@ -116,6 +116,7 @@ namespace MonoDevelop.Ide.TypeSystem
}
FileService.FileChanged += FileService_FileChanged;
+ FileService.FileRemoved += FileService_FileRemoved;
desktopService = await serviceProvider.GetService<DesktopService> ();
@@ -125,6 +126,7 @@ namespace MonoDevelop.Ide.TypeSystem
protected override Task OnDispose ()
{
FileService.FileChanged -= FileService_FileChanged;
+ FileService.FileRemoved -= FileService_FileRemoved;
if (rootWorkspace != null)
rootWorkspace.ActiveConfigurationChanged -= HandleActiveConfigurationChanged;
FinalizeTrackedProjectHandling ();
@@ -173,6 +175,48 @@ namespace MonoDevelop.Ide.TypeSystem
});
}
+ void FileService_FileRemoved (object sender, FileEventArgs e)
+ {
+ try {
+ foreach (var file in e) {
+ if (file.FileName.FileName == ".editorconfig") {
+ OnEditorConfigDocumentRemoved (file.FileName);
+ }
+ }
+ } catch (Exception ex) {
+ LoggingService.LogError ("TypeSystemService.FileService_FileRemoved error", ex);
+ }
+ }
+
+ void OnEditorConfigDocumentRemoved (FilePath fileName)
+ {
+ foreach (var workspace in AllWorkspaces) {
+ var mdWorkspace = workspace as MonoDevelopWorkspace;
+ if (mdWorkspace == null)
+ continue;
+
+ var projects = new HashSet<Project> ();
+ foreach (var mdProject in mdWorkspace.MonoDevelopSolution.GetAllProjects ()) {
+ foreach (var projectId in mdWorkspace.GetProjectIds (mdProject)) {
+ var docId = mdWorkspace.GetDocumentId (projectId, fileName);
+ if (docId != null) {
+ projects.Add (mdProject);
+ try {
+ mdWorkspace.OnAnalyzerConfigDocumentRemoved (docId);
+ } catch (Exception ex) {
+ // Ignore error so other projects can be updated.
+ LoggingService.LogError ("OnAnalyzerConfigDocumentRemoved error", ex);
+ }
+ }
+ }
+ }
+
+ foreach (var mdProject in projects) {
+ mdProject.NotifyModified ("CoreCompileFiles");
+ }
+ }
+ }
+
internal async Task<MonoDevelopWorkspace> CreateEmptyWorkspace ()
{
var ws = new MonoDevelopWorkspace (compositionManager.HostServices, null, this);
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs
index 190e9db83b..4b49c09c4d 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs
@@ -426,6 +426,7 @@ namespace MonoDevelop.Ide
try {
await entry.SaveAsync (monitor);
monitor.ReportSuccess (GettextCatalog.GetString ("Project saved."));
+ } catch (OperationCanceledException) {
} catch (Exception ex) {
monitor.ReportError (GettextCatalog.GetString ("Save failed."), ex);
} finally {