示例#1
0
        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);
        }
示例#3
0
        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;
        }
示例#4
0
        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);
            }
        }
示例#5
0
        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);
                    }
                }
            }
        }
示例#6
0
        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);
        }
示例#7
0
 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;
         }
     }
 }
示例#8
0
        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);
            }
        }