compile.js 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. 'use strict';
  2. const fill = require('fill-range');
  3. const utils = require('./utils');
  4. const compile = (ast, options = {}) => {
  5. const walk = (node, parent = {}) => {
  6. const invalidBlock = utils.isInvalidBrace(parent);
  7. const invalidNode = node.invalid === true && options.escapeInvalid === true;
  8. const invalid = invalidBlock === true || invalidNode === true;
  9. const prefix = options.escapeInvalid === true ? '\\' : '';
  10. let output = '';
  11. if (node.isOpen === true) {
  12. return prefix + node.value;
  13. }
  14. if (node.isClose === true) {
  15. console.log('node.isClose', prefix, node.value);
  16. return prefix + node.value;
  17. }
  18. if (node.type === 'open') {
  19. return invalid ? prefix + node.value : '(';
  20. }
  21. if (node.type === 'close') {
  22. return invalid ? prefix + node.value : ')';
  23. }
  24. if (node.type === 'comma') {
  25. return node.prev.type === 'comma' ? '' : invalid ? node.value : '|';
  26. }
  27. if (node.value) {
  28. return node.value;
  29. }
  30. if (node.nodes && node.ranges > 0) {
  31. const args = utils.reduce(node.nodes);
  32. const range = fill(...args, { ...options, wrap: false, toRegex: true, strictZeros: true });
  33. if (range.length !== 0) {
  34. return args.length > 1 && range.length > 1 ? `(${range})` : range;
  35. }
  36. }
  37. if (node.nodes) {
  38. for (const child of node.nodes) {
  39. output += walk(child, node);
  40. }
  41. }
  42. return output;
  43. };
  44. return walk(ast);
  45. };
  46. module.exports = compile;