Example #1
0
        private void AnalyzeObjectCreationExpression(SyntaxNodeAnalysisContext context)
        {
            if (GeneratedCodeAnalyzer?.IsGeneratedCode(context) == true)
            {
                return;
            }

            var objectCreationExpression = (ObjectCreationExpressionSyntax)context.Node;

            if (objectCreationExpression.Type == null || objectCreationExpression.Initializer == null)
            {
                return;
            }

            InitializerExpressionSyntax initializer = objectCreationExpression.Initializer;

            if (initializer.Expressions.Count == 0 &&
                initializer.OpenBraceToken.TrailingTrivia.IsWhitespaceOrEndOfLine() &&
                initializer.CloseBraceToken.LeadingTrivia.IsWhitespaceOrEndOfLine())
            {
                context.ReportDiagnostic(
                    DiagnosticDescriptors.RemoveEmptyObjectInitializer,
                    initializer.GetLocation());
            }

            ArgumentListSyntax argumentList = objectCreationExpression.ArgumentList;

            if (argumentList == null)
            {
                Location location = Location.Create(
                    context.Node.SyntaxTree,
                    new TextSpan(objectCreationExpression.Type.Span.End, 1));

                context.ReportDiagnostic(
                    DiagnosticDescriptors.AddConstructorArgumentList,
                    location);
            }
            else if (argumentList.Arguments.Count == 0 &&
                     !argumentList.OpenParenToken.IsMissing &&
                     !argumentList.CloseParenToken.IsMissing &&
                     argumentList.OpenParenToken.TrailingTrivia.IsWhitespaceOrEndOfLine() &&
                     argumentList.CloseParenToken.LeadingTrivia.IsWhitespaceOrEndOfLine())
            {
                context.ReportDiagnostic(
                    DiagnosticDescriptors.RemoveEmptyArgumentList,
                    argumentList.GetLocation());
            }
        }
        public static void Analyze(SyntaxNodeAnalysisContext context, ObjectCreationExpressionSyntax objectCreationExpression)
        {
            if (objectCreationExpression.Type?.IsMissing == false &&
                objectCreationExpression.Initializer?.IsMissing == false)
            {
                ArgumentListSyntax argumentList = objectCreationExpression.ArgumentList;

                if (argumentList?.Arguments.Any() == false)
                {
                    SyntaxToken openParen  = argumentList.OpenParenToken;
                    SyntaxToken closeParen = argumentList.CloseParenToken;

                    if (!openParen.IsMissing &&
                        !closeParen.IsMissing &&
                        openParen.TrailingTrivia.All(f => f.IsWhitespaceOrEndOfLineTrivia()) &&
                        closeParen.LeadingTrivia.All(f => f.IsWhitespaceOrEndOfLineTrivia()))
                    {
                        context.ReportDiagnostic(DiagnosticDescriptors.RemoveEmptyArgumentList, argumentList.GetLocation());
                    }
                }
            }
        }
Example #3
0
        private void VerifyMockAttempt(SyntaxNodeAnalysisContext context, ITypeSymbol mockedClass, ArgumentListSyntax argumentList, bool canHaveMockBehavior)
        {
            if (mockedClass is IErrorTypeSymbol)
            {
                return;
            }

            ImmutableArray <ArgumentSyntax> arguments = ImmutableArray <ArgumentSyntax> .Empty;

            if (argumentList != null && argumentList.Arguments != null)
            {
                arguments = argumentList.Arguments.ToImmutableArray();
            }

            if (canHaveMockBehavior && arguments.Length > 0 && argumentList.Arguments[0].Expression is MemberAccessExpressionSyntax memberAccessExpressionSyntax)
            {
                if (memberAccessExpressionSyntax.Expression is IdentifierNameSyntax identifier && identifier.Identifier.Text == "MockBehavior")
                {
                    //they passed a mock behavior as the first argument.  ignore this one, mock swallows it.
                    arguments = arguments.RemoveAt(0);
                }
            }
            else if (canHaveMockBehavior && arguments.Length > 0 && argumentList.Arguments[0].Expression is IdentifierNameSyntax identifierNameSyntax)
            {
                SymbolInfo symbolInfo = context.SemanticModel.GetSymbolInfo(identifierNameSyntax);

                if (symbolInfo.Symbol == null)
                {
                    return;
                }

                ITypeSymbol typeSymbol = null;
                if (symbolInfo.Symbol is IParameterSymbol parameterSymbol)
                {
                    typeSymbol = parameterSymbol.Type;
                }
                else if (symbolInfo.Symbol is ILocalSymbol localSymbol)
                {
                    typeSymbol = localSymbol.Type;
                }
                else if (symbolInfo.Symbol is IFieldSymbol fieldSymbol)
                {
                    typeSymbol = fieldSymbol.Type;
                }

                if (typeSymbol != null && typeSymbol.Name == "MockBehavior")
                {
                    //they passed a mock behavior as the first argument.  ignore this one, mock swallows it.
                    arguments = arguments.RemoveAt(0);
                }
            }

            switch (mockedClass.TypeKind)
            {
            case TypeKind.Interface:
            case TypeKind.Delegate:
                if (arguments.Length == 0)
                {
                    return;
                }

                if (mockedClass.TypeKind == TypeKind.Delegate)
                {
                    context.ReportDiagnostic(Diagnostic.Create(Rule, argumentList.GetLocation(), argumentList));
                    return;
                }
                break;

            default:
                break;
            }

            IMethodSymbol[] constructors = mockedClass.GetMembers().OfType <IMethodSymbol>().Where(x => x.MethodKind == MethodKind.Constructor && !x.IsStatic).ToArray();

            ImmutableArray <IMethodSymbol> bestFitConstructors = constructors.Where(x => x.Parameters.Length == arguments.Length).ToImmutableArray();

            if (bestFitConstructors.IsEmpty)
            {
                Location location;
                if (argumentList != null)
                {
                    location = argumentList.GetLocation();
                }
                else
                {
                    location = context.Node.GetLocation();
                }

                context.ReportDiagnostic(Diagnostic.Create(Rule, location, argumentList));
                return;
            }

            foreach (IMethodSymbol constructor in bestFitConstructors)
            {
                bool didFindAll = true;

                for (int i = 0; i < arguments.Length; i++)
                {
                    ArgumentSyntax   passedArgument         = arguments[i];
                    IParameterSymbol expectedArgumentSymbol = constructor.Parameters[i];

                    Conversion c;
                    if (passedArgument.Expression is InvocationExpressionSyntax invocationExpressionSyntax)
                    {
                        TypeInfo info = context.SemanticModel.GetTypeInfo(invocationExpressionSyntax);

                        c = context.SemanticModel.Compilation.ClassifyConversion(info.Type, expectedArgumentSymbol.Type);
                    }
                    else
                    {
                        c = context.SemanticModel.ClassifyConversion(passedArgument.Expression, expectedArgumentSymbol.Type);
                    }
                    if (!c.Exists)
                    {
                        didFindAll = false;
                        break;
                    }
                }

                if (didFindAll)
                {
                    return;
                }
            }

            context.ReportDiagnostic(Diagnostic.Create(Rule, argumentList.GetLocation(), argumentList));
        }