Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix RCS1257 #1264

Merged
merged 3 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fix [RCS1228](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1228) ([PR](https://github.com/dotnet/roslynator/pull/1249))
- Fix [RCS1213](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1213) ([PR](https://github.com/dotnet/roslynator/pull/1254))
- Fix [RCS1055](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1055) ([PR](https://github.com/dotnet/roslynator/pull/1253))
- Fix [RCS1196](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1196/) ([PR](https://github.com/dotnet/roslynator/pull/1235))
- Fix [RCS1196](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1196) ([PR](https://github.com/dotnet/roslynator/pull/1235))
- Fix [RCS1257](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1257) ([PR](https://github.com/dotnet/roslynator/pull/1264))

## [4.6.2] - 2023-11-10

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) .NET Foundation and Contributors. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
Expand Down Expand Up @@ -56,7 +57,7 @@ private static async Task<Document> UseEnumFieldExplicitlyAsync(

if (enumSymbol.HasAttribute(MetadataNames.System_FlagsAttribute))
{
ulong value = SymbolUtility.GetEnumValueAsUInt64(constantValueOpt.Value, enumSymbol);
ulong value = Convert.ToUInt64(constantValueOpt.Value);

List<ulong> flags = FlagsUtility<ulong>.Instance.GetFlags(value).ToList();

Expand Down Expand Up @@ -86,7 +87,7 @@ private static async Task<Document> UseEnumFieldExplicitlyAsync(
.First(fieldSymbol =>
{
return fieldSymbol.HasConstantValue
&& constantValueOpt.Value.Equals(fieldSymbol.ConstantValue);
&& Convert.ToUInt64(constantValueOpt.Value) == Convert.ToUInt64(fieldSymbol.ConstantValue);
});

ExpressionSyntax newExpression = CreateEnumFieldExpression(symbol).WithTriviaFrom(castExpression);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,15 @@ private static void AnalyzeCastExpression(SyntaxNodeAnalysisContext context)
if (enumSymbol?.EnumUnderlyingType is null)
return;

ulong value = SymbolUtility.GetEnumValueAsUInt64(constantValueOpt.Value, enumSymbol);
if (!ConvertHelpers.TryConvertToUInt64(constantValueOpt.Value, out ulong value))
return;

foreach (ISymbol member in enumSymbol.GetMembers())
{
if (member is IFieldSymbol fieldSymbol
&& fieldSymbol.HasConstantValue
&& value == SymbolUtility.GetEnumValueAsUInt64(fieldSymbol.ConstantValue, enumSymbol))
&& ConvertHelpers.TryConvertToUInt64(fieldSymbol.ConstantValue, out ulong fieldValue)
&& value == fieldValue)
{
context.ReportDiagnostic(DiagnosticRules.UseEnumFieldExplicitly, castExpression);
return;
Expand Down
14 changes: 14 additions & 0 deletions src/Core/ConvertHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,18 @@ public static ulong ConvertToUInt64(object value, SpecialType numericType)
throw new ArgumentException("", nameof(numericType));
}
}

public static bool TryConvertToUInt64(object value, out ulong result)
{
try
{
result = Convert.ToUInt64(value);
return true;
}
catch (Exception ex) when (ex is InvalidCastException || ex is OverflowException)
{
result = 0;
return false;
}
}
}
32 changes: 32 additions & 0 deletions src/Tests/Analyzers.Tests/RCS1257UseEnumFieldExplicitlyTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,38 @@ void M()
");
}

[Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.UseEnumFieldExplicitly)]
public async Task Test_Flags_SByte()
{
await VerifyDiagnosticAndFixAsync(@"
class C
{
void M()
{
var enumValue = [|(TestEnum)2|];
}
}

enum TestEnum : sbyte
{
Foo, Bar, Baz
}
", @"
class C
{
void M()
{
var enumValue = TestEnum.Baz;
}
}

enum TestEnum : sbyte
{
Foo, Bar, Baz
}
");
}

[Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.UseEnumFieldExplicitly)]
public async Task TestNoDiagnostic_UndefinedValue()
{
Expand Down