Projekt

Obecné

Profil

Stáhnout (3.1 KB) Statistiky
| Větev: | Revize:
1 3a515b92 cagy
'use strict';
2
3
var brackets = require('expand-brackets');
4
var define = require('define-property');
5
var utils = require('./utils');
6
7
/**
8
 * Characters to use in text regex (we want to "not" match
9
 * characters that are matched by other parsers)
10
 */
11
12
var TEXT_REGEX = '([!@*?+]?\\(|\\)|[*?.+\\\\]|\\[:?(?=.*\\])|:?\\])+';
13
var not = utils.createRegex(TEXT_REGEX);
14
15
/**
16
 * Extglob parsers
17
 */
18
19
function parsers(extglob) {
20
  extglob.state = extglob.state || {};
21
22
  /**
23
   * Use `expand-brackets` parsers
24
   */
25
26
  extglob.use(brackets.parsers);
27
  extglob.parser.sets.paren = extglob.parser.sets.paren || [];
28
  extglob.parser
29
30
    /**
31
     * Extglob open: "*("
32
     */
33
34
    .capture('paren.open', function() {
35
      var parsed = this.parsed;
36
      var pos = this.position();
37
      var m = this.match(/^([!@*?+])?\(/);
38
      if (!m) return;
39
40
      var prev = this.prev();
41
      var prefix = m[1];
42
      var val = m[0];
43
44
      var open = pos({
45
        type: 'paren.open',
46
        parsed: parsed,
47
        val: val
48
      });
49
50
      var node = pos({
51
        type: 'paren',
52
        prefix: prefix,
53
        nodes: [open]
54
      });
55
56
      // if nested negation extglobs, just cancel them out to simplify
57
      if (prefix === '!' && prev.type === 'paren' && prev.prefix === '!') {
58
        prev.prefix = '@';
59
        node.prefix = '@';
60
      }
61
62
      define(node, 'rest', this.input);
63
      define(node, 'parsed', parsed);
64
      define(node, 'parent', prev);
65
      define(open, 'parent', node);
66
67
      this.push('paren', node);
68
      prev.nodes.push(node);
69
    })
70
71
    /**
72
     * Extglob close: ")"
73
     */
74
75
    .capture('paren.close', function() {
76
      var parsed = this.parsed;
77
      var pos = this.position();
78
      var m = this.match(/^\)/);
79
      if (!m) return;
80
81
      var parent = this.pop('paren');
82
      var node = pos({
83
        type: 'paren.close',
84
        rest: this.input,
85
        parsed: parsed,
86
        val: m[0]
87
      });
88
89
      if (!this.isType(parent, 'paren')) {
90
        if (this.options.strict) {
91
          throw new Error('missing opening paren: "("');
92
        }
93
        node.escaped = true;
94
        return node;
95
      }
96
97
      node.prefix = parent.prefix;
98
      parent.nodes.push(node);
99
      define(node, 'parent', parent);
100
    })
101
102
    /**
103
     * Escape: "\\."
104
     */
105
106
    .capture('escape', function() {
107
      var pos = this.position();
108
      var m = this.match(/^\\(.)/);
109
      if (!m) return;
110
111
      return pos({
112
        type: 'escape',
113
        val: m[0],
114
        ch: m[1]
115
      });
116
    })
117
118
    /**
119
     * Question marks: "?"
120
     */
121
122
    .capture('qmark', function() {
123
      var parsed = this.parsed;
124
      var pos = this.position();
125
      var m = this.match(/^\?+(?!\()/);
126
      if (!m) return;
127
      extglob.state.metachar = true;
128
      return pos({
129
        type: 'qmark',
130
        rest: this.input,
131
        parsed: parsed,
132
        val: m[0]
133
      });
134
    })
135
136
    /**
137
     * Character parsers
138
     */
139
140
    .capture('star', /^\*(?!\()/)
141
    .capture('plus', /^\+(?!\()/)
142
    .capture('dot', /^\./)
143
    .capture('text', not);
144
};
145
146
/**
147
 * Expose text regex string
148
 */
149
150
module.exports.TEXT_REGEX = TEXT_REGEX;
151
152
/**
153
 * Extglob parsers
154
 */
155
156
module.exports = parsers;