public void Switch_Compile_NestedSwitch3() { // NB: See design remark in code. var res = CSharpStatement.Switch( Expression.Constant(1), Expression.Label(), CSharpStatement.SwitchCase( new[] { 5 }, Expression.Switch( Expression.Constant(2), Expression.SwitchCase(CSharpStatement.GotoCase(3), Expression.Constant(4)) ) ) ); var red = res.Reduce(); // This doesn't throw because we don't recurse into the nested Switch. Assert.AreNotSame(red, res); var f = Expression.Lambda <Action>(res); AssertEx.Throws <ArgumentException>(() => f.Compile()); // must be reducible node }
public void Switch_Compile_NestedSwitch2() { AssertCompile <int>((log, v) => SwitchLogValue(log, v, CSharpStatement.SwitchCase( new[] { 1 }, CSharpStatement.Switch( Expression.Constant(3), Expression.Label(), CSharpStatement.SwitchCase(new[] { 2 }, log("C")), CSharpStatement.SwitchCase(new[] { 3 }, log("A"), CSharpStatement.GotoCase(2), log("X")) ) ), CSharpStatement.SwitchCase(new[] { 2 }, log("XC")), CSharpStatement.SwitchCase(new[] { 3 }, log("B"), CSharpStatement.GotoCase(2)) ), new Asserts <int> { { 0, "E" }, { 1, "E", "A", "C" }, { 2, "E", "XC" }, { 3, "E", "B", "XC" }, } ); }
public void Switch_Factory_ArgumentChecking() { var value = Expression.Constant(1); var breakLabel = Expression.Label(); var defaultBody = Expression.Empty(); var cases = new[] { CSharpStatement.SwitchCase(new[] { 1 }, Expression.Empty()), CSharpStatement.SwitchCase(new[] { 2 }, Expression.Empty()) }; var empty = Expression.Empty(); var label = Expression.Label(typeof(int)); var dateTime = Expression.Default(typeof(DateTime)); var nullCase = new[] { cases[0], null, cases[1] }; var duplicateCase = new[] { cases[0], cases[1], cases[0] }; var withNullCase = new[] { cases[0], CSharpStatement.SwitchCase(new[] { default(int?) }, Expression.Empty()) }; var nonIntCases = new[] { CSharpStatement.SwitchCase(new[] { 1L }, Expression.Empty()) }; // null AssertEx.Throws <ArgumentNullException>(() => CSharpStatement.Switch(default(Expression), breakLabel, cases)); AssertEx.Throws <ArgumentNullException>(() => CSharpStatement.Switch(default(Expression), breakLabel, defaultBody, cases)); AssertEx.Throws <ArgumentNullException>(() => CSharpStatement.Switch(default(Expression), breakLabel, defaultBody, cases.AsEnumerable())); AssertEx.Throws <ArgumentNullException>(() => CSharpStatement.Switch(value, default(LabelTarget), cases)); AssertEx.Throws <ArgumentNullException>(() => CSharpStatement.Switch(value, default(LabelTarget), defaultBody, cases)); AssertEx.Throws <ArgumentNullException>(() => CSharpStatement.Switch(value, default(LabelTarget), defaultBody, cases.AsEnumerable())); // switch type void AssertEx.Throws <ArgumentException>(() => CSharpStatement.Switch(empty, breakLabel, cases)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.Switch(empty, breakLabel, defaultBody, cases)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.Switch(empty, breakLabel, defaultBody, cases.AsEnumerable())); // non-void break label AssertEx.Throws <ArgumentException>(() => CSharpStatement.Switch(value, label, cases)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.Switch(value, label, defaultBody, cases)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.Switch(value, label, defaultBody, cases.AsEnumerable())); // invalid switch type AssertEx.Throws <ArgumentException>(() => CSharpStatement.Switch(dateTime, breakLabel, cases)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.Switch(dateTime, breakLabel, defaultBody, cases)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.Switch(dateTime, breakLabel, defaultBody, cases.AsEnumerable())); // null case AssertEx.Throws <ArgumentNullException>(() => CSharpStatement.Switch(value, breakLabel, nullCase)); AssertEx.Throws <ArgumentNullException>(() => CSharpStatement.Switch(value, breakLabel, defaultBody, nullCase)); AssertEx.Throws <ArgumentNullException>(() => CSharpStatement.Switch(value, breakLabel, defaultBody, nullCase.AsEnumerable())); // duplicate values AssertEx.Throws <ArgumentException>(() => CSharpStatement.Switch(value, breakLabel, duplicateCase)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.Switch(value, breakLabel, defaultBody, duplicateCase)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.Switch(value, breakLabel, defaultBody, duplicateCase.AsEnumerable())); // null not allowed AssertEx.Throws <ArgumentException>(() => CSharpStatement.Switch(value, breakLabel, withNullCase)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.Switch(value, breakLabel, defaultBody, withNullCase)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.Switch(value, breakLabel, defaultBody, withNullCase.AsEnumerable())); // incompatible types AssertEx.Throws <ArgumentException>(() => CSharpStatement.Switch(value, breakLabel, nonIntCases)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.Switch(value, breakLabel, defaultBody, nonIntCases)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.Switch(value, breakLabel, defaultBody, nonIntCases.AsEnumerable())); }
public void SwitchCase_Visitor() { var body = Expression.Empty(); var res = CSharpStatement.SwitchCase(new[] { 1, 2, 3 }, body); var v = new V(); Assert.AreSame(res, v.VisitSwitchCase(res)); Assert.IsTrue(v.Visited); }
public void Switch_Properties() { var value = Expression.Constant(1); var label = Expression.Label(); var cases = new[] { CSharpStatement.SwitchCase(new[] { 42 }, Expression.Empty()) }; var res = CSharpStatement.Switch(value, label, cases); Assert.AreEqual(CSharpExpressionType.Switch, res.CSharpNodeType); Assert.AreSame(value, res.SwitchValue); Assert.AreSame(label, res.BreakLabel); Assert.IsTrue(cases.SequenceEqual(res.Cases)); }
public void Switch_Visitor() { var value = Expression.Constant(1); var label = Expression.Label(); var defaultBody = Expression.Empty(); var cases = new[] { CSharpStatement.SwitchCase(new[] { 42 }, Expression.Empty()) }; var res = CSharpStatement.Switch(value, label, defaultBody, cases); var v = new V(); Assert.AreSame(res, v.Visit(res)); Assert.IsTrue(v.Visited); }
public void Switch_Compile_Int32() { AssertCompile <int>((log, v) => SwitchLogValue(log, v, CSharpStatement.SwitchCase(new[] { 1 }, log("A")) ), new Asserts <int> { { 0, "E" }, { 1, "E", "A" }, { 2, "E" }, } ); }
public void Switch_Compile_String() { AssertCompile <string>((log, v) => SwitchLogValue(log, v, CSharpStatement.SwitchCase(new[] { "1" }, log("A")) ), new Asserts <string> { { "0", "E" }, { "1", "E", "A" }, { "2", "E" }, { null, "E" }, } ); }
public void Switch_Compile_GotoCase2() { AssertCompile <int>((log, v) => SwitchLogValue(log, v, CSharpStatement.SwitchCase(new[] { 2 }, log("B")), CSharpStatement.SwitchCase(new[] { 1 }, log("A"), CSharpStatement.GotoCase(2), log("X")) ), new Asserts <int> { { 0, "E" }, { 1, "E", "A", "B" }, { 2, "E", "B" }, { 3, "E" }, } ); }
public void Switch_Compile_NullableInt32_Default() { AssertCompile <int?>((log, v) => SwitchLogValue(log, v, log("D"), CSharpStatement.SwitchCase(new[] { 1 }, log("A")) ), new Asserts <int?> { { 0, "E", "D" }, { 1, "E", "A" }, { 2, "E", "D" }, { null, "E", "D" }, } ); }
public void Switch_Compile_VoidAllCases1() { var p = Expression.Parameter(typeof(int)); var res = CSharpStatement.Switch( p, Expression.Label(), Expression.Constant("foo"), CSharpStatement.SwitchCase(new[] { 3 }, Expression.Constant(2)) ); var f = Expression.Lambda <Action <int> >(res, p).Compile(); // no error despite non-void cases f(1); f(2); f(3); }
public void Switch_Compile_String_Default_NullCase() { AssertCompile <string>((log, v) => SwitchLogValue(log, v, log("D"), CSharpStatement.SwitchCase(new[] { "1" }, log("A")), CSharpStatement.SwitchCase(new[] { default(string) }, log("N")) ), new Asserts <string> { { "0", "E", "D" }, { "1", "E", "A" }, { "2", "E", "D" }, { null, "E", "N" }, } ); }
public void Switch_Compile_GotoCase_Null3() { AssertCompile <int?>((log, v) => SwitchLogValue(log, v, CSharpStatement.SwitchCase(new[] { 1 }, log("A")), CSharpStatement.SwitchCase(new[] { 2 }, log("B")), CSharpStatement.SwitchCase(new[] { default(int?) }, log("N"), CSharpStatement.GotoCase(1), log("X")) ), new Asserts <int?> { { 0, "E" }, { 1, "E", "A" }, { 2, "E", "B" }, { 3, "E" }, { null, "E", "N", "A" } } ); }
public void Switch_Compile_NullableInt32_Many() { AssertCompile <int?>((log, v) => SwitchLogValue(log, v, CSharpStatement.SwitchCase(new[] { 1, 3 }, log("O")), CSharpStatement.SwitchCase(new[] { 2, 4 }, log("E")) ), new Asserts <int?> { { 0, "E" }, { 1, "E", "O" }, { 2, "E", "E" }, { 3, "E", "O" }, { 4, "E", "E" }, { null, "E" }, } ); }
public void Switch_Update() { var value1 = Expression.Constant(1); var label1 = Expression.Label(); var cases1 = new[] { CSharpStatement.SwitchCase(new[] { 42 }, Expression.Empty()) }; var vars1 = new[] { Expression.Parameter(typeof(int)) }; var value2 = Expression.Constant(1); var label2 = Expression.Label(); var cases2 = new[] { CSharpStatement.SwitchCase(new[] { 43 }, Expression.Empty()) }; var vars2 = new[] { Expression.Parameter(typeof(int)) }; var res = CSharpStatement.Switch(value1, label1, vars1, cases1); var u0 = res.Update(res.SwitchValue, res.BreakLabel, res.Variables, res.Cases); var u1 = res.Update(value2, res.BreakLabel, res.Variables, res.Cases); var u2 = res.Update(res.SwitchValue, label2, res.Variables, res.Cases); var u3 = res.Update(res.SwitchValue, res.BreakLabel, vars2, res.Cases); var u4 = res.Update(res.SwitchValue, res.BreakLabel, res.Variables, cases2); Assert.AreSame(res, u0); Assert.AreSame(value2, u1.SwitchValue); Assert.AreSame(label1, u1.BreakLabel); Assert.IsTrue(vars1.SequenceEqual(u1.Variables)); Assert.IsTrue(cases1.SequenceEqual(u1.Cases)); Assert.AreSame(value1, u2.SwitchValue); Assert.AreSame(label2, u2.BreakLabel); Assert.IsTrue(vars1.SequenceEqual(u2.Variables)); Assert.IsTrue(cases1.SequenceEqual(u2.Cases)); Assert.AreSame(value1, u3.SwitchValue); Assert.AreSame(label1, u3.BreakLabel); Assert.IsTrue(vars2.SequenceEqual(u3.Variables)); Assert.IsTrue(cases1.SequenceEqual(u3.Cases)); Assert.AreSame(value1, u4.SwitchValue); Assert.AreSame(label1, u4.BreakLabel); Assert.IsTrue(vars1.SequenceEqual(u4.Variables)); Assert.IsTrue(cases2.SequenceEqual(u4.Cases)); }
public void SwitchCase_Properties() { var b = new[] { Expression.Empty() }; var t = new int[] { 1, 2 }; var s1 = CSharpStatement.SwitchCase(t, b); var s2 = CSharpStatement.SwitchCase(t.AsEnumerable(), b); var s3 = CSharpStatement.SwitchCase(t.Select(x => (object)x).ToArray(), b); var s4 = CSharpStatement.SwitchCase(t.Select(x => (object)x).AsEnumerable(), b); var s5 = CSharpStatement.SwitchCase(t, b.AsEnumerable()); var s6 = CSharpStatement.SwitchCase(t.AsEnumerable(), b.AsEnumerable()); var s7 = CSharpStatement.SwitchCase(t.Select(x => (object)x).ToArray(), b.AsEnumerable()); var s8 = CSharpStatement.SwitchCase(t.Select(x => (object)x).AsEnumerable(), b.AsEnumerable()); foreach (var s in new[] { s1, s2, s3, s4, s5, s6, s7, s8 }) { Assert.IsTrue(b.SequenceEqual(s.Statements)); Assert.IsTrue(t.SequenceEqual(s.TestValues.Cast <int>())); } }
public void Switch_Compile_String_DefaultWithCompanionship3() { AssertCompile <string>((log, v) => SwitchLogValue(log, v, CSharpStatement.SwitchCase(new[] { "1" }, log("A")), CSharpStatement.SwitchCase(new[] { "3", CSharpStatement.SwitchCaseDefaultValue, default(string) }, log("D")), CSharpStatement.SwitchCase(new[] { "2" }, log("B")) ), new Asserts <string> { { "0", "E", "D" }, { "1", "E", "A" }, { "2", "E", "B" }, { "3", "E", "D" }, { "4", "E", "D" }, { null, "E", "D" }, } ); }
public void Switch_Compile_NullableInt32_NullCaseWithCompanionship() { AssertCompile <int?>((log, v) => SwitchLogValue(log, v, log("D"), CSharpStatement.SwitchCase(new[] { 1 }, log("A")), CSharpStatement.SwitchCase(new[] { default(int?), 3 }, log("Z")), CSharpStatement.SwitchCase(new[] { 2 }, log("B")) ), new Asserts <int?> { { 0, "E", "D" }, { 1, "E", "A" }, { 2, "E", "B" }, { 3, "E", "Z" }, { 4, "E", "D" }, { null, "E", "Z" }, } ); }
public void SwitchCase_Update() { var b = new[] { Expression.Empty() }; var c = new[] { Expression.Empty() }; var t = new int[] { 1, 2 }; var s1 = CSharpStatement.SwitchCase(t, b); var s2 = CSharpStatement.SwitchCase(t.AsEnumerable(), b); var s3 = CSharpStatement.SwitchCase(t.Select(x => (object)x).ToArray(), b); var s4 = CSharpStatement.SwitchCase(t.Select(x => (object)x).AsEnumerable(), b); var s5 = CSharpStatement.SwitchCase(t, b.AsEnumerable()); var s6 = CSharpStatement.SwitchCase(t.AsEnumerable(), b.AsEnumerable()); var s7 = CSharpStatement.SwitchCase(t.Select(x => (object)x).ToArray(), b.AsEnumerable()); var s8 = CSharpStatement.SwitchCase(t.Select(x => (object)x).AsEnumerable(), b.AsEnumerable()); foreach (var s in new[] { s1, s2, s3, s4, s5, s6, s7, s8 }) { Assert.AreSame(s, s.Update(s.Statements)); var u = s.Update(c); Assert.IsTrue(c.SequenceEqual(u.Statements)); } }
public void SwitchCase_Factory_ArgumentChecking() { var body = new[] { Expression.Empty() }; var vals = new[] { 1, 2 }; var objs = new object[] { 1, 2 }; // null AssertEx.Throws <ArgumentNullException>(() => CSharpStatement.SwitchCase(default(int[]), body)); AssertEx.Throws <ArgumentNullException>(() => CSharpStatement.SwitchCase(default(IEnumerable <int>), body)); AssertEx.Throws <ArgumentNullException>(() => CSharpStatement.SwitchCase(default(object[]), body)); AssertEx.Throws <ArgumentNullException>(() => CSharpStatement.SwitchCase(default(IEnumerable <object>), body)); AssertEx.Throws <ArgumentNullException>(() => CSharpStatement.SwitchCase(vals, default(Expression[]))); AssertEx.Throws <ArgumentNullException>(() => CSharpStatement.SwitchCase(vals, default(IEnumerable <Expression>))); AssertEx.Throws <ArgumentNullException>(() => CSharpStatement.SwitchCase(objs, default(Expression[]))); AssertEx.Throws <ArgumentNullException>(() => CSharpStatement.SwitchCase(objs, default(IEnumerable <Expression>))); AssertEx.Throws <ArgumentNullException>(() => CSharpStatement.SwitchCaseDefault(default(Expression[]))); AssertEx.Throws <ArgumentNullException>(() => CSharpStatement.SwitchCaseDefault(default(IEnumerable <Expression>))); // empty AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(Array.Empty <int>(), body)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(Enumerable.Empty <int>(), body)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(Array.Empty <object>(), body)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(Enumerable.Empty <object>(), body)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(vals, Array.Empty <Expression>())); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(vals, Enumerable.Empty <Expression>())); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(objs, Array.Empty <Expression>())); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(objs, Enumerable.Empty <Expression>())); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCaseDefault(Array.Empty <Expression>())); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCaseDefault(Enumerable.Empty <Expression>())); // switch type AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new double[] { 0.0 }, body)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new double[] { 0.0 }.AsEnumerable(), body)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new double[] { 0.0 }, body.AsEnumerable())); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new double[] { 0.0 }.AsEnumerable(), body.AsEnumerable())); // duplicate value AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new int[] { 1, 1, 2 }, body)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new int[] { 1, 2, 1 }, body)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new int[] { 1, 2, 1 }.AsEnumerable(), body)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { 1, 2, 1 }, body)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { 1, 2, 1 }.AsEnumerable(), body)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new int[] { 1, 1, 2 }, body.AsEnumerable())); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new int[] { 1, 2, 1 }, body.AsEnumerable())); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new int[] { 1, 2, 1 }.AsEnumerable(), body.AsEnumerable())); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { 1, 2, 1 }, body.AsEnumerable())); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { 1, 2, 1 }.AsEnumerable(), body.AsEnumerable())); // inconsistent typing AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { null, "foo", 1 }.AsEnumerable(), body)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { "foo", null, 1 }.AsEnumerable(), body)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { 1, 2L }.AsEnumerable(), body)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { null, 1, 2L }.AsEnumerable(), body)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { 1, null, 2L }.AsEnumerable(), body)); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { null, "foo", 1 }.AsEnumerable(), body.AsEnumerable())); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { "foo", null, 1 }.AsEnumerable(), body.AsEnumerable())); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { 1, 2L }.AsEnumerable(), body.AsEnumerable())); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { null, 1, 2L }.AsEnumerable(), body.AsEnumerable())); AssertEx.Throws <ArgumentException>(() => CSharpStatement.SwitchCase(new object[] { 1, null, 2L }.AsEnumerable(), body.AsEnumerable())); // those are ok CSharpStatement.SwitchCase(new int?[] { null, 1 }, body); CSharpStatement.SwitchCase(new string[] { null, "bar" }, body); CSharpStatement.SwitchCase(new int?[] { 1, null }, body); CSharpStatement.SwitchCase(new string[] { "bar", null }, body); CSharpStatement.SwitchCase(new object[] { null }, body); CSharpStatement.SwitchCase(new object[] { null }.AsEnumerable(), body); }
public void Switch_Compile_GotoDefault_Error() { var res = CSharpStatement.Switch(Expression.Constant(1), Expression.Label(), CSharpStatement.SwitchCase(new[] { 1 }, CSharpStatement.GotoDefault())); AssertEx.Throws <InvalidOperationException>(() => res.Reduce(), ex => ex.Message.Contains("goto default")); }