trace.cjs 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. 'use strict';
  2. function getTrace(node) {
  3. function shouldPutToTrace(syntax) {
  4. if (syntax === null) {
  5. return false;
  6. }
  7. return (
  8. syntax.type === 'Type' ||
  9. syntax.type === 'Property' ||
  10. syntax.type === 'Keyword'
  11. );
  12. }
  13. function hasMatch(matchNode) {
  14. if (Array.isArray(matchNode.match)) {
  15. // use for-loop for better perfomance
  16. for (let i = 0; i < matchNode.match.length; i++) {
  17. if (hasMatch(matchNode.match[i])) {
  18. if (shouldPutToTrace(matchNode.syntax)) {
  19. result.unshift(matchNode.syntax);
  20. }
  21. return true;
  22. }
  23. }
  24. } else if (matchNode.node === node) {
  25. result = shouldPutToTrace(matchNode.syntax)
  26. ? [matchNode.syntax]
  27. : [];
  28. return true;
  29. }
  30. return false;
  31. }
  32. let result = null;
  33. if (this.matched !== null) {
  34. hasMatch(this.matched);
  35. }
  36. return result;
  37. }
  38. function isType(node, type) {
  39. return testNode(this, node, match => match.type === 'Type' && match.name === type);
  40. }
  41. function isProperty(node, property) {
  42. return testNode(this, node, match => match.type === 'Property' && match.name === property);
  43. }
  44. function isKeyword(node) {
  45. return testNode(this, node, match => match.type === 'Keyword');
  46. }
  47. function testNode(match, node, fn) {
  48. const trace = getTrace.call(match, node);
  49. if (trace === null) {
  50. return false;
  51. }
  52. return trace.some(fn);
  53. }
  54. exports.getTrace = getTrace;
  55. exports.isKeyword = isKeyword;
  56. exports.isProperty = isProperty;
  57. exports.isType = isType;