private static bool?EnumeratorTypeMatchesTheVariableType(SyntaxNodeAnalysisContext context, ForEachStatementSyntax forEachStatement)
        {
            var enumerableType = context.SemanticModel.GetTypeInfoSafe(forEachStatement.Expression, context.CancellationToken);

            if (enumerableType.Type == KnownSymbol.IEnumerable &&
                enumerableType.ConvertedType == KnownSymbol.IEnumerable)
            {
                return(true);
            }

            if (enumerableType.Type.Is(KnownSymbol.IEnumerable))
            {
                if (enumerableType.ConvertedType is INamedTypeSymbol namedType &&
                    namedType.TypeArguments.TrySingle(out var enumerableTypeArg))
                {
                    var variableType = context.SemanticModel.GetTypeInfoSafe(forEachStatement.Type, context.CancellationToken).Type;
                    return(SymbolComparer.Equals(variableType, enumerableTypeArg));
                }

                return(enumerableType.ConvertedType != KnownSymbol.IEnumerable);
            }

            if (enumerableType.ConvertedType.TryFirstMethod("GetEnumerator", out var method) &&
                method.ReturnType is INamedTypeSymbol returnType &&
                returnType.TypeArguments.TrySingle(out var enumeratorTypeArg))
            {
                var variableType = context.SemanticModel.GetTypeInfoSafe(forEachStatement.Type, context.CancellationToken).Type;
                return(SymbolComparer.Equals(variableType, enumeratorTypeArg));
            }

            return(null);
        }
Exemplo n.º 2
0
        internal static bool FirstWith(ISymbol symbol, SyntaxNode scope, Search search, SemanticModel semanticModel, CancellationToken cancellationToken, out AssignmentExpressionSyntax assignment)
        {
            assignment = null;
            if (symbol == null ||
                scope == null)
            {
                return(false);
            }

            using (var pooledAssignments = Create(scope, search, semanticModel, cancellationToken))
            {
                foreach (var candidate in pooledAssignments.Item.Assignments)
                {
                    var assignedSymbol = semanticModel.GetSymbolSafe(candidate.Right, cancellationToken);
                    if (SymbolComparer.Equals(symbol, assignedSymbol))
                    {
                        assignment = candidate;
                        return(true);
                    }

                    if (candidate.Right is ObjectCreationExpressionSyntax objectCreation &&
                        objectCreation.ArgumentList != null &&
                        objectCreation.ArgumentList.Arguments.TryGetFirst(x => SymbolComparer.Equals(symbol, semanticModel.GetSymbolSafe(x.Expression, cancellationToken)), out ArgumentSyntax _))
                    {
                        assignment = candidate;
                        return(true);
                    }
                }
            }

            return(false);
        }
Exemplo n.º 3
0
        internal static bool SingleForSymbol(ISymbol symbol, SyntaxNode scope, Search search, SemanticModel semanticModel, CancellationToken cancellationToken, out AssignmentExpressionSyntax assignment)
        {
            assignment = null;
            if (symbol == null ||
                scope == null)
            {
                return(false);
            }

            using (var pooledAssignments = Create(scope, search, semanticModel, cancellationToken))
            {
                foreach (var candidate in pooledAssignments.Item.Assignments)
                {
                    var assignedSymbol = semanticModel.GetSymbolSafe(candidate.Left, cancellationToken);
                    if (SymbolComparer.Equals(symbol, assignedSymbol))
                    {
                        if (assignment != null)
                        {
                            assignment = null;
                            return(false);
                        }

                        assignment = candidate;
                    }
                }
            }

            return(assignment != null);
        }
