@spyglassmc/core 0.4.0 → 0.4.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.
Files changed (56) hide show
  1. package/lib/common/Dev.js +5 -2
  2. package/lib/common/Operations.js +7 -3
  3. package/lib/common/ReadonlyProxy.js +3 -1
  4. package/lib/common/StateProxy.js +18 -7
  5. package/lib/common/externals/BrowserExternals.js +2 -9
  6. package/lib/common/externals/NodeJsExternals.js +7 -17
  7. package/lib/common/externals/index.d.ts +0 -3
  8. package/lib/common/util.d.ts +1 -0
  9. package/lib/common/util.js +14 -10
  10. package/lib/node/AstNode.js +6 -4
  11. package/lib/node/FileNode.js +6 -1
  12. package/lib/node/ResourceLocationNode.d.ts +2 -2
  13. package/lib/node/ResourceLocationNode.js +11 -5
  14. package/lib/parser/boolean.js +1 -1
  15. package/lib/parser/comment.d.ts +1 -1
  16. package/lib/parser/comment.js +1 -1
  17. package/lib/parser/float.js +2 -1
  18. package/lib/parser/integer.js +2 -1
  19. package/lib/parser/list.d.ts +1 -1
  20. package/lib/parser/list.js +3 -3
  21. package/lib/parser/long.js +2 -1
  22. package/lib/parser/record.d.ts +1 -1
  23. package/lib/parser/record.js +18 -8
  24. package/lib/parser/resourceLocation.js +61 -8
  25. package/lib/parser/string.js +75 -7
  26. package/lib/parser/util.js +7 -3
  27. package/lib/processor/ColorInfoProvider.js +20 -7
  28. package/lib/processor/binder/builtin.js +27 -17
  29. package/lib/processor/checker/builtin.d.ts +1 -2
  30. package/lib/processor/checker/builtin.js +10 -12
  31. package/lib/processor/colorizer/builtin.js +8 -7
  32. package/lib/processor/completer/Completer.js +4 -2
  33. package/lib/processor/completer/builtin.js +26 -23
  34. package/lib/processor/formatter/builtin.js +14 -12
  35. package/lib/processor/linter/builtin/undeclaredSymbol.js +47 -24
  36. package/lib/processor/linter/builtin.js +7 -8
  37. package/lib/service/CacheService.js +9 -6
  38. package/lib/service/Config.d.ts +2 -2
  39. package/lib/service/Config.js +23 -19
  40. package/lib/service/Downloader.js +12 -7
  41. package/lib/service/FileService.js +22 -8
  42. package/lib/service/MetaRegistry.js +7 -6
  43. package/lib/service/Profiler.js +10 -5
  44. package/lib/service/Project.js +36 -30
  45. package/lib/service/Service.js +19 -9
  46. package/lib/service/fileUtil.js +2 -1
  47. package/lib/source/IndexMap.js +1 -1
  48. package/lib/source/LanguageError.js +1 -1
  49. package/lib/source/Location.js +4 -1
  50. package/lib/source/Range.js +6 -3
  51. package/lib/source/Source.js +3 -1
  52. package/lib/symbol/Symbol.d.ts +7 -7
  53. package/lib/symbol/Symbol.js +22 -9
  54. package/lib/symbol/SymbolUtil.d.ts +2 -2
  55. package/lib/symbol/SymbolUtil.js +74 -43
  56. package/package.json +2 -2
