private static bool ParentDeclarationIsNotConstant(LiteralExpressionSyntax syntax)
        {
            LocalDeclarationStatementSyntax localDeclaration = null;

            var fieldDeclaration = syntax.Ancestors()
                                   .OfType <FieldDeclarationSyntax>()
                                   .FirstOrDefault(x => x.Modifiers.Any(SyntaxKind.ConstKeyword));

            if (fieldDeclaration == null)
            {
                localDeclaration = syntax.Ancestors()
                                   .OfType <LocalDeclarationStatementSyntax>()
                                   .FirstOrDefault(x => x.Modifiers.Any(SyntaxKind.ConstKeyword));
            }
            return(fieldDeclaration == null && localDeclaration == null);
        }
Beispiel #2
0
 private static SyntaxNode GetEnclosingMember(LiteralExpressionSyntax literal)
 {
     foreach (var ancestor in literal.Ancestors())
     {
         switch (ancestor.Kind())
         {
         case SyntaxKind.ParenthesizedLambdaExpression:
         case SyntaxKind.SimpleLambdaExpression:
         case SyntaxKind.VariableDeclaration:
         case SyntaxKind.PropertyDeclaration:
         case SyntaxKind.MethodDeclaration:
         case SyntaxKind.LocalFunctionStatement:
             return(ancestor);
         }
     }
     return(null);
 }
Beispiel #3
0
        public override void Initialize(AnalysisContext context)
        {
            context.RegisterSyntaxNodeAction(
                c =>
            {
                LiteralExpressionSyntax literalNode = (LiteralExpressionSyntax)c.Node;

                if (!literalNode.IsPartOfStructuredTrivia() &&
                    !literalNode.Ancestors().Any(e =>
                                                 e.IsKind(SyntaxKind.VariableDeclarator) ||
                                                 e.IsKind(SyntaxKind.EnumDeclaration) ||
                                                 e.IsKind(SyntaxKind.Attribute)) &&
                    !Exceptions.Contains(literalNode.Token.Text))
                {
                    c.ReportDiagnostic(Diagnostic.Create(Rule, literalNode.GetLocation()));
                }
            },
                SyntaxKind.NumericLiteralExpression);
        }
        private static SyntaxNode GetEnclosingMember(LiteralExpressionSyntax literal)
        {
            foreach (var ancestor in literal.Ancestors())
            {
                if (ancestor.IsKind(SyntaxKind.ParenthesizedLambdaExpression))
                {
                    return(null);
                }
                else if (ancestor.IsAnyKind(PossibleEnclosingSyntax))
                {
                    return(ancestor);
                }
                else
                {
                    // do nothing
                }
            }

            return(null);
        }
Beispiel #5
0
        private static SyntaxNode GetEnclosingMember(LiteralExpressionSyntax literal)
        {
            foreach (var ancestor in literal.Ancestors())
            {
                switch (ancestor.Kind())
                {
                case SyntaxKind.MultiLineFunctionLambdaExpression:
                case SyntaxKind.SingleLineFunctionLambdaExpression:
                    return(null);

                case SyntaxKind.VariableDeclarator:
                case SyntaxKind.PropertyBlock:
                case SyntaxKind.FunctionBlock:
                    return(ancestor);

                default:
                    // do nothing
                    break;
                }
            }

            return(null);
        }
Beispiel #6
0
 private static bool IsNoCandidateDiagnostic(LiteralExpressionSyntax literal)
 {
     return(literal.ToString() != "\"\"" ||
            literal.Ancestors().OfType <AttributeArgumentSyntax>().Any() ||
            literal.Ancestors().OfType <ParameterListSyntax>().Any());
 }
 private static bool IsNoCandidateDiagnostic(LiteralExpressionSyntax literal)
 {
     return literal.ToString() != "\"\"" ||
            literal.Ancestors().OfType<AttributeArgumentSyntax>().Any() ||
            literal.Ancestors().OfType<ParameterListSyntax>().Any();
 }
