private static SwitchCSharpStatement SwitchLogValue(Func <string, Expression> log, Expression expression, Expression defaultBody, params CSharpSwitchCase[] cases) { var b = Expression.Label(); var eval = Expression.Block(log("E"), expression); return(CSharpStatement.Switch(eval, b, defaultBody, cases)); }
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 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_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_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 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")); }