コード例 #1
0
ファイル: CallsWalker.cs プロジェクト: mgnslndh/Gu.Reactive
        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);
        }
コード例 #2
0
        public override void VisitInvocationExpression(InvocationExpressionSyntax node)
        {
            if (this.visitedLocations.Add(node))
            {
                base.VisitInvocationExpression(node);
                var method = this.semanticModel.GetSymbolSafe(node, this.cancellationToken);
                if (this.Context is ElementAccessExpressionSyntax &&
                    SymbolComparer.Equals(this.CurrentSymbol, this.semanticModel.GetSymbolSafe((node.Expression as MemberAccessExpressionSyntax)?.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);
            }
        }
コード例 #3
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);
        }
コード例 #4
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);
        }
コード例 #5
0
ファイル: CallsWalker.cs プロジェクト: mgnslndh/Gu.Reactive
        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);
        }
コード例 #6
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);
        }
コード例 #7
0
 public override void VisitElementAccessExpression(ElementAccessExpressionSyntax node)
 {
     if (node.Parent is AssignmentExpressionSyntax assignment &&
         this.visitedLocations.Add(node) &&
         this.Context is ElementAccessExpressionSyntax &&
         SymbolComparer.Equals(this.CurrentSymbol, this.semanticModel.GetSymbolSafe(node.Expression, this.cancellationToken)))
     {
         this.values.Add(assignment.Right);
         base.VisitElementAccessExpression(node);
     }
 }
コード例 #8
0
            public override SyntaxNode VisitIdentifierName(IdentifierNameSyntax node)
            {
                if (node.Identifier.ValueText == this.from.Name)
                {
                    if (SymbolComparer.Equals(this.semanticModel.GetSymbolSafe(node, this.cancellationToken), this.from))
                    {
                        return(SyntaxFactory.IdentifierName(this.to.Name));
                    }
                }

                return(base.VisitIdentifierName(node));
            }
コード例 #9
0
ファイル: Constructor.cs プロジェクト: mgnslndh/Gu.Reactive
        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));
        }
コード例 #10
0
ファイル: CallsWalker.cs プロジェクト: mgnslndh/Gu.Reactive
        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));
        }
コード例 #11
0
ファイル: Constructor.cs プロジェクト: mgnslndh/Gu.Reactive
        private 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));
        }
コード例 #12
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));
        }
コード例 #13
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);
        }
コード例 #14
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);
        }
コード例 #15
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);
        }
コード例 #16
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);
        }
コード例 #17
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);
                }
            }
        }