Exemplo n.º 1
0
        internal static AnalysisResult InvokesPropertyChangedFor(this SyntaxNode assignment, IPropertySymbol property, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            var invokes = AnalysisResult.No;
            var block   = assignment.FirstAncestorOrSelf <MethodDeclarationSyntax>()?.Body ??
                          assignment.FirstAncestorOrSelf <AccessorDeclarationSyntax>()?.Body ??
                          assignment.FirstAncestorOrSelf <AnonymousFunctionExpressionSyntax>()?.Body;

            if (block == null)
            {
                return(AnalysisResult.No);
            }

            using (var pooled = InvocationWalker.Create(block))
            {
                foreach (var invocation in pooled.Item.Invocations)
                {
                    if (invocation.SpanStart < assignment.SpanStart)
                    {
                        continue;
                    }

                    switch (TryGetInvokedPropertyChangedName(invocation, semanticModel, cancellationToken, out ArgumentSyntax _, out string propertyName))
                    {
Exemplo n.º 2
0
        internal static bool TryGetInvoker(ITypeSymbol type, SemanticModel semanticModel, CancellationToken cancellationToken, out IMethodSymbol invoker)
        {
            invoker = null;

            foreach (var member in type.GetMembers())
            {
                var method = member as IMethodSymbol;

                if (method?.Parameters.Length != 1)
                {
                    continue;
                }

                var parameter = method.Parameters[0];

                if (method.DeclaringSyntaxReferences.Length == 0)
                {
                    if (parameter.Type == KnownSymbol.String &&
                        method.Name.Contains("PropertyChnaged"))
                    {
                        // A bit speculative here
                        // for handling the case when inheriting a ViewModelBase class from a binary reference.
                        invoker = method;
                    }

                    continue;
                }

                foreach (var declaration in method.Declarations(cancellationToken))
                {
                    using (var pooled = InvocationWalker.Create(declaration))
                    {
                        foreach (var invocation in pooled.Item.Invocations)
                        {
                            var invokedMethod = semanticModel.GetSymbolSafe(invocation, cancellationToken) as IMethodSymbol;
                            if (invokedMethod == null)
                            {
                                continue;
                            }

                            if (invokedMethod == KnownSymbol.PropertyChangedEventHandler.Invoke)
                            {
                                ArgumentSyntax argument;
                                if (invocation.ArgumentList.Arguments.TryGetAtIndex(1, out argument))
                                {
                                    var identifier = argument.Expression as IdentifierNameSyntax;
                                    if (identifier?.Identifier.ValueText == parameter.Name)
                                    {
                                        invoker = method;
                                        return(true);
                                    }

                                    var objectCreation = argument.Expression as ObjectCreationExpressionSyntax;
                                    if (objectCreation != null)
                                    {
                                        var nameArgument = objectCreation.ArgumentList.Arguments[0];
                                        if ((nameArgument.Expression as IdentifierNameSyntax)?.Identifier.ValueText == parameter.Name)
                                        {
                                            invoker = method;
                                            return(true);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(invoker != null);
        }
Exemplo n.º 3
0
        internal static InvokesPropertyChanged InvokesPropertyChangedFor(this AssignmentExpressionSyntax assignment, IPropertySymbol property, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            var invokes = InvokesPropertyChanged.No;
            var block   = assignment.FirstAncestorOrSelf <BlockSyntax>();

            if (block == null)
            {
                return(InvokesPropertyChanged.No);
            }

            using (var pooled = InvocationWalker.Create(block))
            {
                foreach (var invocation in pooled.Item.Invocations)
                {
                    if (invocation.SpanStart < assignment.SpanStart)
                    {
                        continue;
                    }

                    var method = semanticModel.GetSymbolSafe(invocation, cancellationToken) as IMethodSymbol;
                    if (method == null)
                    {
                        continue;
                    }

                    if (method == KnownSymbol.PropertyChangedEventHandler.Invoke)
                    {
                        ArgumentSyntax argument;
                        if (invocation.ArgumentList.Arguments.TryGetAtIndex(1, out argument))
                        {
                            if (argument.Expression.IsCreatePropertyChangedEventArgsFor(property, semanticModel, cancellationToken))
                            {
                                return(InvokesPropertyChanged.Yes);
                            }

                            var cached = semanticModel.GetSymbolSafe(argument.Expression, cancellationToken);
                            if (cached is IFieldSymbol)
                            {
                                foreach (var syntaxReference in cached.DeclaringSyntaxReferences)
                                {
                                    var declarator = syntaxReference.GetSyntax(cancellationToken) as VariableDeclaratorSyntax;
                                    if (declarator?.Initializer?.Value?.IsCreatePropertyChangedEventArgsFor(property, semanticModel, cancellationToken) == true)
                                    {
                                        return(InvokesPropertyChanged.Yes);
                                    }
                                }
                            }

                            continue;
                        }
                    }

                    switch (method.InvokesPropertyChangedFor(property, invocation, semanticModel, cancellationToken))
                    {
                    case InvokesPropertyChanged.No:
                        break;

                    case InvokesPropertyChanged.Yes:
                        return(InvokesPropertyChanged.Yes);

                    case InvokesPropertyChanged.Maybe:
                        if (invokes == InvokesPropertyChanged.No)
                        {
                            invokes = InvokesPropertyChanged.Maybe;
                        }

                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
            }

            return(invokes);
        }