public void TestCombineWithRenameVarsNotDeclR() { // If one of the variables isn't declared, then this is a "result" and it shouldn't // be combined (or similar - whatever, it is outside the block). So we can't // do the combine for now! // This is the same guy as above - but in reverse order. This is important because // this test needs to be symetric. var inline1 = new StatementInlineBlock(); var inline2 = new StatementInlineBlock(); var vdecl1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var vdecl2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); inline1.Add(vdecl1); var s1 = new CombineTestStatement(vdecl1); inline1.Add(s1); var s2 = new CombineTestStatement(vdecl2); inline2.Add(s2); inline2.Add(new Statements.StatementSimpleStatement(string.Format("dude = {0}", vdecl2.RawValue))); var result = inline2.TryCombineStatement(inline1, null); Assert.IsTrue(result, "try combine didn't work"); Assert.AreEqual(3, inline2.Statements.Count(), "bad # of combined statements"); }
public void TestCombineWithRenameDownstream() { // When doing a good rename, make sure downstream statements get the rename too. var inline1 = new StatementInlineBlock(); var inline2 = new StatementInlineBlock(); var vdecl1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var vdecl2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); inline1.Add(vdecl1); inline2.Add(vdecl2); var s1 = new CombineTestStatement(vdecl1); inline1.Add(s1); var s2 = new CombineTestStatement(vdecl2); inline2.Add(s2); inline2.Add(new Statements.StatementSimpleStatement(string.Format("dude = {0}", vdecl2.ParameterName))); var result = inline1.TryCombineStatement(inline2, null); Assert.IsTrue(result, "try combine didn't work"); Assert.AreEqual(2, inline1.Statements.Count(), "bad # of combined statements"); Assert.AreEqual(string.Format("dude = {0};", vdecl1.ParameterName), inline1.Statements.Skip(1).First().CodeItUp().First(), "Line wasn't renamed"); }
public void TestCombineWithRenameVarsDifferent() { // If the varialbes are initialized differently, then we can't combine them! var inline1 = new StatementInlineBlock(); var inline2 = new StatementInlineBlock(); var vdecl1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); vdecl1.SetInitialValue("0"); var vdecl2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); vdecl2.SetInitialValue("1"); inline1.Add(vdecl1); inline2.Add(vdecl2); var s1 = new CombineTestStatement(vdecl1); inline1.Add(s1); var s2 = new CombineTestStatement(vdecl2); inline2.Add(s2); inline2.Add(new Statements.StatementSimpleStatement(string.Format("dude = {0}", vdecl2.RawValue))); var result = inline1.TryCombineStatement(inline2, null); Assert.IsTrue(result, "try combine didn't work"); Assert.AreEqual(3, inline1.Statements.Count(), "bad # of combined statements"); }
public void TestCombineWithRenameSimple() { // Try to combine two statements that will combine, but require // a rename first. var inline1 = new StatementInlineBlock(); var inline2 = new StatementInlineBlock(); var vdecl1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var vdecl2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); inline1.Add(vdecl1); inline2.Add(vdecl2); var s1 = new CombineTestStatement(vdecl1); inline1.Add(s1); var s2 = new CombineTestStatement(vdecl2); inline2.Add(s2); var result = inline1.TryCombineStatement(inline2, null); Assert.IsTrue(result, "try combine didn't work"); Assert.AreEqual(1, inline1.Statements.Count(), "bad # of combined statements"); }
public void TestCombineWithAlteredValue() { // This variable will be modified in an assignment statement. var varToBeModified = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var statementModifier = new StatementAssign(varToBeModified, new ValSimple("1", typeof(int))); // Next, we access this variable in an if statement. var finalVar = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var assignment = new StatementAssign(finalVar, varToBeModified); var checkVar = DeclarableParameter.CreateDeclarableParameterExpression(typeof(bool)); var ifUsesModifiedValue = new StatementFilter(new ValSimple(checkVar.RawValue, typeof(bool))); ifUsesModifiedValue.Add(assignment); var ifNoUsesModifiedValue = new StatementFilter(new ValSimple(checkVar.RawValue, typeof(bool))); // Ok, now create the two sets of top level statements. var blockWithModified = new StatementInlineBlock(); var blockWithoutModified = new StatementInlineBlock(); blockWithModified.Add(varToBeModified); blockWithModified.Add(finalVar); blockWithModified.Add(statementModifier); blockWithModified.Add(checkVar); blockWithoutModified.Add(checkVar); blockWithModified.Add(ifUsesModifiedValue); blockWithoutModified.Add(ifNoUsesModifiedValue); // Combine var r = blockWithoutModified.TryCombineStatement(blockWithModified, null); Assert.IsTrue(r, "try combine result"); foreach (var s in blockWithoutModified.CodeItUp()) { System.Diagnostics.Trace.WriteLine(s); } // Make sure the checkVar guy comes after the modified statement. var topLevelStatementForAssign = findStatementThatContains(blockWithoutModified, assignment); var posOfUse = findStatementIndex(blockWithoutModified, topLevelStatementForAssign); var posOfMod = findStatementIndex(blockWithoutModified, statementModifier); Assert.IsTrue(posOfMod < posOfUse, string.Format("Modification happens after use. modification: {0} use {1}", posOfMod, posOfUse)); }
public void TestCombineWithRenameAtDifferentLevels() { // Try to combine two statements that look like they should combine, // but one variable is declared at a different "level" than the other // up the hierarchy. var inline1 = new StatementInlineBlock(); var inline11 = new StatementInlineBlock(); inline1.Add(inline11); var inline2 = new StatementInlineBlock(); var inline22 = new StatementInlineBlock(); inline2.Add(inline22); var vdecl1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var vdecl2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); inline1.Add(vdecl1); inline22.Add(vdecl2); var s1 = new CombineTestStatement(vdecl1); inline11.Add(s1); var s2 = new CombineTestStatement(vdecl2); inline22.Add(s2); var result = inline1.TryCombineStatement(inline2, null); Assert.IsTrue(result, "try combine should go ok"); Assert.AreEqual(1, inline1.Statements.Count(), "# statements inside inline 1"); var innerBlock = inline1.Statements.First() as IBookingStatementBlock; Assert.IsNotNull(innerBlock, "inner block a booking statement"); Assert.AreEqual(2, innerBlock.Statements.Count(), "Statements in inner block should not have combined"); }
public void TestCombinePreserveOrder() { // We will have two if statements to do the combination with. They basically "hide" the modification. var checkVar1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(bool)); var if1s1 = new StatementFilter(new ValSimple(checkVar1.RawValue, typeof(bool))); var if1s2 = new StatementFilter(new ValSimple(checkVar1.RawValue, typeof(bool))); var checkVar2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(bool)); var if2s1 = new StatementFilter(new ValSimple(checkVar2.RawValue, typeof(bool))); var if2s2 = new StatementFilter(new ValSimple(checkVar2.RawValue, typeof(bool))); var blockWithModified = new StatementInlineBlock(); var blockWithoutModified = new StatementInlineBlock(); blockWithModified.Add(checkVar1); blockWithModified.Add(checkVar2); blockWithoutModified.Add(checkVar1); blockWithoutModified.Add(checkVar2); // Not the opposite order we put them in here! blockWithModified.Add(if1s1); blockWithModified.Add(if2s1); blockWithoutModified.Add(if2s2); blockWithoutModified.Add(if1s2); // Have the modified if statement contain the modification now. var varToBeModified = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var statementModifier = new StatementAssign(varToBeModified, new ValSimple("1", typeof(int))); blockWithModified.Add(varToBeModified); if1s1.Add(statementModifier); // Next, we need to use the variable in the second if statement. Which, since it is like the first, should be pushed back up there. var finalVar = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var assignment = new StatementAssign(finalVar, varToBeModified); blockWithModified.Add(finalVar); if2s1.Add(assignment); // Combine var r = blockWithoutModified.TryCombineStatement(blockWithModified, null); Assert.IsTrue(r, "try combine result"); foreach (var s in blockWithoutModified.CodeItUp()) { System.Diagnostics.Trace.WriteLine(s); } // Make sure the checkVar guy comes after the modified statement. var topLevelStatementForAssign = findStatementThatContains(blockWithoutModified, assignment); var posOfUse = findStatementIndex(blockWithoutModified, topLevelStatementForAssign); var topLevelStatementForModification = findStatementThatContains(blockWithoutModified, statementModifier); var posOfMod = findStatementIndex(blockWithoutModified, topLevelStatementForModification); Assert.IsTrue(posOfMod < posOfUse, string.Format("Modification happens after use. modification: {0} use {1}", posOfMod, posOfUse)); }
public void TestCombineMinimalOrdering() { // We will have two if statements to do the combination with. They basically "hide" the modification. var checkVar1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(bool)); var if1s1 = new StatementFilter(new ValSimple(checkVar1.RawValue, typeof(bool))); var if1s2 = new StatementFilter(new ValSimple(checkVar1.RawValue, typeof(bool))); var checkVar2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(bool)); var if2s1 = new StatementFilter(new ValSimple(checkVar2.RawValue, typeof(bool))); var if2s2 = new StatementFilter(new ValSimple(checkVar2.RawValue, typeof(bool))); var dummyVar = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var blockWithModified = new StatementInlineBlock(); var blockWithoutModified = new StatementInlineBlock(); blockWithModified.Add(checkVar1); blockWithModified.Add(checkVar2); blockWithModified.Add(dummyVar); blockWithoutModified.Add(checkVar1); blockWithoutModified.Add(checkVar2); blockWithoutModified.Add(dummyVar); // Not the opposite order we put them in here! blockWithModified.Add(if1s1); blockWithModified.Add(if2s1); blockWithoutModified.Add(if2s2); blockWithoutModified.Add(if1s2); if1s1.Add(new StatementAssign(dummyVar, new ValSimple("1", typeof(int)))); if2s1.Add(new StatementAssign(dummyVar, new ValSimple("2", typeof(int)))); if1s2.Add(new StatementAssign(dummyVar, new ValSimple("3", typeof(int)))); if2s2.Add(new StatementAssign(dummyVar, new ValSimple("4", typeof(int)))); // Have the modified if statement contain the modification now. var varToBeModified = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var statementModifier = new StatementAssign(varToBeModified, new ValSimple("1", typeof(int))); blockWithModified.Add(varToBeModified); if1s1.Add(statementModifier); // Next, we need to use the variable in the second if statement. Which, since it is like the first, should be pushed back up there. var finalVar = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var assignment = new StatementAssign(finalVar, varToBeModified); blockWithModified.Add(finalVar); if2s1.Add(assignment); // Combine var r = blockWithoutModified.TryCombineStatement(blockWithModified, null); Assert.IsTrue(r, "try combine result"); foreach (var s in blockWithoutModified.CodeItUp()) { System.Diagnostics.Trace.WriteLine(s); } // Make sure the checkVar guy comes after the modified statement. // To get this right (the 3 should be a 2), we need to implement a full blown statement optimizer. Assert.AreEqual(3, blockWithoutModified.Statements.Where(s => s is StatementFilter).Count(), "# of if statements."); }
public void TestCombineNestedForLoopOnOneSide() { var base1 = new StatementInlineBlock(); var limit = new LINQToTTreeLib.Variables.ValSimple("5", typeof(int)); var loopP1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var loop1 = new StatementForLoop(loopP1, limit); base1.Add(loop1); var base2 = new StatementInlineBlock(); var limit2 = new LINQToTTreeLib.Variables.ValSimple("5", typeof(int)); var loopP12 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var loop12 = new StatementForLoop(loopP12, limit); base2.Add(loop12); var loopP22 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var loop22 = new StatementForLoop(loopP22, limit); loop12.Add(loop22); var r = base1.TryCombineStatement(base2, new dummyOpt()); Assert.IsTrue(r, "combination should work"); Assert.AreEqual(base1, loop1.Parent, "loop 1 parent"); Assert.AreEqual(loop1, loop22.Parent, "Loop 2 parent"); }