public async Task <IMember> GetValueFromFunctionTypeAsync(IPythonFunctionType fn, IPythonInstance instance, CallExpression expr, CancellationToken cancellationToken = default) { // Determine argument types var args = new ArgumentSet(fn, instance, expr, this); args = await args.EvaluateAsync(cancellationToken); // If order to be able to find matching overload, we need to know // parameter types and count. This requires function to be analyzed. // Since we don't know which overload we will need, we have to // process all known overloads for the function. foreach (var o in fn.Overloads) { await SymbolTable.EvaluateAsync(o.FunctionDefinition, cancellationToken); } // Re-declare parameters in the function scope since originally // their types might not have been known and now argument set // may contain concrete values. if (fn.FunctionDefinition != null) { using (OpenScope(fn.FunctionDefinition, out _)) { args.DeclareParametersInScope(this); } } // If instance is not the same as the declaring type, then call // most probably comes from the derived class which means that // the original 'self' and 'cls' variables are no longer valid // and function has to be re-evaluated with new arguments. var instanceType = instance?.GetPythonType(); if (instanceType == null || fn.DeclaringType == null || fn.IsSpecialized || instanceType.IsSpecialized || fn.DeclaringType.IsSpecialized || instanceType.Equals(fn.DeclaringType)) { var t = instance?.Call(fn.Name, args) ?? fn.Call(null, fn.Name, args); if (!t.IsUnknown()) { return(t); } } // Try and evaluate with specific arguments but prevent recursion. return(await TryEvaluateVithArgumentsAsync(fn.FunctionDefinition, args, cancellationToken)); }
public async Task <IMember> GetValueFromClassCtorAsync(IPythonClassType cls, CallExpression expr, CancellationToken cancellationToken = default) { await SymbolTable.EvaluateAsync(cls.ClassDefinition, cancellationToken); // Determine argument types var args = ArgumentSet.Empty; var init = cls.GetMember <IPythonFunctionType>(@"__init__"); if (init != null) { var a = new ArgumentSet(init, new PythonInstance(cls), expr, Module, this); if (a.Errors.Count > 0) { AddDiagnostics(a.Errors); } else { args = await a.EvaluateAsync(cancellationToken); } } return(cls.CreateInstance(cls.Name, GetLoc(expr), args)); }