/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

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