private static void Analyze(
     SyntaxNodeAnalysisContext context,
     EnumMemberDeclarationSyntax member,
     ExpressionSyntax value,
     EnumFlagValueStyle style)
 {
     if (IsFlag(context, member))
     {
         DiagnosticHelpers.ReportDiagnostic(
             context,
             DiagnosticRules.NormalizeFormatOfEnumFlagValue,
             value,
             (style == EnumFlagValueStyle.DecimalNumber) ? "Convert value to decimal number." : "Use '<<' operator.");
     }
 }
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out EnumMemberDeclarationSyntax enumMemberDeclaration))
            {
                return;
            }

            Document   document   = context.Document;
            Diagnostic diagnostic = context.Diagnostics[0];

            switch (diagnostic.Id)
            {
            case DiagnosticIdentifiers.DeclareEnumValueAsCombinationOfNames:
            {
                CodeAction codeAction = CodeAction.Create(
                    "Declare value as combination of names",
                    ct => DeclareEnumValueAsCombinationOfNamesAsync(document, enumMemberDeclaration, ct),
                    GetEquivalenceKey(diagnostic));

                context.RegisterCodeFix(codeAction, diagnostic);
                break;
            }

            case DiagnosticIdentifiers.DuplicateEnumValue:
            {
                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                var enumDeclaration = (EnumDeclarationSyntax)enumMemberDeclaration.Parent;

                IFieldSymbol fieldSymbol = semanticModel.GetDeclaredSymbol(enumMemberDeclaration, context.CancellationToken);

                EnumFieldSymbolInfo enumFieldSymbolInfo = EnumFieldSymbolInfo.Create(fieldSymbol);

                string valueText = FindMemberByValue(enumDeclaration, enumFieldSymbolInfo, semanticModel, context.CancellationToken).Identifier.ValueText;

                CodeAction codeAction = CodeAction.Create(
                    $"Change enum value to '{valueText}'",
                    ct => ChangeEnumValueAsync(document, enumMemberDeclaration, valueText, ct),
                    GetEquivalenceKey(diagnostic));

                context.RegisterCodeFix(codeAction, diagnostic);
                break;
            }

            case DiagnosticIdentifiers.NormalizeFormatOfEnumFlagValue:
            {
                EnumFlagValueStyle style = document.GetConfigOptions(enumMemberDeclaration.SyntaxTree).GetEnumFlagValueStyle();

                if (style == EnumFlagValueStyle.ShiftOperator)
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Use '<<' operator",
                        ct => UseBitShiftOperatorAsync(document, enumMemberDeclaration, ct),
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                }
                else if (style == EnumFlagValueStyle.DecimalNumber)
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Convert to decimal",
                        ct => ConvertToDecimalNumberAsync(document, enumMemberDeclaration, ct),
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                }
                else
                {
                    throw new InvalidOperationException();
                }

                break;
            }
            }
        }
        private void AnalyzeEnumDeclaration(SyntaxNodeAnalysisContext context)
        {
            var enumDeclaration = (EnumDeclarationSyntax)context.Node;

            if (!enumDeclaration.AttributeLists.Any())
            {
                return;
            }

            EnumFlagValueStyle style = context.GetEnumFlagValueStyle();

            if (style == EnumFlagValueStyle.None)
            {
                return;
            }

            if (context.SemanticModel.GetDeclaredSymbol(enumDeclaration, context.CancellationToken) is not INamedTypeSymbol typeSymbol)
            {
                return;
            }

            if (typeSymbol.TypeKind != TypeKind.Enum)
            {
                return;
            }

            if (!typeSymbol.HasAttribute(MetadataNames.System_FlagsAttribute))
            {
                return;
            }

            foreach (EnumMemberDeclarationSyntax member in enumDeclaration.Members)
            {
                ExpressionSyntax value = member.EqualsValue?.Value.WalkDownParentheses();

                if (value != null)
                {
                    if (value.IsKind(SyntaxKind.NumericLiteralExpression))
                    {
                        var    literalExpression = (LiteralExpressionSyntax)value;
                        string text = literalExpression.Token.Text;

                        if (style == EnumFlagValueStyle.DecimalNumber)
                        {
                            if (text.StartsWith("0b", StringComparison.OrdinalIgnoreCase) ||
                                text.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
                            {
                                Analyze(context, member, value, style);
                            }
                        }
                        else if (style == EnumFlagValueStyle.ShiftOperator)
                        {
                            Analyze(context, member, value, style);
                        }
                    }
                    else if (value.IsKind(SyntaxKind.LeftShiftExpression) &&
                             style == EnumFlagValueStyle.DecimalNumber)
                    {
                        Analyze(context, member, value, style);
                    }
                }
            }
        }