protected override CrawlSyntaxNode VisitCall(CallNode call) { CallNode expr = (CallNode)base.VisitCall(call); CrawlType resultType = CrawlType.ErrorType; List <CrawlType> actualParameters = expr.Arguments.Select(x => x.Value.ResultType).ToList(); //Three posibilities exist: //Method type is provided as method name in specific scope. MemberAccessNode asMem = expr.Target as MemberAccessNode; //Method type is provided as a method name. Find candidates and choose best fit. VariableNode asVar = expr.Target as VariableNode; if (expr.Target.ResultType is CrawlStatusType) { return(expr.WithResultType(expr.Target.ResultType)); } else if (asVar != null) { var foo = asVar .FindFirstScope(); var bar = foo .FindSymbol(asVar.Name); List <CrawlMethodType> candidates = bar .SelectMany(GetMethodTypesFromTypeInformation) .ToList(); resultType = BestParameterMatch(candidates, actualParameters); } else if (asMem != null) { List <CrawlMethodType> candidates = asMem .Target.ResultType .FindSymbol(asMem.Member.Value) .SelectMany(GetMethodTypesFromTypeInformation) .ToList(); resultType = BestParameterMatch(candidates, actualParameters); } //Method type is provided by some other expression. In this case it either matches or does not. else { CrawlMethodType methodSignature = expr.Target.ResultType as CrawlMethodType; if (methodSignature != null) { resultType = Call(methodSignature, actualParameters); } } return(expr.WithResultType(resultType)); }