/// <summary> /// Provides type factory. Similar to __metaclass__ but does not expose full /// metaclass functionality. Used in cases when function has to return a class /// rather than the class instance. Example: function annotated as '-> Type[T]' /// can be called as a T constructor so func() constructs class instance rather than invoking /// call on an existing instance. See also collections/namedtuple typing in the Typeshed. /// </summary> internal AstPythonType GetTypeFactory() { var clone = new AstPythonType(Name, DeclaringModule, Documentation, Locations.OfType <LocationInfo>().FirstOrDefault(), TypeId == BuiltinTypeId.Unknown ? BuiltinTypeId.Type : TypeId, true); clone.AddMembers(Members, true); return(clone); }
public override bool Walk(AssignmentStatement node) { var value = _scope.GetValueFromExpression(node.Right); foreach (var lhs in node.Left) { if (lhs is MemberExpression memberExp && memberExp.Target is NameExpression nameExp1) { if (_selfType != null && nameExp1.Name == "self") { _selfType.AddMembers(new[] { new KeyValuePair <string, IMember>(memberExp.Name, value) }, true); } continue; } if (lhs is NameExpression nameExp2 && nameExp2.Name == "self") { continue; // Don't assign to 'self' } // Basic assignment foreach (var ne in node.Left.OfType <NameExpression>()) { _scope.SetInScope(ne.Name, value); } // Tuple = Tuple. Transfer values. if (lhs is TupleExpression tex) { if (value is TupleExpression valTex) { var returnedExpressions = valTex.Items.ToArray(); var names = tex.Items.Select(x => (x as NameExpression)?.Name).ToArray(); for (var i = 0; i < Math.Min(names.Length, returnedExpressions.Length); i++) { if (returnedExpressions[i] != null) { var v = _scope.GetValueFromExpression(returnedExpressions[i]); _scope.SetInScope(names[i], v); } } continue; } // Tuple = 'tuple value' (such as from callable). Transfer values. if (value is AstPythonConstant c && c.Type is AstPythonSequence seq) { var types = seq.IndexTypes.ToArray(); var names = tex.Items.Select(x => (x as NameExpression)?.Name).ToArray(); for (var i = 0; i < Math.Min(names.Length, types.Length); i++) { if (names[i] != null && types[i] != null) { _scope.SetInScope(names[i], new AstPythonConstant(types[i])); } } } } } return(base.Walk(node)); }