예제 #1
0
        public void TestResultScopeCurrentScope()
        {
            var gc = new GeneratedCode();
            var b1 = new StatementInlineBlock();

            gc.Add(b1);
            gc.SetCurrentScopeAsResultScope();
            var outterScope = gc.CurrentScope;

            var b2 = new StatementInlineBlock();

            gc.Add(b2);
            gc.SetCurrentScopeAsResultScope();

            gc.AddAtResultScope(DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)));

            Assert.AreEqual(0, b1.DeclaredVariables.Count(), "variables at outside loop after 0 add");
            Assert.AreEqual(1, b2.DeclaredVariables.Count(), "variables at inner loop after 1 add");

            gc.CurrentScope = outterScope;

            gc.AddAtResultScope(DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)));

            Assert.AreEqual(1, b1.DeclaredVariables.Count(), "variables at outside loop after 1 add");
            Assert.AreEqual(1, b2.DeclaredVariables.Count(), "variables at inner loop after 2 add");
        }
예제 #2
0
        public void TestChangeScopeSpecificNextLevel()
        {
            GeneratedCode target = new GeneratedCode();

            target.Add(new StatementInlineBlock());
            IStatement s = new StatementInlineBlock();

            var deepestStatementLevel = TestUtils.GetDeepestStatementLevel(target);
            var deepestDeclarLevel    = TestUtils.GetDeepestBookingLevel(target);

            var currentS = target.CurrentScope;

            var curVars       = deepestDeclarLevel.DeclaredVariables.Count();
            var curStatements = deepestStatementLevel.Statements.Count();
            var v1            = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));

            target.Add(v1);
            target.Add(s);

            target.CurrentScope = currentS;

            var v2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));

            target.Add(v2);
            s.Parent = null;
            target.Add(s);
            Assert.AreEqual(curStatements + 2, deepestStatementLevel.Statements.Count(), "Scope reset, should always be two extra statements here!");
            Assert.AreEqual(curVars + 2, deepestDeclarLevel.DeclaredVariables.Count(), "Scope reset should have also reset where the variable was pointing");
        }
예제 #3
0
        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");
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
        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");
        }
예제 #6
0
        public void TestObjectInitalizerInInnerBlock()
        {
            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);
            innerBlock.Add(new StatementSimpleStatement("fork = dork"));
            code.Add(innerBlock);

            var r = TranslateGeneratedCode(target, code);

            var st = (r["QueryFunctionBlocks"] as IEnumerable <IEnumerable <string> >).First().ToArray();

            Assert.AreEqual(6, st.Length, "incorrect number of statements");
            Assert.AreEqual("int " + vInt2.RawValue + " = 5;", st[2].Trim(), "incorrect initialization");
        }
예제 #7
0
        public void TestResultScopeNull()
        {
            var gc = new GeneratedCode();
            var b  = new StatementInlineBlock();

            gc.Add(b);
            gc.AddAtResultScope(DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)));
        }
예제 #8
0
 public GeneratedCode(bool blockShouldBeBraced = true)
 {
     CodeBody                        = new StatementInlineBlock(blockShouldBeBraced: blockShouldBeBraced);
     CurrentScopePointer             = CodeBody;
     CurrentDeclarationScopePointer  = CodeBody;
     PreviousDeclarationScopePointer = null;
     Depth = 1;
 }
예제 #9
0
 public IEnumerable <IStatementCompound> QueryCode()
 {
     for (int i = 0; i < 300; i++)
     {
         var innerBlock = new StatementInlineBlock();
         var vInt2      = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));
         vInt2.SetInitialValue("5");
         innerBlock.Add(vInt2);
         yield return(innerBlock);
     }
 }
예제 #10
0
        public void CheckDepthAndPopWorkTogether()
        {
            var target = new GeneratedCode();
            var s1     = new StatementInlineBlock();

            target.Add(s1);
            var s2 = new StatementInlineBlock();

            target.Add(s2);
            Assert.AreEqual(3, target.Depth);
            target.Pop();
            Assert.AreEqual(2, target.Depth);
        }
예제 #11
0
        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());
        }
