示例#1
0
        public override object VisitInvocationExpression(InvocationExpression invocationExpression, object data)
        {
            var previousInvocaton = InvokedSystemTypes.FirstOrDefault(a => a.OriginalExpression.Target.ToString() == invocationExpression.Target.ToString());

            if (previousInvocaton != null)
            {
                previousInvocaton.Variations.Add(invocationExpression);
                return(base.VisitInvocationExpression(invocationExpression, data));
            }

            var targetMember = invocationExpression.Target as MemberReferenceExpression;

            if (targetMember == null)
            {
                return(base.VisitInvocationExpression(invocationExpression, data));
            }

            var targetMemberName = targetMember.Target.ToString();

            //Special cases
            if (targetMember.Target is TypeReferenceExpression)
            {
                Type t;
                switch (targetMemberName)
                {
                case "string":
                    t = typeof(string);
                    break;

                case "int":
                    t = typeof(int);
                    break;

                case "long":
                    t = typeof(long);
                    break;

                case "double":
                    t = typeof(double);
                    break;

                default:
                    t = null;
                    break;
                }

                if (t != null)
                {
                    InvokedSystemTypes.Add(new SystemTypeInvocaton()
                    {
                        MethodName         = targetMember.MemberName,
                        OriginalExpression = invocationExpression,
                        SystemType         = typeof(string)
                    });

                    return(base.VisitInvocationExpression(invocationExpression, data));
                }
            }

            Type systemType;

            //1st strategy - just try directly. This will work if the type is fully named (like System.Console or System.Threading.Thread)
            if (TryGetType(targetMemberName, out systemType))
            {
                InvokedSystemTypes.Add(new SystemTypeInvocaton()
                {
                    MethodName         = targetMember.MemberName,
                    OriginalExpression = invocationExpression,
                    SystemType         = systemType
                });
                return(base.VisitInvocationExpression(invocationExpression, data));
            }

            //2nd strategy. Append all usings to the invoked thing.
            foreach (var ns in invocationExpression.GetUsings())
            {
                if (TryGetType(ns + "." + targetMemberName, out systemType))
                {
                    InvokedSystemTypes.Add(new SystemTypeInvocaton()
                    {
                        MethodName         = targetMember.MemberName,
                        OriginalExpression = invocationExpression,
                        SystemType         = systemType
                    });

                    return(base.VisitInvocationExpression(invocationExpression, data));
                }
            }

            //3rd strategy. The expensive one: attempt to find an identifiers type from the scope.
            var current = targetMember.Target.Parent;

            while (current != null)
            {
                var variableDeclarations = current.Descendants.OfType <VariableDeclarationStatement>();
                if (variableDeclarations.Any())
                {
                    foreach (var variableDeclaration in variableDeclarations)
                    {
                        foreach (var variable in variableDeclaration.Variables)
                        {
                            var objectCreation = variable.Initializer as ObjectCreateExpression;
                            if (objectCreation != null)
                            {
                                foreach (var ns in invocationExpression.GetUsings())
                                {
                                    var typeName = objectCreation.Type.ToString();
                                    if (TryGetType(ns + "." + typeName, out systemType))
                                    {
                                        InvokedSystemTypes.Add(new SystemTypeInvocaton()
                                        {
                                            MethodName         = targetMember.MemberName,
                                            OriginalExpression = invocationExpression,
                                            SystemType         = systemType
                                        });

                                        return(base.VisitInvocationExpression(invocationExpression, data));
                                    }
                                }
                            }
                        }
                    }
                }

                current = current.Parent;
            }

            return(base.VisitInvocationExpression(invocationExpression, data));
        }