private static void AnalyzeMethodDeclaration(SyntaxNodeAnalysisContext context)
    {
      var methodNode = (MethodDeclarationSyntax)context.Node;
      var methodSymbol = context.SemanticModel.GetDeclaredSymbol(methodNode);
      var typeSymbol = methodSymbol.ContainingType;

      if (typeSymbol.IsStereotype() && methodSymbol.IsDataPortalOperation() &&
        methodSymbol.DeclaredAccessibility == Accessibility.Public)
      {
        if(typeSymbol.TypeKind == TypeKind.Interface)
        {
          context.ReportDiagnostic(Diagnostic.Create(
            IsOperationMethodPublicAnalyzer.makeNonPublicForInterfaceRule,
            methodNode.Identifier.GetLocation()));
        }
        else
        {
          var properties = new Dictionary<string, string>()
          {
            [IsOperationMethodPublicAnalyzerConstants.IsSealed] = typeSymbol.IsSealed.ToString()
          }.ToImmutableDictionary();

          context.ReportDiagnostic(Diagnostic.Create(IsOperationMethodPublicAnalyzer.makeNonPublicRule,
            methodNode.Identifier.GetLocation(), properties));
        }
      }
    }
        private static void CheckDeclarationName(MemberDeclarationSyntax member, SyntaxToken identifier, SyntaxNodeAnalysisContext context)
        {
            var symbol = context.SemanticModel.GetDeclaredSymbol(member);
            if (ClassName.IsTypeComRelated(symbol?.ContainingType) ||
                symbol.IsInterfaceImplementationOrMemberOverride() ||
                symbol.IsExtern)
            {
                return;
            }

            if (identifier.ValueText.StartsWith("_", StringComparison.Ordinal) ||
                identifier.ValueText.EndsWith("_", StringComparison.Ordinal))
            {
                context.ReportDiagnostic(Diagnostic.Create(Rule, identifier.GetLocation(), MethodKindNameMapping[member.Kind()],
                    identifier.ValueText, MessageFormatUnderscore));
                return;
            }

            string suggestion;
            if (TryGetChangedName(identifier.ValueText, out suggestion))
            {
                var messageEnding = string.Format(MessageFormatNonUnderscore, suggestion);
                context.ReportDiagnostic(Diagnostic.Create(Rule, identifier.GetLocation(), MethodKindNameMapping[member.Kind()],
                    identifier.ValueText, messageEnding));
            }
        }
        private static void HandleEmptyStatementSyntax(SyntaxNodeAnalysisContext context)
        {
            EmptyStatementSyntax syntax = (EmptyStatementSyntax)context.Node;

            LabeledStatementSyntax labeledStatementSyntax = syntax.Parent as LabeledStatementSyntax;
            if (labeledStatementSyntax != null)
            {
                BlockSyntax blockSyntax = labeledStatementSyntax.Parent as BlockSyntax;
                if (blockSyntax != null)
                {
                    for (int i = blockSyntax.Statements.Count - 1; i >= 0; i--)
                    {
                        StatementSyntax statement = blockSyntax.Statements[i];

                        // allow an empty statement to be used for a label, but only if no non-empty statements exist
                        // before the end of the block
                        if (blockSyntax.Statements[i] == labeledStatementSyntax)
                        {
                            return;
                        }

                        if (!statement.IsKind(SyntaxKind.EmptyStatement))
                        {
                            break;
                        }
                    }
                }
            }

            // Code must not contain empty statements
            context.ReportDiagnostic(Diagnostic.Create(Descriptor, syntax.GetLocation()));
        }
        static bool TryGetDiagnostic(SyntaxNodeAnalysisContext nodeContext, out Diagnostic diagnostic)
        {
            diagnostic = default(Diagnostic);
            var objectCreateExpression = nodeContext.Node as ObjectCreationExpressionSyntax;

            ExpressionSyntax paramNode;
            ExpressionSyntax altParamNode;
            bool canAddParameterName;
            if (!CheckExceptionType(nodeContext.SemanticModel, objectCreateExpression, out paramNode, out altParamNode, out canAddParameterName))
                return false;

            var paramName = GetArgumentParameterName(paramNode);
            if (paramName == null)
                return false;
            var validNames = GetValidParameterNames(objectCreateExpression);

            if (!validNames.Contains(paramName))
            {
                // Case 1: Parameter name is swapped
                var altParamName = GetArgumentParameterName(altParamNode);
                if (altParamName != null && validNames.Contains(altParamName))
                {
                    diagnostic = Diagnostic.Create(descriptor2, altParamNode.GetLocation());
                    return true;
                }
                //var guessName = GuessParameterName(nodeContext.SemanticModel, objectCreateExpression, validNames);

                // General case: mark only
                diagnostic = Diagnostic.Create(descriptor, paramNode.GetLocation(), paramName);
                return true;
            }
            return false;
        }
        private static void ProcessUsings(SyntaxNodeAnalysisContext context, SyntaxList<UsingDirectiveSyntax> usings)
        {
            var usingDirectives = new List<UsingDirectiveSyntax>();
            var systemUsingDirectives = new List<UsingDirectiveSyntax>();

            foreach (var usingDirective in usings)
            {
                if (IsAliasOrStaticUsingDirective(usingDirective))
                {
                    continue;
                }

                if (usingDirective.IsPrecededByPreprocessorDirective())
                {
                    CheckIncorrectlyOrderedUsingsAndReportDiagnostic(context, usingDirectives);
                    CheckIncorrectlyOrderedUsingsAndReportDiagnostic(context, systemUsingDirectives);
                    usingDirectives.Clear();
                    systemUsingDirectives.Clear();
                }

                if (HasNamespaceAliasQualifier(usingDirective) || !usingDirective.IsSystemUsingDirective())
                {
                    usingDirectives.Add(usingDirective);
                }
                else
                {
                    systemUsingDirectives.Add(usingDirective);
                }
            }

            CheckIncorrectlyOrderedUsingsAndReportDiagnostic(context, usingDirectives);
            CheckIncorrectlyOrderedUsingsAndReportDiagnostic(context, systemUsingDirectives);
        }
        private static void AnalyzeNode(SyntaxNodeAnalysisContext context)
        {
            if (context.IsGenerated()) return;
            var objectCreationExpression = (ObjectCreationExpressionSyntax)context.Node;

            var type = objectCreationExpression.Type;
            var typeSymbol = context.SemanticModel.GetSymbolInfo(type).Symbol as ITypeSymbol;
            if (!typeSymbol?.ToString().EndsWith("System.ArgumentException") ?? true) return;

            var argumentList = objectCreationExpression.ArgumentList as ArgumentListSyntax;
            if ((argumentList?.Arguments.Count ?? 0) < 2) return;

            var paramNameLiteral = argumentList.Arguments[1].Expression as LiteralExpressionSyntax;
            if (paramNameLiteral == null) return;

            var paramNameOpt = context.SemanticModel.GetConstantValue(paramNameLiteral);
            if (!paramNameOpt.HasValue) return;

            var paramName = paramNameOpt.Value as string;

            IList<string> parameters;
            if (IsParamNameCompatibleWithCreatingContext(objectCreationExpression, paramName, out parameters)) return;
            var props = parameters.ToImmutableDictionary(p => $"param{p}", p => p);
            var diagnostic = Diagnostic.Create(Rule, paramNameLiteral.GetLocation(), props.ToImmutableDictionary(), paramName);
            context.ReportDiagnostic(diagnostic);
        }
        private static bool TryGetUnusedLocalVariableDiagnostic(SyntaxNodeAnalysisContext nodeContext, out Diagnostic diagnostic)
        {
            diagnostic = default(Diagnostic);

            var method = nodeContext.Node as MethodDeclarationSyntax;
            if ((method == null) || (method.Body == null))
                return false;

            var dataFlow = nodeContext.SemanticModel.AnalyzeDataFlow(method.Body);
            
            var variablesDeclared = dataFlow.VariablesDeclared;
            var variablesRead = dataFlow.ReadInside.Union(dataFlow.ReadOutside);
            var unused = variablesDeclared.Except(variablesRead).Except(dataFlow.WrittenInside).ToArray();

            if (unused.Any())
            {
                foreach (var unusedVar in unused)
                {
                   
                    diagnostic = Diagnostic.Create(descriptor, unusedVar.Locations.First());
                    return true;
                }
            }
            return false;
        }
        private static bool TryGetDiagnostic(SyntaxNodeAnalysisContext nodeContext, out Diagnostic diagnostic)
        {
            diagnostic = default(Diagnostic);

            var localDeclarationUnused = nodeContext.Node as LocalDeclarationStatementSyntax;
            var body = localDeclarationUnused?.Parent as BlockSyntax;
            if (body == null)
                return false;

            var dataFlow = nodeContext.SemanticModel.AnalyzeDataFlow(body);
            var variablesDeclared = dataFlow.VariablesDeclared;
            var variablesRead = dataFlow.ReadInside.Union(dataFlow.ReadOutside);
            var unused = variablesDeclared.Except(variablesRead).ToArray();
            if (unused == null)
                return false;

            if (localDeclarationUnused.Declaration == null || !localDeclarationUnused.Declaration.Variables.Any())
                return false; 

            var localDeclarationSymbol = nodeContext.SemanticModel.GetDeclaredSymbol(localDeclarationUnused.Declaration.Variables.FirstOrDefault());
            if (unused.Any())
            {
                if (unused.Contains(localDeclarationSymbol))
                {
                    diagnostic = Diagnostic.Create(descriptor, localDeclarationUnused.Declaration.GetLocation());
                    return true;
                }
            }
            return false;
        }
        private static void Analyzer(SyntaxNodeAnalysisContext context)
        {
            if (context.IsGenerated()) return;
            var invocationExpression = (InvocationExpressionSyntax)context.Node;

            var memberExpresion = invocationExpression.Expression as MemberAccessExpressionSyntax;
            if (memberExpresion?.Name?.ToString() != "Match") return;

            var memberSymbol = context.SemanticModel.GetSymbolInfo(memberExpresion).Symbol;
            if (memberSymbol?.ToString() != "System.Text.RegularExpressions.Regex.Match(string, string)") return;

            var argumentList = invocationExpression.ArgumentList as ArgumentListSyntax;
            if ((argumentList?.Arguments.Count ?? 0) != 2) return;

            var regexLiteral = argumentList.Arguments[1].Expression as LiteralExpressionSyntax;
            if (regexLiteral == null) return;

            var regexOpt = context.SemanticModel.GetConstantValue(regexLiteral);

            var regex = regexOpt.Value as string;

            try
            {
                System.Text.RegularExpressions.Regex.Match("", regex);
            }
            catch (ArgumentException e)
            {
                var diag = Diagnostic.Create(Rule, regexLiteral.GetLocation(), e.Message);
                context.ReportDiagnostic(diag);
            }
        }
        static bool TryGetDiagnostic(SyntaxNodeAnalysisContext nodeContext, out Diagnostic diagnostic)
        {
            diagnostic = default(Diagnostic);
            var anyInvoke = nodeContext.Node as InvocationExpressionSyntax;

            var info = nodeContext.SemanticModel.GetSymbolInfo(anyInvoke);

            IMethodSymbol anyResolve = info.Symbol as IMethodSymbol;
            if (anyResolve == null)
            {
                anyResolve = info.CandidateSymbols.OfType<IMethodSymbol>().FirstOrDefault(candidate => HasPredicateVersion(candidate));
            }

            if (anyResolve == null || !HasPredicateVersion(anyResolve))
                return false;

            ExpressionSyntax target, followUp;
            TypeSyntax type;
            ParameterSyntax param;
            if (ReplaceWithOfTypeAnyAnalyzer.MatchSelect(anyInvoke, out target, out type, out param, out followUp))
            {
                // if (member == "Where" && followUp == null) return;
                diagnostic = Diagnostic.Create(
                    descriptor,
                    anyInvoke.GetLocation()
                );
                return true;
            }
            return false;
        }
        private static void HandleVariableDeclaration(SyntaxNodeAnalysisContext context)
        {
            VariableDeclarationSyntax syntax = (VariableDeclarationSyntax)context.Node;
            if (syntax.Parent.IsKind(SyntaxKind.FieldDeclaration)
                || syntax.Parent.IsKind(SyntaxKind.EventFieldDeclaration))
            {
                // This diagnostic is only for local variables.
                return;
            }

            if (NamedTypeHelpers.IsContainedInNativeMethodsClass(syntax))
            {
                return;
            }

            LocalDeclarationStatementSyntax parentDeclaration = syntax.Parent as LocalDeclarationStatementSyntax;
            if (parentDeclaration?.IsConst ?? false)
            {
                // this diagnostic does not apply to locals constants
                return;
            }

            foreach (VariableDeclaratorSyntax variableDeclarator in syntax.Variables)
            {
                if (variableDeclarator == null)
                {
                    continue;
                }

                var identifier = variableDeclarator.Identifier;
                CheckIdentifier(context, identifier);
            }
        }
        static bool TryGetDiagnostic(SyntaxNodeAnalysisContext nodeContext, out Diagnostic diagnostic)
        {
            diagnostic = default(Diagnostic);
            var node = nodeContext.Node as InvocationExpressionSyntax;
            MemberAccessExpressionSyntax mre = node.Expression as MemberAccessExpressionSyntax;
            if (mre == null)
                return false;
            if (mre.Name.Identifier.ValueText != "StartsWith")
                return false;

            var rr = nodeContext.SemanticModel.GetSymbolInfo(node, nodeContext.CancellationToken);
            if (rr.Symbol == null)
                return false;
            var symbol = rr.Symbol;
            if (!(symbol.ContainingType != null && symbol.ContainingType.SpecialType == SpecialType.System_String))
                return false;
            var parameters = symbol.GetParameters();
            var firstParameter = parameters.FirstOrDefault();
            if (firstParameter == null || firstParameter.Type.SpecialType != SpecialType.System_String)
                return false;   // First parameter not a string
            var lastParameter = parameters.Last();
            if (lastParameter.Type.Name == "StringComparison")
                return false;   // already specifying a string comparison
            diagnostic = Diagnostic.Create(
                descriptor,
                node.GetLocation()
            );
            return true;
        }
        static bool TryGetDiagnostic(SyntaxNodeAnalysisContext nodeContext, out Diagnostic diagnostic)
        {
            diagnostic = default(Diagnostic);
            if (nodeContext.IsFromGeneratedCode())
                return false;
            var node = nodeContext.Node as MethodDeclarationSyntax;

            if (!node.Modifiers.Any(m => m.IsKind(SyntaxKind.OverrideKeyword)))
                return false;
            var lastParam = node.ParameterList.Parameters.LastOrDefault();
            if (lastParam == null || lastParam.Modifiers.Any(m => m.IsKind(SyntaxKind.ParamsKeyword)))
                return false;
            if (lastParam.Type == null || !lastParam.Type.IsKind(SyntaxKind.ArrayType))
                return false;
            var rr = nodeContext.SemanticModel.GetDeclaredSymbol(node);
            if (rr == null || !rr.IsOverride)
                return false;
            var baseMember = rr.OverriddenMethod;
            if (baseMember == null || baseMember.Parameters.Length == 0 || !baseMember.Parameters.Last().IsParams)
                return false;

            diagnostic = Diagnostic.Create(
                descriptor,
                lastParam.GetLocation(),
                baseMember.Name
            );
            return true;
        }
        static bool TryGetDiagnostic(SyntaxNodeAnalysisContext nodeContext, out Diagnostic diagnostic)
        {
            diagnostic = default(Diagnostic);
            if (nodeContext.IsFromGeneratedCode())
                return false;
            var node = nodeContext.Node as ConditionalExpressionSyntax;

            bool? trueBranch = SimplifyConditionalTernaryExpressionCodeFixProvider.GetBool(node.WhenTrue.SkipParens());
            bool? falseBranch = SimplifyConditionalTernaryExpressionCodeFixProvider.GetBool(node.WhenFalse.SkipParens());

            if (trueBranch == falseBranch ||
                trueBranch == true && falseBranch == false) // Handled by RedundantTernaryExpressionIssue
                return false;

            var typeTrue = nodeContext.SemanticModel.GetTypeInfo(node.WhenTrue);
            var typeFalse = nodeContext.SemanticModel.GetTypeInfo(node.WhenFalse);
            if (typeTrue.Type == null || typeTrue.Type.SpecialType != SpecialType.System_Boolean ||
                typeFalse.Type == null || typeFalse.Type.SpecialType != SpecialType.System_Boolean)
                return false;


            diagnostic = Diagnostic.Create(
                descriptor,
                node.GetLocation()
            );
            return true;
        }
        void Check(SyntaxNodeAnalysisContext nodeContext, ExpressionSyntax condition)
        {
            if (condition == null)
                return;

            if (condition.IsKind(SyntaxKind.TrueLiteralExpression) || condition.IsKind(SyntaxKind.FalseLiteralExpression))
                return;

            var resolveResult = nodeContext.SemanticModel.GetConstantValue(condition);
            if (!resolveResult.HasValue || !(resolveResult.Value is bool))
                return;

            var value = (bool)resolveResult.Value;

            nodeContext.ReportDiagnostic(Diagnostic.Create(
                descriptor.Id,
                descriptor.Category,
                string.Format(descriptor.MessageFormat.ToString(), value),
                descriptor.DefaultSeverity,
                descriptor.DefaultSeverity,
                descriptor.IsEnabledByDefault,
                4,
                descriptor.Title,
                descriptor.Description,
                descriptor.HelpLinkUri,
                condition.GetLocation(),
                null,
                new[] { value.ToString() }
            ));
        }
        static bool TryGetDiagnostic(SyntaxNodeAnalysisContext nodeContext, out Diagnostic diagnostic)
        {
            diagnostic = default(Diagnostic);

            InitializerExpressionSyntax initializer = null;
            var node = nodeContext.Node as ArrayCreationExpressionSyntax;
            if (node != null) initializer = node.Initializer;
            var inode = nodeContext.Node as ImplicitArrayCreationExpressionSyntax;
            if (inode != null) initializer = inode.Initializer;

            if (initializer == null)
                return false;
            var varInitializer = nodeContext.Node.Parent.Parent;
            if (varInitializer == null)
                return false;
            var variableDeclaration = varInitializer.Parent as VariableDeclarationSyntax;
            if (variableDeclaration != null)
            {
                if (!variableDeclaration.Type.IsKind(SyntaxKind.ArrayType))
                    return false;
                diagnostic = Diagnostic.Create(
                    descriptor,
                    Location.Create(nodeContext.SemanticModel.SyntaxTree, TextSpan.FromBounds((node != null ? node.NewKeyword : inode.NewKeyword).Span.Start, initializer.Span.Start))
                );
                return true;
            }
            return false;
        }
        static bool TryGetDiagnostic(SyntaxNodeAnalysisContext nodeContext, out Diagnostic diagnostic)
        {
            diagnostic = default(Diagnostic);
            var node = nodeContext.Node as LocalDeclarationStatementSyntax;
            var member = node.AncestorsAndSelf().FirstOrDefault(n => n is MemberDeclarationSyntax);
            if (member == null)
                return false;
            var symbols = nodeContext.SemanticModel.LookupSymbols(member.SpanStart);
            var memberSymbol = nodeContext.SemanticModel.GetDeclaredSymbol(member);

            foreach (var variable in node.Declaration.Variables)
            {
                var hidingMember = symbols.FirstOrDefault(v => v.Name == variable.Identifier.ValueText && ((memberSymbol.IsStatic && v.IsStatic) || !memberSymbol.IsStatic) && !v.IsKind(SymbolKind.Local) && !v.IsKind(SymbolKind.Parameter));
                if (hidingMember == null)
                    continue;

                var mre = variable.Initializer?.Value as MemberAccessExpressionSyntax;
                if (mre != null && mre.Name.Identifier.ValueText == hidingMember.Name && mre.Expression.IsKind(SyntaxKind.ThisExpression))
                {
                    // Special case: the variable is initialized from the member it is hiding
                    // In this case, the hiding is obviously intentional and we shouldn't show a warning.
                    continue;
                }
                string memberType = GetMemberType(hidingMember.Kind);
                diagnostic = Diagnostic.Create(descriptor, variable.Identifier.GetLocation(), variable.Identifier, memberType, hidingMember.Name);
                return true;
            }
            return false;
        }
        private static void AnalyzeType(SyntaxNodeAnalysisContext context, TypeDeclarationSyntax typeDeclaration)
        {
            var previousFieldReadonly = true;
            var previousAccessLevel = AccessLevel.NotSpecified;
            var previousMemberStatic = true;
            foreach (var member in typeDeclaration.Members)
            {
                var field = member as FieldDeclarationSyntax;
                if (field == null)
                {
                    continue;
                }

                var currentFieldReadonly = field.Modifiers.Any(SyntaxKind.ReadOnlyKeyword);
                var currentAccessLevel = AccessLevelHelper.GetAccessLevel(field.Modifiers);
                currentAccessLevel = currentAccessLevel == AccessLevel.NotSpecified ? AccessLevel.Private : currentAccessLevel;
                var currentMemberStatic = field.Modifiers.Any(SyntaxKind.StaticKeyword);
                if (currentAccessLevel == previousAccessLevel
                    && currentMemberStatic
                    && previousMemberStatic
                    && currentFieldReadonly
                    && !previousFieldReadonly)
                {
                    context.ReportDiagnostic(Diagnostic.Create(Descriptor, NamedTypeHelpers.GetNameOrIdentifierLocation(field), AccessLevelHelper.GetName(currentAccessLevel)));
                }

                previousFieldReadonly = currentFieldReadonly;
                previousAccessLevel = currentAccessLevel;
                previousMemberStatic = currentMemberStatic;
            }
        }
        private static void HandleSyntaxNode(SyntaxNodeAnalysisContext context)
        {
            var node = context.Node;

            var documentation = node.GetDocumentationCommentTriviaSyntax();

            if (documentation != null)
            {
                IEnumerable<ParameterSyntax> parameterList = GetParameters(node);

                if (parameterList == null)
                {
                    return;
                }

                if (documentation.Content.GetFirstXmlElement(XmlCommentHelper.InheritdocXmlTag) != null)
                {
                    // Ignore nodes with an <inheritdoc/> tag.
                    return;
                }

                var xmlParameterNames = documentation.Content.GetXmlElements(XmlCommentHelper.ParamXmlTag)
                    .Select(XmlCommentHelper.GetFirstAttributeOrDefault<XmlNameAttributeSyntax>)
                    .Where(x => x != null)
                    .ToImmutableArray();

                foreach (var parameter in parameterList)
                {
                    if (!xmlParameterNames.Any(x => x.Identifier.Identifier.ValueText == parameter.Identifier.ValueText))
                    {
                        context.ReportDiagnostic(Diagnostic.Create(Descriptor, parameter.Identifier.GetLocation(), parameter.Identifier.ValueText));
                    }
                }
            }
        }
        private static void HandleArrayCreation(SyntaxNodeAnalysisContext context)
        {
            var arrayCreation = (ArrayCreationExpressionSyntax)context.Node;

            if (arrayCreation.Type == null)
            {
                return;
            }

            foreach (var arrayRankSpecifierSyntax in arrayCreation.Type.RankSpecifiers)
            {
                if (!arrayRankSpecifierSyntax.Sizes.Any())
                {
                    continue;
                }

                var lastSize = arrayRankSpecifierSyntax.Sizes
                    .Last();

                if (!arrayRankSpecifierSyntax.CloseBracketToken.IsMissing)
                {
                    CheckIfLocationOfLastArgumentOrParameterAndCloseTokenAreTheSame(
                        context,
                        lastSize,
                        arrayRankSpecifierSyntax.CloseBracketToken);
                }
            }
        }
        private static void ProcessUsingsAndReportDiagnostic(SyntaxList<UsingDirectiveSyntax> usings, SyntaxNodeAnalysisContext context)
        {
            string systemUsingDirectivesShouldBeBeforeThisName = null;
            for (var i = 1; i < usings.Count; i++)
            {
                var usingDirective = usings[i];

                if (usingDirective.Alias != null || !usingDirective.StaticKeyword.IsKind(SyntaxKind.None) || usingDirective.IsPrecededByPreprocessorDirective())
                {
                    continue;
                }

                if (usingDirective.IsSystemUsingDirective())
                {
                    if (systemUsingDirectivesShouldBeBeforeThisName != null)
                    {
                        context.ReportDiagnostic(Diagnostic.Create(Descriptor, usingDirective.GetLocation(), usingDirective.Name.ToNormalizedString(), systemUsingDirectivesShouldBeBeforeThisName));
                        continue;
                    }

                    var previousUsing = usings[i - 1];

                    if (!previousUsing.IsSystemUsingDirective() || previousUsing.StaticKeyword.Kind() != SyntaxKind.None)
                    {
                        systemUsingDirectivesShouldBeBeforeThisName = previousUsing.Name.ToNormalizedString();
                        context.ReportDiagnostic(Diagnostic.Create(Descriptor, usingDirective.GetLocation(), usingDirective.Name.ToNormalizedString(), systemUsingDirectivesShouldBeBeforeThisName));
                    }
                }
            }
        }
        private static void HandleBlock(SyntaxNodeAnalysisContext context)
        {
            BlockSyntax block = context.Node as BlockSyntax;

            if (block != null && block.Statements.Any())
            {
                var previousStatement = block.Statements[0];
                FileLinePositionSpan previousStatementLocation = previousStatement.GetLineSpan();
                FileLinePositionSpan currentStatementLocation;

                for (int i = 1; i < block.Statements.Count; i++)
                {
                    var currentStatement = block.Statements[i];
                    currentStatementLocation = currentStatement.GetLineSpan();

                    if (previousStatementLocation.EndLinePosition.Line
                        == currentStatementLocation.StartLinePosition.Line
                        && !IsLastTokenMissing(previousStatement))
                    {
                        context.ReportDiagnostic(Diagnostic.Create(Descriptor, block.Statements[i].GetLocation()));
                    }

                    previousStatementLocation = currentStatementLocation;
                    previousStatement = currentStatement;
                }
            }
        }
        private void AnalyzeRegexCreation(SyntaxNodeAnalysisContext context)
        {
            var objectCreation = (ObjectCreationExpressionSyntax) context.Node;

            var type = context.SemanticModel.GetSymbolInfo(objectCreation.Type).Symbol as ITypeSymbol;
            if (type == null || !type.Equals(context.SemanticModel.GetClrType(typeof(Regex))))
            {
                return;
            }

            var pattern = objectCreation.ArgumentList.Arguments[0].Expression.GetLiteral(context.SemanticModel);
            if (pattern == null)
            {
                return;
            }

            try
            {
                var regex = new Regex(pattern, RegexOptions.None, Timeout);
            }
            catch (ArgumentException e)
            {
                context.ReportDiagnostic(Diagnostic.Create(InvalidRegexRule, objectCreation.ArgumentList.Arguments[0].GetLocation(), e.Message));
            }
        }
 private static void AnalyzeInvocation(SyntaxNodeAnalysisContext context, Compilation compilation)
 {
     if (context.IsGenerated()) return;
     var methodInvokeSyntax = context.Node as InvocationExpressionSyntax;
     var childNodes = methodInvokeSyntax.ChildNodes();
     var methodCaller = childNodes.OfType<MemberAccessExpressionSyntax>().FirstOrDefault();
     if (methodCaller == null) return;
     var argumentsCount = CountArguments(childNodes);
     var classSymbol = GetCallerClassSymbol(context.SemanticModel, methodCaller.Expression);
     if (classSymbol == null || !classSymbol.MightContainExtensionMethods) return;
     var methodSymbol = GetCallerMethodSymbol(context.SemanticModel, methodCaller.Name, argumentsCount);
     if (methodSymbol == null || !methodSymbol.IsExtensionMethod) return;
     if (ContainsDynamicArgument(context.SemanticModel, childNodes)) return;
     ExpressionSyntax invocationStatement;
     if (methodInvokeSyntax.Parent.IsNotKind(SyntaxKind.ArrowExpressionClause))
     {
         invocationStatement = (methodInvokeSyntax.FirstAncestorOrSelfThatIsAStatement() as ExpressionStatementSyntax).Expression;
     }
     else
     {
         invocationStatement = methodInvokeSyntax.FirstAncestorOrSelfOfType<ArrowExpressionClauseSyntax>().Expression;
     }
     if (invocationStatement == null) return;
     if (IsSelectingADifferentMethod(childNodes, methodCaller.Name, context.Node.SyntaxTree, methodSymbol, invocationStatement, compilation)) return;
     context.ReportDiagnostic(Diagnostic.Create(Rule, methodCaller.GetLocation(), methodSymbol.Name, classSymbol.Name));
 }
        private static void HandleDocumentation(SyntaxNodeAnalysisContext context)
        {
            var documentationTrivia = context.Node as DocumentationCommentTriviaSyntax;

            if (documentationTrivia != null)
            {
                var summaryElement = documentationTrivia.Content.GetFirstXmlElement(XmlCommentHelper.SummaryXmlTag) as XmlElementSyntax;

                if (summaryElement != null)
                {
                    var textElement = summaryElement.Content.FirstOrDefault() as XmlTextSyntax;

                    if (textElement != null)
                    {
                        string text = XmlCommentHelper.GetText(textElement, true);

                        if (!string.IsNullOrEmpty(text))
                        {
                            if (text.TrimStart().StartsWith(DefaultText, StringComparison.Ordinal))
                            {
                                context.ReportDiagnostic(Diagnostic.Create(Descriptor, summaryElement.GetLocation()));
                            }
                        }
                    }
                }
            }
        }
    private static void AnalyzePropertyDeclaration(SyntaxNodeAnalysisContext context)
    {
      var propertyNode = (PropertyDeclarationSyntax)context.Node;

      if(!propertyNode.ContainsDiagnostics)
      {
        var propertySymbol = context.SemanticModel.GetDeclaredSymbol(propertyNode);
        var classSymbol = propertySymbol.ContainingType;

        if (propertySymbol != null && classSymbol != null &&
          classSymbol.IsStereotype() && !propertySymbol.IsAbstract &&
          !propertySymbol.IsStatic)
        {
          if (propertySymbol.GetMethod != null)
          {
            EvaluatePropertiesForSimplicityAnalyzer.AnalyzePropertyGetter(propertyNode, context);
          }

          if (propertySymbol.SetMethod != null)
          {
            EvaluatePropertiesForSimplicityAnalyzer.AnalyzePropertySetter(propertyNode, context);
          }
        }
      }
    }
        private static void AnalyzeTell(SyntaxNodeAnalysisContext context)
        {
            var invocationExpr = (InvocationExpressionSyntax)context.Node;

            // technically this should be a MemberAccessExpression, since it's invoked as a method off of IActorRef / ICanTell
            var memberAccessExpr = invocationExpr.Expression as MemberAccessExpressionSyntax;
            if (memberAccessExpr?.Name.ToString() != TargetMethodName) return;

            // need to verify that this `Tell` method is actually `ICanTell.Tell`
            var memberSymbol = context.SemanticModel.GetSymbolInfo(memberAccessExpr).Symbol as IMethodSymbol;

            var memberIsICanTell = (memberSymbol?.ToString().StartsWith(ICanTellMethodFQN) ?? false) || (memberSymbol?.ToString().StartsWith(IActorRefTellMethodFQN) ?? false);
            var memberIsActorRefExtension = memberSymbol?.ToString().StartsWith(ActorRefImplicitSenderTellFQN) ?? false;
            if (!memberIsICanTell && !memberIsActorRefExtension) return;

            // need to get the first argument being passed to the `Tell` method
            var argumentList = invocationExpr.ArgumentList as ArgumentListSyntax;
            if ((argumentList?.Arguments.Count ?? 0) < 1) return;

            // ReSharper disable once PossibleNullReferenceException //already validated as not null above
            var messageArgument =
                context.SemanticModel.GetSymbolInfo(memberIsICanTell ? argumentList.Arguments[0].Expression : argumentList.Arguments[1].Expression).Symbol;
            var allInterfaces = ((messageArgument as INamedTypeSymbol)?.Interfaces ?? ImmutableArray<INamedTypeSymbol>.Empty).Concat(messageArgument?.ContainingType.Interfaces ?? ImmutableArray<INamedTypeSymbol>.Empty).ToImmutableArray();
            if (allInterfaces.Any(y => y.ToString().StartsWith(ISystemMsgFQN)))
            {
                // found an ISystemMessage being passed into a Tell method
                var diagnostic = Diagnostic.Create(Rule, argumentList.GetLocation(), messageArgument.ToString(), DiagnosticSeverity.Error);
                context.ReportDiagnostic(diagnostic);
            }
        }
 // TODO: Ideally, a load of static code analysis here, but just checking the first use would be a start.
 private void FirstUseOfUntrustedParameterShouldNotBeArgumentToTrustedParameter(SyntaxNodeAnalysisContext context)
 {
     var parameterSyntax = (ParameterSyntax)context.Node;
     var model = context.SemanticModel;
     var parameter = model.GetDeclaredSymbol(parameterSyntax);
     if (parameter.HasAttribute(TrustedAttributeName))
     {
         return;
     }
     var container = parameter.ContainingSymbol;
     if ((container as IMethodSymbol)?.MethodKind == MethodKind.AnonymousFunction)
     {
         // Be lenient for anonymous functions. Not entirely sure whether this is a good idea,
         // admittedly.
         return;
     }
     var firstUse = container.DeclaringSyntaxReferences
         .SelectMany(syntaxRef => syntaxRef.GetSyntax().DescendantNodes())
         .Select(node => ParameterUsage.ForNode(node, model, parameter))
         .FirstOrDefault(usage => usage != null);
     if (firstUse?.CorrespondingParameter == null)
     {
         return;
     }
     if (firstUse.CorrespondingParameter.HasAttribute(TrustedAttributeName))
     {
         context.ReportDiagnostic(UntrustedParameterIsTrusted, firstUse.UsageNode, parameter.Name, container.Name);
     }
 }
        private static void AnalyzeNode(SyntaxNodeAnalysisContext context)
        {
            if (context.IsGenerated()) return;
            var lambda = context.Node as ExpressionSyntax;

            var invocation = GetInvocationIfAny(lambda);
            if (invocation == null || invocation.ArgumentList.Arguments.Count == 0) return;

            var lambdaParameters = BuildParameters(lambda);
            if (!MatchArguments(lambdaParameters, invocation.ArgumentList)) return;

            var root = lambda.SyntaxTree.GetRoot();
            var newRoot = root.ReplaceNode(lambda, invocation.Expression as ExpressionSyntax);

            var semanticNode = GetNodeRootForAnalysis(lambda);
            var newSemanticNode = newRoot.DescendantNodesAndSelf()
                .Where(x => x.SpanStart == semanticNode.SpanStart && x.Span.OverlapsWith(context.Node.Span))
                .LastOrDefault(x => x.Kind() == semanticNode.Kind());

            if (newSemanticNode == null || ReplacementChangesSemantics(semanticNode, newSemanticNode, context.SemanticModel)) return;

            var diagnostic = Diagnostic.Create(
                Rule,
                context.Node.GetLocation(),
                invocation.Expression.ToString());
            context.ReportDiagnostic(diagnostic);
        }
        private static void CheckOverridableCallInConstructor(SyntaxNodeAnalysisContext c)
        {
            var invocationExpression = (InvocationExpressionSyntax)c.Node;

            var calledOn = (invocationExpression.Expression as MemberAccessExpressionSyntax)?.Expression;
            var isCalledOnThis = calledOn == null || calledOn is ThisExpressionSyntax;
            if (!isCalledOnThis)
            {
                return;
            }

            var enclosingSymbol = c.SemanticModel.GetEnclosingSymbol(invocationExpression.SpanStart) as IMethodSymbol;
            if (!IsMethodConstructor(enclosingSymbol))
            {
                return;
            }

            var methodSymbol = c.SemanticModel.GetSymbolInfo(invocationExpression.Expression).Symbol as IMethodSymbol;

            if (methodSymbol != null &&
                IsMethodOverridable(methodSymbol) &&
                enclosingSymbol.IsInType(methodSymbol.ContainingType))
            {
                c.ReportDiagnostic(Diagnostic.Create(Rule, invocationExpression.Expression.GetLocation(),
                    methodSymbol.Name));
            }
        }
