Exemplo n.º 1
0
        public override object VisitIdentifierExpression(IdentifierExpression identifierExpression, object data)
        {
            if (identifierExpression.TypeArguments != null && identifierExpression.TypeArguments.Count > 0)
            {
                if (resolver.CallingType != null)
                {
                    foreach (var type in resolver.Dom.GetInheritanceTree(resolver.CallingType))
                    {
                        IMethod possibleMethod = type.Methods.Where(m => m.Name == identifierExpression.Identifier && m.TypeParameters.Count == identifierExpression.TypeArguments.Count && m.IsAccessibleFrom(resolver.Dom, resolver.CallingType, resolver.CallingMember, true)).FirstOrDefault();
                        if (possibleMethod != null)
                        {
                            MethodResolveResult methodResolveResult = new MethodResolveResult(possibleMethod);
                            methodResolveResult.CallingType   = resolver.CallingType;
                            methodResolveResult.CallingMember = resolver.CallingMember;

                            identifierExpression.TypeArguments.ForEach(arg => methodResolveResult.AddGenericArgument(resolver.ResolveType(arg.ConvertToReturnType())));
                            methodResolveResult.ResolveExtensionMethods();
                            return(methodResolveResult);
                        }
                    }
                }
                TypeReference reference = new TypeReference(identifierExpression.Identifier);
                reference.GenericTypes.AddRange(identifierExpression.TypeArguments);
                ResolveResult result = CreateResult(reference);
                result.StaticResolve = true;
                return(result);
            }
//			Console.WriteLine ("visit id: " + identifierExpression.Identifier);
            var res = resolver.ResolveIdentifier(this, identifierExpression.Identifier.TrimEnd('.'));

//			Console.WriteLine ("result: " + res);
            return(res);
        }
