Exemplo n.º 1
0
        /// <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));
        }