LetExpression.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. "use strict";
  2. var LetExpression = module.exports = function LetExpression(vars, subExpression){
  3. if (arguments.length !== 2) throw new Error("Two args expected");
  4. this._variables = vars;
  5. this._subExpression = subExpression;
  6. }, klass = LetExpression, Expression = require("./Expression"), base = Expression, proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
  7. // DEPENDENCIES
  8. var Variables = require("./Variables"),
  9. VariablesParseState = require("./VariablesParseState");
  10. // PROTOTYPE MEMBERS
  11. proto.parse = function parse(expr, vpsIn){
  12. if(!("$let" in expr)) {
  13. throw new Error("Tried to create a $let with something other than let. Looks like your parse map went all funny.");
  14. }
  15. if(typeof(expr.$let) !== 'object' || (expr.$let instanceof Array)) {
  16. throw new Error("$let only supports an object as it's argument:16874");
  17. }
  18. var args = expr.$let,
  19. varsElem = args.vars,
  20. inElem = args['in'];
  21. if(!varsElem) {
  22. throw new Error("Missing 'vars' parameter to $let: 16876");
  23. }
  24. if(!inElem) {
  25. throw new Error("Missing 'in' parameter to $let: 16877");
  26. }
  27. if(Object.keys(args).length > 2) {
  28. var bogus = Object.keys(args).filter(function(x) {return !(x === 'in' || x === 'vars');});
  29. throw new Error("Unrecognized parameter to $let: " + bogus.join(",") + "- 16875");
  30. }
  31. var vpsSub = new VariablesParseState(vpsIn),
  32. vars = {};
  33. for(var varName in varsElem) {
  34. Variables.uassertValidNameForUserWrite(varName);
  35. var id = vpsSub.defineVariable(varName);
  36. vars[id] = {};
  37. vars[id][varName] = Expression.parseOperand(varsElem, vpsIn);
  38. }
  39. var subExpression = Expression.parseOperand(inElem, vpsSub);
  40. return new LetExpression(vars, subExpression);
  41. };
  42. proto.optimize = function optimize() {
  43. if(this._variables.empty()) {
  44. return this._subExpression.optimize();
  45. }
  46. for(var id in this._variables){
  47. for(var name in this._variables[id]) {
  48. this._variables[id][name] = this._variables[id][name].optimize();
  49. }
  50. }
  51. this._subExpression = this._subExpression.optimize();
  52. return this;
  53. };
  54. proto.addDependencies = function addDependencies(deps, path){
  55. for(var id in this._variables) {
  56. for(var name in this._variables[id]) {
  57. this._variables[id][name].addDependencies(deps);
  58. }
  59. }
  60. this._subExpression.addDependencies(deps, path);
  61. return deps;
  62. };
  63. proto.evaluateInternal = function evaluateInternal(vars) {
  64. for(var id in this._variables) {
  65. for(var name in this._variables[id]) {
  66. vars.setValue(id, this._variables[id][name]);
  67. }
  68. }
  69. return this._subExpression.evaluateInternal(vars);
  70. };
  71. proto.serialize = function serialize(explain) {
  72. var vars = {};
  73. for(var id in this._variables) {
  74. for(var name in this._variables[id]) {
  75. vars[name] = this._variables[id][name];
  76. }
  77. }
  78. return {$let: {vars:vars, 'in':this._subExpression.serialize(explain)}};
  79. };
  80. Expression.registerExpression("$let", LetExpression.parse);