Apply vs-threading analyzers and fix issues they found

Most changes are to style (e.g. using Async suffixes).
There was one change to avoid synchronously blocking.
There were several correctness issues found and fixed around missing .ConfigureAwait(false) suffixes.
This commit is contained in:
Andrew Arnott 2019-10-21 00:18:33 -07:00
Родитель 69c696cb7f
Коммит d42c4c3297
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: A9B9910CDCCDA441
11 изменённых файлов: 39 добавлений и 23 удалений

Просмотреть файл

@ -28,6 +28,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0-preview.2" PrivateAssets="All" />
<PackageReference Include="Nerdbank.GitVersioning" Version="2.3.183" PrivateAssets="all" />
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="16.4.16" PrivateAssets="All" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19351-01" PrivateAssets="All" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
</ItemGroup>

Просмотреть файл

@ -92,4 +92,7 @@
<Rule Id="SA1402" Action="Hidden" />
<Rule Id="SA1101" Action="Hidden" />
</Rules>
<Rules AnalyzerId="Microsoft.VisualStudio.Threading.Analyzers" RuleNamespace="Microsoft.VisualStudio.Threading.Analyzers">
<Rule Id="VSTHRD111" Action="Warning" />
</Rules>
</RuleSet>

Просмотреть файл

@ -26,9 +26,9 @@ namespace MessagePack.AspNetCoreMvcFormatter
public async Task<InputFormatterResult> ReadAsync(InputFormatterContext context)
{
Microsoft.AspNetCore.Http.HttpRequest request = context.HttpContext.Request;
object result = await MessagePackSerializer.DeserializeAsync(context.ModelType, request.Body, this.options, context.HttpContext.RequestAborted);
return await InputFormatterResult.SuccessAsync(result);
var request = context.HttpContext.Request;
var result = await MessagePackSerializer.DeserializeAsync(context.ModelType, request.Body, this.options, context.HttpContext.RequestAborted).ConfigureAwait(false);
return await InputFormatterResult.SuccessAsync(result).ConfigureAwait(false);
}
}
}

Просмотреть файл

