@spyglassmc/core 0.4.0 → 0.4.2
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.js +5 -2
- package/lib/common/Operations.js +7 -3
- package/lib/common/ReadonlyProxy.d.ts +2 -2
- package/lib/common/ReadonlyProxy.js +3 -1
- package/lib/common/StateProxy.d.ts +2 -2
- package/lib/common/StateProxy.js +18 -7
- package/lib/common/externals/BrowserExternals.js +2 -9
- package/lib/common/externals/NodeJsExternals.js +11 -18
- package/lib/common/externals/downloader.d.ts +2 -2
- package/lib/common/externals/index.d.ts +2 -5
- package/lib/common/util.d.ts +8 -7
- package/lib/common/util.js +16 -12
- package/lib/node/AstNode.d.ts +1 -1
- package/lib/node/AstNode.js +9 -5
- package/lib/node/CommentNode.d.ts +2 -2
- package/lib/node/FileNode.js +6 -1
- package/lib/node/ResourceLocationNode.d.ts +3 -3
- package/lib/node/ResourceLocationNode.js +9 -5
- package/lib/node/StringNode.d.ts +3 -3
- package/lib/node/StringNode.js +4 -1
- package/lib/parser/Parser.d.ts +5 -5
- package/lib/parser/boolean.js +1 -1
- package/lib/parser/comment.d.ts +1 -1
- package/lib/parser/comment.js +1 -1
- package/lib/parser/float.d.ts +1 -1
- package/lib/parser/float.js +2 -1
- package/lib/parser/integer.d.ts +1 -1
- package/lib/parser/integer.js +2 -1
- package/lib/parser/list.d.ts +1 -1
- package/lib/parser/list.js +3 -3
- package/lib/parser/long.d.ts +1 -1
- package/lib/parser/long.js +2 -1
- package/lib/parser/record.d.ts +1 -1
- package/lib/parser/record.js +18 -8
- package/lib/parser/resourceLocation.js +61 -8
- package/lib/parser/string.js +79 -8
- package/lib/parser/util.d.ts +7 -7
- package/lib/parser/util.js +14 -5
- package/lib/processor/ColorInfoProvider.d.ts +3 -3
- package/lib/processor/ColorInfoProvider.js +22 -7
- package/lib/processor/InlayHintProvider.d.ts +1 -1
- package/lib/processor/SignatureHelpProvider.d.ts +1 -1
- package/lib/processor/binder/Binder.d.ts +1 -1
- package/lib/processor/binder/builtin.d.ts +2 -2
- package/lib/processor/binder/builtin.js +30 -18
- package/lib/processor/binder/index.d.ts +1 -1
- package/lib/processor/binder/index.js +1 -1
- package/lib/processor/checker/Checker.d.ts +3 -3
- package/lib/processor/checker/builtin.d.ts +2 -3
- package/lib/processor/checker/builtin.js +12 -13
- package/lib/processor/colorizer/Colorizer.d.ts +3 -3
- package/lib/processor/colorizer/builtin.js +8 -7
- package/lib/processor/completer/Completer.d.ts +1 -1
- package/lib/processor/completer/Completer.js +4 -2
- package/lib/processor/completer/builtin.js +33 -26
- package/lib/processor/formatter/Formatter.d.ts +1 -1
- package/lib/processor/formatter/Formatter.js +3 -1
- package/lib/processor/formatter/builtin.js +14 -12
- package/lib/processor/linter/Linter.d.ts +1 -1
- package/lib/processor/linter/builtin/undeclaredSymbol.js +47 -24
- package/lib/processor/linter/builtin.js +7 -8
- package/lib/processor/util.d.ts +1 -1
- package/lib/service/CacheService.d.ts +1 -1
- package/lib/service/CacheService.js +9 -6
- package/lib/service/Config.d.ts +11 -11
- package/lib/service/Config.js +28 -21
- package/lib/service/Dependency.d.ts +3 -3
- package/lib/service/Downloader.js +12 -7
- package/lib/service/FileService.d.ts +1 -1
- package/lib/service/FileService.js +28 -10
- package/lib/service/MetaRegistry.js +7 -6
- package/lib/service/Profiler.js +10 -5
- package/lib/service/Project.d.ts +5 -5
- package/lib/service/Project.js +45 -34
- package/lib/service/Service.js +31 -12
- package/lib/service/SymbolRegistrar.d.ts +1 -1
- package/lib/service/UriProcessor.d.ts +3 -3
- package/lib/service/fileUtil.d.ts +2 -2
- package/lib/service/fileUtil.js +2 -1
- package/lib/source/IndexMap.d.ts +1 -1
- package/lib/source/IndexMap.js +1 -1
- package/lib/source/LanguageError.js +1 -1
- package/lib/source/Location.d.ts +1 -1
- package/lib/source/Location.js +4 -1
- package/lib/source/Offset.d.ts +1 -1
- package/lib/source/Range.d.ts +1 -1
- package/lib/source/Range.js +6 -3
- package/lib/source/Source.d.ts +4 -4
- package/lib/source/Source.js +3 -1
- package/lib/symbol/Symbol.d.ts +19 -19
- package/lib/symbol/Symbol.js +27 -12
- package/lib/symbol/SymbolUtil.d.ts +6 -6
- package/lib/symbol/SymbolUtil.js +76 -44
- package/package.json +2 -2
|
@@ -13,7 +13,7 @@ export function attempt(binder, node, ctx) {
|
|
|
13
13
|
const processAfterBinder = () => {
|
|
14
14
|
StateProxy.undoChanges(node);
|
|
15
15
|
const totalErrorSpan = tempCtx.err.errors
|
|
16
|
-
.map(e => e.range.end - e.range.start)
|
|
16
|
+
.map((e) => e.range.end - e.range.start)
|
|
17
17
|
.reduce((a, b) => a + b, 0);
|
|
18
18
|
return {
|
|
19
19
|
errorAmount: tempCtx.err.errors.length,
|
|
@@ -44,15 +44,14 @@ export function any(binders) {
|
|
|
44
44
|
if (binders.every(SyncBinder.is)) {
|
|
45
45
|
return SyncBinder.create((node, ctx) => {
|
|
46
46
|
const attempts = binders
|
|
47
|
-
.map(binder => attempt(binder, node, ctx))
|
|
47
|
+
.map((binder) => attempt(binder, node, ctx))
|
|
48
48
|
.sort(attemptSorter);
|
|
49
49
|
attempts[0].updateNodeAndCtx();
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
52
|
else {
|
|
53
53
|
return AsyncBinder.create(async (node, ctx) => {
|
|
54
|
-
const attempts = (await Promise.all(binders.map(binder => attempt(binder, node, ctx))))
|
|
55
|
-
.sort(attemptSorter);
|
|
54
|
+
const attempts = (await Promise.all(binders.map((binder) => attempt(binder, node, ctx)))).sort(attemptSorter);
|
|
56
55
|
attempts[0].updateNodeAndCtx();
|
|
57
56
|
});
|
|
58
57
|
}
|
|
@@ -66,7 +65,7 @@ export const noop = SyncBinder.create(() => { });
|
|
|
66
65
|
*/
|
|
67
66
|
export const fallback = AsyncBinder.create(async (node, ctx) => {
|
|
68
67
|
const promises = [];
|
|
69
|
-
traversePreOrder(node, node => !ctx.meta.hasBinder(node.type), node => ctx.meta.hasBinder(node.type), node => {
|
|
68
|
+
traversePreOrder(node, (node) => !ctx.meta.hasBinder(node.type), (node) => ctx.meta.hasBinder(node.type), (node) => {
|
|
70
69
|
const binder = ctx.meta.getBinder(node.type);
|
|
71
70
|
const result = binder(node, ctx);
|
|
72
71
|
if (result instanceof Promise) {
|
|
@@ -84,18 +83,25 @@ export const dispatchSync = SyncBinder.create((node, ctx) => {
|
|
|
84
83
|
}
|
|
85
84
|
});
|
|
86
85
|
export const resourceLocation = SyncBinder.create((node, ctx) => {
|
|
86
|
+
const raw = ResourceLocationNode.toString(node, 'full');
|
|
87
|
+
const sanitizedRaw = ResourceLocation.lengthen(node.options.namespacePathSep === '.'
|
|
88
|
+
? raw.replace(/\./g, ResourceLocation.NamespacePathSep)
|
|
89
|
+
: raw);
|
|
87
90
|
if (node.options.category) {
|
|
88
|
-
const raw = ResourceLocationNode.toString(node, 'full');
|
|
89
|
-
const sanitizedRaw = ResourceLocation.lengthen(node.options.namespacePathSep === '.'
|
|
90
|
-
? raw.replace('.', ResourceLocation.NamespacePathSep)
|
|
91
|
-
: raw);
|
|
92
91
|
ctx.symbols
|
|
93
|
-
.query(ctx.doc, node.isTag
|
|
94
|
-
|
|
92
|
+
.query(ctx.doc, node.isTag
|
|
93
|
+
? `tag/${node.options.category}`
|
|
94
|
+
: node.options.category, sanitizedRaw)
|
|
95
|
+
.enter({
|
|
96
|
+
usage: {
|
|
97
|
+
type: node.options.usageType,
|
|
98
|
+
node,
|
|
99
|
+
accessType: node.options.accessType,
|
|
100
|
+
},
|
|
101
|
+
});
|
|
95
102
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if (!node.options.pool.includes(full)) {
|
|
103
|
+
if (node.options.pool && !node.options.allowUnknown) {
|
|
104
|
+
if (!node.options.pool.includes(sanitizedRaw)) {
|
|
99
105
|
ctx.err.report(localize('expected', node.options.pool), node, 3 /* ErrorSeverity.Error */);
|
|
100
106
|
}
|
|
101
107
|
return;
|
|
@@ -103,10 +109,16 @@ export const resourceLocation = SyncBinder.create((node, ctx) => {
|
|
|
103
109
|
});
|
|
104
110
|
export const symbol = SyncBinder.create((node, ctx) => {
|
|
105
111
|
if (node.value) {
|
|
106
|
-
const path = node.options.parentPath
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
112
|
+
const path = node.options.parentPath
|
|
113
|
+
? [...node.options.parentPath, node.value]
|
|
114
|
+
: [node.value];
|
|
115
|
+
ctx.symbols.query(ctx.doc, node.options.category, ...path).enter({
|
|
116
|
+
usage: {
|
|
117
|
+
type: node.options.usageType,
|
|
118
|
+
node: node,
|
|
119
|
+
accessType: node.options.accessType,
|
|
120
|
+
},
|
|
121
|
+
});
|
|
110
122
|
}
|
|
111
123
|
});
|
|
112
124
|
export function registerBinders(meta) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AstNode } from '../../node/index.js';
|
|
2
2
|
import type { CheckerContext } from '../../service/index.js';
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
3
|
+
export type Checker<N extends AstNode> = (node: N, ctx: CheckerContext) => PromiseLike<void> | void;
|
|
4
|
+
export type SyncChecker<N extends AstNode> = (node: N, ctx: CheckerContext) => void;
|
|
5
|
+
export type AsyncChecker<N extends AstNode> = (node: N, ctx: CheckerContext) => PromiseLike<void>;
|
|
6
6
|
export declare const FallbackChecker: Checker<any>;
|
|
7
7
|
//# sourceMappingURL=Checker.d.ts.map
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import type { AstNode, SymbolBaseNode } from '../../node/index.js';
|
|
2
|
-
import { ResourceLocationNode } from '../../node/index.js';
|
|
1
|
+
import type { AstNode, ResourceLocationNode, SymbolBaseNode } from '../../node/index.js';
|
|
3
2
|
import type { CheckerContext, MetaRegistry } from '../../service/index.js';
|
|
4
3
|
import type { Checker, SyncChecker } from './Checker.js';
|
|
5
|
-
export
|
|
4
|
+
export type AttemptResult = {
|
|
6
5
|
errorAmount: number;
|
|
7
6
|
totalErrorSpan: number;
|
|
8
7
|
updateNodeAndCtx: () => void;
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { localize } from '@spyglassmc/locales';
|
|
2
1
|
import { StateProxy } from '../../common/index.js';
|
|
3
|
-
import { ResourceLocationNode } from '../../node/index.js';
|
|
4
2
|
import { ErrorReporter } from '../../service/index.js';
|
|
5
3
|
import { traversePreOrder } from '../util.js';
|
|
6
4
|
export function attempt(checker, node, ctx) {
|
|
@@ -13,7 +11,7 @@ export function attempt(checker, node, ctx) {
|
|
|
13
11
|
checker(node, tempCtx);
|
|
14
12
|
StateProxy.undoChanges(node);
|
|
15
13
|
const totalErrorSpan = tempCtx.err.errors
|
|
16
|
-
.map(e => e.range.end - e.range.start)
|
|
14
|
+
.map((e) => e.range.end - e.range.start)
|
|
17
15
|
.reduce((a, b) => a + b, 0);
|
|
18
16
|
return {
|
|
19
17
|
errorAmount: tempCtx.err.errors.length,
|
|
@@ -31,8 +29,9 @@ export function any(checkers) {
|
|
|
31
29
|
}
|
|
32
30
|
return (node, ctx) => {
|
|
33
31
|
const attempts = checkers
|
|
34
|
-
.map(checker => attempt(checker, node, ctx))
|
|
35
|
-
.sort((a, b) => a.errorAmount - b.errorAmount ||
|
|
32
|
+
.map((checker) => attempt(checker, node, ctx))
|
|
33
|
+
.sort((a, b) => a.errorAmount - b.errorAmount ||
|
|
34
|
+
a.totalErrorSpan - b.totalErrorSpan);
|
|
36
35
|
attempts[0].updateNodeAndCtx();
|
|
37
36
|
};
|
|
38
37
|
}
|
|
@@ -45,7 +44,7 @@ export const noop = () => { };
|
|
|
45
44
|
*/
|
|
46
45
|
export const fallback = async (node, ctx) => {
|
|
47
46
|
const promises = [];
|
|
48
|
-
traversePreOrder(node, node => !ctx.meta.hasChecker(node.type), node => ctx.meta.hasChecker(node.type), node => {
|
|
47
|
+
traversePreOrder(node, (node) => !ctx.meta.hasChecker(node.type), (node) => ctx.meta.hasChecker(node.type), (node) => {
|
|
49
48
|
const checker = ctx.meta.getChecker(node.type);
|
|
50
49
|
const result = checker(node, ctx);
|
|
51
50
|
if (result instanceof Promise) {
|
|
@@ -63,13 +62,13 @@ export const dispatchSync = (node, ctx) => {
|
|
|
63
62
|
}
|
|
64
63
|
};
|
|
65
64
|
export const resourceLocation = (node, ctx) => {
|
|
66
|
-
const full = ResourceLocationNode.toString(node, 'full')
|
|
67
|
-
if (node.options.pool) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
65
|
+
// const full = ResourceLocationNode.toString(node, 'full')
|
|
66
|
+
// if (node.options.pool) {
|
|
67
|
+
// if (!node.options.pool.includes(full)) {
|
|
68
|
+
// ctx.err.report(localize('expected', node.options.pool), node, ErrorSeverity.Error)
|
|
69
|
+
// }
|
|
70
|
+
// return
|
|
71
|
+
// }
|
|
73
72
|
};
|
|
74
73
|
export const symbol = (_node, _ctx) => {
|
|
75
74
|
// TODO
|
|
@@ -3,7 +3,7 @@ import type { AstNode } from '../../node/index.js';
|
|
|
3
3
|
import type { ColorizerContext } from '../../service/index.js';
|
|
4
4
|
import type { RangeLike } from '../../source/index.js';
|
|
5
5
|
import { Range } from '../../source/index.js';
|
|
6
|
-
export
|
|
6
|
+
export type Colorizer<N extends AstNode = AstNode> = (node: DeepReadonly<N>, ctx: ColorizerContext) => readonly ColorToken[];
|
|
7
7
|
export interface ColorToken {
|
|
8
8
|
range: Range;
|
|
9
9
|
type: ColorTokenType;
|
|
@@ -18,7 +18,7 @@ export declare namespace ColorToken {
|
|
|
18
18
|
function fillGap(tokens: readonly ColorToken[], targetRange: Range, type: ColorTokenType, modifiers?: ColorTokenModifier[]): ColorToken[];
|
|
19
19
|
}
|
|
20
20
|
export declare const ColorTokenTypes: readonly ["comment", "enum", "enumMember", "function", "keyword", "modifier", "number", "operator", "property", "string", "struct", "type", "type", "variable", "error", "literal", "operator", "resourceLocation", "vector"];
|
|
21
|
-
export
|
|
21
|
+
export type ColorTokenType = typeof ColorTokenTypes[number];
|
|
22
22
|
export declare const ColorTokenModifiers: readonly ["declaration", "defaultLibrary", "definition", "deprecated", "documentation", "modification", "readonly"];
|
|
23
|
-
export
|
|
23
|
+
export type ColorTokenModifier = typeof ColorTokenModifiers[number];
|
|
24
24
|
//# sourceMappingURL=Colorizer.d.ts.map
|
|
@@ -6,27 +6,28 @@ import { ColorToken } from './Colorizer.js';
|
|
|
6
6
|
*/
|
|
7
7
|
export const fallback = (node, ctx) => {
|
|
8
8
|
const ans = [];
|
|
9
|
-
traversePreOrder(node, node => !ctx.meta.hasColorizer(node.type) &&
|
|
9
|
+
traversePreOrder(node, (node) => !ctx.meta.hasColorizer(node.type) &&
|
|
10
|
+
(!ctx.range || Range.intersects(node.range, ctx.range)), (node) => ctx.meta.hasColorizer(node.type), (node) => {
|
|
10
11
|
const colorizer = ctx.meta.getColorizer(node.type);
|
|
11
12
|
const result = colorizer(node, ctx);
|
|
12
13
|
ans.push(...result);
|
|
13
14
|
});
|
|
14
15
|
return Object.freeze(ans);
|
|
15
16
|
};
|
|
16
|
-
export const boolean = node => {
|
|
17
|
+
export const boolean = (node) => {
|
|
17
18
|
return [ColorToken.create(node, 'literal')];
|
|
18
19
|
};
|
|
19
|
-
export const comment = node => {
|
|
20
|
+
export const comment = (node) => {
|
|
20
21
|
return [ColorToken.create(node, 'comment')];
|
|
21
22
|
};
|
|
22
|
-
export const error = node => {
|
|
23
|
+
export const error = (node) => {
|
|
23
24
|
// return [ColorToken.create(node, 'error')]
|
|
24
25
|
return [];
|
|
25
26
|
};
|
|
26
|
-
export const literal = node => {
|
|
27
|
+
export const literal = (node) => {
|
|
27
28
|
return [ColorToken.create(node, node.options.colorTokenType ?? 'literal')];
|
|
28
29
|
};
|
|
29
|
-
export const number = node => {
|
|
30
|
+
export const number = (node) => {
|
|
30
31
|
return [ColorToken.create(node, 'number')];
|
|
31
32
|
};
|
|
32
33
|
export const resourceLocation = (node, _ctx) => {
|
|
@@ -53,7 +54,7 @@ export const string = (node, ctx) => {
|
|
|
53
54
|
return [ColorToken.create(node, node.options.colorTokenType ?? 'string')];
|
|
54
55
|
}
|
|
55
56
|
};
|
|
56
|
-
export const symbol = node => {
|
|
57
|
+
export const symbol = (node) => {
|
|
57
58
|
// TODO: Set the modifiers according to `node.symbol`.
|
|
58
59
|
return [ColorToken.create(node, 'variable')];
|
|
59
60
|
};
|
|
@@ -3,7 +3,7 @@ import type { AstNode } from '../../node/index.js';
|
|
|
3
3
|
import type { CompleterContext } from '../../service/index.js';
|
|
4
4
|
import type { RangeLike } from '../../source/index.js';
|
|
5
5
|
import { Range } from '../../source/index.js';
|
|
6
|
-
export
|
|
6
|
+
export type Completer<N extends AstNode = AstNode> = (node: DeepReadonly<N>, ctx: CompleterContext) => CompletionItem[];
|
|
7
7
|
export declare const enum CompletionKind {
|
|
8
8
|
Text = 1,
|
|
9
9
|
Method = 2,
|
|
@@ -17,7 +17,7 @@ export var CompletionItem;
|
|
|
17
17
|
...other,
|
|
18
18
|
label,
|
|
19
19
|
range: Range.get(range),
|
|
20
|
-
...shouldEscape ? { insertText: escape(label) } : {},
|
|
20
|
+
...(shouldEscape ? { insertText: escape(label) } : {}),
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
23
|
CompletionItem.create = create;
|
|
@@ -51,7 +51,9 @@ export class InsertTextBuilder {
|
|
|
51
51
|
this.#ans += `$\{${this.#nextPlaceholder}:${CompletionItem.escape(defaultValues[0])}}`;
|
|
52
52
|
}
|
|
53
53
|
else {
|
|
54
|
-
this.#ans += `$\{${this.#nextPlaceholder}|${defaultValues
|
|
54
|
+
this.#ans += `$\{${this.#nextPlaceholder}|${defaultValues
|
|
55
|
+
.map((v) => v.replace(/([\\$},|])/g, '\\$1'))
|
|
56
|
+
.join(',')}|}`;
|
|
55
57
|
}
|
|
56
58
|
this.#nextPlaceholder += 1;
|
|
57
59
|
return this;
|
|
@@ -12,11 +12,9 @@ export const dispatch = (node, ctx) => {
|
|
|
12
12
|
node: node,
|
|
13
13
|
needle: ctx.offset,
|
|
14
14
|
endInclusive: true,
|
|
15
|
-
predicate: n => ctx.meta.hasCompleter(n.type),
|
|
15
|
+
predicate: (n) => ctx.meta.hasCompleter(n.type),
|
|
16
16
|
});
|
|
17
|
-
return child
|
|
18
|
-
? ctx.meta.getCompleter(child.type)(child, ctx)
|
|
19
|
-
: [];
|
|
17
|
+
return child ? ctx.meta.getCompleter(child.type)(child, ctx) : [];
|
|
20
18
|
};
|
|
21
19
|
export const fallback = dispatch;
|
|
22
20
|
export const boolean = (node, ctx) => {
|
|
@@ -32,7 +30,7 @@ export const file = (node, ctx) => {
|
|
|
32
30
|
const completer = ctx.meta.getCompleterForLanguageID(ctx.doc.languageId);
|
|
33
31
|
return completer(node.children[0], ctx);
|
|
34
32
|
};
|
|
35
|
-
export const literal = node => {
|
|
33
|
+
export const literal = (node) => {
|
|
36
34
|
const kind = new Map([
|
|
37
35
|
['enum', 13 /* CompletionKind.Enum */],
|
|
38
36
|
['enumMember', 20 /* CompletionKind.EnumMember */],
|
|
@@ -45,7 +43,8 @@ export const literal = node => {
|
|
|
45
43
|
['resourceLocation', 17 /* CompletionKind.File */],
|
|
46
44
|
['variable', 6 /* CompletionKind.Variable */],
|
|
47
45
|
]).get(node.options.colorTokenType ?? 'keyword') ?? 14 /* CompletionKind.Keyword */;
|
|
48
|
-
return node.options.pool.map(v => CompletionItem.create(v, node, { kind })) ??
|
|
46
|
+
return (node.options.pool.map((v) => CompletionItem.create(v, node, { kind })) ??
|
|
47
|
+
[]);
|
|
49
48
|
};
|
|
50
49
|
export const noop = () => [];
|
|
51
50
|
export function record(o) {
|
|
@@ -57,12 +56,12 @@ export function record(o) {
|
|
|
57
56
|
const completePairs = (pair) => o.key(node, pair, ctx, pair ?? ctx.offset, true, hasNextPair || !!pair?.end, existingKeys);
|
|
58
57
|
const existingKeys = node.children
|
|
59
58
|
.filter((n) => !!n.key)
|
|
60
|
-
.map(n => n.key);
|
|
59
|
+
.map((n) => n.key);
|
|
61
60
|
const index = binarySearch(node.children, ctx.offset, (n, o) => n.end
|
|
62
61
|
? Range.compareOffset(Range.translate(n, 0, -1), o, true)
|
|
63
62
|
: Range.compareOffset(n.range, o, true));
|
|
64
63
|
const pair = index >= 0 ? node.children[index] : undefined;
|
|
65
|
-
const hasNextPair = !!node.children.find(n => n.range.start > ctx.offset);
|
|
64
|
+
const hasNextPair = !!node.children.find((n) => n.range.start > ctx.offset);
|
|
66
65
|
if (!pair) {
|
|
67
66
|
return completePairs(undefined);
|
|
68
67
|
}
|
|
@@ -70,14 +69,18 @@ export function record(o) {
|
|
|
70
69
|
if (!key && !sep && !value) {
|
|
71
70
|
return completePairs(undefined);
|
|
72
71
|
}
|
|
73
|
-
if ((key && Range.contains(key, ctx.offset, true)) ||
|
|
72
|
+
if ((key && Range.contains(key, ctx.offset, true)) ||
|
|
73
|
+
(sep && ctx.offset <= sep.start) ||
|
|
74
|
+
(value && ctx.offset < value.range.start)) {
|
|
74
75
|
// Selected key.
|
|
75
76
|
if (!value || Range.isEmpty(value.range)) {
|
|
76
77
|
return completePairs(pair);
|
|
77
78
|
}
|
|
78
79
|
return completeKeys(pair);
|
|
79
80
|
}
|
|
80
|
-
if ((value && Range.contains(value, ctx.offset, true)) ||
|
|
81
|
+
if ((value && Range.contains(value, ctx.offset, true)) ||
|
|
82
|
+
(sep && ctx.offset >= sep.end) ||
|
|
83
|
+
(key && ctx.offset > key.range.end)) {
|
|
81
84
|
// Selected value.
|
|
82
85
|
return o.value(node, pair, ctx);
|
|
83
86
|
}
|
|
@@ -86,9 +89,12 @@ export function record(o) {
|
|
|
86
89
|
}
|
|
87
90
|
export const resourceLocation = (node, ctx) => {
|
|
88
91
|
const config = LinterConfigValue.destruct(ctx.config.lint.idOmitDefaultNamespace);
|
|
89
|
-
const includeEmptyNamespace = !node.options.isPredicate &&
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
+
const includeEmptyNamespace = !node.options.isPredicate &&
|
|
93
|
+
node.namespace === '';
|
|
94
|
+
const includeDefaultNamespace = node.options.isPredicate ||
|
|
95
|
+
config?.ruleValue !== true;
|
|
96
|
+
const excludeDefaultNamespace = !node.options.isPredicate &&
|
|
97
|
+
config?.ruleValue !== false;
|
|
92
98
|
const getPool = (category) => optimizePool(Object.keys(ctx.symbols.getVisibleSymbols(category, ctx.doc.uri)));
|
|
93
99
|
const optimizePool = (pool) => {
|
|
94
100
|
const defaultNsPrefix = `${ResourceLocation.DefaultNamespace}${ResourceLocation.NamespacePathSep}`;
|
|
@@ -104,12 +110,16 @@ export const resourceLocation = (node, ctx) => {
|
|
|
104
110
|
}
|
|
105
111
|
const ans = [
|
|
106
112
|
...otherIds,
|
|
107
|
-
...includeDefaultNamespace ? defaultNsIds : [],
|
|
108
|
-
...excludeDefaultNamespace
|
|
109
|
-
|
|
113
|
+
...(includeDefaultNamespace ? defaultNsIds : []),
|
|
114
|
+
...(excludeDefaultNamespace
|
|
115
|
+
? defaultNsIds.map((id) => id.slice(defaultNsPrefix.length))
|
|
116
|
+
: []),
|
|
117
|
+
...(includeEmptyNamespace
|
|
118
|
+
? defaultNsIds.map((id) => id.slice(ResourceLocation.DefaultNamespace.length))
|
|
119
|
+
: []),
|
|
110
120
|
];
|
|
111
121
|
if (node.options.namespacePathSep === '.') {
|
|
112
|
-
return ans.map(v => v.replace(ResourceLocation.NamespacePathSep, '.'));
|
|
122
|
+
return ans.map((v) => v.replace(ResourceLocation.NamespacePathSep, '.'));
|
|
113
123
|
}
|
|
114
124
|
return ans;
|
|
115
125
|
};
|
|
@@ -117,12 +127,11 @@ export const resourceLocation = (node, ctx) => {
|
|
|
117
127
|
? optimizePool(node.options.pool)
|
|
118
128
|
: [
|
|
119
129
|
...getPool(node.options.category),
|
|
120
|
-
...node.options.allowTag
|
|
121
|
-
? getPool(`tag/${node.options.category}`)
|
|
122
|
-
|
|
123
|
-
: [],
|
|
130
|
+
...(node.options.allowTag
|
|
131
|
+
? getPool(`tag/${node.options.category}`).map((v) => `${ResourceLocation.TagPrefix}${v}`)
|
|
132
|
+
: []),
|
|
124
133
|
];
|
|
125
|
-
return pool.map(v => CompletionItem.create(v, node, { kind: 3 /* CompletionKind.Function */ }));
|
|
134
|
+
return pool.map((v) => CompletionItem.create(v, node, { kind: 3 /* CompletionKind.Function */ }));
|
|
126
135
|
};
|
|
127
136
|
export const string = (node, ctx) => {
|
|
128
137
|
if (node.children?.length) {
|
|
@@ -130,7 +139,7 @@ export const string = (node, ctx) => {
|
|
|
130
139
|
return dispatch(node.children[0], ctx);
|
|
131
140
|
}
|
|
132
141
|
if (node.options.quotes && node.value === '') {
|
|
133
|
-
return node.options.quotes.map(q => CompletionItem.create(`${q}${q}`, node, {
|
|
142
|
+
return node.options.quotes.map((q) => CompletionItem.create(`${q}${q}`, node, {
|
|
134
143
|
insertText: `${q}$1${q}`,
|
|
135
144
|
kind: 12 /* CompletionKind.Value */,
|
|
136
145
|
}));
|
|
@@ -138,9 +147,7 @@ export const string = (node, ctx) => {
|
|
|
138
147
|
return [];
|
|
139
148
|
};
|
|
140
149
|
export const symbol = (node, ctx) => {
|
|
141
|
-
return Object
|
|
142
|
-
.keys(ctx.symbols.query(ctx.doc, node.options.category, ...node.options.parentPath ?? []).visibleMembers)
|
|
143
|
-
.map(v => CompletionItem.create(v, node, { kind: 6 /* CompletionKind.Variable */ }));
|
|
150
|
+
return Object.keys(ctx.symbols.query(ctx.doc, node.options.category, ...(node.options.parentPath ?? [])).visibleMembers).map((v) => CompletionItem.create(v, node, { kind: 6 /* CompletionKind.Variable */ }));
|
|
144
151
|
};
|
|
145
152
|
export function registerCompleters(meta) {
|
|
146
153
|
meta.registerCompleter('boolean', boolean);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { DeepReadonly } from '../../common/index.js';
|
|
2
2
|
import type { AstNode } from '../../node/index.js';
|
|
3
3
|
import type { FormatterContext } from '../../service/index.js';
|
|
4
|
-
export
|
|
4
|
+
export type Formatter<N extends AstNode = AstNode> = (node: DeepReadonly<N>, ctx: FormatterContext) => string;
|
|
5
5
|
export declare function formatterContextIndentation(ctx: FormatterContext, additionalLevels?: number): string;
|
|
6
6
|
export declare function indentFormatter(ctx: FormatterContext, additionalLevels?: number): FormatterContext;
|
|
7
7
|
//# sourceMappingURL=Formatter.d.ts.map
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export function formatterContextIndentation(ctx, additionalLevels = 0) {
|
|
2
2
|
const total = ctx.indentLevel + additionalLevels;
|
|
3
|
-
return ctx.insertSpaces
|
|
3
|
+
return ctx.insertSpaces
|
|
4
|
+
? ' '.repeat(total * ctx.tabSize)
|
|
5
|
+
: '\t'.repeat(total);
|
|
4
6
|
}
|
|
5
7
|
export function indentFormatter(ctx, additionalLevels = 1) {
|
|
6
8
|
return {
|
|
@@ -1,34 +1,36 @@
|
|
|
1
1
|
import { ResourceLocationNode } from '../../node/index.js';
|
|
2
|
-
export const fallback = node => {
|
|
2
|
+
export const fallback = (node) => {
|
|
3
3
|
throw new Error(`No formatter registered for type ${node.type}`);
|
|
4
4
|
};
|
|
5
5
|
export const file = (node, ctx) => {
|
|
6
|
-
return node.children
|
|
6
|
+
return node.children
|
|
7
|
+
.map((child) => {
|
|
7
8
|
return ctx.meta.getFormatter(child.type)(child, ctx);
|
|
8
|
-
})
|
|
9
|
+
})
|
|
10
|
+
.join('');
|
|
9
11
|
};
|
|
10
|
-
export const boolean = node => {
|
|
12
|
+
export const boolean = (node) => {
|
|
11
13
|
return node.value ? 'true' : 'false';
|
|
12
14
|
};
|
|
13
|
-
export const comment = node => {
|
|
15
|
+
export const comment = (node) => {
|
|
14
16
|
return '#' + node.comment;
|
|
15
17
|
};
|
|
16
|
-
export const float = node => {
|
|
18
|
+
export const float = (node) => {
|
|
17
19
|
return node.value.toString();
|
|
18
20
|
};
|
|
19
|
-
export const integer = node => {
|
|
21
|
+
export const integer = (node) => {
|
|
20
22
|
return node.value.toFixed();
|
|
21
23
|
};
|
|
22
|
-
export const literal = node => {
|
|
24
|
+
export const literal = (node) => {
|
|
23
25
|
return node.value;
|
|
24
26
|
};
|
|
25
|
-
export const long = node => {
|
|
27
|
+
export const long = (node) => {
|
|
26
28
|
return node.value.toString();
|
|
27
29
|
};
|
|
28
|
-
export const resourceLocation = node => {
|
|
29
|
-
return ResourceLocationNode.toString(node, 'origin');
|
|
30
|
+
export const resourceLocation = (node) => {
|
|
31
|
+
return ResourceLocationNode.toString(node, 'origin', true);
|
|
30
32
|
};
|
|
31
|
-
export const string = node => {
|
|
33
|
+
export const string = (node) => {
|
|
32
34
|
// FIXME: escape this value according to the node's IndexMap and context
|
|
33
35
|
return `"${node.value}"`;
|
|
34
36
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StateProxy } from '../../index.js';
|
|
2
2
|
import type { AstNode } from '../../node/index.js';
|
|
3
3
|
import type { LinterContext } from '../../service/index.js';
|
|
4
|
-
export
|
|
4
|
+
export type Linter<N extends AstNode> = (node: StateProxy<N>, ctx: LinterContext) => void;
|
|
5
5
|
//# sourceMappingURL=Linter.d.ts.map
|
|
@@ -1,24 +1,37 @@
|
|
|
1
|
-
import { localeQuote, localize } from '@spyglassmc/locales';
|
|
2
1
|
import { Arrayable, ResourceLocation } from '../../../common/index.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { SymbolLinterConfig as Config } from '../../../service/index.js';
|
|
3
|
+
// import { localeQuote, localize } from '@spyglassmc/locales'
|
|
4
|
+
// import type { DeepReadonly } from '../../../common/index.js'
|
|
5
|
+
// import { Arrayable, ResourceLocation } from '../../../common/index.js'
|
|
6
|
+
// import type { AstNode } from '../../../node/index.js'
|
|
7
|
+
// import type { LinterContext } from '../../../service/index.js'
|
|
8
|
+
// import { LinterSeverity, SymbolLinterConfig as Config } from '../../../service/index.js'
|
|
9
|
+
// import type { Symbol } from '../../../symbol/index.js'
|
|
10
|
+
// import { SymbolUtil, SymbolVisibility } from '../../../symbol/index.js'
|
|
11
|
+
// import type { Linter } from '../Linter.js'
|
|
5
12
|
export const undeclaredSymbol = (node, ctx) => {
|
|
6
|
-
if (!node.symbol || SymbolUtil.isDeclared(node.symbol)) {
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
const action = getAction(ctx.ruleValue, node.symbol, ctx)
|
|
10
|
-
if (Config.Action.isDeclare(action)) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
if (Config.Action.isReport(action)) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
13
|
+
// if (!node.symbol || SymbolUtil.isDeclared(node.symbol)) {
|
|
14
|
+
// return
|
|
15
|
+
// }
|
|
16
|
+
// const action = getAction(ctx.ruleValue as Config, node.symbol, ctx)
|
|
17
|
+
// if (Config.Action.isDeclare(action)) {
|
|
18
|
+
// ctx.symbols
|
|
19
|
+
// .query({ doc: ctx.doc, node }, node.symbol.category, ...node.symbol.path)
|
|
20
|
+
// .amend({
|
|
21
|
+
// data: { visibility: getVisibility(action.declare) },
|
|
22
|
+
// usage: { type: 'declaration', node },
|
|
23
|
+
// })
|
|
24
|
+
// }
|
|
25
|
+
// if (Config.Action.isReport(action)) {
|
|
26
|
+
// const severityOverride = action.report === 'inherit' ? undefined : LinterSeverity.toErrorSeverity(action.report)
|
|
27
|
+
// ctx.err.lint(
|
|
28
|
+
// localize('linter.undeclared-symbol.message',
|
|
29
|
+
// node.symbol.category,
|
|
30
|
+
// localeQuote(node.symbol.identifier)
|
|
31
|
+
// ),
|
|
32
|
+
// node, undefined, severityOverride
|
|
33
|
+
// )
|
|
34
|
+
// }
|
|
22
35
|
};
|
|
23
36
|
function getAction(config, symbol, ctx) {
|
|
24
37
|
if (Config.Action.is(config)) {
|
|
@@ -28,11 +41,21 @@ function getAction(config, symbol, ctx) {
|
|
|
28
41
|
function testSingleCondition(condition) {
|
|
29
42
|
const resourceLocation = ResourceLocation.lengthen(symbol.identifier);
|
|
30
43
|
const namespace = resourceLocation.slice(0, resourceLocation.indexOf(ResourceLocation.NamespacePathSep));
|
|
31
|
-
return ((condition.category
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
(condition.
|
|
35
|
-
|
|
44
|
+
return ((condition.category
|
|
45
|
+
? Arrayable.toArray(condition.category).includes(symbol.category)
|
|
46
|
+
: true) &&
|
|
47
|
+
(condition.namespace
|
|
48
|
+
? Arrayable.toArray(condition.namespace).includes(namespace)
|
|
49
|
+
: true) &&
|
|
50
|
+
(condition.excludeNamespace
|
|
51
|
+
? !Arrayable.toArray(condition.excludeNamespace).includes(namespace)
|
|
52
|
+
: true) &&
|
|
53
|
+
(condition.pattern
|
|
54
|
+
? Arrayable.toArray(condition.pattern).some((p) => new RegExp(p).test(symbol.identifier))
|
|
55
|
+
: true) &&
|
|
56
|
+
(condition.excludePattern
|
|
57
|
+
? !Arrayable.toArray(condition.excludePattern).some((p) => new RegExp(p).test(symbol.identifier))
|
|
58
|
+
: true));
|
|
36
59
|
}
|
|
37
60
|
try {
|
|
38
61
|
return Arrayable.toArray(conditions).some(testSingleCondition);
|
|
@@ -28,7 +28,7 @@ export function nameConvention(key) {
|
|
|
28
28
|
export const quote = (node, ctx) => {
|
|
29
29
|
const config = ctx.ruleValue;
|
|
30
30
|
const mustValueBeQuoted = node.options.unquotable
|
|
31
|
-
? [...node.value].some(c => !isAllowedCharacter(c, node.options.unquotable))
|
|
31
|
+
? [...node.value].some((c) => !isAllowedCharacter(c, node.options.unquotable))
|
|
32
32
|
: true;
|
|
33
33
|
const isQuoteRequired = config.always || mustValueBeQuoted;
|
|
34
34
|
const isQuoteProhibited = config.always === false && !mustValueBeQuoted;
|
|
@@ -66,8 +66,7 @@ export var configValidator;
|
|
|
66
66
|
new RegExp(val);
|
|
67
67
|
}
|
|
68
68
|
catch (e) {
|
|
69
|
-
logger.error(wrapError(name, localize('')
|
|
70
|
-
), e);
|
|
69
|
+
logger.error(wrapError(name, localize('')), e);
|
|
71
70
|
return false;
|
|
72
71
|
}
|
|
73
72
|
return true;
|
|
@@ -82,27 +81,27 @@ export function registerLinters(meta) {
|
|
|
82
81
|
meta.registerLinter('nameOfObjective', {
|
|
83
82
|
configValidator: configValidator.nameConvention,
|
|
84
83
|
linter: nameConvention('value'),
|
|
85
|
-
nodePredicate: n => n.symbol && n.symbol.category === 'objective',
|
|
84
|
+
nodePredicate: (n) => n.symbol && n.symbol.category === 'objective',
|
|
86
85
|
});
|
|
87
86
|
meta.registerLinter('nameOfScoreHolder', {
|
|
88
87
|
configValidator: configValidator.nameConvention,
|
|
89
88
|
linter: nameConvention('value'),
|
|
90
|
-
nodePredicate: n => n.symbol && n.symbol.category === 'score_holder',
|
|
89
|
+
nodePredicate: (n) => n.symbol && n.symbol.category === 'score_holder',
|
|
91
90
|
});
|
|
92
91
|
meta.registerLinter('nameOfTag', {
|
|
93
92
|
configValidator: configValidator.nameConvention,
|
|
94
93
|
linter: nameConvention('value'),
|
|
95
|
-
nodePredicate: n => n.symbol && n.symbol.category === 'tag',
|
|
94
|
+
nodePredicate: (n) => n.symbol && n.symbol.category === 'tag',
|
|
96
95
|
});
|
|
97
96
|
meta.registerLinter('nameOfTeam', {
|
|
98
97
|
configValidator: configValidator.nameConvention,
|
|
99
98
|
linter: nameConvention('value'),
|
|
100
|
-
nodePredicate: n => n.symbol && n.symbol.category === 'team',
|
|
99
|
+
nodePredicate: (n) => n.symbol && n.symbol.category === 'team',
|
|
101
100
|
});
|
|
102
101
|
meta.registerLinter('undeclaredSymbol', {
|
|
103
102
|
configValidator: configValidator.symbolLinterConfig,
|
|
104
103
|
linter: undeclaredSymbol,
|
|
105
|
-
nodePredicate: n => n.symbol && !McdocCategories.includes(n.symbol.category),
|
|
104
|
+
nodePredicate: (n) => n.symbol && !McdocCategories.includes(n.symbol.category),
|
|
106
105
|
});
|
|
107
106
|
}
|
|
108
107
|
//# sourceMappingURL=builtin.js.map
|