You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							156 lines
						
					
					
						
							3.1 KiB
						
					
					
				
			
		
		
	
	
							156 lines
						
					
					
						
							3.1 KiB
						
					
					
				'use strict'; | 
						|
 | 
						|
var brackets = require('expand-brackets'); | 
						|
var define = require('define-property'); | 
						|
var utils = require('./utils'); | 
						|
 | 
						|
/** | 
						|
 * Characters to use in text regex (we want to "not" match | 
						|
 * characters that are matched by other parsers) | 
						|
 */ | 
						|
 | 
						|
var TEXT_REGEX = '([!@*?+]?\\(|\\)|[*?.+\\\\]|\\[:?(?=.*\\])|:?\\])+'; | 
						|
var not = utils.createRegex(TEXT_REGEX); | 
						|
 | 
						|
/** | 
						|
 * Extglob parsers | 
						|
 */ | 
						|
 | 
						|
function parsers(extglob) { | 
						|
  extglob.state = extglob.state || {}; | 
						|
 | 
						|
  /** | 
						|
   * Use `expand-brackets` parsers | 
						|
   */ | 
						|
 | 
						|
  extglob.use(brackets.parsers); | 
						|
  extglob.parser.sets.paren = extglob.parser.sets.paren || []; | 
						|
  extglob.parser | 
						|
 | 
						|
    /** | 
						|
     * Extglob open: "*(" | 
						|
     */ | 
						|
 | 
						|
    .capture('paren.open', function() { | 
						|
      var parsed = this.parsed; | 
						|
      var pos = this.position(); | 
						|
      var m = this.match(/^([!@*?+])?\(/); | 
						|
      if (!m) return; | 
						|
 | 
						|
      var prev = this.prev(); | 
						|
      var prefix = m[1]; | 
						|
      var val = m[0]; | 
						|
 | 
						|
      var open = pos({ | 
						|
        type: 'paren.open', | 
						|
        parsed: parsed, | 
						|
        val: val | 
						|
      }); | 
						|
 | 
						|
      var node = pos({ | 
						|
        type: 'paren', | 
						|
        prefix: prefix, | 
						|
        nodes: [open] | 
						|
      }); | 
						|
 | 
						|
      // if nested negation extglobs, just cancel them out to simplify | 
						|
      if (prefix === '!' && prev.type === 'paren' && prev.prefix === '!') { | 
						|
        prev.prefix = '@'; | 
						|
        node.prefix = '@'; | 
						|
      } | 
						|
 | 
						|
      define(node, 'rest', this.input); | 
						|
      define(node, 'parsed', parsed); | 
						|
      define(node, 'parent', prev); | 
						|
      define(open, 'parent', node); | 
						|
 | 
						|
      this.push('paren', node); | 
						|
      prev.nodes.push(node); | 
						|
    }) | 
						|
 | 
						|
    /** | 
						|
     * Extglob close: ")" | 
						|
     */ | 
						|
 | 
						|
    .capture('paren.close', function() { | 
						|
      var parsed = this.parsed; | 
						|
      var pos = this.position(); | 
						|
      var m = this.match(/^\)/); | 
						|
      if (!m) return; | 
						|
 | 
						|
      var parent = this.pop('paren'); | 
						|
      var node = pos({ | 
						|
        type: 'paren.close', | 
						|
        rest: this.input, | 
						|
        parsed: parsed, | 
						|
        val: m[0] | 
						|
      }); | 
						|
 | 
						|
      if (!this.isType(parent, 'paren')) { | 
						|
        if (this.options.strict) { | 
						|
          throw new Error('missing opening paren: "("'); | 
						|
        } | 
						|
        node.escaped = true; | 
						|
        return node; | 
						|
      } | 
						|
 | 
						|
      node.prefix = parent.prefix; | 
						|
      parent.nodes.push(node); | 
						|
      define(node, 'parent', parent); | 
						|
    }) | 
						|
 | 
						|
    /** | 
						|
     * Escape: "\\." | 
						|
     */ | 
						|
 | 
						|
    .capture('escape', function() { | 
						|
      var pos = this.position(); | 
						|
      var m = this.match(/^\\(.)/); | 
						|
      if (!m) return; | 
						|
 | 
						|
      return pos({ | 
						|
        type: 'escape', | 
						|
        val: m[0], | 
						|
        ch: m[1] | 
						|
      }); | 
						|
    }) | 
						|
 | 
						|
    /** | 
						|
     * Question marks: "?" | 
						|
     */ | 
						|
 | 
						|
    .capture('qmark', function() { | 
						|
      var parsed = this.parsed; | 
						|
      var pos = this.position(); | 
						|
      var m = this.match(/^\?+(?!\()/); | 
						|
      if (!m) return; | 
						|
      extglob.state.metachar = true; | 
						|
      return pos({ | 
						|
        type: 'qmark', | 
						|
        rest: this.input, | 
						|
        parsed: parsed, | 
						|
        val: m[0] | 
						|
      }); | 
						|
    }) | 
						|
 | 
						|
    /** | 
						|
     * Character parsers | 
						|
     */ | 
						|
 | 
						|
    .capture('star', /^\*(?!\()/) | 
						|
    .capture('plus', /^\+(?!\()/) | 
						|
    .capture('dot', /^\./) | 
						|
    .capture('text', not); | 
						|
}; | 
						|
 | 
						|
/** | 
						|
 * Expose text regex string | 
						|
 */ | 
						|
 | 
						|
module.exports.TEXT_REGEX = TEXT_REGEX; | 
						|
 | 
						|
/** | 
						|
 * Extglob parsers | 
						|
 */ | 
						|
 | 
						|
module.exports = parsers;
 | 
						|
 |