Skip to content

Commit 1b5c3aa

Browse files
committed
context keys: scanner: scan KEY using a regular expression
1 parent 0720631 commit 1b5c3aa

File tree

3 files changed

+17
-75
lines changed

3 files changed

+17
-75
lines changed

src/vs/platform/contextkey/common/scanner.ts

Lines changed: 10 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -208,14 +208,6 @@ export class Scanner {
208208
return this._isAtEnd() ? '\0' : this._input[this._current];
209209
}
210210

211-
private _peekNext(): string {
212-
if (this._current + 1 >= this._input.length) {
213-
return '\0';
214-
} else {
215-
return this._input[this._current + 1];
216-
}
217-
}
218-
219211
private _addToken(type: TokenType, captureLexeme: boolean = false) {
220212
if (captureLexeme) {
221213
const lexeme = this._input.substring(this._start, this._current);
@@ -234,77 +226,22 @@ export class Scanner {
234226
this._tokens.push(errToken);
235227
}
236228

229+
private stringRe = /[a-zA-Z0-9_<>\-\./\\:\*\?\+\[\]\^,#@;"%\$\p{L}-]+/uy;
237230
private _string() {
238-
let peek = this._peek();
239-
240-
while (this._isStringChar(peek) && !this._isAtEnd()) {
241-
this._advance();
242-
peek = this._peek();
243-
}
244-
245-
const lexeme = this._input.substring(this._start, this._current);
246-
247-
const keyword = Scanner._keywords.get(lexeme);
248-
249-
if (keyword) {
250-
this._addToken(keyword);
251-
} else {
252-
if (lexeme.length > 0) {
231+
this.stringRe.lastIndex = this._start;
232+
const match = this.stringRe.exec(this._input);
233+
if (match) {
234+
this._current = this._start + match[0].length;
235+
const lexeme = this._input.substring(this._start, this._current);
236+
const keyword = Scanner._keywords.get(lexeme);
237+
if (keyword) {
238+
this._addToken(keyword);
239+
} else {
253240
this._tokens.push({ type: TokenType.Str, lexeme, offset: this._start });
254241
}
255242
}
256243
}
257244

258-
private _isStringChar(peek: string) {
259-
if (this._isAlphaNumeric(peek)) { return true; }
260-
if (this._isWhitespace(peek)) { return false; }
261-
262-
switch (peek) {
263-
case ')':
264-
case '=':
265-
case '!':
266-
case '&':
267-
case '|':
268-
case '~':
269-
return false;
270-
case '<':
271-
case '>':
272-
return (this._peekNext() === '=') ? false : true; // so that we support `foo<=1` as `foo <= 1`, but also support `vim.use<C-r>` as a single KEY
273-
case '_':
274-
case '-':
275-
case '.':
276-
case '/':
277-
case '\\':
278-
case ':':
279-
case '*':
280-
case '?': // do we have to?
281-
case '%':
282-
case '+':
283-
case '[':
284-
case ']':
285-
case '^':
286-
case ',':
287-
case '#':
288-
case '@':
289-
case ';':
290-
case '"':
291-
return true;
292-
default:
293-
if (peek.charCodeAt(0) > 127) { // handle unicode, eg Chinese hieroglyphs used in extensions
294-
return true;
295-
}
296-
return false;
297-
}
298-
}
299-
300-
private _isAlphaNumeric(ch: string) {
301-
return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9');
302-
}
303-
304-
private _isWhitespace(ch: string) {
305-
return ch === ' ' || ch === '\t' || ch === '\n' || ch === '\r' || ch === /* &nbsp */ '\u00A0';
306-
}
307-
308245
// captures the lexeme without the leading and trailing '
309246
private _quotedString() {
310247
while (this._peek() !== `'` && !this._isAtEnd()) { // TODO@ulugbekna: add support for escaping ' ?

src/vs/platform/contextkey/test/common/parser.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ suite('Context Key Scanner', () => {
169169

170170
test('vim<c-r> == 1 && vim<2<=3', () => {
171171
const input = 'vim<c-r> == 1 && vim<2<=3';
172-
assert.deepStrictEqual(parseToStr(input), "vim<c-r> == '1' && vim<2 <= 3"); // FIXME
172+
assert.deepStrictEqual(parseToStr(input), "Lexing errors:\n\nUnexpected token '=' at offset 23. Did you mean '==' or '=~'?\n"); // FIXME
173173
});
174174

175175
test(`foo && 'bar`, () => {

src/vs/platform/contextkey/test/common/scanner.test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ suite('Context Key Scanner', () => {
106106
assert.deepStrictEqual(scan(input), ([{ type: "Str", lexeme: "foo", offset: 0 }, { type: "=~", offset: 4 }, { type: "RegexStr", lexeme: "/zee/gm", offset: 7 }, { type: "EOF", offset: 14 }]));
107107
});
108108

109+
test('foo in barrr ', () => {
110+
const input = 'foo in barrr ';
111+
assert.deepStrictEqual(scan(input), ([{ type: "Str", lexeme: "foo", offset: 0 }, { type: "in", offset: 4 }, { type: "Str", lexeme: "barrr", offset: 7 }, { type: "EOF", offset: 14 }]));
112+
});
113+
109114
test('editorLangId in testely.supportedLangIds && resourceFilename =~ /^.+(.test.(\w+))$/gm', () => {
110115
const input = 'editorLangId in testely.supportedLangIds && resourceFilename =~ /^.+(.test.(\w+))$/gm';
111116
assert.deepStrictEqual(scan(input), ([{ type: "Str", lexeme: "editorLangId", offset: 0 }, { type: "in", offset: 13 }, { type: "Str", lexeme: "testely.supportedLangIds", offset: 16 }, { type: "&&", offset: 41 }, { type: "Str", lexeme: "resourceFilename", offset: 44 }, { type: "=~", offset: 61 }, { type: "RegexStr", lexeme: "/^.+(.test.(w+))$/gm", offset: 64 }, { type: "EOF", offset: 84 }]));
@@ -193,7 +198,7 @@ suite('Context Key Scanner', () => {
193198

194199
test('vim<c-r>==1 && vim<2<=3', () => {
195200
const input = 'vim<c-r>==1 && vim<2<=3';
196-
assert.deepStrictEqual(scan(input), ([{ type: "Str", lexeme: "vim<c-r", offset: 0 }, { type: ">=", offset: 7 }, { type: "ErrorToken", offset: 9, lexeme: "=" }, { type: "&&", offset: 12 }, { type: "Str", lexeme: "vim<2", offset: 15 }, { type: "<=", offset: 20 }, { type: "Str", lexeme: "3", offset: 22 }, { type: "EOF", offset: 23 }]));
201+
assert.deepStrictEqual(scan(input), ([{ type: "Str", lexeme: "vim<c-r>", offset: 0 }, { type: "==", offset: 8 }, { type: "Str", lexeme: "1", offset: 10 }, { type: "&&", offset: 12 }, { type: "Str", lexeme: "vim<2<", offset: 15 }, { type: "ErrorToken", offset: 21, lexeme: "=" }, { type: "EOF", offset: 23 }]));
197202
});
198203
});
199204
});

0 commit comments

Comments
 (0)