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:
authorMarius Ungureanu <teromario@yahoo.com>2018-02-23 17:37:14 +0300
committerGitHub <noreply@github.com>2018-02-23 17:37:14 +0300
commit1ba94df4b5359d08c0c0ff7adccebf67778173fc (patch)
tree89be95db2bafc6ef1bb40f1009b80875d0cb09e3 /main/src
parent5fa872b257473c4bc4e30e0e13af5aa8596c5d53 (diff)
[Refactoring] Switch to Roslyn CodeFixService (#3636)
* [Refactoring] Switch to Roslyn CodeFixService * Flush some fixes and cleanups * [Ide] More dead code removal * [Refactoring] Delete dead code, migrate options to the diagnostic workspace provider Also fix refactorings taking into account options UI. * Fix a NRE * [Refactoring] Fix code issues still appearing for suppressed diagnostics * This file was not committed * [Refactoring] Some updates to prevent some possible NREs and uniformization * [Ide] Re-enable new error backend for C# and add test for compiler diagnostics fixes
Diffstat (limited to 'main/src')
-rw-r--r--main/src/addins/CSharpBinding/MonoDevelop.CSharp.Parser/CSharpParsedDocument.cs4
-rw-r--r--main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Refactoring/PackageCodeDiagnosticProvider.cs206
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/AnalysisCommands.cs8
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/MonoDevelopWorkspaceDiagnosticAnalyzerProviderService.OptionsTable.cs114
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/MonoDevelopWorkspaceDiagnosticAnalyzerProviderService.cs6
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeActionContainer.cs72
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeActionEditorExtension.cs85
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeActionPanelWidget.cs7
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeFixMenuService.cs240
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeRefactoringService.cs111
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/ValidCodeAction.cs47
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/ValidCodeDiagnosticAction.cs62
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/AnalyzersFromAssembly.cs148
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/BuiltInCodeDiagnosticProvider.cs112
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticDescriptor.cs5
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticFixDescriptor.cs89
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticProvider.cs45
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticRunner.cs145
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeIssuePanelWidget.cs11
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring.addin.xml2
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring.csproj8
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/AnalyzeWholeSolutionHandler.cs13
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs4
23 files changed, 375 insertions, 1169 deletions
diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Parser/CSharpParsedDocument.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Parser/CSharpParsedDocument.cs
index 6be03cc78c..faff647bc7 100644
--- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Parser/CSharpParsedDocument.cs
+++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Parser/CSharpParsedDocument.cs
@@ -517,8 +517,8 @@ namespace MonoDevelop.CSharp.Parser
static readonly IReadOnlyList<Error> emptyErrors = Array.Empty<Error> ();
public override async Task<IReadOnlyList<Error>> GetErrorsAsync (CancellationToken cancellationToken = default(CancellationToken))
{
- //if (Ide.IdeApp.Preferences.EnableSourceAnalysis)
- // return emptyErrors;
+ if (Ide.IdeApp.Preferences.EnableSourceAnalysis)
+ return emptyErrors;
var model = GetAst<SemanticModel> ();
if (model == null)
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Refactoring/PackageCodeDiagnosticProvider.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Refactoring/PackageCodeDiagnosticProvider.cs
index 8b87157e1a..6c0b36215b 100644
--- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Refactoring/PackageCodeDiagnosticProvider.cs
+++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Refactoring/PackageCodeDiagnosticProvider.cs
@@ -1,113 +1,113 @@
-//
-// PackageCodeDiagnosticProvider.cs
-//
-// Author:
-// Mike Krüger <mkrueger@xamarin.com>
-//
-// Copyright (c) 2015 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.
+////
+//// PackageCodeDiagnosticProvider.cs
+////
+//// Author:
+//// Mike Krüger <mkrueger@xamarin.com>
+////
+//// Copyright (c) 2015 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 MonoDevelop.CodeIssues;
-using MonoDevelop.Core;
-using MonoDevelop.Projects;
-using System.Linq;
-using System.IO;
-using System.Collections.Generic;
-using System.Reflection;
-using System.Threading;
-using System.Threading.Tasks;
-using MonoDevelop.Ide.Editor;
-using MonoDevelop.Ide.TypeSystem;
-using MonoDevelop.Ide;
+//using System;
+//using MonoDevelop.CodeIssues;
+//using MonoDevelop.Core;
+//using MonoDevelop.Projects;
+//using System.Linq;
+//using System.IO;
+//using System.Collections.Generic;
+//using System.Reflection;
+//using System.Threading;
+//using System.Threading.Tasks;
+//using MonoDevelop.Ide.Editor;
+//using MonoDevelop.Ide.TypeSystem;
+//using MonoDevelop.Ide;
-namespace MonoDevelop.PackageManagement.Refactoring
-{
- sealed class PackageCodeDiagnosticProvider : CodeDiagnosticProvider
- {
- static readonly Dictionary<Project, AnalyzersFromAssembly> diagnosticCache = new Dictionary<Project, AnalyzersFromAssembly> ();
+//namespace MonoDevelop.PackageManagement.Refactoring
+//{
+// sealed class PackageCodeDiagnosticProvider : CodeDiagnosticProvider
+// {
+// static readonly Dictionary<Project, AnalyzersFromAssembly> diagnosticCache = new Dictionary<Project, AnalyzersFromAssembly> ();
- static PackageCodeDiagnosticProvider ()
- {
- IdeApp.Workspace.SolutionUnloaded += delegate {
- diagnosticCache.Clear ();
- };
- IdeApp.Workspace.ActiveConfigurationChanged += delegate {
- diagnosticCache.Clear ();
- };
- }
+// static PackageCodeDiagnosticProvider ()
+// {
+// IdeApp.Workspace.SolutionUnloaded += delegate {
+// diagnosticCache.Clear ();
+// };
+// IdeApp.Workspace.ActiveConfigurationChanged += delegate {
+// diagnosticCache.Clear ();
+// };
+// }
- public async override Task<IEnumerable<CodeDiagnosticFixDescriptor>> GetCodeFixDescriptorsAsync (DocumentContext document, string language, CancellationToken cancellationToken = default(CancellationToken))
- {
- var diags = await GetProjectDiagnosticsAsync (document.Project, language, cancellationToken).ConfigureAwait (false);
- return diags.Fixes;
- }
+// public async override Task<IEnumerable<CodeDiagnosticFixDescriptor>> GetCodeFixDescriptorsAsync (DocumentContext document, string language, CancellationToken cancellationToken = default(CancellationToken))
+// {
+// var diags = await GetProjectDiagnosticsAsync (document.Project, language, cancellationToken).ConfigureAwait (false);
+// return diags.Fixes;
+// }
- public async override Task<IEnumerable<CodeDiagnosticDescriptor>> GetCodeDiagnosticDescriptorsAsync (DocumentContext document, string language, CancellationToken cancellationToken = default(CancellationToken))
- {
- var diags = await GetProjectDiagnosticsAsync (document.Project, language, cancellationToken).ConfigureAwait (false);
- return diags.Analyzers;
- }
+// public async override Task<IEnumerable<CodeDiagnosticDescriptor>> GetCodeDiagnosticDescriptorsAsync (DocumentContext document, string language, CancellationToken cancellationToken = default(CancellationToken))
+// {
+// var diags = await GetProjectDiagnosticsAsync (document.Project, language, cancellationToken).ConfigureAwait (false);
+// return diags.Analyzers;
+// }
- public async override Task<IEnumerable<MonoDevelop.CodeActions.CodeRefactoringDescriptor>> GetCodeRefactoringDescriptorsAsync (DocumentContext document, string language, CancellationToken cancellationToken)
- {
- var diags = await GetProjectDiagnosticsAsync (document.Project, language, cancellationToken).ConfigureAwait (false);
- return diags.Refactorings;
- }
+// public async override Task<IEnumerable<MonoDevelop.CodeActions.CodeRefactoringDescriptor>> GetCodeRefactoringDescriptorsAsync (DocumentContext document, string language, CancellationToken cancellationToken)
+// {
+// var diags = await GetProjectDiagnosticsAsync (document.Project, language, cancellationToken).ConfigureAwait (false);
+// return diags.Refactorings;
+// }
- static async Task<AnalyzersFromAssembly> GetProjectDiagnosticsAsync (Project project, string language, CancellationToken cancellationToken)
- {
- if (project == null)
- return AnalyzersFromAssembly.Empty;
- AnalyzersFromAssembly result;
- if (diagnosticCache.TryGetValue(project, out result))
- return result;
+// static async Task<AnalyzersFromAssembly> GetProjectDiagnosticsAsync (Project project, string language, CancellationToken cancellationToken)
+// {
+// if (project == null)
+// return AnalyzersFromAssembly.Empty;
+// AnalyzersFromAssembly result;
+// if (diagnosticCache.TryGetValue(project, out result))
+// return result;
- result = new AnalyzersFromAssembly ();
+// result = new AnalyzersFromAssembly ();
- var dotNetProject = project as DotNetProject;
- if (dotNetProject != null) {
- var proxy = new DotNetProjectProxy (dotNetProject);
- if (proxy.HasPackages ()) {
- var packagesPath = await GetPackagesPath (proxy);
- foreach (var file in Directory.EnumerateFiles (packagesPath, "*.dll", SearchOption.AllDirectories)) {
- cancellationToken.ThrowIfCancellationRequested ();
- try {
- var asm = Assembly.LoadFrom (file);
- result.AddAssembly (asm);
- } catch (Exception) {
- }
- }
- }
- }
- diagnosticCache[project] = result;
- return result;
- }
+// var dotNetProject = project as DotNetProject;
+// if (dotNetProject != null) {
+// var proxy = new DotNetProjectProxy (dotNetProject);
+// if (proxy.HasPackages ()) {
+// var packagesPath = await GetPackagesPath (proxy);
+// foreach (var file in Directory.EnumerateFiles (packagesPath, "*.dll", SearchOption.AllDirectories)) {
+// cancellationToken.ThrowIfCancellationRequested ();
+// try {
+// var asm = Assembly.LoadFrom (file);
+// result.AddAssembly (asm);
+// } catch (Exception) {
+// }
+// }
+// }
+// }
+// diagnosticCache[project] = result;
+// return result;
+// }
- static Task<FilePath> GetPackagesPath (IDotNetProject project)
- {
- return Runtime.RunInMainThread (() => {
- var solutionManager = PackageManagementServices.Workspace.GetSolutionManager (project.ParentSolution);
- var nugetProject = solutionManager.GetNuGetProject (project);
- return nugetProject.GetPackagesFolderPath (solutionManager);
- });
- }
- }
-} \ No newline at end of file
+// static Task<FilePath> GetPackagesPath (IDotNetProject project)
+// {
+// return Runtime.RunInMainThread (() => {
+// var solutionManager = PackageManagementServices.Workspace.GetSolutionManager (project.ParentSolution);
+// var nugetProject = solutionManager.GetNuGetProject (project);
+// return nugetProject.GetPackagesFolderPath (solutionManager);
+// });
+// }
+// }
+//} \ No newline at end of file
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/AnalysisCommands.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/AnalysisCommands.cs
index 348cc789a9..3abed75c3d 100644
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/AnalysisCommands.cs
+++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/AnalysisCommands.cs
@@ -44,6 +44,9 @@ namespace MonoDevelop.AnalysisCore
class ExportRulesHandler : CommandHandler
{
+ static MonoDevelopWorkspaceDiagnosticAnalyzerProviderService.OptionsTable options =
+ ((MonoDevelopWorkspaceDiagnosticAnalyzerProviderService)Ide.Composition.CompositionManager.GetExportedValue<IWorkspaceDiagnosticAnalyzerProviderService> ()).Options;
+
protected override void Run ()
{
var lang = "text/x-csharp";
@@ -55,7 +58,8 @@ namespace MonoDevelop.AnalysisCore
Dictionary<CodeDiagnosticDescriptor, DiagnosticSeverity?> severities = new Dictionary<CodeDiagnosticDescriptor, DiagnosticSeverity?> ();
- foreach (var node in BuiltInCodeDiagnosticProvider.GetBuiltInCodeDiagnosticDescriptorsAsync (CodeRefactoringService.MimeTypeToLanguage(lang), true).Result) {
+ var language = CodeRefactoringService.MimeTypeToLanguage (lang);
+ foreach (var node in options.AllDiagnostics.Where (x => x.Languages.Contains (language))) {
severities [node] = node.DiagnosticSeverity;
// if (node.GetProvider ().SupportedDiagnostics.Length > 1) {
// foreach (var subIssue in node.GetProvider ().SupportedDiagnostics) {
@@ -90,7 +94,7 @@ namespace MonoDevelop.AnalysisCore
}
var providerStates = new Dictionary<CodeRefactoringDescriptor, bool> ();
- foreach (var node in BuiltInCodeDiagnosticProvider.GetBuiltInCodeRefactoringDescriptorsAsync (CodeRefactoringService.MimeTypeToLanguage(lang), true).Result) {
+ foreach (var node in options.AllRefactorings.Where (x => x.Language.Contains (language))) {
providerStates [node] = node.IsEnabled;
}
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/MonoDevelopWorkspaceDiagnosticAnalyzerProviderService.OptionsTable.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/MonoDevelopWorkspaceDiagnosticAnalyzerProviderService.OptionsTable.cs
new file mode 100644
index 0000000000..667665a194
--- /dev/null
+++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/MonoDevelopWorkspaceDiagnosticAnalyzerProviderService.OptionsTable.cs
@@ -0,0 +1,114 @@
+//
+// MonoDevelopWorkspaceDiagnosticAnalyzerProviderService.OptionsTable.cs
+//
+// Author:
+// Marius Ungureanu <maungu@microsoft.com>
+//
+// Copyright (c) 2018
+//
+// 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 System.Reflection;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CodeFixes;
+using Microsoft.CodeAnalysis.CodeRefactorings;
+using Microsoft.CodeAnalysis.Diagnostics;
+using MonoDevelop.AnalysisCore.Gui;
+using MonoDevelop.CodeActions;
+using MonoDevelop.CodeIssues;
+using MonoDevelop.Core;
+
+namespace MonoDevelop.AnalysisCore
+{
+ partial class MonoDevelopWorkspaceDiagnosticAnalyzerProviderService
+ {
+ internal class OptionsTable
+ {
+ Dictionary<string, CodeDiagnosticDescriptor> diagnosticTable = new Dictionary<string, CodeDiagnosticDescriptor> ();
+ Dictionary<Type, CodeRefactoringDescriptor> refactoringTable = new Dictionary<Type, CodeRefactoringDescriptor> ();
+ List<CodeDiagnosticDescriptor> diagnostics = new List<CodeDiagnosticDescriptor> ();
+
+ public IEnumerable<CodeDiagnosticDescriptor> AllDiagnostics => diagnostics;
+ public IEnumerable<CodeRefactoringDescriptor> AllRefactorings => refactoringTable.Values;
+
+ public bool TryGetDiagnosticDescriptor (string id, out CodeDiagnosticDescriptor desc)
+ {
+ return diagnosticTable.TryGetValue (id, out desc);
+ }
+
+ public bool TryGetRefactoringDescriptor (Type t, out CodeRefactoringDescriptor desc)
+ {
+ return refactoringTable.TryGetValue (t, out desc);
+ }
+
+ // Needed to support configuration of diagnostics and code fixes/refactorings.
+ public void ProcessAssembly (Assembly asm)
+ {
+ try {
+ foreach (var type in asm.GetTypes ()) {
+
+ //HACK: Workaround for missing UI
+ if (type == typeof (Microsoft.CodeAnalysis.GenerateOverrides.GenerateOverridesCodeRefactoringProvider))
+ continue;
+ if (type == typeof (Microsoft.CodeAnalysis.AddMissingReference.AbstractAddMissingReferenceCodeFixProvider))
+ continue;
+
+ var analyzerAttr = (DiagnosticAnalyzerAttribute)type.GetCustomAttributes (typeof (DiagnosticAnalyzerAttribute), false).FirstOrDefault ();
+ if (analyzerAttr != null) {
+ try {
+ var analyzer = (DiagnosticAnalyzer)Activator.CreateInstance (type);
+ var descriptor = new CodeDiagnosticDescriptor (analyzerAttr.Languages, type);
+
+ foreach (var diag in analyzer.SupportedDiagnostics) {
+ if (!IsDiagnosticSupported (diag))
+ continue;
+
+ diagnosticTable[diag.Id] = descriptor;
+ }
+ diagnostics.Add (descriptor);
+ } catch (Exception e) {
+ LoggingService.LogError ($"error while adding diagnostic analyzer {type} from assembly {asm.FullName}", e);
+ }
+ }
+
+ var exportAttr = type.GetCustomAttributes (typeof (ExportCodeRefactoringProviderAttribute), false).FirstOrDefault () as ExportCodeRefactoringProviderAttribute;
+ if (exportAttr != null) {
+ refactoringTable[type] = new CodeRefactoringDescriptor (type, exportAttr);
+ }
+ }
+ } catch (ReflectionTypeLoadException ex) {
+ foreach (var subException in ex.LoaderExceptions) {
+ LoggingService.LogError ("Error while loading diagnostics in " + asm.FullName, subException);
+ }
+ throw;
+ }
+ }
+
+ static bool IsDiagnosticSupported (DiagnosticDescriptor diag)
+ {
+ //filter out E&C analyzers as we don't support E&C
+ return !diag.CustomTags.Contains (WellKnownDiagnosticTags.EditAndContinue);
+ }
+ }
+ }
+}
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/MonoDevelopWorkspaceDiagnosticAnalyzerProviderService.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/MonoDevelopWorkspaceDiagnosticAnalyzerProviderService.cs
index cddacc5754..5f3184e237 100644
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/MonoDevelopWorkspaceDiagnosticAnalyzerProviderService.cs
+++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/MonoDevelopWorkspaceDiagnosticAnalyzerProviderService.cs
@@ -39,10 +39,12 @@ namespace MonoDevelop.AnalysisCore
[Export(typeof(IWorkspaceDiagnosticAnalyzerProviderService))]
partial class MonoDevelopWorkspaceDiagnosticAnalyzerProviderService : IWorkspaceDiagnosticAnalyzerProviderService
{
+ static readonly AnalyzerAssemblyLoader analyzerAssemblyLoader = new AnalyzerAssemblyLoader ();
readonly static string diagnosticAnalyzerAssembly = typeof (DiagnosticAnalyzerAttribute).Assembly.GetName ().Name;
+
const bool ClrHeapEnabled = false;
- static readonly AnalyzerAssemblyLoader analyzerAssemblyLoader = new AnalyzerAssemblyLoader ();
+ internal OptionsTable Options = new OptionsTable ();
readonly ImmutableArray<HostDiagnosticAnalyzerPackage> hostDiagnosticAnalyzerInfo;
const string extensionPath = "/MonoDevelop/Refactoring/AnalyzerAssemblies";
@@ -50,6 +52,7 @@ namespace MonoDevelop.AnalysisCore
public MonoDevelopWorkspaceDiagnosticAnalyzerProviderService ()
{
LoadAnalyzerAssemblies ();
+ RefactoringEssentials.NRefactory6Host.GetLocalizedString = GettextCatalog.GetString;
hostDiagnosticAnalyzerInfo = CreateHostDiagnosticAnalyzerPackages ();
}
@@ -96,6 +99,7 @@ namespace MonoDevelop.AnalysisCore
// Figure out a way to disable E&C analyzers.
assemblies.Add (asm.Location);
+ Options.ProcessAssembly (asm);
} catch (Exception e) {
LoggingService.LogError ("Error while loading diagnostics in " + asm.FullName, e);
}
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeActionContainer.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeActionContainer.cs
index f8522866e1..28fec6bcef 100644
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeActionContainer.cs
+++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeActionContainer.cs
@@ -24,96 +24,50 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-using System.Collections.Generic;
-using Microsoft.CodeAnalysis.CodeActions;
using System;
-using MonoDevelop.CodeIssues;
using System.Linq;
+using System.Collections.Generic;
using Microsoft.CodeAnalysis;
-using System.Collections;
+using Microsoft.CodeAnalysis.CodeFixes;
+using Microsoft.CodeAnalysis.CodeRefactorings;
+using System.Collections.Immutable;
namespace MonoDevelop.CodeActions
{
class CodeActionContainer
{
- public static readonly CodeActionContainer Empty = new CodeActionContainer();
+ public static readonly CodeActionContainer Empty = new CodeActionContainer(ImmutableArray<CodeFixCollection>.Empty, ImmutableArray<CodeRefactoring>.Empty);
public bool IsEmpty {
get {
- return CodeFixActions.Count + DiagnosticsAtCaret.Count + CodeRefactoringActions.Count == 0;
+ return CodeFixActions.Length + CodeRefactoringActions.Length == 0;
}
}
- IReadOnlyList<ValidCodeDiagnosticAction> codeFixActions;
- public IReadOnlyList<ValidCodeDiagnosticAction> CodeFixActions {
+ ImmutableArray<CodeFixCollection> codeFixActions;
+ public ImmutableArray<CodeFixCollection> CodeFixActions {
get {
- return codeFixActions ?? new ValidCodeDiagnosticAction[0];
+ return codeFixActions;
}
private set {
codeFixActions = value;
}
}
- IReadOnlyList<ValidCodeAction> codeRefactoringActions;
-
- public IReadOnlyList<ValidCodeAction> CodeRefactoringActions {
+ ImmutableArray<CodeRefactoring> codeRefactoringActions;
+ public ImmutableArray<CodeRefactoring> CodeRefactoringActions {
get {
- return codeRefactoringActions ?? new ValidCodeAction[0];
+ return codeRefactoringActions;
}
private set {
codeRefactoringActions = value;
}
}
- public IEnumerable<ValidCodeAction> AllValidCodeActions {
- get {
- return CodeRefactoringActions.Concat (CodeFixActions);
- }
- }
-
- IReadOnlyList<Diagnostic> diagnosticsAtCaret;
- public IReadOnlyList<Diagnostic> DiagnosticsAtCaret {
- get {
- return diagnosticsAtCaret ?? new Diagnostic[0];
- }
- private set {
- diagnosticsAtCaret = value.Distinct (new DiagnosticComparer()).ToList ();
- }
- }
-
- class DiagnosticComparer : IEqualityComparer<Diagnostic>
- {
- bool IEqualityComparer<Diagnostic>.Equals (Diagnostic x, Diagnostic y)
- {
- if (x.Id != null && y.Id != null)
- return x.Id == y.Id;
- return x.Equals (y);
- }
-
- int IEqualityComparer<Diagnostic>.GetHashCode (Diagnostic obj)
- {
- return obj.Id != null ? obj.Id.GetHashCode () : obj.GetHashCode ();
- }
- }
-
- CodeActionContainer ()
- {
- CodeFixActions = new List<ValidCodeDiagnosticAction> ();
- CodeRefactoringActions = new List<ValidCodeAction> ();
- DiagnosticsAtCaret = new List<Diagnostic> ();
- }
-
- internal CodeActionContainer (List<ValidCodeDiagnosticAction> codeDiagnosticActions, List<ValidCodeAction> codeRefactoringActions, List<Diagnostic> diagnosticsAtCaret)
+ internal CodeActionContainer (ImmutableArray<CodeFixCollection> codeDiagnosticActions, ImmutableArray<CodeRefactoring> codeRefactoringActions)
{
- if (codeDiagnosticActions == null)
- throw new ArgumentNullException ("codeDiagnosticActions");
- if (codeRefactoringActions == null)
- throw new ArgumentNullException ("codeRefactoringActions");
- if (diagnosticsAtCaret == null)
- throw new ArgumentNullException ("diagnosticsAtCaret");
CodeFixActions = codeDiagnosticActions;
CodeRefactoringActions = codeRefactoringActions;
- DiagnosticsAtCaret = diagnosticsAtCaret;
}
}
} \ No newline at end of file
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeActionEditorExtension.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeActionEditorExtension.cs
index 941aba52af..e8fa0110be 100644
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeActionEditorExtension.cs
+++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeActionEditorExtension.cs
@@ -35,6 +35,7 @@ using System.Threading.Tasks;
using Gtk;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeFixes;
+using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.Formatting;
using Microsoft.CodeAnalysis.Text;
using MonoDevelop.AnalysisCore;
@@ -100,8 +101,6 @@ namespace MonoDevelop.CodeActions
Task<CodeActionContainer> smartTagTask;
CancellationTokenSource quickFixCancellationTokenSource = new CancellationTokenSource ();
- List<CodeDiagnosticFixDescriptor> codeFixes;
-
void HandleCaretPositionChanged (object sender, EventArgs e)
{
if (Editor.IsInAtomicUndo)
@@ -110,8 +109,8 @@ namespace MonoDevelop.CodeActions
if (AnalysisOptions.EnableFancyFeatures && DocumentContext.ParsedDocument != null) {
if (HasCurrentFixes) {
var curOffset = Editor.CaretOffset;
- foreach (var fix in smartTagTask.Result.AllValidCodeActions) {
- if (!fix.ValidSegment.Contains (curOffset)) {
+ foreach (var fix in smartTagTask.Result.CodeFixActions) {
+ if (!fix.TextSpan.Contains (curOffset)) {
RemoveWidget ();
break;
}
@@ -124,6 +123,8 @@ namespace MonoDevelop.CodeActions
}
}
+ static ICodeFixService codeFixService = Ide.Composition.CompositionManager.GetExportedValue<ICodeFixService> ();
+ static ICodeRefactoringService codeRefactoringService = Ide.Composition.CompositionManager.GetExportedValue<ICodeRefactoringService> ();
internal Task<CodeActionContainer> GetCurrentFixesAsync (CancellationToken cancellationToken)
{
var loc = Editor.CaretOffset;
@@ -132,80 +133,19 @@ namespace MonoDevelop.CodeActions
return Task.FromResult (CodeActionContainer.Empty);
}
TextSpan span;
-
if (Editor.IsSomethingSelected) {
var selectionRange = Editor.SelectionRange;
span = selectionRange.Offset >= 0 ? TextSpan.FromBounds (selectionRange.Offset, selectionRange.EndOffset) : TextSpan.FromBounds (loc, loc);
} else {
span = TextSpan.FromBounds (loc, loc);
}
- var rExt = Editor.GetContent<ResultsEditorExtension> ();
- var errorList = Editor
- .GetTextSegmentMarkersAt (Editor.CaretOffset)
- .OfType<IErrorMarker> ()
- .Where (rm => !string.IsNullOrEmpty (rm.Error.Id)).ToList ();
+
return Task.Run (async delegate {
try {
- var result = await CodeDiagnosticRunner.Check (new AnalysisDocument (Editor, DocumentContext), cancellationToken).ConfigureAwait (false);
- var diagnosticsAtCaret = result.OfType<DiagnosticResult> ().Where (d => d.Region.Contains (loc)).Select (d => d.Diagnostic).ToList ();
+ var fixes = await codeFixService.GetFixesAsync (ad, span, true, cancellationToken);
+ var refactorings = await codeRefactoringService.GetRefactoringsAsync (ad, span, cancellationToken);
- var codeIssueFixes = new List<ValidCodeDiagnosticAction> ();
- var diagnosticIds = diagnosticsAtCaret.Select (diagnostic => diagnostic.Id).Concat (errorList.Select (rm => rm.Error.Id)).ToList ();
- if (codeFixes == null) {
- codeFixes = (await CodeRefactoringService.GetCodeFixesAsync (DocumentContext, CodeRefactoringService.MimeTypeToLanguage (Editor.MimeType), cancellationToken).ConfigureAwait (false)).ToList ();
- }
- var root = await ad.GetSyntaxRootAsync (cancellationToken).ConfigureAwait (false);
- foreach (var cfp in codeFixes) {
- if (cancellationToken.IsCancellationRequested)
- return CodeActionContainer.Empty;
- var provider = cfp.GetCodeFixProvider ();
- if (!provider.FixableDiagnosticIds.Any (diagnosticIds.Contains))
- continue;
-
- // These two delegates were factored out, as using them as lambdas in the inner loop creates more captures than declaring them here.
- Func<Diagnostic, bool> providerIdsContain = d => provider.FixableDiagnosticIds.Contains (d.Id);
- Action<Microsoft.CodeAnalysis.CodeActions.CodeAction, ImmutableArray<Diagnostic>> codeFixRegistration = (ca, d) => codeIssueFixes.Add (new ValidCodeDiagnosticAction (cfp, ca, d, d [0].Location.SourceSpan));
- try {
- var groupedDiagnostics = diagnosticsAtCaret
- .Concat (errorList.Select (em => em.Error.Tag)
- .OfType<Diagnostic> ())
- .GroupBy (d => d.Location.SourceSpan);
- foreach (var g in groupedDiagnostics) {
- if (cancellationToken.IsCancellationRequested)
- return CodeActionContainer.Empty;
- var diagnosticSpan = g.Key;
- var validDiagnostics = g.Where (providerIdsContain).ToImmutableArray ();
- if (validDiagnostics.Length == 0) {
- continue;
- }
- if (diagnosticSpan.Start < 0 || diagnosticSpan.End > root.Span.End) {
- continue;
- }
- await provider.RegisterCodeFixesAsync (new CodeFixContext (ad, diagnosticSpan, validDiagnostics, codeFixRegistration, cancellationToken)).ConfigureAwait (false);
-
- // TODO: Is that right ? Currently it doesn't really make sense to run one code fix provider on several overlapping diagnostics at the same location
- // However the generate constructor one has that case and if I run it twice the same code action is generated twice. So there is a dupe check problem there.
- // Work around for now is to only take the first diagnostic batch.
- break;
- }
- } catch (OperationCanceledException) {
- return CodeActionContainer.Empty;
- } catch (AggregateException ae) {
- ae.Flatten ().Handle (aex => aex is OperationCanceledException);
- return CodeActionContainer.Empty;
- } catch (Exception ex) {
- LoggingService.LogError ("Error while getting refactorings from code fix provider " + cfp.Name, ex);
- continue;
- }
- }
- var codeActions = new List<ValidCodeAction> ();
- foreach (var action in await CodeRefactoringService.GetValidActionsAsync (Editor, DocumentContext, span, cancellationToken).ConfigureAwait (false)) {
- codeActions.Add (action);
- }
- if (cancellationToken.IsCancellationRequested)
- return CodeActionContainer.Empty;
-
- var codeActionContainer = new CodeActionContainer (codeIssueFixes, codeActions, diagnosticsAtCaret);
+ var codeActionContainer = new CodeActionContainer (fixes, refactorings);
Application.Invoke ((o, args) => {
if (cancellationToken.IsCancellationRequested)
return;
@@ -229,7 +169,6 @@ namespace MonoDevelop.CodeActions
}
}, cancellationToken);
-
}
async void PopupQuickFixMenu (Gdk.EventButton evt, Action<CodeFixMenu> menuAction)
@@ -335,8 +274,8 @@ namespace MonoDevelop.CodeActions
bool first = true;
var smartTagLocBegin = offset;
- foreach (var fix in fixes.CodeFixActions.Concat (fixes.CodeRefactoringActions)) {
- var textSpan = fix.ValidSegment;
+ foreach (var fix in fixes.CodeFixActions) {
+ var textSpan = fix.TextSpan;
if (textSpan.IsEmpty)
continue;
if (first || offset < textSpan.Start) {
@@ -356,7 +295,7 @@ namespace MonoDevelop.CodeActions
currentSmartTag.CancelPopup += CurrentSmartTag_CancelPopup;
currentSmartTag.ShowPopup += CurrentSmartTag_ShowPopup;
currentSmartTag.Tag = fixes;
- currentSmartTag.IsVisible = fixes.CodeFixActions.Count > 0;
+ currentSmartTag.IsVisible = fixes.CodeFixActions.Sum (x => x.Fixes.Length) > 0;
editor.AddMarker (currentSmartTag);
}
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeActionPanelWidget.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeActionPanelWidget.cs
index a2ba81c573..52368ba888 100644
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeActionPanelWidget.cs
+++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeActionPanelWidget.cs
@@ -34,6 +34,8 @@ using MonoDevelop.Refactoring;
using System.Collections.Generic;
using GLib;
using MonoDevelop.CodeIssues;
+using MonoDevelop.AnalysisCore;
+using Microsoft.CodeAnalysis.Diagnostics;
namespace MonoDevelop.CodeActions
{
@@ -59,10 +61,13 @@ namespace MonoDevelop.CodeActions
readonly TreeStore treeStore = new TreeStore (typeof(string), typeof(bool), typeof(CodeRefactoringDescriptor));
readonly Dictionary<CodeRefactoringDescriptor, bool> providerStates = new Dictionary<CodeRefactoringDescriptor, bool> ();
+ static MonoDevelopWorkspaceDiagnosticAnalyzerProviderService.OptionsTable options =
+ ((MonoDevelopWorkspaceDiagnosticAnalyzerProviderService)Ide.Composition.CompositionManager.GetExportedValue<IWorkspaceDiagnosticAnalyzerProviderService> ()).Options;
+
void GetAllProviderStates ()
{
var language = CodeRefactoringService.MimeTypeToLanguage (mimeType);
- foreach (var node in BuiltInCodeDiagnosticProvider.GetBuiltInCodeRefactoringDescriptorsAsync (CodeRefactoringService.MimeTypeToLanguage(language), true).Result) {
+ foreach (var node in options.AllRefactorings.Where (x => x.Language.Contains (language))) {
providerStates [node] = node.IsEnabled;
}
}
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeFixMenuService.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeFixMenuService.cs
index 3e1a3491c0..df1fb480aa 100644
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeFixMenuService.cs
+++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeFixMenuService.cs
@@ -48,6 +48,7 @@ using MonoDevelop.Ide.Composition;
using MonoDevelop.Ide.Editor;
using MonoDevelop.Refactoring;
using RefactoringEssentials;
+using MonoDevelop.AnalysisCore;
namespace MonoDevelop.CodeActions
{
@@ -76,6 +77,8 @@ namespace MonoDevelop.CodeActions
usages.Set (id, CodeActionUsages [id]);
}
+ static MonoDevelopWorkspaceDiagnosticAnalyzerProviderService.OptionsTable options =
+ ((MonoDevelopWorkspaceDiagnosticAnalyzerProviderService)Ide.Composition.CompositionManager.GetExportedValue<IWorkspaceDiagnosticAnalyzerProviderService> ()).Options;
public static async Task<CodeFixMenu> CreateFixMenu (TextEditor editor, CodeActionContainer fixes, CancellationToken cancellationToken = default(CancellationToken))
{
var menu = new CodeFixMenu ();
@@ -86,191 +89,101 @@ namespace MonoDevelop.CodeActions
int mnemonic = 1;
- foreach (var fix in fixes.CodeFixActions.OrderByDescending (i => GetUsage (i.CodeAction.EquivalenceKey))) {
- AddFixMenuItem (editor, menu, ref mnemonic, fix.CodeAction);
- }
+ var suppressLabel = GettextCatalog.GetString ("_Suppress");
+ var suppressMenu = new CodeFixMenu (suppressLabel);
- bool first = true;
- foreach (var fix in fixes.CodeRefactoringActions) {
- if (first) {
- if (menu.Items.Count > 0)
- menu.Add (CodeFixMenuEntry.Separator);
- first = false;
- }
-
- AddFixMenuItem (editor, menu, ref mnemonic, fix.CodeAction);
- }
+ var fixAllLabel = GettextCatalog.GetString ("_Fix all");
+ var fixAllMenu = new CodeFixMenu (fixAllLabel);
- var warningsAtCaret = (await editor.DocumentContext.AnalysisDocument.GetSemanticModelAsync (cancellationToken))
- .GetDiagnostics (new TextSpan (editor.CaretOffset, 0))
- .Where (diag => diag.Severity == DiagnosticSeverity.Warning).ToList ();
+ var configureLabel = GettextCatalog.GetString ("_Options");
+ var configureMenu = new CodeFixMenu (configureLabel);
- var caretSpan = new TextSpan (editor.CaretOffset, 0);
+ foreach (var cfa in fixes.CodeFixActions.OrderByDescending (x => x.Fixes.Max(y => GetUsage (y.Action.EquivalenceKey)))) {
+ var state = cfa.FixAllState;
+ var scopes = cfa.SupportedScopes;
- first = true;
- foreach (var warning in warningsAtCaret) {
- if (string.IsNullOrWhiteSpace (warning.Descriptor.Title.ToString ()))
- continue;
- var label = GettextCatalog.GetString ("_Options for \u2018{0}\u2019", warning.Descriptor.Title);
- var subMenu = new CodeFixMenu (label);
+ foreach (var fix in cfa.Fixes) {
+ var diag = fix.PrimaryDiagnostic;
- await AddSuppressionMenuItems (subMenu, editor, warning, caretSpan);
+ if (options.TryGetDiagnosticDescriptor (diag.Id, out var descriptor) && !descriptor.GetIsEnabled (diag.Descriptor))
+ continue;
+
+ bool isSuppress = fix.Action is TopLevelSuppressionCodeAction;
- if (subMenu.Items.Count > 0) {
+ if (isSuppress) {
+ AddFixMenuItem (editor, suppressMenu, ref mnemonic, fix.Action);
+ continue;
+ }
- if (first) {
- menu.Add (CodeFixMenuEntry.Separator);
- first = false;
+ AddFixMenuItem (editor, menu, ref mnemonic, fix.Action);
+
+ var configurable = !DescriptorHasTag (diag.Descriptor, WellKnownDiagnosticTags.NotConfigurable);
+ if (descriptor != null && configurable) {
+ var optionsMenuItem = new CodeFixMenuEntry (GettextCatalog.GetString ("_Configure Rule \u2018{0}\u2019", diag.Descriptor.Title),
+ delegate {
+ IdeApp.Workbench.ShowGlobalPreferencesDialog (null, "C#", dialog => {
+ var panel = dialog.GetPanel<CodeIssuePanel> ("C#");
+ if (panel == null)
+ return;
+ panel.Widget.SelectCodeIssue (fix.PrimaryDiagnostic.Descriptor.Id);
+ });
+ });
+ configureMenu.Add (optionsMenuItem);
}
- menu.Add (subMenu);
+ if (!scopes.Contains (FixAllScope.Document))
+ continue;
+
+ // FIXME: No global undo yet to support fixall in project/solution
+ var fixState = state.WithScopeAndEquivalenceKey (FixAllScope.Document, fix.Action.EquivalenceKey);
+
+ var provider = state.FixAllProvider;
+ if (provider == null)
+ continue;
+
+ // FIXME: Use a real progress tracker.
+ var fixAll = await provider.GetFixAsync (fixState.CreateFixAllContext (new RoslynProgressTracker (), cancellationToken));
+ AddFixMenuItem (editor, fixAllMenu, ref mnemonic, fixAll);
}
}
- first = true;
- foreach (var diag in fixes.DiagnosticsAtCaret) {
- if (string.IsNullOrWhiteSpace (diag.Descriptor.Title.ToString ()))
+ bool first = true;
+ foreach (var refactoring in fixes.CodeRefactoringActions) {
+ if (options.TryGetRefactoringDescriptor (refactoring.GetType (), out var descriptor) && !descriptor.IsEnabled)
continue;
- var notConfigurable = DescriptorHasTag (diag.Descriptor, WellKnownDiagnosticTags.NotConfigurable);
-
- var label = GettextCatalog.GetString ("_Options for \u2018{0}\u2019", diag.Descriptor.Title);
- var subMenu = new CodeFixMenu (label);
-
if (first) {
- menu.Add (CodeFixMenuEntry.Separator);
+ if (menu.Items.Count > 0)
+ menu.Add (CodeFixMenuEntry.Separator);
first = false;
}
- await AddSuppressionMenuItems (subMenu, editor, diag, caretSpan);
-
- var descriptor = BuiltInCodeDiagnosticProvider.GetCodeDiagnosticDescriptor (diag.Id);
-
- if (descriptor != null && IsConfigurable (diag.Descriptor)) {
- var optionsMenuItem = new CodeFixMenuEntry (GettextCatalog.GetString ("_Configure Rule"),
- delegate {
- IdeApp.Workbench.ShowGlobalPreferencesDialog (null, "C#", dialog => {
- var panel = dialog.GetPanel<CodeIssuePanel> ("C#");
- if (panel == null)
- return;
- panel.Widget.SelectCodeIssue (diag.Descriptor.Id);
- });
- });
- subMenu.Add (optionsMenuItem);
+ foreach (var action in refactoring.Actions) {
+ AddFixMenuItem (editor, menu, ref mnemonic, action);
}
+ }
- foreach (var fix in fixes.CodeFixActions.OrderByDescending (i => GetUsage (i.CodeAction.EquivalenceKey))) {
- if (cancellationToken.IsCancellationRequested)
- return null;
- var provider = fix.Diagnostic.GetCodeFixProvider ().GetFixAllProvider ();
- if (provider == null)
- continue;
-
- if (!provider.GetSupportedFixAllScopes ().Contains (FixAllScope.Document))
- continue;
-
- var language = editor.DocumentContext.AnalysisDocument.Project.Language;
- var diagnosticdDescriptor = fix.Diagnostic?.GetCodeDiagnosticDescriptor (language);
- if (diagnosticdDescriptor == null)
- continue;
-
- var subMenu2 = new CodeFixMenu (GettextCatalog.GetString ("Fix all"));
-
- var diagnosticAnalyzer = diagnosticdDescriptor.GetProvider ();
- if (!diagnosticAnalyzer.SupportedDiagnostics.Contains (diag.Descriptor))
- continue;
-
- var menuItem = new CodeFixMenuEntry (
- GettextCatalog.GetString ("In _Document"),
- async delegate { await FixAll (editor, fix, provider, diagnosticAnalyzer); }
- );
- subMenu2.Add (menuItem);
- subMenu.Add (CodeFixMenuEntry.Separator);
- subMenu.Add (subMenu2);
- }
+ first = true;
- menu.Add (subMenu);
+ if (fixAllMenu.Items.Count != 0) {
+ if (first)
+ menu.Add (CodeFixMenuEntry.Separator);
+ menu.Add (fixAllMenu);
+ first = false;
}
- return menu;
- }
-
- static async Task FixAll (TextEditor editor, ValidCodeDiagnosticAction fix, FixAllProvider provider, DiagnosticAnalyzer diagnosticAnalyzer)
- {
- var diagnosticIds = diagnosticAnalyzer.SupportedDiagnostics.Select (d => d.Id).ToImmutableHashSet ();
-
- var analyzers = new [] { diagnosticAnalyzer }.ToImmutableArray ();
-
- var dict = ImmutableDictionary<Document, ImmutableArray<Diagnostic>>.Empty;
- var doc = editor.DocumentContext.AnalysisDocument;
- var diagnostics = await GetDiagnosticsForDocument (analyzers, doc, diagnosticIds, CancellationToken.None);
-
- dict = dict.Add (doc, diagnostics);
- var fixAllDiagnosticProvider = new FixAllState.FixMultipleDiagnosticProvider (dict);
-
- var ctx = new FixAllContext (
- editor.DocumentContext.AnalysisDocument,
- fix.Diagnostic.GetCodeFixProvider (),
- FixAllScope.Document,
- fix.CodeAction.EquivalenceKey,
- diagnosticIds,
- fixAllDiagnosticProvider,
- default (CancellationToken)
- );
-
- var fixAll = await provider.GetFixAsync (ctx);
- using (var undo = editor.OpenUndoGroup ()) {
- await CodeDiagnosticDescriptor.RunAction (editor.DocumentContext, fixAll, default (CancellationToken));
+ if (suppressMenu.Items.Count != 0) {
+ if (first)
+ menu.Add (CodeFixMenuEntry.Separator);
+ menu.Add (suppressMenu);
+ first = false;
}
- }
-
- static async Task<ImmutableArray<Diagnostic>> GetDiagnosticsForDocument (ImmutableArray<DiagnosticAnalyzer> analyzers, Microsoft.CodeAnalysis.Document doc, ImmutableHashSet<string> diagnostics, CancellationToken token)
- {
- var sol = doc.Project.Solution;
- var options = new CompilationWithAnalyzersOptions (
- new WorkspaceAnalyzerOptions (
- new AnalyzerOptions (ImmutableArray<AdditionalText>.Empty),
- sol.Options,
- sol),
- delegate (Exception exception, DiagnosticAnalyzer analyzer, Diagnostic diag) {
- LoggingService.LogError ("Exception in diagnostic analyzer " + diag.Id + ":" + diag.GetMessage (), exception);
- },
- true,
- false
- );
-
- var model = await doc.GetSemanticModelAsync (token).ConfigureAwait (false);
- var compilationWithAnalyzer = model.Compilation.WithAnalyzers (analyzers, options);
-
- var diagnosticList = new List<Diagnostic> ();
- diagnosticList.AddRange (await compilationWithAnalyzer.GetAnalyzerSemanticDiagnosticsAsync (model, null, token).ConfigureAwait (false));
- diagnosticList.AddRange (await compilationWithAnalyzer.GetAnalyzerSemanticDiagnosticsAsync (model, null, token).ConfigureAwait (false));
-
- return diagnosticList.ToImmutableArray ();
- }
-
- static async Task AddSuppressionMenuItems (CodeFixMenu menu, TextEditor editor, Diagnostic diag, TextSpan span)
- {
- var workspace = editor.DocumentContext.AnalysisDocument.Project.Solution.Workspace;
- var language = editor.DocumentContext.AnalysisDocument.Project.Language;
- var mefExporter = (IMefHostExportProvider)workspace.Services.HostServices;
-
- //TODO: cache this
- var suppressionProviders = mefExporter.GetExports<ISuppressionFixProvider, CodeChangeProviderMetadata> ()
- .ToPerLanguageMapWithMultipleLanguages();
-
- foreach (var suppressionProvider in suppressionProviders[LanguageNames.CSharp].Select (lz => lz.Value)) {
- if (!suppressionProvider.CanBeSuppressedOrUnsuppressed (diag)) {
- continue;
- }
- try {
- var fixes = await suppressionProvider.GetSuppressionsAsync (editor.DocumentContext.AnalysisDocument, span, new [] { diag }, default (CancellationToken)).ConfigureAwait (false);
- foreach (var fix in fixes) {
- AddFixMenuItem (editor, menu, fix.Action);
- }
- } catch (Exception e) {
- LoggingService.LogError ("Error while adding fixes", e);
- }
+ if (configureMenu.Items.Count != 0) {
+ if (first)
+ menu.Add (CodeFixMenuEntry.Separator);
+ menu.Add (configureMenu);
+ first = false;
}
+ return menu;
}
static bool DescriptorHasTag (DiagnosticDescriptor desc, string tag)
@@ -278,11 +191,6 @@ namespace MonoDevelop.CodeActions
return desc.CustomTags.Any (c => CultureInfo.InvariantCulture.CompareInfo.Compare (c, tag) == 0);
}
- static bool IsConfigurable (DiagnosticDescriptor desc)
- {
- return !DescriptorHasTag (desc, WellKnownDiagnosticTags.NotConfigurable);
- }
-
static CodeFixMenuEntry CreateFixMenuEntry (TextEditor editor, CodeAction fix)
{
int mnemonic = -1;
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeRefactoringService.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeRefactoringService.cs
index cb53d0a708..8f480dc917 100644
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeRefactoringService.cs
+++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeRefactoringService.cs
@@ -43,117 +43,6 @@ namespace MonoDevelop.CodeActions
{
static class CodeRefactoringService
{
- readonly static List<CodeDiagnosticProvider> providers = new List<CodeDiagnosticProvider> ();
-
- static CodeRefactoringService ()
- {
- providers.Add (new BuiltInCodeDiagnosticProvider ());
-
- AddinManager.AddExtensionNodeHandler ("/MonoDevelop/Refactoring/CodeDiagnosticProvider", delegate (object sender, ExtensionNodeEventArgs args) {
- var node = (TypeExtensionNode)args.ExtensionNode;
- switch (args.Change) {
- case ExtensionChange.Add:
- providers.Add ((CodeDiagnosticProvider)node.CreateInstance ());
- break;
- }
- });
- }
-
- public async static Task<IEnumerable<CodeDiagnosticDescriptor>> GetCodeDiagnosticsAsync (DocumentContext documentContext, string language, CancellationToken cancellationToken = default (CancellationToken))
- {
- var result = new List<CodeDiagnosticDescriptor> ();
-
- foreach (var provider in providers) {
- if (cancellationToken.IsCancellationRequested)
- return Enumerable.Empty<CodeDiagnosticDescriptor> ();
- result.AddRange (await provider.GetCodeDiagnosticDescriptorsAsync (documentContext, language, cancellationToken).ConfigureAwait (false));
- }
- return result;
- }
-
- public async static Task<IEnumerable<CodeDiagnosticFixDescriptor>> GetCodeFixesAsync (DocumentContext documentContext, string language, CancellationToken cancellationToken = default (CancellationToken))
- {
- var result = new List<CodeDiagnosticFixDescriptor> ();
- foreach (var provider in providers) {
- result.AddRange (await provider.GetCodeFixDescriptorsAsync (documentContext, language, cancellationToken).ConfigureAwait (false));
- }
- return result;
- }
-
- public async static Task<IEnumerable<CodeRefactoringDescriptor>> GetCodeRefactoringsAsync (DocumentContext documentContext, string language, CancellationToken cancellationToken = default (CancellationToken))
- {
- var result = new List<CodeRefactoringDescriptor> ();
- foreach (var provider in providers) {
- result.AddRange (await provider.GetCodeRefactoringDescriptorsAsync (documentContext, language, cancellationToken).ConfigureAwait (false));
- }
- return result;
- }
-
- static List<CodeRefactoringDescriptor> codeRefactoringCache;
- public static async Task<IEnumerable<ValidCodeAction>> GetValidActionsAsync (TextEditor editor, DocumentContext doc, TextSpan span, CancellationToken cancellationToken = default (CancellationToken))
- {
- if (editor == null)
- throw new ArgumentNullException ("editor");
- if (doc == null)
- throw new ArgumentNullException ("doc");
- var parsedDocument = doc.ParsedDocument;
- var actions = new List<ValidCodeAction> ();
- if (parsedDocument == null)
- return actions;
- var analysisDocument = doc.AnalysisDocument;
- if (analysisDocument == null)
- return actions;
-
- var model = await analysisDocument.GetSemanticModelAsync (cancellationToken);
- if (model == null)
- return actions;
- var root = await model.SyntaxTree.GetRootAsync (cancellationToken).ConfigureAwait (false);
- if (span.End > root.Span.End)
- return actions;
- TextSpan tokenSegment = span;
- var token = root.FindToken (span.Start);
- if (!token.IsMissing)
- tokenSegment = token.Span;
- try {
- if (codeRefactoringCache == null) {
- codeRefactoringCache = (await GetCodeRefactoringsAsync (doc, MimeTypeToLanguage (editor.MimeType), cancellationToken).ConfigureAwait (false)).ToList ();
- }
- foreach (var descriptor in codeRefactoringCache) {
- if (!descriptor.IsEnabled)
- continue;
- if (cancellationToken.IsCancellationRequested || analysisDocument == null)
- return Enumerable.Empty<ValidCodeAction> ();
- try {
- await descriptor.GetProvider ().ComputeRefactoringsAsync (
- new CodeRefactoringContext (analysisDocument, span, delegate (CodeAction ca) {
- var nrca = ca as NRefactoryCodeAction;
- var validSegment = tokenSegment;
- if (nrca != null)
- validSegment = nrca.TextSpan;
- actions.Add (new ValidCodeAction (ca, validSegment));
- }, cancellationToken)
- ).ConfigureAwait (false);
- } catch (OperationCanceledException) {
- if (cancellationToken.IsCancellationRequested)
- return Enumerable.Empty<ValidCodeAction> ();
- } catch (AggregateException) {
- if (cancellationToken.IsCancellationRequested)
- return Enumerable.Empty<ValidCodeAction> ();
- } catch (Exception e) {
- LoggingService.LogError ("Error while getting refactorings from " + descriptor.IdString, e);
- continue;
- }
- }
- } catch (OperationCanceledException) {
- if (cancellationToken.IsCancellationRequested)
- return Enumerable.Empty<ValidCodeAction> ();
- } catch (AggregateException) {
- if (cancellationToken.IsCancellationRequested)
- return Enumerable.Empty<ValidCodeAction> ();
- }
- return actions;
- }
-
public static string MimeTypeToLanguage (string mimeType)
{
switch (mimeType) {
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/ValidCodeAction.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/ValidCodeAction.cs
deleted file mode 100644
index 803cd429be..0000000000
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/ValidCodeAction.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-//
-// ValidCodeAction.cs
-//
-// Author:
-// Mike Krüger <mkrueger@xamarin.com>
-//
-// Copyright (c) 2015 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 Microsoft.CodeAnalysis.CodeActions;
-using Microsoft.CodeAnalysis.Text;
-
-namespace MonoDevelop.CodeActions
-{
- /// <summary>
- /// Represents a code action that's valid at a specific segment.
- /// </summary>
- class ValidCodeAction
- {
- public CodeAction CodeAction { get; private set; }
-
- public TextSpan ValidSegment { get; private set; }
-
- public ValidCodeAction (CodeAction codeAction, TextSpan validSegment)
- {
- this.CodeAction = codeAction;
- this.ValidSegment = validSegment;
- }
- }
-} \ No newline at end of file
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/ValidCodeDiagnosticAction.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/ValidCodeDiagnosticAction.cs
deleted file mode 100644
index 5c946ac714..0000000000
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/ValidCodeDiagnosticAction.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-//
-// ValidCodeDiagnosticAction.cs
-//
-// Author:
-// Mike Krüger <mkrueger@xamarin.com>
-//
-// Copyright (c) 2015 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.CodeActions;
-using MonoDevelop.Core.Text;
-using MonoDevelop.CodeActions;
-using Microsoft.CodeAnalysis;
-using MonoDevelop.CodeIssues;
-using Microsoft.CodeAnalysis.Text;
-using System.Collections.Immutable;
-
-namespace MonoDevelop.CodeActions
-{
- /// <summary>
- /// Represents a code action that's valid at a specific segment that was created as a action for a specific code diagnostic.
- /// </summary>
- class ValidCodeDiagnosticAction : ValidCodeAction
- {
- ImmutableArray<Diagnostic> validDiagnostics;
-
- public CodeDiagnosticFixDescriptor Diagnostic {
- get;
- private set;
- }
-
- public ImmutableArray<Diagnostic> ValidDiagnostics {
- get {
- return validDiagnostics;
- }
- }
-
- public ValidCodeDiagnosticAction (CodeDiagnosticFixDescriptor diagnostic, CodeAction codeAction, ImmutableArray<Diagnostic> validDiagnostics, TextSpan validSegment) : base (codeAction, validSegment)
- {
- this.Diagnostic = diagnostic;
- this.validDiagnostics = validDiagnostics;
- }
- }
-} \ No newline at end of file
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/AnalyzersFromAssembly.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/AnalyzersFromAssembly.cs
deleted file mode 100644
index 7a0ab88b9f..0000000000
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/AnalyzersFromAssembly.cs
+++ /dev/null
@@ -1,148 +0,0 @@
-//
-// AnalyzersFromAssembly.cs
-//
-// Author:
-// Mike Krüger <mkrueger@xamarin.com>
-//
-// Copyright (c) 2015 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 System.Linq;
-using System.Collections.Generic;
-using System.Reflection;
-using System.Threading;
-using MonoDevelop.CodeIssues;
-using Microsoft.CodeAnalysis.Diagnostics;
-using Microsoft.CodeAnalysis.CodeFixes;
-using RefactoringEssentials;
-using MonoDevelop.Core;
-using System.Threading.Tasks;
-using MonoDevelop.Ide.Editor;
-using MonoDevelop.CodeActions;
-using Microsoft.CodeAnalysis.CodeRefactorings;
-using Microsoft.CodeAnalysis;
-using Mono.Addins;
-using MonoDevelop.Core.AddIns;
-
-namespace MonoDevelop.CodeIssues
-{
-
- class AnalyzersFromAssembly
- {
- public List<CodeDiagnosticDescriptor> Analyzers;
- public List<CodeDiagnosticFixDescriptor> Fixes;
- public List<CodeRefactoringDescriptor> Refactorings;
-
- public readonly static AnalyzersFromAssembly Empty = new AnalyzersFromAssembly ();
-
- const string extensionPath = "/MonoDevelop/Refactoring/AnalyzerAssemblies";
- string [] RuntimeEnabledAssemblies;
- public AnalyzersFromAssembly ()
- {
- Analyzers = new List<CodeDiagnosticDescriptor> ();
- Fixes = new List<CodeDiagnosticFixDescriptor> ();
- Refactorings = new List<CodeRefactoringDescriptor> ();
-
- LoadAnalyzerAssemblies ();
- }
-
- void LoadAnalyzerAssemblies ()
- {
- RuntimeEnabledAssemblies = AddinManager.GetExtensionNodes<AssemblyExtensionNode> (extensionPath).Select (b => b.FileName).ToArray ();
- }
-
- readonly static string diagnosticAnalyzerAssembly = typeof (DiagnosticAnalyzerAttribute).Assembly.GetName ().Name;
-
- const bool ClrHeapEnabled = false;
- internal void AddAssembly (System.Reflection.Assembly asm, bool force = false)
- {
- //FIXME; this is a really hacky arbitrary heuristic
- //we should be using proper MEF composition APIs as part of the addin scan
- if (!force) {
- var assemblyName = asm.GetName ().Name;
- if (Array.IndexOf (RuntimeEnabledAssemblies, assemblyName) == -1) {
- switch (assemblyName) {
- case "ClrHeapAllocationAnalyzer":
- if (!ClrHeapEnabled)
- return;
- break;
- //blacklist
- case "FSharpBinding":
- return;
- //addin assemblies that reference roslyn
- default:
- var refAsm = asm.GetReferencedAssemblies ();
- if (refAsm.Any (a => a.Name == diagnosticAnalyzerAssembly) && refAsm.Any (a => a.Name == "MonoDevelop.Ide"))
- break;
- return;
- }
- }
- }
-
- try {
- foreach (var type in asm.GetTypes ()) {
-
- //HACK: Workaround for missing UI
- if (type == typeof (Microsoft.CodeAnalysis.GenerateOverrides.GenerateOverridesCodeRefactoringProvider))
- continue;
-
- var analyzerAttr = (DiagnosticAnalyzerAttribute)type.GetCustomAttributes (typeof (DiagnosticAnalyzerAttribute), false).FirstOrDefault ();
- if (analyzerAttr != null) {
- try {
- var analyzer = (DiagnosticAnalyzer)Activator.CreateInstance (type);
-
- if (analyzer.SupportedDiagnostics.Any (IsDiagnosticSupported)) {
- Analyzers.Add (new CodeDiagnosticDescriptor (analyzerAttr.Languages, type));
- }
- } catch (Exception e) {
- LoggingService.LogError ($"error while adding diagnostic analyzer {type} from assembly {asm.FullName}", e);
- }
- }
-
- var codeFixAttr = (ExportCodeFixProviderAttribute)type.GetCustomAttributes (typeof(ExportCodeFixProviderAttribute), false).FirstOrDefault ();
- if (codeFixAttr != null) {
- Fixes.Add (new CodeDiagnosticFixDescriptor (type, codeFixAttr));
- }
-
- var exportAttr = type.GetCustomAttributes (typeof(ExportCodeRefactoringProviderAttribute), false).FirstOrDefault () as ExportCodeRefactoringProviderAttribute;
- if (exportAttr != null) {
- Refactorings.Add (new CodeRefactoringDescriptor (type, exportAttr));
- }
- }
- } catch (ReflectionTypeLoadException ex) {
- foreach (var subException in ex.LoaderExceptions) {
- LoggingService.LogError ("Error while loading diagnostics in " + asm.FullName, subException);
- }
- throw;
- }
- }
-
- static bool IsDiagnosticSupported (DiagnosticDescriptor diag)
- {
- //filter out E&C analyzers as we don't support E&C
- if (diag.CustomTags.Contains (WellKnownDiagnosticTags.EditAndContinue)) {
- return false;
- }
-
- return true;
- }
- }
-}
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/BuiltInCodeDiagnosticProvider.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/BuiltInCodeDiagnosticProvider.cs
deleted file mode 100644
index 08eff6b5d7..0000000000
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/BuiltInCodeDiagnosticProvider.cs
+++ /dev/null
@@ -1,112 +0,0 @@
-//
-// BuiltInCodeDiagnosticProvider.cs
-//
-// Author:
-// Mike Krüger <mkrueger@xamarin.com>
-//
-// Copyright (c) 2015 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 System.Linq;
-using System.Collections.Generic;
-using System.Threading;
-using MonoDevelop.CodeIssues;
-using MonoDevelop.Core;
-using System.Threading.Tasks;
-using MonoDevelop.Ide.Editor;
-using MonoDevelop.CodeActions;
-
-namespace MonoDevelop.CodeIssues
-{
-
- /// <summary>
- /// Provides all IDE code diagnostics and fix provider.
- /// (Scans the app domain for providers)
- /// </summary>
- class BuiltInCodeDiagnosticProvider : CodeDiagnosticProvider
- {
- readonly static Task<AnalyzersFromAssembly> builtInDiagnostics;
-
- static BuiltInCodeDiagnosticProvider ()
- {
- RefactoringEssentials.NRefactory6Host.GetLocalizedString = GettextCatalog.GetString;
- builtInDiagnostics = Task.Run (() => {
- var result = new AnalyzersFromAssembly ();
- foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) {
- try {
- result.AddAssembly (asm);
- } catch (Exception e) {
- LoggingService.LogError ("Error while loading diagnostics in " + asm.FullName, e);
- }
- }
- return result;
- });
- }
-
- internal static CodeDiagnosticDescriptor GetCodeDiagnosticDescriptor (string diagnosticId)
- {
- foreach (var builtInDescriptor in GetBuiltInCodeDiagnosticDescriptorsAsync (null).Result) {
- if (builtInDescriptor.GetProvider ().SupportedDiagnostics.Any (diagnostic => diagnosticId == diagnostic.Id))
- return builtInDescriptor;
- }
- return null;
- }
-
- internal async static Task<IEnumerable<CodeDiagnosticDescriptor>> GetBuiltInCodeDiagnosticDescriptorsAsync (string language, bool includeDisabledNodes = false, CancellationToken cancellationToken = default (CancellationToken))
- {
- builtInDiagnostics.Wait (cancellationToken);
- var diags = await builtInDiagnostics;
- var builtInCodeDiagnostics = diags.Analyzers;
- if (string.IsNullOrEmpty (language))
- return includeDisabledNodes ? builtInCodeDiagnostics : builtInCodeDiagnostics.Where (act => act.IsEnabled);
- return includeDisabledNodes ? builtInCodeDiagnostics.Where (ca => ca.Languages.Contains (language)) : builtInCodeDiagnostics.Where (ca => ca.Languages.Contains (language) && ca.IsEnabled);
- }
-
- public async static Task<IEnumerable<CodeDiagnosticFixDescriptor>> GetBuiltInCodeFixDescriptorsAsync (string language, CancellationToken cancellationToken = default (CancellationToken))
- {
- var diags = await builtInDiagnostics.ConfigureAwait (false);
- var builtInCodeFixes = diags.Fixes;
- return string.IsNullOrEmpty (language) ? builtInCodeFixes : builtInCodeFixes.Where (cfp => cfp.Languages.Contains (language));
- }
-
- public async static Task<IEnumerable<CodeRefactoringDescriptor>> GetBuiltInCodeRefactoringDescriptorsAsync (string language, bool includeDisabledNodes = false, CancellationToken cancellationToken = default (CancellationToken))
- {
- var diags = await builtInDiagnostics.ConfigureAwait (false);
- var builtInCodeFixes = diags.Refactorings;
- return string.IsNullOrEmpty (language) ? builtInCodeFixes : builtInCodeFixes.Where (cfp => cfp.Language.Contains (language));
- }
-
- public override Task<IEnumerable<CodeDiagnosticFixDescriptor>> GetCodeFixDescriptorsAsync (DocumentContext document, string language, CancellationToken cancellationToken)
- {
- return GetBuiltInCodeFixDescriptorsAsync (language, cancellationToken);
- }
-
- public override Task<IEnumerable<CodeDiagnosticDescriptor>> GetCodeDiagnosticDescriptorsAsync (DocumentContext document, string language, CancellationToken cancellationToken)
- {
- return GetBuiltInCodeDiagnosticDescriptorsAsync (language, false, cancellationToken);
- }
-
- public override Task<IEnumerable<CodeRefactoringDescriptor>> GetCodeRefactoringDescriptorsAsync (DocumentContext document, string language, CancellationToken cancellationToken = default (CancellationToken))
- {
- return GetBuiltInCodeRefactoringDescriptorsAsync (language, false, cancellationToken);
- }
- }
-} \ No newline at end of file
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticDescriptor.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticDescriptor.cs
index 114a56ff2d..c0a9daca33 100644
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticDescriptor.cs
+++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticDescriptor.cs
@@ -124,6 +124,11 @@ namespace MonoDevelop.CodeIssues
return PropertyService.Get ("CodeIssues." + Languages + "." + IdString + "." + diagnostic.Id + ".enabled", true);
}
+ internal bool GetIsEnabled (string diagnosticId)
+ {
+ return PropertyService.Get ("CodeIssues." + Languages + "." + IdString + "." + diagnosticId + ".enabled", true);
+ }
+
internal void SetIsEnabled (DiagnosticDescriptor diagnostic, bool value)
{
PropertyService.Set ("CodeIssues." + Languages + "." + IdString + "." + diagnostic.Id + ".enabled", value);
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticFixDescriptor.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticFixDescriptor.cs
deleted file mode 100644
index b70fd9e0e2..0000000000
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticFixDescriptor.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-//
-// CodeFixDescriptor.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.CodeFixes;
-using Microsoft.CodeAnalysis.Diagnostics;
-using System.Linq;
-using MonoDevelop.Core;
-
-namespace MonoDevelop.CodeIssues
-{
- class CodeDiagnosticFixDescriptor
- {
- readonly Type codeFixProviderType;
- readonly ExportCodeFixProviderAttribute attribute;
- CodeFixProvider instance;
-
- public string Name {
- get {
- return attribute.Name;
- }
- }
-
- public string[] Languages {
- get {
- return attribute.Languages;
- }
- }
-
- internal CodeDiagnosticFixDescriptor (Type codeFixProviderType, ExportCodeFixProviderAttribute attribute)
- {
- if (codeFixProviderType == null)
- throw new ArgumentNullException ("codeFixProviderType");
- if (attribute == null)
- throw new ArgumentNullException ("attribute");
- this.codeFixProviderType = codeFixProviderType;
- this.attribute = attribute;
- }
-
- public CodeFixProvider GetCodeFixProvider ()
- {
- if (instance == null) {
- try {
- instance = (CodeFixProvider)Activator.CreateInstance (codeFixProviderType);
- } catch (InvalidCastException) {
- LoggingService.LogError (codeFixProviderType + " can't be cast to CodeFixProvider.");
- throw;
- }
- }
-
- return instance;
- }
-
- public CodeDiagnosticDescriptor GetCodeDiagnosticDescriptor (string language)
- {
- var fixableIds = GetCodeFixProvider ().FixableDiagnosticIds.ToList ();
-
- foreach (var descriptor in BuiltInCodeDiagnosticProvider.GetBuiltInCodeDiagnosticDescriptorsAsync (language).Result) {
- if (descriptor.GetProvider ().SupportedDiagnostics.Any (diagnostic => fixableIds.Contains (diagnostic.Id)))
- return descriptor;
-
- }
- return null;
-
- }
- }
-}
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticProvider.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticProvider.cs
deleted file mode 100644
index 479d24dffb..0000000000
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticProvider.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-//
-// CodeDiagnosticProvider.cs
-//
-// Author:
-// Mike Krüger <mkrueger@xamarin.com>
-//
-// Copyright (c) 2015 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.Collections.Generic;
-using System.Threading;
-using MonoDevelop.CodeIssues;
-using System.Threading.Tasks;
-using MonoDevelop.Ide.Editor;
-using MonoDevelop.CodeActions;
-
-namespace MonoDevelop.CodeIssues
-{
- /// <summary>
- /// The code diagnostic provider gives a list of code diagnostic and fix providers from an arbitrary source.
- /// </summary>
- abstract class CodeDiagnosticProvider
- {
- public abstract Task<IEnumerable<CodeDiagnosticDescriptor>> GetCodeDiagnosticDescriptorsAsync (DocumentContext document, string language, CancellationToken cancellationToken = default (CancellationToken));
- public abstract Task<IEnumerable<CodeDiagnosticFixDescriptor>> GetCodeFixDescriptorsAsync (DocumentContext document, string language, CancellationToken cancellationToken = default (CancellationToken));
- public abstract Task<IEnumerable<CodeRefactoringDescriptor>> GetCodeRefactoringDescriptorsAsync (DocumentContext document, string language, CancellationToken cancellationToken = default (CancellationToken));
- }
-} \ No newline at end of file
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticRunner.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticRunner.cs
index fda8a10732..6da380030f 100644
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticRunner.cs
+++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticRunner.cs
@@ -48,131 +48,11 @@ namespace MonoDevelop.CodeIssues
{
static class CodeDiagnosticRunner
{
- static List<DiagnosticAnalyzer> providers = new List<DiagnosticAnalyzer> ();
- static IEnumerable<CodeDiagnosticDescriptor> diagnostics;
- static Dictionary<string, CodeDiagnosticDescriptor> diagnosticTable;
- static SemaphoreSlim diagnosticLock = new SemaphoreSlim (1, 1);
+ static MonoDevelopWorkspaceDiagnosticAnalyzerProviderService.OptionsTable options =
+ ((MonoDevelopWorkspaceDiagnosticAnalyzerProviderService)Ide.Composition.CompositionManager.GetExportedValue<IWorkspaceDiagnosticAnalyzerProviderService> ()).Options;
+
static TraceListener consoleTraceListener = new ConsoleTraceListener ();
- static bool SkipContext (DocumentContext ctx)
- {
- return (ctx.IsAdHocProject || !(ctx.Project is MonoDevelop.Projects.DotNetProject));
- }
-
- static async Task GetDescriptorTable (AnalysisDocument analysisDocument, CancellationToken cancellationToken)
- {
- if (diagnosticTable != null)
- return;
-
- bool locked = await diagnosticLock.WaitAsync (Timeout.Infinite, cancellationToken).ConfigureAwait (false);
- if (diagnosticTable != null)
- return;
-
- try {
- var language = CodeRefactoringService.MimeTypeToLanguage (analysisDocument.Editor.MimeType);
- var alreadyAdded = new HashSet<Type> ();
-
- var table = new Dictionary<string, CodeDiagnosticDescriptor> ();
-
- diagnostics = await CodeRefactoringService.GetCodeDiagnosticsAsync (analysisDocument.DocumentContext, language, cancellationToken);
- foreach (var diagnostic in diagnostics) {
- if (!alreadyAdded.Add (diagnostic.DiagnosticAnalyzerType))
- continue;
- var provider = diagnostic.GetProvider ();
- if (provider == null)
- continue;
- foreach (var diag in provider.SupportedDiagnostics)
- table [diag.Id] = diagnostic;
-
- providers.Add (provider);
- }
-
- diagnosticTable = table;
- } finally {
- if (locked)
- diagnosticLock.Release ();
- }
- }
-
- // Old code, until we get EditorFeatures into composition so we can switch code fix service.
- public static async Task<IEnumerable<Result>> Check (AnalysisDocument analysisDocument, CancellationToken cancellationToken)
- {
- var input = analysisDocument.DocumentContext;
- if (!AnalysisOptions.EnableFancyFeatures || input.Project == null || !input.IsCompileableInProject || input.AnalysisDocument == null)
- return Enumerable.Empty<Result> ();
- if (SkipContext (input))
- return Enumerable.Empty<Result> ();
- try {
- var model = await analysisDocument.DocumentContext.AnalysisDocument.GetSemanticModelAsync (cancellationToken);
- if (model == null)
- return Enumerable.Empty<Result> ();
- var compilation = model.Compilation;
- var language = CodeRefactoringService.MimeTypeToLanguage (analysisDocument.Editor.MimeType);
-
- await GetDescriptorTable (analysisDocument, cancellationToken);
-
- if (providers.Count == 0 || cancellationToken.IsCancellationRequested)
- return Enumerable.Empty<Result> ();
- #if DEBUG
- Debug.Listeners.Add (consoleTraceListener);
- #endif
-
- CompilationWithAnalyzers compilationWithAnalyzer;
- var analyzers = ImmutableArray<DiagnosticAnalyzer>.Empty.AddRange (providers);
- var diagnosticList = new List<Diagnostic> ();
- try {
- var sol = analysisDocument.DocumentContext.AnalysisDocument.Project.Solution;
- var options = new CompilationWithAnalyzersOptions (
- new WorkspaceAnalyzerOptions (
- new AnalyzerOptions (ImmutableArray<AdditionalText>.Empty),
- sol.Options,
- sol),
- delegate (Exception exception, DiagnosticAnalyzer analyzer, Diagnostic diag) {
- LoggingService.LogError ("Exception in diagnostic analyzer " + diag.Id + ":" + diag.GetMessage (), exception);
- },
- false,
- false
- );
-
- compilationWithAnalyzer = compilation.WithAnalyzers (analyzers, options);
- if (input.ParsedDocument == null || cancellationToken.IsCancellationRequested)
- return Enumerable.Empty<Result> ();
-
- diagnosticList.AddRange (await compilationWithAnalyzer.GetAnalyzerSemanticDiagnosticsAsync (model, null, cancellationToken).ConfigureAwait (false));
- diagnosticList.AddRange (await compilationWithAnalyzer.GetAnalyzerSyntaxDiagnosticsAsync (model.SyntaxTree, cancellationToken).ConfigureAwait (false));
- } catch (OperationCanceledException) {
- } catch (AggregateException ae) {
- ae.Flatten ().Handle (ix => ix is OperationCanceledException);
- } catch (Exception ex) {
- LoggingService.LogError ("Error creating analyzer compilation", ex);
- return Enumerable.Empty<Result> ();
- } finally {
- #if DEBUG
- Debug.Listeners.Remove (consoleTraceListener);
- #endif
- CompilationWithAnalyzers.ClearAnalyzerState (analyzers);
- }
-
- return diagnosticList
- .Where (d => !d.Id.StartsWith("CS", StringComparison.Ordinal))
- .Where (d => !diagnosticTable.TryGetValue (d.Id, out var desc) || desc.GetIsEnabled (d.Descriptor))
- .Select (diagnostic => {
- var res = new DiagnosticResult(diagnostic);
- // var line = analysisDocument.Editor.GetLineByOffset (res.Region.Start);
- // Console.WriteLine (diagnostic.Id + "/" + res.Region +"/" + analysisDocument.Editor.GetTextAt (line));
- return res;
- });
- } catch (OperationCanceledException) {
- return Enumerable.Empty<Result> ();
- } catch (AggregateException ae) {
- ae.Flatten ().Handle (ix => ix is OperationCanceledException);
- return Enumerable.Empty<Result> ();
- } catch (Exception e) {
- LoggingService.LogError ("Error while running diagnostics.", e);
- return Enumerable.Empty<Result> ();
- }
- }
-
public static async Task<IEnumerable<Result>> Check (AnalysisDocument analysisDocument, CancellationToken cancellationToken, ImmutableArray<DiagnosticData> results)
{
var input = analysisDocument.DocumentContext;
@@ -183,20 +63,21 @@ namespace MonoDevelop.CodeIssues
Debug.Listeners.Add (consoleTraceListener);
#endif
- await GetDescriptorTable (analysisDocument, cancellationToken);
-
var resultList = new List<Result> (results.Length);
foreach (var data in results) {
if (input.IsAdHocProject && SkipError (data.Id))
continue;
+ if (data.IsSuppressed)
+ continue;
+
if (DataHasTag (data, WellKnownDiagnosticTags.EditAndContinue))
continue;
- if (diagnosticTable.TryGetValue (data.Id, out var descriptor) && !descriptor.IsEnabled)
+ if (options.TryGetDiagnosticDescriptor (data.Id, out var desc) && !desc.GetIsEnabled (data.Id))
continue;
-
- var diagnostic = await data.ToDiagnosticAsync (analysisDocument, cancellationToken);
+
+ var diagnostic = await data.ToDiagnosticAsync (analysisDocument, cancellationToken, desc);
resultList.Add (new DiagnosticResult (diagnostic));
}
return resultList;
@@ -241,17 +122,13 @@ namespace MonoDevelop.CodeIssues
return !lexicalError.Contains (errorId);
}
- static async Task<Diagnostic> ToDiagnosticAsync (this DiagnosticData data, AnalysisDocument analysisDocument, CancellationToken cancellationToken)
+ static async Task<Diagnostic> ToDiagnosticAsync (this DiagnosticData data, AnalysisDocument analysisDocument, CancellationToken cancellationToken, CodeDiagnosticDescriptor desc)
{
var project = analysisDocument.DocumentContext.AnalysisDocument.Project;
var location = await data.DataLocation.ConvertLocationAsync (project, cancellationToken).ConfigureAwait (false);
var additionalLocations = await data.AdditionalLocations.ConvertLocationsAsync (project, cancellationToken).ConfigureAwait (false);
- DiagnosticSeverity severity;
- if (diagnosticTable.TryGetValue (data.Id, out var desc))
- severity = diagnosticTable [data.Id].GetSeverity (data.Id, data.Severity);
- else
- severity = data.Severity;
+ DiagnosticSeverity severity = desc != null ? desc.GetSeverity (data.Id, data.Severity) : data.Severity;
return Diagnostic.Create (
data.Id, data.Category, data.Message, severity, data.DefaultSeverity,
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeIssuePanelWidget.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeIssuePanelWidget.cs
index 59a26bc5ca..db0004a6c8 100644
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeIssuePanelWidget.cs
+++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeIssuePanelWidget.cs
@@ -32,6 +32,8 @@ using Gdk;
using GLib;
using Gtk;
using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Diagnostics;
+using MonoDevelop.AnalysisCore;
using MonoDevelop.CodeActions;
using MonoDevelop.Components;
using MonoDevelop.Core;
@@ -79,9 +81,16 @@ namespace MonoDevelop.CodeIssues
readonly Dictionary<Tuple<CodeDiagnosticDescriptor, DiagnosticDescriptor>, DiagnosticSeverity?> severities = new Dictionary<Tuple<CodeDiagnosticDescriptor, DiagnosticDescriptor>, DiagnosticSeverity?> ();
readonly Dictionary<Tuple<CodeDiagnosticDescriptor, DiagnosticDescriptor>, bool> enableState = new Dictionary<Tuple<CodeDiagnosticDescriptor, DiagnosticDescriptor>, bool> ();
+ static MonoDevelopWorkspaceDiagnosticAnalyzerProviderService.OptionsTable options =
+ ((MonoDevelopWorkspaceDiagnosticAnalyzerProviderService)Ide.Composition.CompositionManager.GetExportedValue<IWorkspaceDiagnosticAnalyzerProviderService> ()).Options;
+
void GetAllSeverities ()
{
- foreach (var node in BuiltInCodeDiagnosticProvider.GetBuiltInCodeDiagnosticDescriptorsAsync (CodeRefactoringService.MimeTypeToLanguage (mimeType), true).Result) {
+ var language = CodeRefactoringService.MimeTypeToLanguage (mimeType);
+ foreach (var node in options.AllDiagnostics) {
+ if (!node.Languages.Contains (language))
+ continue;
+
foreach (var subIssue in node.GetProvider ().SupportedDiagnostics.Where (IsConfigurable).ToList ()) {
var sub = new Tuple<CodeDiagnosticDescriptor, DiagnosticDescriptor> (node, subIssue);
severities [sub] = node.GetSeverity (subIssue);
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring.addin.xml b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring.addin.xml
index 63bc190940..1b2f6f142a 100644
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring.addin.xml
+++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring.addin.xml
@@ -159,6 +159,8 @@
<Assembly file="Refactoring Essentials" />
<Assembly file="Microsoft.CodeAnalysis.CSharp" />
<Assembly file="Microsoft.CodeAnalysis.CSharp.Features" />
+ <Assembly file="Microsoft.CodeAnalysis.EditorFeatures" />
+ <Assembly file="Microsoft.CodeAnalysis.EditorFeatures.CSharp" />
<Assembly file="Microsoft.CodeAnalysis.Features" />
<Assembly file="Microsoft.CodeAnalysis.VisualBasic" />
<Assembly file="Microsoft.CodeAnalysis.VisualBasic.Features" />
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring.csproj b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring.csproj
index bb5f9b40b2..d2b8064860 100644
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring.csproj
+++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring.csproj
@@ -174,12 +174,6 @@
<Compile Include="MonoDevelop.CodeIssues\CodeDiagnosticRunner.cs" />
<Compile Include="MonoDevelop.CodeActions\CodeActionContainer.cs" />
<Compile Include="MonoDevelop.AnalysisCore\IssueMarker.cs" />
- <Compile Include="MonoDevelop.CodeIssues\CodeDiagnosticProvider.cs" />
- <Compile Include="MonoDevelop.CodeIssues\BuiltInCodeDiagnosticProvider.cs" />
- <Compile Include="MonoDevelop.CodeIssues\AnalyzersFromAssembly.cs" />
- <Compile Include="MonoDevelop.CodeActions\ValidCodeAction.cs" />
- <Compile Include="MonoDevelop.CodeActions\ValidCodeDiagnosticAction.cs" />
- <Compile Include="MonoDevelop.CodeIssues\CodeDiagnosticFixDescriptor.cs" />
<Compile Include="MonoDevelop.Refactoring\Commands.cs" />
<Compile Include="MonoDevelop.Refactoring\RefactoringSymbolInfo.cs" />
<Compile Include="MonoDevelop.CodeIssues\CodeFix.cs" />
@@ -203,6 +197,7 @@
<Compile Include="MonoDevelop.Refactoring.ExtractInterface\ExtractInterfaceDialog.cs" />
<Compile Include="MonoDevelop.AnalysisCore\MonoDevelopWorkspaceDiagnosticAnalyzerProviderService.cs" />
<Compile Include="MonoDevelop.AnalysisCore\MonoDevelopWorkspaceDiagnosticAnalyzerProviderService.AnalyzerAssemblyLoader.cs" />
+ <Compile Include="MonoDevelop.AnalysisCore\MonoDevelopWorkspaceDiagnosticAnalyzerProviderService.OptionsTable.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="MonoDevelop.Refactoring\" />
@@ -350,6 +345,7 @@
<InternalsVisibleTo Include="MonoDevelop.CSharpBinding" />
<InternalsVisibleTo Include="MonoDevelop.PackageManagement" />
<InternalsVisibleTo Include="MonoDevelop.MonoDroid" />
+ <InternalsVisibleTo Include="MonoDevelop.Refactoring.Tests" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/AnalyzeWholeSolutionHandler.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/AnalyzeWholeSolutionHandler.cs
index 8fe1b65c0e..8994b736d3 100644
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/AnalyzeWholeSolutionHandler.cs
+++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/AnalyzeWholeSolutionHandler.cs
@@ -28,11 +28,11 @@ using MonoDevelop.Components.Commands;
using MonoDevelop.Ide.TypeSystem;
using System.Threading.Tasks;
using System.Threading;
-using Microsoft.CodeAnalysis.Diagnostics;
using System.Collections.Generic;
using MonoDevelop.CodeActions;
using MonoDevelop.Ide.Editor;
using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Options;
using MonoDevelop.CodeIssues;
using MonoDevelop.Core;
@@ -42,23 +42,26 @@ using MonoDevelop.Ide.Gui.Pads;
using System.Collections.Immutable;
using System.Linq;
using MonoDevelop.Ide.Gui.Components;
+using MonoDevelop.AnalysisCore;
namespace MonoDevelop.Refactoring
{
class AnalyzeWholeSolutionHandler : CommandHandler
{
+ static MonoDevelopWorkspaceDiagnosticAnalyzerProviderService.OptionsTable options =
+ ((MonoDevelopWorkspaceDiagnosticAnalyzerProviderService)Ide.Composition.CompositionManager.GetExportedValue<IWorkspaceDiagnosticAnalyzerProviderService> ()).Options;
+
internal static async Task<List<DiagnosticAnalyzer>> GetProviders (Project project)
{
var providers = new List<DiagnosticAnalyzer> ();
var alreadyAdded = new HashSet<Type> ();
- var diagnostics = await CodeRefactoringService.GetCodeDiagnosticsAsync (new EmptyDocumentContext (project), LanguageNames.CSharp, default (CancellationToken));
+ var diagnostics = options.AllDiagnostics.Where (x => x.Languages.Contains (LanguageNames.CSharp));
var diagnosticTable = new Dictionary<string, CodeDiagnosticDescriptor> ();
foreach (var diagnostic in diagnostics) {
- if (alreadyAdded.Contains (diagnostic.DiagnosticAnalyzerType))
- continue;
if (!diagnostic.IsEnabled)
continue;
- alreadyAdded.Add (diagnostic.DiagnosticAnalyzerType);
+ if (!alreadyAdded.Add (diagnostic.DiagnosticAnalyzerType))
+ continue;
var provider = diagnostic.GetProvider ();
if (provider == null)
continue;
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 3899d41417..f3074a2e58 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs
@@ -103,8 +103,8 @@ namespace MonoDevelop.Ide.TypeSystem
IdeApp.Workspace.ActiveConfigurationChanged += HandleActiveConfigurationChanged;
}
ISolutionCrawlerRegistrationService solutionCrawler = Services.GetService<ISolutionCrawlerRegistrationService> ();
- //Options = Options.WithChangedOption (Microsoft.CodeAnalysis.Diagnostics.InternalRuntimeDiagnosticOptions.Syntax, true)
- // .WithChangedOption (Microsoft.CodeAnalysis.Diagnostics.InternalRuntimeDiagnosticOptions.Semantic, true);
+ Options = Options.WithChangedOption (Microsoft.CodeAnalysis.Diagnostics.InternalRuntimeDiagnosticOptions.Syntax, true)
+ .WithChangedOption (Microsoft.CodeAnalysis.Diagnostics.InternalRuntimeDiagnosticOptions.Semantic, true);
if (IdeApp.Preferences.EnableSourceAnalysis) {
solutionCrawler.Register (this);