Beispiel #8
0
        private static bool InAllowedDeclarationContext(LiteralExpressionSyntax literalExpression, Settings settings)
        {
            bool result = literalExpression.Ancestors()
                          .Any(ancestor =>
            {
                bool allowed = false;

                switch (ancestor.Kind())
                {
                case SyntaxKind.LocalDeclarationStatement:
                    allowed = ((LocalDeclarationStatementSyntax)ancestor).Modifiers.Any(SyntaxKind.ConstKeyword);
                    break;

                case SyntaxKind.FieldDeclaration:
                    // Allow any static readonly field to use unnamed numeric literals in expressions because sometimes
                    // arrays of numeric literals are needed (e.g., Crc32Code) or special instances are created (e.g.,
                    // Color.FromArgb(225, 255, 255), new DateTime(1970, 1, 1)).  Also, allow fields that are set to
                    // single, non-calculated constants.  In these cases the field name is good enough documentation.
                    FieldDeclarationSyntax fieldDeclaration = (FieldDeclarationSyntax)ancestor;
                    SyntaxTokenList fieldModifiers          = fieldDeclaration.Modifiers;
                    allowed = fieldModifiers.Any(SyntaxKind.ConstKeyword) ||
                              (fieldModifiers.Any(SyntaxKind.StaticKeyword) && fieldModifiers.Any(SyntaxKind.ReadOnlyKeyword)) ||
                              HasParentChain(
                        literalExpression,
                        SyntaxKind.EqualsValueClause,
                        SyntaxKind.VariableDeclarator,
                        SyntaxKind.VariableDeclaration,
                        SyntaxKind.FieldDeclaration);
                    break;

                case SyntaxKind.PropertyDeclaration:
                    // Allow property initializers that are set to single, non-calculated constants.  The property name is good enough.
                    allowed = HasParentChain(literalExpression, SyntaxKind.EqualsValueClause, SyntaxKind.PropertyDeclaration);
                    break;

                case SyntaxKind.BracketedArgumentList:
                    // Allow small numeric literals as indexer arguments (e.g., for sequential item access).  Since 0, 1,
                    // and 2 are allowed by default, it's common to see other small sequential indexes used too.
                    // Note: ArrayRankSpecifier (e.g., in new string[7]) is a different syntax kind, so this won't allow
                    // magic numbers for array ranks (just indexes).
                    byte indexValue;
                    allowed = HasParentChain(literalExpression, SyntaxKind.Argument, SyntaxKind.BracketedArgumentList) &&
                              byte.TryParse(literalExpression.Token.Text, out indexValue);
                    break;

                case SyntaxKind.EnumMemberDeclaration:
                case SyntaxKind.AttributeArgument:
                    allowed = true;
                    break;

                case SyntaxKind.MethodDeclaration:
                    // Unit test methods typically use lots of numeric literals for test cases, and they don't need to be named constants.
                    allowed = IsUnitTestMethod((BaseMethodDeclarationSyntax)ancestor, settings);
                    break;

                case SyntaxKind.ClassDeclaration:
                    // Unit test classes typically use lots of numeric literals for test cases, and they don't need to be named constants.
                    allowed = IsUnitTestClass((ClassDeclarationSyntax)ancestor, settings);
                    break;

                case SyntaxKind.InvocationExpression:
                    // Allow cases like item.GetXxx(n) for n in [0,255] to handle cases like IDataRecord.Get and Array.Get accessors.
                    allowed = IsGetIndexInvocation(literalExpression);
                    break;
                }

                return(allowed);
            });

            return(result);
        }
 private static bool HasAttributes(LiteralExpressionSyntax literalExpression) =>
 literalExpression.Ancestors().Any(expr => expr.IsKind(Microsoft.CodeAnalysis.CSharp.SyntaxKind.Attribute));