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 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()));
                            }
                        }
                    }
                }
            }
        }
        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 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;
        }
        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;
        }
        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;
        }
        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 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));
            }
        }
Example #10
0
        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);
            }
        }
 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 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 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);
        }
 // 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);
     }
 }
        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;
        }
        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));
                    }
                }
            }
        }
        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;
        }
        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 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);
            }
        }
        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));
                    }
                }
            }
        }
Example #21
0
        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);
            }
        }
        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 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;
        }
        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;
        }
        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 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 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));
        }
      }
    }
        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() }
            ));
        }
        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()));
        }
Example #30
0
        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));
            }
        }