Skip to content

Commit

Permalink
Cache symbols for performance
Browse files Browse the repository at this point in the history
  • Loading branch information
meziantou committed Dec 5, 2023
1 parent a6d847d commit 0b8137f
Show file tree
Hide file tree
Showing 19 changed files with 292 additions and 287 deletions.
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[Meziantou.FluentAssertionsAnalyzers.Tests/**/*.cs]

# MA0004: Use Task.ConfigureAwait(false)
dotnet_diagnostic.MA0004.severity = none
6 changes: 3 additions & 3 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ defaults:

jobs:
create_nuget:
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET Core
Expand All @@ -37,7 +37,7 @@ jobs:
TestResultsDirectory: ${{ github.workspace}}/TestResults
strategy:
matrix:
runs-on: [ ubuntu-20.04, windows-2019 ]
runs-on: [ ubuntu-latest, windows-latest ]
configuration: [ Debug, Release ]
fail-fast: false
steps:
Expand All @@ -55,7 +55,7 @@ jobs:
path: ${{ env.TestResultsDirectory }}/*.trx

deploy:
runs-on: 'ubuntu-20.04'
runs-on: 'ubuntu-latest'
needs: [ create_nuget, build_and_test ]
steps:
- uses: actions/download-artifact@v3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,24 @@ public sealed partial class ProjectBuilder
{
public async Task ValidateAsync()
{
if (DiagnosticAnalyzer == null)
if (DiagnosticAnalyzer is null)
{
Assert.True(false, "DiagnosticAnalyzer is not configured");
}

if (ExpectedFixedCode != null && CodeFixProviders.Count == 0)
if (ExpectedFixedCode is not null && CodeFixProviders.Count == 0)
{
Assert.True(false, "CodeFixProvider is not configured");
}

if (ExpectedDiagnosticResults == null)
if (ExpectedDiagnosticResults is null)
{
Assert.True(false, "ExpectedDiagnostic is not configured");
}

await VerifyDiagnostic(ExpectedDiagnosticResults).ConfigureAwait(false);

if (ExpectedFixedCode != null)
if (ExpectedFixedCode is not null)
{
await VerifyFix(DiagnosticAnalyzer, CodeFixProviders, ExpectedFixedCode, CodeFixIndex).ConfigureAwait(false);
}
Expand All @@ -63,7 +63,7 @@ private static void VerifyDiagnosticResults(IReadOnlyCollection<Diagnostic> actu

if (expectedCount != actualCount)
{
var diagnosticsOutput = actualResults.Any() ? FormatDiagnostics(analyzer, actualResults.ToArray()) : " NONE.";
var diagnosticsOutput = actualResults.Count != 0 ? FormatDiagnostics(analyzer, [.. actualResults]) : " NONE.";

Assert.True(false, $"Mismatch between number of diagnostics returned, expected \"{expectedCount}\" actual \"{actualCount}\"\r\n\r\nDiagnostics:\r\n{diagnosticsOutput}\r\n");
}
Expand Down Expand Up @@ -102,21 +102,21 @@ private static void VerifyDiagnosticResults(IReadOnlyCollection<Diagnostic> actu
}
}

if (expected.Id != null && !string.Equals(actual.Id, expected.Id, StringComparison.Ordinal))
if (expected.Id is not null && !string.Equals(actual.Id, expected.Id, StringComparison.Ordinal))
{
Assert.True(false,
string.Format(CultureInfo.InvariantCulture, "Expected diagnostic id to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
expected.Id, actual.Id, FormatDiagnostics(analyzer, actual)));
}

if (expected.Severity != null && actual.Severity != expected.Severity)
if (expected.Severity is not null && actual.Severity != expected.Severity)
{
Assert.True(false,
string.Format(CultureInfo.InvariantCulture, "Expected diagnostic severity to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
expected.Severity, actual.Severity, FormatDiagnostics(analyzer, actual)));
}

if (expected.Message != null && !string.Equals(actual.GetMessage(), expected.Message, StringComparison.Ordinal))
if (expected.Message is not null && !string.Equals(actual.GetMessage(), expected.Message, StringComparison.Ordinal))
{
Assert.True(false,
string.Format(CultureInfo.InvariantCulture, "Expected diagnostic message to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
Expand Down Expand Up @@ -249,7 +249,7 @@ private async Task<Diagnostic[]> GetSortedDiagnosticsFromDocuments(DiagnosticAna
{
string sourceCode = null;
var document = project.Documents.FirstOrDefault();
if (document != null)
if (document is not null)
{
sourceCode = (await document.GetSyntaxRootAsync().ConfigureAwait(false)).ToFullString();
}
Expand All @@ -262,7 +262,7 @@ private async Task<Diagnostic[]> GetSortedDiagnosticsFromDocuments(DiagnosticAna
var analyzerOptionsProvider = new TestAnalyzerConfigOptionsProvider(AnalyzerConfiguration);

var compilationWithAnalyzers = compilation.WithAnalyzers(
ImmutableArray.Create(analyzer),
[analyzer],
new AnalyzerOptions(additionalFiles, analyzerOptionsProvider));
var diags = await compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync(compilationWithAnalyzers.CancellationToken).ConfigureAwait(false);
foreach (var diag in diags)
Expand Down Expand Up @@ -303,7 +303,7 @@ private static string FormatDiagnostics(DiagnosticAnalyzer analyzer, params Diag

foreach (var rule in rules)
{
if (rule != null && string.Equals(rule.Id, diagnostics[i].Id, StringComparison.Ordinal))
if (rule is not null && string.Equals(rule.Id, diagnostics[i].Id, StringComparison.Ordinal))
{
var location = diagnostics[i].Location;
if (location == Location.None)
Expand Down Expand Up @@ -342,15 +342,15 @@ private static string FormatDiagnostics(DiagnosticAnalyzer analyzer, params Diag

private static Diagnostic[] SortDiagnostics(IEnumerable<Diagnostic> diagnostics)
{
return diagnostics.OrderBy(d => d.Location.SourceSpan.Start).ToArray();
return [.. diagnostics.OrderBy(d => d.Location.SourceSpan.Start)];
}

[DebuggerStepThrough]
private static void VerifyDiagnosticLocation(DiagnosticAnalyzer analyzer, Diagnostic diagnostic, Location actual, in DiagnosticResultLocation expected)
{
var actualSpan = actual.GetLineSpan();

Assert.True(string.Equals(actualSpan.Path, expected.Path, StringComparison.Ordinal) || (actualSpan.Path != null && actualSpan.Path.StartsWith("Test", StringComparison.Ordinal) && expected.Path.EndsWith(".cs", StringComparison.Ordinal)),
Assert.True(string.Equals(actualSpan.Path, expected.Path, StringComparison.Ordinal) || (actualSpan.Path is not null && actualSpan.Path.StartsWith("Test", StringComparison.Ordinal) && expected.Path.EndsWith(".cs", StringComparison.Ordinal)),
string.Format(CultureInfo.InvariantCulture, "Expected diagnostic to be in file \"{0}\" was actually in file \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
expected.Path, actualSpan.Path, FormatDiagnostics(analyzer, diagnostic)));

Expand Down Expand Up @@ -416,7 +416,7 @@ private async Task VerifyFix(DiagnosticAnalyzer analyzer, IEnumerable<CodeFixPro
{
var project = await CreateProject().ConfigureAwait(false);
var document = project.Documents.First();
var analyzerDiagnostics = await GetSortedDiagnosticsFromDocuments(analyzer, new[] { document }, compileSolution: false).ConfigureAwait(false);
var analyzerDiagnostics = await GetSortedDiagnosticsFromDocuments(analyzer, [document], compileSolution: false).ConfigureAwait(false);
var compilerDiagnostics = await GetCompilerDiagnostics(document).ConfigureAwait(false);

// Assert fixer is value
Expand Down Expand Up @@ -471,14 +471,14 @@ private async Task VerifyFix(DiagnosticAnalyzer analyzer, IEnumerable<CodeFixPro
if (actions.Count == 0)
break;

if (codeFixIndex != null)
if (codeFixIndex is not null)
{
document = await ApplyFix(document, actions[(int)codeFixIndex]).ConfigureAwait(false);
break;
}

document = await ApplyFix(document, actions[0]).ConfigureAwait(false);
analyzerDiagnostics = await GetSortedDiagnosticsFromDocuments(analyzer, new[] { document }, compileSolution: false).ConfigureAwait(false);
analyzerDiagnostics = await GetSortedDiagnosticsFromDocuments(analyzer, [document], compileSolution: false).ConfigureAwait(false);
}
}

Expand All @@ -487,7 +487,7 @@ private async Task VerifyFix(DiagnosticAnalyzer analyzer, IEnumerable<CodeFixPro
Assert.Equal(newSource, actual, ignoreLineEndingDifferences: true);

// Ensure the code fix compiles
_ = await GetSortedDiagnosticsFromDocuments(analyzer, new[] { document }, compileSolution: true).ConfigureAwait(false);
_ = await GetSortedDiagnosticsFromDocuments(analyzer, [document], compileSolution: true).ConfigureAwait(false);
}

private static async Task<Document> ApplyFix(Document document, CodeAction codeAction)
Expand All @@ -505,15 +505,8 @@ private static async Task<string> GetStringFromDocument(Document document)
return root.GetText().ToString();
}

private sealed class CustomDiagnosticProvider : FixAllContext.DiagnosticProvider
private sealed class CustomDiagnosticProvider(Diagnostic[] diagnostics) : FixAllContext.DiagnosticProvider
{
private readonly Diagnostic[] _diagnostics;

public CustomDiagnosticProvider(Diagnostic[] diagnostics)
{
_diagnostics = diagnostics;
}

public override Task<IEnumerable<Diagnostic>> GetAllDiagnosticsAsync(Project project, CancellationToken cancellationToken)
{
return GetProjectDiagnosticsAsync(project, cancellationToken);
Expand All @@ -522,13 +515,12 @@ public override Task<IEnumerable<Diagnostic>> GetAllDiagnosticsAsync(Project pro
public override async Task<IEnumerable<Diagnostic>> GetDocumentDiagnosticsAsync(Document document, CancellationToken cancellationToken)
{
var documentRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
return _diagnostics.Where(diagnostic => documentRoot == diagnostic.Location.SourceTree.GetRoot(cancellationToken));
return diagnostics.Where(diagnostic => documentRoot == diagnostic.Location.SourceTree.GetRoot(cancellationToken));
}

public override Task<IEnumerable<Diagnostic>> GetProjectDiagnosticsAsync(Project project, CancellationToken cancellationToken)
{
var diagnostics = project.Documents.SelectMany(doc => GetDocumentDiagnosticsAsync(doc, cancellationToken).Result);
return Task.FromResult(diagnostics);
return Task.FromResult(project.Documents.SelectMany(doc => GetDocumentDiagnosticsAsync(doc, cancellationToken).Result));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ async Task<string[]> Download()
{
Directory.CreateDirectory(tempFolder);
using var httpClient = new HttpClient();
using var stream = await httpClient.GetStreamAsync(new Uri($"https://www.nuget.org/api/v2/package/{packageName}/{version}")).ConfigureAwait(false);
await using var stream = await httpClient.GetStreamAsync(new Uri($"https://www.nuget.org/api/v2/package/{packageName}/{version}")).ConfigureAwait(false);
using var zip = new ZipArchive(stream, ZipArchiveMode.Read);

foreach (var entry in zip.Entries.Where(file => file.FullName.StartsWith(path, StringComparison.Ordinal)))
Expand All @@ -70,7 +70,7 @@ async Task<string[]> Download()

try
{
using var stream = File.OpenRead(dll);
await using var stream = File.OpenRead(dll);
using var peFile = new PEReader(stream);
var metadataReader = peFile.GetMetadataReader();
result.Add(dll);
Expand All @@ -81,7 +81,7 @@ async Task<string[]> Download()
}

Assert.NotEmpty(result);
return result.ToArray();
return [.. result];
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,17 @@

namespace Meziantou.FluentAssertionsAnalyzers.Tests.Helpers;

internal sealed class TestAnalyzerConfigOptionsProvider : AnalyzerConfigOptionsProvider
internal sealed class TestAnalyzerConfigOptionsProvider(IDictionary<string, string> values) : AnalyzerConfigOptionsProvider
{
private readonly IDictionary<string, string> _values;

public TestAnalyzerConfigOptionsProvider(IDictionary<string, string> values)
{
_values = values ?? new Dictionary<string, string>(StringComparer.Ordinal);
}
private readonly IDictionary<string, string> _values = values ?? new Dictionary<string, string>(StringComparer.Ordinal);

public override AnalyzerConfigOptions GlobalOptions => new TestAnalyzerConfigOptions(_values);
public override AnalyzerConfigOptions GetOptions(SyntaxTree tree) => new TestAnalyzerConfigOptions(_values);
public override AnalyzerConfigOptions GetOptions(AdditionalText textFile) => new TestAnalyzerConfigOptions(_values);

private sealed class TestAnalyzerConfigOptions : AnalyzerConfigOptions
private sealed class TestAnalyzerConfigOptions(IDictionary<string, string> values) : AnalyzerConfigOptions
{
private readonly IDictionary<string, string> _values;

public TestAnalyzerConfigOptions(IDictionary<string, string> values)
{
_values = values;
}
private readonly IDictionary<string, string> _values = values;

public override bool TryGetValue(string key, out string value)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand Down
7 changes: 0 additions & 7 deletions Meziantou.FluentAssertionsAnalyzers.lutconfig

This file was deleted.

76 changes: 38 additions & 38 deletions Meziantou.FluentAssertionsAnalyzers.sln
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.3.32505.426
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meziantou.FluentAssertionsAnalyzers", "Meziantou.FluentAssertionsAnalyzers\Meziantou.FluentAssertionsAnalyzers.csproj", "{BF5457B6-418B-4CFA-9C5A-636B52A776F6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meziantou.FluentAssertionsAnalyzers.Tests", "Meziantou.FluentAssertionsAnalyzers.Tests\Meziantou.FluentAssertionsAnalyzers.Tests.csproj", "{0F21616A-F924-42CA-B7C6-0E9ED4416776}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B1EC2E1E-AD5D-472B-ABD8-F9045D57155A}"
ProjectSection(SolutionItems) = preProject
Directory.Build.props = Directory.Build.props
README.md = README.md
global.json = global.json
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{BF5457B6-418B-4CFA-9C5A-636B52A776F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BF5457B6-418B-4CFA-9C5A-636B52A776F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF5457B6-418B-4CFA-9C5A-636B52A776F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BF5457B6-418B-4CFA-9C5A-636B52A776F6}.Release|Any CPU.Build.0 = Release|Any CPU
{0F21616A-F924-42CA-B7C6-0E9ED4416776}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0F21616A-F924-42CA-B7C6-0E9ED4416776}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0F21616A-F924-42CA-B7C6-0E9ED4416776}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0F21616A-F924-42CA-B7C6-0E9ED4416776}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {1FB14A4F-BE40-45B2-8848-8BA80822621A}
EndGlobalSection
EndGlobal

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.3.32505.426
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meziantou.FluentAssertionsAnalyzers", "Meziantou.FluentAssertionsAnalyzers\Meziantou.FluentAssertionsAnalyzers.csproj", "{BF5457B6-418B-4CFA-9C5A-636B52A776F6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meziantou.FluentAssertionsAnalyzers.Tests", "Meziantou.FluentAssertionsAnalyzers.Tests\Meziantou.FluentAssertionsAnalyzers.Tests.csproj", "{0F21616A-F924-42CA-B7C6-0E9ED4416776}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B1EC2E1E-AD5D-472B-ABD8-F9045D57155A}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
Directory.Build.props = Directory.Build.props
README.md = README.md
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{BF5457B6-418B-4CFA-9C5A-636B52A776F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BF5457B6-418B-4CFA-9C5A-636B52A776F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF5457B6-418B-4CFA-9C5A-636B52A776F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BF5457B6-418B-4CFA-9C5A-636B52A776F6}.Release|Any CPU.Build.0 = Release|Any CPU
{0F21616A-F924-42CA-B7C6-0E9ED4416776}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0F21616A-F924-42CA-B7C6-0E9ED4416776}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0F21616A-F924-42CA-B7C6-0E9ED4416776}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0F21616A-F924-42CA-B7C6-0E9ED4416776}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {1FB14A4F-BE40-45B2-8848-8BA80822621A}
EndGlobalSection
EndGlobal
Loading

0 comments on commit 0b8137f

Please sign in to comment.