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); }
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; } } }
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; } } }
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); }