|
@@ -13,12 +13,27 @@
|
|
|
* @module mungedb-aggregate
|
|
* @module mungedb-aggregate
|
|
|
* @constructor
|
|
* @constructor
|
|
|
**/
|
|
**/
|
|
|
-var Expression = module.exports = function Expression(){
|
|
|
|
|
- if (arguments.length !== 0) throw new Error("zero args expected");
|
|
|
|
|
-}, klass = Expression, base = Object, proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
|
|
|
|
|
|
|
+var Expression = module.exports = function Expression() {
|
|
|
|
|
+ if (arguments.length !== 0) throw new Error("zero args expected");
|
|
|
|
|
+}, klass = Expression,
|
|
|
|
|
+ base = Object,
|
|
|
|
|
+ proto = klass.prototype = Object.create(base.prototype, {
|
|
|
|
|
+ constructor: {
|
|
|
|
|
+ value: klass
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
// DEPENDENCIES
|
|
// DEPENDENCIES
|
|
|
var Document = require("../Document");
|
|
var Document = require("../Document");
|
|
|
|
|
+var ObjectExpression;
|
|
|
|
|
+var FieldPathExpression;
|
|
|
|
|
+var ConstantExpression;
|
|
|
|
|
+var kinds;
|
|
|
|
|
+
|
|
|
|
|
+function fn(){
|
|
|
|
|
+ return;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
|
|
|
// NESTED CLASSES
|
|
// NESTED CLASSES
|
|
|
/**
|
|
/**
|
|
@@ -26,49 +41,54 @@ var Document = require("../Document");
|
|
|
* @static
|
|
* @static
|
|
|
* @property ObjectCtx
|
|
* @property ObjectCtx
|
|
|
**/
|
|
**/
|
|
|
-var ObjectCtx = Expression.ObjectCtx = (function(){
|
|
|
|
|
- // CONSTRUCTOR
|
|
|
|
|
- /**
|
|
|
|
|
- * Utility class for parseObject() below. isDocumentOk indicates that it is OK to use a Document in the current context.
|
|
|
|
|
- *
|
|
|
|
|
- * NOTE: deviation from Mongo code: accepts an `Object` of settings rather than a bitmask to help simplify the interface a little bit
|
|
|
|
|
- *
|
|
|
|
|
- * @class ObjectCtx
|
|
|
|
|
- * @namespace mungedb-aggregate.pipeline.expressions.Expression
|
|
|
|
|
- * @module mungedb-aggregate
|
|
|
|
|
- * @constructor
|
|
|
|
|
- * @param opts
|
|
|
|
|
- * @param [opts.isDocumentOk] {Boolean}
|
|
|
|
|
- * @param [opts.isTopLevel] {Boolean}
|
|
|
|
|
- * @param [opts.isInclusionOk] {Boolean}
|
|
|
|
|
- **/
|
|
|
|
|
- var klass = function ObjectCtx(opts /*= {isDocumentOk:..., isTopLevel:..., isInclusionOk:...}*/){
|
|
|
|
|
- if(!(opts instanceof Object && opts.constructor == Object)) throw new Error("opts is required and must be an Object containing named args");
|
|
|
|
|
- for (var k in opts) { // assign all given opts to self so long as they were part of klass.prototype as undefined properties
|
|
|
|
|
- if (opts.hasOwnProperty(k) && proto.hasOwnProperty(k) && proto[k] === undefined) this[k] = opts[k];
|
|
|
|
|
- }
|
|
|
|
|
- }, base = Object, proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
|
|
|
|
|
|
|
+var ObjectCtx = Expression.ObjectCtx = (function() {
|
|
|
|
|
+ // CONSTRUCTOR
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Utility class for parseObject() below. isDocumentOk indicates that it is OK to use a Document in the current context.
|
|
|
|
|
+ *
|
|
|
|
|
+ * NOTE: deviation from Mongo code: accepts an `Object` of settings rather than a bitmask to help simplify the interface a little bit
|
|
|
|
|
+ *
|
|
|
|
|
+ * @class ObjectCtx
|
|
|
|
|
+ * @namespace mungedb-aggregate.pipeline.expressions.Expression
|
|
|
|
|
+ * @module mungedb-aggregate
|
|
|
|
|
+ * @constructor
|
|
|
|
|
+ * @param opts
|
|
|
|
|
+ * @param [opts.isDocumentOk] {Boolean}
|
|
|
|
|
+ * @param [opts.isTopLevel] {Boolean}
|
|
|
|
|
+ * @param [opts.isInclusionOk] {Boolean}
|
|
|
|
|
+ **/
|
|
|
|
|
+ var klass = function ObjectCtx(opts /*= {isDocumentOk:..., isTopLevel:..., isInclusionOk:...}*/ ) {
|
|
|
|
|
+ if (!(opts instanceof Object && opts.constructor == Object)) throw new Error("opts is required and must be an Object containing named args");
|
|
|
|
|
+ for (var k in opts) { // assign all given opts to self so long as they were part of klass.prototype as undefined properties
|
|
|
|
|
+ if (opts.hasOwnProperty(k) && proto.hasOwnProperty(k) && proto[k] === undefined) this[k] = opts[k];
|
|
|
|
|
+ }
|
|
|
|
|
+ }, base = Object,
|
|
|
|
|
+ proto = klass.prototype = Object.create(base.prototype, {
|
|
|
|
|
+ constructor: {
|
|
|
|
|
+ value: klass
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
- // PROTOTYPE MEMBERS
|
|
|
|
|
- proto.isDocumentOk =
|
|
|
|
|
- proto.isTopLevel =
|
|
|
|
|
- proto.isInclusionOk = undefined;
|
|
|
|
|
|
|
+ // PROTOTYPE MEMBERS
|
|
|
|
|
+ proto.isDocumentOk =
|
|
|
|
|
+ proto.isTopLevel =
|
|
|
|
|
+ proto.isInclusionOk = undefined;
|
|
|
|
|
|
|
|
- return klass;
|
|
|
|
|
|
|
+ return klass;
|
|
|
})();
|
|
})();
|
|
|
|
|
|
|
|
-proto.removeFieldPrefix = function removeFieldPrefix( prefixedField ) {
|
|
|
|
|
- if(prefixedField.indexOf("\0") !== -1 ) {
|
|
|
|
|
- // field path must not contain embedded null characters - 16419
|
|
|
|
|
- }
|
|
|
|
|
- if(prefixedField[0] !== '$') {
|
|
|
|
|
- // "field path references must be prefixed with a '$'"
|
|
|
|
|
- }
|
|
|
|
|
- return prefixedField.slice(1);
|
|
|
|
|
|
|
+proto.removeFieldPrefix = function removeFieldPrefix(prefixedField) {
|
|
|
|
|
+ if (prefixedField.indexOf("\0") !== -1) {
|
|
|
|
|
+ // field path must not contain embedded null characters - 16419
|
|
|
|
|
+ }
|
|
|
|
|
+ if (prefixedField[0] !== '$') {
|
|
|
|
|
+ // "field path references must be prefixed with a '$'"
|
|
|
|
|
+ }
|
|
|
|
|
+ return prefixedField.slice(1);
|
|
|
};
|
|
};
|
|
|
var KIND_UNKNOWN = 0,
|
|
var KIND_UNKNOWN = 0,
|
|
|
- KIND_NOTOPERATOR = 1,
|
|
|
|
|
- KIND_OPERATOR = 2;
|
|
|
|
|
|
|
+ KIND_NOTOPERATOR = 1,
|
|
|
|
|
+ KIND_OPERATOR = 2;
|
|
|
/**
|
|
/**
|
|
|
* Parse an Object. The object could represent a functional expression or a Document expression.
|
|
* Parse an Object. The object could represent a functional expression or a Document expression.
|
|
|
*
|
|
*
|
|
@@ -83,84 +103,84 @@ var KIND_UNKNOWN = 0,
|
|
|
* @param ctx a MiniCtx representing the options above
|
|
* @param ctx a MiniCtx representing the options above
|
|
|
* @returns the parsed Expression
|
|
* @returns the parsed Expression
|
|
|
**/
|
|
**/
|
|
|
-klass.parseObject = function parseObject(obj, ctx, vps){
|
|
|
|
|
- if(!(ctx instanceof ObjectCtx)) throw new Error("ctx must be ObjectCtx");
|
|
|
|
|
- var kind = KIND_UNKNOWN,
|
|
|
|
|
- pExpression, // the result
|
|
|
|
|
- pExpressionObject; // the alt result
|
|
|
|
|
- if (obj === undefined || obj == {}) return new ObjectExpression();
|
|
|
|
|
- var fieldNames = Object.keys(obj);
|
|
|
|
|
- if(fieldNames.length === 0) { //NOTE: Added this for mongo 2.5 port of document sources. Should reconsider when porting the expressions themselves
|
|
|
|
|
- return new ObjectExpression();
|
|
|
|
|
- }
|
|
|
|
|
- for (var fieldCount = 0, n = fieldNames.length; fieldCount < n; ++fieldCount) {
|
|
|
|
|
- var pFieldName = fieldNames[fieldCount];
|
|
|
|
|
-
|
|
|
|
|
- if (pFieldName[0] === "$") {
|
|
|
|
|
- if (fieldCount !== 0)
|
|
|
|
|
- throw new Error("the operator must be the only field in a pipeline object (at '" + pFieldName + "'.; code 16410");
|
|
|
|
|
|
|
+klass.parseObject = function parseObject(obj, ctx, vps) {
|
|
|
|
|
+ if (!(ctx instanceof ObjectCtx)) throw new Error("ctx must be ObjectCtx");
|
|
|
|
|
+ var kind = KIND_UNKNOWN,
|
|
|
|
|
+ pExpression, // the result
|
|
|
|
|
+ pExpressionObject; // the alt result
|
|
|
|
|
+ if (obj === undefined || obj == {}) return new ObjectExpression();
|
|
|
|
|
+ var fieldNames = Object.keys(obj);
|
|
|
|
|
+ if (fieldNames.length === 0) { //NOTE: Added this for mongo 2.5 port of document sources. Should reconsider when porting the expressions themselves
|
|
|
|
|
+ return new ObjectExpression();
|
|
|
|
|
+ }
|
|
|
|
|
+ for (var fieldCount = 0, n = fieldNames.length; fieldCount < n; ++fieldCount) {
|
|
|
|
|
+ var pFieldName = fieldNames[fieldCount];
|
|
|
|
|
|
|
|
- if(ctx.isTopLevel)
|
|
|
|
|
- throw new Error("$expressions are not allowed at the top-level of $project; code 16404");
|
|
|
|
|
- kind = KIND_OPERATOR; //we've determined this "object" is an operator expression
|
|
|
|
|
- pExpression = Expression.parseExpression(pFieldName, obj[pFieldName], vps);
|
|
|
|
|
- } else {
|
|
|
|
|
- if (kind === KIND_OPERATOR)
|
|
|
|
|
- throw new Error("this object is already an operator expression, and can't be used as a document expression (at '" + pFieldName + "'.; code 15990");
|
|
|
|
|
|
|
+ if (pFieldName[0] === "$") {
|
|
|
|
|
+ if (fieldCount !== 0)
|
|
|
|
|
+ throw new Error("the operator must be the only field in a pipeline object (at '" + pFieldName + "'.; code 16410");
|
|
|
|
|
|
|
|
- if (!ctx.isTopLevel && pFieldName.indexOf(".") != -1)
|
|
|
|
|
- throw new Error("dotted field names are only allowed at the top level; code 16405");
|
|
|
|
|
- if (pExpression === undefined) { // if it's our first time, create the document expression
|
|
|
|
|
- if (!ctx.isDocumentOk)
|
|
|
|
|
- throw new Error("document not allowed in this context"); // CW TODO error: document not allowed in this context
|
|
|
|
|
- pExpression = pExpressionObject = new ObjectExpression(); //check for top level?
|
|
|
|
|
- kind = kinds.NOT_OPERATOR; //this "object" is not an operator expression
|
|
|
|
|
- }
|
|
|
|
|
- var fieldValue = obj[pFieldName];
|
|
|
|
|
- switch (typeof(fieldValue)) {
|
|
|
|
|
- case "object":
|
|
|
|
|
- // it's a nested document
|
|
|
|
|
- var subCtx = new ObjectCtx({
|
|
|
|
|
- isDocumentOk: ctx.isDocumentOk,
|
|
|
|
|
- isInclusionOk: ctx.isInclusionOk
|
|
|
|
|
- });
|
|
|
|
|
- pExpressionObject.addField(pFieldName, Expression.parseObject(fieldValue, subCtx, vps));
|
|
|
|
|
- break;
|
|
|
|
|
- case "string":
|
|
|
|
|
- // it's a renamed field // CW TODO could also be a constant
|
|
|
|
|
- var pathExpr = new FieldPathExpression.parse(fieldValue);
|
|
|
|
|
- pExpressionObject.addField(pFieldName, pathExpr);
|
|
|
|
|
- break;
|
|
|
|
|
- case "boolean":
|
|
|
|
|
- case "number":
|
|
|
|
|
- // it's an inclusion specification
|
|
|
|
|
- if (fieldValue) {
|
|
|
|
|
- if (!ctx.isInclusionOk)
|
|
|
|
|
- throw new Error("field inclusion is not allowed inside of $expressions; code 16420");
|
|
|
|
|
- pExpressionObject.includePath(pFieldName);
|
|
|
|
|
|
|
+ if (ctx.isTopLevel)
|
|
|
|
|
+ throw new Error("$expressions are not allowed at the top-level of $project; code 16404");
|
|
|
|
|
+ kind = KIND_OPERATOR; //we've determined this "object" is an operator expression
|
|
|
|
|
+ pExpression = Expression.parseExpression(pFieldName, obj[pFieldName], vps);
|
|
|
} else {
|
|
} else {
|
|
|
- if (!(ctx.isTopLevel && fn == Document.ID_PROPERTY_NAME))
|
|
|
|
|
- throw new Error("The top-level " + Document.ID_PROPERTY_NAME + " field is the only field currently supported for exclusion; code 16406");
|
|
|
|
|
- pExpressionObject.excludeId = true;
|
|
|
|
|
|
|
+ if (kind === KIND_OPERATOR)
|
|
|
|
|
+ throw new Error("this object is already an operator expression, and can't be used as a document expression (at '" + pFieldName + "'.; code 15990");
|
|
|
|
|
+
|
|
|
|
|
+ if (!ctx.isTopLevel && pFieldName.indexOf(".") != -1)
|
|
|
|
|
+ throw new Error("dotted field names are only allowed at the top level; code 16405");
|
|
|
|
|
+ if (pExpression === undefined) { // if it's our first time, create the document expression
|
|
|
|
|
+ if (!ctx.isDocumentOk)
|
|
|
|
|
+ throw new Error("document not allowed in this context"); // CW TODO error: document not allowed in this context
|
|
|
|
|
+ pExpression = pExpressionObject = new ObjectExpression(); //check for top level?
|
|
|
|
|
+ kind = kinds.NOT_OPERATOR; //this "object" is not an operator expression
|
|
|
|
|
+ }
|
|
|
|
|
+ var fieldValue = obj[pFieldName];
|
|
|
|
|
+ switch (typeof(fieldValue)) {
|
|
|
|
|
+ case "object":
|
|
|
|
|
+ // it's a nested document
|
|
|
|
|
+ var subCtx = new ObjectCtx({
|
|
|
|
|
+ isDocumentOk: ctx.isDocumentOk,
|
|
|
|
|
+ isInclusionOk: ctx.isInclusionOk
|
|
|
|
|
+ });
|
|
|
|
|
+ pExpressionObject.addField(pFieldName, Expression.parseObject(fieldValue, subCtx, vps));
|
|
|
|
|
+ break;
|
|
|
|
|
+ case "string":
|
|
|
|
|
+ // it's a renamed field // CW TODO could also be a constant
|
|
|
|
|
+ var pathExpr = new FieldPathExpression.parse(fieldValue);
|
|
|
|
|
+ pExpressionObject.addField(pFieldName, pathExpr);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case "boolean":
|
|
|
|
|
+ case "number":
|
|
|
|
|
+ // it's an inclusion specification
|
|
|
|
|
+ if (fieldValue) {
|
|
|
|
|
+ if (!ctx.isInclusionOk)
|
|
|
|
|
+ throw new Error("field inclusion is not allowed inside of $expressions; code 16420");
|
|
|
|
|
+ pExpressionObject.includePath(pFieldName);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (!(ctx.isTopLevel && fn == Document.ID_PROPERTY_NAME))
|
|
|
|
|
+ throw new Error("The top-level " + Document.ID_PROPERTY_NAME + " field is the only field currently supported for exclusion; code 16406");
|
|
|
|
|
+ pExpressionObject.excludeId = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ default:
|
|
|
|
|
+ throw new Error("disallowed field type " + (fieldValue ? fieldValue.constructor.name + ":" : "") + typeof(fieldValue) + " in object expression (at '" + pFieldName + "')");
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- break;
|
|
|
|
|
- default:
|
|
|
|
|
- throw new Error("disallowed field type " + (fieldValue ? fieldValue.constructor.name + ":" : "") + typeof(fieldValue) + " in object expression (at '" + pFieldName + "')");
|
|
|
|
|
- }
|
|
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- return pExpression;
|
|
|
|
|
|
|
+ return pExpression;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
klass.expressionParserMap = {};
|
|
klass.expressionParserMap = {};
|
|
|
|
|
|
|
|
klass.registerExpression = function registerExpression(key, parserFunc) {
|
|
klass.registerExpression = function registerExpression(key, parserFunc) {
|
|
|
- if( key in klass.expressionParserMap ) {
|
|
|
|
|
- throw new Error("Duplicate expression registrarion for " + key);
|
|
|
|
|
- }
|
|
|
|
|
- klass.expressionParserMap[key] = parserFunc;
|
|
|
|
|
- return 0; // Should
|
|
|
|
|
|
|
+ if (key in klass.expressionParserMap) {
|
|
|
|
|
+ throw new Error("Duplicate expression registrarion for " + key);
|
|
|
|
|
+ }
|
|
|
|
|
+ klass.expressionParserMap[key] = parserFunc;
|
|
|
|
|
+ return 0; // Should
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -173,10 +193,10 @@ klass.registerExpression = function registerExpression(key, parserFunc) {
|
|
|
* @returns the parsed Expression
|
|
* @returns the parsed Expression
|
|
|
**/
|
|
**/
|
|
|
klass.parseExpression = function parseExpression(exprKey, exprValue, vps) {
|
|
klass.parseExpression = function parseExpression(exprKey, exprValue, vps) {
|
|
|
- if( !(exprKey in Expression.expressionParserMap) ) {
|
|
|
|
|
- throw new Error("Invalid operator : " + exprKey);
|
|
|
|
|
- }
|
|
|
|
|
- return Expression.expressionParserMap[exprKey](exprValue, vps);
|
|
|
|
|
|
|
+ if (!(exprKey in Expression.expressionParserMap)) {
|
|
|
|
|
+ throw new Error("Invalid operator : " + exprKey);
|
|
|
|
|
+ }
|
|
|
|
|
+ return Expression.expressionParserMap[exprKey](exprValue, vps);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -186,15 +206,16 @@ klass.parseExpression = function parseExpression(exprKey, exprValue, vps) {
|
|
|
* @param pBsonElement the expected operand's BSONElement
|
|
* @param pBsonElement the expected operand's BSONElement
|
|
|
* @returns the parsed operand, as an Expression
|
|
* @returns the parsed operand, as an Expression
|
|
|
**/
|
|
**/
|
|
|
-klass.parseOperand = function parseOperand(exprElement, vps){
|
|
|
|
|
- var t = typeof(exprElement);
|
|
|
|
|
- if (t === "string" && exprElement[0] == "$") { //if we got here, this is a field path expression
|
|
|
|
|
- return new FieldPathExpression.parse(exprElement, vps);
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- if (t === "object" && exprElement && exprElement.constructor === Object)
|
|
|
|
|
- return Expression.parseObject(exprElement, new ObjectCtx({isDocumentOk: true}), vps);
|
|
|
|
|
- else return ConstantExpression.parse(exprElement, vps);
|
|
|
|
|
|
|
+klass.parseOperand = function parseOperand(exprElement, vps) {
|
|
|
|
|
+ var t = typeof(exprElement);
|
|
|
|
|
+ if (t === "string" && exprElement[0] == "$") { //if we got here, this is a field path expression
|
|
|
|
|
+ return new FieldPathExpression.parse(exprElement, vps);
|
|
|
|
|
+ } else
|
|
|
|
|
+ if (t === "object" && exprElement && exprElement.constructor === Object)
|
|
|
|
|
+ return Expression.parseObject(exprElement, new ObjectCtx({
|
|
|
|
|
+ isDocumentOk: true
|
|
|
|
|
+ }), vps);
|
|
|
|
|
+ else return ConstantExpression.parse(exprElement, vps);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -206,9 +227,9 @@ klass.parseOperand = function parseOperand(exprElement, vps){
|
|
|
* @returns the field path with the prefix removed
|
|
* @returns the field path with the prefix removed
|
|
|
**/
|
|
**/
|
|
|
klass.removeFieldPrefix = function removeFieldPrefix(prefixedField) {
|
|
klass.removeFieldPrefix = function removeFieldPrefix(prefixedField) {
|
|
|
- if (prefixedField.indexOf("\0") != -1) throw new Error("field path must not contain embedded null characters; code 16419");
|
|
|
|
|
- if (prefixedField[0] !== "$") throw new Error("field path references must be prefixed with a '$' ('" + prefixedField + "'); code 15982");
|
|
|
|
|
- return prefixedField.substr(1);
|
|
|
|
|
|
|
+ if (prefixedField.indexOf("\0") != -1) throw new Error("field path must not contain embedded null characters; code 16419");
|
|
|
|
|
+ if (prefixedField[0] !== "$") throw new Error("field path references must be prefixed with a '$' ('" + prefixedField + "'); code 15982");
|
|
|
|
|
+ return prefixedField.substr(1);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
@@ -220,7 +241,7 @@ klass.removeFieldPrefix = function removeFieldPrefix(prefixedField) {
|
|
|
* @returns the computed value
|
|
* @returns the computed value
|
|
|
**/
|
|
**/
|
|
|
proto.evaluate = function evaluate(obj) {
|
|
proto.evaluate = function evaluate(obj) {
|
|
|
- throw new Error("WAS NOT IMPLEMENTED BY INHERITOR!");
|
|
|
|
|
|
|
+ throw new Error("WAS NOT IMPLEMENTED BY INHERITOR!");
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -237,7 +258,7 @@ proto.evaluate = function evaluate(obj) {
|
|
|
* @returns the optimized Expression
|
|
* @returns the optimized Expression
|
|
|
**/
|
|
**/
|
|
|
proto.optimize = function optimize() {
|
|
proto.optimize = function optimize() {
|
|
|
- throw new Error("WAS NOT IMPLEMENTED BY INHERITOR!");
|
|
|
|
|
|
|
+ throw new Error("WAS NOT IMPLEMENTED BY INHERITOR!");
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -251,7 +272,7 @@ proto.optimize = function optimize() {
|
|
|
* @param path path to self if all ancestors are ExpressionObjects.
|
|
* @param path path to self if all ancestors are ExpressionObjects.
|
|
|
**/
|
|
**/
|
|
|
proto.addDependencies = function addDependencies(deps, path) {
|
|
proto.addDependencies = function addDependencies(deps, path) {
|
|
|
- throw new Error("WAS NOT IMPLEMENTED BY INHERITOR!");
|
|
|
|
|
|
|
+ throw new Error("WAS NOT IMPLEMENTED BY INHERITOR!");
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -259,9 +280,9 @@ proto.addDependencies = function addDependencies(deps, path) {
|
|
|
* @method getIsSimple
|
|
* @method getIsSimple
|
|
|
**/
|
|
**/
|
|
|
proto.getIsSimple = function getIsSimple() {
|
|
proto.getIsSimple = function getIsSimple() {
|
|
|
- return false;
|
|
|
|
|
|
|
+ return false;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-proto.toMatcherBson = function toMatcherBson(){
|
|
|
|
|
- throw new Error("WAS NOT IMPLEMENTED BY INHERITOR!"); //verify(false && "Expression::toMatcherBson()");
|
|
|
|
|
-};
|
|
|
|
|
|
|
+proto.toMatcherBson = function toMatcherBson() {
|
|
|
|
|
+ throw new Error("WAS NOT IMPLEMENTED BY INHERITOR!"); //verify(false && "Expression::toMatcherBson()");
|
|
|
|
|
+};
|