public async Task <IMember> GetValueFromPropertyAsync(IPythonPropertyType p, IPythonInstance instance, CancellationToken cancellationToken = default) { // Function may not have been walked yet. Do it now. await SymbolTable.EvaluateAsync(p.FunctionDefinition, cancellationToken); return(instance.Call(p.Name, ArgumentSet.Empty)); }
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)); }
private IMember GetValueFromProperty(IPythonPropertyType p, IPythonInstance instance, CallExpression expr) { // Function may not have been walked yet. Do it now. SymbolTable.Evaluate(p.FunctionDefinition); return(instance.Call(p.Name, ArgumentSet.Empty(expr, this))); }
public IMember GetValueFromFunctionType(IPythonFunctionType fn, IPythonInstance instance, CallExpression expr) { // 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) { SymbolTable.Evaluate(o.FunctionDefinition); } // Pick the best overload. FunctionDefinition fd; ArgumentSet args; var instanceType = instance?.GetPythonType(); if (fn.Overloads.Count == 1) { fd = fn.Overloads[0].FunctionDefinition; args = new ArgumentSet(fn, 0, instanceType, expr, this); args = args.Evaluate(); } else { args = FindOverload(fn, instanceType, expr); if (args == null) { return(UnknownType); } fd = fn.Overloads.Count > 0 ? fn.Overloads[args.OverloadIndex].FunctionDefinition : null; } // 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 (fd != null && EvaluateFunctionBody(fn)) { using (OpenScope(fn.DeclaringModule, fn.FunctionDefinition, out _)) { args.DeclareParametersInScope(this); } } // If instance type 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. // Note that there is nothing to re-evaluate in stubs. if (instanceType == null || fn.DeclaringType == null || fn.IsSpecialized || instanceType.IsSpecialized || fn.DeclaringType.IsSpecialized || instanceType.Equals(fn.DeclaringType) || fn.IsStub || !string.IsNullOrEmpty(fn.Overloads[args.OverloadIndex].GetReturnDocumentation())) { LoadFunctionDependencyModules(fn); var m = instance?.Call(fn.Name, args) ?? fn.Call(null, fn.Name, args); if (!m.IsUnknown()) { return(m); } } // We could not tell the return type from the call. Here we try and evaluate with specific arguments. // Note that it does not make sense evaluating stubs or compiled/scraped modules since they // should be either annotated or static return type known from the analysis. // // Also, we do not evaluate library code with arguments for performance reasons. // This will prevent cases like // def func(a, b): return a + b // from working in libraries, but this is small sacrifice for significant performance // increase in library analysis. if (fn.DeclaringModule is IDocument && EvaluateFunctionBody(fn)) { // Stubs are coming from another module. return(TryEvaluateWithArguments(fn, args)); } return(UnknownType); }
/// <summary> /// Invokes method or property on the specified instance. /// </summary> /// <param name="instance">Instance of the type.</param> /// <param name="memberName">Member name to call, if applicable.</param> /// <param name="argSet">Call arguments.</param> public virtual IMember Call(IPythonInstance instance, string memberName, IArgumentSet argSet) => instance?.Call(memberName, argSet) ?? UnknownType;
public IMember GetValueFromProperty(IPythonPropertyType p, IPythonInstance instance) { // Function may not have been walked yet. Do it now. SymbolTable.Evaluate(p.FunctionDefinition); return(instance.Call(p.Name, ArgumentSet.Empty)); }
public IMember GetValueFromFunctionType(IPythonFunctionType fn, IPythonInstance instance, CallExpression expr) { // 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) { SymbolTable.Evaluate(o.FunctionDefinition); } // Pick the best overload. FunctionDefinition fd; ArgumentSet args; if (fn.Overloads.Count == 1) { fd = fn.Overloads[0].FunctionDefinition; args = new ArgumentSet(fn, 0, instance, expr, this); args = args.Evaluate(); } else { args = FindOverload(fn, instance, expr); if (args == null) { return(UnknownType); } fd = fn.Overloads.Count > 0 ? fn.Overloads[args.OverloadIndex].FunctionDefinition : null; } // 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 (fd != null) { using (OpenScope(fn.DeclaringModule, 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. // Note that there is nothing to re-evaluate in stubs. var instanceType = instance?.GetPythonType(); if (instanceType == null || fn.DeclaringType == null || fn.IsSpecialized || instanceType.IsSpecialized || fn.DeclaringType.IsSpecialized || instanceType.Equals(fn.DeclaringType) || fn.IsStub || !string.IsNullOrEmpty(fn.Overloads[args.OverloadIndex].GetReturnDocumentation(null))) { if (fn.IsSpecialized && fn is PythonFunctionType ft && ft.Dependencies.Count > 0) { var dependencies = ImmutableArray <IPythonModule> .Empty; foreach (var moduleName in ft.Dependencies) { var dependency = Interpreter.ModuleResolution.GetOrLoadModule(moduleName); if (dependency != null) { dependencies = dependencies.Add(dependency); } } Services.GetService <IPythonAnalyzer>().EnqueueDocumentForAnalysis(Module, dependencies); } var t = instance?.Call(fn.Name, args) ?? fn.Call(null, fn.Name, args); if (!t.IsUnknown()) { return(t); } } // Try and evaluate with specific arguments. Note that it does not // make sense to evaluate stubs since they already should be annotated. if (fn.DeclaringModule is IDocument doc && fd?.Ast == doc.GetAnyAst()) { // Stubs are coming from another module. return(TryEvaluateWithArguments(fn.DeclaringModule, fd, args)); } return(UnknownType); }