public override IRppNode Analyze(SymbolTable scope, Diagnostic diagnostic) { if (TargetType == null) { throw new Exception("TargetType should be specified before anaylyze is called"); } RType classType = TargetType; // TODO It's kinda weird to have resolution here and not in the scope, because similar // lookup is done for methods while (classType != null && Field == null) { Field = classType.Fields.FirstOrDefault(f => f.Name == Name); if (Field != null) { break; } classType = classType.BaseType; } if (Field == null) { var functions = scope.LookupFunction(Name); if (functions.Any(f => f.Parameters.IsEmpty())) { RppFuncCall funcCall = new RppFuncCall(Name, Collections.NoExprs); return funcCall.Analyze(scope, diagnostic); } throw SemanticExceptionFactory.ValueIsNotMember(Token, TargetType.ToString()); } Debug.Assert(classType != null, "obj != null"); Type = new ResolvableType(Field.Type); return this; }
private ResolveResults SearchInFunctions(string name, IEnumerable<IRppExpr> args, SymbolTable scope) { IReadOnlyCollection<RppMethodInfo> overloads = scope.LookupFunction(name); if (overloads.IsEmpty()) { return null; } DefaultTypesComparator typesComparator = new DefaultTypesComparator(_typeArgs); IEnumerable<IRppExpr> argList = args as IList<IRppExpr> ?? args.ToList(); List<RppMethodInfo> candidates = OverloadQuery.Find(argList, _typeArgs, overloads, typesComparator).ToList(); if (candidates.Count == 0 && overloads.Any()) { throw SemanticExceptionFactory.CreateOverloadFailureException(_token, candidates, argList, overloads); } RppMethodInfo candidate = candidates[0]; IEnumerable<RType> inferredTypeArguments = null; if (candidate.GenericParameters != null) { inferredTypeArguments = InferTypes(candidate, argList).ToList(); } return new ResolveResults(candidate, inferredTypeArguments, scope.IsInsideClosure); }