示例#1
0
文件: TestTuple.cs 项目: zspitz/dlr
        public void TestNestedTupleSize()
        {
            int size = 8;

            Type[] args = new Type[size];
            for (int i = 0; i < size; i++)
            {
                if (i == 5)
                {
                    var nestedTupleType = MutableTuple.MakeTupleType(typeof(int), typeof(int));
                    args[i] = nestedTupleType;
                }
                else
                {
                    args[i] = typeof(int);
                }
            }

            var tupleType = MutableTuple.MakeTupleType(args);

            // these both fail - https://github.com/IronLanguages/dlr/issues/231
            //Assert.AreEqual(MutableTuple.GetSize(tupleType), size);
            //Assert.Throws<ArgumentException>(() => MutableTuple.GetAccessPath(tupleType, size).ToArray());
            Assert.AreEqual(MutableTuple.GetSize(tupleType), size + 1);
            Assert.Throws <InvalidOperationException>(() => MutableTuple.GetAccessPath(tupleType, size).ToArray());
        }
示例#2
0
        public override Expression Reduce()
        {
            Expression res = _tupleExpr.Value;

            foreach (PropertyInfo pi in MutableTuple.GetAccessPath(_tupleType.Value, Index))
            {
                res = Expression.Property(res, pi);
            }
            return(res);
        }
        public static MSA.Expression /*!*/ GetVariableAccessor(MSA.Expression /*!*/ tupleVariable, int tupleFieldIndex)
        {
            MSA.Expression accessor = tupleVariable;

            foreach (var property in MutableTuple.GetAccessPath(tupleVariable.Type, tupleFieldIndex))
            {
                accessor = Ast.Property(accessor, property);
            }

            return(accessor);
        }
示例#4
0
 internal Type GetVariableType(Compiler compiler, out IEnumerable <PropertyInfo> tupleAccessPath, out bool localInTuple)
 {
     localInTuple    = (this._tupleIndex >= 0) && (compiler.Optimize || (this._tupleIndex < 9));
     tupleAccessPath = null;
     if (localInTuple)
     {
         tupleAccessPath = MutableTuple.GetAccessPath(compiler.LocalVariablesTupleType, this._tupleIndex);
         return(tupleAccessPath.Last <PropertyInfo>().PropertyType);
     }
     return(typeof(object));
 }
示例#5
0
        internal virtual void FinishBind(PythonNameBinder binder)
        {
            List <ClosureInfo> closureVariables = null;

            if (FreeVariables != null && FreeVariables.Count > 0)
            {
                var tupleType = Parent.GetClosureTupleType();
                LocalParentTuple = Ast.Parameter(tupleType, "$tuple");

                var parentClosure = Parent._closureVariables;
                Debug.Assert(parentClosure != null);

                foreach (var variable in FreeVariables)
                {
                    for (int i = 0; i < parentClosure.Length; i++)
                    {
                        if (parentClosure[i].Variable == variable)
                        {
                            Ast prop = LocalParentTuple;
                            foreach (PropertyInfo pi in MutableTuple.GetAccessPath(tupleType, parentClosure.Length, i))
                            {
                                prop = Ast.Property(prop, pi);
                            }
                            _variableMapping[variable] = new ClosureExpression(variable, prop, null);
                            break;
                        }
                    }
                    Debug.Assert(_variableMapping.ContainsKey(variable));

                    if (closureVariables == null)
                    {
                        closureVariables = new List <ClosureInfo>();
                    }
                    closureVariables.Add(new ClosureInfo(variable, !(this is ClassDefinition)));
                }
            }

            if (Variables != null)
            {
                foreach (PythonVariable variable in Variables.Values)
                {
                    if (!HasClosureVariable(closureVariables, variable) &&
                        variable.Kind is not VariableKind.Global and not VariableKind.Nonlocal &&
                        (variable.AccessedInNestedScope || ExposesLocalVariable(variable)))
                    {
                        if (closureVariables == null)
                        {
                            closureVariables = new List <ClosureInfo>();
                        }
                        closureVariables.Add(new ClosureInfo(variable, true));
                    }

                    if (variable.Kind == VariableKind.Local)
                    {
                        Debug.Assert(variable.Scope == this);

                        if (variable.AccessedInNestedScope || ExposesLocalVariable(variable))
                        {
                            _variableMapping[variable] = new ClosureExpression(variable, Ast.Parameter(typeof(ClosureCell), variable.Name), null);
                        }
                        else
                        {
                            _variableMapping[variable] = Ast.Parameter(typeof(object), variable.Name);
                        }
                    }
                }
            }

            if (closureVariables != null)
            {
                _closureVariables = closureVariables.ToArray();
            }

            // no longer needed
            _references   = null;
            _nonlocalVars = null;
        }
