@spyglassmc/core 0.2.0 → 0.3.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/lib/common/Dev.d.ts +11 -0
- package/lib/common/Dev.js +90 -0
- package/lib/{service → common}/Logger.d.ts +0 -0
- package/lib/{service → common}/Logger.js +0 -0
- package/lib/common/Operations.d.ts +12 -0
- package/lib/common/Operations.js +33 -0
- package/lib/common/ReadonlyProxy.d.ts +9 -0
- package/lib/common/ReadonlyProxy.js +23 -0
- package/lib/common/StateProxy.d.ts +35 -0
- package/lib/common/StateProxy.js +69 -0
- package/lib/common/externals/NodeJsExternals.js +1 -0
- package/lib/common/index.d.ts +6 -0
- package/lib/common/index.js +6 -0
- package/lib/common/util.d.ts +33 -5
- package/lib/common/util.js +43 -11
- package/lib/node/AstNode.d.ts +9 -8
- package/lib/node/CommentNode.d.ts +5 -4
- package/lib/node/CommentNode.js +4 -6
- package/lib/node/FileNode.d.ts +5 -1
- package/lib/node/FileNode.js +1 -1
- package/lib/node/FloatNode.d.ts +1 -1
- package/lib/node/IntegerNode.d.ts +1 -1
- package/lib/node/LiteralNode.d.ts +1 -1
- package/lib/node/LongNode.d.ts +1 -1
- package/lib/node/ResourceLocationNode.d.ts +3 -3
- package/lib/node/StringNode.d.ts +1 -1
- package/lib/node/SymbolNode.d.ts +1 -1
- package/lib/parser/resourceLocation.js +0 -8
- package/lib/parser/string.d.ts +2 -2
- package/lib/parser/symbol.js +1 -7
- package/lib/parser/util.js +0 -2
- package/lib/processor/InlayHintProvider.d.ts +2 -1
- package/lib/processor/SignatureHelpProvider.d.ts +2 -1
- package/lib/processor/binder/Binder.d.ts +26 -0
- package/lib/processor/binder/Binder.js +18 -0
- package/lib/processor/binder/builtin.d.ts +27 -0
- package/lib/processor/binder/builtin.js +116 -0
- package/lib/processor/binder/index.d.ts +3 -0
- package/lib/processor/binder/index.js +3 -0
- package/lib/processor/checker/builtin.js +5 -5
- package/lib/processor/colorizer/Colorizer.d.ts +2 -1
- package/lib/processor/completer/Completer.d.ts +2 -1
- package/lib/processor/completer/builtin.d.ts +3 -2
- package/lib/processor/completer/builtin.js +1 -1
- package/lib/processor/formatter/Formatter.d.ts +2 -1
- package/lib/processor/index.d.ts +1 -0
- package/lib/processor/index.js +1 -0
- package/lib/processor/linter/Linter.d.ts +2 -1
- package/lib/processor/linter/builtin.d.ts +2 -1
- package/lib/processor/util.d.ts +3 -13
- package/lib/processor/util.js +0 -10
- package/lib/service/CacheService.d.ts +2 -0
- package/lib/service/CacheService.js +3 -0
- package/lib/service/Context.d.ts +15 -12
- package/lib/service/Context.js +12 -6
- package/lib/service/Downloader.d.ts +1 -2
- package/lib/service/FileService.d.ts +1 -2
- package/lib/service/MetaRegistry.d.ts +8 -3
- package/lib/service/MetaRegistry.js +20 -1
- package/lib/service/Profiler.d.ts +3 -2
- package/lib/service/Profiler.js +58 -6
- package/lib/service/Project.d.ts +55 -24
- package/lib/service/Project.js +265 -166
- package/lib/service/Service.d.ts +1 -1
- package/lib/service/UriProcessor.d.ts +5 -0
- package/lib/service/UriProcessor.js +2 -0
- package/lib/service/index.d.ts +1 -2
- package/lib/service/index.js +1 -2
- package/lib/symbol/Symbol.d.ts +3 -2
- package/lib/symbol/SymbolUtil.d.ts +8 -7
- package/lib/symbol/SymbolUtil.js +31 -9
- package/lib/symbol/index.d.ts +0 -1
- package/lib/symbol/index.js +0 -1
- package/package.json +2 -2
- package/lib/service/Operations.d.ts +0 -8
- package/lib/service/Operations.js +0 -20
- package/lib/symbol/UriBinder.d.ts +0 -3
- package/lib/symbol/UriBinder.js +0 -2
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const Dev: Readonly<{
|
|
2
|
+
assertDefined<T>(value: T): asserts value is Exclude<T, undefined>;
|
|
3
|
+
assertNever(value: never): never;
|
|
4
|
+
assertTrue(value: boolean, message: string): void;
|
|
5
|
+
/**
|
|
6
|
+
* @returns An estimate of the memory taken by the given value, assuming objects are stored as array-like structures instead of dictionaries in the V8 engine.
|
|
7
|
+
*/
|
|
8
|
+
estimateMemoryUsage(value: unknown): number;
|
|
9
|
+
stringify(value: unknown): string;
|
|
10
|
+
}>;
|
|
11
|
+
//# sourceMappingURL=Dev.d.ts.map
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
export const Dev = Object.freeze({
|
|
2
|
+
assertDefined(value) {
|
|
3
|
+
if (value === undefined) {
|
|
4
|
+
throw new Error(`'${Dev.stringify(value)}' is 'undefined'`);
|
|
5
|
+
}
|
|
6
|
+
},
|
|
7
|
+
assertNever(value) {
|
|
8
|
+
throw new Error(`'${Dev.stringify(value)}' is not of type 'never'`);
|
|
9
|
+
},
|
|
10
|
+
assertTrue(value, message) {
|
|
11
|
+
if (!value) {
|
|
12
|
+
throw new Error(`Assertion failed: ${message}. '${Dev.stringify(value)}' should be true.`);
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
/**
|
|
16
|
+
* @returns An estimate of the memory taken by the given value, assuming objects are stored as array-like structures instead of dictionaries in the V8 engine.
|
|
17
|
+
*/
|
|
18
|
+
estimateMemoryUsage(value) {
|
|
19
|
+
const ByteToBits = 8;
|
|
20
|
+
const PointerSize = 8;
|
|
21
|
+
let ans = 0;
|
|
22
|
+
const calculatedObjects = new Set();
|
|
23
|
+
const stack = [value];
|
|
24
|
+
while (stack.length) {
|
|
25
|
+
const current = stack.pop();
|
|
26
|
+
switch (typeof current) {
|
|
27
|
+
case 'bigint': {
|
|
28
|
+
const bits = Math.ceil(Math.log2(Number(current)));
|
|
29
|
+
ans += (2 + Math.ceil(bits / (ByteToBits * PointerSize))) * PointerSize; // https://stackoverflow.com/a/54298760
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
case 'boolean':
|
|
33
|
+
ans += PointerSize; // Aggressive alignment estimation.
|
|
34
|
+
break;
|
|
35
|
+
case 'number':
|
|
36
|
+
ans += 8;
|
|
37
|
+
break;
|
|
38
|
+
case 'object':
|
|
39
|
+
ans += PointerSize; // Reference pointer.
|
|
40
|
+
if (!current || calculatedObjects.has(current)) {
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
ans += PointerSize; // Header pointer.
|
|
44
|
+
for (const value of Object.values(current)) {
|
|
45
|
+
stack.push(value);
|
|
46
|
+
ans += PointerSize; // Aggressive padding estimation.
|
|
47
|
+
}
|
|
48
|
+
calculatedObjects.add(current);
|
|
49
|
+
break;
|
|
50
|
+
case 'string':
|
|
51
|
+
ans += current.length * 2;
|
|
52
|
+
break;
|
|
53
|
+
case 'symbol':
|
|
54
|
+
ans += PointerSize;
|
|
55
|
+
break;
|
|
56
|
+
default:
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return ans;
|
|
61
|
+
},
|
|
62
|
+
stringify(value) {
|
|
63
|
+
if (value && typeof value === 'object') {
|
|
64
|
+
try {
|
|
65
|
+
const seen = new Set();
|
|
66
|
+
return JSON.stringify(value, (_k, v) => {
|
|
67
|
+
if (v && typeof v === 'object') {
|
|
68
|
+
return seen.has(v) ? '[Circular]' : (seen.add(v), v);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
return v;
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
catch (ignored) {
|
|
76
|
+
// Most likely "Maximum callstack size exceeded".
|
|
77
|
+
// Fall back to a shallow string representation.
|
|
78
|
+
return `{ ${Object.entries(value).map(([k, v]) => `'${k}': '${String(v)}'`).join(', ')} }`;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else if (typeof value === 'symbol') {
|
|
82
|
+
// JavaScript does not convert `Symbol`s to strings implicitly.
|
|
83
|
+
return String(value);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
return `${value}`;
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
//# sourceMappingURL=Dev.js.map
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class Operations {
|
|
2
|
+
private readonly parent?;
|
|
3
|
+
constructor(parent?: Operations | undefined);
|
|
4
|
+
private readonly undoOps;
|
|
5
|
+
private readonly redoOps;
|
|
6
|
+
private addUndoOp;
|
|
7
|
+
private addRedoOp;
|
|
8
|
+
set<O extends object, K extends keyof O>(obj: O, key: K, value: O[K], receiver?: any): void;
|
|
9
|
+
undo(): void;
|
|
10
|
+
redo(): void;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=Operations.d.ts.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export class Operations {
|
|
2
|
+
parent;
|
|
3
|
+
constructor(parent) {
|
|
4
|
+
this.parent = parent;
|
|
5
|
+
}
|
|
6
|
+
undoOps = [];
|
|
7
|
+
redoOps = [];
|
|
8
|
+
addUndoOp(op) {
|
|
9
|
+
this.undoOps.push(op);
|
|
10
|
+
this.parent?.addUndoOp(op);
|
|
11
|
+
}
|
|
12
|
+
addRedoOp(op) {
|
|
13
|
+
this.redoOps.push(op);
|
|
14
|
+
this.parent?.addRedoOp(op);
|
|
15
|
+
}
|
|
16
|
+
set(obj, key, value, receiver = obj) {
|
|
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); };
|
|
20
|
+
this.addRedoOp(op);
|
|
21
|
+
this.addUndoOp(undoOp);
|
|
22
|
+
op();
|
|
23
|
+
}
|
|
24
|
+
undo() {
|
|
25
|
+
for (let i = this.undoOps.length - 1; i >= 0; i--) {
|
|
26
|
+
this.undoOps[i]();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
redo() {
|
|
30
|
+
this.redoOps.forEach(op => op());
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=Operations.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
declare type Wrap<T> = T extends object ? DeepReadonly<T> : T;
|
|
2
|
+
export declare type DeepReadonly<T extends object> = {
|
|
3
|
+
readonly [K in keyof T]: Wrap<T[K]>;
|
|
4
|
+
};
|
|
5
|
+
export declare const ReadonlyProxy: Readonly<{
|
|
6
|
+
create<T extends object>(obj: T): DeepReadonly<T>;
|
|
7
|
+
}>;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=ReadonlyProxy.d.ts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { emplaceMap, isObject } from './util.js';
|
|
2
|
+
export const ReadonlyProxy = Object.freeze({
|
|
3
|
+
create(obj) {
|
|
4
|
+
return new Proxy(obj, new ReadonlyProxyHandler());
|
|
5
|
+
},
|
|
6
|
+
});
|
|
7
|
+
class ReadonlyProxyHandler {
|
|
8
|
+
map = new Map();
|
|
9
|
+
get(target, p, receiver) {
|
|
10
|
+
const value = Reflect.get(target, p, receiver);
|
|
11
|
+
if (p !== 'prototype' && isObject(value)) {
|
|
12
|
+
return emplaceMap(this.map, p, { insert: () => ReadonlyProxy.create(value) });
|
|
13
|
+
}
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
set(_target, p, _value, _receiver) {
|
|
17
|
+
throw new TypeError(`Cannot set property '${String(p)}' on a readonly proxy`);
|
|
18
|
+
}
|
|
19
|
+
deleteProperty(_target, p) {
|
|
20
|
+
throw new TypeError(`Cannot delete property '${String(p)}' on a readonly proxy`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=ReadonlyProxy.js.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
declare const BranchOff: unique symbol;
|
|
2
|
+
declare const Is: unique symbol;
|
|
3
|
+
declare const Origin: unique symbol;
|
|
4
|
+
declare const Redo: unique symbol;
|
|
5
|
+
declare const Undo: unique symbol;
|
|
6
|
+
declare type Wrap<T> = T extends object ? StateProxy<T> : T;
|
|
7
|
+
/**
|
|
8
|
+
* A proxy wrapped around an arbitrary object value.
|
|
9
|
+
* You can access and mutate the value as normal, but you also have the ability to revert all changes ever since the
|
|
10
|
+
* proxy was created using {@link StateProxy.redoChanges} and {@link StateProxy.undoChanges}.
|
|
11
|
+
*
|
|
12
|
+
* A new proxy can be branched off of an existing proxy using {@link StateProxy.branchOff} to have finer control
|
|
13
|
+
* over what changes to be reverted.
|
|
14
|
+
*/
|
|
15
|
+
export declare type StateProxy<T extends object> = {
|
|
16
|
+
[K in keyof T]: Wrap<T[K]>;
|
|
17
|
+
} & {
|
|
18
|
+
[BranchOff]: () => StateProxy<T>;
|
|
19
|
+
[Is]: true;
|
|
20
|
+
[Origin]: T;
|
|
21
|
+
[Redo]: () => void;
|
|
22
|
+
[Undo]: () => void;
|
|
23
|
+
};
|
|
24
|
+
export declare const StateProxy: Readonly<{
|
|
25
|
+
branchOff<T extends object>(proxy: StateProxy<T>): StateProxy<T>;
|
|
26
|
+
create<T_1 extends object>(obj: T_1): T_1 extends StateProxy<any> ? void & {
|
|
27
|
+
_cannotCreateProxyFromProxy: never;
|
|
28
|
+
} : StateProxy<T_1>;
|
|
29
|
+
dereference<T_2 extends object>(value: T_2 | StateProxy<T_2>): T_2;
|
|
30
|
+
is(obj: any): obj is StateProxy<object>;
|
|
31
|
+
redoChanges(proxy: StateProxy<object>): void;
|
|
32
|
+
undoChanges(proxy: StateProxy<object>): void;
|
|
33
|
+
}>;
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=StateProxy.d.ts.map
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { emplaceMap, isObject } from '../common/index.js';
|
|
2
|
+
import { Operations } from './Operations.js';
|
|
3
|
+
const BranchOff = Symbol('StateBranchOff');
|
|
4
|
+
const Is = Symbol('IsStateProxy');
|
|
5
|
+
const Origin = Symbol('OriginState');
|
|
6
|
+
const Redo = Symbol('RedoStateChanges');
|
|
7
|
+
const Undo = Symbol('UndoStateChanges');
|
|
8
|
+
export const StateProxy = Object.freeze({
|
|
9
|
+
branchOff(proxy) {
|
|
10
|
+
return proxy[BranchOff]();
|
|
11
|
+
},
|
|
12
|
+
create(obj) {
|
|
13
|
+
if (StateProxy.is(obj)) {
|
|
14
|
+
throw new TypeError('Cannot create a proxy over a proxy. You might want to use branchOff instead.');
|
|
15
|
+
}
|
|
16
|
+
return _createStateProxy(obj, new Operations());
|
|
17
|
+
},
|
|
18
|
+
dereference(value) {
|
|
19
|
+
return StateProxy.is(value) ? value[Origin] : value;
|
|
20
|
+
},
|
|
21
|
+
is(obj) {
|
|
22
|
+
return obj?.[Is];
|
|
23
|
+
},
|
|
24
|
+
redoChanges(proxy) {
|
|
25
|
+
proxy[Redo]();
|
|
26
|
+
},
|
|
27
|
+
undoChanges(proxy) {
|
|
28
|
+
proxy[Undo]();
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
class StateProxyHandler {
|
|
32
|
+
rootOps;
|
|
33
|
+
map = new Map();
|
|
34
|
+
constructor(
|
|
35
|
+
/**
|
|
36
|
+
* Shared across all handlers created for the same root state object under the same branch.
|
|
37
|
+
*/
|
|
38
|
+
rootOps) {
|
|
39
|
+
this.rootOps = rootOps;
|
|
40
|
+
}
|
|
41
|
+
#branchOff(target) {
|
|
42
|
+
return _createStateProxy(target, new Operations(this.rootOps));
|
|
43
|
+
}
|
|
44
|
+
get(target, p, receiver) {
|
|
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();
|
|
51
|
+
}
|
|
52
|
+
const value = Reflect.get(target, p, receiver);
|
|
53
|
+
if (p !== 'prototype' && isObject(value)) {
|
|
54
|
+
return emplaceMap(this.map, p, { insert: () => _createStateProxy(value, this.rootOps) });
|
|
55
|
+
}
|
|
56
|
+
return value;
|
|
57
|
+
}
|
|
58
|
+
set(target, p, value, receiver) {
|
|
59
|
+
if (p === BranchOff || p === Is || p === Origin || p === Redo || p === Undo) {
|
|
60
|
+
throw new TypeError(`Cannot set ${String(p)}`);
|
|
61
|
+
}
|
|
62
|
+
this.rootOps.set(target, p, StateProxy.dereference(value), receiver);
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function _createStateProxy(target, operations) {
|
|
67
|
+
return new Proxy(target, new StateProxyHandler(operations));
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=StateProxy.js.map
|
package/lib/common/index.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
export * from './Dev.js';
|
|
1
2
|
export * from './externals/index.js';
|
|
3
|
+
export * from './Logger.js';
|
|
4
|
+
export * from './Operations.js';
|
|
5
|
+
export * from './ReadonlyProxy.js';
|
|
6
|
+
export * from './StateProxy.js';
|
|
7
|
+
export * from './TwoWayMap.js';
|
|
2
8
|
export * from './util.js';
|
|
3
9
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/common/index.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
export * from './Dev.js';
|
|
1
2
|
export * from './externals/index.js';
|
|
3
|
+
export * from './Logger.js';
|
|
4
|
+
export * from './Operations.js';
|
|
5
|
+
export * from './ReadonlyProxy.js';
|
|
6
|
+
export * from './StateProxy.js';
|
|
7
|
+
export * from './TwoWayMap.js';
|
|
2
8
|
export * from './util.js';
|
|
3
9
|
//# sourceMappingURL=index.js.map
|
package/lib/common/util.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import externalBinarySearch from 'binary-search';
|
|
2
|
+
import type { AstNode } from '../node/index.js';
|
|
2
3
|
import type { ProcessorContext } from '../service/index.js';
|
|
3
4
|
import type { Externals } from './externals/index.js';
|
|
5
|
+
import type { DeepReadonly } from './ReadonlyProxy.js';
|
|
4
6
|
export declare const Uri: {
|
|
5
7
|
new (url: string | URL, base?: string | URL | undefined): URL;
|
|
6
8
|
prototype: URL;
|
|
@@ -13,14 +15,14 @@ export declare type Uri = URL;
|
|
|
13
15
|
*/
|
|
14
16
|
export declare type IntervalId = any;
|
|
15
17
|
/**
|
|
16
|
-
* @param
|
|
17
|
-
* The result of this function will be used as the key to
|
|
18
|
+
* @param getKey A function that takes the actual arguments being passed into the decorated method, and returns anything.
|
|
19
|
+
* The result of this function will be used as the key to identify the `Promise`. By default the first element in the argument
|
|
18
20
|
* list will be used.
|
|
19
21
|
*
|
|
20
22
|
* This is a decorator for async methods. Decorated methods will return the same `Promise` for
|
|
21
|
-
* the same
|
|
23
|
+
* the same key, provided that the previously returned `Promise` is still pending.
|
|
22
24
|
*/
|
|
23
|
-
export declare function
|
|
25
|
+
export declare function SingletonPromise(getKey?: (args: any[]) => any): MethodDecorator;
|
|
24
26
|
/**
|
|
25
27
|
* This is a decorator for methods. Decorated methods will return the same non-`undefined` value no matter what.
|
|
26
28
|
*/
|
|
@@ -71,7 +73,10 @@ export declare namespace TypePredicates {
|
|
|
71
73
|
}
|
|
72
74
|
export declare function promisifyAsyncIterable<T, U>(iterable: AsyncIterable<T>, joiner: (chunks: T[]) => U): Promise<U>;
|
|
73
75
|
export declare function parseGzippedJson(externals: Externals, buffer: Uint8Array): Promise<unknown>;
|
|
74
|
-
|
|
76
|
+
/**
|
|
77
|
+
* @returns Is Plain Old JavaScript Object (POJO).
|
|
78
|
+
*/
|
|
79
|
+
export declare function isPojo(value: unknown): value is Record<string, unknown>;
|
|
75
80
|
export declare function merge<T extends Record<string, any>>(a: T, b: Record<string, any>): T;
|
|
76
81
|
export declare type Lazy<T> = T | Lazy.ComplexLazy<T>;
|
|
77
82
|
export declare namespace Lazy {
|
|
@@ -100,4 +105,27 @@ export declare namespace Lazy {
|
|
|
100
105
|
export declare function getStates(category: 'block' | 'fluid', ids: readonly string[], ctx: ProcessorContext): Record<string, string[]>;
|
|
101
106
|
export declare const binarySearch: typeof externalBinarySearch;
|
|
102
107
|
export declare function isIterable(value: unknown): value is Iterable<unknown>;
|
|
108
|
+
export declare function atArray<T>(array: readonly T[] | undefined, index: number): T | undefined;
|
|
109
|
+
export declare function emplaceMap<K, V>(map: Map<K, V>, key: K, handler: {
|
|
110
|
+
insert?: (key: K, map: Map<K, V>) => V;
|
|
111
|
+
update?: (existing: V, key: K, map: Map<K, V>) => V;
|
|
112
|
+
}): V;
|
|
113
|
+
/**
|
|
114
|
+
* @returns If `val` is an non-null object or a callable object (i.e. function).
|
|
115
|
+
*/
|
|
116
|
+
export declare function isObject(val: unknown): val is object;
|
|
117
|
+
/**
|
|
118
|
+
* @example
|
|
119
|
+
* ```ts
|
|
120
|
+
* function isCommentNode<T extends DeepReadonly<AstNode> | undefined>(node: T): node is IsHelper<AstNode, CommentNode, T>
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
export declare type IsHelper<ROOT extends object, TARGET extends ROOT, INPUT extends DeepReadonly<ROOT> | undefined> = INPUT extends DeepReadonly<ROOT> ? INPUT & DeepReadonly<TARGET> : INPUT & TARGET;
|
|
124
|
+
/**
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* function isCommentNode<T extends DeepReadonly<AstNode> | undefined>(node: T): node is NodeIsHelper<CommentNode, T>
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
export declare type NodeIsHelper<TARGET extends AstNode, INPUT extends DeepReadonly<AstNode> | undefined> = IsHelper<AstNode, TARGET, INPUT>;
|
|
103
131
|
//# sourceMappingURL=util.d.ts.map
|
package/lib/common/util.js
CHANGED
|
@@ -2,26 +2,26 @@ import externalBinarySearch from 'binary-search';
|
|
|
2
2
|
import rfdc from 'rfdc';
|
|
3
3
|
export const Uri = URL;
|
|
4
4
|
/**
|
|
5
|
-
* @param
|
|
6
|
-
* The result of this function will be used as the key to
|
|
5
|
+
* @param getKey A function that takes the actual arguments being passed into the decorated method, and returns anything.
|
|
6
|
+
* The result of this function will be used as the key to identify the `Promise`. By default the first element in the argument
|
|
7
7
|
* list will be used.
|
|
8
8
|
*
|
|
9
9
|
* This is a decorator for async methods. Decorated methods will return the same `Promise` for
|
|
10
|
-
* the same
|
|
10
|
+
* the same key, provided that the previously returned `Promise` is still pending.
|
|
11
11
|
*/
|
|
12
|
-
export function
|
|
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;
|
|
16
16
|
// The `function` syntax is used to preserve `this` context from the decorated method.
|
|
17
17
|
descripter.value = function (...args) {
|
|
18
|
-
const
|
|
19
|
-
if (promises.has(
|
|
20
|
-
return promises.get(
|
|
18
|
+
const key = getKey(args);
|
|
19
|
+
if (promises.has(key)) {
|
|
20
|
+
return promises.get(key);
|
|
21
21
|
}
|
|
22
22
|
const ans = decoratedMethod.apply(this, args)
|
|
23
|
-
.then(ans => (promises.delete(
|
|
24
|
-
promises.set(
|
|
23
|
+
.then(ans => (promises.delete(key), ans), e => (promises.delete(key), Promise.reject(e)));
|
|
24
|
+
promises.set(key, ans);
|
|
25
25
|
return ans;
|
|
26
26
|
};
|
|
27
27
|
return descripter;
|
|
@@ -138,13 +138,16 @@ export function promisifyAsyncIterable(iterable, joiner) {
|
|
|
138
138
|
export async function parseGzippedJson(externals, buffer) {
|
|
139
139
|
return JSON.parse(bufferToString(await externals.archive.gunzip(buffer)));
|
|
140
140
|
}
|
|
141
|
-
|
|
141
|
+
/**
|
|
142
|
+
* @returns Is Plain Old JavaScript Object (POJO).
|
|
143
|
+
*/
|
|
144
|
+
export function isPojo(value) {
|
|
142
145
|
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
143
146
|
}
|
|
144
147
|
export function merge(a, b) {
|
|
145
148
|
const ans = rfdc()(a);
|
|
146
149
|
for (const [key, value] of Object.entries(b)) {
|
|
147
|
-
if (
|
|
150
|
+
if (isPojo(ans[key]) && isPojo(value)) {
|
|
148
151
|
ans[key] = merge(ans[key], value);
|
|
149
152
|
}
|
|
150
153
|
else if (value === undefined) {
|
|
@@ -208,4 +211,33 @@ export const binarySearch = externalBinarySearch;
|
|
|
208
211
|
export function isIterable(value) {
|
|
209
212
|
return !!value[Symbol.iterator];
|
|
210
213
|
}
|
|
214
|
+
//#region ESNext functions polyfill
|
|
215
|
+
export function atArray(array, index) {
|
|
216
|
+
return index >= 0 ? array?.[index] : array?.[array.length + index];
|
|
217
|
+
}
|
|
218
|
+
export function emplaceMap(map, key, handler) {
|
|
219
|
+
if (map.has(key)) {
|
|
220
|
+
let value = map.get(key);
|
|
221
|
+
if (handler.update) {
|
|
222
|
+
value = handler.update(value, key, map);
|
|
223
|
+
map.set(key, value);
|
|
224
|
+
}
|
|
225
|
+
return value;
|
|
226
|
+
}
|
|
227
|
+
else if (handler.insert) {
|
|
228
|
+
const value = handler.insert(key, map);
|
|
229
|
+
map.set(key, value);
|
|
230
|
+
return value;
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
throw new Error(`No key ${key} in map and no insert handler provided`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
//#endregion
|
|
237
|
+
/**
|
|
238
|
+
* @returns If `val` is an non-null object or a callable object (i.e. function).
|
|
239
|
+
*/
|
|
240
|
+
export function isObject(val) {
|
|
241
|
+
return typeof val === 'function' || (!!val && typeof val === 'object');
|
|
242
|
+
}
|
|
211
243
|
//# sourceMappingURL=util.js.map
|
package/lib/node/AstNode.d.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
+
import type { DeepReadonly } from '../common/index.js';
|
|
1
2
|
import type { Color, FormattableColor } from '../processor/index.js';
|
|
2
3
|
import { Range } from '../source/index.js';
|
|
3
4
|
import type { Symbol, SymbolTable } from '../symbol/index.js';
|
|
4
5
|
export interface AstNode {
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
type: string;
|
|
7
|
+
range: Range;
|
|
7
8
|
/**
|
|
8
9
|
* All child nodes of this AST node.
|
|
9
10
|
*/
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
children?: AstNode[];
|
|
12
|
+
parent?: AstNode;
|
|
12
13
|
locals?: SymbolTable;
|
|
13
14
|
symbol?: Symbol;
|
|
14
15
|
hover?: string;
|
|
@@ -23,21 +24,21 @@ export declare namespace AstNode {
|
|
|
23
24
|
/**
|
|
24
25
|
* @param endInclusive Defaults to `false`.
|
|
25
26
|
*/
|
|
26
|
-
export function findChildIndex(node: AstNode
|
|
27
|
+
export function findChildIndex(node: DeepReadonly<AstNode>, needle: number | Range, endInclusive?: boolean): number;
|
|
27
28
|
/**
|
|
28
29
|
* @param endInclusive Defaults to `false`.
|
|
29
30
|
*/
|
|
30
|
-
export function findChild<N extends AstNode
|
|
31
|
+
export function findChild<N extends DeepReadonly<AstNode>>(node: N, needle: number | Range, endInclusive?: boolean): Exclude<N['children'], undefined>[number] | undefined;
|
|
31
32
|
/**
|
|
32
33
|
* Returns the index of the last child node that ends before the `needle`.
|
|
33
34
|
*
|
|
34
35
|
* @param endInclusive Defaults to `false`.
|
|
35
36
|
*/
|
|
36
|
-
export function findLastChildIndex(node: AstNode
|
|
37
|
+
export function findLastChildIndex(node: DeepReadonly<AstNode>, needle: number | Range, endInclusive?: boolean): number;
|
|
37
38
|
/**
|
|
38
39
|
* @param endInclusive Defaults to `false`.
|
|
39
40
|
*/
|
|
40
|
-
export function findLastChild<N extends AstNode
|
|
41
|
+
export function findLastChild<N extends DeepReadonly<AstNode>>(node: N, needle: number | Range, endInclusive?: boolean): (N['children'] extends readonly unknown[] ? N['children'][number] : undefined) | undefined;
|
|
41
42
|
interface FindRecursivelyOptions<P = (node: AstNode) => boolean> {
|
|
42
43
|
node: AstNode;
|
|
43
44
|
needle: number;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
+
import type { DeepReadonly } from '../common/index.js';
|
|
1
2
|
import type { AstNode } from './AstNode.js';
|
|
2
3
|
export interface CommentNode extends AstNode {
|
|
3
4
|
readonly type: 'comment';
|
|
4
5
|
/**
|
|
5
6
|
* The actual comment with prefixes and suffixes removed.
|
|
6
7
|
*/
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
export declare namespace CommentNode {
|
|
10
|
-
function is(obj: AstNode | undefined): obj is CommentNode;
|
|
8
|
+
comment: string;
|
|
11
9
|
}
|
|
10
|
+
export declare const CommentNode: Readonly<{
|
|
11
|
+
is<T extends DeepReadonly<AstNode> | undefined>(obj: T): obj is import("../common/util.js").IsHelper<AstNode, CommentNode, T>;
|
|
12
|
+
}>;
|
|
12
13
|
//# sourceMappingURL=CommentNode.d.ts.map
|
package/lib/node/CommentNode.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
export
|
|
2
|
-
(
|
|
3
|
-
function is(obj) {
|
|
1
|
+
export const CommentNode = Object.freeze({
|
|
2
|
+
is(obj) {
|
|
4
3
|
return obj?.type === 'comment';
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
})(CommentNode || (CommentNode = {}));
|
|
4
|
+
},
|
|
5
|
+
});
|
|
8
6
|
//# sourceMappingURL=CommentNode.js.map
|
package/lib/node/FileNode.d.ts
CHANGED
|
@@ -5,7 +5,11 @@ export interface FileNode<CN extends AstNode> extends AstNode {
|
|
|
5
5
|
readonly type: 'file';
|
|
6
6
|
readonly children: CN[];
|
|
7
7
|
locals: SymbolTable;
|
|
8
|
-
|
|
8
|
+
parserErrors: readonly LanguageError[];
|
|
9
|
+
/**
|
|
10
|
+
* Only exists when the file has been bound.
|
|
11
|
+
*/
|
|
12
|
+
binderErrors?: readonly LanguageError[];
|
|
9
13
|
/**
|
|
10
14
|
* Only exists when the file has been checked.
|
|
11
15
|
*/
|
package/lib/node/FileNode.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export var FileNode;
|
|
2
2
|
(function (FileNode) {
|
|
3
3
|
function getErrors(node) {
|
|
4
|
-
return [...node.parserErrors, ...node.checkerErrors ?? [], ...node.linterErrors ?? []];
|
|
4
|
+
return [...node.parserErrors, ...node.binderErrors ?? [], ...node.checkerErrors ?? [], ...node.linterErrors ?? []];
|
|
5
5
|
}
|
|
6
6
|
FileNode.getErrors = getErrors;
|
|
7
7
|
})(FileNode || (FileNode = {}));
|
package/lib/node/FloatNode.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { RangeLike } from '../source/index.js';
|
|
2
2
|
import type { AstNode } from './AstNode.js';
|
|
3
3
|
export interface FloatBaseNode extends AstNode {
|
|
4
|
-
|
|
4
|
+
value: number;
|
|
5
5
|
}
|
|
6
6
|
export interface FloatNode extends FloatBaseNode {
|
|
7
7
|
readonly type: 'float';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { RangeLike } from '../source/index.js';
|
|
2
2
|
import type { AstNode } from './AstNode.js';
|
|
3
3
|
export interface IntegerBaseNode extends AstNode {
|
|
4
|
-
|
|
4
|
+
value: number;
|
|
5
5
|
}
|
|
6
6
|
export interface IntegerNode extends IntegerBaseNode {
|
|
7
7
|
readonly type: 'integer';
|
package/lib/node/LongNode.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { RangeLike } from '../source/index.js';
|
|
2
2
|
import type { AstNode } from './AstNode.js';
|
|
3
3
|
export interface LongBaseNode extends AstNode {
|
|
4
|
-
|
|
4
|
+
value: bigint;
|
|
5
5
|
}
|
|
6
6
|
export interface LongNode extends LongBaseNode {
|
|
7
7
|
readonly type: 'long';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FullResourceLocation } from '../common/index.js';
|
|
1
|
+
import type { DeepReadonly, FullResourceLocation } from '../common/index.js';
|
|
2
2
|
import { ResourceLocation } from '../common/index.js';
|
|
3
3
|
import type { RangeLike } from '../source/index.js';
|
|
4
4
|
import type { ResourceLocationCategory, SymbolAccessType, SymbolUsageType, TaggableResourceLocationCategory } from '../symbol/index.js';
|
|
@@ -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: ResourceLocationBaseNode
|
|
37
|
-
function toString(node: ResourceLocationBaseNode
|
|
36
|
+
function toString(node: DeepReadonly<ResourceLocationBaseNode>, type?: 'full'): FullResourceLocation;
|
|
37
|
+
function toString(node: DeepReadonly<ResourceLocationBaseNode>, type?: 'origin' | 'full' | 'short'): string;
|
|
38
38
|
}
|
|
39
39
|
//# sourceMappingURL=ResourceLocationNode.d.ts.map
|
package/lib/node/StringNode.d.ts
CHANGED
|
@@ -50,7 +50,7 @@ export interface StringOptions {
|
|
|
50
50
|
export declare type QuoteTypeConfig = 'always double' | 'always single' | 'prefer double' | 'prefer single';
|
|
51
51
|
export interface StringBaseNode extends AstNode {
|
|
52
52
|
readonly options: StringOptions;
|
|
53
|
-
|
|
53
|
+
value: string;
|
|
54
54
|
readonly valueMap: IndexMap;
|
|
55
55
|
}
|
|
56
56
|
export interface StringNode extends StringBaseNode {
|