private async Task VerifyFixInternalAsync(string language, ImmutableArray<DiagnosticAnalyzer> analyzers, CodeFixProvider codeFixProvider, string oldSource, string newSource, int? codeFixIndex, bool allowNewCompilerDiagnostics, int maxNumberOfIterations, Func<ImmutableArray<DiagnosticAnalyzer>, CodeFixProvider, int?, CancellationToken, Document, int, Task<Document>> getFixedDocument, CancellationToken cancellationToken) { var document = this.CreateDocument(oldSource, language); var compilerDiagnostics = await GetCompilerDiagnosticsAsync(document, cancellationToken).ConfigureAwait(false); document = await getFixedDocument(analyzers, codeFixProvider, codeFixIndex, cancellationToken, document, maxNumberOfIterations).ConfigureAwait(false); var newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, await GetCompilerDiagnosticsAsync(document, cancellationToken).ConfigureAwait(false)); // check if applying the code fix introduced any new compiler diagnostics if (!allowNewCompilerDiagnostics && newCompilerDiagnostics.Any()) { // Format and get the compiler diagnostics again so that the locations make sense in the output document = await Formatter.FormatAsync(document, Formatter.Annotation, cancellationToken: cancellationToken).ConfigureAwait(false); newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, await GetCompilerDiagnosticsAsync(document, cancellationToken).ConfigureAwait(false)); string message = string.Format("Fix introduced new compiler diagnostics:\r\n{0}\r\n\r\nNew document:\r\n{1}\r\n", string.Join("\r\n", newCompilerDiagnostics.Select(d => d.ToString())), (await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false)).ToFullString()); Assert.True(false, message); } // after applying all of the code fixes, compare the resulting string to the inputted one var actual = await GetStringFromDocumentAsync(document, cancellationToken).ConfigureAwait(false); Assert.Equal(newSource, actual); }
private FixAllState( FixAllProvider fixAllProvider, Document document, Project project, CodeFixProvider codeFixProvider, FixAllScope scope, string codeActionEquivalenceKey, IEnumerable<string> diagnosticIds, FixAllContext.DiagnosticProvider fixAllDiagnosticProvider) { Contract.ThrowIfNull(project); if (diagnosticIds == null) { throw new ArgumentNullException(nameof(diagnosticIds)); } if (diagnosticIds.Any(d => d == null)) { throw new ArgumentException(WorkspacesResources.Supplied_diagnostic_cannot_be_null, nameof(diagnosticIds)); } this.FixAllProvider = fixAllProvider; this.Document = document; this.Project = project; this.CodeFixProvider = codeFixProvider ?? throw new ArgumentNullException(nameof(codeFixProvider)); this.Scope = scope; this.CodeActionEquivalenceKey = codeActionEquivalenceKey; this.DiagnosticIds = ImmutableHashSet.CreateRange(diagnosticIds); this.DiagnosticProvider = fixAllDiagnosticProvider ?? throw new ArgumentNullException(nameof(fixAllDiagnosticProvider)); }
internal static async Task<ImmutableList<CodeFixEquivalenceGroup>> CreateAsync(CodeFixProvider codeFixProvider, IEnumerable<Diagnostic> allDiagnostics, Solution solution) { var fixAllProvider = codeFixProvider.GetFixAllProvider(); var relevantDiagnostics = allDiagnostics.Where(diagnostic => codeFixProvider.FixableDiagnosticIds.Contains(diagnostic.Id)).ToImmutableArray(); if (fixAllProvider == null) { return ImmutableList.Create<CodeFixEquivalenceGroup>(); } List<CodeAction> actions = new List<CodeAction>(); foreach (var diagnostic in relevantDiagnostics) { actions.AddRange(await GetFixesAsync(solution, codeFixProvider, diagnostic).ConfigureAwait(false)); } List<CodeFixEquivalenceGroup> groups = new List<CodeFixEquivalenceGroup>(); foreach (var item in actions.GroupBy(x => x.EquivalenceKey)) { groups.Add(new CodeFixEquivalenceGroup(item.Key, solution, fixAllProvider, codeFixProvider, relevantDiagnostics)); } return groups.ToImmutableList(); }
protected void VerifyFix(string language, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider, string oldSource, string newSource, int? codeFixIndex, bool allowNewCompilerDiagnostics) { Document document = CreateDocument(oldSource, language); VerifyFix(document, analyzer, codeFixProvider, newSource, codeFixIndex, useCompilerAnalyzerDriver: true, allowNewCompilerDiagnostics: allowNewCompilerDiagnostics); VerifyFix(document, analyzer, codeFixProvider, newSource, codeFixIndex, useCompilerAnalyzerDriver: false, allowNewCompilerDiagnostics: allowNewCompilerDiagnostics); }
internal void VerifyFix(CodeFixProvider codeFixProvider, DiagnosticAnalyzer diagnosticAnalyzer, string language, string oldSource, string newSource, int? codeFixIndex = null, string[] allowedNewCompilerDiagnosticsId = null) { CodeFixProvider = codeFixProvider; DiagnosticAnalyzer = diagnosticAnalyzer; if (allowedNewCompilerDiagnosticsId == null || !allowedNewCompilerDiagnosticsId.Any()) { VerifyFix(language, DiagnosticAnalyzer, CodeFixProvider, oldSource, newSource, codeFixIndex, false); } else { var document = DiagnosticVerifier.CreateDocument(oldSource, language); var compilerDiagnostics = GetCompilerDiagnostics(document).ToArray(); VerifyFix(language, DiagnosticAnalyzer, CodeFixProvider, oldSource, newSource, codeFixIndex, true); var newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, GetCompilerDiagnostics(document)).ToList(); if (newCompilerDiagnostics.Any(diagnostic => allowedNewCompilerDiagnosticsId.Any(s => s == diagnostic.Id))) { Assert.AreEqual(document.GetSyntaxRootAsync().Result.ToFullString(), string.Join(Environment.NewLine, newCompilerDiagnostics.Select(d => d.ToString())), "Fix introduced new compiler diagnostics"); } } }
/// <summary> /// General verifier for codefixes. /// Creates a Document from the source string, then gets diagnostics on it and applies the relevant codefixes. /// Then gets the string after the codefix is applied and compares it with the expected result. /// Note: If any codefix causes new diagnostics to show up, the test fails unless allowNewCompilerDiagnostics is set to true. /// </summary> /// <param name="language">The language the source code is in</param> /// <param name="analyzer">The analyzer to be applied to the source code</param> /// <param name="codeFixProvider">The codefix to be applied to the code wherever the relevant Diagnostic is found</param> /// <param name="oldSource">A class in the form of a string before the CodeFix was applied to it</param> /// <param name="newSource">A class in the form of a string after the CodeFix was applied to it</param> /// <param name="codeFixIndex">Index determining which codefix to apply if there are multiple</param> /// <param name="allowNewCompilerDiagnostics">A bool controlling whether or not the test will fail if the CodeFix introduces other warnings after being applied</param> private void VerifyFix(string language, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider, string oldSource, string newSource, int? codeFixIndex, bool allowNewCompilerDiagnostics) { Document document = DiagnosticVerifier.CreateDocument(oldSource, language); Diagnostic[] analyzerDiagnostics = DiagnosticVerifier.GetSortedDiagnosticsFromDocuments(analyzer, new[] { document }); IEnumerable<Diagnostic> compilerDiagnostics = CodeFixVerifier.GetCompilerDiagnostics(document); int attempts = analyzerDiagnostics.Length; for (int i = 0; i < attempts; ++i) { List<CodeAction> actions = new List<CodeAction>(); CodeFixContext context = new CodeFixContext(document, analyzerDiagnostics[0], (a, d) => actions.Add(a), CancellationToken.None); codeFixProvider.RegisterCodeFixesAsync(context).Wait(); if (!actions.Any()) { break; } if (codeFixIndex != null) { document = CodeFixVerifier.ApplyFix(document, actions.ElementAt((int)codeFixIndex)); break; } document = CodeFixVerifier.ApplyFix(document, actions.ElementAt(0)); analyzerDiagnostics = DiagnosticVerifier.GetSortedDiagnosticsFromDocuments(analyzer, new[] { document }); IEnumerable<Diagnostic> newCompilerDiagnostics = CodeFixVerifier.GetNewDiagnostics(compilerDiagnostics, CodeFixVerifier.GetCompilerDiagnostics(document)); // check if applying the code fix introduced any new compiler diagnostics if (!allowNewCompilerDiagnostics && newCompilerDiagnostics.Any()) { // Format and get the compiler diagnostics again so that the locations make sense in the output document = document.WithSyntaxRoot(Formatter.Format(document.GetSyntaxRootAsync().Result, Formatter.Annotation, document.Project.Solution.Workspace)); newCompilerDiagnostics = CodeFixVerifier.GetNewDiagnostics(compilerDiagnostics, CodeFixVerifier.GetCompilerDiagnostics(document)); Assert.IsTrue(false, string.Format("Fix introduced new compiler diagnostics:\r\n{0}\r\n\r\nNew document:\r\n{1}\r\n", string.Join("\r\n", newCompilerDiagnostics.Select(d => d.ToString())), document.GetSyntaxRootAsync().Result.ToFullString())); } // check if there are analyzer diagnostics left after the code fix if (!analyzerDiagnostics.Any()) { break; } } // after applying all of the code fixes, compare the resulting string to the inputted one string actual = CodeFixVerifier.GetStringFromDocument(document); Assert.AreEqual(newSource, actual); }
private static async Task<IEnumerable<CodeAction>> GetFixesAsync(Solution solution, CodeFixProvider codeFixProvider, Diagnostic diagnostic) { List<CodeAction> codeActions = new List<CodeAction>(); await codeFixProvider.RegisterCodeFixesAsync(new CodeFixContext(solution.GetDocument(diagnostic.Location.SourceTree), diagnostic, (a, d) => codeActions.Add(a), CancellationToken.None)); return codeActions; }
private void VerifyFix(Document document, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider, string newSource, int? codeFixIndex, bool useCompilerAnalyzerDriver, bool allowNewCompilerDiagnostics) { Diagnostic[] analyzerDiagnostics = GetSortedDiagnostics(analyzer, document, useCompilerAnalyzerDriver: useCompilerAnalyzerDriver); System.Collections.Immutable.ImmutableArray<Diagnostic> compilerDiagnostics = document.GetSemanticModelAsync().Result.GetDiagnostics(); // TODO(mavasani): Delete the below if statement once FxCop Analyzers have been ported to new IDiagnosticAnalyzer API. if (!useCompilerAnalyzerDriver) { Assert.True(analyzerDiagnostics.IsEmpty()); return; } int attempts = analyzerDiagnostics.Length; for (int i = 0; i < attempts; ++i) { var actions = new List<CodeAction>(); var context = new CodeFixContext(document, analyzerDiagnostics[0], (a, d) => actions.Add(a), CancellationToken.None); codeFixProvider.RegisterCodeFixesAsync(context).Wait(); if (!actions.Any()) { break; } if (codeFixIndex != null) { document = document.Apply(actions.ElementAt((int)codeFixIndex)); break; } document = document.Apply(actions.ElementAt(0)); analyzerDiagnostics = GetSortedDiagnostics(analyzer, document, useCompilerAnalyzerDriver: useCompilerAnalyzerDriver); IEnumerable<Diagnostic> newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, document.GetSemanticModelAsync().Result.GetDiagnostics()); if (!allowNewCompilerDiagnostics && newCompilerDiagnostics.Any()) { // Format and get the compiler diagnostics again so that the locations make sense in the output document = document.WithSyntaxRoot(Formatter.Format(document.GetSyntaxRootAsync().Result, Formatter.Annotation, document.Project.Solution.Workspace)); newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, document.GetSemanticModelAsync().Result.GetDiagnostics()); Assert.True(false, string.Format("Fix introduced new compiler diagnostics:\r\n{0}\r\n\r\nNew document:\r\n{1}\r\n", newCompilerDiagnostics.Select(d => d.ToString()).Join("\r\n"), document.GetSyntaxRootAsync().Result.ToFullString())); } if (analyzerDiagnostics.IsEmpty()) { break; } } Document newDocument = Simplifier.ReduceAsync(document, Simplifier.Annotation).Result; SyntaxNode root = newDocument.GetSyntaxRootAsync().Result; root = Formatter.Format(root, Formatter.Annotation, newDocument.Project.Solution.Workspace); string actual = root.GetText().ToString(); Assert.Equal(newSource, actual); }
/// <summary> /// General verifier for code fixes. /// Creates a Document from the source string, then gets diagnostics on it and applies the relevant code fixes. /// Then gets the string after the code fix is applied and compares it with the expected result. /// Note: If any code fix causes new diagnostics to show up, the test fails unless allowNewCompilerDiagnostics is set to true. /// </summary> /// <param name="language">The language the source code is in.</param> /// <param name="analyzer">The analyzer to be applied to the source code.</param> /// <param name="codeFixProvider">The code fix to be applied to the code wherever the relevant Diagnostic is found.</param> /// <param name="oldSource">A class in the form of a string before the code fix was applied to it.</param> /// <param name="newSource">A class in the form of a string after the code fix was applied to it.</param> /// <param name="codeFixIndex">Index determining which code fix to apply if there are multiple.</param> /// <param name="allowNewCompilerDiagnostics">A boolean controlling whether or not the test will fail if the code fix introduces other warnings after being applied.</param> private void VerifyFix(string language, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider, string oldSource, string newSource, int? codeFixIndex, bool allowNewCompilerDiagnostics) { var document = CreateDocument(oldSource, language); var analyzerDiagnostics = GetSortedDiagnosticsFromDocuments(analyzer, new[] { document }); var compilerDiagnostics = GetCompilerDiagnostics(document); var attempts = analyzerDiagnostics.Length; for (int i = 0; i < attempts; ++i) { var actions = new List<CodeAction>(); var context = new CodeFixContext(document, analyzerDiagnostics[0], (a, d) => actions.Add(a), CancellationToken.None); codeFixProvider.RegisterCodeFixesAsync(context).Wait(); if (!actions.Any()) { break; } if (codeFixIndex != null) { document = ApplyFix(document, actions.ElementAt((int)codeFixIndex)); break; } document = ApplyFix(document, actions.ElementAt(0)); analyzerDiagnostics = CodeFixVerifier.GetSortedDiagnosticsFromDocuments(analyzer, new[] { document }); var newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, GetCompilerDiagnostics(document)); // Check if applying the code fix introduced any new compiler diagnostics if (!allowNewCompilerDiagnostics && newCompilerDiagnostics.Any()) { // Format and get the compiler diagnostics again so that the locations make sense in the output document = document.WithSyntaxRoot(Formatter.Format(document.GetSyntaxRootAsync().Result, Formatter.Annotation, document.Project.Solution.Workspace)); newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, GetCompilerDiagnostics(document)); string message = FormattableString.Invariant( $@"Fix introduced new compiler diagnostics: {string.Join("\r\n", newCompilerDiagnostics.Select(d => d.ToString()))} New document: {document.GetSyntaxRootAsync().Result.ToFullString()} "); Execute.Assertion.FailWith(message); } // Check if there are analyzer diagnostics left after the code fix if (!analyzerDiagnostics.Any()) { break; } } // After applying all of the code fixes, compare the resulting string to the inputted one var actual = GetStringFromDocument(document); actual.Should().Be(newSource); }
private static bool IsInternalCodeFixProvider(CodeFixProvider fixer) { var exportAttributes = fixer.GetType().GetCustomAttributes(typeof(ExportCodeFixProviderAttribute), false); if (exportAttributes != null && exportAttributes.Length > 0) { var exportAttribute = (ExportCodeFixProviderAttribute)exportAttributes[0]; return s_predefinedCodeFixProviderNames.Contains(exportAttribute.Name); } return false; }
private FixMultipleContext( Project triggerProject, CodeFixProvider codeFixProvider, string codeActionEquivalenceKey, ImmutableHashSet<string> diagnosticIds, FixMultipleDiagnosticProvider diagnosticProvider, CancellationToken cancellationToken) : base(triggerProject, codeFixProvider, FixAllScope.Custom, codeActionEquivalenceKey, diagnosticIds, diagnosticProvider, cancellationToken) { _diagnosticProvider = diagnosticProvider; }
/// <summary> /// Creates a new <see cref="FixMultipleContext"/>. /// Use this overload when applying fix multiple diagnostics with a source location. /// </summary> /// <param name="diagnosticsToFix">Specific set of diagnostics to fix. Must be a non-empty set.</param> /// <param name="codeFixProvider">Underlying <see cref="CodeFixes.CodeFixProvider"/> which triggered this fix all.</param> /// <param name="codeActionEquivalenceKey">The <see cref="CodeAction.EquivalenceKey"/> value expected of a <see cref="CodeAction"/> participating in this fix all.</param> /// <param name="cancellationToken">Cancellation token for fix all computation.</param> public static FixMultipleContext Create( ImmutableDictionary<Project, ImmutableArray<Diagnostic>> diagnosticsToFix, CodeFixProvider codeFixProvider, string codeActionEquivalenceKey, CancellationToken cancellationToken) { var triggerProject = diagnosticsToFix.First().Key; var diagnosticIds = GetDiagnosticsIds(diagnosticsToFix.Values); var diagnosticProvider = new FixMultipleDiagnosticProvider(diagnosticsToFix); return new FixMultipleContext(triggerProject, codeFixProvider, codeActionEquivalenceKey, diagnosticIds, diagnosticProvider, cancellationToken); }
private static bool IsInternalCodeFixProvider(CodeFixProvider fixer) { var exportAttributes = fixer.GetType().GetTypeInfo().GetCustomAttributes(typeof(ExportCodeFixProviderAttribute), false); if (exportAttributes?.Any() == true) { var exportAttribute = (ExportCodeFixProviderAttribute)exportAttributes.First(); return s_predefinedCodeFixProviderNames.Contains(exportAttribute.Name); } return false; }
internal FixAllContext( Project project, CodeFixProvider codeFixProvider, FixAllScope scope, string codeActionId, IEnumerable<string> diagnosticIds, Func<Document, ImmutableHashSet<string>, CancellationToken, Task<IEnumerable<Diagnostic>>> getDocumentDiagnosticsAsync, Func<Project, bool, ImmutableHashSet<string>, CancellationToken, Task<IEnumerable<Diagnostic>>> getProjectDiagnosticsAsync, CancellationToken cancellationToken) : this(null, project, codeFixProvider, scope, codeActionId, diagnosticIds, getDocumentDiagnosticsAsync, getProjectDiagnosticsAsync, cancellationToken) { }
internal void VerifyFix(CodeFixProvider codeFixProvider, DiagnosticAnalyzer diagnosticAnalyzer, string language, string oldSource, string newSource, int? codeFixIndex = null, bool allowNewCompilerDiagnostics = false) { CodeFixProvider = codeFixProvider; DiagnosticAnalyzer = diagnosticAnalyzer; VerifyFix(language, DiagnosticAnalyzer, CodeFixProvider, oldSource, newSource, codeFixIndex, allowNewCompilerDiagnostics); }
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; }
internal static FixAllCodeActionContext Create( Project project, FixAllProviderInfo fixAllProviderInfo, CodeFixProvider originalFixProvider, IEnumerable<Diagnostic> originalFixDiagnostics, Func<Document, ImmutableHashSet<string>, CancellationToken, Task<IEnumerable<Diagnostic>>> getDocumentDiagnosticsAsync, Func<Project, bool, ImmutableHashSet<string>, CancellationToken, Task<IEnumerable<Diagnostic>>> getProjectDiagnosticsAsync, CancellationToken cancellationToken) { var diagnosticIds = GetFixAllDiagnosticIds(fixAllProviderInfo, originalFixDiagnostics).ToImmutableHashSet(); var diagnosticProvider = new FixAllDiagnosticProvider(diagnosticIds, getDocumentDiagnosticsAsync, getProjectDiagnosticsAsync); return new FixAllCodeActionContext(project, fixAllProviderInfo, originalFixProvider, originalFixDiagnostics, diagnosticIds, diagnosticProvider, cancellationToken); }
private CodeFixEquivalenceGroup( string equivalenceKey, Solution solution, FixAllProvider fixAllProvider, CodeFixProvider codeFixProvider, ImmutableArray<Diagnostic> diagnosticsToFix) { this.CodeFixEquivalenceKey = equivalenceKey; this.Solution = solution; this.FixAllProvider = fixAllProvider; this.CodeFixProvider = codeFixProvider; this.DiagnosticsToFix = diagnosticsToFix; }
/// <summary> /// Check the method body of the Initialize method of an analyzer and if that's empty, /// then the analyzer hasn't been implemented yet. /// </summary> private static bool HasImplementation(CodeFixProvider fixer) { var method = fixer.GetType().GetTypeInfo().GetMethod("RegisterCodeFixesAsync"); var stateMachineAttr = method?.GetCustomAttribute<AsyncStateMachineAttribute>(); var moveNextMethod = stateMachineAttr?.StateMachineType.GetTypeInfo().GetDeclaredMethod("MoveNext"); if (moveNextMethod != null) { var body = moveNextMethod.GetMethodBody(); var ilInstructionCount = body?.GetILAsByteArray()?.Count(); return ilInstructionCount != 177; } return true; }
public void ComputeAndApplyFix( ImmutableDictionary<Project, ImmutableArray<Diagnostic>> diagnosticsToFix, Workspace workspace, CodeFixProvider fixProvider, FixAllProvider fixAllProvider, string equivalenceKey, string waitDialogAndPreviewChangesTitle, string waitDialogMessage, bool showPreviewChangesDialog, CancellationToken cancellationToken) { var fixMultipleContext = FixMultipleContext.Create(diagnosticsToFix, fixProvider, equivalenceKey, cancellationToken); ComputeAndApplyFix(fixMultipleContext, workspace, fixAllProvider, waitDialogAndPreviewChangesTitle, waitDialogMessage, showPreviewChangesDialog, cancellationToken); }
/// <summary> /// Called to test a VB codefix when applied on the inputted string as a source /// </summary> /// <param name="oldSource">A class in the form of a string before the CodeFix was applied to it</param> /// <param name="newSource">A class in the form of a string after the CodeFix was applied to it</param> /// <param name="codeFixIndex">Index determining which codefix to apply if there are multiple</param> /// <param name="allowNewCompilerDiagnostics">A bool controlling whether or not the test will fail if the CodeFix introduces other warnings after being applied</param> /// <param name="formatBeforeCompare">Format the code before comparing, bot the old source and the new.</param> /// <param name="codeFixProvider">The codefix to be applied to the code wherever the relevant Diagnostic is found</param> /// <param name="languageVersionVB">The VB language version.</param> protected async Task VerifyBasicFixAsync(string oldSource, string newSource, int? codeFixIndex = null, bool allowNewCompilerDiagnostics = false, bool formatBeforeCompare = false, CodeFixProvider codeFixProvider = null, Microsoft.CodeAnalysis.VisualBasic.LanguageVersion languageVersionVB = Microsoft.CodeAnalysis.VisualBasic.LanguageVersion.VisualBasic14) { if (formatBeforeCompare) { oldSource = await FormatSourceAsync(LanguageNames.VisualBasic, oldSource, languageVersionVB: languageVersionVB).ConfigureAwait(true); newSource = await FormatSourceAsync(LanguageNames.VisualBasic, newSource, languageVersionVB: languageVersionVB).ConfigureAwait(true); } codeFixProvider = codeFixProvider ?? GetCodeFixProvider(); var diagnosticAnalyzer = GetDiagnosticAnalyzer(); if (diagnosticAnalyzer != null) await VerifyFixAsync(LanguageNames.VisualBasic, diagnosticAnalyzer, codeFixProvider, oldSource, newSource, codeFixIndex, allowNewCompilerDiagnostics, LanguageVersion.CSharp6, languageVersionVB).ConfigureAwait(true); else await VerifyFixAsync(LanguageNames.VisualBasic, codeFixProvider.FixableDiagnosticIds, codeFixProvider, oldSource, newSource, codeFixIndex, allowNewCompilerDiagnostics, LanguageVersion.CSharp6, languageVersionVB).ConfigureAwait(true); }
private FixAllCodeActionContext( Project project, FixAllProviderInfo fixAllProviderInfo, CodeFixProvider originalFixProvider, IEnumerable<Diagnostic> originalFixDiagnostics, ImmutableHashSet<string> diagnosticIds, FixAllDiagnosticProvider diagnosticProvider, CancellationToken cancellationToken) : base(project, originalFixProvider, FixAllScope.Project, null, diagnosticIds, diagnosticProvider, cancellationToken) { _fixAllProviderInfo = fixAllProviderInfo; _originalFixDiagnostics = originalFixDiagnostics; _diagnosticProvider = diagnosticProvider; }
public Solution GetFix( ImmutableDictionary<Project, ImmutableArray<Diagnostic>> diagnosticsToFix, Workspace workspace, CodeFixProvider fixProvider, FixAllProvider fixAllProvider, string equivalenceKey, string waitDialogTitle, string waitDialogMessage, CancellationToken cancellationToken) { var fixMultipleContext = FixMultipleContext.Create(diagnosticsToFix, fixProvider, equivalenceKey, cancellationToken); var suggestedAction = GetSuggestedAction(fixMultipleContext, workspace, fixAllProvider, waitDialogTitle, waitDialogMessage, showPreviewChangesDialog: false, cancellationToken: cancellationToken); return suggestedAction.GetChangedSolution(cancellationToken); }
public void ComputeAndApplyFix( ImmutableDictionary<Document, ImmutableArray<Diagnostic>> diagnosticsToFix, Workspace workspace, CodeFixProvider fixProvider, FixAllProvider fixAllProvider, string equivalenceKey, string title, string waitDialogMessage, bool showPreviewChangesDialog, CancellationToken cancellationToken) { var fixMultipleContext = FixMultipleContext.Create(diagnosticsToFix, fixProvider, equivalenceKey, cancellationToken); var suggestedAction = GetSuggestedAction(fixMultipleContext, workspace, fixAllProvider, title, waitDialogMessage, showPreviewChangesDialog, cancellationToken); suggestedAction.Invoke(cancellationToken); }
internal FixAllState( FixAllProvider fixAllProvider, Project project, CodeFixProvider codeFixProvider, FixAllScope scope, string codeActionEquivalenceKey, IEnumerable<string> diagnosticIds, FixAllContext.DiagnosticProvider fixAllDiagnosticProvider) : this(fixAllProvider, null, project, codeFixProvider, scope, codeActionEquivalenceKey, diagnosticIds, fixAllDiagnosticProvider) { if (project == null) { throw new ArgumentNullException(nameof(project)); } }
/// <summary> /// Creates a new <see cref="FixAllContext"/>. /// Use this overload when applying fix all to a diagnostic with a source location. /// </summary> /// <param name="document">Document within which fix all occurrences was triggered.</param> /// <param name="codeFixProvider">Underlying <see cref="CodeFixes.CodeFixProvider"/> which triggered this fix all.</param> /// <param name="scope"><see cref="FixAllScope"/> to fix all occurrences.</param> /// <param name="codeActionEquivalenceKey">The <see cref="CodeAction.EquivalenceKey"/> value expected of a <see cref="CodeAction"/> participating in this fix all.</param> /// <param name="diagnosticIds">Diagnostic Ids to fix.</param> /// <param name="fixAllDiagnosticProvider"> /// <see cref="DiagnosticProvider"/> to fetch document/project diagnostics to fix in a <see cref="FixAllContext"/>. /// </param> /// <param name="cancellationToken">Cancellation token for fix all computation.</param> public FixAllContext( Document document, CodeFixProvider codeFixProvider, FixAllScope scope, string codeActionEquivalenceKey, IEnumerable<string> diagnosticIds, DiagnosticProvider fixAllDiagnosticProvider, CancellationToken cancellationToken) : this(document, document.Project, codeFixProvider, scope, codeActionEquivalenceKey, diagnosticIds, fixAllDiagnosticProvider, cancellationToken) { if (document == null) { throw new ArgumentNullException(nameof(document)); } }
public Solution GetFix( ImmutableDictionary<Document, ImmutableArray<Diagnostic>> diagnosticsToFix, Workspace workspace, CodeFixProvider fixProvider, FixAllProvider fixAllProvider, string equivalenceKey, string waitDialogTitle, string waitDialogMessage, CancellationToken cancellationToken) { var fixMultipleState = FixAllState.Create(fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey); var triggerDiagnostic = diagnosticsToFix.First().Value.First(); var suggestedAction = GetSuggestedAction(fixMultipleState, triggerDiagnostic, workspace, waitDialogTitle, waitDialogMessage, showPreviewChangesDialog: false, cancellationToken: cancellationToken); return suggestedAction.GetChangedSolution(cancellationToken); }
public Solution GetFix( ImmutableDictionary<Project, ImmutableArray<Diagnostic>> diagnosticsToFix, Workspace workspace, CodeFixProvider fixProvider, FixAllProvider fixAllProvider, string equivalenceKey, string waitDialogTitle, string waitDialogMessage, CancellationToken cancellationToken) { var fixMultipleState = FixAllState.Create( fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey); return GetFixedSolution( fixMultipleState, workspace, waitDialogTitle, waitDialogMessage, cancellationToken); }
internal FixAllCodeActionContext( Project project, FixAllProviderInfo fixAllProviderInfo, CodeFixProvider originalFixProvider, IEnumerable<Diagnostic> originalFixDiagnostics, Func<Document, ImmutableHashSet<string>, CancellationToken, Task<IEnumerable<Diagnostic>>> getDocumentDiagnosticsAsync, Func<Project, bool, ImmutableHashSet<string>, CancellationToken, Task<IEnumerable<Diagnostic>>> getProjectDiagnosticsAsync, CancellationToken cancellationToken) : base(project, originalFixProvider, FixAllScope.Project, null, GetFixAllDiagnosticIds(fixAllProviderInfo, originalFixDiagnostics), getDocumentDiagnosticsAsync, getProjectDiagnosticsAsync, cancellationToken) { _fixAllProviderInfo = fixAllProviderInfo; _originalFixDiagnostics = originalFixDiagnostics; _getDocumentDiagnosticsAsync = getDocumentDiagnosticsAsync; _getProjectDiagnosticsAsync = getProjectDiagnosticsAsync; }
private CodeFixEquivalenceGroup( string equivalenceKey, Solution solution, FixAllProvider fixAllProvider, CodeFixProvider codeFixProvider, ImmutableDictionary<ProjectId, ImmutableDictionary<string, ImmutableArray<Diagnostic>>> documentDiagnosticsToFix, ImmutableDictionary<ProjectId, ImmutableArray<Diagnostic>> projectDiagnosticsToFix) { this.CodeFixEquivalenceKey = equivalenceKey; this.Solution = solution; this.FixAllProvider = fixAllProvider; this.CodeFixProvider = codeFixProvider; this.DocumentDiagnosticsToFix = documentDiagnosticsToFix; this.ProjectDiagnosticsToFix = projectDiagnosticsToFix; this.NumberOfDiagnostics = documentDiagnosticsToFix.SelectMany(x => x.Value.Select(y => y.Value).SelectMany(y => y)).Count() + projectDiagnosticsToFix.SelectMany(x => x.Value).Count(); }
private ImmutableArray <DiagnosticId> GetFixableDiagnosticIds(CodeFixProvider fixer) { return(ImmutableInterlocked.GetOrAdd(ref _fixerToFixableIdsMap, fixer, f => f.FixableDiagnosticIds)); }
private bool IsInteractiveCodeFixProvider(CodeFixProvider provider) { // TODO (https://github.com/dotnet/roslyn/issues/4932): Don't restrict CodeFixes in Interactive return(provider is FullyQualify.AbstractFullyQualifyCodeFixProvider || provider is AddImport.AbstractAddImportCodeFixProvider); }
/// <summary> /// Gets the diagnostic IDs for which fix all occurrences is supported. /// By default, it returns <see cref="CodeFixProvider.FixableDiagnosticIds"/> for the given <paramref name="originalCodeFixProvider"/>. /// </summary> /// <param name="originalCodeFixProvider">Original code fix provider that returned this fix all provider from <see cref="CodeFixProvider.GetFixAllProvider"/> method.</param> public virtual IEnumerable <string> GetSupportedFixAllDiagnosticIds(CodeFixProvider originalCodeFixProvider) => originalCodeFixProvider.FixableDiagnosticIds;