public bool HandleFor(ForStatement node)
        {
            var iterable = Eval.GetValueFromExpression(node.List);
            var iterator = (iterable as IPythonIterable)?.GetIterator();
            var value    = iterator?.Next ?? Eval.UnknownType;

            switch (node.Left)
            {
            case NameExpression nex:
                // for x in y:
                if (!string.IsNullOrEmpty(nex.Name))
                {
                    Eval.DeclareVariable(nex.Name, value, VariableSource.Declaration, nex);
                }
                break;

            case SequenceExpression seq:
                // x = [('abc', 42, True), ('abc', 23, False)]
                // for some_str, (some_int, some_bool) in x:
                var h = new SequenceExpressionHandler(Walker);
                h.HandleAssignment(seq, value);
                break;
            }

            node.Body?.Walk(Walker);
            node.Else?.Walk(Walker);
            return(false);
        }
Beispiel #2
0
        public void HandleWith(WithStatement node)
        {
            foreach (var item in node.Items.Where(x => x.Variable != null))
            {
                var     contextManager = Eval.GetValueFromExpression(item.ContextManager);
                var     cmType         = contextManager?.GetPythonType();
                IMember context        = Eval.UnknownType;

                var enter = cmType?.GetMember(node.IsAsync ? @"__aenter__" : @"__enter__")?.GetPythonType <IPythonFunctionType>();
                if (enter != null)
                {
                    var instance = contextManager as IPythonInstance;
                    var callExpr = item.ContextManager as CallExpression;
                    context = Eval.GetValueFromFunctionType(enter, instance, callExpr);
                    // If fetching context from __enter__ failed, annotation in the stub may be using
                    // type from typing that we haven't specialized yet or there may be an issue in
                    // the stub itself, such as type or incorrect type. Try using context manager then.
                    context = context.IsUnknown() ? contextManager : context;
                }

                switch (item.Variable)
                {
                case NameExpression nameExpr when !string.IsNullOrEmpty(nameExpr.Name):
                    Eval.DeclareVariable(nameExpr.Name, context, VariableSource.Declaration, item);
                    break;

                case ParenthesisExpression parExpr:
                case SequenceExpression seqExpr:
                    var sequenceHandler = new SequenceExpressionHandler(Walker);
                    SequenceExpressionHandler.Assign(new[] { item.Variable }, context, Eval);
                    break;
                }
            }
        }
Beispiel #3
0
        public void HandleAssignment(AssignmentStatement node)
        {
            if (node.Right is ErrorExpression)
            {
                return;
            }

            var value = Eval.GetValueFromExpression(node.Right) ?? Eval.UnknownType;
            // Filter out parenthesis expression in assignment because it makes no difference.
            var lhs = node.Left.Select(s => s.RemoveParenthesis());
            // Check PEP hint first
            var valueType = Eval.GetTypeFromPepHint(node.Right);

            if (valueType != null)
            {
                HandleTypedVariable(valueType, value, lhs.FirstOrDefault());
                return;
            }

            if (value.IsUnknown())
            {
                Log?.Log(TraceEventType.Verbose, $"Undefined value: {node.Right.ToCodeString(Ast).Trim()}");
            }
            if (value?.GetPythonType().TypeId == BuiltinTypeId.Ellipsis)
            {
                value = Eval.UnknownType;
            }

            foreach (var expr in lhs)
            {
                switch (expr)
                {
                case SequenceExpression seq:
                    // Tuple = Tuple. Transfer values.
                    var seqHandler = new SequenceExpressionHandler(Walker);
                    seqHandler.HandleAssignment(seq, value);
                    break;

                case ExpressionWithAnnotation annExpr:
                    HandleAnnotatedExpression(annExpr, value);
                    break;

                case NameExpression nameExpr:
                    HandleNameExpression(nameExpr, value);
                    break;

                case MemberExpression memberExpr:
                    TryHandleClassVariable(memberExpr, value);
                    break;
                }
            }
        }
Beispiel #4
0
        private void AssignToExpr(Expression expr, IMember value)
        {
            switch (expr)
            {
            case SequenceExpression seq:
                // Tuple = Tuple. Transfer values.
                var seqHandler = new SequenceExpressionHandler(Walker);
                seqHandler.HandleAssignment(seq, value);
                break;

            case ExpressionWithAnnotation annExpr:
                HandleAnnotatedExpression(annExpr, value);
                break;

            case NameExpression nameExpr:
                HandleNameExpression(nameExpr, value);
                break;

            case MemberExpression memberExpr:
                TryHandleClassVariable(memberExpr, value);
                break;
            }
        }
        public void HandleAssignment(AssignmentStatement node)
        {
            if (node.Right is ErrorExpression)
            {
                return;
            }

            var value = Eval.GetValueFromExpression(node.Right) ?? Eval.UnknownType;
            // Check PEP hint first
            var valueType = Eval.GetTypeFromPepHint(node.Right);

            if (valueType != null)
            {
                HandleTypedVariable(valueType, value, node.Left.FirstOrDefault());
                return;
            }

            if (value.IsUnknown())
            {
                Log?.Log(TraceEventType.Verbose, $"Undefined value: {node.Right.ToCodeString(Ast).Trim()}");
            }
            if (value?.GetPythonType().TypeId == BuiltinTypeId.Ellipsis)
            {
                value = Eval.UnknownType;
            }

            if (node.Left.FirstOrDefault() is SequenceExpression seq)
            {
                // Tuple = Tuple. Transfer values.
                var seqHandler = new SequenceExpressionHandler(Walker);
                seqHandler.HandleAssignment(seq.Items, node.Right, value);
                return;
            }

            // Process annotations, if any.
            foreach (var expr in node.Left.OfType <ExpressionWithAnnotation>())
            {
                // x: List[str] = [...]
                HandleAnnotatedExpression(expr, value);
            }

            foreach (var ne in node.Left.OfType <NameExpression>())
            {
                if (Eval.CurrentScope.NonLocals[ne.Name] != null)
                {
                    Eval.LookupNameInScopes(ne.Name, out var scope, LookupOptions.Nonlocal);
                    scope?.Variables[ne.Name].Assign(value, Eval.GetLocationOfName(ne));
                    continue;
                }

                if (Eval.CurrentScope.Globals[ne.Name] != null)
                {
                    Eval.LookupNameInScopes(ne.Name, out var scope, LookupOptions.Global);
                    scope?.Variables[ne.Name].Assign(value, Eval.GetLocationOfName(ne));
                    continue;
                }

                var source   = value.IsGeneric() ? VariableSource.Generic : VariableSource.Declaration;
                var location = Eval.GetLocationOfName(ne);
                if (IsValidAssignment(ne.Name, location))
                {
                    Eval.DeclareVariable(ne.Name, value ?? Module.Interpreter.UnknownType, source, location);
                }
            }

            TryHandleClassVariable(node, value);
        }