예제 #12
0
        public void TestResultScopePop()
        {
            var gc = new GeneratedCode();
            var b1 = new StatementInlineBlock();

            gc.Add(b1);

            var b2 = new StatementInlineBlock();

            gc.Add(b2);
            gc.SetCurrentScopeAsResultScope();

            gc.AddAtResultScope(DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)));

            // This pop should remove the result scope, and it should be back to "null" now, which
            // should cause an exception.

            gc.Pop();
            gc.AddAtResultScope(DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)));
        }
예제 #13
0
        public void CheckPopAndCurrentScopeWorkTogether()
        {
            GeneratedCode target = new GeneratedCode();
            IStatement    s1     = new StatementInlineBlock();

            target.Add(s1);
            var depth = target.Depth;
            var s2    = new StatementInlineBlock();

            target.Add(s2);
            var firstTwoDown = target.CurrentScope;

            var s3 = new StatementInlineBlock();

            target.Add(s3);

            target.CurrentScope = firstTwoDown;
            // This pop should put us at the s1 level.
            target.Pop();
            Assert.AreEqual(depth, target.Depth);
        }
예제 #14
0
        private QMFuncSource[] GenerateFunction2()
        {
            var fsub = QMFuncUtils.GenerateFunction();

            int[] ints = new int[10];
            var   h    = new QMFuncHeader()
            {
                Arguments = new object[] { }, QM = new QueryModel(new MainFromClause("i", typeof(int), Expression.Constant(ints)), new SelectClause(Expression.Constant(10)))
            };

            h.QMText = h.QM.ToString();
            var f = new QMFuncSource(h);

            var p           = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));
            var st          = new StatementAssign(p, new ValSimple(fsub.Name + "()", typeof(int)));
            var inlineblock = new StatementInlineBlock();

            inlineblock.Add(st);
            inlineblock.Add(new StatementReturn(p));
            f.SetCodeBody(inlineblock);

            return(new QMFuncSource[] { fsub, f });
        }
        /// <summary>Test stub for ProcessResultOperator(ResultOperatorBase, QueryModel, IGeneratedCode)</summary>
        internal GeneratedCode ProcessResultOperator(
            ROTakeSkipOperators target,
            ResultOperatorBase resultOperator,
            QueryModel queryModel,
            GeneratedCode codeEnv
            )
        {
            if (codeEnv.ResultValue != null)
            {
                throw new ArgumentException("this should not be null for this test");
            }
            if (codeEnv.CodeBody.DeclaredVariables == null)
            {
                throw new ArgumentException("Need this declare variables to be defined");
            }

            ///
            /// We always expect to be inside a loop - and depend on it for doing our declares, so add something...
            ///

            var inlineBlock = new StatementInlineBlock();

            codeEnv.Add(inlineBlock);

            ///
            /// Get the environment setup and run it
            ///

            CodeContext c = new CodeContext();

            c.SetLoopVariable(Expression.Variable(typeof(int), "d"), null);

            target.ProcessResultOperator(resultOperator, queryModel, codeEnv, c, MEFUtilities.MEFContainer);

            codeEnv.DumpCodeToConsole();

            ///
            /// First, there should be a counter now declared and ready to go in the current variable block - which will
            /// be the outer one for this test. If this is the outter most, then this is going to be burried.
            ///

            var declBlock = inlineBlock.Parent.Parent as IBookingStatementBlock;

            Assert.IsNotNull(declBlock, "Expecting a declaration block above!");

            Assert.AreEqual(1, inlineBlock.Statements.Count(), "Expected an if block/increment!");
            Assert.IsInstanceOfType(inlineBlock.Statements.First(), typeof(StatementIfOnCount), "if statement not found!");

            var s = inlineBlock.Statements.First() as StatementIfOnCount;

            bool isTopLevel = codeEnv.DumpCode().Where(l => l.Contains("static int")).Any();

            if (!isTopLevel)
            {
                Assert.AreEqual(1, declBlock.DeclaredVariables.Count(), "Expected only 1 variable to be declared");
                Assert.IsInstanceOfType(declBlock.DeclaredVariables.First(), typeof(DeclarableParameter), "Expected it to be a counter");
            }
            else
            {
                Assert.AreEqual(1, (s.Parent as IBookingStatementBlock).DeclaredVariables.Count());
            }

            string count = "";

            if (resultOperator is SkipResultOperator)
            {
                count = (resultOperator as SkipResultOperator).Count.ToString();
            }
            else if (resultOperator is TakeResultOperator)
            {
                count = (resultOperator as TakeResultOperator).Count.ToString();
            }
            Assert.AreEqual(count, s.Limit.RawValue, "bad count made it through");

            ///
            /// Finally, the current loop variable should be identical, and there should be no result set.
            ///

            Assert.IsNull(codeEnv.ResultValue, "result value");
            Assert.IsInstanceOfType(c.LoopVariable, typeof(ParameterExpression), "loop variable type");
            var lv = c.LoopVariable as ParameterExpression;

            Assert.AreEqual("d", lv.Name, "loop variable name");

            //
            // Dump everything and return. To force it out, add a dummy statement
            // (because if statements, etc., are smart enough to not print anything if they
            // are empty).
            //

            codeEnv.Add(new StatementSimpleStatement("fork = left"));
            codeEnv.DumpCodeToConsole();

            return(codeEnv);
        }
