diff --git a/src/StaticCs/EnumClosedConversionAnalyzer.cs b/src/StaticCs/EnumClosedConversionAnalyzer.cs index 5edda05..6fd4332 100644 --- a/src/StaticCs/EnumClosedConversionAnalyzer.cs +++ b/src/StaticCs/EnumClosedConversionAnalyzer.cs @@ -1,9 +1,8 @@ using System.Collections.Immutable; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Operations; namespace StaticCs; @@ -24,22 +23,30 @@ public override void Initialize(AnalysisContext ctx) { ctx.EnableConcurrentExecution(); ctx.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.ReportDiagnostics); - ctx.RegisterSyntaxNodeAction(ctx => + ctx.RegisterOperationAction(ctx => { - var castSyntax = (CastExpressionSyntax)ctx.Node; - var model = ctx.SemanticModel; - var targetTypeInfo = model.GetTypeInfo(castSyntax.Type); - - if (targetTypeInfo.Type is { TypeKind: TypeKind.Enum } type) + var conversion = (IConversionOperation)ctx.Operation; + + // Check if the conversion is from an integer type to an enum type + if (conversion.Type is { TypeKind: TypeKind.Enum } targetType && + conversion.Operand.Type?.SpecialType is + SpecialType.System_SByte or + SpecialType.System_Byte or + SpecialType.System_Int16 or + SpecialType.System_UInt16 or + SpecialType.System_Int32 or + SpecialType.System_UInt32 or + SpecialType.System_Int64 or + SpecialType.System_UInt64) { - foreach (var attr in type.GetAttributes()) + foreach (var attr in targetType.GetAttributes()) { if (attr.AttributeClass?.ToDisplayString() == "StaticCs.ClosedAttribute") { - ctx.ReportDiagnostic(Diagnostic.Create(s_descriptor, castSyntax.GetLocation(), type)); + ctx.ReportDiagnostic(Diagnostic.Create(s_descriptor, conversion.Syntax.GetLocation(), targetType)); } } } - }, SyntaxKind.CastExpression); + }, OperationKind.Conversion); } } \ No newline at end of file diff --git a/test/test/ClosedTests.cs b/test/test/ClosedTests.cs index bd03399..74995ec 100644 --- a/test/test/ClosedTests.cs +++ b/test/test/ClosedTests.cs @@ -80,7 +80,7 @@ await VerifyDiagnostics(src, } [Fact] - public async Task ImplicitConversionToClosedLoophole() + public async Task ImplicitConversionToClosedError() { var src = """ using System; @@ -96,7 +96,9 @@ void M() } } """; - await VerifyDiagnostics(src); + await VerifyDiagnostics(src, + // /0/Test0.cs(9,19): error STATICCS002: Integer conversions to [Closed] enum Rgb are disallowed + ClosedEnumConversion.WithSpan(9, 19, 9, 20).WithArguments("Rgb")); } [Fact]