Example #1
0
        private static void AnalyzeCodeRefactoringProvider(SymbolAnalysisContext context, INamedTypeSymbol symbol)
        {
            AttributeData attribute = symbol.GetAttribute(RoslynMetadataNames.Microsoft_CodeAnalysis_CodeRefactorings_ExportCodeRefactoringProviderAttribute);

            if (attribute == null)
            {
                return;
            }

            if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UnknownLanguageName))
            {
                AnalyzeLanguageName(context, attribute);
            }

            if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.SpecifyExportCodeRefactoringProviderAttributeName) &&
                !ContainsNamedArgument(attribute, "Name"))
            {
                ReportDiagnostic(context, attribute, DiagnosticDescriptors.SpecifyExportCodeRefactoringProviderAttributeName);
            }
        }
Example #2
0
        private static void AnalyzeDiagnosticAnalyzer(SymbolAnalysisContext context, INamedTypeSymbol symbol)
        {
            AttributeData attribute = symbol.GetAttribute(RoslynMetadataNames.Microsoft_CodeAnalysis_Diagnostics_DiagnosticAnalyzerAttribute);

            if (attribute == null)
            {
                return;
            }

            if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UnknownLanguageName))
            {
                AnalyzeLanguageName(context, attribute);
            }
        }
Example #3
0
        private static void AnalyzeFieldSymbol(SymbolAnalysisContext context)
        {
            var fieldSymbol = (IFieldSymbol)context.Symbol;

            if (!fieldSymbol.IsConst &&
                !fieldSymbol.IsImplicitlyDeclared &&
                fieldSymbol.DeclaredAccessibility == Accessibility.Private &&
                !string.IsNullOrEmpty(fieldSymbol.Name) &&
                !IsValidIdentifier(fieldSymbol.Name))
            {
                if (!fieldSymbol.IsStatic ||
                    !fieldSymbol.IsReadOnly ||
                    context.IsAnalyzerSuppressed(AnalyzerOptions.DoNotRenamePrivateStaticReadOnlyFieldToCamelCaseWithUnderscore))
                {
                    DiagnosticHelpers.ReportDiagnostic(context,
                                                       DiagnosticDescriptors.RenamePrivateFieldToCamelCaseWithUnderscore,
                                                       fieldSymbol.Locations[0]);
                }
            }
        }
