Exemple #1
0
        private void HandleVirtualMethod(InvocationExpressionSyntax node, IMethodSymbol method, SyntaxReference declaringSyntaxReference, TypeInfo?targetType)
        {
            TypeInfo?target = node.GetTargetOfInvocation(method, model, this.invokedMethod);

            if (target.HasValue)
            {
                // Find the members of the type on which the current method is being invoked that are defined as an override
                foreach (var member in target?.Type.GetMembers().OfType <IMethodSymbol>().Where(member => member.IsOverride))
                {
                    // Walk the override tree until we find the method being invoked
                    IMethodSymbol overridenMethod = member.OverriddenMethod;
                    while (overridenMethod != null && !overridenMethod.GetComparableSyntax().Equals(declaringSyntaxReference) && overridenMethod.IsOverride)
                    {
                        overridenMethod = overridenMethod.OverriddenMethod;
                    }

                    // Check if the current member is the abstract/virtual method being invoked
                    if (overridenMethod.GetComparableSyntax().Equals(declaringSyntaxReference))
                    {
                        HandleInvocation(node, member, member.GetComparableSyntax(), target);
                        return;
                    }
                }
            }

            StepInto(node, new InvokedMethod(method, this.invokedMethod.TargetType, node.GetArgumentTypes(method, model, this.invokedMethod), declaringSyntaxReference));
        }
Exemple #2
0
        /// <summary>
        /// Called when a method invocation is discovered in source code.
        /// </summary>
        /// <param name="node">An <see cref="InvocationExpressionSyntax"/> describing the method being invoked.</param>
        public override void VisitInvocationExpression(InvocationExpressionSyntax node)
        {
            // We might have nested invocations thus go one level deeper first if necessary
            ExpressionSyntax expression = node.Expression;
            bool             goDeeper   = true;

            do
            {
                switch (expression)
                {
                case MemberAccessExpressionSyntax maes:
                    expression = maes.Expression;
                    break;

                case InvocationExpressionSyntax ies:
                    goDeeper = false;
                    this.VisitInvocationExpression(ies);
                    break;

                default:
                    goDeeper = false;
                    break;
                }
            }while (goDeeper);

            // Determine the kind of invocation
            if (node.Expression.Kind() == SyntaxKind.SimpleMemberAccessExpression ||
                node.Expression.Kind() == SyntaxKind.InvocationExpression ||
                node.Expression.Kind() == SyntaxKind.IdentifierName)
            {
                // Check if the method being invoked is defined in source
                IMethodSymbol methodInvoked = model.GetSymbolInfo(node).Symbol as IMethodSymbol;
                if (methodInvoked == null)
                {
                    // Nothing to see here
                    return;
                }

                SyntaxReference declaringSyntaxReference = methodInvoked.GetComparableSyntax();
                if (declaringSyntaxReference == null)
                {
                    StepOver(node, methodInvoked);
                    return;
                }

                HandleInvocation(node, methodInvoked, declaringSyntaxReference, this.invokedMethod.TargetType);
                return;
            }

            base.VisitInvocationExpression(node);
        }
        private SyntaxNode HandleInterfaceMethod(InvocationExpressionSyntax node, IMethodSymbol method, SyntaxReference declaringSyntaxReference, TypeInfo?targetType)
        {
            TypeInfo?target = node.GetTargetOfInvocation(method, model, this.invokedMethod);

            if (!target.HasValue)
            {
                return(StepOver(node, method));
            }

            IMethodSymbol implementingMethod = target.Value.Type.FindImplementationForInterfaceMember(method) as IMethodSymbol;

            if (implementingMethod != null)
            {
                return(HandleInvocation(node, implementingMethod, implementingMethod.GetComparableSyntax(), target));
            }
            else
            {
                return(StepOver(node, method));
            }
        }