From 5131f5ffb2dfe09177f7002a6386945be393f70e Mon Sep 17 00:00:00 2001 From: Antao Almada Date: Fri, 13 Oct 2023 12:22:16 +0100 Subject: [PATCH] Try using .NET 5 --- .github/workflows/dotnetcore.yml | 2 +- .../HLQ001_AssignmentBoxing.cs | 57 ++--- .../HLQ004_RefEnumerationVariable.cs | 63 +++--- .../HLQ005_AvoidSingleAnalyzer.cs | 77 +++---- .../HLQ006_GetEnumeratorReturnType.cs | 151 +++++++------ .../HLQ007_NonDisposableEnumerator.cs | 213 +++++++++--------- .../HLQ012_UseCollectionsMarshalAsSpan.cs | 69 +++--- .../HLQ013_UseForEachLoop.cs | 69 +++--- .../NetFabric.Hyperlinq.Analyzer.csproj | 2 +- .../Utils/ExpressionSyntaxExtensions.cs | 4 +- .../Utils/TypeSymbolExtensions.cs | 91 ++++---- 11 files changed, 403 insertions(+), 395 deletions(-) diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml index 72f6f1c..4a9a3f2 100644 --- a/.github/workflows/dotnetcore.yml +++ b/.github/workflows/dotnetcore.yml @@ -12,7 +12,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v3 with: - dotnet-version: 6.0.x + dotnet-version: 5.0.x - name: Restore dependencies run: dotnet restore diff --git a/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ001_AssignmentBoxing.cs b/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ001_AssignmentBoxing.cs index 4e92c05..92c1f8c 100644 --- a/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ001_AssignmentBoxing.cs +++ b/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ001_AssignmentBoxing.cs @@ -1,37 +1,38 @@ using BenchmarkDotNet.Attributes; -namespace NetFabric.Hyperlinq.Analyzer.Benchmarks; - -public class HLQ001_AssignmentBoxing +namespace NetFabric.Hyperlinq.Analyzer.Benchmarks { - List? list; - IEnumerable? enumerable; + public class HLQ001_AssignmentBoxing + { + List? list; + IEnumerable? enumerable; - [Params(100, 10_000)] - public int Count { get; set; } + [Params(100, 10_000)] + public int Count { get; set; } - [GlobalSetup] - public void GlobalSetup() - { - list = System.Linq.Enumerable.Range(0, Count).ToList(); - enumerable = list; - } + [GlobalSetup] + public void GlobalSetup() + { + list = System.Linq.Enumerable.Range(0, Count).ToList(); + enumerable = list; + } - [Benchmark(Baseline = true)] - public int Enumerable() - { - var sum = 0; - foreach (var item in enumerable!) - sum += item; - return sum; - } + [Benchmark(Baseline = true)] + public int Enumerable() + { + var sum = 0; + foreach (var item in enumerable!) + sum += item; + return sum; + } - [Benchmark] - public int List() - { - var sum = 0; - foreach (var item in list!) - sum += item; - return sum; + [Benchmark] + public int List() + { + var sum = 0; + foreach (var item in list!) + sum += item; + return sum; + } } } diff --git a/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ004_RefEnumerationVariable.cs b/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ004_RefEnumerationVariable.cs index c351b89..b0b30a2 100644 --- a/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ004_RefEnumerationVariable.cs +++ b/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ004_RefEnumerationVariable.cs @@ -1,45 +1,46 @@ using BenchmarkDotNet.Attributes; -namespace NetFabric.Hyperlinq.Analyzer.Benchmarks; - -public class HLQ004_RefEnumerationVariable +namespace NetFabric.Hyperlinq.Analyzer.Benchmarks { - public readonly record struct Person(string Name, int Age); + public class HLQ004_RefEnumerationVariable + { + public readonly record struct Person(string Name, int Age); - Person[]? people; + Person[]? people; - [Params(100, 10_000)] - public int Count { get; set; } + [Params(100, 10_000)] + public int Count { get; set; } - [GlobalSetup] - public void GlobalSetup() - { - people = Enumerable.Range(0, Count) - .Select(value => new Person(value.ToString(), value)) - .ToArray(); - } + [GlobalSetup] + public void GlobalSetup() + { + people = Enumerable.Range(0, Count) + .Select(value => new Person(value.ToString(), value)) + .ToArray(); + } - [Benchmark(Baseline = true)] - public Person? Copy() - { - var oldest = default(Person); - foreach (var person in people!.AsSpan()) + [Benchmark(Baseline = true)] + public Person? Copy() { - if (person.Age > oldest.Age) - oldest = person; + var oldest = default(Person); + foreach (var person in people!.AsSpan()) + { + if (person.Age > oldest.Age) + oldest = person; + } + return oldest; } - return oldest; - } - [Benchmark] - public Person Ref() - { - var oldest = default(Person); - foreach (ref var person in people!.AsSpan()) + [Benchmark] + public Person Ref() { - if (person.Age > oldest.Age) - oldest = person; + var oldest = default(Person); + foreach (ref var person in people!.AsSpan()) + { + if (person.Age > oldest.Age) + oldest = person; + } + return oldest; } - return oldest; } } diff --git a/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ005_AvoidSingleAnalyzer.cs b/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ005_AvoidSingleAnalyzer.cs index e8c8ee2..a252359 100644 --- a/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ005_AvoidSingleAnalyzer.cs +++ b/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ005_AvoidSingleAnalyzer.cs @@ -1,45 +1,46 @@ using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Configs; -namespace NetFabric.Hyperlinq.Analyzer.Benchmarks; - -[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] -[CategoriesColumn] -public class HLQ005_AvoidSingleAnalyzer +namespace NetFabric.Hyperlinq.Analyzer.Benchmarks { - int[]? bestCase; - int[]? worstCase; - - [Params(100, 10_000)] - public int Count { get; set; } - - [GlobalSetup] - public void GlobalSetup() + [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] + [CategoriesColumn] + public class HLQ005_AvoidSingleAnalyzer { - bestCase = Enumerable.Range(0, Count).ToArray(); - worstCase = bestCase.Reverse().ToArray(); + int[]? bestCase; + int[]? worstCase; + + [Params(100, 10_000)] + public int Count { get; set; } + + [GlobalSetup] + public void GlobalSetup() + { + bestCase = Enumerable.Range(0, Count).ToArray(); + worstCase = bestCase.Reverse().ToArray(); + } + + [BenchmarkCategory("BestCase")] + [Benchmark(Baseline = true)] + public int BestCase_Single() + => bestCase!.Single(Comparer); + + [BenchmarkCategory("BestCase")] + [Benchmark] + public int BestCase_First() + => bestCase!.First(Comparer); + + [BenchmarkCategory("WorstCase")] + [Benchmark(Baseline = true)] + public int WorstCase_Single() + => worstCase!.Single(Comparer); + + [BenchmarkCategory("WorstCase")] + [Benchmark] + public int WorstCase_First() + => worstCase!.First(Comparer); + + static bool Comparer(int value) + => value == 0; } - - [BenchmarkCategory("BestCase")] - [Benchmark(Baseline = true)] - public int BestCase_Single() - => bestCase!.Single(Comparer); - - [BenchmarkCategory("BestCase")] - [Benchmark] - public int BestCase_First() - => bestCase!.First(Comparer); - - [BenchmarkCategory("WorstCase")] - [Benchmark(Baseline = true)] - public int WorstCase_Single() - => worstCase!.Single(Comparer); - - [BenchmarkCategory("WorstCase")] - [Benchmark] - public int WorstCase_First() - => worstCase!.First(Comparer); - - static bool Comparer(int value) - => value == 0; } diff --git a/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ006_GetEnumeratorReturnType.cs b/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ006_GetEnumeratorReturnType.cs index 38221ac..7fd7be2 100644 --- a/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ006_GetEnumeratorReturnType.cs +++ b/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ006_GetEnumeratorReturnType.cs @@ -1,101 +1,102 @@ using BenchmarkDotNet.Attributes; using System.Collections; -namespace NetFabric.Hyperlinq.Analyzer.Benchmarks; - -public class HLQ006_GetEnumeratorReturnType +namespace NetFabric.Hyperlinq.Analyzer.Benchmarks { - TestEnumerable? enumerable; - TestEnumerableOptimized? enumerableOptimized; - - [Params(100, 10_000)] - public int Count { get; set; } - - [GlobalSetup] - public void GlobalSetup() + public class HLQ006_GetEnumeratorReturnType { - var array = System.Linq.Enumerable.Range(0, Count) - .ToArray(); - enumerable = new(array); - enumerableOptimized = new(array); - } + TestEnumerable? enumerable; + TestEnumerableOptimized? enumerableOptimized; - [Benchmark(Baseline = true)] - public int Enumerable() - { - var sum = 0; - foreach (var value in enumerable!) - sum += value; - return sum; - } + [Params(100, 10_000)] + public int Count { get; set; } - [Benchmark] - public int Optimized() - { - var sum = 0; - foreach (var value in enumerableOptimized!) - sum += value; - return sum; - } + [GlobalSetup] + public void GlobalSetup() + { + var array = System.Linq.Enumerable.Range(0, Count) + .ToArray(); + enumerable = new(array); + enumerableOptimized = new(array); + } - public class TestEnumerable - : IEnumerable - { - readonly T[] array; + [Benchmark(Baseline = true)] + public int Enumerable() + { + var sum = 0; + foreach (var value in enumerable!) + sum += value; + return sum; + } - public TestEnumerable(T[] array) - => this.array = array; + [Benchmark] + public int Optimized() + { + var sum = 0; + foreach (var value in enumerableOptimized!) + sum += value; + return sum; + } - public IEnumerator GetEnumerator() - => new Enumerator(array); + public class TestEnumerable + : IEnumerable + { + readonly T[] array; - IEnumerator IEnumerable.GetEnumerator() - => GetEnumerator(); - } + public TestEnumerable(T[] array) + => this.array = array; - public class TestEnumerableOptimized - : IEnumerable - { - readonly T[] array; + public IEnumerator GetEnumerator() + => new Enumerator(array); - public TestEnumerableOptimized(T[] array) - => this.array = array; + IEnumerator IEnumerable.GetEnumerator() + => GetEnumerator(); + } - public Enumerator GetEnumerator() - => new(array); + public class TestEnumerableOptimized + : IEnumerable + { + readonly T[] array; - IEnumerator IEnumerable.GetEnumerator() - => GetEnumerator(); + public TestEnumerableOptimized(T[] array) + => this.array = array; - IEnumerator IEnumerable.GetEnumerator() - => GetEnumerator(); - } + public Enumerator GetEnumerator() + => new(array); - public struct Enumerator - : IEnumerator - { - readonly T[] array; - int index; + IEnumerator IEnumerable.GetEnumerator() + => GetEnumerator(); - public Enumerator(T[] array) - { - this.array = array; - index = -1; + IEnumerator IEnumerable.GetEnumerator() + => GetEnumerator(); } - public readonly T Current - => array[index]; + public struct Enumerator + : IEnumerator + { + readonly T[] array; + int index; + + public Enumerator(T[] array) + { + this.array = array; + index = -1; + } + + public readonly T Current + => array[index]; - readonly object? IEnumerator.Current - => Current; + readonly object? IEnumerator.Current + => Current; - public bool MoveNext() - => ++index < array.Length; + public bool MoveNext() + => ++index < array.Length; - public readonly void Dispose() - { } + public readonly void Dispose() + { } - public void Reset() - => throw new NotImplementedException(); + public void Reset() + => throw new NotImplementedException(); + } } } diff --git a/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ007_NonDisposableEnumerator.cs b/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ007_NonDisposableEnumerator.cs index 931d1c2..6e406af 100644 --- a/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ007_NonDisposableEnumerator.cs +++ b/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ007_NonDisposableEnumerator.cs @@ -2,140 +2,141 @@ using System.Collections; using System.Runtime.CompilerServices; -namespace NetFabric.Hyperlinq.Analyzer.Benchmarks; - -public class HLQ007_NonDisposableEnumerator +namespace NetFabric.Hyperlinq.Analyzer.Benchmarks { - TestEnumerableDisposable? enumerableDisposable; - TestEnumerable? enumerable; - - [Params(100_000)] - public int Count { get; set; } - - [GlobalSetup] - public void GlobalSetup() + public class HLQ007_NonDisposableEnumerator { - var array = Enumerable.Range(0, 10) - .ToArray(); - enumerableDisposable = new(array); - enumerable = new(array); - } + TestEnumerableDisposable? enumerableDisposable; + TestEnumerable? enumerable; - [Benchmark(Baseline = true)] - public int Disposable() - { - var sum = 0; - for(var count = 0; count < Count; count++) - sum += SumDisposable(enumerableDisposable!); - return sum; - } + [Params(100_000)] + public int Count { get; set; } - [Benchmark] - public int NonDisposable() - { - var sum = 0; - for (var count = 0; count < Count; count++) - sum += Sum(enumerable!); - return sum; - } + [GlobalSetup] + public void GlobalSetup() + { + var array = Enumerable.Range(0, 10) + .ToArray(); + enumerableDisposable = new(array); + enumerable = new(array); + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int Sum(TestEnumerable values) - { - var sum = 0; - foreach (var value in values) - sum += value; - return sum; - } + [Benchmark(Baseline = true)] + public int Disposable() + { + var sum = 0; + for(var count = 0; count < Count; count++) + sum += SumDisposable(enumerableDisposable!); + return sum; + } - //[MethodImpl(MethodImplOptions.AggressiveInlining)] - public int SumDisposable(TestEnumerableDisposable values) - { - var sum = 0; - foreach (var value in values) - sum += value; - return sum; - } + [Benchmark] + public int NonDisposable() + { + var sum = 0; + for (var count = 0; count < Count; count++) + sum += Sum(enumerable!); + return sum; + } - public class TestEnumerable - : IEnumerable - { - readonly T[] array; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int Sum(TestEnumerable values) + { + var sum = 0; + foreach (var value in values) + sum += value; + return sum; + } - public TestEnumerable(T[] array) - => this.array = array; + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public int SumDisposable(TestEnumerableDisposable values) + { + var sum = 0; + foreach (var value in values) + sum += value; + return sum; + } - public Enumerator GetEnumerator() - => new(array); + public class TestEnumerable + : IEnumerable + { + readonly T[] array; - IEnumerator IEnumerable.GetEnumerator() - => new DisposableEnumerator(); + public TestEnumerable(T[] array) + => this.array = array; - IEnumerator IEnumerable.GetEnumerator() - => new DisposableEnumerator(); - } + public Enumerator GetEnumerator() + => new(array); - public class TestEnumerableDisposable - : IEnumerable - { - readonly T[] array; + IEnumerator IEnumerable.GetEnumerator() + => new DisposableEnumerator(); - public TestEnumerableDisposable(T[] array) - => this.array = array; + IEnumerator IEnumerable.GetEnumerator() + => new DisposableEnumerator(); + } - public DisposableEnumerator GetEnumerator() - => new(array); + public class TestEnumerableDisposable + : IEnumerable + { + readonly T[] array; - IEnumerator IEnumerable.GetEnumerator() - => GetEnumerator(); + public TestEnumerableDisposable(T[] array) + => this.array = array; - IEnumerator IEnumerable.GetEnumerator() - => GetEnumerator(); - } + public DisposableEnumerator GetEnumerator() + => new(array); - public struct Enumerator - { - readonly T[] array; - int index; + IEnumerator IEnumerable.GetEnumerator() + => GetEnumerator(); - public Enumerator(T[] array) - { - this.array = array; - index = -1; + IEnumerator IEnumerable.GetEnumerator() + => GetEnumerator(); } - public readonly T Current - => array[index]; + public struct Enumerator + { + readonly T[] array; + int index; - public bool MoveNext() - => ++index < array.Length; - } + public Enumerator(T[] array) + { + this.array = array; + index = -1; + } - public struct DisposableEnumerator - : IEnumerator - { - readonly T[] array; - int index; + public readonly T Current + => array[index]; - public DisposableEnumerator(T[] array) - { - this.array = array; - index = -1; + public bool MoveNext() + => ++index < array.Length; } - public readonly T Current - => array[index]; + public struct DisposableEnumerator + : IEnumerator + { + readonly T[] array; + int index; + + public DisposableEnumerator(T[] array) + { + this.array = array; + index = -1; + } - readonly object? IEnumerator.Current - => Current; + public readonly T Current + => array[index]; - public bool MoveNext() - => ++index < array.Length; + readonly object? IEnumerator.Current + => Current; - public readonly void Dispose() - { } + public bool MoveNext() + => ++index < array.Length; - public void Reset() - => throw new NotImplementedException(); + public readonly void Dispose() + { } + + public void Reset() + => throw new NotImplementedException(); + } } } diff --git a/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ012_UseCollectionsMarshalAsSpan.cs b/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ012_UseCollectionsMarshalAsSpan.cs index 7592c70..3682828 100644 --- a/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ012_UseCollectionsMarshalAsSpan.cs +++ b/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ012_UseCollectionsMarshalAsSpan.cs @@ -1,45 +1,46 @@ using BenchmarkDotNet.Attributes; using System.Runtime.InteropServices; -namespace NetFabric.Hyperlinq.Analyzer.Benchmarks; - -public class HLQ012_UseCollectionsMarshalAsSpan +namespace NetFabric.Hyperlinq.Analyzer.Benchmarks { - List? list; + public class HLQ012_UseCollectionsMarshalAsSpan + { + List? list; - [Params(0, 10, 100, 1_000)] - public int Count { get; set; } + [Params(0, 10, 100, 1_000)] + public int Count { get; set; } - [GlobalSetup] - public void GlobalSetup() - { - list = Enumerable.Range(0, Count).ToList(); - } + [GlobalSetup] + public void GlobalSetup() + { + list = Enumerable.Range(0, Count).ToList(); + } - [Benchmark(Baseline = true)] - public int ForEach() - { - var sum = 0; - foreach (var angle in list!) - sum += angle; - return sum; - } + [Benchmark(Baseline = true)] + public int ForEach() + { + var sum = 0; + foreach (var angle in list!) + sum += angle; + return sum; + } - [Benchmark] - public int For() - { - var sum = 0; - for (var index = 0; index < list!.Count; index++) - sum += list![index]; - return sum; - } + [Benchmark] + public int For() + { + var sum = 0; + for (var index = 0; index < list!.Count; index++) + sum += list![index]; + return sum; + } - [Benchmark] - public int ForEachAsSpan() - { - var sum = 0; - foreach (var angle in CollectionsMarshal.AsSpan(list!)) - sum += angle; - return sum; + [Benchmark] + public int ForEachAsSpan() + { + var sum = 0; + foreach (var angle in CollectionsMarshal.AsSpan(list!)) + sum += angle; + return sum; + } } } diff --git a/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ013_UseForEachLoop.cs b/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ013_UseForEachLoop.cs index b45a759..65f3887 100644 --- a/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ013_UseForEachLoop.cs +++ b/NetFabric.Hyperlinq.Analyzer.Benchmarks/HLQ013_UseForEachLoop.cs @@ -1,44 +1,45 @@ using BenchmarkDotNet.Attributes; -namespace NetFabric.Hyperlinq.Analyzer.Benchmarks; - -public class HLQ013_UseForEachLoop +namespace NetFabric.Hyperlinq.Analyzer.Benchmarks { - int[]? array; + public class HLQ013_UseForEachLoop + { + int[]? array; - [Params(10, 1_000)] - public int Count { get; set; } + [Params(10, 1_000)] + public int Count { get; set; } - [GlobalSetup] - public void GlobalSetup() - { - array = Enumerable.Range(0, Count).ToArray(); - } + [GlobalSetup] + public void GlobalSetup() + { + array = Enumerable.Range(0, Count).ToArray(); + } - [Benchmark(Baseline = true)] - public int For() - { - var sum = 0; - for (var index = 0; index < Count; index++) - sum += array![index]; - return sum; - } + [Benchmark(Baseline = true)] + public int For() + { + var sum = 0; + for (var index = 0; index < Count; index++) + sum += array![index]; + return sum; + } - [Benchmark] - public int ForEach() - { - var sum = 0; - foreach (var item in array!) - sum += item; - return sum; - } + [Benchmark] + public int ForEach() + { + var sum = 0; + foreach (var item in array!) + sum += item; + return sum; + } - [Benchmark] - public int ForEach_Span() - { - var sum = 0; - foreach (var item in array!.AsSpan()[..Count]) - sum += item; - return sum; + [Benchmark] + public int ForEach_Span() + { + var sum = 0; + foreach (var item in array!.AsSpan()[..Count]) + sum += item; + return sum; + } } } diff --git a/NetFabric.Hyperlinq.Analyzer/NetFabric.Hyperlinq.Analyzer.csproj b/NetFabric.Hyperlinq.Analyzer/NetFabric.Hyperlinq.Analyzer.csproj index cda52be..18d0fb9 100644 --- a/NetFabric.Hyperlinq.Analyzer/NetFabric.Hyperlinq.Analyzer.csproj +++ b/NetFabric.Hyperlinq.Analyzer/NetFabric.Hyperlinq.Analyzer.csproj @@ -3,7 +3,7 @@ netstandard2.0 false - 10 + 9 True *$(MSBuildProjectFile)* diff --git a/NetFabric.Hyperlinq.Analyzer/Utils/ExpressionSyntaxExtensions.cs b/NetFabric.Hyperlinq.Analyzer/Utils/ExpressionSyntaxExtensions.cs index 6382c0b..d7d9256 100644 --- a/NetFabric.Hyperlinq.Analyzer/Utils/ExpressionSyntaxExtensions.cs +++ b/NetFabric.Hyperlinq.Analyzer/Utils/ExpressionSyntaxExtensions.cs @@ -9,14 +9,14 @@ static class ExpressionSyntaxExtensions public static bool IsIncrementAssignment(this ExpressionSyntax? expression, [NotNullWhen(true)] out string? identifier) { // check if it's something like `index++` - if (expression is PostfixUnaryExpressionSyntax { OperatorToken.ValueText: "++" } postfixIncrementExpression) + if (expression is PostfixUnaryExpressionSyntax postfixIncrementExpression && postfixIncrementExpression.OperatorToken.ValueText == "++") { identifier = postfixIncrementExpression.Operand.ToString(); return true; } // check if it's something like `++index` - if (expression is PrefixUnaryExpressionSyntax { OperatorToken.ValueText: "++" } prefixIncrementExpression) + if (expression is PrefixUnaryExpressionSyntax prefixIncrementExpression && prefixIncrementExpression.OperatorToken.ValueText == "++") { identifier = prefixIncrementExpression.Operand.ToString(); return true; diff --git a/NetFabric.Hyperlinq.Analyzer/Utils/TypeSymbolExtensions.cs b/NetFabric.Hyperlinq.Analyzer/Utils/TypeSymbolExtensions.cs index b8589d4..d791926 100644 --- a/NetFabric.Hyperlinq.Analyzer/Utils/TypeSymbolExtensions.cs +++ b/NetFabric.Hyperlinq.Analyzer/Utils/TypeSymbolExtensions.cs @@ -2,65 +2,66 @@ using NetFabric.CodeAnalysis; using System.Diagnostics.CodeAnalysis; -namespace NetFabric.Hyperlinq.Analyzer; - -static class TypeSymbolExtensions +namespace NetFabric.Hyperlinq.Analyzer { - public static bool IsForEachOptimized(this ITypeSymbol typeSymbol) - { - if (typeSymbol is IArrayTypeSymbol) - return true; - - var namedTypeSymbol = typeSymbol.OriginalDefinition.ToString(); - return namedTypeSymbol - is "System.Span" - or "System.ReadOnlySpan" - or "System.Collections.Immutable.ImmutableArray"; - } - - public static bool IsList(this ITypeSymbol typeSymbol, [NotNullWhen(true)] out ITypeSymbol? itemType) + static class TypeSymbolExtensions { - if (typeSymbol is INamedTypeSymbol namedTypeSymbol && - namedTypeSymbol.IsGenericType && - namedTypeSymbol.OriginalDefinition.ToString() == "System.Collections.Generic.List") + public static bool IsForEachOptimized(this ITypeSymbol typeSymbol) { - itemType = namedTypeSymbol.TypeArguments[0]; - return true; - } + if (typeSymbol is IArrayTypeSymbol) + return true; - itemType = default; - return false; - } + var namedTypeSymbol = typeSymbol.OriginalDefinition.ToString(); + return namedTypeSymbol + is "System.Span" + or "System.ReadOnlySpan" + or "System.Collections.Immutable.ImmutableArray"; + } - public static bool IsEnumerableOrAsyncEnumerable(this ITypeSymbol typeSymbol, Compilation compilation, [NotNullWhen(true)] out ITypeSymbol? enumeratorType) - { - if (typeSymbol is not null) + public static bool IsList(this ITypeSymbol typeSymbol, [NotNullWhen(true)] out ITypeSymbol? itemType) { - if (typeSymbol.IsEnumerable(compilation, out var enumerableSymbols)) + if (typeSymbol is INamedTypeSymbol namedTypeSymbol && + namedTypeSymbol.IsGenericType && + namedTypeSymbol.OriginalDefinition.ToString() == "System.Collections.Generic.List") { - enumeratorType = enumerableSymbols.GetEnumerator.ReturnType; + itemType = namedTypeSymbol.TypeArguments[0]; return true; } - if (typeSymbol.IsAsyncEnumerable(compilation, out var asyncEnumerableSymbols)) + itemType = default; + return false; + } + + public static bool IsEnumerableOrAsyncEnumerable(this ITypeSymbol typeSymbol, Compilation compilation, [NotNullWhen(true)] out ITypeSymbol? enumeratorType) + { + if (typeSymbol is not null) { - enumeratorType = asyncEnumerableSymbols.GetAsyncEnumerator.ReturnType; - return true; + if (typeSymbol.IsEnumerable(compilation, out var enumerableSymbols)) + { + enumeratorType = enumerableSymbols.GetEnumerator.ReturnType; + return true; + } + + if (typeSymbol.IsAsyncEnumerable(compilation, out var asyncEnumerableSymbols)) + { + enumeratorType = asyncEnumerableSymbols.GetAsyncEnumerator.ReturnType; + return true; + } } - } - enumeratorType = default; - return false; - } + enumeratorType = default; + return false; + } - public static bool IsEnumerator(this ITypeSymbol type) - => type.ImplementsInterface(SpecialType.System_Collections_IEnumerator, out _) || - (type.GetPublicReadProperty("Current") is not null && type.GetPublicMethod("MoveNext") is not null); + public static bool IsEnumerator(this ITypeSymbol type) + => type.ImplementsInterface(SpecialType.System_Collections_IEnumerator, out _) || + (type.GetPublicReadProperty("Current") is not null && type.GetPublicMethod("MoveNext") is not null); - public static bool IsAsyncEnumerator(this ITypeSymbol type, Compilation compilation) - { - var asyncEnumeratorType = compilation.GetTypeByMetadataName("System.Collections.Generic.IAsyncEnumerator`1"); - return (asyncEnumeratorType is not null && type.ImplementsInterface(asyncEnumeratorType, out _)) || - (type.GetPublicReadProperty("Current") is not null && type.GetPublicMethod("MoveNextAsync") is not null); + public static bool IsAsyncEnumerator(this ITypeSymbol type, Compilation compilation) + { + var asyncEnumeratorType = compilation.GetTypeByMetadataName("System.Collections.Generic.IAsyncEnumerator`1"); + return (asyncEnumeratorType is not null && type.ImplementsInterface(asyncEnumeratorType, out _)) || + (type.GetPublicReadProperty("Current") is not null && type.GetPublicMethod("MoveNextAsync") is not null); + } } }