Example #4
0
        private static void AnalyzeNamedType(SymbolAnalysisContext context)
        {
            var typeSymbol = (INamedTypeSymbol)context.Symbol;

            if (typeSymbol.IsImplicitlyDeclared)
            {
                return;
            }

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

            bool hasFlagsAttribute = typeSymbol.HasAttribute(MetadataNames.System_FlagsAttribute);

            ImmutableArray <ISymbol> members = default;

            if (hasFlagsAttribute &&
                !context.IsAnalyzerSuppressed(DiagnosticDescriptors.DeclareEnumMemberWithZeroValue))
            {
                members = typeSymbol.GetMembers();

                if (!ContainsFieldWithZeroValue(members))
                {
                    var enumDeclaration = (EnumDeclarationSyntax)typeSymbol.GetSyntax(context.CancellationToken);

                    DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.DeclareEnumMemberWithZeroValue, enumDeclaration.Identifier);
                }
            }

            EnumSymbolInfo enumInfo = default;

            if (hasFlagsAttribute &&
                !context.IsAnalyzerSuppressed(DiagnosticDescriptors.CompositeEnumValueContainsUndefinedFlag))
            {
                enumInfo = EnumSymbolInfo.Create(typeSymbol);

                foreach (EnumFieldSymbolInfo field in enumInfo.Fields)
                {
                    if (field.HasValue &&
                        ConvertHelpers.CanConvertFromUInt64(field.Value, typeSymbol.EnumUnderlyingType.SpecialType) &&
                        !IsMaxValue(field.Value, typeSymbol.EnumUnderlyingType.SpecialType) &&
                        field.HasCompositeValue())
                    {
                        foreach (ulong value in (field.DecomposeValue()))
                        {
                            if (!enumInfo.Contains(value))
                            {
                                ReportUndefinedFlag(context, field.Symbol, value.ToString());
                            }
                        }
                    }
                }
            }

            if (hasFlagsAttribute &&
                !context.IsAnalyzerSuppressed(DiagnosticDescriptors.DeclareEnumValueAsCombinationOfNames))
            {
                if (members.IsDefault)
                {
                    members = typeSymbol.GetMembers();
                }

                foreach (ISymbol member in members)
                {
                    if (!(member is IFieldSymbol fieldSymbol))
                    {
                        continue;
                    }

                    if (!fieldSymbol.HasConstantValue)
                    {
                        break;
                    }

                    EnumFieldSymbolInfo fieldInfo = EnumFieldSymbolInfo.Create(fieldSymbol);

                    if (!fieldInfo.HasCompositeValue())
                    {
                        continue;
                    }

                    var declaration = (EnumMemberDeclarationSyntax)fieldInfo.Symbol.GetSyntax(context.CancellationToken);

                    ExpressionSyntax expression = declaration.EqualsValue?.Value.WalkDownParentheses();

                    if (expression != null &&
                        (expression.IsKind(SyntaxKind.NumericLiteralExpression) ||
                         expression
                         .DescendantNodes()
                         .Any(f => f.IsKind(SyntaxKind.NumericLiteralExpression))))
                    {
                        if (enumInfo.IsDefault)
                        {
                            enumInfo = EnumSymbolInfo.Create(typeSymbol);

                            if (enumInfo.Fields.Any(f => !f.HasValue))
                            {
                                break;
                            }
                        }

                        List <EnumFieldSymbolInfo> values = enumInfo.Decompose(fieldInfo);

                        if (values?.Count > 1)
                        {
                            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.DeclareEnumValueAsCombinationOfNames, expression);
                        }
                    }
                }
            }

            if (hasFlagsAttribute &&
                !context.IsAnalyzerSuppressed(DiagnosticDescriptors.UseBitShiftOperator))
            {
                if (members.IsDefault)
                {
                    members = typeSymbol.GetMembers();
                }

                foreach (ISymbol member in members)
                {
                    if (!(member is IFieldSymbol fieldSymbol))
                    {
                        continue;
                    }

                    if (!fieldSymbol.HasConstantValue)
                    {
                        continue;
                    }

                    EnumFieldSymbolInfo fieldInfo = EnumFieldSymbolInfo.Create(fieldSymbol);

                    if (fieldInfo.Value <= 1)
                    {
                        continue;
                    }

                    if (fieldInfo.HasCompositeValue())
                    {
                        continue;
                    }

                    var declaration = (EnumMemberDeclarationSyntax)fieldInfo.Symbol.GetSyntax(context.CancellationToken);

                    ExpressionSyntax expression = declaration.EqualsValue?.Value.WalkDownParentheses();

                    if (expression.IsKind(SyntaxKind.NumericLiteralExpression))
                    {
                        var enumDeclaration = (EnumDeclarationSyntax)typeSymbol.GetSyntax(context.CancellationToken);

                        DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UseBitShiftOperator, enumDeclaration.Identifier);
                        break;
                    }
                }
            }

            if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.DuplicateEnumValue))
            {
                if (enumInfo.IsDefault)
                {
                    enumInfo = EnumSymbolInfo.Create(typeSymbol);
                }

                ImmutableArray <EnumFieldSymbolInfo> fields = enumInfo.Fields;

                if (fields.Length > 1)
                {
                    EnumFieldSymbolInfo symbolInfo1 = fields[0];
                    EnumFieldSymbolInfo symbolInfo2 = default;

                    for (int i = 1; i < fields.Length; i++, symbolInfo1 = symbolInfo2)
                    {
                        symbolInfo2 = fields[i];

                        if (!symbolInfo1.HasValue ||
                            !symbolInfo2.HasValue ||
                            symbolInfo1.Value != symbolInfo2.Value)
                        {
                            continue;
                        }

                        var enumMember1 = (EnumMemberDeclarationSyntax)symbolInfo1.Symbol.GetSyntax(context.CancellationToken);

                        if (enumMember1 == null)
                        {
                            continue;
                        }

                        var enumMember2 = (EnumMemberDeclarationSyntax)symbolInfo2.Symbol.GetSyntax(context.CancellationToken);

                        if (enumMember2 == null)
                        {
                            continue;
                        }

                        ExpressionSyntax value1 = enumMember1.EqualsValue?.Value?.WalkDownParentheses();
                        ExpressionSyntax value2 = enumMember2.EqualsValue?.Value?.WalkDownParentheses();

                        if (value1 == null)
                        {
                            if (value2 != null)
                            {
                                ReportDuplicateValue(context, enumMember1, value2);
                            }
                        }
                        else if (value2 == null)
                        {
                            ReportDuplicateValue(context, enumMember2, value1);
                        }
                        else
                        {
                            SyntaxKind kind1 = value1.Kind();
                            SyntaxKind kind2 = value2.Kind();

                            if (kind1 == SyntaxKind.NumericLiteralExpression)
                            {
                                if (kind2 == SyntaxKind.NumericLiteralExpression)
                                {
                                    var enumDeclaration = (EnumDeclarationSyntax)enumMember1.Parent;
                                    SeparatedSyntaxList <EnumMemberDeclarationSyntax> enumMembers = enumDeclaration.Members;

                                    if (enumMembers.IndexOf(enumMember1) < enumMembers.IndexOf(enumMember2))
                                    {
                                        ReportDuplicateValue(context, value2);
                                    }
                                    else
                                    {
                                        ReportDuplicateValue(context, value1);
                                    }
                                }
                                else if (!string.Equals((value2 as IdentifierNameSyntax)?.Identifier.ValueText, enumMember1.Identifier.ValueText, StringComparison.Ordinal))
                                {
                                    ReportDuplicateValue(context, value1);
                                }
                            }
                            else if (kind2 == SyntaxKind.NumericLiteralExpression &&
                                     !string.Equals((value1 as IdentifierNameSyntax)?.Identifier.ValueText, enumMember2.Identifier.ValueText, StringComparison.Ordinal))
                            {
                                ReportDuplicateValue(context, value2);
                            }
                        }
                    }
                }
            }
        }