feat(complex-matcher): regexp support (#3199)
This commit is contained in:
parent
c3066921ab
commit
829beb84e2
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
### Released packages
|
### Released packages
|
||||||
|
|
||||||
|
- complex-matcher v0.4.0
|
||||||
- xo-server-backup-reports v0.12.3
|
- xo-server-backup-reports v0.12.3
|
||||||
- xo-server v5.23.0
|
- xo-server v5.23.0
|
||||||
- xo-web v5.23.0
|
- xo-web v5.23.0
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import * as CM from './'
|
import * as CM from './'
|
||||||
|
|
||||||
export const pattern =
|
export const pattern =
|
||||||
'foo !"\\\\ \\"" name:|(wonderwoman batman) hasCape? age:32 chi*go'
|
'foo !"\\\\ \\"" name:|(wonderwoman batman) hasCape? age:32 chi*go /^foo\\/bar\\./i'
|
||||||
|
|
||||||
export const ast = new CM.And([
|
export const ast = new CM.And([
|
||||||
new CM.String('foo'),
|
new CM.String('foo'),
|
||||||
@ -13,4 +13,5 @@ export const ast = new CM.And([
|
|||||||
new CM.TruthyProperty('hasCape'),
|
new CM.TruthyProperty('hasCape'),
|
||||||
new CM.Property('age', new CM.Number(32)),
|
new CM.Property('age', new CM.Number(32)),
|
||||||
new CM.GlobPattern('chi*go'),
|
new CM.GlobPattern('chi*go'),
|
||||||
|
new CM.RegExp('^foo/bar\\.', 'i'),
|
||||||
])
|
])
|
||||||
|
@ -220,6 +220,37 @@ export class GlobPattern extends Node {
|
|||||||
return this.value
|
return this.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class RegExpNode extends Node {
|
||||||
|
constructor (pattern, flags) {
|
||||||
|
super()
|
||||||
|
|
||||||
|
this.re = new RegExp(pattern, flags)
|
||||||
|
|
||||||
|
// should not be enumerable for the tests
|
||||||
|
Object.defineProperty(this, 'match', {
|
||||||
|
value: this.match.bind(this),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
match (value) {
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
return this.re.test(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(value) || isPlainObject(value)) {
|
||||||
|
return some(value, this.match)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
toString () {
|
||||||
|
return this.re.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export { RegExpNode as RegExp }
|
||||||
|
|
||||||
export class StringNode extends Node {
|
export class StringNode extends Node {
|
||||||
constructor (value) {
|
constructor (value) {
|
||||||
super()
|
super()
|
||||||
@ -471,6 +502,33 @@ const parser = P.grammar({
|
|||||||
? new Failure(pos, 'a raw string')
|
? new Failure(pos, 'a raw string')
|
||||||
: new Success(pos, value)
|
: new Success(pos, value)
|
||||||
}),
|
}),
|
||||||
|
regex: new P((input, pos, end) => {
|
||||||
|
if (input[pos] !== '/') {
|
||||||
|
return new Failure(pos, '/')
|
||||||
|
}
|
||||||
|
++pos
|
||||||
|
|
||||||
|
let c
|
||||||
|
|
||||||
|
let pattern = ''
|
||||||
|
let escaped = false
|
||||||
|
while (pos < end && ((c = input[pos++]) !== '/' || escaped)) {
|
||||||
|
escaped = c === '\\'
|
||||||
|
pattern += c
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c !== '/') {
|
||||||
|
return new Failure(pos, '/')
|
||||||
|
}
|
||||||
|
|
||||||
|
let flags = ''
|
||||||
|
if (pos < end && (c = input[pos]) === 'i') {
|
||||||
|
++pos
|
||||||
|
flags += c
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Success(pos, new RegExpNode(pattern, flags))
|
||||||
|
}),
|
||||||
term: r =>
|
term: r =>
|
||||||
P.alt(
|
P.alt(
|
||||||
P.seq(P.text('('), r.ws, r.term.repeat(1), P.text(')')).map(
|
P.seq(P.text('('), r.ws, r.term.repeat(1), P.text(')')).map(
|
||||||
@ -501,6 +559,7 @@ const parser = P.grammar({
|
|||||||
value: r =>
|
value: r =>
|
||||||
P.alt(
|
P.alt(
|
||||||
r.quotedString.map(_ => new StringNode(_)),
|
r.quotedString.map(_ => new StringNode(_)),
|
||||||
|
r.regex,
|
||||||
r.globPattern.map(str => {
|
r.globPattern.map(str => {
|
||||||
const asNum = +str
|
const asNum = +str
|
||||||
return Number.isNaN(asNum)
|
return Number.isNaN(asNum)
|
||||||
|
Loading…
Reference in New Issue
Block a user