Example #1
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

            // TODO: Replace the following code with your own analysis, generating a CodeAction for each fix to suggest
            var diagnostic     = context.Diagnostics.First();
            var diagnosticSpan = diagnostic.Location.SourceSpan;

            // Find the type declaration identified by the diagnostic.
            var declaration = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType <EnumDeclarationSyntax>().First();
            var model       = await context.Document.GetSemanticModelAsync();

            var values = EnumValuesUtility.GetEnumValues(declaration, model);

            var offendingFieldDeclaration = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType <EnumMemberDeclarationSyntax>().Single();

            // Register a code action that will invoke the fix.
            context.RegisterCodeFix(
                CodeAction.Create(
                    title: CodeFixResources.ChangeToNextBinaryValueTitle,
                    createChangedSolution: c => ChangeEnumValueAsync(context.Document, offendingFieldDeclaration, values, model, c),
                    equivalenceKey: nameof(CodeFixResources.ChangeToNextBinaryValueTitle)),
                diagnostic);
            if (diagnostic.Id == FlagEnumAnalyzer.EnumValueIsZeroId)
            {
                RegisterAppendAttributeCodefix <NoneAttribute>(
                    context,
                    CodeFixResources.AddNoneAttribute,
                    nameof(CodeFixResources.AddNoneAttribute),
                    diagnostic,
                    offendingFieldDeclaration,
                    model);
            }
            else
            {
                RegisterAppendAttributeCodefix <CombinedFlagsAttribute>(
                    context,
                    CodeFixResources.AddCombinedFlagsAttribute,
                    nameof(CodeFixResources.AddCombinedFlagsAttribute),
                    diagnostic,
                    offendingFieldDeclaration,
                    model);
            }
        }
Example #2
0
        private static void AnalyzeSymbol(SyntaxNodeAnalysisContext context)
        {
            // TODO: Replace the following code with your own analysis, generating Diagnostic objects for any issues you find
            var semanticModel = context.SemanticModel;

            if (context.Node is EnumDeclarationSyntax enumDeclaration)
            {
                var symbol = (ITypeSymbol)semanticModel.GetDeclaredSymbol(enumDeclaration);
                if (symbol.TypeKind == TypeKind.Enum)
                {
                    var attributes = symbol.GetAttributes();
                    if (attributes.Any(x => x.AttributeClass.Name == nameof(FlagsAttribute)))
                    {
                        var takenValues = new HashSet <int>();
                        foreach (var value in enumDeclaration.Members)
                        {
                            var model           = semanticModel.GetDeclaredSymbol(value);
                            var valueAttributes = model.GetAttributes();
                            if (!valueAttributes.Any(x => x.AttributeClass.Name == nameof(CombinedFlagsAttribute)))
                            {
                                if (EnumValuesUtility.IsPowerOfTwo((int)model.ConstantValue) && !takenValues.Contains((int)model.ConstantValue))
                                {
                                    if (model.ConstantValue is 0 && !valueAttributes.Any(x => x.AttributeClass.Name == nameof(NoneAttribute)))
                                    {
                                        context.ReportDiagnostic(Diagnostic.Create(EnumValueIsZero, value.GetLocation(), model.Name, nameof(NoneAttribute)));
                                    }
                                    takenValues.Add((int)model.ConstantValue);
                                }
                                else
                                {
                                    context.ReportDiagnostic(Diagnostic.Create(EnumValueIsNotPowerOfTwo, value.GetLocation(), model.Name, nameof(CombinedFlagsAttribute)));
                                }
                            }
                        }
                    }
                }
            }
        }