Exemple #31
0
        private void HandleElementAccess(SyntaxNodeAnalysisContext context)
        {
            var elementAccess = (ElementAccessExpressionSyntax)context.Node;

            AnalyzeArgumentList(context, elementAccess.ArgumentList);
        }
 internal static void AnalyzeNotEqualsExpression(SyntaxNodeAnalysisContext context)
 {
     Analyze(context, (BinaryExpressionSyntax)context.Node);
 }
        private void AnalyzeTernaryConditionalExpression(
            SyntaxNodeAnalysisContext context,
            INamedTypeSymbol?expressionType,
            IMethodSymbol?referenceEqualsMethod)
        {
            var cancellationToken     = context.CancellationToken;
            var conditionalExpression = (TConditionalExpressionSyntax)context.Node;

            var option = context.GetAnalyzerOptions().PreferNullPropagation;

            if (!option.Value)
            {
                return;
            }

            var syntaxFacts = GetSyntaxFacts();

            syntaxFacts.GetPartsOfConditionalExpression(
                conditionalExpression, out var condition, out var whenTrue, out var whenFalse);

            var conditionNode = (TExpressionSyntax)condition;

            var whenTrueNode  = (TExpressionSyntax)syntaxFacts.WalkDownParentheses(whenTrue);
            var whenFalseNode = (TExpressionSyntax)syntaxFacts.WalkDownParentheses(whenFalse);

            if (!TryAnalyzeCondition(
                    context, syntaxFacts, referenceEqualsMethod, conditionNode,
                    out var conditionPartToCheck, out var isEquals))
            {
                return;
            }

            // Needs to be of the form:
            //      x == null ? null : ...    or
            //      x != null ? ...  : null;
            if (isEquals && !syntaxFacts.IsNullLiteralExpression(whenTrueNode))
            {
                return;
            }

            if (!isEquals && !syntaxFacts.IsNullLiteralExpression(whenFalseNode))
            {
                return;
            }

            var whenPartToCheck = isEquals ? whenFalseNode : whenTrueNode;

            var semanticModel = context.SemanticModel;
            var whenPartMatch = GetWhenPartMatch(syntaxFacts, semanticModel, conditionPartToCheck, whenPartToCheck, cancellationToken);

            if (whenPartMatch == null)
            {
                return;
            }

            // can't use ?. on a pointer
            var whenPartType = semanticModel.GetTypeInfo(whenPartMatch, cancellationToken).Type;

            if (whenPartType is IPointerTypeSymbol)
            {
                return;
            }

            // ?. is not available in expression-trees.  Disallow the fix in that case.
            var type = semanticModel.GetTypeInfo(conditionalExpression, cancellationToken).Type;

            if (type?.IsValueType == true)
            {
                if (type is not INamedTypeSymbol namedType || namedType.ConstructedFrom.SpecialType != SpecialType.System_Nullable_T)
                {
                    // User has something like:  If(str is nothing, nothing, str.Length)
                    // In this case, converting to str?.Length changes the type of this from
                    // int to int?
                    return;
                }
                // But for a nullable type, such as  If(c is nothing, nothing, c.nullable)
                // converting to c?.nullable doesn't affect the type
            }

            if (IsInExpressionTree(semanticModel, conditionNode, expressionType, cancellationToken))
            {
                return;
            }

            var locations = ImmutableArray.Create(
                conditionalExpression.GetLocation(),
                conditionPartToCheck.GetLocation(),
                whenPartToCheck.GetLocation());

            var whenPartIsNullable = whenPartType?.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T;
            var properties         = whenPartIsNullable
                ? s_whenPartIsNullableProperties
                : ImmutableDictionary <string, string?> .Empty;

            context.ReportDiagnostic(DiagnosticHelper.Create(
                                         Descriptor,
                                         conditionalExpression.GetLocation(),
                                         option.Notification.Severity,
                                         locations,
                                         properties));
        }
        private static void HandleMemberDeclaration(SyntaxNodeAnalysisContext context, bool needsComment, SyntaxNode node, TypeParameterListSyntax typeParameterList)
        {
            if (!needsComment)
            {
                // Documentation is not required for this element.
                return;
            }

            if (typeParameterList == null)
            {
                // The member does not have a type parameter list
                return;
            }

            var documentation = node.GetDocumentationCommentTriviaSyntax();

            if (documentation == null)
            {
                // Don't report if the documentation is missing
                return;
            }

            if (documentation.Content.GetFirstXmlElement(XmlCommentHelper.InheritdocXmlTag) != null)
            {
                // Ignore nodes with an <inheritdoc/> tag.
                return;
            }

            // Check if the return value is documented
            var includeElement = documentation.Content.GetFirstXmlElement(XmlCommentHelper.IncludeXmlTag);

            if (includeElement != null)
            {
                string rawDocumentation;
                var    declaration = context.SemanticModel.GetDeclaredSymbol(context.Node, context.CancellationToken);
                if (declaration == null)
                {
                    return;
                }

                rawDocumentation = declaration.GetDocumentationCommentXml(expandIncludes: true, cancellationToken: context.CancellationToken);
                var completeDocumentation = XElement.Parse(rawDocumentation, LoadOptions.None);
                if (completeDocumentation.Nodes().OfType <XElement>().Any(element => element.Name == XmlCommentHelper.InheritdocXmlTag))
                {
                    // Ignore nodes with an <inheritdoc/> tag in the included XML.
                    return;
                }

                var typeParameterAttributes = completeDocumentation.Nodes()
                                              .OfType <XElement>()
                                              .Where(element => element.Name == XmlCommentHelper.TypeParamXmlTag)
                                              .Select(element => element.Attribute(XmlCommentHelper.NameArgumentName))
                                              .Where(x => x != null);

                foreach (var parameter in typeParameterList.Parameters)
                {
                    if (!typeParameterAttributes.Any(x => x.Value == parameter.Identifier.ValueText))
                    {
                        context.ReportDiagnostic(Diagnostic.Create(Descriptor, parameter.Identifier.GetLocation(), parameter.Identifier.ValueText));
                    }
                }
            }
            else
            {
                var xmlParameterNames = documentation.Content.GetXmlElements(XmlCommentHelper.TypeParamXmlTag)
                                        .Select(XmlCommentHelper.GetFirstAttributeOrDefault <XmlNameAttributeSyntax>)
                                        .Where(x => x != null)
                                        .ToImmutableArray();

                foreach (var parameter in typeParameterList.Parameters)
                {
                    if (!xmlParameterNames.Any(x => x.Identifier.Identifier.ValueText == parameter.Identifier.ValueText))
                    {
                        context.ReportDiagnostic(Diagnostic.Create(Descriptor, parameter.Identifier.GetLocation(), parameter.Identifier.ValueText));
                    }
                }
            }
        }
