예제 #1
0
        public void Visit(WhenLiteralStatement statement)
        {
            CodeStatementCollection collection = new CodeStatementCollection();
            var arg = VisitChild(statement.Literal);

            var condition = new CodeConditionStatement();

            if (arg.Tag != null) //this is a null literal
            {
                condition.Condition = new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("var"), CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(null));
            }
            else
            {
                //always convert from object to type
                var leftArgs = new CodeDomArg()
                {
                    Scope = new ScopeData <Type> {
                        Type = typeof(object), CodeDomReference = new CodeTypeReference(typeof(object))
                    }, CodeExpression = new CodeVariableReferenceExpression("var")
                };
                var preCondition = new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("var"), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null));
                condition.Condition = new CodeBinaryOperatorExpression(preCondition, CodeBinaryOperatorType.BooleanAnd, DoBoolean(leftArgs, arg, CodeBinaryOperatorType.IdentityEquality));
            }

            var then = VisitChild(statement.Then);

            condition.TrueStatements.Add(new CodeMethodReturnStatement(then.CodeExpression));
            _codeStack.Peek().Tag = then.Tag;
            _codeStack.Peek().ParentStatements.Add(condition);
        }
        public void Visit(CaseVariableStatement statement)
        {
            var domArg = new CodeDomArg();

            CodeMemberMethod method = new CodeMemberMethod();
            method.Name = "Case_" + domArg.MethodIdentifier;
            method.Attributes = MemberAttributes.Private;
            method.ReturnType = new CodeTypeReference(typeof(object));
            GenerateCallStatement(method.Statements, statement.Line.Line);

            var caseArgs = VisitChild(statement.Case, new CodeDomArg() { Scope = _codeStack.Peek().Scope });
            if (caseArgs.Tag != null)
                _codeStack.Peek().Tag = caseArgs.Tag;

            method.Statements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference(typeof(object)), "var", caseArgs.CodeExpression));

            foreach (var childArg in statement.BooleanStatements)
            {
                domArg = VisitChild(childArg, new CodeDomArg() { Scope = _codeStack.Peek().Scope });
                if (domArg.Tag != null)
                    _codeStack.Peek().Tag = domArg.Tag;

                method.Statements.AddRange(domArg.ParentStatements);
            }

            if (statement.ElseStatement == null)
                method.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(null)));
            else
            {
                domArg = VisitChild(statement.ElseStatement, new CodeDomArg() { Scope = _codeStack.Peek().Scope });
                if (domArg.Tag != null)
                    _codeStack.Peek().Tag = domArg.Tag;

                method.Statements.Add(new CodeMethodReturnStatement(domArg.CodeExpression));
            }

            _mainType.Type.Members.Add(method);

            var methodcall = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(null, method.Name));
            var rowParam = new CodeParameterDeclarationExpression(_codeStack.Peek().Scope.CodeDomReference.TypeArguments[0], "row");
            method.Parameters.Add(rowParam);
            methodcall.Parameters.Add(new CodeVariableReferenceExpression("row"));

            if(_codeStack.Peek().Tag != null) //pick statement
            {
                var htmlNodeParam = new CodeParameterDeclarationExpression(new CodeTypeReference("HtmlNode"), "node");
                methodcall.Parameters.Add(new CodeVariableReferenceExpression("node"));
                method.Parameters.Add(htmlNodeParam);
            }

            _codeStack.Peek()
                  .ParentStatements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("result"),
                      "AddColumn",
                      new CodePrimitiveExpression("(No column name)")));

            _codeStack.Peek().CodeExpression = methodcall;
        }
        public void Visit(ProcedureCall call)
        {
            var domArg = new CodeDomArg();

            CodeMemberMethod method = new CodeMemberMethod();

            method.Name       = "Exec_" + domArg.MethodIdentifier;
            method.Attributes = MemberAttributes.Private;
            GenerateCallStatement(method.Statements, call.Line.Line);
            _mainType.Type.Members.Add(method);

            var methodStatements = new CodeStatementCollection();

            var argList = new List <CodeExpression>();

            foreach (var arg in call.Args)
            {
                domArg = VisitChild(arg);
                argList.Add(domArg.CodeExpression);
            }

            methodStatements.Add(
                new CodeVariableDeclarationStatement(call.Name, "r",
                                                     new CodeObjectCreateExpression(call.Name, argList.ToArray()))
                );

            methodStatements.Add(
                new CodeAssignStatement(
                    new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("r"), "RequestFactory"),
                    new CodePropertyReferenceExpression(null, "RequestFactory"))
                );


            var delegateGen = new CodeDelegateCreateExpression(new CodeTypeReference(typeof(Action <ProgressArgs>)),
                                                               new CodeThisReferenceExpression(), "OnProgress");

            methodStatements.Add(new CodeAttachEventStatement(new CodeVariableReferenceExpression("r"), "Progress", delegateGen));

            methodStatements.Add(
                new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("r"), "Run")
                );

            methodStatements.Add(new CodeRemoveEventStatement(new CodeVariableReferenceExpression("r"), "Progress", delegateGen));

            method.Statements.AddRange(methodStatements);

            var methodcall = new CodeMethodInvokeExpression(
                new CodeMethodReferenceExpression(null, method.Name));

            _codeStack.Peek().ParentStatements.Add(methodcall);
        }
