Skip to content

Commit

Permalink
fix(CA2208): false positive when message start with parameter name fo…
Browse files Browse the repository at this point in the history
…llowed by punctuation
  • Loading branch information
HenryZhang-ZHY authored and github-actions committed Dec 12, 2023
1 parent 7e5f473 commit 93e7073
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -150,15 +150,14 @@ public override void Initialize(AnalysisContext context)
string stringArgument,
OperationAnalysisContext context)
{
bool matchesParameter = MatchesParameter(targetSymbol, creation, stringArgument);

if (IsMessage(parameter) && matchesParameter)
if (IsMessage(parameter) && MatchesParameterStrict(targetSymbol, creation, stringArgument))
{
var dictBuilder = ImmutableDictionary.CreateBuilder<string, string?>();
dictBuilder.Add(MessagePosition, parameter.Ordinal.ToString(CultureInfo.InvariantCulture));
return context.Operation.CreateDiagnostic(RuleIncorrectMessage, dictBuilder.ToImmutable(), targetSymbol.Name, stringArgument, parameter.Name, creation.Type!.Name);
}
else if (HasParameters(targetSymbol) && IsParameterName(parameter) && !matchesParameter)

if (HasParameters(targetSymbol) && IsParameterName(parameter) && !MatchesParameterRelax(targetSymbol, creation, stringArgument))
{
// Allow argument exceptions in accessors to use the associated property symbol name.
if (!MatchesAssociatedSymbol(targetSymbol, stringArgument))
Expand Down Expand Up @@ -202,9 +201,19 @@ private static bool HasParameterNameConstructor(ITypeSymbol type)
return false;
}

private static bool MatchesParameter(ISymbol? symbol, IObjectCreationOperation creation, string stringArgumentValue)
private static bool MatchesParameterStrict(ISymbol? symbol, IObjectCreationOperation creation, string stringArgumentValue)
{
return MatchesParameterCore(symbol, creation, stringArgumentValue, strict: true);
}

private static bool MatchesParameterRelax(ISymbol? symbol, IObjectCreationOperation creation, string stringArgumentValue)
{
return MatchesParameterCore(symbol, creation, stringArgumentValue, strict: false);
}

private static bool MatchesParameterCore(ISymbol? symbol, IObjectCreationOperation creation, string stringArgumentValue, bool strict)
{
if (MatchesParameterCore(symbol, stringArgumentValue))
if (MatchesParameterCore(symbol, stringArgumentValue, strict))
{
return true;
}
Expand All @@ -224,7 +233,7 @@ private static bool MatchesParameter(ISymbol? symbol, IObjectCreationOperation c
break;
}

if (symbol != null && MatchesParameterCore(symbol, stringArgumentValue))
if (symbol != null && MatchesParameterCore(symbol, stringArgumentValue, strict))
{
return true;
}
Expand All @@ -235,7 +244,7 @@ private static bool MatchesParameter(ISymbol? symbol, IObjectCreationOperation c
return false;
}

private static bool MatchesParameterCore(ISymbol? symbol, string stringArgumentValue)
private static bool MatchesParameterCore(ISymbol? symbol, string stringArgumentValue, bool strict)
{
foreach (IParameterSymbol parameter in symbol.GetParameters())
{
Expand All @@ -245,13 +254,16 @@ private static bool MatchesParameterCore(ISymbol? symbol, string stringArgumentV
return true;
}

// If the string argument begins with the parameter name followed by punctuation, it's also considered a match.
// e.g. "arg.Length", "arg[0]", etc.
if (stringArgumentValue.Length > parameter.Name.Length &&
stringArgumentValue.StartsWith(parameter.Name, StringComparison.Ordinal) &&
char.IsPunctuation(stringArgumentValue, parameter.Name.Length))
if (!strict)
{
return true;
// If the string argument begins with the parameter name followed by punctuation, it's also considered a match.
// e.g. "arg.Length", "arg[0]", etc.
if (stringArgumentValue.Length > parameter.Name.Length &&
stringArgumentValue.StartsWith(parameter.Name, StringComparison.Ordinal) &&
char.IsPunctuation(stringArgumentValue, parameter.Name.Length))
{
return true;
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,35 @@ End Sub
End Class");
}

[Fact, WorkItem(6863, "https://github.com/dotnet/roslyn-analyzers/issues/6863")]
public async Task ArgumentException_MessageStartWithParameterNameFollowedByPunctuation_DoesNotWarnAsync()
{
await VerifyCS.VerifyAnalyzerAsync(@"
public class Class
{
public void Test1(string first)
{
throw new System.ArgumentException(""first.Length is incorrect"", nameof(first));
}
public void Test2(string first)
{
throw new System.ArgumentException(""first[0] is incorrect"", nameof(first));
}
}");

await VerifyVB.VerifyAnalyzerAsync(@"
Public Class [MyClass]
Public Sub Test1(first As String)
Throw New System.ArgumentException(""first.Length is incorrect"", NameOf(first))
End Sub
Public Sub Test2(first As String)
Throw New System.ArgumentException(""first(0) is incorrect"", NameOf(first))
End Sub
End Class");
}

[Fact]
public async Task ArgumentException_GenericParameterName_DoesNotWarnAsync()
{
Expand Down

0 comments on commit 93e7073

Please sign in to comment.