private IPythonType TryDetermineReturnValue() { var annotationType = Eval.GetTypeFromAnnotation(FunctionDefinition.ReturnAnnotation); if (!annotationType.IsUnknown()) { // Annotations are typically types while actually functions return // instances unless specifically annotated to a type such as Type[T]. // TODO: try constructing argument set from types. Consider Tuple[_T1, _T2] where _T1 = TypeVar('_T1', str, bytes) var t = annotationType.CreateInstance(ArgumentSet.Empty(FunctionDefinition.ReturnAnnotation, Eval)); // If instance could not be created, such as when return type is List[T] and // type of T is not yet known, just use the type. var instance = t.IsUnknown() ? (IMember)annotationType : t; _overload.SetReturnValue(instance, true); _overload.SetReturnValue(instance, true); } else { // Check if function is a generator var suite = FunctionDefinition.Body as SuiteStatement; var yieldExpr = suite?.Statements.OfType <ExpressionStatement>().Select(s => s.Expression as YieldExpression).ExcludeDefault().FirstOrDefault(); if (yieldExpr != null) { // Function return is an iterator var yieldValue = Eval.GetValueFromExpression(yieldExpr.Expression) ?? Eval.UnknownType; var returnValue = new PythonGenerator(Eval.Interpreter, yieldValue); _overload.SetReturnValue(returnValue, true); } } return(annotationType); }
private IMember TryDetermineReturnValue() { var returnType = GetReturnValueFromAnnotation(Eval, FunctionDefinition.ReturnAnnotation); if (returnType != null) { _overload.SetReturnValue(returnType, true); return(returnType); } // Check if function is a generator var suite = FunctionDefinition.Body as SuiteStatement; var yieldExpr = suite?.Statements.OfType <ExpressionStatement>().Select(s => s.Expression as YieldExpression).ExcludeDefault().FirstOrDefault(); if (yieldExpr != null) { // Function return is an iterator var yieldValue = Eval.GetValueFromExpression(yieldExpr.Expression) ?? Eval.UnknownType; var returnValue = new PythonGenerator(Eval.Interpreter, yieldValue); _overload.SetReturnValue(returnValue, true); return(returnValue); } return(null); }
public override void Evaluate() { var stub = SymbolTable.ReplacedByStubs.Contains(Target) || _function.DeclaringModule.ModuleType == ModuleType.Stub || Module.ModuleType == ModuleType.Specialized; using (Eval.OpenScope(_function.DeclaringModule, FunctionDefinition, out _)) { // Process annotations. var annotationType = Eval.GetTypeFromAnnotation(FunctionDefinition.ReturnAnnotation); if (!annotationType.IsUnknown()) { // Annotations are typically types while actually functions return // instances unless specifically annotated to a type such as Type[T]. var instance = annotationType.CreateInstance(annotationType.Name, ArgumentSet.Empty); _overload.SetReturnValue(instance, true); } else { // Check if function is a generator var suite = FunctionDefinition.Body as SuiteStatement; var yieldExpr = suite?.Statements.OfType <ExpressionStatement>().Select(s => s.Expression as YieldExpression).ExcludeDefault().FirstOrDefault(); if (yieldExpr != null) { // Function return is an iterator var yieldValue = Eval.GetValueFromExpression(yieldExpr.Expression) ?? Eval.UnknownType; var returnValue = new PythonGenerator(Eval.Interpreter, yieldValue); _overload.SetReturnValue(returnValue, true); } } DeclareParameters(!stub); // Do process body of constructors since they may be declaring // variables that are later used to determine return type of other // methods and properties. var ctor = _function.Name.EqualsOrdinal("__init__") || _function.Name.EqualsOrdinal("__new__"); if (ctor || annotationType.IsUnknown() || Module.ModuleType == ModuleType.User) { // Return type from the annotation is sufficient for libraries and stubs, no need to walk the body. FunctionDefinition.Body?.Walk(this); // For libraries remove declared local function variables to free up some memory. var optionsProvider = Eval.Services.GetService <IAnalysisOptionsProvider>(); if (Module.ModuleType != ModuleType.User && optionsProvider?.Options.KeepLibraryLocalVariables != true) { ((VariableCollection)Eval.CurrentScope.Variables).Clear(); } } } Result = _function; }
private void SpecializeFuture(FromImportStatement node) { if (Interpreter.LanguageVersion.Is3x()) { return; } var printNameExpression = node.Names.FirstOrDefault(n => n?.Name == "print_function"); if (printNameExpression != null) { var fn = new PythonFunctionType("print", new Location(Module), null, string.Empty); var o = new PythonFunctionOverload(fn.Name, new Location(Module)); var parameters = new List <ParameterInfo> { new ParameterInfo("*values", Interpreter.GetBuiltinType(BuiltinTypeId.Object), ParameterKind.List, null), new ParameterInfo("sep", Interpreter.GetBuiltinType(BuiltinTypeId.Str), ParameterKind.KeywordOnly, null), new ParameterInfo("end", Interpreter.GetBuiltinType(BuiltinTypeId.Str), ParameterKind.KeywordOnly, null), new ParameterInfo("file", Interpreter.GetBuiltinType(BuiltinTypeId.Str), ParameterKind.KeywordOnly, null) }; o.SetParameters(parameters); o.SetReturnValue(Interpreter.GetBuiltinType(BuiltinTypeId.NoneType), true); fn.AddOverload(o); Eval.DeclareVariable("print", fn, VariableSource.Import, printNameExpression); } }
public override async Task EvaluateAsync(CancellationToken cancellationToken = default) { if (SymbolTable.ReplacedByStubs.Contains(Target)) { return; } cancellationToken.ThrowIfCancellationRequested(); // Process annotations. var annotationType = await Eval.GetTypeFromAnnotationAsync(FunctionDefinition.ReturnAnnotation, cancellationToken); if (!annotationType.IsUnknown()) { // Annotations are typically types while actually functions return // instances unless specifically annotated to a type such as Type[T]. var instance = annotationType.CreateInstance(annotationType.Name, Eval.GetLoc(FunctionDefinition), ArgumentSet.Empty); _overload.SetReturnValue(instance, true); } else { // Check if function is a generator var suite = FunctionDefinition.Body as SuiteStatement; var yieldExpr = suite?.Statements.OfType <ExpressionStatement>().Select(s => s.Expression as YieldExpression).ExcludeDefault().FirstOrDefault(); if (yieldExpr != null) { // Function return is an iterator var yieldValue = await Eval.GetValueFromExpressionAsync(yieldExpr.Expression, cancellationToken) ?? Eval.UnknownType; var returnValue = new PythonGenerator(Eval.Interpreter, yieldValue); _overload.SetReturnValue(returnValue, true); } } using (Eval.OpenScope(FunctionDefinition, out _)) { await DeclareParametersAsync(cancellationToken); if (annotationType.IsUnknown() || Module.ModuleType == ModuleType.User) { // Return type from the annotation is sufficient for libraries // and stubs, no need to walk the body. if (FunctionDefinition.Body != null && Module.ModuleType != ModuleType.Specialized) { await FunctionDefinition.Body.WalkAsync(this, cancellationToken); } } } }
public override void Populate(ModuleFactory mf, IPythonType declaringType, IGlobalScope gs) { _property.SetDocumentation(Documentation); var o = new PythonFunctionOverload(_property, mf.DefaultLocation); o.SetDocumentation(Documentation); o.SetReturnValue(mf.ConstructMember(ReturnType), true); _property.AddOverload(o); }
private void EnsureContent() { lock (_contentLock) { if (_model != null) { _overload.SetParameters(_model.Parameters.Select(p => ConstructParameter(_mf, p)).ToArray()); _overload.SetReturnValue(_mf.ConstructMember(_model.ReturnType), true); _model = null; _mf = null; } } }
public override void Populate(ModuleFactory mf, IPythonType declaringType, IGlobalScope gs) { // Create inner functions and classes first since function may be returning one of them. var all = Classes.Concat <MemberModel>(Functions).ToArray(); foreach (var model in all) { _function.AddMember(Name, model.Create(mf, _function, gs), overwrite: true); } foreach (var model in all) { model.Populate(mf, _function, gs); } foreach (var om in Overloads) { var o = new PythonFunctionOverload(_function, new Location(mf.Module, IndexSpan.ToSpan())); o.SetDocumentation(Documentation); o.SetReturnValue(mf.ConstructMember(om.ReturnType), true); o.SetParameters(om.Parameters.Select(p => ConstructParameter(mf, p)).ToArray()); _function.AddOverload(o); } }