예제 #4
0
        public void Visit(ProcedureCall call)
        {
            var domArg = new CodeDomArg();

            CodeMemberMethod method = new CodeMemberMethod();
            method.Name = "Exec_" + domArg.MethodIdentifier;
            method.Attributes = MemberAttributes.Private;
            GenerateCallStatement(method.Statements, call.Line.Line);
            _mainType.Type.Members.Add(method);

            var methodStatements = new CodeStatementCollection();

            var argList = new List<CodeExpression>();
            foreach(var arg in call.Args)
            {
                domArg = VisitChild(arg);
                argList.Add(domArg.CodeExpression);
            }

            methodStatements.Add(
                new CodeVariableDeclarationStatement(call.Name, "r",
                    new CodeObjectCreateExpression(call.Name, argList.ToArray()))
                    );

            methodStatements.Add(
            new CodeAssignStatement(
                new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("r"), "RequestFactory"),
                new CodePropertyReferenceExpression(null, "RequestFactory"))
                );

            var delegateGen = new CodeDelegateCreateExpression(new CodeTypeReference(typeof(Action<ProgressArgs>)),
                new CodeThisReferenceExpression(), "OnProgress");
            methodStatements.Add(new CodeAttachEventStatement(new CodeVariableReferenceExpression("r"), "Progress", delegateGen));

            methodStatements.Add(
                new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("r"), "Run")
            );

            methodStatements.Add(new CodeRemoveEventStatement(new CodeVariableReferenceExpression("r"), "Progress", delegateGen));

            method.Statements.AddRange(methodStatements);

            var methodcall = new CodeMethodInvokeExpression(
              new CodeMethodReferenceExpression(null, method.Name));
            _codeStack.Peek().ParentStatements.Add(methodcall);
        }
