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 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 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 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 CombineFilterWithHiddenBehindIfAndExtraDependentStatements() { // When we move an if statement, if there are extra statements and they depend on the code // we want to move, then we can't move them. // Top level guy. This is the unique filter statement. var filterUnique = new StatementFilter(new ValSimple("fUnique", typeof(bool))); // Next, we will do the two common ones. var f1 = new StatementFilter(new ValSimple("f1", typeof(bool))); var f2 = new StatementFilter(new ValSimple("f1", typeof(bool))); var p = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var a1 = new StatementAssign(p, new ValSimple("5", typeof(int))); var a2 = new StatementAssign(p, new ValSimple("5", typeof(int))); f1.Add(a1); f1.Add(p); f2.Add(a2); f2.Add(p); // Now, a unique assignment. This can't be lifted b.c. it is hidden behind a different if statement in // the outside (the filterUnique). var pSpecial = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var aUnique = new StatementAssign(pSpecial, p); f1.Add(aUnique); f1.Add(pSpecial); filterUnique.Add(f1); var topLevel = new StatementInlineBlock(); topLevel.Add(filterUnique); topLevel.Add(f2); Console.WriteLine("Before optimization:"); foreach (var l in topLevel.CodeItUp()) { Console.WriteLine(l); } // The combine should fail. Assert.IsFalse(f2.TryCombineStatement(f1, null), "The two are different if statements, so it should have failed"); Console.WriteLine("After optimization:"); foreach (var l in topLevel.CodeItUp()) { Console.WriteLine(l); } // But some statements should have been moved! (note that f1 normally has two statements). Assert.AreEqual(2, f1.Statements.Count()); Assert.AreEqual(1, f2.Statements.Count()); }
public void TestSimpleVariableCodingNoDeclAndDecl() { StatementInlineBlock b = new StatementInlineBlock(); b.Add(DeclarableParameter.CreateDeclarableParameterExpression(typeof(int))); b.Add(new Statements.StatementSimpleStatement("Bork")); var r = b.CodeItUp().ToArray(); Assert.AreEqual(4, r.Length, "# of statements"); }
public void TestRemoveSingleStatementResetsParent() { var s = new StatementInlineBlock(); var s1 = new StatementSimpleStatement("one"); var s2 = new StatementSimpleStatement("two"); s.Add(s1); s.Add(s2); s.Remove(s1); Assert.IsNull(s1.Parent, "s1 parent"); }
public void TestRemoveSingleStatement() { var s = new StatementInlineBlock(); var s1 = new StatementSimpleStatement("one"); var s2 = new StatementSimpleStatement("two"); s.Add(s1); s.Add(s2); s.Remove(s1); Assert.AreEqual(1, s.Statements.Count(), "# of statements after remove"); Assert.AreEqual(s2, s.Statements.First(), "First statement"); }
public void RenameVariablesToCauseDuplicate() { var inline1 = new StatementInlineBlock(); var v1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var v2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); inline1.Add(v1); inline1.Add(v2); inline1.RenameBlockVariables(v1.RawValue, v2.RawValue); Assert.AreEqual(1, inline1.DeclaredVariables.Count()); }
public void TestSimpleVariableCoding() { StatementInlineBlock b = new StatementInlineBlock(); b.Add(DeclarableParameter.CreateDeclarableParameterExpression(typeof(int))); b.Add(new Statements.StatementSimpleStatement("bork")); var r = b.CodeItUp().ToArray(); Assert.AreEqual(4, r.Length, "incorrect number of lines"); Assert.AreEqual("{", r[0], "open bracket"); Assert.AreEqual("}", r[3], "close bracket"); Assert.IsTrue(r[1].EndsWith("= 0;")); }
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 TestCombineSameStatement() { var inline1 = new StatementInlineBlock(); var vdecl1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); inline1.Add(vdecl1); var s1 = new CombineSameStatement(vdecl1); inline1.Add(s1); var result = inline1.CombineAndMark(s1, s1.Parent as IBookingStatementBlock, false); Assert.IsNull(result, "combine should fail"); }
public void TestIsBefore() { var s = new StatementInlineBlock(); var vdecl1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var s1 = new Statements.StatementAssign(vdecl1, new ValSimple("fork", typeof(int))); var s2 = new Statements.StatementAssign(vdecl1, new ValSimple("fork", typeof(int))); s.Add(s1); s.Add(s2); Assert.IsTrue(s.IsBefore(s1, s2), "s1 before s2"); Assert.IsFalse(s.IsBefore(s2, s1), "s2 is before s1"); }
public void BlockStaticDefinition() { var b = new StatementInlineBlock(); var p = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); p.DeclareAsStatic = true; b.Add(p); b.Add(new StatementAssign(p, new ValSimple("10", typeof(int)))); var r = b.CodeItUp().ToArray(); Assert.AreEqual(1, r.Where(l => l.Contains("static int aInt32")).Count()); }
public void TestAddBeforeWithAnother() { var s = new StatementInlineBlock(); var s1 = new StatementSimpleStatement("one"); var s2 = new StatementSimpleStatement("two"); var s3 = new StatementSimpleStatement("three"); s.Add(s2); s.Add(s3); s.AddBefore(s1, s3); Assert.AreEqual(3, s.Statements.Count(), "# of statements"); Assert.AreEqual(s2, s.Statements.First(), "first statement"); Assert.AreEqual(s1, s.Statements.Skip(1).First(), "second statement"); Assert.AreEqual(s3, s.Statements.Skip(2).First(), "third statement"); }
public void TestForFunctionNumber() { CPPTranslator target = new CPPTranslator(); var vInt = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); vInt.SetInitialValue("2"); GeneratedCode code = new GeneratedCode(); code.SetResult(vInt); var innerBlock = new StatementInlineBlock(); var vInt2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); vInt2.SetInitialValue("5"); innerBlock.Add(vInt2); code.Add(innerBlock); var r = TranslateGeneratedCode(target, code); Assert.IsTrue(r.ContainsKey("NumberOfQueryFunctions"), "Number of functions isn't here"); Assert.IsInstanceOfType(r["NumberOfQueryFunctions"], typeof(int), "# function type"); Assert.AreEqual(1, r["NumberOfQueryFunctions"], "# of functions"); Assert.IsTrue(r.ContainsKey("QueryFunctionBlocks"), "Missing query function blocks"); Assert.IsInstanceOfType(r["QueryFunctionBlocks"], typeof(IEnumerable<IEnumerable<string>>), "Type is incorrect"); var codeBlocks = r["QueryFunctionBlocks"] as IEnumerable<IEnumerable<string>>; Assert.AreEqual(1, codeBlocks.Count(), "Wrong number of code blocks"); }
public void DeclarationsAreMovedCorrectlyWhenStatementsReassigned() { // In this new world of moving things around, we move declaration and statements, but they aren't really connected. // So we should make sure that declaration aren't moved accidentally when they shouldn't be. // Inline block at the top var topLevel1 = new StatementInlineBlock(); var topLevel2 = new StatementInlineBlock(); // Top level guy. This is the unique filter statement. var filterUnique = new StatementFilter(new ValSimple("fUnique", typeof(bool))); topLevel1.Add(filterUnique); // Next, we will do the two common ones. var f1 = new StatementFilter(new ValSimple("f1", typeof(bool))); var f2 = new StatementFilter(new ValSimple("f1", typeof(bool))); var p1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var p2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); filterUnique.Add(p1); topLevel2.Add(p2); var a1 = new StatementAssign(p1, new ValSimple("5", typeof(int))); var a2 = new StatementAssign(p2, new ValSimple("5", typeof(int))); f1.Add(a1); f2.Add(a2); filterUnique.Add(f1); topLevel2.Add(f2); Console.WriteLine("Before optimization (target):"); topLevel2.DumpCodeToConsole(); Console.WriteLine("Before optimization (what is being merged):"); topLevel1.DumpCodeToConsole(); Assert.IsTrue(f2.TryCombineStatement(f1, null), "Two of the same if statements, and the combine should have worked"); Console.WriteLine("After optimization:"); foreach (var l in topLevel2.CodeItUp()) { Console.WriteLine(l); } Assert.AreEqual(1, f2.Statements.Count()); }
public void InlineBlockDeclardVariablesOne() { var s = new StatementInlineBlock(); var d = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); s.Add(d); Assert.AreEqual(1, s.DeclaredVariables.Count()); }
public void CombineFilterWithHiddenBehindIfAndExtraIndependentStatementsAndDeclaredVariables() { // When we try and fail to combine if statements, make sure we don't leave dangling name // changes - that the declaration aren't totally renamed. // Top level guy. This is the unique filter statement. var filterUnique = new StatementFilter(new ValSimple("fUnique", typeof(bool))); // Next, we will do the two common ones. var f1 = new StatementFilter(new ValSimple("f1", typeof(bool))); var f2 = new StatementFilter(new ValSimple("f1", typeof(bool))); var p1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var p2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); f1.Add(p1); f2.Add(p2); var a1 = new StatementAssign(p1, new ValSimple("5", typeof(int))); var a2 = new StatementAssign(p2, new ValSimple("5", typeof(int))); f1.Add(a1); f2.Add(a2); // Now, a unique assignment. This can't be lifted b.c. it is hidden behind a different if statement in // the outside (the filterUnique). var pSpecial = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var aUnique = new StatementAssign(pSpecial, new ValSimple("10", typeof(int))); f1.Add(pSpecial); f1.Add(aUnique); filterUnique.Add(f1); var topLevel1 = new StatementInlineBlock(); var topLevel2 = new StatementInlineBlock(); topLevel1.Add(filterUnique); topLevel2.Add(f2); Console.WriteLine("Before optimization (target):"); topLevel2.DumpCodeToConsole(); Console.WriteLine("Before optimization (merge):"); topLevel1.DumpCodeToConsole(); // The combine should fail. Assert.IsFalse(f2.TryCombineStatement(f1, null), "The two are different if statements, so it should have failed"); Console.WriteLine("After optimization (target):"); topLevel2.DumpCodeToConsole(); Console.WriteLine("After optimization (merge):"); topLevel1.DumpCodeToConsole(); // Nothing should have been touched in f1 - double check. Assert.AreEqual(2, f1.Statements.Count()); Assert.AreEqual(2, f1.DeclaredVariables.Count()); }
public void CombineFilterWithHiddenBehindIfAndExtraIndependentStatements() { // Seen in the wild. We have two identical if statements, one outside, and one inside another // (different) if statement. It is OK to combine these two as the code is identical. // See test CombineFilterWithHiddenBehindIfAndExtraStatements for the case where at // least one statement needs to be left behind. // Top level guy. This is the unique filter statement. var filterUnique = new StatementFilter(new ValSimple("fUnique", typeof(bool))); // Next, we will do the two common ones. var f1 = new StatementFilter(new ValSimple("f1", typeof(bool))); var f2 = new StatementFilter(new ValSimple("f1", typeof(bool))); var p1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var p2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var a1 = new StatementAssign(p1, new ValSimple("5", typeof(int))); var a2 = new StatementAssign(p2, new ValSimple("5", typeof(int))); f1.Add(a1); f1.Add(p1); f2.Add(a2); f2.Add(p2); // Now, a unique assignment. This can't be lifted b.c. it is hidden behind a different if statement in // the outside (the filterUnique). var pSpecial = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var aUnique = new StatementAssign(pSpecial, new ValSimple("10", typeof(int))); f1.Add(aUnique); f1.Add(pSpecial); filterUnique.Add(f1); var topLevel1 = new StatementInlineBlock(); var topLevel2 = new StatementInlineBlock(); topLevel1.Add(filterUnique); topLevel2.Add(f2); Console.WriteLine("Before optimization (target):"); topLevel2.DumpCodeToConsole(); Console.WriteLine("Before optimization (merge):"); topLevel1.DumpCodeToConsole(); // The combine should fail. Assert.IsFalse(f2.TryCombineStatement(f1, null), "The two are different if statements, so it should have failed"); Console.WriteLine("After optimization (target):"); topLevel2.DumpCodeToConsole(); Console.WriteLine("After optimization (merge):"); topLevel1.DumpCodeToConsole(); // Nothing should have been touched in f1 - double check. Assert.AreEqual(2, f1.Statements.Count()); }
public void SingleStatementCodeWithNoBrackets() { StatementInlineBlock b = new StatementInlineBlock(blockShouldBeBraced: false); b.Add(new Statements.StatementSimpleStatement("Bork")); var r = b.CodeItUp().ToArray(); Assert.AreEqual(1, r.Length, "# of statements"); }
public void TestSimpleVariableCodingNoDecl() { // No statements - so there should be no declares. StatementInlineBlock b = new StatementInlineBlock(); b.Add(DeclarableParameter.CreateDeclarableParameterExpression(typeof(int))); var r = b.CodeItUp().ToArray(); Assert.AreEqual(0, r.Length, "# of statements"); }
public void TestAddBeforeParentNonNullParent() { var s = new StatementInlineBlock(); var s1 = new StatementSimpleStatement("one"); var s2 = new StatementSimpleStatement("two"); s1.Parent = s; s.Add(s2); s.AddBefore(s1, s2); }
public void TestAddBeforeParent() { var s = new StatementInlineBlock(); var s1 = new StatementSimpleStatement("one"); var s2 = new StatementSimpleStatement("two"); s.Add(s2); s.AddBefore(s1, s2); Assert.AreEqual(s, s1.Parent, "s1 parent"); Assert.AreEqual(s, s2.Parent, "s2 parent"); }
public void TestAddBefore() { var s = new StatementInlineBlock(); var s1 = new StatementSimpleStatement("one"); var s2 = new StatementSimpleStatement("two"); s.Add(s2); s.AddBefore(s1, s2); Assert.AreEqual(2, s.Statements.Count(), "# of statements"); Assert.AreEqual(s1, s.Statements.First(), "first statement"); Assert.AreEqual(s2, s.Statements.Skip(1).First(), "second statement"); }
/// <summary> /// Generate a function with no arguments that returns an int given that name. The /// actual statement is a very simple constant. /// </summary> /// <param name="fname"></param> /// <returns></returns> public static QMFuncSource GenerateFunction() { int[] ints = new int[10]; var qmb = new QueryModelBuilder(); qmb.AddClause(new MainFromClause("i", typeof(int), Expression.Constant(ints))); qmb.AddClause(new SelectClause(Expression.Constant(1))); qmb.AddResultOperator(new Remotion.Linq.Clauses.ResultOperators.CountResultOperator()); var h = new QMFuncHeader() { Arguments = new object[] { }, QM = qmb.Build() }; h.QMText = h.QM.ToString(); var f = new QMFuncSource(h); var p = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var st = new StatementAssign(p, new ValSimple("5", typeof(int))); var inlineblock = new StatementInlineBlock(); inlineblock.Add(st); inlineblock.Add(new StatementReturn(p)); f.SetCodeBody(inlineblock); return f; }
public void CombineWithMoveNonAndNotNonIdenticalStatements() { // Part of a fix for something found in the wild. When we move statements, with append turned off, and // move turned on, make sure the move occurs. var inline1 = new StatementInlineBlock(); var inline2 = new StatementInlineBlock(); var s1 = new StatementSimpleStatement("dude", true); var s11 = new StatementSimpleStatement("fork", true); inline1.Add(s1); inline1.Add(s11); var s2 = new StatementSimpleStatement("fork", true); inline2.Add(s2); Assert.IsFalse(inline2.Combine(new IStatement[] { s1, s11 }, inline1, appendIfCantCombine: false, moveIfIdentical: true), "Combine of two idential statements should go"); Assert.AreEqual(1, inline1.Statements.Count(), "All statements should have been removed from block 1"); Assert.AreEqual(1, inline2.Statements.Count(), "statements in inlien2"); }
public void TestSimpleCodeing() { StatementInlineBlock b = new StatementInlineBlock(); b.Add(new StatementSimpleStatement("junk;")); var r = b.CodeItUp().ToArray(); Assert.AreEqual(3, r.Length, "incorrect number of lines"); Assert.AreEqual("{", r[0], "open bracket"); Assert.AreEqual("}", r[2], "close bracket"); Assert.AreEqual(" junk;", r[1], "statement"); }
public void DeclarationsAreIgnoredDuringLowerLevelMove() { // In this new world of moving things around, we move declaration and statements, but they aren't really connected. // So we should make sure that declaration aren't moved accidentally when they shouldn't be. // Inline block at the top var topLevel1 = new StatementInlineBlock(); var topLevel2 = new StatementInlineBlock(); // Top level guy. This is the unique filter statement. var filterUnique = new StatementFilter(new ValSimple("fUnique", typeof(bool))); topLevel1.Add(filterUnique); // Next, we will do the two common ones. var f1 = new StatementFilter(new ValSimple("f1", typeof(bool))); var f2 = new StatementFilter(new ValSimple("f1", typeof(bool))); var p = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); topLevel1.Add(p); topLevel2.Add(p); var a1 = new StatementAssign(p, new ValSimple("5", typeof(int))); var a2 = new StatementAssign(p, new ValSimple("5", typeof(int))); f1.Add(a1); f2.Add(a2); filterUnique.Add(f1); topLevel2.Add(f2); Console.WriteLine("Before optimization (target):"); topLevel1.DumpCodeToConsole(); Console.WriteLine("After optimization (merge):"); topLevel2.DumpCodeToConsole(); Assert.IsFalse(f1.TryCombineStatement(f2, null), "Two of the same if statements, but the one to be merged is not hidden behind other if statements!"); Assert.AreEqual(1, f1.Statements.Count()); Assert.AreEqual(1, f2.Statements.Count()); }
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 TestLiftSimpleStatementInFunction() { var v = new StatementInlineBlock(); var loopP = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var loop = new StatementForLoop(loopP, new LINQToTTreeLib.Variables.ValSimple("10", typeof(int))); v.Add(loop); loop.Add(new StatementWithNoSideEffects()); var f = QMFunctions.QMFuncUtils.GenerateFunction(); f.SetCodeBody(v); var gc = new GeneratedCode(); gc.Add(new StatementSimpleStatement("int i = 10;")); gc.Add(f); StatementLifter.Optimize(gc); Assert.AreEqual(1, gc.Functions.Count(), "# of functions after lifting"); var firstStatement = gc.Functions.First().StatementBlock.Statements.First(); Assert.IsInstanceOfType(firstStatement, typeof(StatementWithNoSideEffects), "first statement"); }
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"); }
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 CombineFailsWhenNestedIsTarget() { // In this new world of moving things around, we move declaration and statements, but they aren't really connected. // So we should make sure that declaration aren't moved accidentally when they shouldn't be. // Inline block at the top var topLevel1 = new StatementInlineBlock(); var topLevel2 = new StatementInlineBlock(); // Top level guy. This is the unique filter statement. var filterUnique = new StatementFilter(new ValSimple("fUnique", typeof(bool))); topLevel1.Add(filterUnique); // Next, we will do the two common ones. var f1 = new StatementFilter(new ValSimple("f1", typeof(bool))); var f2 = new StatementFilter(new ValSimple("f1", typeof(bool))); var p1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var p2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); filterUnique.Add(p1); topLevel2.Add(p2); var a1 = new StatementAssign(p1, new ValSimple("5", typeof(int))); var a2 = new StatementAssign(p2, new ValSimple("5", typeof(int))); f1.Add(a1); f2.Add(a2); filterUnique.Add(f1); topLevel2.Add(f2); Console.WriteLine("Before optimization (target):"); topLevel1.DumpCodeToConsole(); Console.WriteLine("Before optimization (what is being merged):"); topLevel2.DumpCodeToConsole(); Assert.IsFalse(f1.TryCombineStatement(f2, null), "Two of the same if statements, and the combine should have worked"); Console.WriteLine("After optimization (target):"); topLevel1.DumpCodeToConsole(); Console.WriteLine("After optimization (merge):"); topLevel2.DumpCodeToConsole(); }
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 DeclaredVariablesLocalOnly() { var outter = new StatementInlineBlock(); outter.Add(DeclarableParameter.CreateDeclarableParameterExpression(typeof(int))); var s = new StatementForLoop(DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)), new ValSimple("5", typeof(int))); s.Add(DeclarableParameter.CreateDeclarableParameterExpression(typeof(int))); outter.Add(s); Assert.AreEqual(2, s.DeclaredVariables.Count()); Assert.AreEqual(3, s.AllDeclaredVariables.Count()); }