Пример #1
0
        private static void AnalyzeNode(SyntaxNodeAnalysisContext context)
        {
            var invocation = (InvocationExpressionSyntax)context.Node;

            var symbolInfo = context.SemanticModel.GetSymbolInfo(invocation);

            var symbol = symbolInfo.Symbol as IMethodSymbol;

            // Are we an extension method?
            if (symbol?.MethodKind != MethodKind.ReducedExtension)
            {
                return;
            }

            // Are we extending IDbConnection
            if (!(symbol.ReceiverType.Name.EndsWith("IDbConnection")))
            {
                return;
            }

            // Is our first argument a string aka SQL? Is the string a constant value (aka, does it contain anything besides string literals and const references)?
            var isNotConstant = false;
            var sqlLiteral    = SemanticStringHelpers.GetResolvedString(context, invocation.ArgumentList.Arguments.FirstOrDefault()?.Expression, ref isNotConstant);

            if (string.IsNullOrWhiteSpace(sqlLiteral) || isNotConstant)
            {
                return;
            }

            IParseTree tree;
            string     error;

            if (!SqlHelpers.TryParse(sqlLiteral, out tree, out error) || !SqlHelpers.Validate(tree))
            {
                var diagnostic = Diagnostic.Create(Rule, invocation.ArgumentList.Arguments.First().GetLocation(), error);
                context.ReportDiagnostic(diagnostic);
            }
        }
Пример #2
0
        private static void AnalyzeNode(SyntaxNodeAnalysisContext context)
        {
            var invocation = (InvocationExpressionSyntax)context.Node;

            var symbolInfo = context.SemanticModel.GetSymbolInfo(invocation);

            var symbol = symbolInfo.Symbol as IMethodSymbol;

            // Are we an extension method?
            if (symbol?.MethodKind != MethodKind.ReducedExtension)
            {
                return;
            }

            // Are we extending IDbConnection
            if (!(symbol?.ReceiverType.Name.EndsWith("IDbConnection")).GetValueOrDefault())
            {
                return;
            }

            // Is our first argument a string aka SQL? Is the string a constant value (aka, does it contain anything besides string literals and const references)?
            var isNotConstant = false;
            var sqlLiteral    = SemanticStringHelpers.GetResolvedString(context, invocation.ArgumentList.Arguments.FirstOrDefault()?.Expression, ref isNotConstant);

            if (string.IsNullOrWhiteSpace(sqlLiteral))
            {
                return;
            }

            var secondArgument = invocation.ArgumentList.Arguments.Skip(1).FirstOrDefault()?.Expression;

            if (secondArgument == null)
            {
                return;
            }

            IReadOnlyList <string> availableProperties;

            if (secondArgument is AnonymousObjectCreationExpressionSyntax)
            {
                availableProperties = TypeHelpers.GetMembers(secondArgument as AnonymousObjectCreationExpressionSyntax);
            }
            else if (secondArgument is IdentifierNameSyntax)
            {
                availableProperties = TypeHelpers.GetMembers(context.SemanticModel.GetTypeInfo(secondArgument).Type).ToList();
            }
            else
            {
                return;
            }

            bool isValid;
            var  parameters = SqlHelpers.GetSqlParameters(sqlLiteral, out isValid);

            if (!isValid)
            {
                return;
            }

            if (!availableProperties.All(
                    availableProperty => parameters.Contains(availableProperty, StringComparer.CurrentCultureIgnoreCase)))
            {
                var diagnostic = Diagnostic.Create(
                    Rule,
                    secondArgument.GetLocation(),
                    string.Join(
                        ", ",
                        availableProperties.Where(
                            availableProperty =>
                            !parameters.Contains(availableProperty, StringComparer.CurrentCultureIgnoreCase))));

                context.ReportDiagnostic(diagnostic);
            }
        }
Пример #3
0
        private static void AnalyzeNode(SyntaxNodeAnalysisContext context)
        {
            var invocation = (InvocationExpressionSyntax)context.Node;

            var symbolInfo = context.SemanticModel.GetSymbolInfo(invocation);

            var symbol = symbolInfo.Symbol as IMethodSymbol;

            // Are we an extension method?
            if (symbol?.MethodKind != MethodKind.ReducedExtension)
            {
                return;
            }

            // Are we extending IDbConnection
            if (!(symbol?.ReceiverType.Name.EndsWith("IDbConnection")).GetValueOrDefault())
            {
                return;
            }

            // Is our first argument a string aka SQL? Is the string a constant value (aka, does it contain anything besides string literals and const references)?
            var isNotConstant = false;
            var sqlArgument   = invocation.ArgumentList.Arguments.FirstOrDefault();

            if (sqlArgument == null)
            {
                return;
            }

            var sqlLiteral = SemanticStringHelpers.GetResolvedString(context, sqlArgument.Expression, ref isNotConstant);

            if (string.IsNullOrWhiteSpace(sqlLiteral))
            {
                return;
            }

            // Do we have a select statement?
            if (sqlLiteral.IndexOf("select", StringComparison.OrdinalIgnoreCase) < 0)
            {
                return;
            }

            var genericTypeSyntax = ((invocation.Expression as MemberAccessExpressionSyntax)?.Name as GenericNameSyntax)?.TypeArgumentList.Arguments.FirstOrDefault();

            if (genericTypeSyntax == null)
            {
                return;
            }

            var genericTypeInfo     = context.SemanticModel.GetTypeInfo(genericTypeSyntax);
            var genericTypeArgument = genericTypeInfo.ConvertedType;

            if (genericTypeArgument == null)
            {
                return;
            }

            bool isValid;
            var  selectNames = SqlHelpers.GetSqlSelectValues(sqlLiteral, out isValid);

            if (!isValid)
            {
                return;
            }

            // If we're expecting a scalar type, but returning multiple things, that's wrong.
            if (TypeHelpers.IsPrimitiveType(genericTypeArgument) || TypeHelpers.IsString(genericTypeArgument))
            {
                if (selectNames.Count == 1)
                {
                    return;
                }

                var diagnostic = Diagnostic.Create(
                    ScalarRule,
                    sqlArgument.GetLocation(),
                    selectNames.Count);
                context.ReportDiagnostic(diagnostic);
            }
            else
            {
                var availableProperties = TypeHelpers.GetMembers(genericTypeArgument);

                if (selectNames.Any(
                        name => !availableProperties.Contains(name, StringComparer.CurrentCultureIgnoreCase)))
                {
                    var diagnostic = Diagnostic.Create(
                        PropertiesRule,
                        sqlArgument.GetLocation(),
                        string.Join(", ", selectNames.Where(name => !availableProperties.Contains(name, StringComparer.CurrentCultureIgnoreCase))),
                        genericTypeArgument.Name);
                    context.ReportDiagnostic(diagnostic);
                }
            }
        }