Skip to content

Commit a54c482

Browse files
authored
Fix params argument if type isn't exact much but is implicitly convertible (#2114)
* Fix params argument if type isn't exact much but is implicitly convertible * Don't consider string a collection * Fix
1 parent 2401faf commit a54c482

8 files changed

Lines changed: 543 additions & 5 deletions

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using NUnit.Framework;
2+
using Verifier = TUnit.Analyzers.Tests.Verifiers.CSharpAnalyzerVerifier<TUnit.Analyzers.TestDataAnalyzer>;
3+
4+
namespace TUnit.Analyzers.Tests;
5+
6+
public class ArgumentsAnalyzerTests
7+
{
8+
[Test]
9+
public async Task Test_No_Error()
10+
{
11+
await Verifier
12+
.VerifyAnalyzerAsync(
13+
"""
14+
using TUnit.Core;
15+
16+
public class MyClass
17+
{
18+
[Test]
19+
[Arguments(0, 1L)] // this is ok
20+
[Arguments(0, 1)] // Error TUnit0001 : Attribute argument types 'int' don't match method parameter types 'long[]'
21+
public void Test(int a, params long[] arr)
22+
{
23+
}
24+
}
25+
"""
26+
);
27+
}
28+
}

TUnit.Analyzers/Extensions/TypeExtensions.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,13 @@ public static bool IsAsyncDisposable(this ITypeSymbol type)
124124

125125
public static bool IsCollectionType(this ITypeSymbol typeSymbol, Compilation compilation, [NotNullWhen(true)] out ITypeSymbol? innerType)
126126
{
127+
if (typeSymbol.SpecialType == SpecialType.System_String)
128+
{
129+
// Technically a collection but not what we're looking for
130+
innerType = null;
131+
return false;
132+
}
133+
127134
if (typeSymbol is IArrayTypeSymbol arrayTypeSymbol)
128135
{
129136
innerType = arrayTypeSymbol.ElementType;

TUnit.Analyzers/TestDataAnalyzer.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ private void CheckArguments(SymbolAnalysisContext context, AttributeData argumen
213213
var argument = arguments.ElementAtOrDefault(i);
214214

215215
if (typeSymbol.IsCollectionType(context.Compilation, out var innerType)
216-
&& arguments.Skip(i).Select(x => x.Type).All(x => SymbolEqualityComparer.Default.Equals(x, innerType)))
216+
&& arguments.Skip(i).Select(x => x.Type).All(x => CanConvert(context, x, innerType)))
217217
{
218218
break;
219219
}
@@ -596,17 +596,22 @@ private static bool CanConvert(SymbolAnalysisContext context, TypedConstant argu
596596
return true;
597597
}
598598

599-
if (argument.Type is not null
599+
return CanConvert(context, argument.Type, methodParameterType);
600+
}
601+
602+
private static bool CanConvert(SymbolAnalysisContext context, ITypeSymbol? argumentType, ITypeSymbol? methodParameterType)
603+
{
604+
if (argumentType is not null
600605
&& methodParameterType is not null
601-
&& context.Compilation.ClassifyConversion(argument.Type, methodParameterType)
606+
&& context.Compilation.ClassifyConversion(argumentType, methodParameterType)
602607
is { IsImplicit: true }
603608
or { IsExplicit: true }
604609
or { IsNumeric: true })
605610
{
606611
return true;
607612
}
608613

609-
return context.Compilation.HasImplicitConversionOrGenericParameter(argument.Type, methodParameterType);
614+
return context.Compilation.HasImplicitConversionOrGenericParameter(argumentType, methodParameterType);
610615
}
611616

612617
private bool IsEnumAndInteger(ITypeSymbol? type1, ITypeSymbol? type2)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using TUnit.Core.SourceGenerator.CodeGenerators;
2+
3+
namespace TUnit.Core.SourceGenerator.Tests.Bugs._2112;
4+
5+
internal class Tests2112 : TestsBase<TestsGenerator>
6+
{
7+
[Test]
8+
public Task Test() => RunTest(Path.Combine(Git.RootDirectory.FullName,
9+
"TUnit.TestProject",
10+
"Bugs",
11+
"2112",
12+
"Tests.cs"),
13+
async generatedFiles =>
14+
{
15+
await Assert.That(generatedFiles.Length).IsEqualTo(2);
16+
});
17+
}

0 commit comments

Comments
 (0)