trace.js 1.6 KB

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