forked from codesandbox/codesandbox-client
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmatcher.ts
More file actions
109 lines (103 loc) · 2.85 KB
/
matcher.ts
File metadata and controls
109 lines (103 loc) · 2.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*---------------------------------------------------------
* Copyright (C) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------*/
'use strict';
export interface MatcherWithPriority<T> {
matcher: Matcher<T>;
priority: -1 | 0 | 1;
}
export interface Matcher<T> {
(matcherInput: T): boolean;
}
export function createMatchers<T>(selector: string, matchesName: (names: string[], matcherInput: T) => boolean): MatcherWithPriority<T>[] {
var results = <MatcherWithPriority<T>[]> [];
var tokenizer = newTokenizer(selector);
var token = tokenizer.next();
while (token !== null) {
let priority : -1 | 0 | 1 = 0;
if (token.length === 2 && token.charAt(1) === ':') {
switch (token.charAt(0)) {
case 'R': priority = 1; break;
case 'L': priority = -1; break;
default:
console.log(`Unknown priority ${token} in scope selector`);
}
token = tokenizer.next();
}
let matcher = parseConjunction();
if (matcher) {
results.push({ matcher, priority });
}
if (token !== ',') {
break;
}
token = tokenizer.next();
}
return results;
function parseOperand(): Matcher<T> {
if (token === '-') {
token = tokenizer.next();
var expressionToNegate = parseOperand();
return matcherInput => expressionToNegate && !expressionToNegate(matcherInput);
}
if (token === '(') {
token = tokenizer.next();
var expressionInParents = parseInnerExpression();
if (token === ')') {
token = tokenizer.next();
}
return expressionInParents;
}
if (isIdentifier(token)) {
var identifiers: string[] = [];
do {
identifiers.push(token);
token = tokenizer.next();
} while (isIdentifier(token));
return matcherInput => matchesName(identifiers, matcherInput);
}
return null;
}
function parseConjunction(): Matcher<T> {
var matchers: Matcher<T>[] = [];
var matcher = parseOperand();
while (matcher) {
matchers.push(matcher);
matcher = parseOperand();
}
return matcherInput => matchers.every(matcher => matcher(matcherInput)); // and
}
function parseInnerExpression(): Matcher<T> {
var matchers: Matcher<T>[] = [];
var matcher = parseConjunction();
while (matcher) {
matchers.push(matcher);
if (token === '|' || token === ',') {
do {
token = tokenizer.next();
} while (token === '|' || token === ','); // ignore subsequent commas
} else {
break;
}
matcher = parseConjunction();
}
return matcherInput => matchers.some(matcher => matcher(matcherInput)); // or
}
}
function isIdentifier(token: string) {
return token && token.match(/[\w\.:]+/);
}
function newTokenizer(input: string): { next: () => string } {
let regex = /([LR]:|[\w\.:][\w\.:\-]*|[\,\|\-\(\)])/g;
var match = regex.exec(input);
return {
next: () => {
if (!match) {
return null;
}
var res = match[0];
match = regex.exec(input);
return res;
}
};
}