WXL
3 天以前 2cc85c64f1c64a2dbaeae276a3e2ca8420de76b7
node_modules/minimatch/minimatch.js
@@ -142,6 +142,8 @@
  }
  this.options = options
  this.maxGlobstarRecursion = options.maxGlobstarRecursion !== undefined
    ? options.maxGlobstarRecursion : 200
  this.set = []
  this.pattern = pattern
  this.regexp = null
@@ -389,6 +391,9 @@
          re += c
          continue
        }
        // coalesce consecutive non-globstar * characters
        if (c === '*' && stateChar === '*') continue
        // if we already have a stateChar, then it means
        // that there was something like ** or +? in there.
@@ -784,19 +789,163 @@
// out of pattern, then that's fine, as long as all
// the parts match.
Minimatch.prototype.matchOne = function (file, pattern, partial) {
  var options = this.options
  if (pattern.indexOf(GLOBSTAR) !== -1) {
    return this._matchGlobstar(file, pattern, partial, 0, 0)
  }
  return this._matchOne(file, pattern, partial, 0, 0)
}
  this.debug('matchOne',
    { 'this': this, file: file, pattern: pattern })
Minimatch.prototype._matchGlobstar = function (file, pattern, partial, fileIndex, patternIndex) {
  var i
  this.debug('matchOne', file.length, pattern.length)
  // find first globstar from patternIndex
  var firstgs = -1
  for (i = patternIndex; i < pattern.length; i++) {
    if (pattern[i] === GLOBSTAR) { firstgs = i; break }
  }
  for (var fi = 0,
      pi = 0,
      fl = file.length,
      pl = pattern.length
      ; (fi < fl) && (pi < pl)
      ; fi++, pi++) {
  // find last globstar
  var lastgs = -1
  for (i = pattern.length - 1; i >= 0; i--) {
    if (pattern[i] === GLOBSTAR) { lastgs = i; break }
  }
  var head = pattern.slice(patternIndex, firstgs)
  var body = partial ? pattern.slice(firstgs + 1) : pattern.slice(firstgs + 1, lastgs)
  var tail = partial ? [] : pattern.slice(lastgs + 1)
  // check the head
  if (head.length) {
    var fileHead = file.slice(fileIndex, fileIndex + head.length)
    if (!this._matchOne(fileHead, head, partial, 0, 0)) {
      return false
    }
    fileIndex += head.length
  }
  // check the tail
  var fileTailMatch = 0
  if (tail.length) {
    if (tail.length + fileIndex > file.length) return false
    var tailStart = file.length - tail.length
    if (this._matchOne(file, tail, partial, tailStart, 0)) {
      fileTailMatch = tail.length
    } else {
      // affordance for stuff like a/**/* matching a/b/
      if (file[file.length - 1] !== '' ||
          fileIndex + tail.length === file.length) {
        return false
      }
      tailStart--
      if (!this._matchOne(file, tail, partial, tailStart, 0)) {
        return false
      }
      fileTailMatch = tail.length + 1
    }
  }
  // if body is empty (single ** between head and tail)
  if (!body.length) {
    var sawSome = !!fileTailMatch
    for (i = fileIndex; i < file.length - fileTailMatch; i++) {
      var f = String(file[i])
      sawSome = true
      if (f === '.' || f === '..' ||
          (!this.options.dot && f.charAt(0) === '.')) {
        return false
      }
    }
    return partial || sawSome
  }
  // split body into segments at each GLOBSTAR
  var bodySegments = [[[], 0]]
  var currentBody = bodySegments[0]
  var nonGsParts = 0
  var nonGsPartsSums = [0]
  for (var bi = 0; bi < body.length; bi++) {
    var b = body[bi]
    if (b === GLOBSTAR) {
      nonGsPartsSums.push(nonGsParts)
      currentBody = [[], 0]
      bodySegments.push(currentBody)
    } else {
      currentBody[0].push(b)
      nonGsParts++
    }
  }
  var idx = bodySegments.length - 1
  var fileLength = file.length - fileTailMatch
  for (var si = 0; si < bodySegments.length; si++) {
    bodySegments[si][1] = fileLength -
      (nonGsPartsSums[idx--] + bodySegments[si][0].length)
  }
  return !!this._matchGlobStarBodySections(
    file, bodySegments, fileIndex, 0, partial, 0, !!fileTailMatch
  )
}
// return false for "nope, not matching"
// return null for "not matching, cannot keep trying"
Minimatch.prototype._matchGlobStarBodySections = function (
  file, bodySegments, fileIndex, bodyIndex, partial, globStarDepth, sawTail
) {
  var bs = bodySegments[bodyIndex]
  if (!bs) {
    // just make sure there are no bad dots
    for (var i = fileIndex; i < file.length; i++) {
      sawTail = true
      var f = file[i]
      if (f === '.' || f === '..' ||
          (!this.options.dot && f.charAt(0) === '.')) {
        return false
      }
    }
    return sawTail
  }
  var body = bs[0]
  var after = bs[1]
  while (fileIndex <= after) {
    var m = this._matchOne(
      file.slice(0, fileIndex + body.length),
      body,
      partial,
      fileIndex,
      0
    )
    // if limit exceeded, no match. intentional false negative,
    // acceptable break in correctness for security.
    if (m && globStarDepth < this.maxGlobstarRecursion) {
      var sub = this._matchGlobStarBodySections(
        file, bodySegments,
        fileIndex + body.length, bodyIndex + 1,
        partial, globStarDepth + 1, sawTail
      )
      if (sub !== false) {
        return sub
      }
    }
    var f = file[fileIndex]
    if (f === '.' || f === '..' ||
        (!this.options.dot && f.charAt(0) === '.')) {
      return false
    }
    fileIndex++
  }
  return partial || null
}
Minimatch.prototype._matchOne = function (file, pattern, partial, fileIndex, patternIndex) {
  var fi, pi, fl, pl
  for (
    fi = fileIndex, pi = patternIndex, fl = file.length, pl = pattern.length
    ; (fi < fl) && (pi < pl)
    ; fi++, pi++
  ) {
    this.debug('matchOne loop')
    var p = pattern[pi]
    var f = file[fi]
@@ -806,87 +955,7 @@
    // should be impossible.
    // some invalid regexp stuff in the set.
    /* istanbul ignore if */
    if (p === false) return false
    if (p === GLOBSTAR) {
      this.debug('GLOBSTAR', [pattern, p, f])
      // "**"
      // a/**/b/**/c would match the following:
      // a/b/x/y/z/c
      // a/x/y/z/b/c
      // a/b/x/b/x/c
      // a/b/c
      // To do this, take the rest of the pattern after
      // the **, and see if it would match the file remainder.
      // If so, return success.
      // If not, the ** "swallows" a segment, and try again.
      // This is recursively awful.
      //
      // a/**/b/**/c matching a/b/x/y/z/c
      // - a matches a
      // - doublestar
      //   - matchOne(b/x/y/z/c, b/**/c)
      //     - b matches b
      //     - doublestar
      //       - matchOne(x/y/z/c, c) -> no
      //       - matchOne(y/z/c, c) -> no
      //       - matchOne(z/c, c) -> no
      //       - matchOne(c, c) yes, hit
      var fr = fi
      var pr = pi + 1
      if (pr === pl) {
        this.debug('** at the end')
        // a ** at the end will just swallow the rest.
        // We have found a match.
        // however, it will not swallow /.x, unless
        // options.dot is set.
        // . and .. are *never* matched by **, for explosively
        // exponential reasons.
        for (; fi < fl; fi++) {
          if (file[fi] === '.' || file[fi] === '..' ||
            (!options.dot && file[fi].charAt(0) === '.')) return false
        }
        return true
      }
      // ok, let's see if we can swallow whatever we can.
      while (fr < fl) {
        var swallowee = file[fr]
        this.debug('\nglobstar while', file, fr, pattern, pr, swallowee)
        // XXX remove this slice.  Just pass the start index.
        if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
          this.debug('globstar found match!', fr, fl, swallowee)
          // found a match.
          return true
        } else {
          // can't swallow "." or ".." ever.
          // can only swallow ".foo" when explicitly asked.
          if (swallowee === '.' || swallowee === '..' ||
            (!options.dot && swallowee.charAt(0) === '.')) {
            this.debug('dot detected!', file, fr, pattern, pr)
            break
          }
          // ** swallows a segment, and continue.
          this.debug('globstar swallow a segment, and continue')
          fr++
        }
      }
      // no match was found.
      // However, in partial mode, we can't say this is necessarily over.
      // If there's more *pattern* left, then
      /* istanbul ignore if */
      if (partial) {
        // ran out of file
        this.debug('\n>>> no match, partial?', file, fr, pattern, pr)
        if (fr === fl) return true
      }
      return false
    }
    if (p === false || p === GLOBSTAR) return false
    // something other than **
    // non-magic patterns just have to match exactly
@@ -902,17 +971,6 @@
    if (!hit) return false
  }
  // Note: ending in / means that we'll get a final ""
  // at the end of the pattern.  This can only match a
  // corresponding "" at the end of the file.
  // If the file ends in /, then it can only match a
  // a pattern that ends in /, unless the pattern just
  // doesn't have any more for it. But, a/b/ should *not*
  // match "a/b/*", even though "" matches against the
  // [^/]*? pattern, except in partial mode, where it might
  // simply not be reached yet.
  // However, a/b/ should still satisfy a/*
  // now either we fell off the end of the pattern, or we're done.
  if (fi === fl && pi === pl) {