Exemplo n.º 2
0
        public override object VisitInvocationExpression(InvocationExpression invocationExpression, object data)
        {
            if (invocationExpression == null)
            {
                return(null);
            }

            if (invocationDictionary.ContainsKey(invocationExpression))
            {
                return(invocationDictionary[invocationExpression]);
            }

            // add support for undocumented __makeref and __reftype keywords
            if (invocationExpression.TargetObject is IdentifierExpression)
            {
                IdentifierExpression idExpr = invocationExpression.TargetObject as IdentifierExpression;
                if (idExpr.Identifier == "__makeref")
                {
                    return(CreateResult("System.TypedReference"));
                }
                if (idExpr.Identifier == "__reftype")
                {
                    return(CreateResult("System.Type"));
                }
            }

            ResolveResult targetResult = Resolve(invocationExpression.TargetObject);

            if (targetResult is CombinedMethodResolveResult)
            {
                targetResult = ((CombinedMethodResolveResult)targetResult).MethodResolveResult;
            }

            targetResult.StaticResolve = false;             // invocation result is never static
            if (this.resolver.CallingType != null)
            {
                if (targetResult is ThisResolveResult)
                {
                    targetResult = new MethodResolveResult(this.resolver.CallingType.Methods.Where(method => method.IsConstructor));
                    ((MethodResolveResult)targetResult).Type = this.resolver.CallingType;
                    targetResult.CallingType   = resolver.CallingType;
                    targetResult.CallingMember = resolver.CallingMember;
                }
                else if (targetResult is BaseResolveResult)
                {
                    System.Collections.IEnumerable baseConstructors = null;
                    IType firstBaseType = null;
                    foreach (IReturnType bT in this.resolver.CallingType.BaseTypes)
                    {
                        IType resolvedBaseType = resolver.SearchType(bT);
                        if (firstBaseType == null && resolvedBaseType.ClassType != MonoDevelop.Projects.Dom.ClassType.Interface)
                        {
                            firstBaseType = resolvedBaseType;
                        }
                        foreach (IType baseType in resolver.Dom.GetInheritanceTree(resolvedBaseType))
                        {
                            if (baseType.ClassType == MonoDevelop.Projects.Dom.ClassType.Interface)
                            {
                                break;
                            }
                            baseConstructors = baseType.Methods.Where(method => method.IsConstructor);
                            goto bailOut;
                        }
                    }
bailOut:
                    if (baseConstructors == null)
                    {
                        if (firstBaseType != null)
                        {
                            // if there is a real base type without a .ctor a default .ctor for this type is generated.
                            DomMethod constructedConstructor;
                            constructedConstructor                = new DomMethod();
                            constructedConstructor.Name           = ".ctor";
                            constructedConstructor.MethodModifier = MethodModifier.IsConstructor;
                            constructedConstructor.DeclaringType  = firstBaseType;
                            constructedConstructor.Modifiers      = MonoDevelop.Projects.Dom.Modifiers.Public;
                            baseConstructors = new IMethod[] {
                                constructedConstructor
                            };
                        }
                        else
                        {
                            baseConstructors = resolver.SearchType(DomReturnType.Object).SearchMember(".ctor", true);
                        }
                    }
                    targetResult = new MethodResolveResult(baseConstructors);
                    ((MethodResolveResult)targetResult).Type = this.resolver.CallingType;
                    targetResult.CallingType   = resolver.CallingType;
                    targetResult.CallingMember = resolver.CallingMember;
                }
            }

            MethodResolveResult methodResult = targetResult as MethodResolveResult;

            if (methodResult != null)
            {
                methodResult.GetsInvoked = true;
//				Console.WriteLine ("--------------------");
//				Console.WriteLine ("i:" + methodResult.ResolvedType);

/*				foreach (var arg in methodResult.GenericArguments) {
 *                                      methodResult.AddGenericArgument (arg);
 *                              }*/
                foreach (Expression arg in invocationExpression.Arguments)
                {
                    var type = GetTypeSafe(arg);
                    methodResult.AddArgument(type);
                }
                //Console.WriteLine ("--------------------");
                methodResult.ResolveExtensionMethods();
//				Console.WriteLine ("i2:" + methodResult.ResolvedType);

                /*	MemberReferenceExpression mre = invocationExpression.TargetObject as MemberReferenceExpression;
                 *      if (mre != null) {
                 *              foreach (TypeReference typeReference in mre.TypeArguments) {
                 *                      methodResult.AddGenericArgument (new DomReturnType (String.IsNullOrEmpty (typeReference.SystemType) ? typeReference.Type : typeReference.SystemType));
                 *              }
                 *      }*/
//				return CreateResult (methodResult.Methods [0].ReturnType);
            }
            invocationDictionary[invocationExpression] = targetResult;
            return(targetResult);
        }
            internal ResolveResult ResolveLambda(ResolveVisitor visitor, Expression lambdaExpression)
            {
                if (expressions.Contains(lambdaExpression))
                {
                    return(null);
                }
                expressions.Add(lambdaExpression);
                if (lambdaExpression.Parent is LambdaExpression)
                {
                    return(ResolveLambda(visitor, lambdaExpression.Parent as Expression));
                }
                if (lambdaExpression.Parent is ParenthesizedExpression)
                {
                    return(ResolveLambda(visitor, lambdaExpression.Parent as Expression));
                }
                if (lambdaExpression.Parent is AssignmentExpression)
                {
                    return(visitor.Resolve(((AssignmentExpression)lambdaExpression.Parent).Left));
                }
                if (lambdaExpression.Parent is CastExpression)
                {
                    return(visitor.Resolve(((CastExpression)lambdaExpression.Parent)));
                }
                if (lambdaExpression.Parent is VariableDeclaration)
                {
                    VariableDeclaration varDec = (VariableDeclaration)lambdaExpression.Parent;
                    return(resolver.GetFunctionParameterType(resolver.ResolveIdentifier(visitor, varDec.Name)));
                }
                if (lambdaExpression.Parent is InvocationExpression)
                {
                    LambdaExpression lambda           = (LambdaExpression)lambdaExpression;
                    ResolveResult    lambdaReturnType = null;
                    if (!lambda.ExpressionBody.IsNull)
                    {
                        DomLocation old = resolver.resolvePosition;
                        try {
                            resolver.resolvePosition = new DomLocation((resolver.CallingMember != null ? resolver.CallingMember.Location.Line : 0) +
                                                                       lambda.ExpressionBody.StartLocation.Line - 2,
                                                                       lambda.ExpressionBody.StartLocation.Column - 1);
                            lambdaReturnType = visitor.Resolve(lambda.ExpressionBody);
                        } finally {
                            resolver.resolvePosition = old;
                        }
                    }

                    InvocationExpression invocation = (InvocationExpression)lambdaExpression.Parent;
                    MethodResolveResult  result     = visitor.Resolve(invocation.TargetObject) as MethodResolveResult;
                    if (result == null)
                    {
                        MonoDevelop.Core.LoggingService.LogWarning("No compatible method found :" + invocation.TargetObject);
                        return(null);
                    }
                    result.ResolveExtensionMethods();

                    for (int i = 0; i < invocation.Arguments.Count; i++)
                    {
                        if (invocation.Arguments[i] == lambdaExpression && i < result.MostLikelyMethod.Parameters.Count)
                        {
                            IParameter  parameter  = result.MostLikelyMethod.Parameters[i];
                            IReturnType returnType = parameter.ReturnType;
                            IType       type       = resolver.Dom.GetType(returnType);

                            bool isResolved = false;
                            if (type != null && type.ClassType == MonoDevelop.Projects.Dom.ClassType.Delegate)
                            {
                                IMethod invocationMethod = type.Methods.First();
                                if (invocationMethod.Parameters.Count > 0)
                                {
                                    if (lambdaReturnType == null || lambdaReturnType.ResolvedType == null || string.IsNullOrEmpty(lambdaReturnType.ResolvedType.FullName))
                                    {
                                        returnType = invocationMethod.Parameters[System.Math.Min(i, invocationMethod.Parameters.Count - 1)].ReturnType;
                                    }
                                    else
                                    {
                                        returnType = (IReturnType) new TypeReplaceVisitor(invocationMethod.ReturnType, lambdaReturnType.ResolvedType).Visit(returnType, null);
                                    }
                                    isResolved = true;
                                }
                            }

                            if (!isResolved)
                            {
                                while (returnType.GenericArguments.Count > 0)
                                {
                                    returnType = returnType.GenericArguments[0];
                                }
                            }
                            string invariantString = returnType.ToInvariantString();
                            if (returnTypeDictionary.ContainsKey(invariantString))
                            {
                                return(returnTypeDictionary[invariantString]);
                            }
                            ResolveResult createdResult = visitor.CreateResult(returnType);
//							if (!(returnType.Type is AnonymousType))
                            returnTypeDictionary[invariantString] = createdResult;
                            return(createdResult);
                        }
                    }

                    if (lambdaReturnType != null && !string.IsNullOrEmpty(lambdaReturnType.ResolvedType.FullName))
                    {
                        return(lambdaReturnType);
                    }

                    foreach (Expression arg in invocation.Arguments)
                    {
                        var argType = arg is LambdaExpression ?  DomReturnType.Void : visitor.GetTypeSafe(arg);
                        result.AddArgument(argType);
                    }

                    result.ResolveExtensionMethods();
                    //Console.WriteLine ("maybe method:" + result.MostLikelyMethod);
                    for (int i = 0; i < invocation.Arguments.Count; i++)
                    {
                        if (invocation.Arguments [i] == lambdaExpression && i < result.MostLikelyMethod.Parameters.Count)
                        {
                            IParameter parameterType = result.MostLikelyMethod.Parameters [i];
                            //Console.WriteLine (i + " par: " + parameterType);
                            if (parameterType.ReturnType.Name == "Func" && parameterType.ReturnType.GenericArguments.Count > 0)
                            {
                                return(visitor.CreateResult(parameterType.ReturnType.GenericArguments[0]));
                            }
                        }
                    }
                    return(result);
                }

                if (lambdaExpression.Parent is ObjectCreateExpression)
                {
                    ObjectCreateExpression objectCreateExpression = (ObjectCreateExpression)lambdaExpression.Parent;
                    int index = objectCreateExpression.Parameters.IndexOf(lambdaExpression);
                    if (index < 0)
                    {
                        return(null);
                    }
                    MemberResolveResult resolvedCreateExpression = visitor.Resolve(objectCreateExpression) as MemberResolveResult;

                    if (resolvedCreateExpression != null)
                    {
                        IMethod method = resolvedCreateExpression.ResolvedMember as IMethod;
                        if (method != null && index < method.Parameters.Count)
                        {
                            return(new ParameterResolveResult(method.Parameters[index]));
                        }
                        else
                        {
                            return(null);
                        }
                    }
                }

                return(null);
            }