/src/Otis/CodeGen/DefaultAggregateFunctionCodeGenerator.cs

http://otis-lib.googlecode.com/ · C# · 81 lines · 65 code · 16 blank · 0 comment · 7 complexity · f5ce46866986b1a6dd2c53ad432071e3 MD5 · raw file

  1. using System;
  2. using System.CodeDom;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. using Otis.Parsing;
  6. namespace Otis.CodeGen
  7. {
  8. public class DefaultAggregateFunctionCodeGenerator : IAggregateFunctionCodeGenerator
  9. {
  10. virtual public IEnumerable<CodeStatement> GetInitializationStatements(AggregateFunctionContext context)
  11. {
  12. CodeExpression[] parameters = new CodeExpression[0];
  13. CodeStatement st = new CodeVariableDeclarationStatement(context.ImplementationType, context.FunctionObjectName,
  14. new CodeObjectCreateExpression(context.ImplementationType, parameters));
  15. return new CodeStatement[] {st};
  16. }
  17. virtual public IEnumerable<string> GetIterationStatements(AggregateFunctionContext context, IList<AggregateExpressionPathItem> pathItems)
  18. {
  19. AggregateExpressionPathItem lastPathItem = pathItems[pathItems.Count - 1];
  20. string finalTarget = "";
  21. foreach (AggregateExpressionPathItem pathItem in pathItems)
  22. if (pathItem.IsCollection)
  23. finalTarget = pathItem.Object;
  24. string finalExpression = context.Member.AggregateMappingDescription.FinalExpression;
  25. string processedExpression = "";
  26. if ((string.IsNullOrEmpty(finalExpression) || lastPathItem.IsCollection))
  27. processedExpression = finalTarget;
  28. else
  29. processedExpression = string.Format("{0}.{1}", finalTarget, finalExpression);
  30. string fullFormat = GetFormatForExecutedExpression(context);
  31. fullFormat = fullFormat.Replace("FN_OBJ", "{0}");
  32. fullFormat = fullFormat.Replace("CURR_ITEM", "{1}");
  33. return new string[] { string.Format(fullFormat, context.FunctionObjectName, processedExpression) };
  34. }
  35. protected virtual string GetFormatForExecutedExpression(AggregateFunctionContext context)
  36. {
  37. string processedExpressionFormat = GetProcessedExpressionFormat(context);
  38. return "{0}.ProcessValue(" + processedExpressionFormat + ")";
  39. }
  40. virtual public CodeStatement GetAssignmentStatement(AggregateFunctionContext context)
  41. {
  42. string resultExpression = context.FunctionObjectName + ".Result";
  43. if (context.Member.HasFormatting)
  44. resultExpression = string.Format("string.Format(\"{0}\", {1}.Result)", context.Member.Format, context.FunctionObjectName);
  45. return new CodeAssignStatement(
  46. new CodeVariableReferenceExpression("target." + context.Member.Member),
  47. new CodeArgumentReferenceExpression(resultExpression));
  48. }
  49. private string GetProcessedExpressionFormat(AggregateFunctionContext context)
  50. {
  51. IExpressionFormatProvider fmtProvider = context.Generator as IExpressionFormatProvider;
  52. if (fmtProvider == null)
  53. {
  54. Type realImplementationType = context.ImplementationType.IsGenericTypeDefinition ?
  55. context.ImplementationType.MakeGenericType(typeof (int)) :
  56. context.ImplementationType;
  57. fmtProvider = (IExpressionFormatProvider) Activator.CreateInstance(realImplementationType, true);
  58. }
  59. if (string.IsNullOrEmpty(fmtProvider.ExpressionFormat))
  60. return "{1}";
  61. else
  62. return fmtProvider.ExpressionFormat;
  63. }
  64. }
  65. }