Exemple #35
0
        private static void CheckForNullDereference(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
        {
            var methodSymbol = context.SemanticModel.GetSymbolInfo(context.Node).Symbol
                               ?? context.SemanticModel.GetDeclaredSymbol(context.Node);

            if (!methodSymbol.IsPubliclyAccessible())
            {
                return;
            }

            var nullPointerCheck = new NullPointerDereference.NullPointerCheck(explodedGraph);

            explodedGraph.AddExplodedGraphCheck(nullPointerCheck);

            var identifiers = new HashSet <IdentifierNameSyntax>();

            void memberAccessingHandler(object sender, MemberAccessingEventArgs args) => CollectMemberAccesses(args, identifiers, context.SemanticModel);

            nullPointerCheck.MemberAccessing += memberAccessingHandler;

            try
            {
                explodedGraph.Walk();
            }
            finally
            {
                nullPointerCheck.MemberAccessing -= memberAccessingHandler;
            }

            foreach (var identifier in identifiers)
            {
                var message = IsArgumentOfConstructorInitializer(identifier)
                    ? string.Format(Constructor, identifier.Identifier.ValueText)
                    : string.Format(Method, identifier.Identifier.ValueText);

                context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, identifier.GetLocation(), message));
            }

            bool IsArgumentOfConstructorInitializer(IdentifierNameSyntax identifier) =>
            identifier.FirstAncestorOrSelf <ConstructorInitializerSyntax>() != null;
        }