예제 #5
0
        private void GenerateNestedSelectOnly(string bufferVariable, IList <CodeAssignStatement> codeAssignments, SelectStatement statement)
        {
            var fromDomArg = new CodeDomArg();

            CodeMemberMethod method = new CodeMemberMethod();

            method.Name       = "Nested_Select_" + fromDomArg.MethodIdentifier;
            method.Attributes = MemberAttributes.Private;
            method.ReturnType = new CodeTypeReference("CodeTable", new CodeTypeReference(bufferVariable));
            GenerateCallStatement(method.Statements, statement.Line.Line);

            _mainType.Type.Members.Add(method);

            var methodStatements = new CodeStatementCollection();

            methodStatements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("CodeTable", new CodeTypeReference(bufferVariable)),
                                                                      "result",
                                                                      new CodeObjectCreateExpression(new CodeTypeReference("BufferTable", new CodeTypeReference(bufferVariable)))));

            methodStatements.Add(new CodeVariableDeclarationStatement(
                                     new CodeTypeReference(bufferVariable),
                                     "resultRow",
                                     new CodeObjectCreateExpression(new CodeTypeReference(bufferVariable))));

            var addResults = new CodeMethodInvokeExpression(
                new CodeMethodReferenceExpression(new CodeTypeReferenceExpression("result"), "Add"),
                new CodeArgumentReferenceExpression("resultRow"));

            methodStatements.AddRange(codeAssignments.ToArray());
            methodStatements.Add(addResults);

            methodStatements.Add(new CodeMethodReturnStatement(new CodeTypeReferenceExpression("result")));

            method.Statements.AddRange(methodStatements);

            var methodcall = new CodeMethodInvokeExpression(
                new CodeMethodReferenceExpression(null, method.Name));

            _codeStack.Peek().CodeExpression = methodcall;
            _codeStack.Peek().Scope          = new ScopeData <TableDescriptor>()
            {
                CodeDomReference = method.ReturnType
            };
        }
        private CodeExpression DoBoolean(CodeDomArg leftArgs, CodeDomArg rightArgs, CodeBinaryOperatorType operation)
        {
            Type leftType = null;

            if (leftArgs.Scope != null)
            {
                leftType = leftArgs.Scope.CodeDomReference.GenerateType();
            }

            Type rightType = null;

            if (rightArgs.Scope != null)
            {
                rightType = rightArgs.Scope.CodeDomReference.GenerateType();
            }

            if (leftType != null && rightType != null && leftType != rightType)
            {
                if (leftType == typeof(string) || leftType == typeof(object))
                {
                    var primitive = TablePrimitive.FromType(rightType);
                    leftArgs.CodeExpression = primitive.ToNative(leftArgs.CodeExpression);
                }
                else if (rightType == typeof(string))
                {
                    var primitive = TablePrimitive.FromType(leftType);
                    rightArgs.CodeExpression = primitive.ToNative(rightArgs.CodeExpression);
                }
            }

            if (leftArgs.Tag != null)
            {
                _codeStack.Peek().Tag = leftArgs.Tag;
            }
            if (rightArgs.Tag != null)
            {
                _codeStack.Peek().Tag = rightArgs.Tag;
            }

            return(new CodeBinaryOperatorExpression(leftArgs.CodeExpression, operation, rightArgs.CodeExpression));
        }
        public void Visit(CaseVariableStatement statement)
        {
            var domArg = new CodeDomArg();

            CodeMemberMethod method = new CodeMemberMethod();

            method.Name       = "Case_" + domArg.MethodIdentifier;
            method.Attributes = MemberAttributes.Private;
            method.ReturnType = new CodeTypeReference(typeof(object));
            GenerateCallStatement(method.Statements, statement.Line.Line);

            var caseArgs = VisitChild(statement.Case, new CodeDomArg()
            {
                Scope = _codeStack.Peek().Scope
            });

            if (caseArgs.Tag != null)
            {
                _codeStack.Peek().Tag = caseArgs.Tag;
            }

            method.Statements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference(typeof(object)), "var", caseArgs.CodeExpression));

            foreach (var childArg in statement.BooleanStatements)
            {
                domArg = VisitChild(childArg, new CodeDomArg()
                {
                    Scope = _codeStack.Peek().Scope
                });
                if (domArg.Tag != null)
                {
                    _codeStack.Peek().Tag = domArg.Tag;
                }

                method.Statements.AddRange(domArg.ParentStatements);
            }

            if (statement.ElseStatement == null)
            {
                method.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(null)));
            }
            else
            {
                domArg = VisitChild(statement.ElseStatement, new CodeDomArg()
                {
                    Scope = _codeStack.Peek().Scope
                });
                if (domArg.Tag != null)
                {
                    _codeStack.Peek().Tag = domArg.Tag;
                }

                method.Statements.Add(new CodeMethodReturnStatement(domArg.CodeExpression));
            }

            _mainType.Type.Members.Add(method);

            var methodcall = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(null, method.Name));
            var rowParam   = new CodeParameterDeclarationExpression(_codeStack.Peek().Scope.CodeDomReference.TypeArguments[0], "row");

            method.Parameters.Add(rowParam);
            methodcall.Parameters.Add(new CodeVariableReferenceExpression("row"));

            if (_codeStack.Peek().Tag != null) //pick statement
            {
                var htmlNodeParam = new CodeParameterDeclarationExpression(new CodeTypeReference("HtmlNode"), "node");
                methodcall.Parameters.Add(new CodeVariableReferenceExpression("node"));
                method.Parameters.Add(htmlNodeParam);
            }

            _codeStack.Peek()
            .ParentStatements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("result"),
                                                                 "AddColumn",
                                                                 new CodePrimitiveExpression("(No column name)")));

            _codeStack.Peek().CodeExpression = methodcall;
        }
        public void Visit(SelectStatement statement)
        {
            using (Scope.PushSelect())
            {
                if (statement.From == null)
                {
                    GenerateSelectOnly(statement);
                    return;
                }

                var fromDomArg = VisitChild(statement.From);
                var rowType    = fromDomArg.Scope.CodeDomReference.TypeArguments[0];

                CodeMemberMethod method = new CodeMemberMethod();
                method.Name       = "Select_" + fromDomArg.MethodIdentifier;
                method.Attributes = MemberAttributes.Private;
                method.ReturnType = new CodeTypeReference("Table", new CodeTypeReference("ResultRow"));
                GenerateCallStatement(method.Statements, statement.Line.Line);

                _mainType.Type.Members.Add(method);

                var methodStatements = new CodeStatementCollection();

                methodStatements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("RuntimeTable", new CodeTypeReference("ResultRow")),
                                                                          "result",
                                                                          new CodeObjectCreateExpression(new CodeTypeReference("RuntimeTable", new CodeTypeReference("ResultRow")))));


                var selectArgAssignments = new List <CodeAssignStatement>();
                if (statement.Args.Length > 0) //visit first one in case select *
                {
                    VisitChild(statement.Args[0], new CodeDomArg()
                    {
                        Scope = fromDomArg.Scope
                    });
                }

                var outerLoopNeeded = false;

                //Needed for both
                for (int x = 0; x < statement.Args.Length; x++) //select args
                {
                    var domSelectArg = VisitChild(statement.Args[x], new CodeDomArg()
                    {
                        Scope = fromDomArg.Scope
                    });
                    if (((SelectArgsInfo)domSelectArg.Tag).IsPickStatement)
                    {
                        outerLoopNeeded = true;
                    }

                    var assignment = new CodeAssignStatement();
                    assignment.Left  = new CodeIndexerExpression(new CodeTypeReferenceExpression("resultRow"), new CodeSnippetExpression(x.ToString()));
                    assignment.Right = domSelectArg.CodeExpression;

                    methodStatements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("result"), "AddColumn", new CodePrimitiveExpression(((SelectArgsInfo)domSelectArg.Tag).DisplayColumnName)));
                    selectArgAssignments.Add(assignment);
                }


                methodStatements.Add(new CodeVariableDeclarationStatement(fromDomArg.Scope.CodeDomReference,
                                                                          "fromTable",
                                                                          fromDomArg.CodeExpression));

                if (statement.Where != null)
                {
                    var domWhereArgs = VisitChild(statement.Where, new CodeDomArg()
                    {
                        Scope = fromDomArg.Scope
                    });
                    methodStatements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression("fromTable"), domWhereArgs.CodeExpression));
                }

                //outside iterator
                methodStatements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("IEnumerator", rowType),
                                                                          "x",
                                                                          new CodeMethodInvokeExpression(
                                                                              new CodeMethodReferenceExpression(new CodeTypeReferenceExpression("fromTable"), "GetEnumerator",
                                                                                                                null))));


                //foreach loops

                var outerLoop = new CodeIterationStatement();
                outerLoop.InitStatement      = new CodeSnippetStatement();
                outerLoop.IncrementStatement = new CodeSnippetStatement();
                outerLoop.TestExpression     = new CodeMethodInvokeExpression(
                    new CodeMethodReferenceExpression(new CodeTypeReferenceExpression("x"), "MoveNext",
                                                      null));

                outerLoop.Statements.Add(new CodeVariableDeclarationStatement(rowType,
                                                                              "row",
                                                                              new CodePropertyReferenceExpression(new CodeTypeReferenceExpression("x"), "Current")));

                var codeLoop = outerLoop;
                if (outerLoopNeeded)
                {
                    var        aliases = Scope.Current.AliasType <DownloadPage>();
                    CodeDomArg args    = null;
                    if (aliases.Length == 0)
                    {
                        //register error we could't find a download table and we are trying to access pick statements.
                        //create fake codedomargs
                        args = new CodeDomArg()
                        {
                            CodeExpression = new CodePrimitiveExpression("DownloadTable")
                        };
                    }
                    else
                    {
                        var reference = new TableMemberReference()
                        {
                            Member = "nodes", RowReference = new TableVariableRowReference()
                            {
                                Id = aliases[0]
                            }
                        };
                        args = VisitChild(reference);
                    }

                    //Needed only for DownloadRow
                    outerLoop.Statements.Add(
                        new CodeVariableDeclarationStatement(
                            new CodeTypeReference("IEnumerator", new CodeTypeReference("HtmlElement")),
                            "y",
                            new CodeMethodInvokeExpression(
                                new CodeMethodReferenceExpression(
                                    args.CodeExpression, "GetEnumerator", null))));


                    //Needed only for DownloadRow
                    codeLoop = new CodeIterationStatement();
                    codeLoop.InitStatement      = new CodeSnippetStatement();
                    codeLoop.IncrementStatement = new CodeSnippetStatement();
                    codeLoop.TestExpression     = new CodeMethodInvokeExpression(
                        new CodeMethodReferenceExpression(new CodeTypeReferenceExpression("y"), "MoveNext",
                                                          null));

                    //Needed only for DownloadRow
                    codeLoop.Statements.Add(new CodeVariableDeclarationStatement(
                                                new CodeTypeReference("HtmlElement"),
                                                "node",
                                                new CodePropertyReferenceExpression(new CodeTypeReferenceExpression("y"), "Current")));

                    outerLoop.Statements.Add(codeLoop);
                }

                //Needed for both.
                codeLoop.Statements.Add(new CodeVariableDeclarationStatement(
                                            new CodeTypeReference("ResultRow"),
                                            "resultRow",
                                            new CodeObjectCreateExpression(new CodeTypeReference("ResultRow"), new CodeSnippetExpression(statement.Args.Length.ToString()))));

                codeLoop.Statements.AddRange(selectArgAssignments.ToArray());

                var addResults = new CodeMethodInvokeExpression(
                    new CodeMethodReferenceExpression(new CodeTypeReferenceExpression("result"), "Add"),
                    new CodeArgumentReferenceExpression("resultRow"));
                codeLoop.Statements.Add(addResults);


                methodStatements.Add(outerLoop);

                if (outerLoopNeeded)
                {
                    var aliases = Scope.Current.AliasType <DownloadPage>();
                    outerLoop.Statements.Add(new CodeMethodInvokeExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("row"), aliases[0]), "Clear"));
                }

                var callSelect = new CodeExpressionStatement(new CodeMethodInvokeExpression(null, "OnSelect", new CodeVariableReferenceExpression("result")));
                methodStatements.Add(callSelect);
                methodStatements.Add(new CodeMethodReturnStatement(new CodeTypeReferenceExpression("result")));
                method.Statements.AddRange(methodStatements);

                var methodcall = new CodeMethodInvokeExpression(
                    new CodeMethodReferenceExpression(null, method.Name));

                _codeStack.Peek().Tag            = new Action(() => method.Statements.Remove(callSelect));
                _codeStack.Peek().CodeExpression = methodcall;
                _codeStack.Peek().Scope          = new ScopeData <TableDescriptor>()
                {
                    CodeDomReference = method.ReturnType
                };
                _codeStack.Peek().ParentStatements.Add(methodcall);
            }
        }
        private void GenerateSelectOnly(SelectStatement statement)
        {
            var fromDomArg = new CodeDomArg();

            CodeMemberMethod method = new CodeMemberMethod();

            method.Name       = "Select_" + fromDomArg.MethodIdentifier;
            method.Attributes = MemberAttributes.Private;
            method.ReturnType = new CodeTypeReference("Table", new CodeTypeReference("ResultRow"));
            GenerateCallStatement(method.Statements, statement.Line.Line);

            _mainType.Type.Members.Add(method);

            var methodStatements = new CodeStatementCollection();


            methodStatements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("RuntimeTable", new CodeTypeReference("ResultRow")),
                                                                      "result",
                                                                      new CodeObjectCreateExpression(new CodeTypeReference("RuntimeTable", new CodeTypeReference("ResultRow")))));


            methodStatements.Add(new CodeVariableDeclarationStatement(
                                     new CodeTypeReference("ResultRow"),
                                     "resultRow",
                                     new CodeObjectCreateExpression(new CodeTypeReference("ResultRow"), new CodeSnippetExpression(statement.Args.Length.ToString()))));


            var selectArgAssignments = new List <CodeAssignStatement>();

            for (int x = 0; x < statement.Args.Length; x++) //select args
            {
                var domSelectArg = VisitChild(statement.Args[x], new CodeDomArg()
                {
                    Scope = fromDomArg.Scope
                });

                var assignment = new CodeAssignStatement();
                assignment.Left  = new CodeIndexerExpression(new CodeTypeReferenceExpression("resultRow"), new CodeSnippetExpression(x.ToString()));
                assignment.Right = domSelectArg.CodeExpression;

                methodStatements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("result"), "AddColumn", new CodePrimitiveExpression(((SelectArgsInfo)domSelectArg.Tag).DisplayColumnName)));

                selectArgAssignments.Add(assignment);
            }

            var addResults = new CodeMethodInvokeExpression(
                new CodeMethodReferenceExpression(new CodeTypeReferenceExpression("result"), "Add"),
                new CodeArgumentReferenceExpression("resultRow"));

            methodStatements.AddRange(selectArgAssignments.ToArray());
            methodStatements.Add(addResults);
            var callSelect = new CodeExpressionStatement(new CodeMethodInvokeExpression(null, "OnSelect", new CodeVariableReferenceExpression("result")));

            methodStatements.Add(callSelect);
            methodStatements.Add(new CodeMethodReturnStatement(new CodeTypeReferenceExpression("result")));

            method.Statements.AddRange(methodStatements);

            var methodcall = new CodeMethodInvokeExpression(
                new CodeMethodReferenceExpression(null, method.Name));

            _codeStack.Peek().Tag            = new Action(() => method.Statements.Remove(callSelect));
            _codeStack.Peek().CodeExpression = methodcall;
            _codeStack.Peek().Scope          = new ScopeData <TableDescriptor>()
            {
                CodeDomReference = method.ReturnType
            };
            _codeStack.Peek().ParentStatements.Add(methodcall);
        }