@ -69,7 +69,7 @@ namespace MessagePack
return GetOrAdd(type).Deserialize_ReadOnlyMemory_Options.Invoke(bytes, options);
}
private static async ValueTask<object> DeserializeObjectAsync<T>(Stream stream, MessagePackSerializerOptions options, CancellationToken cancellationToken) => await DeserializeAsync<T>(stream, options, cancellationToken);
private static async ValueTask<object> DeserializeObjectAsync<T>(Stream stream, MessagePackSerializerOptions options, CancellationToken cancellationToken) => await DeserializeAsync<T>(stream, options, cancellationToken).ConfigureAwait(false);
private static CompiledMethods GetOrAdd(Type type)
{

Просмотреть файл

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
namespace MessagePack.CodeGenerator
@ -180,10 +181,9 @@ namespace MessagePack.CodeGenerator
private List<GenericSerializationInfo> collectedGenericInfo;
private List<UnionSerializationInfo> collectedUnionInfo;
public TypeCollector(string csProjPath, IEnumerable<string> conditinalSymbols, bool disallowInternal, bool isForceUseMap)
private TypeCollector(string csProjPath, Compilation compilation, IEnumerable<string> conditionalSymbols, bool disallowInternal, bool isForceUseMap)
{
this.csProjPath = csProjPath;
Compilation compilation = RoslynExtensions.GetCompilationFromProject(csProjPath, conditinalSymbols.Concat(new[] { CodegeneratorOnlyPreprocessorSymbol }).ToArray()).GetAwaiter().GetResult();
Diagnostic[] compilationErrors = compilation.GetDiagnostics().Where(x => x.Severity == DiagnosticSeverity.Error).ToArray();
if (compilationErrors.Length != 0)
{
@ -217,6 +217,12 @@ namespace MessagePack.CodeGenerator
.ToArray();
}
public static async Task<TypeCollector> CreateAsync(string csProjPath, IEnumerable<string> conditionalSymbols, bool disallowInternal, bool isForceUseMap)
{
Compilation compilation = await RoslynExtensions.GetCompilationFromProjectAsync(csProjPath, conditionalSymbols.Concat(new[] { CodegeneratorOnlyPreprocessorSymbol }).ToArray());
return new TypeCollector(csProjPath, compilation, conditionalSymbols, disallowInternal, isForceUseMap);
}
private void ResetWorkspace()
{
this.alreadyCollected = new HashSet<ITypeSymbol>();

Просмотреть файл

@ -28,4 +28,7 @@
<Rule Id="RS1022" Action="None" />
<Rule Id="RS1023" Action="None" />
</Rules>
<Rules AnalyzerId="Microsoft.VisualStudio.Threading.Analyzers" RuleNamespace="Microsoft.VisualStudio.Threading.Analyzers">
<Rule Id="VSTHRD111" Action="None" />
</Rules>
</RuleSet>

Просмотреть файл

@ -7,6 +7,7 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MessagePack.CodeGenerator.Generator;
using Mono.Options;
@ -14,7 +15,7 @@ namespace MessagePack.CodeGenerator
{
internal class Program
{
private static int Main(string[] args)
private static async Task<int> Main(string[] args)
{
try
{
@ -28,7 +29,7 @@ namespace MessagePack.CodeGenerator
var sw = Stopwatch.StartNew();
Console.WriteLine("Project Compilation Start:" + cmdArgs.InputPath);
var collector = new TypeCollector(cmdArgs.InputPath, cmdArgs.ConditionalSymbols, true, cmdArgs.IsUseMap);
var collector = await TypeCollector.CreateAsync(cmdArgs.InputPath, cmdArgs.ConditionalSymbols, true, cmdArgs.IsUseMap);
Console.WriteLine("Project Compilation Complete:" + sw.Elapsed.ToString());
Console.WriteLine();

Просмотреть файл

@ -48,14 +48,14 @@ namespace MessagePack.CodeGenerator
{
if (stdout != null)
{
await RedirectOutputTask(proc.StandardOutput.BaseStream, stdout, exitedct.Token, "stdout");
await RedirectOutputTaskAsync(proc.StandardOutput.BaseStream, stdout, exitedct.Token, "stdout");
}
}),
Task.Run(async () =>
{
if (stderr != null)
{
await RedirectOutputTask(proc.StandardError.BaseStream, stderr, exitedct.Token, "stderr");
await RedirectOutputTaskAsync(proc.StandardError.BaseStream, stderr, exitedct.Token, "stderr");
}
}));
if (exitCode >= 0)
@ -103,7 +103,7 @@ namespace MessagePack.CodeGenerator
}
}
private static async Task RedirectOutputTask(Stream procStdout, Stream stdout, CancellationToken ct, string suffix)
private static async Task RedirectOutputTaskAsync(Stream procStdout, Stream stdout, CancellationToken ct, string suffix)
{
if (stdout != null)
{
@ -118,7 +118,7 @@ namespace MessagePack.CodeGenerator
break;
}
stdout.Write(buf, 0, bytesread);
await stdout.WriteAsync(buf, 0, bytesread, ct);
}
catch (NullReferenceException)
{

Просмотреть файл

@ -61,7 +61,7 @@ namespace MessagePack.CodeGenerator
}
}
private static async Task<bool> TryExecute(string csprojPath, string tempPath, bool useDotNet)
private static async Task<bool> TryExecuteAsync(string csprojPath, string tempPath, bool useDotNet)
{
// executing build command with output binary log
(string fname, string args) = GetBuildCommandLine(csprojPath, tempPath, useDotNet);
@ -142,7 +142,7 @@ namespace MessagePack.CodeGenerator
{
try
{
if (!await TryExecute(csprojPath, tempPath, useDotNet).ConfigureAwait(false))
if (!await TryExecuteAsync(csprojPath, tempPath, useDotNet).ConfigureAwait(false))
{
return (null, Array.Empty<StLogger.Error>());
}
@ -160,7 +160,7 @@ namespace MessagePack.CodeGenerator
}
}
private static async Task<StLogger.Build> GetBuildResult(string csprojPath, params string[] preprocessorSymbols)
private static async Task<StLogger.Build> GetBuildResultAsync(string csprojPath, params string[] preprocessorSymbols)
{
var tempPath = Path.Combine(new FileInfo(csprojPath).Directory.FullName, "__buildtemp");
try
@ -276,9 +276,9 @@ namespace MessagePack.CodeGenerator
return ws;
}
public static async Task<Compilation> GetCompilationFromProject(string csprojPath, params string[] preprocessorSymbols)
public static async Task<Compilation> GetCompilationFromProjectAsync(string csprojPath, params string[] preprocessorSymbols)
{
StLogger.Build build = await GetBuildResult(csprojPath, preprocessorSymbols).ConfigureAwait(false);
StLogger.Build build = await GetBuildResultAsync(csprojPath, preprocessorSymbols).ConfigureAwait(false);
using (Workspace workspace = GetWorkspaceFromBuild(build, preprocessorSymbols))
{

Просмотреть файл

@ -116,19 +116,19 @@ namespace MessagePackAnalyzer
}
}
var action = CodeAction.Create("Add MessagePack KeyAttribute", c => AddKeyAttribute(context.Document, namedSymbol, c), "MessagePackAnalyzer.AddKeyAttribute");
var action = CodeAction.Create("Add MessagePack KeyAttribute", c => AddKeyAttributeAsync(context.Document, namedSymbol, c), "MessagePackAnalyzer.AddKeyAttribute");
context.RegisterCodeFix(action, context.Diagnostics.First()); // use single.
}
private static async Task<Document> AddKeyAttribute(Document document, INamedTypeSymbol type, CancellationToken cancellationToken)
private static async Task<Document> AddKeyAttributeAsync(Document document, INamedTypeSymbol type, CancellationToken cancellationToken)
{
if (type.DeclaringSyntaxReferences.Length != 0)
{
document = document.Project.GetDocument(type.DeclaringSyntaxReferences[0].SyntaxTree);
}
DocumentEditor editor = await DocumentEditor.CreateAsync(document);
DocumentEditor editor = await DocumentEditor.CreateAsync(document).ConfigureAwait(false);
ISymbol[] targets = type.GetAllMembers()
.Where(x => x.Kind == SymbolKind.Property || x.Kind == SymbolKind.Field)
@ -164,7 +164,7 @@ namespace MessagePackAnalyzer
foreach (ISymbol item in targets)
{
SyntaxNode node = await item.DeclaringSyntaxReferences[0].GetSyntaxAsync();
SyntaxNode node = await item.DeclaringSyntaxReferences[0].GetSyntaxAsync().ConfigureAwait(false);
AttributeData attr = item.GetAttributes().FindAttributeShortName(MessagePackAnalyzer.KeyAttributeShortName);
if (attr != null)
@ -180,7 +180,7 @@ namespace MessagePackAnalyzer
if (type.GetAttributes().FindAttributeShortName(MessagePackAnalyzer.MessagePackObjectAttributeShortName) == null)
{
SyntaxNode rootNode = await type.DeclaringSyntaxReferences[0].GetSyntaxAsync();
SyntaxNode rootNode = await type.DeclaringSyntaxReferences[0].GetSyntaxAsync().ConfigureAwait(false);
editor.AddAttribute(rootNode, RoslynExtensions.ParseAttributeList("[MessagePackObject]"));
}

Просмотреть файл

@ -5,7 +5,9 @@
<Rule Id="SA1401" Action="Hidden" />
</Rules>
<Rules AnalyzerId="Microsoft.VisualStudio.Threading.Analyzers" RuleNamespace="Microsoft.VisualStudio.Threading.Analyzers">
<Rule Id="VSTHRD200" Action="Hidden" />
<Rule Id="VSTHRD002" Action="Hidden" />
<Rule Id="VSTHRD103" Action="Hidden" />
<Rule Id="VSTHRD111" Action="None" />
<Rule Id="VSTHRD200" Action="Hidden" />
</Rules>
</RuleSet>