예제 #1
0
        public static bool Equals(IParameterSymbol x, IParameterSymbol y)
        {
            if (ReferenceEquals(x, y))
            {
                return(true);
            }

            if (x == null ||
                y == null)
            {
                return(false);
            }

            return(x.MetadataName == y.MetadataName &&
                   SymbolComparer.Equals(x.ContainingSymbol, y.ContainingSymbol));
        }
예제 #2
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);
        }
예제 #3
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 ParameterSyntax 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);
        }
예제 #4
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);
        }
예제 #5
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);
        }
예제 #6
0
        internal static bool FirstForSymbol(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))
                    {
                        assignment = candidate;
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #7
0
        private void HandleAssignedValue(SyntaxNode assignee, ExpressionSyntax value)
        {
            if (value == null)
            {
                return;
            }

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

            if (assignedSymbol == null)
            {
                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 property = assignedSymbol as IPropertySymbol;

            if (!SymbolComparer.Equals(this.CurrentSymbol, property) &&
                (this.CurrentSymbol is IFieldSymbol || this.CurrentSymbol is IPropertySymbol) &&
                property != null &&
                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.TryGetSetAccessorDeclaration(out AccessorDeclarationSyntax 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;
                    }
                }
            }
            else
            {
                if (SymbolComparer.Equals(this.CurrentSymbol, assignedSymbol) ||
                    this.refParameters.Contains(assignedSymbol as IParameterSymbol))
                {
                    this.values.Add(value);
                }
            }
        }