PageRenderTime 23ms CodeModel.GetById 18ms app.highlight 2ms RepoModel.GetById 1ms app.codeStats 0ms

/Rhino.Etl.Dsl/Macros/JoinSectionMacro.cs

http://github.com/ayende/rhino-etl
C# | 80 lines | 59 code | 10 blank | 11 comment | 9 complexity | 856ef485c9cfada3283425e3f69406c4 MD5 | raw file
 1using System.Collections.Generic;
 2
 3namespace Rhino.Etl.Dsl.Macros
 4{
 5    using Boo.Lang.Compiler;
 6    using Boo.Lang.Compiler.Ast;
 7
 8    /// <summary>
 9    /// A part of a join
10    /// </summary>
11    public abstract class JoinSectionMacro : AbstractChildMacro
12    {
13        private readonly string name;
14
15        /// <summary>
16        /// Initializes a new instance of the <see cref="JoinSectionMacro"/> class.
17        /// </summary>
18        public JoinSectionMacro(string name)
19            : base("join", "leftjoin", "rightjoin", "innerjoin", "fulljoin")
20        {
21            this.name = name;
22        }
23
24        /// <summary>
25        /// Perform the actual expansion of the macro
26        /// </summary>
27        /// <param name="macro">The macro.</param>
28        /// <returns></returns>
29        protected override Statement DoExpand(MacroStatement macro)
30        {
31            Block body = (Block)macro.GetAncestor(NodeType.Block);
32            MacroStatement macroParent = (MacroStatement)macro.GetAncestor(NodeType.MacroStatement);
33           
34            if (macro.Body.Statements.Count < 1 && parent.Name=="join")
35            {
36                Errors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, "Join " + name + " section must contain at least a single expression statement"));
37                return null;
38            }
39
40            if (macro.Arguments.Count == 0 && parent.Name!="join")
41            {
42                Errors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, "Join " + name + " section must contain at least one key column"));
43                return null;
44            }
45
46            if (macro.Arguments.Count > 0)
47            {
48                ArrayLiteralExpression ale = new ArrayLiteralExpression(macro.LexicalInfo);
49                ale.Type = new ArrayTypeReference(CodeBuilder.CreateTypeReference(typeof(string)));
50                foreach (Expression argument in macro.Arguments)
51                {
52                    ReferenceExpression expr = argument as ReferenceExpression;
53                    if (expr == null)
54                    {
55                        Errors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo,"Join " + name +" section arguments must be reference expressions. Example: " + name + " name, surname"));
56                        return null;
57                    }
58                    ale.Items.Add(new StringLiteralExpression(expr.Name));
59                }
60                var keyExpr = new BinaryExpression(BinaryOperatorType.Assign, new ReferenceExpression(name+"KeyColumns"), ale);
61                macroParent.Arguments.Add(keyExpr);
62            }
63
64            foreach (Statement statement in macro.Body.Statements)
65            {
66                ExpressionStatement exprStmt = statement as ExpressionStatement;
67                if(exprStmt==null)
68                {
69                    Errors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, "Join " + name + " section can only contain expressions"));
70                    return null;
71                }
72                Expression expr = exprStmt.Expression;
73                parent.Arguments.Add(new MethodInvocationExpression(new ReferenceExpression(name), expr));
74            }
75
76            return null;
77            
78        }
79    }
80}