@spyglassmc/core 0.1.2 → 0.2.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/README.md +7 -0
- package/lib/browser.d.ts +2 -0
- package/lib/browser.js +2 -0
- package/lib/common/TwoWayMap.js +4 -10
- package/lib/common/externals/BrowserExternals.d.ts +3 -0
- package/lib/common/externals/BrowserExternals.js +191 -0
- package/lib/common/externals/NodeJsExternals.d.ts +3 -0
- package/lib/common/externals/NodeJsExternals.js +151 -0
- package/lib/common/externals/downloader.d.ts +31 -0
- package/lib/common/externals/downloader.js +32 -0
- package/lib/common/externals/index.d.ts +96 -0
- package/lib/common/externals/index.js +2 -0
- package/lib/common/index.d.ts +2 -1
- package/lib/common/index.js +2 -17
- package/lib/common/util.d.ts +15 -15
- package/lib/common/util.js +30 -77
- package/lib/index.d.ts +7 -7
- package/lib/index.js +7 -23
- package/lib/node/AstNode.d.ts +3 -3
- package/lib/node/AstNode.js +10 -16
- package/lib/node/BooleanNode.d.ts +2 -2
- package/lib/node/BooleanNode.js +4 -7
- package/lib/node/CommentNode.d.ts +1 -1
- package/lib/node/CommentNode.js +2 -5
- package/lib/node/ErrorNode.d.ts +1 -1
- package/lib/node/ErrorNode.js +2 -5
- package/lib/node/FileNode.d.ts +3 -3
- package/lib/node/FileNode.js +2 -5
- package/lib/node/FloatNode.d.ts +2 -2
- package/lib/node/FloatNode.js +4 -7
- package/lib/node/IntegerNode.d.ts +2 -2
- package/lib/node/IntegerNode.js +4 -7
- package/lib/node/ListNode.d.ts +2 -2
- package/lib/node/ListNode.js +2 -5
- package/lib/node/LiteralNode.d.ts +3 -3
- package/lib/node/LiteralNode.js +4 -7
- package/lib/node/LongNode.d.ts +2 -2
- package/lib/node/LongNode.js +4 -7
- package/lib/node/RecordNode.d.ts +2 -2
- package/lib/node/RecordNode.js +2 -5
- package/lib/node/ResourceLocationNode.d.ts +5 -5
- package/lib/node/ResourceLocationNode.js +9 -12
- package/lib/node/Sequence.d.ts +2 -2
- package/lib/node/Sequence.js +4 -7
- package/lib/node/StringNode.d.ts +4 -4
- package/lib/node/StringNode.js +9 -12
- package/lib/node/SymbolNode.d.ts +3 -3
- package/lib/node/SymbolNode.js +4 -7
- package/lib/node/index.d.ts +15 -15
- package/lib/node/index.js +15 -31
- package/lib/nodejs.d.ts +2 -0
- package/lib/nodejs.js +2 -0
- package/lib/parser/Parser.d.ts +3 -3
- package/lib/parser/Parser.js +1 -4
- package/lib/parser/boolean.d.ts +2 -2
- package/lib/parser/boolean.js +3 -6
- package/lib/parser/comment.d.ts +2 -2
- package/lib/parser/comment.js +5 -9
- package/lib/parser/empty.d.ts +1 -1
- package/lib/parser/empty.js +1 -5
- package/lib/parser/error.d.ts +2 -2
- package/lib/parser/error.js +5 -9
- package/lib/parser/file.d.ts +3 -3
- package/lib/parser/file.js +9 -13
- package/lib/parser/float.d.ts +4 -4
- package/lib/parser/float.js +12 -16
- package/lib/parser/index.d.ts +16 -16
- package/lib/parser/index.js +16 -38
- package/lib/parser/integer.d.ts +4 -4
- package/lib/parser/integer.js +10 -14
- package/lib/parser/list.d.ts +2 -2
- package/lib/parser/list.js +15 -19
- package/lib/parser/literal.d.ts +2 -2
- package/lib/parser/literal.js +5 -9
- package/lib/parser/long.d.ts +4 -4
- package/lib/parser/long.js +10 -14
- package/lib/parser/record.d.ts +3 -3
- package/lib/parser/record.js +20 -24
- package/lib/parser/resourceLocation.d.ts +2 -2
- package/lib/parser/resourceLocation.js +14 -18
- package/lib/parser/string.d.ts +5 -5
- package/lib/parser/string.js +36 -42
- package/lib/parser/symbol.d.ts +3 -3
- package/lib/parser/symbol.js +3 -7
- package/lib/parser/util.d.ts +5 -5
- package/lib/parser/util.js +38 -56
- package/lib/processor/ColorInfoProvider.d.ts +1 -1
- package/lib/processor/ColorInfoProvider.js +6 -9
- package/lib/processor/InlayHintProvider.d.ts +2 -2
- package/lib/processor/InlayHintProvider.js +1 -2
- package/lib/processor/SignatureHelpProvider.d.ts +2 -2
- package/lib/processor/SignatureHelpProvider.js +1 -2
- package/lib/processor/checker/Checker.d.ts +2 -2
- package/lib/processor/checker/Checker.js +1 -5
- package/lib/processor/checker/builtin.d.ts +4 -4
- package/lib/processor/checker/builtin.js +19 -30
- package/lib/processor/checker/index.d.ts +2 -2
- package/lib/processor/checker/index.js +2 -31
- package/lib/processor/colorizer/Colorizer.d.ts +4 -4
- package/lib/processor/colorizer/Colorizer.js +8 -11
- package/lib/processor/colorizer/builtin.d.ts +3 -3
- package/lib/processor/colorizer/builtin.js +33 -46
- package/lib/processor/colorizer/index.d.ts +2 -2
- package/lib/processor/colorizer/index.js +2 -31
- package/lib/processor/completer/Completer.d.ts +4 -4
- package/lib/processor/completer/Completer.js +14 -33
- package/lib/processor/completer/builtin.d.ts +7 -7
- package/lib/processor/completer/builtin.js +46 -62
- package/lib/processor/completer/index.d.ts +2 -2
- package/lib/processor/completer/index.js +2 -31
- package/lib/processor/formatter/Formatter.d.ts +2 -2
- package/lib/processor/formatter/Formatter.js +2 -7
- package/lib/processor/formatter/builtin.d.ts +3 -3
- package/lib/processor/formatter/builtin.js +22 -36
- package/lib/processor/formatter/index.d.ts +2 -2
- package/lib/processor/formatter/index.js +2 -31
- package/lib/processor/index.d.ts +9 -9
- package/lib/processor/index.js +9 -25
- package/lib/processor/linter/Linter.d.ts +2 -2
- package/lib/processor/linter/Linter.js +1 -2
- package/lib/processor/linter/builtin/undeclaredSymbol.d.ts +2 -2
- package/lib/processor/linter/builtin/undeclaredSymbol.js +20 -24
- package/lib/processor/linter/builtin.d.ts +3 -3
- package/lib/processor/linter/builtin.js +19 -26
- package/lib/processor/linter/index.d.ts +2 -2
- package/lib/processor/linter/index.js +2 -31
- package/lib/processor/util.d.ts +2 -2
- package/lib/processor/util.js +4 -9
- package/lib/service/CacheService.d.ts +6 -6
- package/lib/service/CacheService.js +32 -56
- package/lib/service/Config.d.ts +11 -12
- package/lib/service/Config.js +50 -45
- package/lib/service/Context.d.ts +13 -13
- package/lib/service/Context.js +29 -32
- package/lib/service/Dependency.js +2 -5
- package/lib/service/Downloader.d.ts +10 -40
- package/lib/service/Downloader.js +37 -110
- package/lib/service/ErrorReporter.d.ts +2 -2
- package/lib/service/ErrorReporter.js +10 -14
- package/lib/service/FileService.d.ts +16 -14
- package/lib/service/FileService.js +55 -92
- package/lib/service/Hover.d.ts +2 -2
- package/lib/service/Hover.js +4 -7
- package/lib/service/Logger.js +2 -5
- package/lib/service/MetaRegistry.d.ts +12 -12
- package/lib/service/MetaRegistry.js +62 -73
- package/lib/service/Operations.js +3 -9
- package/lib/service/Profiler.d.ts +1 -1
- package/lib/service/Profiler.js +25 -41
- package/lib/service/Project.d.ts +47 -51
- package/lib/service/Project.js +199 -239
- package/lib/service/Service.d.ts +17 -27
- package/lib/service/Service.js +37 -43
- package/lib/service/SymbolLocations.d.ts +3 -3
- package/lib/service/SymbolLocations.js +4 -7
- package/lib/service/SymbolRegistrar.d.ts +1 -1
- package/lib/service/SymbolRegistrar.js +1 -2
- package/lib/service/fileUtil.d.ts +15 -45
- package/lib/service/fileUtil.js +38 -143
- package/lib/service/index.d.ts +17 -17
- package/lib/service/index.js +17 -35
- package/lib/source/IndexMap.d.ts +1 -1
- package/lib/source/IndexMap.js +7 -10
- package/lib/source/LanguageError.d.ts +2 -2
- package/lib/source/LanguageError.js +2 -5
- package/lib/source/Location.d.ts +3 -3
- package/lib/source/Location.js +6 -9
- package/lib/source/Offset.d.ts +1 -1
- package/lib/source/Offset.js +4 -7
- package/lib/source/Position.js +2 -5
- package/lib/source/PositionRange.d.ts +2 -2
- package/lib/source/PositionRange.js +14 -17
- package/lib/source/Range.d.ts +1 -1
- package/lib/source/Range.js +7 -10
- package/lib/source/Source.d.ts +3 -3
- package/lib/source/Source.js +28 -29
- package/lib/source/index.d.ts +8 -8
- package/lib/source/index.js +8 -24
- package/lib/symbol/Symbol.d.ts +2 -2
- package/lib/symbol/Symbol.js +49 -65
- package/lib/symbol/SymbolUtil.d.ts +22 -25
- package/lib/symbol/SymbolUtil.js +150 -151
- package/lib/symbol/UriBinder.d.ts +1 -1
- package/lib/symbol/UriBinder.js +1 -2
- package/lib/symbol/index.d.ts +3 -3
- package/lib/symbol/index.js +3 -19
- package/package.json +7 -4
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
const symbol_1 = require("../../symbol");
|
|
8
|
-
const undeclaredSymbol_1 = require("./builtin/undeclaredSymbol");
|
|
9
|
-
const noop = () => { };
|
|
10
|
-
exports.noop = noop;
|
|
1
|
+
import { localeQuote, localize } from '@spyglassmc/locales';
|
|
2
|
+
import { isAllowedCharacter } from '../../parser/index.js';
|
|
3
|
+
import { SymbolLinterConfig } from '../../service/index.js';
|
|
4
|
+
import { McdocCategories } from '../../symbol/index.js';
|
|
5
|
+
import { undeclaredSymbol } from './builtin/undeclaredSymbol.js';
|
|
6
|
+
export const noop = () => { };
|
|
11
7
|
/**
|
|
12
8
|
* @param key The name of the key on the {@link AstNode} that contains the value to be validated.
|
|
13
9
|
*/
|
|
14
|
-
function nameConvention(key) {
|
|
10
|
+
export function nameConvention(key) {
|
|
15
11
|
return (node, ctx) => {
|
|
16
12
|
if (typeof node[key] !== 'string') {
|
|
17
13
|
throw new Error(`Trying to access property "${key}" of node type "${node.type}"`);
|
|
@@ -21,7 +17,7 @@ function nameConvention(key) {
|
|
|
21
17
|
// SECURITY: ReDoS attack. The risk is acceptable at the moment.
|
|
22
18
|
const regex = new RegExp(ctx.ruleValue);
|
|
23
19
|
if (!name.match(regex)) {
|
|
24
|
-
ctx.err.lint(
|
|
20
|
+
ctx.err.lint(localize('linter.name-convention.illegal', localeQuote(name), localeQuote(ctx.ruleValue)), node);
|
|
25
21
|
}
|
|
26
22
|
}
|
|
27
23
|
catch (e) {
|
|
@@ -29,11 +25,10 @@ function nameConvention(key) {
|
|
|
29
25
|
}
|
|
30
26
|
};
|
|
31
27
|
}
|
|
32
|
-
|
|
33
|
-
const quote = (node, ctx) => {
|
|
28
|
+
export const quote = (node, ctx) => {
|
|
34
29
|
const config = ctx.ruleValue;
|
|
35
30
|
const mustValueBeQuoted = node.options.unquotable
|
|
36
|
-
? [...node.value].some(c => !
|
|
31
|
+
? [...node.value].some(c => !isAllowedCharacter(c, node.options.unquotable))
|
|
37
32
|
: true;
|
|
38
33
|
const isQuoteRequired = config.always || mustValueBeQuoted;
|
|
39
34
|
const isQuoteProhibited = config.always === false && !mustValueBeQuoted;
|
|
@@ -53,18 +48,17 @@ const quote = (node, ctx) => {
|
|
|
53
48
|
// TODO: Error no quote expected
|
|
54
49
|
}
|
|
55
50
|
};
|
|
56
|
-
|
|
57
|
-
var configValidator;
|
|
51
|
+
export var configValidator;
|
|
58
52
|
(function (configValidator) {
|
|
59
53
|
function getDocLink(name) {
|
|
60
54
|
return `https://spyglassmc.com/user/lint/${name}`;
|
|
61
55
|
}
|
|
62
56
|
function wrapError(name, msg) {
|
|
63
|
-
return `[Invalid Linter Config] [${name}] ${
|
|
57
|
+
return `[Invalid Linter Config] [${name}] ${localize('linter-config-validator.wrapper', msg, getDocLink(name))}`;
|
|
64
58
|
}
|
|
65
59
|
function nameConvention(name, val, logger) {
|
|
66
60
|
if (typeof val !== 'string') {
|
|
67
|
-
logger.error(wrapError(name,
|
|
61
|
+
logger.error(wrapError(name, localize('linter-config-validator.name-convention.type')));
|
|
68
62
|
return false;
|
|
69
63
|
}
|
|
70
64
|
try {
|
|
@@ -72,7 +66,7 @@ var configValidator;
|
|
|
72
66
|
new RegExp(val);
|
|
73
67
|
}
|
|
74
68
|
catch (e) {
|
|
75
|
-
logger.error(wrapError(name,
|
|
69
|
+
logger.error(wrapError(name, localize('') // FIXME
|
|
76
70
|
), e);
|
|
77
71
|
return false;
|
|
78
72
|
}
|
|
@@ -80,11 +74,11 @@ var configValidator;
|
|
|
80
74
|
}
|
|
81
75
|
configValidator.nameConvention = nameConvention;
|
|
82
76
|
function symbolLinterConfig(_name, value, _logger) {
|
|
83
|
-
return
|
|
77
|
+
return SymbolLinterConfig.is(value);
|
|
84
78
|
}
|
|
85
79
|
configValidator.symbolLinterConfig = symbolLinterConfig;
|
|
86
|
-
})(configValidator
|
|
87
|
-
function registerLinters(meta) {
|
|
80
|
+
})(configValidator || (configValidator = {}));
|
|
81
|
+
export function registerLinters(meta) {
|
|
88
82
|
meta.registerLinter('nameOfObjective', {
|
|
89
83
|
configValidator: configValidator.nameConvention,
|
|
90
84
|
linter: nameConvention('value'),
|
|
@@ -107,9 +101,8 @@ function registerLinters(meta) {
|
|
|
107
101
|
});
|
|
108
102
|
meta.registerLinter('undeclaredSymbol', {
|
|
109
103
|
configValidator: configValidator.symbolLinterConfig,
|
|
110
|
-
linter:
|
|
111
|
-
nodePredicate: n => n.symbol && !
|
|
104
|
+
linter: undeclaredSymbol,
|
|
105
|
+
nodePredicate: n => n.symbol && !McdocCategories.includes(n.symbol.category),
|
|
112
106
|
});
|
|
113
107
|
}
|
|
114
|
-
exports.registerLinters = registerLinters;
|
|
115
108
|
//# sourceMappingURL=builtin.js.map
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * as linter from './builtin';
|
|
2
|
-
export * from './Linter';
|
|
1
|
+
export * as linter from './builtin.js';
|
|
2
|
+
export * from './Linter.js';
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,32 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
26
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
27
|
-
};
|
|
28
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.linter = void 0;
|
|
30
|
-
exports.linter = __importStar(require("./builtin"));
|
|
31
|
-
__exportStar(require("./Linter"), exports);
|
|
1
|
+
export * as linter from './builtin.js';
|
|
2
|
+
export * from './Linter.js';
|
|
32
3
|
//# sourceMappingURL=index.js.map
|
package/lib/processor/util.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { AstNode } from '../node';
|
|
2
|
-
import { Range } from '../source';
|
|
1
|
+
import type { AstNode } from '../node/index.js';
|
|
2
|
+
import { Range } from '../source/index.js';
|
|
3
3
|
declare type Callback<R> = (this: void, node: AstNode, parents: AstNode[]) => R;
|
|
4
4
|
export declare function traversePreOrder(node: AstNode, shouldContinue: Callback<unknown>, shouldCallFn: Callback<unknown>, fn: Callback<unknown>): void;
|
|
5
5
|
interface NodeResult {
|
package/lib/processor/util.js
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.findNode = exports.traversePreOrder = void 0;
|
|
4
|
-
const source_1 = require("../source");
|
|
5
|
-
function traversePreOrder(node, shouldContinue, shouldCallFn, fn) {
|
|
1
|
+
import { Range } from '../source/index.js';
|
|
2
|
+
export function traversePreOrder(node, shouldContinue, shouldCallFn, fn) {
|
|
6
3
|
traversePreOrderImpl(node, shouldContinue, shouldCallFn, fn, []);
|
|
7
4
|
}
|
|
8
|
-
exports.traversePreOrder = traversePreOrder;
|
|
9
5
|
function traversePreOrderImpl(node, shouldContinue, shouldCallFn, fn, parents) {
|
|
10
6
|
if (shouldCallFn(node, parents)) {
|
|
11
7
|
fn(node, parents);
|
|
@@ -22,11 +18,10 @@ function traversePreOrderImpl(node, shouldContinue, shouldCallFn, fn, parents) {
|
|
|
22
18
|
/**
|
|
23
19
|
* @returns The shallowest node that is fully contained within `range`.
|
|
24
20
|
*/
|
|
25
|
-
function findNode(node, range) {
|
|
21
|
+
export function findNode(node, range) {
|
|
26
22
|
let ans = { node: undefined, parents: [] };
|
|
27
23
|
// TODO: Binary search here.
|
|
28
|
-
traversePreOrder(node, (node) => ans.node === undefined &&
|
|
24
|
+
traversePreOrder(node, (node) => ans.node === undefined && Range.intersects(node.range, range), (node) => Range.containsRange(range, node.range), (node, parents) => ans = { node, parents: [...parents] });
|
|
29
25
|
return ans;
|
|
30
26
|
}
|
|
31
|
-
exports.findNode = findNode;
|
|
32
27
|
//# sourceMappingURL=util.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { SymbolTable } from '../symbol';
|
|
2
|
-
import type { RootUriString } from './fileUtil';
|
|
3
|
-
import type { Project } from './Project';
|
|
1
|
+
import { SymbolTable } from '../symbol/index.js';
|
|
2
|
+
import type { RootUriString } from './fileUtil.js';
|
|
3
|
+
import type { Project } from './Project.js';
|
|
4
4
|
/**
|
|
5
5
|
* The format version of the cache. Should be increased when any changes that
|
|
6
6
|
* could invalidate the cache are introduced to the Spyglass codebase.
|
|
@@ -35,13 +35,13 @@ export declare class CacheService {
|
|
|
35
35
|
* @param cacheRoot File path to the directory where cache files by Spyglass should be stored.
|
|
36
36
|
* @param project
|
|
37
37
|
*/
|
|
38
|
-
constructor(cacheRoot:
|
|
38
|
+
constructor(cacheRoot: RootUriString, project: Project);
|
|
39
39
|
/**
|
|
40
40
|
* @throws
|
|
41
41
|
*
|
|
42
|
-
* @returns `${cacheRoot}
|
|
42
|
+
* @returns `${cacheRoot}symbols/${sha1(projectRoot)}.json`
|
|
43
43
|
*/
|
|
44
|
-
private
|
|
44
|
+
private getCacheFileUri;
|
|
45
45
|
load(): Promise<LoadResult>;
|
|
46
46
|
validate(): Promise<ValidateResult>;
|
|
47
47
|
/**
|
|
@@ -1,30 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
5
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
|
-
};
|
|
7
|
-
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
8
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
9
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
10
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
11
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
12
|
-
};
|
|
13
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
-
};
|
|
16
|
-
var _CacheService_hasValidatedFiles, _CacheService_cacheFilePath;
|
|
17
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.CacheService = exports.LatestCacheVersion = void 0;
|
|
19
|
-
const path_1 = __importDefault(require("path"));
|
|
20
|
-
const common_1 = require("../common");
|
|
21
|
-
const symbol_1 = require("../symbol");
|
|
22
|
-
const fileUtil_1 = require("./fileUtil");
|
|
1
|
+
import { Uri } from '../common/index.js';
|
|
2
|
+
import { SymbolTable } from '../symbol/index.js';
|
|
3
|
+
import { fileUtil } from './fileUtil.js';
|
|
23
4
|
/**
|
|
24
5
|
* The format version of the cache. Should be increased when any changes that
|
|
25
6
|
* could invalidate the cache are introduced to the Spyglass codebase.
|
|
26
7
|
*/
|
|
27
|
-
|
|
8
|
+
export const LatestCacheVersion = 1;
|
|
28
9
|
var Checksums;
|
|
29
10
|
(function (Checksums) {
|
|
30
11
|
function create() {
|
|
@@ -36,7 +17,11 @@ var Checksums;
|
|
|
36
17
|
}
|
|
37
18
|
Checksums.create = create;
|
|
38
19
|
})(Checksums || (Checksums = {}));
|
|
39
|
-
class CacheService {
|
|
20
|
+
export class CacheService {
|
|
21
|
+
cacheRoot;
|
|
22
|
+
project;
|
|
23
|
+
checksums = Checksums.create();
|
|
24
|
+
#hasValidatedFiles = false;
|
|
40
25
|
/**
|
|
41
26
|
* @param cacheRoot File path to the directory where cache files by Spyglass should be stored.
|
|
42
27
|
* @param project
|
|
@@ -44,30 +29,22 @@ class CacheService {
|
|
|
44
29
|
constructor(cacheRoot, project) {
|
|
45
30
|
this.cacheRoot = cacheRoot;
|
|
46
31
|
this.project = project;
|
|
47
|
-
this.
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* @param cacheRoot File path to the directory where cache files by Spyglass should be stored.
|
|
51
|
-
* @param project
|
|
52
|
-
*/
|
|
53
|
-
);
|
|
54
|
-
_CacheService_cacheFilePath.set(this, void 0);
|
|
55
|
-
this.project.on('documentUpdated', ({ doc }) => {
|
|
56
|
-
if (!__classPrivateFieldGet(this, _CacheService_hasValidatedFiles, "f")) {
|
|
32
|
+
this.project.on('documentUpdated', async ({ doc }) => {
|
|
33
|
+
if (!this.#hasValidatedFiles) {
|
|
57
34
|
return;
|
|
58
35
|
}
|
|
59
36
|
try {
|
|
60
37
|
// TODO: Don't update this for every single change.
|
|
61
|
-
this.checksums.files[doc.uri] =
|
|
38
|
+
this.checksums.files[doc.uri] = await this.project.externals.crypto.getSha1(doc.getText());
|
|
62
39
|
}
|
|
63
40
|
catch (e) {
|
|
64
|
-
if (!
|
|
41
|
+
if (!this.project.externals.error.isKind(e, 'EISDIR')) {
|
|
65
42
|
this.project.logger.error(`[CacheService#hash-file] ${doc.uri}`);
|
|
66
43
|
}
|
|
67
44
|
}
|
|
68
45
|
});
|
|
69
46
|
this.project.on('rootsUpdated', async ({ roots }) => {
|
|
70
|
-
if (!
|
|
47
|
+
if (!this.#hasValidatedFiles) {
|
|
71
48
|
return;
|
|
72
49
|
}
|
|
73
50
|
for (const root of roots) {
|
|
@@ -75,7 +52,7 @@ class CacheService {
|
|
|
75
52
|
this.checksums.roots[root] = await this.project.fs.hash(root);
|
|
76
53
|
}
|
|
77
54
|
catch (e) {
|
|
78
|
-
if (!
|
|
55
|
+
if (!this.project.externals.error.isKind(e, 'EISDIR')) {
|
|
79
56
|
this.project.logger.error(`[CacheService#hash-root] ${root}`);
|
|
80
57
|
}
|
|
81
58
|
}
|
|
@@ -87,34 +64,35 @@ class CacheService {
|
|
|
87
64
|
}
|
|
88
65
|
});
|
|
89
66
|
}
|
|
67
|
+
#cacheFilePath;
|
|
90
68
|
/**
|
|
91
69
|
* @throws
|
|
92
70
|
*
|
|
93
|
-
* @returns `${cacheRoot}
|
|
71
|
+
* @returns `${cacheRoot}symbols/${sha1(projectRoot)}.json`
|
|
94
72
|
*/
|
|
95
|
-
|
|
96
|
-
return
|
|
73
|
+
async getCacheFileUri() {
|
|
74
|
+
return this.#cacheFilePath ??= new Uri(`symbols/${await this.project.externals.crypto.getSha1(this.project.projectRoot)}.json.gz`, this.cacheRoot).toString();
|
|
97
75
|
}
|
|
98
76
|
async load() {
|
|
99
77
|
const __profiler = this.project.profilers.get('cache#load');
|
|
100
78
|
const ans = { symbols: {} };
|
|
101
79
|
let filePath;
|
|
102
80
|
try {
|
|
103
|
-
filePath = this.
|
|
81
|
+
filePath = await this.getCacheFileUri();
|
|
104
82
|
this.project.logger.info(`[CacheService#load] symbolCachePath = “${filePath}”`);
|
|
105
|
-
const cache = await
|
|
83
|
+
const cache = await fileUtil.readGzippedJson(this.project.externals, filePath);
|
|
106
84
|
__profiler.task('Read File');
|
|
107
|
-
if (cache.version ===
|
|
85
|
+
if (cache.version === LatestCacheVersion) {
|
|
108
86
|
this.checksums = cache.checksums;
|
|
109
|
-
ans.symbols =
|
|
87
|
+
ans.symbols = SymbolTable.link(cache.symbols);
|
|
110
88
|
__profiler.task('Link Symbols');
|
|
111
89
|
}
|
|
112
90
|
else {
|
|
113
|
-
this.project.logger.info(`[CacheService#load] Unsupported cache format ${cache.version}; expected ${
|
|
91
|
+
this.project.logger.info(`[CacheService#load] Unsupported cache format ${cache.version}; expected ${LatestCacheVersion}`);
|
|
114
92
|
}
|
|
115
93
|
}
|
|
116
94
|
catch (e) {
|
|
117
|
-
if (!(
|
|
95
|
+
if (!this.project.externals.error.isKind(e, 'ENOENT')) {
|
|
118
96
|
this.project.logger.error('[CacheService#load] ', e);
|
|
119
97
|
}
|
|
120
98
|
}
|
|
@@ -137,7 +115,7 @@ class CacheService {
|
|
|
137
115
|
}
|
|
138
116
|
}
|
|
139
117
|
catch (e) {
|
|
140
|
-
if (!
|
|
118
|
+
if (!this.project.externals.error.isKind(e, 'EISDIR')) {
|
|
141
119
|
this.project.logger.error(`[CacheService#hash-file] ${uri}`);
|
|
142
120
|
}
|
|
143
121
|
// Failed calculating hash. Assume the root has changed.
|
|
@@ -158,7 +136,7 @@ class CacheService {
|
|
|
158
136
|
}
|
|
159
137
|
}
|
|
160
138
|
catch (e) {
|
|
161
|
-
if ((
|
|
139
|
+
if (this.project.externals.error.isKind(e, 'ENOENT') || this.project.externals.error.isKind(e, 'EISDIR')) {
|
|
162
140
|
ans.removedFiles.push(uri);
|
|
163
141
|
}
|
|
164
142
|
else {
|
|
@@ -173,7 +151,7 @@ class CacheService {
|
|
|
173
151
|
ans.addedFiles.push(uri);
|
|
174
152
|
}
|
|
175
153
|
}
|
|
176
|
-
|
|
154
|
+
this.#hasValidatedFiles = true;
|
|
177
155
|
return ans;
|
|
178
156
|
}
|
|
179
157
|
/**
|
|
@@ -183,15 +161,15 @@ class CacheService {
|
|
|
183
161
|
const __profiler = this.project.profilers.get('cache#save');
|
|
184
162
|
let filePath;
|
|
185
163
|
try {
|
|
186
|
-
filePath = this.
|
|
164
|
+
filePath = await this.getCacheFileUri();
|
|
187
165
|
const cache = {
|
|
188
166
|
checksums: this.checksums,
|
|
189
167
|
projectRoot: this.project.projectRoot,
|
|
190
|
-
symbols:
|
|
191
|
-
version:
|
|
168
|
+
symbols: SymbolTable.unlink(this.project.symbols.global),
|
|
169
|
+
version: LatestCacheVersion,
|
|
192
170
|
};
|
|
193
171
|
__profiler.task('Unlink Symbols');
|
|
194
|
-
await
|
|
172
|
+
await fileUtil.writeGzippedJson(this.project.externals, filePath, cache);
|
|
195
173
|
__profiler.task('Write File').finalize();
|
|
196
174
|
return true;
|
|
197
175
|
}
|
|
@@ -204,6 +182,4 @@ class CacheService {
|
|
|
204
182
|
this.checksums = Checksums.create();
|
|
205
183
|
}
|
|
206
184
|
}
|
|
207
|
-
exports.CacheService = CacheService;
|
|
208
|
-
_CacheService_hasValidatedFiles = new WeakMap(), _CacheService_cacheFilePath = new WeakMap();
|
|
209
185
|
//# sourceMappingURL=CacheService.js.map
|
package/lib/service/Config.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import type { Project } from './Project';
|
|
1
|
+
import type { ExternalEventEmitter } from '../common/index.js';
|
|
2
|
+
import { Arrayable } from '../common/index.js';
|
|
3
|
+
import { ErrorSeverity } from '../source/index.js';
|
|
4
|
+
import type { Project } from './Project.js';
|
|
6
5
|
export interface Config {
|
|
7
6
|
/**
|
|
8
7
|
* Environment settings. Unlike other configs, all involved root folders must have the same `env` settings. It is undocumented
|
|
@@ -200,21 +199,21 @@ declare type ErrorEvent = {
|
|
|
200
199
|
error: unknown;
|
|
201
200
|
uri: string;
|
|
202
201
|
};
|
|
203
|
-
export
|
|
202
|
+
export declare class ConfigService implements ExternalEventEmitter {
|
|
203
|
+
#private;
|
|
204
|
+
private readonly project;
|
|
205
|
+
private readonly defaultConfig;
|
|
206
|
+
static readonly ConfigFileNames: readonly ["spyglass.json", ".spyglassrc.json"];
|
|
207
|
+
constructor(project: Project, defaultConfig?: Config);
|
|
204
208
|
on(event: 'changed', callbackFn: (data: ConfigEvent) => void): this;
|
|
205
209
|
on(event: 'error', callbackFn: (data: ErrorEvent) => void): this;
|
|
206
210
|
once(event: 'changed', callbackFn: (data: ConfigEvent) => void): this;
|
|
207
211
|
once(event: 'error', callbackFn: (data: ErrorEvent) => void): this;
|
|
208
212
|
emit(event: 'changed', data: ConfigEvent): boolean;
|
|
209
213
|
emit(event: 'error', data: ErrorEvent): boolean;
|
|
210
|
-
}
|
|
211
|
-
export declare class ConfigService extends EventEmitter {
|
|
212
|
-
private readonly project;
|
|
213
|
-
static readonly ConfigFileNames: readonly ["spyglass.json", ".spyglassrc.json"];
|
|
214
|
-
constructor(project: Project);
|
|
215
214
|
load(): Promise<Config>;
|
|
216
215
|
private static isConfigFile;
|
|
217
|
-
|
|
216
|
+
static merge(base: Config, ...overrides: any[]): Config;
|
|
218
217
|
}
|
|
219
218
|
export {};
|
|
220
219
|
//# sourceMappingURL=Config.d.ts.map
|
package/lib/service/Config.js
CHANGED
|
@@ -1,15 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.ConfigService = exports.VanillaConfig = exports.SymbolLinterConfig = exports.LinterConfigValue = exports.LinterSeverity = void 0;
|
|
7
|
-
const events_1 = __importDefault(require("events"));
|
|
8
|
-
const fs_1 = require("fs");
|
|
9
|
-
const rfdc_1 = __importDefault(require("rfdc"));
|
|
10
|
-
const common_1 = require("../common");
|
|
11
|
-
const symbol_1 = require("../symbol");
|
|
12
|
-
var LinterSeverity;
|
|
1
|
+
import rfdc from 'rfdc';
|
|
2
|
+
import { Arrayable, bufferToString, TypePredicates } from '../common/index.js';
|
|
3
|
+
import { FileCategories, RegistryCategories } from '../symbol/index.js';
|
|
4
|
+
export var LinterSeverity;
|
|
13
5
|
(function (LinterSeverity) {
|
|
14
6
|
function is(value) {
|
|
15
7
|
return value === 'hint' ||
|
|
@@ -31,8 +23,8 @@ var LinterSeverity;
|
|
|
31
23
|
}
|
|
32
24
|
}
|
|
33
25
|
LinterSeverity.toErrorSeverity = toErrorSeverity;
|
|
34
|
-
})(LinterSeverity
|
|
35
|
-
var LinterConfigValue;
|
|
26
|
+
})(LinterSeverity || (LinterSeverity = {}));
|
|
27
|
+
export var LinterConfigValue;
|
|
36
28
|
(function (LinterConfigValue) {
|
|
37
29
|
function destruct(value) {
|
|
38
30
|
if (value === null || value === undefined) {
|
|
@@ -56,11 +48,11 @@ var LinterConfigValue;
|
|
|
56
48
|
};
|
|
57
49
|
}
|
|
58
50
|
LinterConfigValue.destruct = destruct;
|
|
59
|
-
})(LinterConfigValue
|
|
60
|
-
var SymbolLinterConfig;
|
|
51
|
+
})(LinterConfigValue || (LinterConfigValue = {}));
|
|
52
|
+
export var SymbolLinterConfig;
|
|
61
53
|
(function (SymbolLinterConfig) {
|
|
62
54
|
function is(value) {
|
|
63
|
-
return
|
|
55
|
+
return Arrayable.is(value, Complex.is) || Action.is(value);
|
|
64
56
|
}
|
|
65
57
|
SymbolLinterConfig.is = is;
|
|
66
58
|
let Complex;
|
|
@@ -70,9 +62,9 @@ var SymbolLinterConfig;
|
|
|
70
62
|
return false;
|
|
71
63
|
}
|
|
72
64
|
const value = v;
|
|
73
|
-
return ((value.if === undefined ||
|
|
65
|
+
return ((value.if === undefined || Arrayable.is(value.if, Condition.is)) &&
|
|
74
66
|
(value.then === undefined || Action.is(value.then)) &&
|
|
75
|
-
(value.override === undefined ||
|
|
67
|
+
(value.override === undefined || Arrayable.is(value.override, Complex.is)));
|
|
76
68
|
}
|
|
77
69
|
Complex.is = is;
|
|
78
70
|
})(Complex = SymbolLinterConfig.Complex || (SymbolLinterConfig.Complex = {}));
|
|
@@ -83,11 +75,11 @@ var SymbolLinterConfig;
|
|
|
83
75
|
return false;
|
|
84
76
|
}
|
|
85
77
|
const value = v;
|
|
86
|
-
return ((value.category === undefined ||
|
|
87
|
-
(value.pattern === undefined ||
|
|
88
|
-
(value.excludePattern === undefined ||
|
|
89
|
-
(value.namespace === undefined ||
|
|
90
|
-
(value.excludeNamespace === undefined ||
|
|
78
|
+
return ((value.category === undefined || Arrayable.is(value.category, TypePredicates.isString)) &&
|
|
79
|
+
(value.pattern === undefined || Arrayable.is(value.pattern, TypePredicates.isString)) &&
|
|
80
|
+
(value.excludePattern === undefined || Arrayable.is(value.excludePattern, TypePredicates.isString)) &&
|
|
81
|
+
(value.namespace === undefined || Arrayable.is(value.namespace, TypePredicates.isString)) &&
|
|
82
|
+
(value.excludeNamespace === undefined || Arrayable.is(value.excludeNamespace, TypePredicates.isString)));
|
|
91
83
|
}
|
|
92
84
|
Condition.is = is;
|
|
93
85
|
})(Condition = SymbolLinterConfig.Condition || (SymbolLinterConfig.Condition = {}));
|
|
@@ -110,11 +102,11 @@ var SymbolLinterConfig;
|
|
|
110
102
|
}
|
|
111
103
|
Action.is = is;
|
|
112
104
|
})(Action = SymbolLinterConfig.Action || (SymbolLinterConfig.Action = {}));
|
|
113
|
-
})(SymbolLinterConfig
|
|
105
|
+
})(SymbolLinterConfig || (SymbolLinterConfig = {}));
|
|
114
106
|
/**
|
|
115
107
|
* Config which simulates the default vanilla command system.
|
|
116
108
|
*/
|
|
117
|
-
|
|
109
|
+
export const VanillaConfig = {
|
|
118
110
|
env: {
|
|
119
111
|
dataSource: 'GitHub',
|
|
120
112
|
dependencies: [
|
|
@@ -195,8 +187,8 @@ exports.VanillaConfig = {
|
|
|
195
187
|
undeclaredSymbol: [
|
|
196
188
|
{
|
|
197
189
|
if: [
|
|
198
|
-
{ category:
|
|
199
|
-
{ category: [...
|
|
190
|
+
{ category: RegistryCategories, namespace: 'minecraft' },
|
|
191
|
+
{ category: [...FileCategories, 'bossbar', 'objective', 'team'] },
|
|
200
192
|
],
|
|
201
193
|
then: { report: 'warning' },
|
|
202
194
|
},
|
|
@@ -210,10 +202,18 @@ exports.VanillaConfig = {
|
|
|
210
202
|
summonAec: 'summon minecraft:area_effect_cloud ~ ~ ~ {Age: -2147483648, Duration: -1, WaitTime: -2147483648, Tags: ["${1:tag}"]}',
|
|
211
203
|
},
|
|
212
204
|
};
|
|
213
|
-
class ConfigService
|
|
214
|
-
|
|
215
|
-
|
|
205
|
+
export class ConfigService {
|
|
206
|
+
project;
|
|
207
|
+
defaultConfig;
|
|
208
|
+
static ConfigFileNames = Object.freeze([
|
|
209
|
+
'spyglass.json',
|
|
210
|
+
'.spyglassrc.json',
|
|
211
|
+
]);
|
|
212
|
+
#eventEmitter;
|
|
213
|
+
constructor(project, defaultConfig = VanillaConfig) {
|
|
216
214
|
this.project = project;
|
|
215
|
+
this.defaultConfig = defaultConfig;
|
|
216
|
+
this.#eventEmitter = new project.externals.event.EventEmitter();
|
|
217
217
|
const handler = async ({ uri }) => {
|
|
218
218
|
if (ConfigService.isConfigFile(uri)) {
|
|
219
219
|
this.emit('changed', { config: await this.load() });
|
|
@@ -223,31 +223,41 @@ class ConfigService extends events_1.default {
|
|
|
223
223
|
project.on('fileModified', handler);
|
|
224
224
|
project.on('fileDeleted', handler);
|
|
225
225
|
}
|
|
226
|
+
on(event, callbackFn) {
|
|
227
|
+
this.#eventEmitter.on(event, callbackFn);
|
|
228
|
+
return this;
|
|
229
|
+
}
|
|
230
|
+
once(event, callbackFn) {
|
|
231
|
+
this.#eventEmitter.once(event, callbackFn);
|
|
232
|
+
return this;
|
|
233
|
+
}
|
|
234
|
+
emit(event, ...args) {
|
|
235
|
+
return this.#eventEmitter.emit(event, ...args);
|
|
236
|
+
}
|
|
226
237
|
async load() {
|
|
227
|
-
let ans =
|
|
238
|
+
let ans = this.defaultConfig;
|
|
228
239
|
for (const name of ConfigService.ConfigFileNames) {
|
|
229
|
-
const
|
|
230
|
-
const uri = new common_1.Uri(uriString);
|
|
240
|
+
const uri = this.project.projectRoot + name;
|
|
231
241
|
try {
|
|
232
|
-
ans = JSON.parse(
|
|
242
|
+
ans = JSON.parse(bufferToString(await this.project.externals.fs.readFile(uri)));
|
|
233
243
|
}
|
|
234
244
|
catch (e) {
|
|
235
|
-
if ((
|
|
245
|
+
if (this.project.externals.error.isKind(e, 'ENOENT')) {
|
|
236
246
|
// File doesn't exist.
|
|
237
247
|
continue;
|
|
238
248
|
}
|
|
239
|
-
this.emit('error', { error: e, uri
|
|
249
|
+
this.emit('error', { error: e, uri });
|
|
240
250
|
}
|
|
241
251
|
break;
|
|
242
252
|
}
|
|
243
|
-
return
|
|
253
|
+
return ConfigService.merge(this.defaultConfig, ans);
|
|
244
254
|
}
|
|
245
255
|
static isConfigFile(uri) {
|
|
246
256
|
return ConfigService.ConfigFileNames.some(n => uri.endsWith(`/${n}`));
|
|
247
257
|
}
|
|
248
|
-
merge(base, ...overrides) {
|
|
258
|
+
static merge(base, ...overrides) {
|
|
249
259
|
// FIXME
|
|
250
|
-
const ans = (
|
|
260
|
+
const ans = rfdc()(base);
|
|
251
261
|
for (const override of overrides) {
|
|
252
262
|
for (const key of ['env', 'format', 'lint', 'snippet']) {
|
|
253
263
|
ans[key] = { ...ans[key], ...override[key] };
|
|
@@ -256,9 +266,4 @@ class ConfigService extends events_1.default {
|
|
|
256
266
|
return ans;
|
|
257
267
|
}
|
|
258
268
|
}
|
|
259
|
-
exports.ConfigService = ConfigService;
|
|
260
|
-
ConfigService.ConfigFileNames = Object.freeze([
|
|
261
|
-
'spyglass.json',
|
|
262
|
-
'.spyglassrc.json',
|
|
263
|
-
]);
|
|
264
269
|
//# sourceMappingURL=Config.js.map
|