Exemplo n.º 4
0
        public override void VisitInvocationExpression(InvocationExpressionSyntax node)
        {
            if (this.visitedLocations.Add(node))
            {
                base.VisitInvocationExpression(node);
                var method = this.semanticModel.GetSymbolSafe(node, this.cancellationToken);
                if (method == null)
                {
                    return;
                }

                if (this.context is ElementAccessExpressionSyntax &&
                    node.Expression is MemberAccessExpressionSyntax memberAccess &&
                    SymbolComparer.Equals(this.CurrentSymbol, this.semanticModel.GetSymbolSafe(memberAccess.Expression, this.cancellationToken)))
                {
                    if (method.Name == "Add")
                    {
                        if (method.ContainingType.Is(KnownSymbol.IDictionary) &&
                            node.ArgumentList?.Arguments.Count == 2)
                        {
                            this.values.Add(node.ArgumentList.Arguments[1].Expression);
                        }
                        else if (node.ArgumentList?.Arguments.Count == 1)
                        {
                            this.values.Add(node.ArgumentList.Arguments[0].Expression);
                        }
                    }
                }

                this.HandleInvoke(method, node.ArgumentList);
            }
        }
Exemplo n.º 5
0
        private static bool IsMatch(ISymbol symbol, ExpressionSyntax expression, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            switch (expression)
            {
            case ConditionalExpressionSyntax conditional:
                return(IsMatch(symbol, conditional.WhenTrue, semanticModel, cancellationToken) ||
                       IsMatch(symbol, conditional.WhenFalse, semanticModel, cancellationToken));

            case BinaryExpressionSyntax binary when binary.IsKind(SyntaxKind.CoalesceExpression):
                return(IsMatch(symbol, binary.Left, semanticModel, cancellationToken) ||
                       IsMatch(symbol, binary.Right, semanticModel, cancellationToken));

            case BinaryExpressionSyntax binary when binary.IsKind(SyntaxKind.AsExpression):
                return(IsMatch(symbol, binary.Left, semanticModel, cancellationToken));

            case CastExpressionSyntax cast:
                return(IsMatch(symbol, cast.Expression, semanticModel, cancellationToken));

            case ObjectCreationExpressionSyntax objectCreation when objectCreation.ArgumentList != null && objectCreation.ArgumentList.Arguments.TryFirst(x => SymbolComparer.Equals(symbol, semanticModel.GetSymbolSafe(x.Expression, cancellationToken)), out ArgumentSyntax _):
                return(true);

            default:
                if (symbol.IsEither <ILocalSymbol, IParameterSymbol>())
                {
                    return(expression is IdentifierNameSyntax identifierName &&
                           identifierName.Identifier.ValueText == symbol.Name &&
                           SymbolComparer.Equals(symbol, semanticModel.GetSymbolSafe(expression, cancellationToken)));
                }

                return(SymbolComparer.Equals(symbol, semanticModel.GetSymbolSafe(expression, cancellationToken)));
            }
        }
Exemplo n.º 6
0
        public override void VisitConstructorInitializer(ConstructorInitializerSyntax node)
        {
            if (this.method.MethodKind == MethodKind.Constructor)
            {
                var calledCtor = this.semanticModel.GetSymbolSafe(node, this.cancellationToken);
                if (this.IsValidCtor(calledCtor))
                {
                    var callingCtor = this.semanticModel.GetDeclaredSymbolSafe(node.Parent, this.cancellationToken) as IMethodSymbol;
                    if (SymbolComparer.Equals(calledCtor.ContainingType, callingCtor?.ContainingType))
                    {
                        this.initializers.Add(node);
                    }
                    else if (this.ctors.Contains(callingCtor))
                    {
                        this.initializers.Add(node);
                    }
                }
            }
            else
            {
                this.initializers.Add(node);
            }

            base.VisitConstructorInitializer(node);
        }