예제 #16
0
        /// <summary>
        /// Cache the result of a query model into a function.
        /// </summary>
        /// <param name="queryModel"></param>
        /// <param name="qmSource"></param>
        private void VisitQueryModelCache(QueryModel queryModel, IQMFunctionSource qmSource)
        {
            // If we already have the answer for this cache, then we should just re-call the routine.
            if (qmSource.StatementBlock != null)
            {
                Debug.WriteLine("Using previously cached QM result");
                GenerateQMFunctionCall(qmSource);
                return;
            }
            Debug.WriteLine("Cache: Gathering Data");
            Debug.Indent();

            // Since we don't have it cached, we need to re-run things, and carefully watch for
            // everything new that shows up. What shows up will be what we declare as the function
            // body.
            var currentScope      = _codeEnv.CurrentScope;
            var topLevelStatement = new StatementInlineBlock();

            _codeEnv.Add(topLevelStatement);
            _codeEnv.SetCurrentScopeAsResultScope();

            // If this variable has been cached, then return it. Otherwise, mark the cache as filled.
            _codeEnv.Add(new StatementFilter(qmSource.CacheVariableGood));
            _codeEnv.Add(new StatementReturn(qmSource.CacheVariable));
            _codeEnv.Pop();
            _codeEnv.Add(new StatementAssign(qmSource.CacheVariableGood, new ValSimple("true", typeof(bool), null)));

            // Now, run the code to process the query model!

            VisitQueryModelNoCache(queryModel);

            // The result is treated differently depending on it being a sequence or a single value.
            if (qmSource.IsSequence)
            {
                // Push the good values into our cache object.
                if (!(_codeContext.LoopIndexVariable is IDeclaredParameter))
                {
                    throw new InvalidOperationException("Can't deal with anythign that isn't a loop var");
                }
                _codeEnv.Add(new StatementRecordIndicies(ExpressionToCPP.GetExpression(_codeContext.LoopVariable, _codeEnv, _codeContext, MEFContainer), qmSource.CacheVariable));

                // Remember what the loop index variable is, as we are going to need it when we generate the return function!
                qmSource.SequenceVariable(_codeContext.LoopIndexVariable, _codeContext.LoopVariable);
            }
            else
            {
                // This is a specific result. Save just the result and return it.
                // Grab the result, cache it, and return it.
                var rtnExpr = ExpressionToCPP.GetExpression(_codeEnv.ResultValue, _codeEnv, _codeContext, MEFContainer);
                topLevelStatement.Add(new StatementAssign(qmSource.CacheVariable, rtnExpr));

                // If the return is a declared parameter, then it must be actually defined somewhere (we normally don't).
                var declParam = _codeEnv.ResultValue as IDeclaredParameter;
                if (declParam != null)
                {
                    topLevelStatement.Add(declParam, false);
                }
            }

            // Always return the proper value...
            topLevelStatement.Add(new StatementReturn(qmSource.CacheVariable));

            // Now extract the block of code and put it in the function block.
            _codeEnv.CurrentScope = currentScope;
            qmSource.SetCodeBody(topLevelStatement);

            // Reset our state and remove the function code. And put in the function call in its place.
            _codeEnv.Remove(topLevelStatement);
            GenerateQMFunctionCall(qmSource);

            Debug.Unindent();
        }