Esempio n. 1
0
        private static bool TryGetCanBeSlim(InvocationExpressionSyntax invocation, SyntaxNodeAnalysisContext context, out SyntaxNode path)
        {
            path = null;
            var argument = invocation.FirstAncestor <ArgumentSyntax>();

            if (argument != null)
            {
                if (argument.TryGetParameter(context.SemanticModel, context.CancellationToken, out var parameter) &&
                    parameter.Type == KnownSymbol.IObservableOfT)
                {
                    if (parameter.Type is INamedTypeSymbol namedType &&
                        namedType.TypeArguments[0] == KnownSymbol.Object)
                    {
                        path = invocation.Expression is MemberAccessExpressionSyntax memberAccess
                            ? (SyntaxNode)memberAccess.Name
                            : invocation;
                        return(true);
                    }
                }
            }

            var parentInvocation = invocation.FirstAncestor <InvocationExpressionSyntax>();

            if (parentInvocation != null)
            {
                var parentMethod = (IMethodSymbol)context.SemanticModel.GetSymbolSafe(parentInvocation, context.CancellationToken);
                if (parentMethod == KnownSymbol.ObservableExtensions.Subscribe &&
                    parentInvocation.ArgumentList?.Arguments.TryGetSingle(out argument) == true)
                {
                    if (argument.Expression is SimpleLambdaExpressionSyntax lambda)
                    {
                        using (var pooled = IdentifierNameWalker.Create(lambda.Body))
                        {
                            if (pooled.Item.IdentifierNames.TryGetFirst(x => x.Identifier.ValueText == lambda.Parameter.Identifier.ValueText, out IdentifierNameSyntax _))
                            {
                                return(false);
                            }

                            path = invocation.Expression is MemberAccessExpressionSyntax memberAccess
                                ? (SyntaxNode)memberAccess.Name
                                : invocation;
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Esempio n. 2
0
        private static void HandleInvocation(SyntaxNodeAnalysisContext context)
        {
            if (context.IsExcludedFromAnalysis())
            {
                return;
            }

            var initializer       = (ConstructorInitializerSyntax)context.Node;
            var semanticModel     = context.SemanticModel;
            var cancellationToken = context.CancellationToken;
            var ctor = semanticModel.GetSymbolSafe(initializer, cancellationToken);

            if (ctor != null &&
                ctor.ContainingType == KnownSymbol.Condition &&
                ctor.Parameters.Length == 2 &&
                initializer.ArgumentList != null &&
                initializer.ArgumentList.Arguments.Count == 2)
            {
                var observableArg = ObservableArg(initializer, ctor);
                var criteriaArg   = CriteriaArg(initializer, ctor);
                using (var observableIdentifiers = IdentifierNameWalker.Create(observableArg, Search.Recursive, semanticModel, cancellationToken))
                {
                    using (var criteriaIdentifiers = IdentifierNameWalker.Create(criteriaArg, Search.Recursive, semanticModel, cancellationToken))
                    {
                        using (var observed = SetPool <IPropertySymbol> .Create())
                        {
                            foreach (var name in observableIdentifiers.Item.IdentifierNames)
                            {
                                if (semanticModel.GetSymbolSafe(name, cancellationToken) is IPropertySymbol property)
                                {
                                    observed.Item.Add(property);
                                }
                            }

                            using (var usedInCriteria = SetPool <IPropertySymbol> .Create())
                            {
                                foreach (var name in criteriaIdentifiers.Item.IdentifierNames)
                                {
                                    if (semanticModel.GetSymbolSafe(name, cancellationToken) is IPropertySymbol property)
                                    {
                                        if (!property.ContainingType.IsValueType &&
                                            !property.IsGetOnly())
                                        {
                                            usedInCriteria.Item.Add(property);
                                        }
                                    }
                                }

                                using (var missing = SetPool <IPropertySymbol> .Create())
                                {
                                    missing.Item.UnionWith(usedInCriteria.Item);
                                    missing.Item.ExceptWith(observed.Item);
                                    if (missing.Item.Count != 0)
                                    {
                                        var observedText       = string.Join(Environment.NewLine, observed.Item.Select(p => $"  {p}"));
                                        var usedInCriteriaText = string.Join(Environment.NewLine, usedInCriteria.Item.Select(p => $"  {p}"));
                                        var missingText        = string.Join(Environment.NewLine, missing.Item.Select(p => $"  {p}"));
                                        context.ReportDiagnostic(Diagnostic.Create(Descriptor, initializer.GetLocation(), observedText, usedInCriteriaText, missingText));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Esempio n. 3
0
        private static void HandleInvocation(SyntaxNodeAnalysisContext context)
        {
            if (context.IsExcludedFromAnalysis())
            {
                return;
            }

            var invocation = (InvocationExpressionSyntax)context.Node;
            var method     = (IMethodSymbol)context.SemanticModel.GetSymbolSafe(invocation, context.CancellationToken);

            if (method != KnownSymbol.NotifyPropertyChangedExt.ObservePropertyChanged)
            {
                return;
            }

            var argument = invocation.FirstAncestor <ArgumentSyntax>();

            if (argument != null)
            {
                if (argument.TryGetParameter(context.SemanticModel, context.CancellationToken, out IParameterSymbol parameter) &&
                    parameter.Type == KnownSymbol.IObservableOfT)
                {
                    if (parameter.Type is INamedTypeSymbol namedType &&
                        namedType.TypeArguments[0] == KnownSymbol.Object)
                    {
                        if (invocation.Expression is MemberAccessExpressionSyntax memberAccess)
                        {
                            context.ReportDiagnostic(Diagnostic.Create(Descriptor, memberAccess.Name.GetLocation()));
                        }
                        else
                        {
                            context.ReportDiagnostic(Diagnostic.Create(Descriptor, invocation.GetLocation()));
                        }
                    }
                }
            }

            var parentInvocation = invocation.FirstAncestor <InvocationExpressionSyntax>();

            if (parentInvocation != null)
            {
                var parentMethod = (IMethodSymbol)context.SemanticModel.GetSymbolSafe(parentInvocation, context.CancellationToken);
                if (parentMethod == KnownSymbol.ObservableExtensions.Subscribe &&
                    parentInvocation.ArgumentList?.Arguments.TryGetSingle(out argument) == true)
                {
                    if (argument.Expression is SimpleLambdaExpressionSyntax lambda)
                    {
                        using (var pooled = IdentifierNameWalker.Create(lambda.Body))
                        {
                            if (pooled.Item.IdentifierNames.TryGetFirst(x => x.Identifier.ValueText == lambda.Parameter.Identifier.ValueText, out IdentifierNameSyntax _))
                            {
                                return;
                            }

                            if (invocation.Expression is MemberAccessExpressionSyntax memberAccess)
                            {
                                context.ReportDiagnostic(Diagnostic.Create(Descriptor, memberAccess.Name.GetLocation()));
                            }
                            else
                            {
                                context.ReportDiagnostic(Diagnostic.Create(Descriptor, invocation.GetLocation()));
                            }
                        }
                    }
                }
            }
        }