forked from microsoft/vs-threading
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVSTHRD107AwaitTaskWithinUsingExpressionCodeFix.cs
More file actions
88 lines (79 loc) · 3.76 KB
/
Copy pathVSTHRD107AwaitTaskWithinUsingExpressionCodeFix.cs
File metadata and controls
88 lines (79 loc) · 3.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace Microsoft.VisualStudio.Threading.Analyzers
{
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Simplification;
using Microsoft.VisualStudio.Threading;
/// <summary>
/// Offers a code fix for diagnostics produced by the
/// <see cref="VSTHRD107AwaitTaskWithinUsingExpressionAnalyzer" />.
/// </summary>
/// <remarks>
/// The code fix changes code like this as described:
/// <code>
/// <![CDATA[
/// AsyncSemaphore semaphore;
/// async Task FooAsync()
/// {
/// using (semaphore.EnterAsync()) // CODE FIX: add await to the using expression
/// {
/// }
/// }
/// ]]>
/// </code>
/// </remarks>
[ExportCodeFixProvider(LanguageNames.CSharp)]
public class VSTHRD107AwaitTaskWithinUsingExpressionCodeFix : CodeFixProvider
{
private static readonly ImmutableArray<string> ReusableFixableDiagnosticIds = ImmutableArray.Create(
VSTHRD107AwaitTaskWithinUsingExpressionAnalyzer.Id);
public override ImmutableArray<string> FixableDiagnosticIds => ReusableFixableDiagnosticIds;
public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
Diagnostic? diagnostic = context.Diagnostics.First();
context.RegisterCodeFix(
CodeAction.Create(
Strings.VSTHRD107_CodeFix_Title,
async ct =>
{
Document? document = context.Document;
SyntaxNode? root = await document.GetSyntaxRootAsync(ct).ConfigureAwait(false);
MethodDeclarationSyntax? method = root.FindNode(diagnostic.Location.SourceSpan).FirstAncestorOrSelf<MethodDeclarationSyntax>();
(document, method, _) = await FixUtils.UpdateDocumentAsync(
document,
method,
m =>
{
root = m.SyntaxTree.GetRoot(ct);
UsingStatementSyntax usingStatement = root.FindNode(diagnostic.Location.SourceSpan).FirstAncestorOrSelf<UsingStatementSyntax>();
AwaitExpressionSyntax awaitExpression = SyntaxFactory.AwaitExpression(
SyntaxFactory.ParenthesizedExpression(usingStatement.Expression));
UsingStatementSyntax modifiedUsingStatement = usingStatement.WithExpression(awaitExpression)
.WithAdditionalAnnotations(Simplifier.Annotation);
return m.ReplaceNode(usingStatement, modifiedUsingStatement);
},
ct).ConfigureAwait(false);
(document, method) = await method.MakeMethodAsync(document, ct).ConfigureAwait(false);
return document.Project.Solution;
},
"only action"),
diagnostic);
return Task.FromResult<object?>(null);
}
/// <inheritdoc />
public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
}
}