Exemple #36
0
        protected override void AnalyzeNode(SyntaxNodeAnalysisContext context)
        {
            var node          = context.Node;
            var semanticModel = context.SemanticModel;
            Action <Diagnostic> reportDiagnostic = context.ReportDiagnostic;
            var    cancellationToken             = context.CancellationToken;
            string filePath = node.SyntaxTree.FilePath;

            // An InitializerExpressionSyntax has an ObjectCreationExpressionSyntax as it's parent, i.e
            // var testing = new TestClass { Name = "Bob" };
            //               |             |--------------| <- InitializerExpressionSyntax or SyntaxKind.ObjectInitializerExpression
            //               |----------------------------| <- ObjectCreationExpressionSyntax or SyntaxKind.ObjectCreationExpression
            var initializerExpression = node as InitializerExpressionSyntax;

            if (initializerExpression?.Parent is ObjectCreationExpressionSyntax)
            {
                var objectCreation = node.Parent as ObjectCreationExpressionSyntax;
                var typeInfo       = semanticModel.GetTypeInfo(objectCreation, cancellationToken);
                if (typeInfo.ConvertedType?.TypeKind != TypeKind.Error &&
                    typeInfo.ConvertedType?.IsReferenceType == true &&
                    objectCreation.Parent?.IsKind(SyntaxKind.EqualsValueClause) == true &&
                    objectCreation.Parent?.Parent?.IsKind(SyntaxKind.VariableDeclarator) == true)
                {
                    reportDiagnostic(Diagnostic.Create(InitializerCreationRule, ((VariableDeclaratorSyntax)objectCreation.Parent.Parent).Identifier.GetLocation(), EmptyMessageArgs));
                    HeapAllocationAnalyzerEventSource.Logger.NewInitializerExpression(filePath);
                    return;
                }
            }

            var implicitArrayExpression = node as ImplicitArrayCreationExpressionSyntax;

            if (implicitArrayExpression != null)
            {
                reportDiagnostic(Diagnostic.Create(ImplicitArrayCreationRule, implicitArrayExpression.NewKeyword.GetLocation(), EmptyMessageArgs));
                HeapAllocationAnalyzerEventSource.Logger.NewImplicitArrayCreationExpression(filePath);
                return;
            }

            var newAnon = node as AnonymousObjectCreationExpressionSyntax;

            if (newAnon != null)
            {
                reportDiagnostic(Diagnostic.Create(AnonymousNewObjectRule, newAnon.NewKeyword.GetLocation(), EmptyMessageArgs));
                HeapAllocationAnalyzerEventSource.Logger.NewAnonymousObjectCreationExpression(filePath);
                return;
            }

            var newArr = node as ArrayCreationExpressionSyntax;

            if (newArr != null)
            {
                reportDiagnostic(Diagnostic.Create(NewArrayRule, newArr.NewKeyword.GetLocation(), EmptyMessageArgs));
                HeapAllocationAnalyzerEventSource.Logger.NewArrayExpression(filePath);
                return;
            }

            var newObj = node as ObjectCreationExpressionSyntax;

            if (newObj != null)
            {
                var typeInfo = semanticModel.GetTypeInfo(newObj, cancellationToken);
                if (typeInfo.ConvertedType != null && typeInfo.ConvertedType.TypeKind != TypeKind.Error && typeInfo.ConvertedType.IsReferenceType)
                {
                    reportDiagnostic(Diagnostic.Create(NewObjectRule, newObj.NewKeyword.GetLocation(), EmptyMessageArgs));
                    HeapAllocationAnalyzerEventSource.Logger.NewObjectCreationExpression(filePath);
                }
                return;
            }

            var letKind = node as LetClauseSyntax;

            if (letKind != null)
            {
                reportDiagnostic(Diagnostic.Create(LetCauseRule, letKind.LetKeyword.GetLocation(), EmptyMessageArgs));
                HeapAllocationAnalyzerEventSource.Logger.LetClauseExpression(filePath);
                return;
            }
        }
 public static void Analyze(SyntaxNodeAnalysisContext context, in SimpleMemberInvocationExpressionInfo invocationInfo)
            private void AnalyzeInvocation(SyntaxNodeAnalysisContext context)
            {
                var           invocation    = (TInvocationExpressionSyntax)context.Node;
                SemanticModel semanticModel = context.SemanticModel;

                ISymbol symbol = semanticModel.GetSymbolInfo(invocation, context.CancellationToken).Symbol;

                if (symbol == null || symbol.Kind != SymbolKind.Method || !symbol.Name.StartsWith("Register", StringComparison.Ordinal))
                {
                    return;
                }

                var method = (IMethodSymbol)symbol;

                NoteRegisterActionInvocation(method, invocation, semanticModel, context.CancellationToken);

                bool isRegisterSymbolAction         = IsRegisterAction(DiagnosticWellKnownNames.RegisterSymbolActionName, method, _analysisContext, _compilationStartAnalysisContext);
                bool isRegisterSyntaxNodeAction     = IsRegisterAction(DiagnosticWellKnownNames.RegisterSyntaxNodeActionName, method, _analysisContext, _compilationStartAnalysisContext, _codeBlockStartAnalysisContext);
                bool isRegisterCodeBlockStartAction = IsRegisterAction(DiagnosticWellKnownNames.RegisterCodeBlockStartActionName, method, _analysisContext, _compilationStartAnalysisContext);
                bool isRegisterOperationAction      = IsRegisterAction(DiagnosticWellKnownNames.RegisterOperationActionName, method, _analysisContext, _compilationStartAnalysisContext, _operationBlockStartAnalysisContext);

                if (isRegisterSymbolAction || isRegisterSyntaxNodeAction || isRegisterOperationAction)
                {
                    if (method.Parameters.Length == 2 && method.Parameters[1].IsParams)
                    {
                        IEnumerable <SyntaxNode>?arguments = GetArgumentExpressions(invocation);
                        if (arguments != null)
                        {
                            int argumentCount = arguments.Count();
                            if (argumentCount >= 1)
                            {
                                ITypeSymbol type = semanticModel.GetTypeInfo(arguments.First(), context.CancellationToken).ConvertedType;
                                if (type == null || type.Name.Equals(nameof(Action), StringComparison.Ordinal))
                                {
                                    if (argumentCount == 1)
                                    {
                                        DiagnosticDescriptor rule;
                                        if (isRegisterSymbolAction)
                                        {
                                            rule = MissingSymbolKindArgumentRule;
                                        }
                                        else if (isRegisterOperationAction)
                                        {
                                            rule = MissingOperationKindArgumentRule;
                                        }
                                        else
                                        {
                                            rule = MissingSyntaxKindArgumentRule;
                                        }

                                        SyntaxNode invocationExpression = GetInvocationExpression(invocation);
                                        Diagnostic diagnostic           = invocationExpression.CreateDiagnostic(rule);
                                        context.ReportDiagnostic(diagnostic);
                                    }
                                    else if (isRegisterSymbolAction)
                                    {
                                        foreach (SyntaxNode argument in arguments.Skip(1))
                                        {
                                            symbol = semanticModel.GetSymbolInfo(argument, context.CancellationToken).Symbol;
                                            if (symbol != null &&
#pragma warning disable CA1508 // Avoid dead conditional code - https://github.com/dotnet/roslyn-analyzers/issues/4519
                                                symbol.Kind == SymbolKind.Field &&
#pragma warning restore CA1508 // Avoid dead conditional code
                                                _symbolKind.Equals(symbol.ContainingType) &&
                                                !s_supportedSymbolKinds.Contains(symbol.Name))
                                            {
                                                Diagnostic diagnostic = argument.CreateDiagnostic(UnsupportedSymbolKindArgumentRule, symbol.Name);
                                                context.ReportDiagnostic(diagnostic);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                if (!method.TypeParameters.IsEmpty &&
                    (isRegisterSyntaxNodeAction || isRegisterCodeBlockStartAction))
                {
                    ITypeSymbol?typeArgument = null;
                    if (method.TypeParameters.Length == 1)
                    {
                        if (method.TypeParameters[0].Name == DiagnosticWellKnownNames.TLanguageKindEnumName)
                        {
                            typeArgument = method.TypeArguments[0];
                        }
                    }
                    else
                    {
                        ITypeParameterSymbol typeParam = method.TypeParameters.FirstOrDefault(t => t.Name == DiagnosticWellKnownNames.TLanguageKindEnumName);
                        if (typeParam != null)
                        {
                            int index = method.TypeParameters.IndexOf(typeParam);
                            typeArgument = method.TypeArguments[index];
                        }
                    }

                    if (typeArgument != null &&
                        typeArgument.TypeKind != TypeKind.TypeParameter &&
                        typeArgument.TypeKind != TypeKind.Error &&
                        !IsSyntaxKind(typeArgument))
                    {
                        Location location = typeArgument.Locations[0];
                        if (!location.IsInSource)
                        {
                            SyntaxNode invocationExpression = GetInvocationExpression(invocation);
                            location = invocationExpression.GetLocation();
                        }

                        Diagnostic diagnostic = Diagnostic.Create(InvalidSyntaxKindTypeArgumentRule, location, typeArgument.Name, DiagnosticWellKnownNames.TLanguageKindEnumName, method.Name);
                        context.ReportDiagnostic(diagnostic);
                    }
                }
            }
Exemple #39
0
        private static void CheckEmptyNullableAccess(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
        {
            var nullPointerCheck = new NullValueAccessedCheck(explodedGraph);

            explodedGraph.AddExplodedGraphCheck(nullPointerCheck);

            var nullIdentifiers = new HashSet <IdentifierNameSyntax>();

            void nullValueAccessedHandler(object sender, MemberAccessedEventArgs args) => nullIdentifiers.Add(args.Identifier);

            nullPointerCheck.ValuePropertyAccessed += nullValueAccessedHandler;

            try
            {
                explodedGraph.Walk();
            }
            finally
            {
                nullPointerCheck.ValuePropertyAccessed -= nullValueAccessedHandler;
            }

            foreach (var nullIdentifier in nullIdentifiers)
            {
                context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, nullIdentifier.Parent.GetLocation(), nullIdentifier.Identifier.ValueText));
            }
        }
Exemple #40
0
        private static void AnalyzeUsingStatement(SyntaxNodeAnalysisContext context)
        {
            var usingStatement = (UsingStatementSyntax)context.Node;

            StatementSyntax statement = usingStatement.Statement;

            if (statement?.Kind() != SyntaxKind.Block)
            {
                return;
            }

            var block = (BlockSyntax)statement;

            StatementSyntax lastStatement = block.Statements.LastOrDefault();

            if (lastStatement == null)
            {
                return;
            }

            if (lastStatement.SpanContainsDirectives())
            {
                return;
            }

            SimpleMemberInvocationStatementInfo info = SyntaxInfo.SimpleMemberInvocationStatementInfo(lastStatement);

            if (!info.Success)
            {
                return;
            }

            if (info.Arguments.Any())
            {
                return;
            }

            string methodName = info.NameText;

            if (methodName != "Dispose" && methodName != "Close")
            {
                return;
            }

            ExpressionSyntax usingExpression = usingStatement.Expression;

            if (usingExpression != null)
            {
                if (CSharpFactory.AreEquivalent(info.Expression, usingExpression))
                {
                    ReportDiagnostic(context, info.Statement, methodName);
                }
            }
            else
            {
                VariableDeclarationSyntax usingDeclaration = usingStatement.Declaration;

                if (usingDeclaration != null &&
                    info.Expression.Kind() == SyntaxKind.IdentifierName)
                {
                    var identifierName = (IdentifierNameSyntax)info.Expression;

                    VariableDeclaratorSyntax declarator = usingDeclaration.Variables.LastOrDefault();

                    if (declarator != null &&
                        declarator.Identifier.ValueText == identifierName.Identifier.ValueText)
                    {
                        ISymbol symbol = context.SemanticModel.GetDeclaredSymbol(declarator, context.CancellationToken);

                        if (SymbolEqualityComparer.Default.Equals(symbol, context.SemanticModel.GetSymbol(identifierName, context.CancellationToken)))
                        {
                            ReportDiagnostic(context, info.Statement, methodName);
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Analyzes the top-level elements of a documentation comment.
 /// </summary>
 /// <param name="context">The current analysis context.</param>
 /// <param name="settings">The StyleCop settings to use.</param>
 /// <param name="needsComment"><see langword="true"/> if the current documentation settings indicate that the
 /// element should be documented; otherwise, <see langword="false"/>.</param>
 /// <param name="syntaxList">The <see cref="XmlElementSyntax"/> or <see cref="XmlEmptyElementSyntax"/> of the node
 /// to examine.</param>
 /// <param name="diagnosticLocations">The location(s) where diagnostics, if any, should be reported.</param>
 protected abstract void HandleXmlElement(SyntaxNodeAnalysisContext context, StyleCopSettings settings, bool needsComment, IEnumerable <XmlNodeSyntax> syntaxList, params Location[] diagnosticLocations);
 /// <summary>
 /// Analyzes the XML elements of a documentation comment.
 /// </summary>
 /// <param name="context">The current analysis context.</param>
 /// <param name="needsComment"><see langword="true"/> if the current documentation settings indicate that the
 /// element should be documented; otherwise, <see langword="false"/>.</param>
 /// <param name="completeDocumentation">The complete documentation for the declared symbol, with any
 /// <c>&lt;include&gt;</c> elements expanded. If the XML documentation comment included a <c>&lt;param&gt;</c>
 /// element, this value will be <see langword="null"/>, even if the XML documentation comment also included an
 /// <c>&lt;include&gt;</c> element.</param>
 /// <param name="diagnosticLocations">The location(s) where diagnostics, if any, should be reported.</param>
 protected abstract void HandleCompleteDocumentation(SyntaxNodeAnalysisContext context, bool needsComment, XElement completeDocumentation, params Location[] diagnosticLocations);
 protected abstract void LanguageSpecificAnalyzeSyntax(
     SyntaxNodeAnalysisContext context,
     SyntaxTree syntaxTree,
     AnalyzerOptions options,
     CancellationToken cancellationToken
     );
 protected abstract TContext CreateContext(SyntaxNodeAnalysisContext context);
 public void AnalyzeNode(SyntaxNodeAnalysisContext context)
 {
     // Ensure only executable nodes are analyzed.
     Assert.NotEqual(SyntaxKind.MethodDeclaration, context.Node.Kind());
     context.ReportDiagnostic(Diagnostic.Create(Descriptor, context.Node.GetLocation()));
 }
Exemple #46
0
        private void AnalyzeSqlTypeMatching(SyntaxNodeAnalysisContext context)
        {
            var expression = (AssignmentExpressionSyntax)context.Node;

            if (expression.Left is MemberAccessExpressionSyntax leftExpression && leftExpression.Expression is InvocationExpressionSyntax addExpression)
            {
                if (addExpression.ArgumentList.Arguments.Count < 1)
                {
                    return;
                }

                var dbParameterMetaName = context.Compilation.GetTypeByMetadataName(typeof(DbParameter).FullName);
                var valueSymbol         = context.SemanticModel.GetSymbolInfo(leftExpression).Symbol; // command.Parameters.Add().|Value|

                if (valueSymbol is null)
                {
                    return;
                }

                if (valueSymbol.IsOverride &&
                    valueSymbol.Name == "Value" &&
                    valueSymbol is IPropertySymbol valuePropertySymbol &&
                    SymbolEqualityComparer.Default.Equals(dbParameterMetaName, valuePropertySymbol.OverriddenProperty.ContainingType) &&
                    addExpression.ArgumentList.Arguments[1].Expression is MemberAccessExpressionSyntax sqlType)
                {
                    SpecialType rightExpressionType = 0;

                    if (expression.Right is IdentifierNameSyntax identifierExpression)
                    {
                        rightExpressionType = context.SemanticModel.GetTypeInfo(identifierExpression).Type.SpecialType;
                    }

                    else if (expression.Right is BinaryExpressionSyntax binaryExpression)
                    {
                        if (binaryExpression.Left is CastExpressionSyntax leftCast)
                        {
                            rightExpressionType = context.SemanticModel.GetTypeInfo(leftCast.Expression).Type.SpecialType;
                        }
                        else
                        {
                            rightExpressionType = context.SemanticModel.GetTypeInfo(binaryExpression.Left).Type.SpecialType;
                        }
                    }

                    else if (expression.Right is ExpressionSyntax expressionExpression)
                    {
                        rightExpressionType = context.SemanticModel.GetTypeInfo(expressionExpression).Type.SpecialType;
                    }

                    if (rightExpressionType is SpecialType.System_Object or SpecialType.None)
                    {
                        return;
                    }

                    if (!IsValid(rightExpressionType, sqlType.Name.Identifier.ValueText))
                    {
                        var diagnostic = Diagnostic.Create(SqlTypeMatching, expression.GetLocation());
                        context.ReportDiagnostic(diagnostic);
                    }
                }
            }
        }
 private void AnalyzeClassSyntax(SyntaxNodeAnalysisContext context)
 {
     CheckStructShouldImplementIEquatable(context);
 }
 private static void AnalyzeNode(SyntaxNodeAnalysisContext context)
 {
     context.ReportDiagnostic(Diagnostic.Create(Descriptor, context.Node.GetLocation()));
 }
Exemple #49
0
        /// <summary>
        /// Function returns members that are considered to be grouped with another member of the same interface (adjacent members).
        /// These members are allowed to be grouped by interface and not forced to be grouped by member name.
        /// Another overload (not related by interface) can be placed somewhere else.
        ///
        /// Returned ImmutableArray of interfaces for each member is used to determine whether overloads of the same interface should be grouped by name.
        /// If all methods of the class implement single interface, we want the overloads to be placed together within interface group.
        /// </summary>
        private static Dictionary <TMemberDeclarationSyntax, ImmutableArray <INamedTypeSymbol> > MembersGroupedByInterface(SyntaxNodeAnalysisContext c, IEnumerable <TMemberDeclarationSyntax> members)
        {
            var ret = new Dictionary <TMemberDeclarationSyntax, ImmutableArray <INamedTypeSymbol> >();
            ImmutableArray <INamedTypeSymbol> currentInterfaces, previousInterfaces = ImmutableArray <INamedTypeSymbol> .Empty;
            TMemberDeclarationSyntax          previous = null;

            foreach (var member in members)
            {
                currentInterfaces = FindInterfaces(c.SemanticModel, member);
                if (currentInterfaces.Intersect(previousInterfaces).Any())
                {
                    ret.Add(member, currentInterfaces);
                    if (previous != null && !ret.ContainsKey(previous))
                    {
                        ret.Add(previous, previousInterfaces);
                    }
                }
                previousInterfaces = currentInterfaces;
                previous           = member;
            }
            return(ret);
        }
Exemple #50
0
 protected abstract MemberInfo CreateMemberInfo(SyntaxNodeAnalysisContext c, TMemberDeclarationSyntax member);
Exemple #51
0
        private void HandleConversionOperatorDeclaration(SyntaxNodeAnalysisContext context)
        {
            var conversionOperatorDeclaration = (ConversionOperatorDeclarationSyntax)context.Node;

            AnalyzeParametersList(context, conversionOperatorDeclaration.ParameterList);
        }
Exemple #52
0
        private void HandleLambdaExpression(SyntaxNodeAnalysisContext context)
        {
            var lambdaExpression = (ParenthesizedLambdaExpressionSyntax)context.Node;

            AnalyzeParametersList(context, lambdaExpression.ParameterList);
        }
Exemple #53
0
        private void HandleMethodInvocation(SyntaxNodeAnalysisContext context)
        {
            var invocationExpression = (InvocationExpressionSyntax)context.Node;

            AnalyzeArgumentList(context, invocationExpression.ArgumentList);
        }
Exemple #54
0
        private void HandleMethodDeclaration(SyntaxNodeAnalysisContext context)
        {
            var methodDeclaration = (MethodDeclarationSyntax)context.Node;

            AnalyzeParametersList(context, methodDeclaration.ParameterList);
        }
        private static bool TryAnalyzeInvocationCondition(
            SyntaxNodeAnalysisContext context,
            ISyntaxFacts syntaxFacts,
            IMethodSymbol?referenceEqualsMethod,
            TInvocationExpressionSyntax invocation,
            [NotNullWhen(true)] out TExpressionSyntax?conditionPartToCheck,
            out bool isEquals)
        {
            conditionPartToCheck = null;
            isEquals             = true;

            if (referenceEqualsMethod == null)
            {
                return(false);
            }

            var expression = syntaxFacts.GetExpressionOfInvocationExpression(invocation);
            var nameNode   = syntaxFacts.IsIdentifierName(expression)
                ? expression
                : syntaxFacts.IsSimpleMemberAccessExpression(expression)
                    ? syntaxFacts.GetNameOfMemberAccessExpression(expression)
                    : null;

            if (!syntaxFacts.IsIdentifierName(nameNode))
            {
                return(false);
            }

            syntaxFacts.GetNameAndArityOfSimpleName(nameNode, out var name, out _);
            if (!syntaxFacts.StringComparer.Equals(name, nameof(ReferenceEquals)))
            {
                return(false);
            }

            var arguments = syntaxFacts.GetArgumentsOfInvocationExpression(invocation);

            if (arguments.Count != 2)
            {
                return(false);
            }

            var conditionLeft  = (TExpressionSyntax)syntaxFacts.GetExpressionOfArgument(arguments[0]);
            var conditionRight = (TExpressionSyntax)syntaxFacts.GetExpressionOfArgument(arguments[1]);

            if (conditionLeft == null || conditionRight == null)
            {
                return(false);
            }

            conditionPartToCheck = GetConditionPartToCheck(syntaxFacts, conditionLeft, conditionRight);
            if (conditionPartToCheck == null)
            {
                return(false);
            }

            var semanticModel     = context.SemanticModel;
            var cancellationToken = context.CancellationToken;
            var symbol            = semanticModel.GetSymbolInfo(invocation, cancellationToken).Symbol;

            return(referenceEqualsMethod.Equals(symbol));
        }
Exemple #56
0
        private void HandleIndexerDeclaration(SyntaxNodeAnalysisContext context)
        {
            var indexerDeclaration = (IndexerDeclarationSyntax)context.Node;

            AnalyzeBracketParametersList(context, indexerDeclaration.ParameterList);
        }
Exemple #57
0
        private void HandleAttributesList(SyntaxNodeAnalysisContext context)
        {
            var attributesList = (AttributeListSyntax)context.Node;

            AnalyzeAttributeList(context, attributesList);
        }
Exemple #58
0
        private void HandleDelegateDeclaration(SyntaxNodeAnalysisContext context)
        {
            var delegateDeclaration = (DelegateDeclarationSyntax)context.Node;

            AnalyzeParametersList(context, delegateDeclaration.ParameterList);
        }
Exemple #59
0
        private void HandleAnonymousMethod(SyntaxNodeAnalysisContext context)
        {
            var anonymousMethod = (AnonymousMethodExpressionSyntax)context.Node;

            AnalyzeParametersList(context, anonymousMethod.ParameterList);
        }
Exemple #60
0
        private void HandleAttribute(SyntaxNodeAnalysisContext context)
        {
            var attribute = (AttributeSyntax)context.Node;

            AnalyzeArgumentList(context, attribute.ArgumentList);
        }