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); }
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); }