package/lib/common/Dev.js CHANGED
@@ -26,7 +26,8 @@ export const Dev = Object.freeze({
26
26
  switch (typeof current) {
27
27
  case 'bigint': {
28
28
  const bits = Math.ceil(Math.log2(Number(current)));
29
- ans += (2 + Math.ceil(bits / (ByteToBits * PointerSize))) * PointerSize; // https://stackoverflow.com/a/54298760
29
+ ans +=
30
+ (2 + Math.ceil(bits / (ByteToBits * PointerSize))) * PointerSize; // https://stackoverflow.com/a/54298760
30
31
  break;
31
32
  }
32
33
  case 'boolean':
@@ -75,7 +76,9 @@ export const Dev = Object.freeze({
75
76
  catch (ignored) {
76
77
  // Most likely "Maximum callstack size exceeded".
77
78
  // Fall back to a shallow string representation.
78
- return `{ ${Object.entries(value).map(([k, v]) => `'${k}': '${String(v)}'`).join(', ')} }`;
79
+ return `{ ${Object.entries(value)
80
+ .map(([k, v]) => `'${k}': '${String(v)}'`)
81
+ .join(', ')} }`;
79
82
  }
80
83
  }
81
84
  else if (typeof value === 'symbol') {
@@ -15,8 +15,12 @@ export class Operations {
15
15
  }
16
16
  set(obj, key, value, receiver = obj) {
17
17
  const oldValue = Reflect.get(obj, key, receiver);
18
- const op = () => { Reflect.set(obj, key, value, receiver); };
19
- const undoOp = () => { Reflect.set(obj, key, oldValue, receiver); };
18
+ const op = () => {
19
+ Reflect.set(obj, key, value, receiver);
20
+ };
21
+ const undoOp = () => {
22
+ Reflect.set(obj, key, oldValue, receiver);
23
+ };
20
24
  this.addRedoOp(op);
21
25
  this.addUndoOp(undoOp);
22
26
  op();
@@ -27,7 +31,7 @@ export class Operations {
27
31
  }
28
32
  }
29
33
  redo() {
30
- this.redoOps.forEach(op => op());
34
+ this.redoOps.forEach((op) => op());
31
35
  }
32
36
  }
33
37
  //# sourceMappingURL=Operations.js.map
@@ -9,7 +9,9 @@ class ReadonlyProxyHandler {
9
9
  get(target, p, receiver) {
10
10
  const value = Reflect.get(target, p, receiver);
11
11
  if (p !== 'prototype' && isObject(value)) {
12
- return emplaceMap(this.map, p, { insert: () => ReadonlyProxy.create(value) });
12
+ return emplaceMap(this.map, p, {
13
+ insert: () => ReadonlyProxy.create(value),
14
+ });
13
15
  }
14
16
  return value;
15
17
  }
@@ -43,20 +43,31 @@ class StateProxyHandler {
43
43
  }
44
44
  get(target, p, receiver) {
45
45
  switch (p) {
46
- case BranchOff: return () => this.#branchOff(target);
47
- case Is: return true;
48
- case Origin: return target;
49
- case Redo: return () => this.rootOps.redo();
50
- case Undo: return () => this.rootOps.undo();
46
+ case BranchOff:
47
+ return () => this.#branchOff(target);
48
+ case Is:
49
+ return true;
50
+ case Origin:
51
+ return target;
52
+ case Redo:
53
+ return () => this.rootOps.redo();
54
+ case Undo:
55
+ return () => this.rootOps.undo();
51
56
  }
52
57
  const value = Reflect.get(target, p, receiver);
53
58
  if (p !== 'prototype' && isObject(value)) {
54
- return emplaceMap(this.map, p, { insert: () => _createStateProxy(value, this.rootOps) });
59
+ return emplaceMap(this.map, p, {
60
+ insert: () => _createStateProxy(value, this.rootOps),
61
+ });
55
62
  }
56
63
  return value;
57
64
  }
58
65
  set(target, p, value, receiver) {
59
- if (p === BranchOff || p === Is || p === Origin || p === Redo || p === Undo) {
66
+ if (p === BranchOff ||
67
+ p === Is ||
68
+ p === Origin ||
69
+ p === Redo ||
70
+ p === Undo) {
60
71
  throw new TypeError(`Cannot set ${String(p)}`);
61
72
  }
62
73
  this.rootOps.set(target, p, StateProxy.dereference(value), receiver);
@@ -1,7 +1,6 @@
1
- import { decode as arrayBufferFromBase64, encode as arrayBufferToBase64 } from 'base64-arraybuffer';
1
+ import { decode as arrayBufferFromBase64, encode as arrayBufferToBase64, } from 'base64-arraybuffer';
2
2
  import pako from 'pako';
3
3
  import { fileUtil } from '../../service/fileUtil.js';
4
- import { Uri } from '../index.js';
5
4
  class BrowserEventEmitter {
6
5
  #listeners = new Map();
7
6
  emit(eventName, ...args) {
@@ -70,8 +69,7 @@ class BrowserFsWatcher {
70
69
  }
71
70
  return this;
72
71
  }
73
- async close() {
74
- }
72
+ async close() { }
75
73
  }
76
74
  class BrowserFileSystem {
77
75
  static LocalStorageKey = 'spyglassmc-browser-fs';
@@ -174,11 +172,6 @@ export const BrowserExternals = {
174
172
  EventEmitter: BrowserEventEmitter,
175
173
  },
176
174
  fs: new BrowserFileSystem(),
177
- uri: {
178
- normalize(uri) {
179
- return new Uri(uri).toString();
180
- },
181
- },
182
175
  };
183
176
  function uint8ArrayToHex(array) {
184
177
  let ans = '';
@@ -26,7 +26,7 @@ class NodeJsExternalDownloader {
26
26
  reject(new Error(`Status code ${res.statusCode}: ${res.statusMessage}`));
27
27
  }
28
28
  else {
29
- resolve(promisifyAsyncIterable(res, chunks => Buffer.concat(chunks)));
29
+ resolve(promisifyAsyncIterable(res, (chunks) => Buffer.concat(chunks)));
30
30
  }
31
31
  });
32
32
  });
@@ -71,7 +71,7 @@ export const NodeJsExternals = {
71
71
  return (await globby(toPath(location) + '**/*', { absolute: true, dot: true })).map(uriFromPath);
72
72
  },
73
73
  async mkdir(location, options) {
74
- return void await fsp.mkdir(toFsPathLike(location), options);
74
+ return void (await fsp.mkdir(toFsPathLike(location), options));
75
75
  },
76
76
  readFile(location) {
77
77
  return fsp.readFile(toFsPathLike(location));
@@ -90,7 +90,7 @@ export const NodeJsExternals = {
90
90
  command = 'xdg-open';
91
91
  break;
92
92
  }
93
- return void await execFile(command, [toPath(location)]);
93
+ return void (await execFile(command, [toPath(location)]));
94
94
  },
95
95
  stat(location) {
96
96
  return fsp.stat(toFsPathLike(location));
@@ -105,16 +105,6 @@ export const NodeJsExternals = {
105
105
  return fsp.writeFile(toFsPathLike(location), data, options);
106
106
  },
107
107
  },
108
- uri: {
109
- normalize(uri) {
110
- if (uri.startsWith('file:')) {
111
- return url.pathToFileURL(url.fileURLToPath(uri)).toString();
112
- }
113
- else {
114
- return new Uri(uri).toString();
115
- }
116
- },
117
- },
118
108
  };
119
109
  Object.freeze(NodeJsExternals);
120
110
  /**
@@ -140,10 +130,10 @@ class ChokidarWatcherWrapper extends EventEmitter {
140
130
  super();
141
131
  this.#watcher = watcher
142
132
  .on('ready', () => this.emit('ready'))
143
- .on('add', path => this.emit('add', uriFromPath(path)))
144
- .on('change', path => this.emit('change', uriFromPath(path)))
145
- .on('unlink', path => this.emit('unlink', uriFromPath(path)))
146
- .on('error', e => this.emit('error', e));
133
+ .on('add', (path) => this.emit('add', uriFromPath(path)))
134
+ .on('change', (path) => this.emit('change', uriFromPath(path)))
135
+ .on('unlink', (path) => this.emit('unlink', uriFromPath(path)))
136
+ .on('error', (e) => this.emit('error', e));
147
137
  }
148
138
  close() {
149
139
  return this.#watcher.close();
@@ -23,9 +23,6 @@ export interface Externals {
23
23
  EventEmitter: new () => ExternalEventEmitter;
24
24
  };
25
25
  fs: ExternalFileSystem;
26
- uri: {
27
- normalize: (uri: string) => string;
28
- };
29
26
  }
30
27
  export interface DecompressedFile {
31
28
  data: Uint8Array;
@@ -114,6 +114,7 @@ export declare function emplaceMap<K, V>(map: Map<K, V>, key: K, handler: {
114
114
  * @returns If `val` is an non-null object or a callable object (i.e. function).
115
115
  */
116
116
  export declare function isObject(val: unknown): val is object;
117
+ export declare function normalizeUri(uri: string): string;
117
118
  /**
118
119
  * @example
119
120
  * ```ts
@@ -9,7 +9,7 @@ export const Uri = URL;
9
9
  * This is a decorator for async methods. Decorated methods will return the same `Promise` for
10
10
  * the same key, provided that the previously returned `Promise` is still pending.
11
11
  */
12
- export function SingletonPromise(getKey = args => args[0]) {
12
+ export function SingletonPromise(getKey = (args) => args[0]) {
13
13
  return (_target, _key, descripter) => {
14
14
  const promises = new Map();
15
15
  const decoratedMethod = descripter.value;
@@ -19,8 +19,7 @@ export function SingletonPromise(getKey = args => args[0]) {
19
19
  if (promises.has(key)) {
20
20
  return promises.get(key);
21
21
  }
22
- const ans = decoratedMethod.apply(this, args)
23
- .then(ans => (promises.delete(key), ans), e => (promises.delete(key), Promise.reject(e)));
22
+ const ans = decoratedMethod.apply(this, args).then((ans) => (promises.delete(key), ans), (e) => (promises.delete(key), Promise.reject(e)));
24
23
  promises.set(key, ans);
25
24
  return ans;
26
25
  };
@@ -35,7 +34,7 @@ export const Singleton = (_target, _key, descripter) => {
35
34
  const decoratedMethod = descripter.value;
36
35
  // The `function` syntax is used to preserve `this` context from the decorated method.
37
36
  descripter.value = function (...args) {
38
- return value ??= decoratedMethod.apply(this, args);
37
+ return (value ??= decoratedMethod.apply(this, args));
39
38
  };
40
39
  return descripter;
41
40
  };
@@ -46,7 +45,7 @@ export const Singleton = (_target, _key, descripter) => {
46
45
  *
47
46
  * Decorated methods will be scheduled to run after `ms` milliseconds. The timer will reset when the method is called again.
48
47
  */
49
- export function Delay(ms, getKey = args => args[0]) {
48
+ export function Delay(ms, getKey = (args) => args[0]) {
50
49
  return (_target, _key, descripter) => {
51
50
  const timeouts = new Map();
52
51
  const decoratedMethod = descripter.value;
@@ -109,9 +108,7 @@ export function bufferToString(buffer) {
109
108
  export var Arrayable;
110
109
  (function (Arrayable) {
111
110
  function is(value, isT) {
112
- return Array.isArray(value)
113
- ? value.every(e => isT(e))
114
- : isT(value);
111
+ return Array.isArray(value) ? value.every((e) => isT(e)) : isT(value);
115
112
  }
116
113
  Arrayable.is = is;
117
114
  function toArray(value) {
@@ -178,7 +175,9 @@ export var Lazy;
178
175
  }
179
176
  Lazy.isUnresolved = isUnresolved;
180
177
  function resolve(lazy) {
181
- return isUnresolved(lazy) ? lazy.value = lazy.getter() : lazy;
178
+ return isUnresolved(lazy)
179
+ ? (lazy.value = lazy.getter())
180
+ : lazy;
182
181
  }
183
182
  Lazy.resolve = resolve;
184
183
  })(Lazy || (Lazy = {}));
@@ -195,7 +194,7 @@ export function getStates(category, ids, ctx) {
195
194
  .query(ctx.doc, category, id)
196
195
  .forEachMember((state, stateQuery) => {
197
196
  const values = Object.keys(stateQuery.visibleMembers);
198
- const set = ans[state] ??= new Set();
197
+ const set = (ans[state] ??= new Set());
199
198
  const defaultValue = stateQuery.symbol?.relations?.default;
200
199
  if (defaultValue) {
201
200
  set.add(defaultValue.path[defaultValue.path.length - 1]);
@@ -240,4 +239,9 @@ export function emplaceMap(map, key, handler) {
240
239
  export function isObject(val) {
241
240
  return typeof val === 'function' || (!!val && typeof val === 'object');
242
241
  }
242
+ export function normalizeUri(uri) {
243
+ const obj = new Uri(uri);
244
+ obj.pathname = obj.pathname.replace(/%3A/gi, ':');
245
+ return obj.toString();
246
+ }
243
247
  //# sourceMappingURL=util.js.map
@@ -4,8 +4,10 @@ export var AstNode;
4
4
  (function (AstNode) {
5
5
  /* istanbul ignore next */
6
6
  function is(obj) {
7
- return !!obj && typeof obj === 'object' && typeof obj.type === 'string' &&
8
- Range.is(obj.range);
7
+ return (!!obj &&
8
+ typeof obj === 'object' &&
9
+ typeof obj.type === 'string' &&
10
+ Range.is(obj.range));
9
11
  }
10
12
  AstNode.is = is;
11
13
  function setParents(node) {
@@ -61,7 +63,7 @@ export var AstNode;
61
63
  return node.children?.[findLastChildIndex(node, needle, endInclusive)];
62
64
  }
63
65
  AstNode.findLastChild = findLastChild;
64
- function findDeepestChild({ node, needle, endInclusive = false, predicate = () => true }) {
66
+ function findDeepestChild({ node, needle, endInclusive = false, predicate = () => true, }) {
65
67
  let last;
66
68
  let head = Range.contains(node, needle, endInclusive) ? node : undefined;
67
69
  while (head && predicate(head)) {
@@ -71,7 +73,7 @@ export var AstNode;
71
73
  return last;
72
74
  }
73
75
  AstNode.findDeepestChild = findDeepestChild;
74
- function findShallowestChild({ node, needle, endInclusive = false, predicate = () => true }) {
76
+ function findShallowestChild({ node, needle, endInclusive = false, predicate = () => true, }) {
75
77
  let head = Range.contains(node, needle, endInclusive) ? node : undefined;
76
78
  while (head && !predicate(head)) {
77
79
  head = findChild(head, needle, endInclusive);
@@ -1,7 +1,12 @@
1
1
  export var FileNode;
2
2
  (function (FileNode) {
3
3
  function getErrors(node) {
4
- return [...node.parserErrors, ...node.binderErrors ?? [], ...node.checkerErrors ?? [], ...node.linterErrors ?? []];
4
+ return [
5
+ ...node.parserErrors,
6
+ ...(node.binderErrors ?? []),
7
+ ...(node.checkerErrors ?? []),
8
+ ...(node.linterErrors ?? []),
9
+ ];
5
10
  }
6
11
  FileNode.getErrors = getErrors;
7
12
  })(FileNode || (FileNode = {}));
@@ -33,7 +33,7 @@ export interface ResourceLocationNode extends ResourceLocationBaseNode {
33
33
  export declare namespace ResourceLocationNode {
34
34
  function is(obj: AstNode | undefined): obj is ResourceLocationNode;
35
35
  function mock(range: RangeLike, options: ResourceLocationOptions): ResourceLocationNode;
36
- function toString(node: DeepReadonly<ResourceLocationBaseNode>, type?: 'full'): FullResourceLocation;
37
- function toString(node: DeepReadonly<ResourceLocationBaseNode>, type?: 'origin' | 'full' | 'short'): string;
36
+ function toString(node: DeepReadonly<ResourceLocationBaseNode>, type?: 'full', includesTagPrefix?: false): FullResourceLocation;
37
+ function toString(node: DeepReadonly<ResourceLocationBaseNode>, type?: 'origin' | 'full' | 'short', includesTagPrefix?: boolean): string;
38
38
  }
39
39
  //# sourceMappingURL=ResourceLocationNode.d.ts.map
@@ -17,7 +17,7 @@ export var ResourceLocationNode;
17
17
  const DefaultNamespace = ResourceLocation.DefaultNamespace;
18
18
  /* istanbul ignore next */
19
19
  function is(obj) {
20
- return obj?.type === 'resource_location';
20
+ return (obj?.type === 'resource_location');
21
21
  }
22
22
  ResourceLocationNode.is = is;
23
23
  function mock(range, options) {
@@ -28,7 +28,7 @@ export var ResourceLocationNode;
28
28
  };
29
29
  }
30
30
  ResourceLocationNode.mock = mock;
31
- function toString(node, type = 'origin') {
31
+ function toString(node, type = 'origin', includesTagPrefix = false) {
32
32
  const path = node.path ? node.path.join(PathSep) : '';
33
33
  let id;
34
34
  /*
@@ -43,7 +43,10 @@ export var ResourceLocationNode;
43
43
  switch (type) {
44
44
  case 'origin':
45
45
  // Use `node.namespace !== undefined`, so that empty namespaces can be correctly restored to string.
46
- id = node.namespace !== undefined ? `${node.namespace}${NamespacePathSep}${path}` : path;
46
+ id =
47
+ node.namespace !== undefined
48
+ ? `${node.namespace}${NamespacePathSep}${path}`
49
+ : path;
47
50
  break;
48
51
  case 'full':
49
52
  // Use `node.namespace` before `||`, so that both undefined and empty value can result in the default namespace.
@@ -52,10 +55,13 @@ export var ResourceLocationNode;
52
55
  break;
53
56
  case 'short':
54
57
  // Use `node.namespace` before `&&` for the same reason stated above.
55
- id = node.namespace && node.namespace !== DefaultNamespace ? `${node.namespace}${NamespacePathSep}${path}` : path;
58
+ id =
59
+ node.namespace && node.namespace !== DefaultNamespace
60
+ ? `${node.namespace}${NamespacePathSep}${path}`
61
+ : path;
56
62
  break;
57
63
  }
58
- return node.isTag ? `${TagPrefix}${id}` : id;
64
+ return includesTagPrefix && node.isTag ? `${TagPrefix}${id}` : id;
59
65
  }
60
66
  ResourceLocationNode.toString = toString;
61
67
  })(ResourceLocationNode || (ResourceLocationNode = {}));
@@ -1,6 +1,6 @@
1
1
  import { literal } from './literal.js';
2
2
  import { map } from './util.js';
3
- export const boolean = map(literal('false', 'true'), res => ({
3
+ export const boolean = map(literal('false', 'true'), (res) => ({
4
4
  type: 'boolean',
5
5
  range: res.range,
6
6
  value: res.value === '' ? undefined : res.value === 'true',
@@ -7,6 +7,6 @@ interface Options {
7
7
  /**
8
8
  * `Failure` when three isn't a comment.
9
9
  */
10
- export declare function comment({ singleLinePrefixes, includesEol }: Options): Parser<CommentNode>;
10
+ export declare function comment({ singleLinePrefixes, includesEol, }: Options): Parser<CommentNode>;
11
11
  export {};
12
12
  //# sourceMappingURL=comment.d.ts.map
@@ -3,7 +3,7 @@ import { Failure } from './Parser.js';
3
3
  /**
4
4
  * `Failure` when three isn't a comment.
5
5
  */
6
- export function comment({ singleLinePrefixes, includesEol }) {
6
+ export function comment({ singleLinePrefixes, includesEol, }) {
7
7
  return (src, _ctx) => {
8
8
  const start = src.cursor;
9
9
  const ans = {
@@ -43,7 +43,8 @@ export function float(options) {
43
43
  else if (!options.pattern.test(raw)) {
44
44
  ctx.err.report(localize('parser.float.illegal', options.pattern), ans);
45
45
  }
46
- else if ((options.min && ans.value < options.min) || (options.max && ans.value > options.max)) {
46
+ else if ((options.min && ans.value < options.min) ||
47
+ (options.max && ans.value > options.max)) {
47
48
  const onOutOfRange = options.onOutOfRange ?? fallbackOnOutOfRange;
48
49
  onOutOfRange(ans, src, ctx, options);
49
50
  }
@@ -32,7 +32,8 @@ export function integer(options) {
32
32
  else if (!options.pattern.test(raw) || isOnlySign) {
33
33
  ctx.err.report(localize('parser.integer.illegal', options.pattern), ans);
34
34
  }
35
- else if ((options.min !== undefined && ans.value < options.min) || (options.max !== undefined && ans.value > options.max)) {
35
+ else if ((options.min !== undefined && ans.value < options.min) ||
36
+ (options.max !== undefined && ans.value > options.max)) {
36
37
  const onOutOfRange = options.onOutOfRange ?? fallbackOnOutOfRange;
37
38
  onOutOfRange(ans, src, ctx, options);
38
39
  }
@@ -8,5 +8,5 @@ export interface Options<V extends AstNode> {
8
8
  trailingSep: boolean;
9
9
  end: string;
10
10
  }
11
- export declare function list<V extends AstNode>({ start, value, sep, trailingSep, end }: Options<V>): InfallibleParser<ListNode<V>>;
11
+ export declare function list<V extends AstNode>({ start, value, sep, trailingSep, end, }: Options<V>): InfallibleParser<ListNode<V>>;
12
12
  //# sourceMappingURL=list.d.ts.map
@@ -2,7 +2,7 @@ import { localeQuote, localize } from '@spyglassmc/locales';
2
2
  import { Range } from '../source/index.js';
3
3
  import { Failure } from './Parser.js';
4
4
  import { attempt } from './util.js';
5
- export function list({ start, value, sep, trailingSep, end }) {
5
+ export function list({ start, value, sep, trailingSep, end, }) {
6
6
  return (src, ctx) => {
7
7
  const ans = {
8
8
  type: 'list',
@@ -34,14 +34,14 @@ export function list({ start, value, sep, trailingSep, end }) {
34
34
  let sepRange = undefined;
35
35
  src.skipWhitespace();
36
36
  requiresValueSep = true;
37
- if (hasValueSep = src.peek(sep.length) === sep) {
37
+ if ((hasValueSep = src.peek(sep.length) === sep)) {
38
38
  sepRange = Range.create(src, () => src.skip(sep.length));
39
39
  }
40
40
  // Create item.
41
41
  ans.children.push({
42
42
  type: 'item',
43
43
  range: Range.create(itemStart, src),
44
- ...valueNode ? { children: [valueNode] } : {},
44
+ ...(valueNode ? { children: [valueNode] } : {}),
45
45
  value: valueNode,
46
46
  sep: sepRange,
47
47
  });
@@ -36,7 +36,8 @@ export function long(options) {
36
36
  else if (!options.pattern.test(raw) || isOnlySign) {
37
37
  ctx.err.report(localize('parser.long.illegal', options.pattern), ans);
38
38
  }
39
- else if ((options.min && ans.value < options.min) || (options.max && ans.value > options.max)) {
39
+ else if ((options.min && ans.value < options.min) ||
40
+ (options.max && ans.value > options.max)) {
40
41
  const onOutOfRange = options.onOutOfRange ?? fallbackOnOutOfRange;
41
42
  onOutOfRange(ans, src, ctx, options);
42
43
  }
@@ -18,5 +18,5 @@ export interface Options<K extends AstNode, V extends AstNode> {
18
18
  /**
19
19
  * @returns A parser that parses something coming in a key-value pair form. e.g. SNBT objects, entity selector arguments.
20
20
  */
21
- export declare function record<K extends AstNode, V extends AstNode>({ start, pair, end }: Options<K, V>): InfallibleParser<RecordNode<K, V>>;
21
+ export declare function record<K extends AstNode, V extends AstNode>({ start, pair, end, }: Options<K, V>): InfallibleParser<RecordNode<K, V>>;
22
22
  //# sourceMappingURL=record.d.ts.map
@@ -5,7 +5,7 @@ import { attempt } from './util.js';
5
5
  /**
6
6
  * @returns A parser that parses something coming in a key-value pair form. e.g. SNBT objects, entity selector arguments.
7
7
  */
8
- export function record({ start, pair, end }) {
8
+ export function record({ start, pair, end, }) {
9
9
  return (src, ctx) => {
10
10
  const ans = {
11
11
  type: 'record',
@@ -26,8 +26,10 @@ export function record({ start, pair, end }) {
26
26
  }
27
27
  // Key.
28
28
  const keyStart = src.cursor;
29
- const { result: keyResult, updateSrcAndCtx: updateForKey, endCursor: keyEnd } = attempt(pair.key, src, ctx);
30
- if (keyResult === Failure || (keyEnd - keyStart === 0 && ![pair.sep, pair.end, end, '\r', '\n', '\t', ' '].includes(src.peek()))) {
29
+ const { result: keyResult, updateSrcAndCtx: updateForKey, endCursor: keyEnd, } = attempt(pair.key, src, ctx);
30
+ if (keyResult === Failure ||
31
+ (keyEnd - keyStart === 0 &&
32
+ ![pair.sep, pair.end, end, '\r', '\n', '\t', ' '].includes(src.peek()))) {
31
33
  ctx.err.report(localize('expected', localize('parser.record.key')), Range.create(src, () => src.skipUntilOrEnd(pair.sep, pair.end, end, '\r', '\n')));
32
34
  }
33
35
  else {
@@ -45,10 +47,14 @@ export function record({ start, pair, end }) {
45
47
  }
46
48
  // Value.
47
49
  src.skipWhitespace();
48
- const valueParser = typeof pair.value === 'function' ? pair.value : pair.value.get(ans, key);
50
+ const valueParser = typeof pair.value === 'function'
51
+ ? pair.value
52
+ : pair.value.get(ans, key);
49
53
  const valueStart = src.cursor;
50
- const { result: valueResult, updateSrcAndCtx: updateForValue, endCursor: valueEnd } = attempt(valueParser, src, ctx);
51
- if (valueResult === Failure || (valueEnd - valueStart === 0 && ![pair.sep, pair.end, end, '\r', '\n', '\t', ' '].includes(src.peek()))) {
54
+ const { result: valueResult, updateSrcAndCtx: updateForValue, endCursor: valueEnd, } = attempt(valueParser, src, ctx);
55
+ if (valueResult === Failure ||
56
+ (valueEnd - valueStart === 0 &&
57
+ ![pair.sep, pair.end, end, '\r', '\n', '\t', ' '].includes(src.peek()))) {
52
58
  ctx.err.report(localize('expected', localize('parser.record.value')), Range.create(src, () => src.skipUntilOrEnd(pair.sep, pair.end, end, '\r', '\n')));
53
59
  }
54
60
  else {
@@ -59,14 +65,18 @@ export function record({ start, pair, end }) {
59
65
  let endCharRange = undefined;
60
66
  src.skipWhitespace();
61
67
  requiresPairEnd = true;
62
- if (hasPairEnd = src.peek(pair.end.length) === pair.end) {
68
+ if ((hasPairEnd = src.peek(pair.end.length) === pair.end)) {
63
69
  endCharRange = Range.create(src, () => src.skip(pair.end.length));
64
70
  }
65
71
  // Create pair.
66
72
  ans.children.push({
67
73
  type: 'pair',
68
74
  range: Range.create(pairStart, src),
69
- ...(key || value) ? { children: [key, value].filter(v => !!v) } : {},
75
+ ...(key || value
76
+ ? {
77
+ children: [key, value].filter((v) => !!v),
78
+ }
79
+ : {}),
70
80
  key,
71
81
  sep: sepCharRange,
72
82
  value,
@@ -1,11 +1,62 @@
1
1
  import { arrayToMessage, localize } from '@spyglassmc/locales';
2
2
  import { ResourceLocation } from '../common/index.js';
3
3
  import { Range } from '../source/index.js';
4
- const Terminators = new Set([' ', '\r', '\n', '=', ',', '"', "'", '{', '}', '[', ']', '(', ')', ';']);
4
+ const Terminators = new Set([
5
+ ' ',
6
+ '\r',
7
+ '\n',
8
+ '=',
9
+ ',',
10
+ '"',
11
+ "'",
12
+ '{',
13
+ '}',
14
+ '[',
15
+ ']',
16
+ '(',
17
+ ')',
18
+ ';',
19
+ ]);
5
20
  const LegalCharacters = new Set([
6
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
7
- 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
8
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '_', '-', '.',
21
+ 'a',
22
+ 'b',
23
+ 'c',
24
+ 'd',
25
+ 'e',
26
+ 'f',
27
+ 'g',
28
+ 'h',
29
+ 'i',
30
+ 'j',
31
+ 'k',
32
+ 'l',
33
+ 'm',
34
+ 'n',
35
+ 'o',
36
+ 'p',
37
+ 'q',
38
+ 'r',
39
+ 's',
40
+ 't',
41
+ 'u',
42
+ 'v',
43
+ 'w',
44
+ 'x',
45
+ 'y',
46
+ 'z',
47
+ '0',
48
+ '1',
49
+ '2',
50
+ '3',
51
+ '4',
52
+ '5',
53
+ '6',
54
+ '7',
55
+ '8',
56
+ '9',
57
+ '_',
58
+ '-',
59
+ '.',
9
60
  ]);
10
61
  export function resourceLocation(options) {
11
62
  return (src, ctx) => {
@@ -35,10 +86,12 @@ export function resourceLocation(options) {
35
86
  ans.path = rawPath.split(ResourceLocation.PathSep);
36
87
  // Check characters.
37
88
  /* istanbul ignore next */
38
- const illegalChars = [...new Set([
39
- ...[...ans.namespace ?? []].filter(c => !LegalCharacters.has(c)),
40
- ...[...rawPath].filter(c => c !== '/' && !LegalCharacters.has(c)),
41
- ])];
89
+ const illegalChars = [
90
+ ...new Set([
91
+ ...[...(ans.namespace ?? [])].filter((c) => !LegalCharacters.has(c)),
92
+ ...[...rawPath].filter((c) => c !== '/' && !LegalCharacters.has(c)),
93
+ ]),
94
+ ];
42
95
  if (illegalChars.length) {
43
96
  ctx.err.report(localize('parser.resource-location.illegal', arrayToMessage(illegalChars, true, 'and')), ans);
44
97
  }