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, Eval.GetLoc(nex)); } break; case TupleExpression tex: // x = [('abc', 42, True), ('abc', 23, False)] // for some_str, (some_int, some_bool) in x: var h = new TupleExpressionHandler(Walker); h.HandleTupleAssignment(tex, node.List, value); break; } node.Body?.Walk(Walker); return(false); }
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 TupleExpression lhs) { // Tuple = Tuple. Transfer values. var texHandler = new TupleExpressionHandler(Walker); texHandler.HandleTupleAssignment(lhs, 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); if (scope != null) { scope.Variables[ne.Name].Assign(value, Eval.GetLoc(ne)); } else { // TODO: report variable is not declared in outer scopes. } continue; } if (Eval.CurrentScope.Globals[ne.Name] != null) { Eval.LookupNameInScopes(ne.Name, out var scope, LookupOptions.Global); if (scope != null) { scope.Variables[ne.Name].Assign(value, Eval.GetLoc(ne)); } else { // TODO: report variable is not declared in global scope. } continue; } var source = value.IsGeneric() ? VariableSource.Generic : VariableSource.Declaration; Eval.DeclareVariable(ne.Name, value ?? Module.Interpreter.UnknownType, source, Eval.GetLoc(ne)); } TryHandleClassVariable(node, value); }