@spyglassmc/core 0.1.0 → 0.1.1
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/lib/node/StringNode.d.ts +1 -1
- package/lib/parser/string.d.ts +2 -2
- package/lib/processor/checker/builtin.d.ts +1 -0
- package/lib/processor/checker/builtin.js +10 -1
- package/lib/processor/linter/builtin.js +0 -5
- package/lib/service/CacheService.js +17 -3
- package/lib/service/Project.d.ts +2 -0
- package/lib/service/Project.js +40 -10
- package/lib/source/Source.d.ts +3 -0
- package/lib/source/Source.js +28 -0
- package/lib/symbol/Symbol.d.ts +5 -5
- package/package.json +2 -2
- package/lib/common/Heap.d.ts +0 -1
- package/lib/common/Heap.js +0 -2
- package/lib/node/TableNode.d.ts +0 -17
- package/lib/node/TableNode.js +0 -11
- package/lib/parser/table.d.ts +0 -22
- package/lib/parser/table.js +0 -97
- package/lib/service/CommandExecutor.d.ts +0 -3
- package/lib/service/CommandExecutor.js +0 -7
package/lib/node/StringNode.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export declare type EscapeChar = typeof EscapeChars[number];
|
|
|
7
7
|
export declare namespace EscapeChar {
|
|
8
8
|
function is(expected: EscapeChar[] | undefined, c: string): c is EscapeChar;
|
|
9
9
|
}
|
|
10
|
-
export declare const EscapeTable: Map<"
|
|
10
|
+
export declare const EscapeTable: Map<"\"" | "'" | "b" | "f" | "n" | "r" | "t" | "\\", string>;
|
|
11
11
|
export declare type Quote = "'" | '"';
|
|
12
12
|
export interface StringOptions {
|
|
13
13
|
colorTokenType?: ColorTokenType;
|
package/lib/parser/string.d.ts
CHANGED
|
@@ -6,11 +6,11 @@ import type { Parser, Result, Returnable } from './Parser';
|
|
|
6
6
|
export declare function string(options: StringOptions): InfallibleParser<StringNode>;
|
|
7
7
|
export declare function parseStringValue<T extends Returnable>(parser: Parser<T>, value: string, map: IndexMap, ctx: ParserContext): Result<T>;
|
|
8
8
|
export declare const BrigadierUnquotableCharacters: readonly ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "_", ".", "+", "-"];
|
|
9
|
-
export declare const BrigadierUnquotableCharacterSet: Set<"0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "
|
|
9
|
+
export declare const BrigadierUnquotableCharacterSet: Set<"0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "." | "i" | "p" | "-" | "+" | "e" | "a" | "b" | "c" | "d" | "f" | "g" | "h" | "j" | "k" | "l" | "m" | "n" | "o" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" | "_" | "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z">;
|
|
10
10
|
export declare const BrigadierUnquotablePattern: RegExp;
|
|
11
11
|
export declare const BrigadierUnquotableOption: {
|
|
12
12
|
allowEmpty: boolean;
|
|
13
|
-
allowList: Set<"0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "
|
|
13
|
+
allowList: Set<"0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "." | "i" | "p" | "-" | "+" | "e" | "a" | "b" | "c" | "d" | "f" | "g" | "h" | "j" | "k" | "l" | "m" | "n" | "o" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" | "_" | "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z">;
|
|
14
14
|
};
|
|
15
15
|
export declare const BrigadierStringOptions: StringOptions;
|
|
16
16
|
export declare const brigadierString: InfallibleParser<StringNode>;
|
|
@@ -17,6 +17,7 @@ export declare const noop: SyncChecker<AstNode>;
|
|
|
17
17
|
* Use the shallowest children that have their own checker to validate.
|
|
18
18
|
*/
|
|
19
19
|
export declare const fallback: Checker<AstNode>;
|
|
20
|
+
export declare const dispatchSync: SyncChecker<AstNode>;
|
|
20
21
|
export declare const resourceLocation: Checker<ResourceLocationNode>;
|
|
21
22
|
export declare const symbol: Checker<SymbolBaseNode>;
|
|
22
23
|
export declare function registerCheckers(meta: MetaRegistry): void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.registerCheckers = exports.symbol = exports.resourceLocation = exports.fallback = exports.noop = exports.any = exports.attempt = void 0;
|
|
3
|
+
exports.registerCheckers = exports.symbol = exports.resourceLocation = exports.dispatchSync = exports.fallback = exports.noop = exports.any = exports.attempt = void 0;
|
|
4
4
|
const lib_1 = require("../../../../locales/lib");
|
|
5
5
|
const node_1 = require("../../node");
|
|
6
6
|
const service_1 = require("../../service");
|
|
@@ -61,6 +61,15 @@ const fallback = async (node, ctx) => {
|
|
|
61
61
|
await Promise.allSettled(promises);
|
|
62
62
|
};
|
|
63
63
|
exports.fallback = fallback;
|
|
64
|
+
const dispatchSync = (node, ctx) => {
|
|
65
|
+
for (const child of node.children ?? []) {
|
|
66
|
+
if (ctx.meta.hasChecker(child.type)) {
|
|
67
|
+
const checker = ctx.meta.getChecker(child.type);
|
|
68
|
+
checker(child, ctx);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
exports.dispatchSync = dispatchSync;
|
|
64
73
|
const resourceLocation = (node, ctx) => {
|
|
65
74
|
const full = node_1.ResourceLocationNode.toString(node, 'full');
|
|
66
75
|
if (node.options.pool) {
|
|
@@ -85,11 +85,6 @@ var configValidator;
|
|
|
85
85
|
configValidator.symbolLinterConfig = symbolLinterConfig;
|
|
86
86
|
})(configValidator = exports.configValidator || (exports.configValidator = {}));
|
|
87
87
|
function registerLinters(meta) {
|
|
88
|
-
meta.registerLinter('nameOfNbtKey', {
|
|
89
|
-
configValidator: configValidator.nameConvention,
|
|
90
|
-
linter: nameConvention('value'),
|
|
91
|
-
nodePredicate: n => n.parent?.parent?.type === 'nbt:compound' && n.parent.type === 'pair' && n.type === 'string',
|
|
92
|
-
});
|
|
93
88
|
meta.registerLinter('nameOfObjective', {
|
|
94
89
|
configValidator: configValidator.nameConvention,
|
|
95
90
|
linter: nameConvention('value'),
|
|
@@ -13,7 +13,7 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
13
13
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
15
|
};
|
|
16
|
-
var _CacheService_cacheFilePath;
|
|
16
|
+
var _CacheService_hasValidatedFiles, _CacheService_cacheFilePath;
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.CacheService = exports.LatestCacheVersion = void 0;
|
|
19
19
|
const path_1 = __importDefault(require("path"));
|
|
@@ -45,8 +45,17 @@ class CacheService {
|
|
|
45
45
|
this.cacheRoot = cacheRoot;
|
|
46
46
|
this.project = project;
|
|
47
47
|
this.checksums = Checksums.create();
|
|
48
|
+
_CacheService_hasValidatedFiles.set(this, false
|
|
49
|
+
/**
|
|
50
|
+
* @param cacheRoot File path to the directory where cache files by Spyglass should be stored.
|
|
51
|
+
* @param project
|
|
52
|
+
*/
|
|
53
|
+
);
|
|
48
54
|
_CacheService_cacheFilePath.set(this, void 0);
|
|
49
55
|
this.project.on('documentUpdated', ({ doc }) => {
|
|
56
|
+
if (!__classPrivateFieldGet(this, _CacheService_hasValidatedFiles, "f")) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
50
59
|
try {
|
|
51
60
|
// TODO: Don't update this for every single change.
|
|
52
61
|
this.checksums.files[doc.uri] = (0, common_1.getSha1)(doc.getText());
|
|
@@ -58,6 +67,9 @@ class CacheService {
|
|
|
58
67
|
}
|
|
59
68
|
});
|
|
60
69
|
this.project.on('rootsUpdated', async ({ roots }) => {
|
|
70
|
+
if (!__classPrivateFieldGet(this, _CacheService_hasValidatedFiles, "f")) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
61
73
|
for (const root of roots) {
|
|
62
74
|
try {
|
|
63
75
|
this.checksums.roots[root] = await this.project.fs.hash(root);
|
|
@@ -89,6 +101,7 @@ class CacheService {
|
|
|
89
101
|
let filePath;
|
|
90
102
|
try {
|
|
91
103
|
filePath = this.getCacheFilePath();
|
|
104
|
+
this.project.logger.info(`[CacheService#load] symbolCachePath = “${filePath}”`);
|
|
92
105
|
const cache = await fileUtil_1.fileUtil.readGzippedJson(filePath);
|
|
93
106
|
__profiler.task('Read File');
|
|
94
107
|
if (cache.version === exports.LatestCacheVersion) {
|
|
@@ -102,7 +115,7 @@ class CacheService {
|
|
|
102
115
|
}
|
|
103
116
|
catch (e) {
|
|
104
117
|
if (!(0, common_1.isEnoent)(e)) {
|
|
105
|
-
this.project.logger.error(
|
|
118
|
+
this.project.logger.error('[CacheService#load] ', e);
|
|
106
119
|
}
|
|
107
120
|
}
|
|
108
121
|
__profiler.finalize();
|
|
@@ -160,6 +173,7 @@ class CacheService {
|
|
|
160
173
|
ans.addedFiles.push(uri);
|
|
161
174
|
}
|
|
162
175
|
}
|
|
176
|
+
__classPrivateFieldSet(this, _CacheService_hasValidatedFiles, true, "f");
|
|
163
177
|
return ans;
|
|
164
178
|
}
|
|
165
179
|
/**
|
|
@@ -191,5 +205,5 @@ class CacheService {
|
|
|
191
205
|
}
|
|
192
206
|
}
|
|
193
207
|
exports.CacheService = CacheService;
|
|
194
|
-
_CacheService_cacheFilePath = new WeakMap();
|
|
208
|
+
_CacheService_hasValidatedFiles = new WeakMap(), _CacheService_cacheFilePath = new WeakMap();
|
|
195
209
|
//# sourceMappingURL=CacheService.js.map
|
package/lib/service/Project.d.ts
CHANGED
|
@@ -84,6 +84,7 @@ export declare class Project extends EventEmitter {
|
|
|
84
84
|
#private;
|
|
85
85
|
private static readonly RootSuffix;
|
|
86
86
|
readonly cacheService: CacheService;
|
|
87
|
+
get isReady(): boolean;
|
|
87
88
|
config: Config;
|
|
88
89
|
readonly downloader: Downloader;
|
|
89
90
|
readonly fs: FileService;
|
|
@@ -150,6 +151,7 @@ export declare class Project extends EventEmitter {
|
|
|
150
151
|
private lint;
|
|
151
152
|
ensureLinted(doc: TextDocument, node: FileNode<AstNode>): void;
|
|
152
153
|
ensureParsedAndChecked(uri: string): Promise<DocAndNode | undefined>;
|
|
154
|
+
ensureParsedAndCheckedOnlyWhenReady(uri: string): Promise<DocAndNode | undefined>;
|
|
153
155
|
private bind;
|
|
154
156
|
/**
|
|
155
157
|
* Notify that a new document was opened in the editor.
|
package/lib/service/Project.js
CHANGED
|
@@ -19,7 +19,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
19
19
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
20
20
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
21
21
|
};
|
|
22
|
-
var _Project_cacheSaverIntervalId, _Project_clientManagedUris, _Project_configService, _Project_docAndNodes, _Project_initializers, _Project_initPromise, _Project_readyPromise, _Project_watchedFiles, _Project_watcher, _Project_watcherReady, _Project_dependencyRoots, _Project_dependencyFiles, _Project_roots, _Project_ctx, _Project_cacheRoot;
|
|
22
|
+
var _Project_cacheSaverIntervalId, _Project_clientManagedUris, _Project_configService, _Project_docAndNodes, _Project_initializers, _Project_initPromise, _Project_readyPromise, _Project_watchedFiles, _Project_watcher, _Project_watcherReady, _Project_isReady, _Project_dependencyRoots, _Project_dependencyFiles, _Project_roots, _Project_ctx, _Project_cacheRoot;
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
24
|
exports.Project = exports.ProjectData = void 0;
|
|
25
25
|
const chokidar_1 = __importDefault(require("chokidar"));
|
|
@@ -89,6 +89,7 @@ class Project extends events_1.default {
|
|
|
89
89
|
_Project_watchedFiles.set(this, new Set());
|
|
90
90
|
_Project_watcher.set(this, void 0);
|
|
91
91
|
_Project_watcherReady.set(this, false);
|
|
92
|
+
_Project_isReady.set(this, false);
|
|
92
93
|
this.meta = new MetaRegistry_1.MetaRegistry();
|
|
93
94
|
_Project_dependencyRoots.set(this, void 0);
|
|
94
95
|
_Project_dependencyFiles.set(this, void 0);
|
|
@@ -129,6 +130,9 @@ class Project extends events_1.default {
|
|
|
129
130
|
__classPrivateFieldSet(this, _Project_cacheSaverIntervalId, setInterval(() => this.cacheService.save(), CacheAutoSaveInterval), "f");
|
|
130
131
|
this
|
|
131
132
|
.on('documentUpdated', ({ doc, node }) => {
|
|
133
|
+
if (!__classPrivateFieldGet(this, _Project_isReady, "f")) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
132
136
|
this.emit('documentErrorred', {
|
|
133
137
|
doc,
|
|
134
138
|
errors: node_1.FileNode.getErrors(node),
|
|
@@ -136,7 +140,6 @@ class Project extends events_1.default {
|
|
|
136
140
|
});
|
|
137
141
|
})
|
|
138
142
|
.on('fileCreated', async ({ uri }) => {
|
|
139
|
-
__classPrivateFieldGet(this, _Project_watchedFiles, "f").add(uri);
|
|
140
143
|
if (uri.endsWith(Project.RootSuffix)) {
|
|
141
144
|
this.updateRoots();
|
|
142
145
|
}
|
|
@@ -150,14 +153,28 @@ class Project extends events_1.default {
|
|
|
150
153
|
}
|
|
151
154
|
})
|
|
152
155
|
.on('fileDeleted', ({ uri }) => {
|
|
153
|
-
__classPrivateFieldGet(this, _Project_watchedFiles, "f").delete(uri);
|
|
154
156
|
if (uri.endsWith(Project.RootSuffix)) {
|
|
155
157
|
this.updateRoots();
|
|
156
158
|
}
|
|
157
159
|
this.symbols.clear({ uri });
|
|
158
160
|
this.tryClearingCache(uri);
|
|
161
|
+
})
|
|
162
|
+
.on('ready', () => {
|
|
163
|
+
__classPrivateFieldSet(this, _Project_isReady, true, "f");
|
|
164
|
+
// Recheck client managed files.
|
|
165
|
+
const promises = [];
|
|
166
|
+
for (const uri of __classPrivateFieldGet(this, _Project_clientManagedUris, "f")) {
|
|
167
|
+
const result = __classPrivateFieldGet(this, _Project_docAndNodes, "f").get(uri);
|
|
168
|
+
if (result) {
|
|
169
|
+
promises.push(this.check(result.doc, result.node));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
Promise.all(promises).catch(e => this.logger.error('[Project#ready] Error occurred when rechecking client managed files after ready', e));
|
|
159
173
|
});
|
|
160
174
|
}
|
|
175
|
+
get isReady() {
|
|
176
|
+
return __classPrivateFieldGet(this, _Project_isReady, "f");
|
|
177
|
+
}
|
|
161
178
|
/**
|
|
162
179
|
* All tracked root URIs. Each URI in this array is guaranteed to end with a slash (`/`).
|
|
163
180
|
*
|
|
@@ -360,7 +377,6 @@ class Project extends events_1.default {
|
|
|
360
377
|
return this;
|
|
361
378
|
}
|
|
362
379
|
async ready() {
|
|
363
|
-
await __classPrivateFieldGet(this, _Project_initPromise, "f");
|
|
364
380
|
await __classPrivateFieldGet(this, _Project_readyPromise, "f");
|
|
365
381
|
return this;
|
|
366
382
|
}
|
|
@@ -507,11 +523,18 @@ class Project extends events_1.default {
|
|
|
507
523
|
}
|
|
508
524
|
return result;
|
|
509
525
|
}
|
|
526
|
+
async ensureParsedAndCheckedOnlyWhenReady(uri) {
|
|
527
|
+
const result = await this.ensureParsed(uri);
|
|
528
|
+
if (__classPrivateFieldGet(this, _Project_isReady, "f") && result) {
|
|
529
|
+
await this.ensureChecked(result.doc, result.node);
|
|
530
|
+
}
|
|
531
|
+
return result;
|
|
532
|
+
}
|
|
510
533
|
bind(param) {
|
|
511
534
|
const ctx = Context_1.UriBinderContext.create(this);
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
535
|
+
if (typeof param === 'string') {
|
|
536
|
+
ctx.symbols.clear({ contributor: 'uri_binder', uri: param });
|
|
537
|
+
}
|
|
515
538
|
ctx.symbols.contributeAs('uri_binder', () => {
|
|
516
539
|
const uris = Array.isArray(param) ? param : [param];
|
|
517
540
|
for (const binder of this.meta.uriBinders) {
|
|
@@ -527,7 +550,9 @@ class Project extends events_1.default {
|
|
|
527
550
|
__classPrivateFieldGet(this, _Project_clientManagedUris, "f").add(uri);
|
|
528
551
|
const doc = vscode_languageserver_textdocument_1.TextDocument.create(uri, languageID, version, content);
|
|
529
552
|
const { node } = this.parseAndCache(doc);
|
|
530
|
-
this
|
|
553
|
+
if (__classPrivateFieldGet(this, _Project_isReady, "f")) {
|
|
554
|
+
this.check(doc, node);
|
|
555
|
+
}
|
|
531
556
|
}
|
|
532
557
|
/**
|
|
533
558
|
* Notify that an existing document was changed in the editor.
|
|
@@ -541,7 +566,9 @@ class Project extends events_1.default {
|
|
|
541
566
|
}
|
|
542
567
|
vscode_languageserver_textdocument_1.TextDocument.update(result.doc, changes, version);
|
|
543
568
|
const { node } = this.parseAndCache(result.doc);
|
|
544
|
-
this
|
|
569
|
+
if (__classPrivateFieldGet(this, _Project_isReady, "f")) {
|
|
570
|
+
this.check(result.doc, node);
|
|
571
|
+
}
|
|
545
572
|
}
|
|
546
573
|
/**
|
|
547
574
|
* Notify that an existing document was closed in the editor.
|
|
@@ -575,7 +602,7 @@ class Project extends events_1.default {
|
|
|
575
602
|
return __classPrivateFieldGet(this, _Project_watchedFiles, "f").has(uri) && !__classPrivateFieldGet(this, _Project_clientManagedUris, "f").has(uri) && !__classPrivateFieldGet(this, _Project_dependencyFiles, "f").has(uri);
|
|
576
603
|
}
|
|
577
604
|
}
|
|
578
|
-
_Project_cacheSaverIntervalId = new WeakMap(), _Project_clientManagedUris = new WeakMap(), _Project_configService = new WeakMap(), _Project_docAndNodes = new WeakMap(), _Project_initializers = new WeakMap(), _Project_initPromise = new WeakMap(), _Project_readyPromise = new WeakMap(), _Project_watchedFiles = new WeakMap(), _Project_watcher = new WeakMap(), _Project_watcherReady = new WeakMap(), _Project_dependencyRoots = new WeakMap(), _Project_dependencyFiles = new WeakMap(), _Project_roots = new WeakMap(), _Project_ctx = new WeakMap(), _Project_cacheRoot = new WeakMap();
|
|
605
|
+
_Project_cacheSaverIntervalId = new WeakMap(), _Project_clientManagedUris = new WeakMap(), _Project_configService = new WeakMap(), _Project_docAndNodes = new WeakMap(), _Project_initializers = new WeakMap(), _Project_initPromise = new WeakMap(), _Project_readyPromise = new WeakMap(), _Project_watchedFiles = new WeakMap(), _Project_watcher = new WeakMap(), _Project_watcherReady = new WeakMap(), _Project_isReady = new WeakMap(), _Project_dependencyRoots = new WeakMap(), _Project_dependencyFiles = new WeakMap(), _Project_roots = new WeakMap(), _Project_ctx = new WeakMap(), _Project_cacheRoot = new WeakMap();
|
|
579
606
|
Project.RootSuffix = '/pack.mcmeta';
|
|
580
607
|
__decorate([
|
|
581
608
|
(0, common_1.CachePromise)()
|
|
@@ -589,5 +616,8 @@ __decorate([
|
|
|
589
616
|
__decorate([
|
|
590
617
|
(0, common_1.CachePromise)()
|
|
591
618
|
], Project.prototype, "ensureParsedAndChecked", null);
|
|
619
|
+
__decorate([
|
|
620
|
+
(0, common_1.CachePromise)()
|
|
621
|
+
], Project.prototype, "ensureParsedAndCheckedOnlyWhenReady", null);
|
|
592
622
|
exports.Project = Project;
|
|
593
623
|
//# sourceMappingURL=Project.js.map
|
package/lib/source/Source.d.ts
CHANGED
|
@@ -38,6 +38,9 @@ export declare class ReadonlySource {
|
|
|
38
38
|
* @see {@link Source.trySkip}
|
|
39
39
|
*/
|
|
40
40
|
tryPeek(expectedValue: string): boolean;
|
|
41
|
+
peekUntil(...terminators: string[]): string;
|
|
42
|
+
peekLine(): string;
|
|
43
|
+
hasNonSpaceAheadInLine(): boolean;
|
|
41
44
|
slice(start: number, end?: number): string;
|
|
42
45
|
slice(rangeLike: Range | RangeContainer): string;
|
|
43
46
|
sliceToCursor(start: number): string;
|
package/lib/source/Source.js
CHANGED
|
@@ -45,6 +45,34 @@ class ReadonlySource {
|
|
|
45
45
|
tryPeek(expectedValue) {
|
|
46
46
|
return this.peek(expectedValue.length) === expectedValue;
|
|
47
47
|
}
|
|
48
|
+
peekUntil(...terminators) {
|
|
49
|
+
let ans = '';
|
|
50
|
+
for (let cursor = this.innerCursor; cursor < this.string.length; cursor++) {
|
|
51
|
+
const c = this.string.charAt(cursor);
|
|
52
|
+
if (terminators.includes(c)) {
|
|
53
|
+
return ans;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
ans += c;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return ans;
|
|
60
|
+
}
|
|
61
|
+
peekLine() {
|
|
62
|
+
return this.peekUntil(exports.CR, exports.LF);
|
|
63
|
+
}
|
|
64
|
+
hasNonSpaceAheadInLine() {
|
|
65
|
+
for (let cursor = this.innerCursor; cursor < this.string.length; cursor++) {
|
|
66
|
+
const c = this.string.charAt(cursor);
|
|
67
|
+
if (c === exports.CR || c === exports.LF) {
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
if (!(c === ' ' || c === '\t')) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
48
76
|
slice(param0, end) {
|
|
49
77
|
if (typeof param0 === 'number') {
|
|
50
78
|
const innerStart = _1.IndexMap.toInnerOffset(this.indexMap, param0);
|