@codingame/monaco-vscode-editor-api 11.1.2 → 12.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/vs/editor/browser/config/tabFocus.d.ts +1 -0
- package/esm/vs/editor/browser/coreCommands.d.ts +1 -0
- package/esm/vs/editor/common/commands/shiftCommand.d.ts +1 -0
- package/esm/vs/editor/contrib/bracketMatching/browser/bracketMatching.d.ts +1 -0
- package/esm/vs/editor/contrib/clipboard/browser/clipboard.d.ts +1 -0
- package/esm/vs/editor/contrib/contextmenu/browser/contextmenu.d.ts +1 -0
- package/esm/vs/editor/contrib/cursorUndo/browser/cursorUndo.d.ts +1 -0
- package/esm/vs/editor/contrib/find/browser/findController.d.ts +1 -0
- package/esm/vs/editor/contrib/format/browser/formatActions.d.ts +1 -0
- package/esm/vs/editor/contrib/hover/browser/hoverContribution.d.ts +1 -0
- package/esm/vs/editor/contrib/hover/browser/hoverContribution.js +1 -0
- package/esm/vs/editor/contrib/inlineCompletions/browser/inlineCompletions.contribution.d.ts +1 -0
- package/esm/vs/editor/editor.api.d.ts +7 -2
- package/esm/vs/editor/editor.api.js +4 -2311
- package/package.json +14 -9
- package/vscode/src/vs/editor/editor.api.d.ts +9338 -0
- package/vscode/src/vs/editor/editor.api.js +35 -0
- package/vscode/src/vs/editor/standalone/browser/colorizer.d.ts +17 -0
- package/vscode/src/vs/editor/standalone/browser/colorizer.js +178 -0
- package/vscode/src/vs/editor/standalone/browser/standalone-tokens.css.js +6 -0
- package/vscode/src/vs/editor/standalone/browser/standaloneEditor.d.ts +73 -0
- package/vscode/src/vs/editor/standalone/browser/standaloneEditor.js +347 -0
- package/vscode/src/vs/editor/standalone/browser/standaloneLanguages.d.ts +114 -0
- package/vscode/src/vs/editor/standalone/browser/standaloneLanguages.js +444 -0
- package/vscode/src/vs/editor/standalone/browser/standaloneWebWorker.d.ts +15 -0
- package/vscode/src/vs/editor/standalone/browser/standaloneWebWorker.js +66 -0
- package/vscode/src/vs/editor/standalone/common/monarch/monarchCommon.d.ts +72 -0
- package/vscode/src/vs/editor/standalone/common/monarch/monarchCommon.js +111 -0
- package/vscode/src/vs/editor/standalone/common/monarch/monarchCompile.d.ts +3 -0
- package/vscode/src/vs/editor/standalone/common/monarch/monarchCompile.js +476 -0
- package/vscode/src/vs/editor/standalone/common/monarch/monarchLexer.d.ts +33 -0
- package/vscode/src/vs/editor/standalone/common/monarch/monarchLexer.js +707 -0
- package/vscode/src/vs/editor/standalone/common/monarch/monarchTypes.d.ts +46 -0
- package/editor.api.d.ts +0 -7
- package/monaco.d.ts +0 -10
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export declare enum MonarchBracket {
|
|
2
|
+
None = 0,
|
|
3
|
+
Open = 1,
|
|
4
|
+
Close = -1
|
|
5
|
+
}
|
|
6
|
+
export interface ILexerMin {
|
|
7
|
+
languageId: string;
|
|
8
|
+
includeLF: boolean;
|
|
9
|
+
noThrow: boolean;
|
|
10
|
+
ignoreCase: boolean;
|
|
11
|
+
unicode: boolean;
|
|
12
|
+
usesEmbedded: boolean;
|
|
13
|
+
defaultToken: string;
|
|
14
|
+
stateNames: {
|
|
15
|
+
[stateName: string]: any;
|
|
16
|
+
};
|
|
17
|
+
[attr: string]: any;
|
|
18
|
+
}
|
|
19
|
+
export interface ILexer extends ILexerMin {
|
|
20
|
+
maxStack: number;
|
|
21
|
+
start: string | null;
|
|
22
|
+
ignoreCase: boolean;
|
|
23
|
+
unicode: boolean;
|
|
24
|
+
tokenPostfix: string;
|
|
25
|
+
tokenizer: {
|
|
26
|
+
[stateName: string]: IRule[];
|
|
27
|
+
};
|
|
28
|
+
brackets: IBracket[];
|
|
29
|
+
}
|
|
30
|
+
export interface IBracket {
|
|
31
|
+
token: string;
|
|
32
|
+
open: string;
|
|
33
|
+
close: string;
|
|
34
|
+
}
|
|
35
|
+
export type FuzzyAction = IAction | string;
|
|
36
|
+
export declare function isFuzzyActionArr(what: FuzzyAction | FuzzyAction[]): what is FuzzyAction[];
|
|
37
|
+
export declare function isFuzzyAction(what: FuzzyAction | FuzzyAction[]): what is FuzzyAction;
|
|
38
|
+
export declare function isString(what: FuzzyAction): what is string;
|
|
39
|
+
export declare function isIAction(what: FuzzyAction): what is IAction;
|
|
40
|
+
export interface IRule {
|
|
41
|
+
action: FuzzyAction;
|
|
42
|
+
matchOnlyAtLineStart: boolean;
|
|
43
|
+
name: string;
|
|
44
|
+
resolveRegex(state: string): RegExp;
|
|
45
|
+
}
|
|
46
|
+
export interface IAction {
|
|
47
|
+
group?: FuzzyAction[];
|
|
48
|
+
test?: (id: string, matches: string[], state: string, eos: boolean) => FuzzyAction;
|
|
49
|
+
token?: string;
|
|
50
|
+
tokenSubst?: boolean;
|
|
51
|
+
next?: string;
|
|
52
|
+
nextEmbedded?: string;
|
|
53
|
+
bracket?: MonarchBracket;
|
|
54
|
+
log?: string;
|
|
55
|
+
switchTo?: string;
|
|
56
|
+
goBack?: number;
|
|
57
|
+
transform?: (states: string[]) => string[];
|
|
58
|
+
}
|
|
59
|
+
export interface IBranch {
|
|
60
|
+
name: string;
|
|
61
|
+
value: FuzzyAction;
|
|
62
|
+
test?: (id: string, matches: string[], state: string, eos: boolean) => boolean;
|
|
63
|
+
}
|
|
64
|
+
export declare function empty(s: string): boolean;
|
|
65
|
+
export declare function fixCase(lexer: ILexerMin, str: string): string;
|
|
66
|
+
export declare function sanitize(s: string): string;
|
|
67
|
+
export declare function log(lexer: ILexerMin, msg: string): void;
|
|
68
|
+
export declare function createError(lexer: ILexerMin, msg: string): Error;
|
|
69
|
+
export declare function substituteMatches(lexer: ILexerMin, str: string, id: string, matches: string[], state: string): string;
|
|
70
|
+
export declare function substituteMatchesRe(lexer: ILexerMin, str: string, state: string): string;
|
|
71
|
+
export declare function findRules(lexer: ILexer, inState: string): IRule[] | null;
|
|
72
|
+
export declare function stateExists(lexer: ILexerMin, inState: string): boolean;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
var MonarchBracket;
|
|
4
|
+
(function (MonarchBracket) {
|
|
5
|
+
MonarchBracket[MonarchBracket["None"] = 0] = "None";
|
|
6
|
+
MonarchBracket[MonarchBracket["Open"] = 1] = "Open";
|
|
7
|
+
MonarchBracket[MonarchBracket["Close"] = -1] = "Close";
|
|
8
|
+
})(MonarchBracket || (MonarchBracket = {}));
|
|
9
|
+
function isFuzzyActionArr(what) {
|
|
10
|
+
return (Array.isArray(what));
|
|
11
|
+
}
|
|
12
|
+
function isFuzzyAction(what) {
|
|
13
|
+
return !isFuzzyActionArr(what);
|
|
14
|
+
}
|
|
15
|
+
function isString(what) {
|
|
16
|
+
return (typeof what === 'string');
|
|
17
|
+
}
|
|
18
|
+
function isIAction(what) {
|
|
19
|
+
return !isString(what);
|
|
20
|
+
}
|
|
21
|
+
function empty(s) {
|
|
22
|
+
return (s ? false : true);
|
|
23
|
+
}
|
|
24
|
+
function fixCase(lexer, str) {
|
|
25
|
+
return (lexer.ignoreCase && str ? str.toLowerCase() : str);
|
|
26
|
+
}
|
|
27
|
+
function sanitize(s) {
|
|
28
|
+
return s.replace(/[&<>'"_]/g, '-');
|
|
29
|
+
}
|
|
30
|
+
function log(lexer, msg) {
|
|
31
|
+
console.log(`${lexer.languageId}: ${msg}`);
|
|
32
|
+
}
|
|
33
|
+
function createError(lexer, msg) {
|
|
34
|
+
return ( new Error(`${lexer.languageId}: ${msg}`));
|
|
35
|
+
}
|
|
36
|
+
function substituteMatches(lexer, str, id, matches, state) {
|
|
37
|
+
const re = /\$((\$)|(#)|(\d\d?)|[sS](\d\d?)|@(\w+))/g;
|
|
38
|
+
let stateMatches = null;
|
|
39
|
+
return str.replace(re, function (full, sub, dollar, hash, n, s, attr, ofs, total) {
|
|
40
|
+
if (!empty(dollar)) {
|
|
41
|
+
return '$';
|
|
42
|
+
}
|
|
43
|
+
if (!empty(hash)) {
|
|
44
|
+
return fixCase(lexer, id);
|
|
45
|
+
}
|
|
46
|
+
if (!empty(n) && n < matches.length) {
|
|
47
|
+
return fixCase(lexer, matches[n]);
|
|
48
|
+
}
|
|
49
|
+
if (!empty(attr) && lexer && typeof (lexer[attr]) === 'string') {
|
|
50
|
+
return lexer[attr];
|
|
51
|
+
}
|
|
52
|
+
if (stateMatches === null) {
|
|
53
|
+
stateMatches = state.split('.');
|
|
54
|
+
stateMatches.unshift(state);
|
|
55
|
+
}
|
|
56
|
+
if (!empty(s) && s < stateMatches.length) {
|
|
57
|
+
return fixCase(lexer, stateMatches[s]);
|
|
58
|
+
}
|
|
59
|
+
return '';
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function substituteMatchesRe(lexer, str, state) {
|
|
63
|
+
const re = /\$[sS](\d\d?)/g;
|
|
64
|
+
let stateMatches = null;
|
|
65
|
+
return str.replace(re, function (full, s) {
|
|
66
|
+
if (stateMatches === null) {
|
|
67
|
+
stateMatches = state.split('.');
|
|
68
|
+
stateMatches.unshift(state);
|
|
69
|
+
}
|
|
70
|
+
if (!empty(s) && s < stateMatches.length) {
|
|
71
|
+
return fixCase(lexer, stateMatches[s]);
|
|
72
|
+
}
|
|
73
|
+
return '';
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function findRules(lexer, inState) {
|
|
77
|
+
let state = inState;
|
|
78
|
+
while (state && state.length > 0) {
|
|
79
|
+
const rules = lexer.tokenizer[state];
|
|
80
|
+
if (rules) {
|
|
81
|
+
return rules;
|
|
82
|
+
}
|
|
83
|
+
const idx = state.lastIndexOf('.');
|
|
84
|
+
if (idx < 0) {
|
|
85
|
+
state = null;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
state = state.substr(0, idx);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
function stateExists(lexer, inState) {
|
|
94
|
+
let state = inState;
|
|
95
|
+
while (state && state.length > 0) {
|
|
96
|
+
const exist = lexer.stateNames[state];
|
|
97
|
+
if (exist) {
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
const idx = state.lastIndexOf('.');
|
|
101
|
+
if (idx < 0) {
|
|
102
|
+
state = null;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
state = state.substr(0, idx);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export { MonarchBracket, createError, empty, findRules, fixCase, isFuzzyAction, isFuzzyActionArr, isIAction, isString, log, sanitize, stateExists, substituteMatches, substituteMatchesRe };
|
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
|
|
2
|
+
import { createError, empty, substituteMatchesRe, substituteMatches, fixCase, MonarchBracket, stateExists } from './monarchCommon.js';
|
|
3
|
+
|
|
4
|
+
function isArrayOf(elemType, obj) {
|
|
5
|
+
if (!obj) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
if (!(Array.isArray(obj))) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
for (const el of obj) {
|
|
12
|
+
if (!(elemType(el))) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
function bool(prop, defValue) {
|
|
19
|
+
if (typeof prop === 'boolean') {
|
|
20
|
+
return prop;
|
|
21
|
+
}
|
|
22
|
+
return defValue;
|
|
23
|
+
}
|
|
24
|
+
function string(prop, defValue) {
|
|
25
|
+
if (typeof (prop) === 'string') {
|
|
26
|
+
return prop;
|
|
27
|
+
}
|
|
28
|
+
return defValue;
|
|
29
|
+
}
|
|
30
|
+
function arrayToHash(array) {
|
|
31
|
+
const result = {};
|
|
32
|
+
for (const e of array) {
|
|
33
|
+
result[e] = true;
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
function createKeywordMatcher(arr, caseInsensitive = false) {
|
|
38
|
+
if (caseInsensitive) {
|
|
39
|
+
arr = ( arr.map(function (x) { return x.toLowerCase(); }));
|
|
40
|
+
}
|
|
41
|
+
const hash = arrayToHash(arr);
|
|
42
|
+
if (caseInsensitive) {
|
|
43
|
+
return function (word) {
|
|
44
|
+
return hash[word.toLowerCase()] !== undefined && hash.hasOwnProperty(word.toLowerCase());
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
return function (word) {
|
|
49
|
+
return hash[word] !== undefined && hash.hasOwnProperty(word);
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function compileRegExp(lexer, str, handleSn) {
|
|
54
|
+
str = str.replace(/@@/g, `\x01`);
|
|
55
|
+
let n = 0;
|
|
56
|
+
let hadExpansion;
|
|
57
|
+
do {
|
|
58
|
+
hadExpansion = false;
|
|
59
|
+
str = str.replace(/@(\w+)/g, function (s, attr) {
|
|
60
|
+
hadExpansion = true;
|
|
61
|
+
let sub = '';
|
|
62
|
+
if (typeof (lexer[attr]) === 'string') {
|
|
63
|
+
sub = lexer[attr];
|
|
64
|
+
}
|
|
65
|
+
else if (lexer[attr] && lexer[attr] instanceof RegExp) {
|
|
66
|
+
sub = lexer[attr].source;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
if (lexer[attr] === undefined) {
|
|
70
|
+
throw createError(lexer, 'language definition does not contain attribute \'' + attr + '\', used at: ' + str);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
throw createError(lexer, 'attribute reference \'' + attr + '\' must be a string, used at: ' + str);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return (empty(sub) ? '' : '(?:' + sub + ')');
|
|
77
|
+
});
|
|
78
|
+
n++;
|
|
79
|
+
} while (hadExpansion && n < 5);
|
|
80
|
+
str = str.replace(/\x01/g, '@');
|
|
81
|
+
const flags = (lexer.ignoreCase ? 'i' : '') + (lexer.unicode ? 'u' : '');
|
|
82
|
+
if (handleSn) {
|
|
83
|
+
const match = str.match(/\$[sS](\d\d?)/g);
|
|
84
|
+
if (match) {
|
|
85
|
+
let lastState = null;
|
|
86
|
+
let lastRegEx = null;
|
|
87
|
+
return (state) => {
|
|
88
|
+
if (lastRegEx && lastState === state) {
|
|
89
|
+
return lastRegEx;
|
|
90
|
+
}
|
|
91
|
+
lastState = state;
|
|
92
|
+
lastRegEx = ( new RegExp(substituteMatchesRe(lexer, str, state), flags));
|
|
93
|
+
return lastRegEx;
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return ( new RegExp(str, flags));
|
|
98
|
+
}
|
|
99
|
+
function selectScrutinee(id, matches, state, num) {
|
|
100
|
+
if (num < 0) {
|
|
101
|
+
return id;
|
|
102
|
+
}
|
|
103
|
+
if (num < matches.length) {
|
|
104
|
+
return matches[num];
|
|
105
|
+
}
|
|
106
|
+
if (num >= 100) {
|
|
107
|
+
num = num - 100;
|
|
108
|
+
const parts = state.split('.');
|
|
109
|
+
parts.unshift(state);
|
|
110
|
+
if (num < parts.length) {
|
|
111
|
+
return parts[num];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
function createGuard(lexer, ruleName, tkey, val) {
|
|
117
|
+
let scrut = -1;
|
|
118
|
+
let oppat = tkey;
|
|
119
|
+
let matches = tkey.match(/^\$(([sS]?)(\d\d?)|#)(.*)$/);
|
|
120
|
+
if (matches) {
|
|
121
|
+
if (matches[3]) {
|
|
122
|
+
scrut = parseInt(matches[3]);
|
|
123
|
+
if (matches[2]) {
|
|
124
|
+
scrut = scrut + 100;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
oppat = matches[4];
|
|
128
|
+
}
|
|
129
|
+
let op = '~';
|
|
130
|
+
let pat = oppat;
|
|
131
|
+
if (!oppat || oppat.length === 0) {
|
|
132
|
+
op = '!=';
|
|
133
|
+
pat = '';
|
|
134
|
+
}
|
|
135
|
+
else if (/^\w*$/.test(pat)) {
|
|
136
|
+
op = '==';
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
matches = oppat.match(/^(@|!@|~|!~|==|!=)(.*)$/);
|
|
140
|
+
if (matches) {
|
|
141
|
+
op = matches[1];
|
|
142
|
+
pat = matches[2];
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
let tester;
|
|
146
|
+
if ((op === '~' || op === '!~') && /^(\w|\|)*$/.test(pat)) {
|
|
147
|
+
const inWords = createKeywordMatcher(pat.split('|'), lexer.ignoreCase);
|
|
148
|
+
tester = function (s) { return (op === '~' ? inWords(s) : !inWords(s)); };
|
|
149
|
+
}
|
|
150
|
+
else if (op === '@' || op === '!@') {
|
|
151
|
+
const words = lexer[pat];
|
|
152
|
+
if (!words) {
|
|
153
|
+
throw createError(lexer, 'the @ match target \'' + pat + '\' is not defined, in rule: ' + ruleName);
|
|
154
|
+
}
|
|
155
|
+
if (!(isArrayOf(function (elem) { return (typeof (elem) === 'string'); }, words))) {
|
|
156
|
+
throw createError(lexer, 'the @ match target \'' + pat + '\' must be an array of strings, in rule: ' + ruleName);
|
|
157
|
+
}
|
|
158
|
+
const inWords = createKeywordMatcher(words, lexer.ignoreCase);
|
|
159
|
+
tester = function (s) { return (op === '@' ? inWords(s) : !inWords(s)); };
|
|
160
|
+
}
|
|
161
|
+
else if (op === '~' || op === '!~') {
|
|
162
|
+
if (pat.indexOf('$') < 0) {
|
|
163
|
+
const re = compileRegExp(lexer, '^' + pat + '$', false);
|
|
164
|
+
tester = function (s) { return (op === '~' ? re.test(s) : !re.test(s)); };
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
tester = function (s, id, matches, state) {
|
|
168
|
+
const re = compileRegExp(lexer, '^' + substituteMatches(lexer, pat, id, matches, state) + '$', false);
|
|
169
|
+
return re.test(s);
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
if (pat.indexOf('$') < 0) {
|
|
175
|
+
const patx = fixCase(lexer, pat);
|
|
176
|
+
tester = function (s) { return (op === '==' ? s === patx : s !== patx); };
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
const patx = fixCase(lexer, pat);
|
|
180
|
+
tester = function (s, id, matches, state, eos) {
|
|
181
|
+
const patexp = substituteMatches(lexer, patx, id, matches, state);
|
|
182
|
+
return (op === '==' ? s === patexp : s !== patexp);
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (scrut === -1) {
|
|
187
|
+
return {
|
|
188
|
+
name: tkey, value: val, test: function (id, matches, state, eos) {
|
|
189
|
+
return tester(id, id, matches, state, eos);
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
return {
|
|
195
|
+
name: tkey, value: val, test: function (id, matches, state, eos) {
|
|
196
|
+
const scrutinee = selectScrutinee(id, matches, state, scrut);
|
|
197
|
+
return tester(!scrutinee ? '' : scrutinee, id, matches, state, eos);
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
function compileAction(lexer, ruleName, action) {
|
|
203
|
+
if (!action) {
|
|
204
|
+
return { token: '' };
|
|
205
|
+
}
|
|
206
|
+
else if (typeof (action) === 'string') {
|
|
207
|
+
return action;
|
|
208
|
+
}
|
|
209
|
+
else if (action.token || action.token === '') {
|
|
210
|
+
if (typeof (action.token) !== 'string') {
|
|
211
|
+
throw createError(lexer, 'a \'token\' attribute must be of type string, in rule: ' + ruleName);
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
const newAction = { token: action.token };
|
|
215
|
+
if (action.token.indexOf('$') >= 0) {
|
|
216
|
+
newAction.tokenSubst = true;
|
|
217
|
+
}
|
|
218
|
+
if (typeof (action.bracket) === 'string') {
|
|
219
|
+
if (action.bracket === '@open') {
|
|
220
|
+
newAction.bracket = MonarchBracket.Open;
|
|
221
|
+
}
|
|
222
|
+
else if (action.bracket === '@close') {
|
|
223
|
+
newAction.bracket = MonarchBracket.Close;
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
throw createError(lexer, 'a \'bracket\' attribute must be either \'@open\' or \'@close\', in rule: ' + ruleName);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (action.next) {
|
|
230
|
+
if (typeof (action.next) !== 'string') {
|
|
231
|
+
throw createError(lexer, 'the next state must be a string value in rule: ' + ruleName);
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
let next = action.next;
|
|
235
|
+
if (!/^(@pop|@push|@popall)$/.test(next)) {
|
|
236
|
+
if (next[0] === '@') {
|
|
237
|
+
next = next.substr(1);
|
|
238
|
+
}
|
|
239
|
+
if (next.indexOf('$') < 0) {
|
|
240
|
+
if (!stateExists(lexer, substituteMatches(lexer, next, '', [], ''))) {
|
|
241
|
+
throw createError(lexer, 'the next state \'' + action.next + '\' is not defined in rule: ' + ruleName);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
newAction.next = next;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (typeof (action.goBack) === 'number') {
|
|
249
|
+
newAction.goBack = action.goBack;
|
|
250
|
+
}
|
|
251
|
+
if (typeof (action.switchTo) === 'string') {
|
|
252
|
+
newAction.switchTo = action.switchTo;
|
|
253
|
+
}
|
|
254
|
+
if (typeof (action.log) === 'string') {
|
|
255
|
+
newAction.log = action.log;
|
|
256
|
+
}
|
|
257
|
+
if (typeof (action.nextEmbedded) === 'string') {
|
|
258
|
+
newAction.nextEmbedded = action.nextEmbedded;
|
|
259
|
+
lexer.usesEmbedded = true;
|
|
260
|
+
}
|
|
261
|
+
return newAction;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
else if (Array.isArray(action)) {
|
|
265
|
+
const results = [];
|
|
266
|
+
for (let i = 0, len = action.length; i < len; i++) {
|
|
267
|
+
results[i] = compileAction(lexer, ruleName, action[i]);
|
|
268
|
+
}
|
|
269
|
+
return { group: results };
|
|
270
|
+
}
|
|
271
|
+
else if (action.cases) {
|
|
272
|
+
const cases = [];
|
|
273
|
+
for (const tkey in action.cases) {
|
|
274
|
+
if (action.cases.hasOwnProperty(tkey)) {
|
|
275
|
+
const val = compileAction(lexer, ruleName, action.cases[tkey]);
|
|
276
|
+
if (tkey === '@default' || tkey === '@' || tkey === '') {
|
|
277
|
+
cases.push({ test: undefined, value: val, name: tkey });
|
|
278
|
+
}
|
|
279
|
+
else if (tkey === '@eos') {
|
|
280
|
+
cases.push({ test: function (id, matches, state, eos) { return eos; }, value: val, name: tkey });
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
cases.push(createGuard(lexer, ruleName, tkey, val));
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
const def = lexer.defaultToken;
|
|
288
|
+
return {
|
|
289
|
+
test: function (id, matches, state, eos) {
|
|
290
|
+
for (const _case of cases) {
|
|
291
|
+
const didmatch = (!_case.test || _case.test(id, matches, state, eos));
|
|
292
|
+
if (didmatch) {
|
|
293
|
+
return _case.value;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return def;
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
throw createError(lexer, 'an action must be a string, an object with a \'token\' or \'cases\' attribute, or an array of actions; in rule: ' + ruleName);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
class Rule {
|
|
305
|
+
constructor(name) {
|
|
306
|
+
this.regex = ( new RegExp(''));
|
|
307
|
+
this.action = { token: '' };
|
|
308
|
+
this.matchOnlyAtLineStart = false;
|
|
309
|
+
this.name = '';
|
|
310
|
+
this.name = name;
|
|
311
|
+
}
|
|
312
|
+
setRegex(lexer, re) {
|
|
313
|
+
let sregex;
|
|
314
|
+
if (typeof (re) === 'string') {
|
|
315
|
+
sregex = re;
|
|
316
|
+
}
|
|
317
|
+
else if (re instanceof RegExp) {
|
|
318
|
+
sregex = re.source;
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
throw createError(lexer, 'rules must start with a match string or regular expression: ' + this.name);
|
|
322
|
+
}
|
|
323
|
+
this.matchOnlyAtLineStart = (sregex.length > 0 && sregex[0] === '^');
|
|
324
|
+
this.name = this.name + ': ' + sregex;
|
|
325
|
+
this.regex = compileRegExp(lexer, '^(?:' + (this.matchOnlyAtLineStart ? sregex.substr(1) : sregex) + ')', true);
|
|
326
|
+
}
|
|
327
|
+
setAction(lexer, act) {
|
|
328
|
+
this.action = compileAction(lexer, this.name, act);
|
|
329
|
+
}
|
|
330
|
+
resolveRegex(state) {
|
|
331
|
+
if (this.regex instanceof RegExp) {
|
|
332
|
+
return this.regex;
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
return this.regex(state);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
function compile(languageId, json) {
|
|
340
|
+
if (!json || typeof (json) !== 'object') {
|
|
341
|
+
throw ( new Error('Monarch: expecting a language definition object'));
|
|
342
|
+
}
|
|
343
|
+
const lexer = {
|
|
344
|
+
languageId: languageId,
|
|
345
|
+
includeLF: bool(json.includeLF, false),
|
|
346
|
+
noThrow: false,
|
|
347
|
+
maxStack: 100,
|
|
348
|
+
start: (typeof json.start === 'string' ? json.start : null),
|
|
349
|
+
ignoreCase: bool(json.ignoreCase, false),
|
|
350
|
+
unicode: bool(json.unicode, false),
|
|
351
|
+
tokenPostfix: string(json.tokenPostfix, '.' + languageId),
|
|
352
|
+
defaultToken: string(json.defaultToken, 'source'),
|
|
353
|
+
usesEmbedded: false,
|
|
354
|
+
stateNames: {},
|
|
355
|
+
tokenizer: {},
|
|
356
|
+
brackets: []
|
|
357
|
+
};
|
|
358
|
+
const lexerMin = json;
|
|
359
|
+
lexerMin.languageId = languageId;
|
|
360
|
+
lexerMin.includeLF = lexer.includeLF;
|
|
361
|
+
lexerMin.ignoreCase = lexer.ignoreCase;
|
|
362
|
+
lexerMin.unicode = lexer.unicode;
|
|
363
|
+
lexerMin.noThrow = lexer.noThrow;
|
|
364
|
+
lexerMin.usesEmbedded = lexer.usesEmbedded;
|
|
365
|
+
lexerMin.stateNames = json.tokenizer;
|
|
366
|
+
lexerMin.defaultToken = lexer.defaultToken;
|
|
367
|
+
function addRules(state, newrules, rules) {
|
|
368
|
+
for (const rule of rules) {
|
|
369
|
+
let include = rule.include;
|
|
370
|
+
if (include) {
|
|
371
|
+
if (typeof (include) !== 'string') {
|
|
372
|
+
throw createError(lexer, 'an \'include\' attribute must be a string at: ' + state);
|
|
373
|
+
}
|
|
374
|
+
if (include[0] === '@') {
|
|
375
|
+
include = include.substr(1);
|
|
376
|
+
}
|
|
377
|
+
if (!json.tokenizer[include]) {
|
|
378
|
+
throw createError(lexer, 'include target \'' + include + '\' is not defined at: ' + state);
|
|
379
|
+
}
|
|
380
|
+
addRules(state + '.' + include, newrules, json.tokenizer[include]);
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
const newrule = ( new Rule(state));
|
|
384
|
+
if (Array.isArray(rule) && rule.length >= 1 && rule.length <= 3) {
|
|
385
|
+
newrule.setRegex(lexerMin, rule[0]);
|
|
386
|
+
if (rule.length >= 3) {
|
|
387
|
+
if (typeof (rule[1]) === 'string') {
|
|
388
|
+
newrule.setAction(lexerMin, { token: rule[1], next: rule[2] });
|
|
389
|
+
}
|
|
390
|
+
else if (typeof (rule[1]) === 'object') {
|
|
391
|
+
const rule1 = rule[1];
|
|
392
|
+
rule1.next = rule[2];
|
|
393
|
+
newrule.setAction(lexerMin, rule1);
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
throw createError(lexer, 'a next state as the last element of a rule can only be given if the action is either an object or a string, at: ' + state);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
newrule.setAction(lexerMin, rule[1]);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
if (!rule.regex) {
|
|
405
|
+
throw createError(lexer, 'a rule must either be an array, or an object with a \'regex\' or \'include\' field at: ' + state);
|
|
406
|
+
}
|
|
407
|
+
if (rule.name) {
|
|
408
|
+
if (typeof rule.name === 'string') {
|
|
409
|
+
newrule.name = rule.name;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (rule.matchOnlyAtStart) {
|
|
413
|
+
newrule.matchOnlyAtLineStart = bool(rule.matchOnlyAtLineStart, false);
|
|
414
|
+
}
|
|
415
|
+
newrule.setRegex(lexerMin, rule.regex);
|
|
416
|
+
newrule.setAction(lexerMin, rule.action);
|
|
417
|
+
}
|
|
418
|
+
newrules.push(newrule);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
if (!json.tokenizer || typeof (json.tokenizer) !== 'object') {
|
|
423
|
+
throw createError(lexer, 'a language definition must define the \'tokenizer\' attribute as an object');
|
|
424
|
+
}
|
|
425
|
+
lexer.tokenizer = [];
|
|
426
|
+
for (const key in json.tokenizer) {
|
|
427
|
+
if (json.tokenizer.hasOwnProperty(key)) {
|
|
428
|
+
if (!lexer.start) {
|
|
429
|
+
lexer.start = key;
|
|
430
|
+
}
|
|
431
|
+
const rules = json.tokenizer[key];
|
|
432
|
+
lexer.tokenizer[key] = ( new Array());
|
|
433
|
+
addRules('tokenizer.' + key, lexer.tokenizer[key], rules);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
lexer.usesEmbedded = lexerMin.usesEmbedded;
|
|
437
|
+
if (json.brackets) {
|
|
438
|
+
if (!(Array.isArray(json.brackets))) {
|
|
439
|
+
throw createError(lexer, 'the \'brackets\' attribute must be defined as an array');
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
json.brackets = [
|
|
444
|
+
{ open: '{', close: '}', token: 'delimiter.curly' },
|
|
445
|
+
{ open: '[', close: ']', token: 'delimiter.square' },
|
|
446
|
+
{ open: '(', close: ')', token: 'delimiter.parenthesis' },
|
|
447
|
+
{ open: '<', close: '>', token: 'delimiter.angle' }
|
|
448
|
+
];
|
|
449
|
+
}
|
|
450
|
+
const brackets = [];
|
|
451
|
+
for (const el of json.brackets) {
|
|
452
|
+
let desc = el;
|
|
453
|
+
if (desc && Array.isArray(desc) && desc.length === 3) {
|
|
454
|
+
desc = { token: desc[2], open: desc[0], close: desc[1] };
|
|
455
|
+
}
|
|
456
|
+
if (desc.open === desc.close) {
|
|
457
|
+
throw createError(lexer, 'open and close brackets in a \'brackets\' attribute must be different: ' + desc.open +
|
|
458
|
+
'\n hint: use the \'bracket\' attribute if matching on equal brackets is required.');
|
|
459
|
+
}
|
|
460
|
+
if (typeof desc.open === 'string' && typeof desc.token === 'string' && typeof desc.close === 'string') {
|
|
461
|
+
brackets.push({
|
|
462
|
+
token: desc.token + lexer.tokenPostfix,
|
|
463
|
+
open: fixCase(lexer, desc.open),
|
|
464
|
+
close: fixCase(lexer, desc.close)
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
else {
|
|
468
|
+
throw createError(lexer, 'every element in the \'brackets\' array must be a \'{open,close,token}\' object or array');
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
lexer.brackets = brackets;
|
|
472
|
+
lexer.noThrow = true;
|
|
473
|
+
return lexer;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
export { compile };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Disposable, IDisposable } from "vscode/vscode/vs/base/common/lifecycle";
|
|
2
|
+
import * as languages from "vscode/vscode/vs/editor/common/languages";
|
|
3
|
+
import { ILanguageService } from "vscode/vscode/vs/editor/common/languages/language";
|
|
4
|
+
import * as monarchCommon from "./monarchCommon.js";
|
|
5
|
+
import { IStandaloneThemeService } from "vscode/vscode/vs/editor/standalone/common/standaloneTheme";
|
|
6
|
+
import { IConfigurationService } from "vscode/vscode/vs/platform/configuration/common/configuration.service";
|
|
7
|
+
export type ILoadStatus = {
|
|
8
|
+
loaded: true;
|
|
9
|
+
} | {
|
|
10
|
+
loaded: false;
|
|
11
|
+
promise: Promise<void>;
|
|
12
|
+
};
|
|
13
|
+
export declare class MonarchTokenizer extends Disposable implements languages.ITokenizationSupport, IDisposable {
|
|
14
|
+
private readonly _configurationService;
|
|
15
|
+
private readonly _languageService;
|
|
16
|
+
private readonly _standaloneThemeService;
|
|
17
|
+
private readonly _languageId;
|
|
18
|
+
private readonly _lexer;
|
|
19
|
+
private readonly _embeddedLanguages;
|
|
20
|
+
embeddedLoaded: Promise<void>;
|
|
21
|
+
private _maxTokenizationLineLength;
|
|
22
|
+
constructor(languageService: ILanguageService, standaloneThemeService: IStandaloneThemeService, languageId: string, lexer: monarchCommon.ILexer, _configurationService: IConfigurationService);
|
|
23
|
+
getLoadStatus(): ILoadStatus;
|
|
24
|
+
getInitialState(): languages.IState;
|
|
25
|
+
tokenize(line: string, hasEOL: boolean, lineState: languages.IState): languages.TokenizationResult;
|
|
26
|
+
tokenizeEncoded(line: string, hasEOL: boolean, lineState: languages.IState): languages.EncodedTokenizationResult;
|
|
27
|
+
private _tokenize;
|
|
28
|
+
private _findLeavingNestedLanguageOffset;
|
|
29
|
+
private _nestedTokenize;
|
|
30
|
+
private _safeRuleName;
|
|
31
|
+
private _myTokenize;
|
|
32
|
+
private _getNestedEmbeddedLanguageData;
|
|
33
|
+
}
|