Exemplo n.º 7
0
 public override void VisitElementAccessExpression(ElementAccessExpressionSyntax node)
 {
     if (node.Parent is AssignmentExpressionSyntax assignment &&
         this.context is ElementAccessExpressionSyntax &&
         SymbolComparer.Equals(this.CurrentSymbol, this.semanticModel.GetSymbolSafe(node.Expression, this.cancellationToken)))
     {
         this.values.Add(assignment.Right);
         base.VisitElementAccessExpression(node);
     }
 }
        private static void HandleDisposeMethod(SyntaxNodeAnalysisContext context)
        {
            if (context.IsExcludedFromAnalysis())
            {
                return;
            }

            if (context.ContainingSymbol is IMethodSymbol method &&
                method.IsOverride &&
                method.Name == "Dispose")
            {
                var overridden = method.OverriddenMethod;
                if (overridden == null)
                {
                    return;
                }

                using (var invocations = InvocationWalker.Create(context.Node))
                {
                    foreach (var invocation in invocations.Item)
                    {
                        if (
                            SymbolComparer.Equals(
                                context.SemanticModel.GetSymbolSafe(invocation, context.CancellationToken), overridden))
                        {
                            return;
                        }
                    }
                }

                if (overridden.DeclaringSyntaxReferences.Length == 0)
                {
                    context.ReportDiagnostic(Diagnostic.Create(Descriptor, context.Node.GetLocation()));
                    return;
                }

                using (
                    var disposeWalker = Disposable.DisposeWalker.Create(overridden, context.SemanticModel, context.CancellationToken))
                {
                    foreach (var disposeCall in disposeWalker.Item)
                    {
                        if (Disposable.TryGetDisposedRootMember(disposeCall, context.SemanticModel, context.CancellationToken, out ExpressionSyntax disposed))
                        {
                            var member = context.SemanticModel.GetSymbolSafe(disposed, context.CancellationToken);
                            if (
                                !Disposable.IsMemberDisposed(member, method, context.SemanticModel, context.CancellationToken))
                            {
                                context.ReportDiagnostic(Diagnostic.Create(Descriptor, context.Node.GetLocation()));
                                return;
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 9
0
        public override void VisitInvocationExpression(InvocationExpressionSyntax node)
        {
            var invokedMethod = this.semanticModel.GetSymbolSafe(node, this.cancellationToken) as IMethodSymbol;

            if (SymbolComparer.Equals(this.method, invokedMethod))
            {
                this.invocations.Add(node);
            }

            base.VisitInvocationExpression(node);
        }
Exemplo n.º 10
0
        public override void VisitObjectCreationExpression(ObjectCreationExpressionSyntax node)
        {
            var ctor = this.semanticModel.GetSymbolSafe(node, this.cancellationToken) as IMethodSymbol;

            if (SymbolComparer.Equals(this.type, ctor?.ContainingType))
            {
                this.objectCreations.Add(node);
            }

            base.VisitObjectCreationExpression(node);
        }
Exemplo n.º 11
0
 public override void VisitObjectCreationExpression(ObjectCreationExpressionSyntax node)
 {
     if (node.Type is SimpleNameSyntax typeName &&
         typeName.Identifier.ValueText == this.context.Identifier.ValueText)
     {
         if (this.semanticModel.GetSymbolSafe(node, this.cancellationToken) is IMethodSymbol ctor &&
             SymbolComparer.Equals(this.Type, ctor.ContainingType))
         {
             this.objectCreations.Add(node);
         }
     }
Exemplo n.º 12
0
        internal static bool Creates(this ObjectCreationExpressionSyntax creation, ConstructorDeclarationSyntax ctor, Search search, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            var created    = semanticModel.GetSymbolSafe(creation, cancellationToken) as IMethodSymbol;
            var ctorSymbol = semanticModel.GetDeclaredSymbolSafe(ctor, cancellationToken);

            if (SymbolComparer.Equals(ctorSymbol, created))
            {
                return(true);
            }

            return(search == Search.Recursive &&
                   IsRunBefore(created, ctorSymbol, semanticModel, cancellationToken));
        }
Exemplo n.º 13
0
        internal static bool IsRunBefore(IMethodSymbol first, IMethodSymbol other, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            if (first == null ||
                other == null)
            {
                return(false);
            }

            if (TryGetInitializer(other, cancellationToken, out ConstructorInitializerSyntax initializer))
            {
                if (SymbolComparer.Equals(first.ContainingType, other.ContainingType) &&
                    !initializer.ThisOrBaseKeyword.IsKind(SyntaxKind.ThisKeyword))
                {
                    return(false);
                }

                if (!other.ContainingType.Is(first.ContainingType) &&
                    initializer.ThisOrBaseKeyword.IsKind(SyntaxKind.BaseKeyword))
                {
                    return(false);
                }
            }
            else
            {
                if (SymbolComparer.Equals(first.ContainingType, other.ContainingType) ||
                    !other.ContainingType.Is(first.ContainingType))
                {
                    return(false);
                }
            }

            var next = semanticModel.GetSymbolSafe(initializer, cancellationToken);

            if (SymbolComparer.Equals(first, next))
            {
                return(true);
            }

            if (next == null)
            {
                if (TryGetDefault(other.ContainingType?.BaseType, out next))
                {
                    return(SymbolComparer.Equals(first, next));
                }

                return(false);
            }

            return(IsRunBefore(first, next, semanticModel, cancellationToken));
        }
Exemplo n.º 14
0
        private bool IsValidCtor(IMethodSymbol ctor)
        {
            if (!SymbolComparer.Equals(this.method, ctor))
            {
                return(false);
            }

            if (SymbolComparer.Equals(this.contextType, ctor?.ContainingType))
            {
                return(true);
            }

            return(this.ctors.Contains(ctor));
        }
Exemplo n.º 15
0
        public override void VisitConstructorDeclaration(ConstructorDeclarationSyntax node)
        {
            var ctor = this.semanticModel.GetDeclaredSymbolSafe(node, this.cancellationToken);

            if (SymbolComparer.Equals(this.type, ctor.ContainingType))
            {
                if (ctor.DeclaredAccessibility != Accessibility.Private)
                {
                    this.nonPrivateCtors.Add(node);
                }

                if (ctor.Parameters.Length == 0)
                {
                    this.Default = node;
                }
            }

            base.VisitConstructorDeclaration(node);
        }
Exemplo n.º 16
0
        public override void VisitArgument(ArgumentSyntax node)
        {
            if (this.visitedLocations.Add(node) &&
                (node.RefOrOutKeyword.IsKind(SyntaxKind.RefKeyword) ||
                 node.RefOrOutKeyword.IsKind(SyntaxKind.OutKeyword)))
            {
                var invocation = node.FirstAncestorOrSelf <InvocationExpressionSyntax>();
                var argSymbol  = this.semanticModel.GetSymbolSafe(node.Expression, this.cancellationToken);
                if (invocation != null &&
                    (SymbolComparer.Equals(this.CurrentSymbol, argSymbol) ||
                     this.refParameters.Contains(argSymbol as IParameterSymbol)))
                {
                    var method = this.semanticModel.GetSymbolSafe(invocation, this.cancellationToken);
                    if (method != null &&
                        method.DeclaringSyntaxReferences.Length > 0)
                    {
                        foreach (var reference in method.DeclaringSyntaxReferences)
                        {
                            var methodDeclaration = reference.GetSyntax(this.cancellationToken) as MethodDeclarationSyntax;
                            if (methodDeclaration.TryGetMatchingParameter(node, out var parameterSyntax))
                            {
                                var parameterSymbol = this.semanticModel.GetDeclaredSymbolSafe(parameterSyntax, this.cancellationToken);
                                if (parameterSymbol != null)
                                {
                                    if (node.RefOrOutKeyword.IsKind(SyntaxKind.RefKeyword))
                                    {
                                        this.refParameters.Add(parameterSymbol).IgnoreReturnValue();
                                    }

                                    if (node.RefOrOutKeyword.IsKind(SyntaxKind.OutKeyword))
                                    {
                                        this.values.Add(node.Expression);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            base.VisitArgument(node);
        }
            internal Result IsMemberDisposed(ISymbol member)
            {
                foreach (var invocation in this.invocations)
                {
                    if (TryGetDisposedRootMember(invocation, this.SemanticModel, this.CancellationToken, out ExpressionSyntax disposed) &&
                        SymbolComparer.Equals(member, this.SemanticModel.GetSymbolSafe(disposed, this.CancellationToken)))
                    {
                        return(Result.Yes);
                    }
                }

                foreach (var name in this.identifiers)
                {
                    if (SymbolComparer.Equals(member, this.SemanticModel.GetSymbolSafe(name, this.CancellationToken)))
                    {
                        return(Result.Maybe);
                    }
                }

                return(Result.No);
            }
        internal static bool IsDisposing(InvocationExpressionSyntax invocation, ISymbol member, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            var method = semanticModel.GetSymbolSafe(invocation, cancellationToken) as IMethodSymbol;

            if (method == null ||
                method.Parameters.Length != 0 ||
                method != KnownSymbol.IDisposable.Dispose)
            {
                return(false);
            }

            if (TryGetDisposedRootMember(invocation, semanticModel, cancellationToken, out ExpressionSyntax disposed))
            {
                if (SymbolComparer.Equals(member, semanticModel.GetSymbolSafe(disposed, cancellationToken)))
                {
                    return(true);
                }
            }

            return(false);
        }
Exemplo n.º 19
0
        private bool TryHandleInvocation(InvocationExpressionSyntax invocation)
        {
            if (invocation == null)
            {
                return(false);
            }

            var method = this.semanticModel.GetSymbolSafe(invocation, this.cancellationToken);

            if (method == null ||
                method.DeclaringSyntaxReferences.Length == 0)
            {
                return(true);
            }

            foreach (var reference in method.DeclaringSyntaxReferences)
            {
                base.Visit(reference.GetSyntax(this.cancellationToken));
            }

            for (var i = this.values.Count - 1; i >= 0; i--)
            {
                var symbol = this.semanticModel.GetSymbolSafe(this.values[i], this.cancellationToken);
                if (this.search == Search.Recursive &&
                    SymbolComparer.Equals(symbol, method))
                {
                    this.values.RemoveAt(i);
                    continue;
                }

                if (invocation.TryGetArgumentValue(symbol as IParameterSymbol, this.cancellationToken, out ExpressionSyntax arg))
                {
                    this.values[i] = arg;
                }
            }

            this.values.PurgeDuplicates();
            return(true);
        }
Exemplo n.º 20
0
        private bool TryHandlePropertyGet(ExpressionSyntax propertyGet)
        {
            if (propertyGet == null)
            {
                return(false);
            }

            var property = this.semanticModel.GetSymbolSafe(propertyGet, this.cancellationToken) as IPropertySymbol;
            var getter   = property?.GetMethod;

            if (getter == null)
            {
                return(false);
            }

            if (getter.DeclaringSyntaxReferences.Length == 0)
            {
                return(true);
            }

            foreach (var reference in getter.DeclaringSyntaxReferences)
            {
                base.Visit(reference.GetSyntax(this.cancellationToken));
            }

            for (var i = this.values.Count - 1; i >= 0; i--)
            {
                var symbol = this.semanticModel.GetSymbolSafe(this.values[i], this.cancellationToken);
                if (this.search == Search.Recursive &&
                    SymbolComparer.Equals(symbol, property))
                {
                    this.values.RemoveAt(i);
                }
            }

            this.values.PurgeDuplicates();

            return(true);
        }
Exemplo n.º 21
0
        private void HandleAssignedValue(SyntaxNode assignee, ExpressionSyntax value)
        {
            if (value == null)
            {
                return;
            }

            if (assignee is VariableDeclaratorSyntax declarator &&
                declarator.Identifier.ValueText != this.CurrentSymbol.Name)
            {
                return;
            }

            if (this.CurrentSymbol.IsEither <ILocalSymbol, IParameterSymbol>() &&
                assignee is MemberAccessExpressionSyntax)
            {
                return;
            }

            if (this.context is ElementAccessExpressionSyntax)
            {
                switch (value)
                {
                case ArrayCreationExpressionSyntax arrayCreation:
                {
                    if (arrayCreation.Initializer == null)
                    {
                        return;
                    }

                    foreach (var item in arrayCreation.Initializer.Expressions)
                    {
                        this.values.Add(item);
                    }
                }

                break;

                case ObjectCreationExpressionSyntax objectCreation:
                {
                    if (objectCreation.Initializer == null)
                    {
                        return;
                    }

                    foreach (var item in objectCreation.Initializer.Expressions)
                    {
                        if (item is InitializerExpressionSyntax kvp)
                        {
                            if (kvp.Expressions.Count == 2)
                            {
                                this.values.Add(kvp.Expressions[1]);
                            }
                        }
                        else if (item is AssignmentExpressionSyntax assignment)
                        {
                            this.values.Add(assignment.Right);
                        }
                        else
                        {
                            this.values.Add(item);
                        }
                    }
                }

                break;

                case InitializerExpressionSyntax initializer:
                {
                    foreach (var item in initializer.Expressions)
                    {
                        this.values.Add(item);
                    }
                }

                break;

                default:
                    return;
                }

                return;
            }

            var assignedSymbol = this.semanticModel.GetSymbolSafe(assignee, this.cancellationToken) ??
                                 this.semanticModel.GetDeclaredSymbolSafe(assignee, this.cancellationToken);

            if (assignedSymbol == null)
            {
                return;
            }

            if (this.CurrentSymbol.IsEither <IFieldSymbol, IPropertySymbol>() &&
                assignedSymbol is IPropertySymbol property &&
                !SymbolComparer.Equals(this.CurrentSymbol, property) &&
                Property.AssignsSymbolInSetter(property, this.CurrentSymbol, this.semanticModel, this.cancellationToken))
            {
                var before = this.values.Count;
                foreach (var reference in property.DeclaringSyntaxReferences)
                {
                    var declaration = (PropertyDeclarationSyntax)reference.GetSyntax(this.cancellationToken);
                    if (declaration.TryGetSetter(out var setter))
                    {
                        this.Visit(setter);
                    }
                }

                for (var i = before; i < this.values.Count; i++)
                {
                    var parameter = this.semanticModel.GetSymbolSafe(this.values[i], this.cancellationToken) as IParameterSymbol;
                    if (Equals(parameter?.ContainingSymbol, property.SetMethod))
                    {
                        this.values[i] = value;
                    }
                }
            }
Exemplo n.º 22
0
        private static bool IsReturned(ILocalSymbol symbol, BlockSyntax block, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            using (var pooled = ReturnValueWalker.Create(block, Search.TopLevel, semanticModel, cancellationToken))
            {
                foreach (var value in pooled.Item)
                {
                    var returnedSymbol = semanticModel.GetSymbolSafe(value, cancellationToken);
                    if (SymbolComparer.Equals(symbol, returnedSymbol))
                    {
                        return(true);
                    }

                    if (value is ObjectCreationExpressionSyntax objectCreation)
                    {
                        if (objectCreation.ArgumentList != null)
                        {
                            foreach (var argument in objectCreation.ArgumentList.Arguments)
                            {
                                var arg = semanticModel.GetSymbolSafe(argument.Expression, cancellationToken);
                                if (SymbolComparer.Equals(symbol, arg))
                                {
                                    return(true);
                                }
                            }
                        }

                        if (objectCreation.Initializer != null)
                        {
                            foreach (var argument in objectCreation.Initializer.Expressions)
                            {
                                var arg = semanticModel.GetSymbolSafe(argument, cancellationToken);
                                if (SymbolComparer.Equals(symbol, arg))
                                {
                                    return(true);
                                }
                            }
                        }
                    }

                    if (value is InvocationExpressionSyntax invocation)
                    {
                        if (returnedSymbol == KnownSymbol.RxDisposable.Create &&
                            invocation.ArgumentList != null &&
                            invocation.ArgumentList.Arguments.TryGetSingle(out ArgumentSyntax argument))
                        {
                            var body = (argument.Expression as ParenthesizedLambdaExpressionSyntax)?.Body;
                            using (var pooledInvocations = InvocationWalker.Create(body))
                            {
                                foreach (var candidate in pooledInvocations.Item.Invocations)
                                {
                                    if (Disposable.IsDisposing(candidate, symbol, semanticModel, cancellationToken))
                                    {
                                        return(true);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }
Exemplo n.º 23
0
        internal void HandleInvoke(IMethodSymbol method, ArgumentListSyntax argumentList)
        {
            if (method != null &&
                (method.Parameters.TryFirst(x => x.RefKind != RefKind.None, out _) ||
                 this.CurrentSymbol.ContainingType.Is(method.ContainingType)))
            {
                if (TryGetWalker(out var walker))
                {
                    foreach (var value in walker.values)
                    {
                        this.values.Add(GetArgumentValue(value));
                    }

                    foreach (var outValue in walker.outValues)
                    {
                        this.values.Add(GetArgumentValue(outValue));
                    }
                }
            }

            bool TryGetWalker(out AssignedValueWalker result)
            {
                result = null;
                if (TryGetKey(out var key))
                {
                    if (this.memberWalkers.TryGetValue(key, out result))
                    {
                        return(false);
                    }

                    if (method.TrySingleDeclaration(this.cancellationToken, out var declaration))
                    {
                        result = Borrow(() => new AssignedValueWalker());
                        this.memberWalkers.Add(key, result);
                        result.CurrentSymbol        = this.CurrentSymbol;
                        result.semanticModel        = this.semanticModel;
                        result.cancellationToken    = this.cancellationToken;
                        result.context              = this.context.FirstAncestorOrSelf <ConstructorDeclarationSyntax>() != null ? this.context : declaration;
                        result.memberWalkers.Parent = this.memberWalkers;
                        if (argumentList != null)
                        {
                            foreach (var argument in argumentList.Arguments)
                            {
                                if (argument.RefOrOutKeyword.IsKind(SyntaxKind.RefKeyword) &&
                                    TryGetMatchingParameter(argument, out var parameter))
                                {
                                    result.refParameters.Add(parameter);
                                }
                                else if (argument.RefOrOutKeyword.IsKind(SyntaxKind.OutKeyword) &&
                                         TryGetMatchingParameter(argument, out parameter))
                                {
                                    result.outParameters.Add(parameter);
                                }
                            }
                        }

                        result.Visit(declaration);
                    }
                }

                return(result != null);

                bool TryGetMatchingParameter(ArgumentSyntax argument, out IParameterSymbol parameter)
                {
                    parameter = null;
                    if (this.semanticModel.GetSymbolSafe(argument.Expression, this.cancellationToken) is ISymbol symbol)
                    {
                        if (SymbolComparer.Equals(this.CurrentSymbol, symbol) ||
                            this.refParameters.Contains(symbol as IParameterSymbol) ||
                            this.outParameters.Contains(symbol as IParameterSymbol))
                        {
                            return(method.TryGetMatchingParameter(argument, out parameter));
                        }
                    }

                    return(false);
                }

                bool TryGetKey(out SyntaxNode node)
                {
                    if (argumentList != null)
                    {
                        node = argumentList;
                        return(true);
                    }

                    return(method.TrySingleDeclaration(this.cancellationToken, out node));
                }
            }

            ExpressionSyntax GetArgumentValue(ExpressionSyntax value)
            {
                if (value is IdentifierNameSyntax identifierName &&
                    method.Parameters.TryFirst(x => x.Name == identifierName.Identifier.ValueText, out var parameter))
                {
                    if (argumentList.TryGetMatchingArgument(parameter, out var argument))
                    {
                        return(argument.Expression);
                    }

                    if (parameter.HasExplicitDefaultValue &&
                        parameter.TrySingleDeclaration(this.cancellationToken, out var parameterDeclaration))
                    {
                        return(parameterDeclaration.Default?.Value);
                    }
                }

                return(value);
            }
        }