예제 #10
0
 private CodeDomArg VisitChild(AstNode node, CodeDomArg arg)
 {
     _codeStack.Push(arg);
     node.Accept(this);
     return(_codeStack.Pop());
 }
 private CodeDomArg VisitChild(AstNode node, CodeDomArg arg)
 {
     _codeStack.Push(arg);
     node.Accept(this);
     return _codeStack.Pop();
 }
        public void Visit(SelectStatement statement)
        {
            using (Scope.PushSelect())
            {
                if (statement.From == null)
                {
                    GenerateSelectOnly(statement);
                    return;
                }

                var fromDomArg = VisitChild(statement.From);
                var rowType = fromDomArg.Scope.CodeDomReference.TypeArguments[0];

                CodeMemberMethod method = new CodeMemberMethod();
                method.Name = "Select_" + fromDomArg.MethodIdentifier;
                method.Attributes = MemberAttributes.Private;
                method.ReturnType = new CodeTypeReference("Table", new CodeTypeReference("ResultRow"));
                GenerateCallStatement(method.Statements, statement.Line.Line);

                _mainType.Type.Members.Add(method);

                var methodStatements = new CodeStatementCollection();

                methodStatements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("RuntimeTable", new CodeTypeReference("ResultRow")),
                    "result",
                    new CodeObjectCreateExpression(new CodeTypeReference("RuntimeTable", new CodeTypeReference("ResultRow")))));

                var selectArgAssignments = new List<CodeAssignStatement>();
                if (statement.Args.Length > 0) //visit first one in case select *
                    VisitChild(statement.Args[0], new CodeDomArg() { Scope = fromDomArg.Scope });

                var outerLoopNeeded = false;

                //Needed for both
                for (int x = 0; x < statement.Args.Length; x++) //select args
                {
                    var domSelectArg = VisitChild(statement.Args[x], new CodeDomArg() { Scope = fromDomArg.Scope });
                    if (domSelectArg.Tag != null)
                        outerLoopNeeded = true;

                    var assignment = new CodeAssignStatement();
                    assignment.Left = new CodeIndexerExpression(new CodeTypeReferenceExpression("resultRow"), new CodeSnippetExpression(x.ToString()));
                    assignment.Right = domSelectArg.CodeExpression;

                    methodStatements.AddRange(domSelectArg.ParentStatements);

                    selectArgAssignments.Add(assignment);
                }

                methodStatements.Add(new CodeVariableDeclarationStatement(fromDomArg.Scope.CodeDomReference,
                "fromTable",
                fromDomArg.CodeExpression));

                if (statement.Where != null)
                {
                    var domWhereArgs = VisitChild(statement.Where, new CodeDomArg() { Scope = fromDomArg.Scope });
                    methodStatements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression("fromTable"), domWhereArgs.CodeExpression));
                }

                //outside iterator
                methodStatements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("IEnumerator", rowType),
                    "x",
                new CodeMethodInvokeExpression(
                        new CodeMethodReferenceExpression(new CodeTypeReferenceExpression("fromTable"), "GetEnumerator",
                        null))));

                //foreach loops

                var outerLoop = new CodeIterationStatement();
                outerLoop.InitStatement = new CodeSnippetStatement();
                outerLoop.IncrementStatement = new CodeSnippetStatement();
                outerLoop.TestExpression = new CodeMethodInvokeExpression(
                    new CodeMethodReferenceExpression(new CodeTypeReferenceExpression("x"), "MoveNext",
                    null));

                outerLoop.Statements.Add(new CodeVariableDeclarationStatement(rowType,
                "row",
                new CodePropertyReferenceExpression(new CodeTypeReferenceExpression("x"), "Current")));

                var codeLoop = outerLoop;
                if (outerLoopNeeded)
                {
                    var aliases = Scope.Current.AliasType<DownloadPage>();
                    CodeDomArg args = null;
                    if (aliases.Length == 0)
                    {
                        //register error we could't find a download table and we are trying to access pick statements.
                        //create fake codedomargs
                        args = new CodeDomArg() { CodeExpression = new CodePrimitiveExpression("DownloadTable") };
                    }
                    else
                    {
                        var reference = new TableMemberReference() { Member = "nodes", RowReference = new TableVariableRowReference() { Id = aliases[0] } };
                        args = VisitChild(reference);
                    }

                    //Needed only for DownloadRow
                    outerLoop.Statements.Add(
                        new CodeVariableDeclarationStatement(
                            new CodeTypeReference("IEnumerator", new CodeTypeReference("HtmlNode")),
                            "y",
                            new CodeMethodInvokeExpression(
                                new CodeMethodReferenceExpression(
                                        args.CodeExpression, "GetEnumerator", null))));

                    //Needed only for DownloadRow
                    codeLoop = new CodeIterationStatement();
                    codeLoop.InitStatement = new CodeSnippetStatement();
                    codeLoop.IncrementStatement = new CodeSnippetStatement();
                    codeLoop.TestExpression = new CodeMethodInvokeExpression(
                        new CodeMethodReferenceExpression(new CodeTypeReferenceExpression("y"), "MoveNext",
                        null));

                    //Needed only for DownloadRow
                    codeLoop.Statements.Add(new CodeVariableDeclarationStatement(
                        new CodeTypeReference("HtmlNode"),
                        "node",
                        new CodePropertyReferenceExpression(new CodeTypeReferenceExpression("y"), "Current")));

                    outerLoop.Statements.Add(codeLoop);
                }

                //Needed for both.
                codeLoop.Statements.Add(new CodeVariableDeclarationStatement(
                    new CodeTypeReference("ResultRow"),
                    "resultRow",
                    new CodeObjectCreateExpression(new CodeTypeReference("ResultRow"), new CodeSnippetExpression(statement.Args.Length.ToString()))));

                codeLoop.Statements.AddRange(selectArgAssignments.ToArray());

                //need to check if all are not null
                if (selectArgAssignments.Count > 0)
                {
                    var binaryExpression = new CodeBinaryOperatorExpression(selectArgAssignments[0].Left, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null));
                    for (int x = 1; x < selectArgAssignments.Count; x++)
                    {
                        var booleanTest = new CodeBinaryOperatorExpression(selectArgAssignments[x].Left, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null));
                        binaryExpression = new CodeBinaryOperatorExpression(binaryExpression, CodeBinaryOperatorType.BooleanAnd, booleanTest);
                    }

                    var addResults = new CodeMethodInvokeExpression(
                        new CodeMethodReferenceExpression(new CodeTypeReferenceExpression("result"), "Add"),
                        new CodeArgumentReferenceExpression("resultRow"));

                    var ifCondition = new CodeConditionStatement(binaryExpression, new CodeExpressionStatement(addResults));
                    codeLoop.Statements.Add(ifCondition);
                }

                methodStatements.Add(outerLoop);

                if (outerLoopNeeded)
                    outerLoop.Statements.Add(new CodeMethodInvokeExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("row"), "DownloadPage"), "Clear"));

                var callSelect = new CodeExpressionStatement(new CodeMethodInvokeExpression(null, "OnSelect", new CodeVariableReferenceExpression("result")));
                methodStatements.Add(callSelect);
                methodStatements.Add(new CodeMethodReturnStatement(new CodeTypeReferenceExpression("result")));
                method.Statements.AddRange(methodStatements);

                var methodcall = new CodeMethodInvokeExpression(
                    new CodeMethodReferenceExpression(null, method.Name));

                _codeStack.Peek().Tag = new Action(() => method.Statements.Remove(callSelect));
                _codeStack.Peek().CodeExpression = methodcall;
                _codeStack.Peek().Scope = new ScopeData<TableDescriptor>() { CodeDomReference = method.ReturnType };
                _codeStack.Peek().ParentStatements.Add(methodcall);
            }
        }
        private void GenerateSelectOnly(SelectStatement statement)
        {
            var fromDomArg = new CodeDomArg();

            CodeMemberMethod method = new CodeMemberMethod();
            method.Name = "Select_" + fromDomArg.MethodIdentifier;
            method.Attributes = MemberAttributes.Private;
            method.ReturnType = new CodeTypeReference("Table", new CodeTypeReference("ResultRow"));
            GenerateCallStatement(method.Statements, statement.Line.Line);

            _mainType.Type.Members.Add(method);

            var methodStatements = new CodeStatementCollection();

            methodStatements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("RuntimeTable", new CodeTypeReference("ResultRow")),
                "result",
                new CodeObjectCreateExpression(new CodeTypeReference("RuntimeTable", new CodeTypeReference("ResultRow")))));

            methodStatements.Add(new CodeVariableDeclarationStatement(
               new CodeTypeReference("ResultRow"),
               "resultRow",
               new CodeObjectCreateExpression(new CodeTypeReference("ResultRow"), new CodeSnippetExpression(statement.Args.Length.ToString()))));

            var selectArgAssignments = new List<CodeAssignStatement>();
            for (int x = 0; x < statement.Args.Length; x++) //select args
            {
                var domSelectArg = VisitChild(statement.Args[x], new CodeDomArg() { Scope = fromDomArg.Scope });

                var assignment = new CodeAssignStatement();
                assignment.Left = new CodeIndexerExpression(new CodeTypeReferenceExpression("resultRow"), new CodeSnippetExpression(x.ToString()));
                assignment.Right = domSelectArg.CodeExpression;

                methodStatements.AddRange(domSelectArg.ParentStatements);

                selectArgAssignments.Add(assignment);
            }

            var addResults = new CodeMethodInvokeExpression(
                    new CodeMethodReferenceExpression(new CodeTypeReferenceExpression("result"), "Add"),
                    new CodeArgumentReferenceExpression("resultRow"));

            methodStatements.AddRange(selectArgAssignments.ToArray());
            methodStatements.Add(addResults);
            var callSelect = new CodeExpressionStatement(new CodeMethodInvokeExpression(null, "OnSelect", new CodeVariableReferenceExpression("result")));
            methodStatements.Add(callSelect);
            methodStatements.Add(new CodeMethodReturnStatement(new CodeTypeReferenceExpression("result")));

            method.Statements.AddRange(methodStatements);

            var methodcall = new CodeMethodInvokeExpression(
                new CodeMethodReferenceExpression(null, method.Name));

            _codeStack.Peek().Tag = new Action(() => method.Statements.Remove(callSelect));
            _codeStack.Peek().CodeExpression = methodcall;
            _codeStack.Peek().Scope = new ScopeData<TableDescriptor>() { CodeDomReference = method.ReturnType };
            _codeStack.Peek().ParentStatements.Add(methodcall);
        }
