TypeMatchExpression.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. "use strict";
  2. var MatchExpression = require('./MatchExpression');
  3. var ElementPath = require('./ElementPath');
  4. var TypeMatchExpression = module.exports = function TypeMatchExpression() {
  5. base.call(this, 'TYPE_OPERATOR');
  6. this._elementPath = new ElementPath();
  7. }, klass = TypeMatchExpression, base = MatchExpression, proto = klass.prototype = Object.create(base.prototype, {constructor: {value: klass}});
  8. proto._elementPath = undefined;
  9. proto._path = undefined;
  10. proto._type = undefined;
  11. /**
  12. * Initialize the current object.
  13. *
  14. * @param path
  15. * @param type
  16. * @returns {*}
  17. */
  18. proto.init = function init(path, type) {
  19. this._path = path;
  20. this._type = type;
  21. return this._elementPath.init(path);
  22. };
  23. /**
  24. *
  25. * Returns a shallow copy of the instance.
  26. *
  27. * @returns {TypeMatchExpression}
  28. */
  29. proto.shallowClone = function shallowClone(){
  30. var clone = new TypeMatchExpression();
  31. clone.init(this._path, this._type);
  32. if (this.getTag()) {
  33. clone.setTag(this.getTag().clone());
  34. }
  35. return clone;
  36. };
  37. /**
  38. * Used number reference to types like the C++ enum (?).
  39. *
  40. * @param e
  41. * @returns {number}
  42. */
  43. klass.type = function type(e) {
  44. if(e === undefined) {
  45. return 6;
  46. } else if (e === null) {
  47. return 10;
  48. }
  49. switch (typeof e) {
  50. case 'number':
  51. return 1;
  52. case 'string':
  53. return 2;
  54. case 'boolean':
  55. return 8;
  56. case 'object':
  57. if (e instanceof Array) {
  58. return 4;
  59. } else if (e instanceof RegExp) {
  60. return 11;
  61. } else if (e instanceof Date) {
  62. return 9;
  63. } else if (e.constructor.name === 'MinKey') {
  64. return -1;
  65. } else if (e.constructor.name === 'MaxKey') {
  66. return 127;
  67. }
  68. }
  69. return 42;
  70. };
  71. /**
  72. * Matches single element.
  73. *
  74. * @param e
  75. * @returns {boolean}
  76. */
  77. proto.matchesSingleElement = function matchesSingleElement(e) {
  78. return klass.type(e) === this._type;
  79. };
  80. /**
  81. * Matches against the document.
  82. *
  83. * @param doc
  84. * @param details
  85. * @returns {*}
  86. */
  87. proto.matches = function matches(doc, details) {
  88. var self = this,
  89. matcher = function matcher(element) {
  90. if (!self.matchesSingleElement(element, details)) {
  91. return false;
  92. }
  93. return true;
  94. };
  95. return this._elementPath._matches(doc, details, matcher);
  96. };
  97. /**
  98. * Writes a debug string for this object.
  99. *
  100. * @param level
  101. * @returns {string}
  102. */
  103. proto.debugString = function debugString(level) {
  104. var rtn = this._debugAddSpace(level) + this.path() + ' type: ' + this._type;
  105. if (this.getTag()) {
  106. rtn += ' ' + this.getTag().debugString();
  107. }
  108. return rtn + '\n';
  109. };
  110. /**
  111. * Checks to see if the other instance is equivalent to the current instance.
  112. *
  113. * @param other
  114. * @returns {boolean}
  115. */
  116. proto.equivalent = function equivalent(other) {
  117. if (this.matchType() !== other.matchType()) {
  118. return false;
  119. }
  120. return (this._path === other._path && this._type === other._type);
  121. };
  122. /**
  123. * Return the type we're matching against.
  124. *
  125. * @returns {undefined|*}
  126. */
  127. proto.getData = function getData() {
  128. return this._type;
  129. };
  130. /**
  131. * Return the path associated with the current object.
  132. *
  133. * @returns {undefined|*|klass._path}
  134. */
  135. proto.path = function path() {
  136. return this._path;
  137. };