@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.
@@ -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<"b" | "f" | "'" | "\"" | "n" | "r" | "t" | "\\", string>;
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;
@@ -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" | "b" | "B" | "d" | "D" | "f" | "F" | "l" | "L" | "s" | "S" | "." | "i" | "p" | "-" | "+" | "e" | "a" | "c" | "g" | "h" | "j" | "k" | "m" | "n" | "o" | "q" | "r" | "t" | "u" | "v" | "w" | "x" | "y" | "z" | "_" | "A" | "C" | "E" | "G" | "H" | "I" | "J" | "K" | "M" | "N" | "O" | "P" | "Q" | "R" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z">;
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" | "b" | "B" | "d" | "D" | "f" | "F" | "l" | "L" | "s" | "S" | "." | "i" | "p" | "-" | "+" | "e" | "a" | "c" | "g" | "h" | "j" | "k" | "m" | "n" | "o" | "q" | "r" | "t" | "u" | "v" | "w" | "x" | "y" | "z" | "_" | "A" | "C" | "E" | "G" | "H" | "I" | "J" | "K" | "M" | "N" | "O" | "P" | "Q" | "R" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z">;
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(`[CacheService#load] path = “${filePath}”`, e);
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
@@ -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.
@@ -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
- // Remove all symbol locations contributed by URI binders if the parameter is an array.
513
- // Otherwise only remove the ones associated with the specified URI.
514
- ctx.symbols.clear({ contributor: 'uri_binder', uri: Array.isArray(param) ? undefined : param });
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.check(doc, node);
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.check(result.doc, node);
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
@@ -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;
@@ -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);