예제 #14
0
        public void Visit(NestedSelectStatement statement)
        {
            BufferTable      bufferTable;
            CodeMemberMethod method   = new CodeMemberMethod();
            var  methodStatements     = new CodeStatementCollection();
            var  selectArgAssignments = new List <CodeAssignStatement>();
            bool outerLoopNeeded;

            if (statement.From == null)
            {
                SelectOnly(statement);
                return;
            }

            using (Scope.PushSelect())
            {
                var fromDomArg = VisitChild(statement.From);
                var rowType    = fromDomArg.Scope.CodeDomReference.TypeArguments[0];

                method.Name       = "Nested_Select_" + fromDomArg.MethodIdentifier;
                method.Attributes = MemberAttributes.Private;
                GenerateCallStatement(method.Statements, statement.Line.Line);

                _mainType.Type.Members.Add(method);

                //create type
                bufferTable = FetchBufferTable(statement, fromDomArg.Scope, selectArgAssignments, out outerLoopNeeded);

                methodStatements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("CodeTable", new CodeTypeReference(bufferTable.Variable)),
                                                                          "result",
                                                                          new CodeObjectCreateExpression(new CodeTypeReference("BufferTable", new CodeTypeReference(bufferTable.Variable)))));

                methodStatements.Add(new CodeVariableDeclarationStatement(fromDomArg.Scope.CodeDomReference,
                                                                          "fromTable",
                                                                          fromDomArg.CodeExpression));

                if (statement.Where != null)
                {
                    var domWhereArgs = VisitChild(statement.Where, new CodeDomArg()
                    {
                        Scope = fromDomArg.Scope
                    });
                    methodStatements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression("fromTable"), domWhereArgs.CodeExpression));
                }

                //outside iterator
                methodStatements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("IEnumerator", rowType),
                                                                          "x",
                                                                          new CodeMethodInvokeExpression(
                                                                              new CodeMethodReferenceExpression(new CodeTypeReferenceExpression("fromTable"), "GetEnumerator",
                                                                                                                null))));


                //foreach loops

                var outerLoop = new CodeIterationStatement();
                outerLoop.InitStatement      = new CodeSnippetStatement();
                outerLoop.IncrementStatement = new CodeSnippetStatement();
                outerLoop.TestExpression     = new CodeMethodInvokeExpression(
                    new CodeMethodReferenceExpression(new CodeTypeReferenceExpression("x"), "MoveNext",
                                                      null));

                outerLoop.Statements.Add(new CodeVariableDeclarationStatement(rowType,
                                                                              "row",
                                                                              new CodePropertyReferenceExpression(new CodeTypeReferenceExpression("x"), "Current")));

                var codeLoop = outerLoop;
                if (outerLoopNeeded)
                {
                    var        aliases = Scope.Current.AliasType <DownloadPage>();
                    CodeDomArg args    = null;
                    if (aliases.Length == 0)
                    {
                        //register error we could't find a download table and we are trying to access pick statements.
                        //create fake codedomargs
                        args = new CodeDomArg()
                        {
                            CodeExpression = new CodePrimitiveExpression("DownloadTable")
                        };
                    }
                    else
                    {
                        var reference = new TableMemberReference()
                        {
                            Member = "nodes", RowReference = new TableVariableRowReference()
                            {
                                Id = aliases[0]
                            }
                        };
                        args = VisitChild(reference);
                    }

                    //Needed only for DownloadRow
                    outerLoop.Statements.Add(
                        new CodeVariableDeclarationStatement(
                            new CodeTypeReference("IEnumerator", new CodeTypeReference("HtmlElement")),
                            "y",
                            new CodeMethodInvokeExpression(
                                new CodeMethodReferenceExpression(
                                    args.CodeExpression, "GetEnumerator", null))));


                    //Needed only for DownloadRow
                    codeLoop = new CodeIterationStatement();
                    codeLoop.InitStatement      = new CodeSnippetStatement();
                    codeLoop.IncrementStatement = new CodeSnippetStatement();
                    codeLoop.TestExpression     = new CodeMethodInvokeExpression(
                        new CodeMethodReferenceExpression(new CodeTypeReferenceExpression("y"), "MoveNext",
                                                          null));

                    //Needed only for DownloadRow
                    codeLoop.Statements.Add(new CodeVariableDeclarationStatement(
                                                new CodeTypeReference("HtmlElement"),
                                                "node",
                                                new CodePropertyReferenceExpression(new CodeTypeReferenceExpression("y"), "Current")));

                    outerLoop.Statements.Add(codeLoop);
                }

                //Needed for both.
                codeLoop.Statements.Add(new CodeVariableDeclarationStatement(
                                            new CodeTypeReference(bufferTable.Variable),
                                            "resultRow",
                                            new CodeObjectCreateExpression(new CodeTypeReference(bufferTable.Variable))));

                codeLoop.Statements.AddRange(selectArgAssignments.ToArray());

                var addResults = new CodeMethodInvokeExpression(
                    new CodeMethodReferenceExpression(new CodeTypeReferenceExpression("result"), "Add"),
                    new CodeArgumentReferenceExpression("resultRow"));
                codeLoop.Statements.Add(addResults);


                methodStatements.Add(outerLoop);

                if (outerLoopNeeded)
                {
                    var aliases = Scope.Current.AliasType <DownloadPage>();
                    outerLoop.Statements.Add(new CodeMethodInvokeExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("row"), aliases[0]), "Clear"));
                }
            }

            var scope = CreateBufferTable(bufferTable);

            method.ReturnType = scope.CodeDomReference;
            var methodcall = new CodeMethodInvokeExpression(
                new CodeMethodReferenceExpression(null, method.Name));

            methodStatements.Add(new CodeMethodReturnStatement(new CodeTypeReferenceExpression("result")));
            method.Statements.AddRange(methodStatements);

            _codeStack.Peek().CodeExpression = methodcall;
            _codeStack.Peek().Scope          = new ScopeData <TableDescriptor>()
            {
                CodeDomReference = method.ReturnType
            };
        }