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