示例#6
0
        public void VerifyTuple(int size)
        {
            //Construct a tuple of the right type
            MethodInfo mi = typeof(MutableTuple).GetMethod("MakeTupleType", BindingFlags.Public | BindingFlags.Static);

            Assert.NotNull(mi, "Could not find Tuple.MakeTupleType");

            Type[]   args   = new Type[size];
            object[] values = new object[size];
            for (int i = 0; i < size; i++)
            {
                args[i]   = typeof(int);
                values[i] = 0;
            }

            Type         tupleType = (Type)mi.Invoke(null, new object[] { args });
            MutableTuple t         = MutableTuple.MakeTuple(tupleType, values);

            /////////////////////
            //Properties

            //Write
            for (int i = 0; i < size; i++)
            {
                object o = t;
                foreach (PropertyInfo pi in MutableTuple.GetAccessPath(tupleType, i))
                {
                    if (typeof(MutableTuple).IsAssignableFrom(pi.PropertyType))
                    {
                        o = pi.GetValue(o, null);
                    }
                    else
                    {
                        pi.SetValue(o, i * 5, null);
                    }
                }
            }

            //Read
            for (int i = 0; i < size; i++)
            {
                object o = t;
                foreach (PropertyInfo pi in MutableTuple.GetAccessPath(tupleType, i))
                {
                    o = pi.GetValue(o, null);
                }
                Assert.AreEqual(typeof(int), o.GetType());
                Assert.AreEqual((int)o, i * 5);
            }

            //Negative cases for properties
            Assert.Throws <ArgumentException>(delegate() {
                foreach (PropertyInfo pi in MutableTuple.GetAccessPath(tupleType, -1))
                {
                    Console.WriteLine(pi.Name); //This won't run, but we need it so that this call isn't inlined
                }
            });

            /////////////////////
            //GetTupleValues
            values = MutableTuple.GetTupleValues(t);
            Assert.AreEqual(values.Length, size);
            for (int i = 0; i < size; i++)
            {
                Assert.AreEqual(typeof(int), values[i].GetType());
                Assert.AreEqual((int)(values[i]), i * 5);
            }

            /////////////////////
            //Access methods

            if (size <= MutableTuple.MaxSize)
            {
                //SetValue
                for (int i = 0; i < size; i++)
                {
                    t.SetValue(i, i * 3);
                }

                //GetValue
                for (int i = 0; i < size; i++)
                {
                    Assert.AreEqual(t.GetValue(i), i * 3);
                }

                //Ensure there are no extras
                if (tupleType.GetGenericArguments().Length <= size)
                {
                    //We're requesting an index beyond the end of this tuple.
                    Assert.Throws <ArgumentOutOfRangeException>(delegate() { t.SetValue(size, 3); });
                    Assert.Throws <ArgumentOutOfRangeException>(delegate() { t.GetValue(size); });
                }
                else
                {
                    /*We're requesting an index in the scope of this tuple but beyond the scope of our
                     * requested capacity (in which case the field's type will be Microsoft.Scripting.None
                     * and we won't be able to convert "3" to that).  Imagine asking for a tuple of 3 ints,
                     * we'd actually get a Tuple<int,int,int,Microsoft.Scripting.None> since there is no
                     * Tuple that takes only 3 generic arguments.*/
                    Assert.Throws <InvalidCastException>(delegate() { t.SetValue(size, 3); });

                    //Verify the type of the field
                    Assert.AreEqual(typeof(Microsoft.Scripting.Runtime.DynamicNull), tupleType.GetGenericArguments()[size]);

                    //Verify the value of the field is null
                    Assert.AreEqual(null, t.GetValue(size));
                }
            }
        }