@spyglassmc/java-edition 0.3.18 → 0.3.20
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/binder/index.d.ts +2 -1
- package/lib/binder/index.js +63 -26
- package/lib/dependency/common.d.ts +10 -0
- package/lib/dependency/common.js +7 -0
- package/lib/dependency/index.d.ts +8 -0
- package/lib/dependency/index.js +23 -2
- package/lib/dependency/mcmeta.d.ts +4 -2
- package/lib/dependency/mcmeta.js +89 -19
- package/lib/index.d.ts +1 -0
- package/lib/index.js +51 -80
- package/lib/mcdocAttributes.d.ts +6 -0
- package/lib/mcdocAttributes.js +89 -0
- package/lib/mcfunction/checker/index.js +12 -15
- package/lib/mcfunction/completer/argument.js +27 -14
- package/lib/mcfunction/mcdocAttributes.js +1 -1
- package/lib/mcfunction/node/argument.d.ts +23 -4
- package/lib/mcfunction/node/argument.js +16 -0
- package/lib/mcfunction/parser/argument.js +92 -22
- package/lib/mcfunction/tree/argument.d.ts +8 -0
- package/lib/mcfunction/tree/patch.js +39 -4
- package/package.json +7 -7
package/lib/index.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import * as core from '@spyglassmc/core';
|
|
2
2
|
import * as json from '@spyglassmc/json';
|
|
3
|
-
import { localize } from '@spyglassmc/locales';
|
|
4
3
|
import * as mcdoc from '@spyglassmc/mcdoc';
|
|
5
4
|
import * as nbt from '@spyglassmc/nbt';
|
|
6
5
|
import { uriBinder } from './binder/index.js';
|
|
7
|
-
import { getMcmetaSummary, getVanillaDatapack, getVanillaMcdoc, getVersions, PackMcmeta,
|
|
6
|
+
import { getMcmetaSummary, getVanillaDatapack, getVanillaMcdoc, getVanillaResourcepack, getVersions, PackMcmeta, resolveConfiguredVersion, symbolRegistrar, } from './dependency/index.js';
|
|
8
7
|
import * as jeJson from './json/index.js';
|
|
8
|
+
import { registerMcdocAttributes, registerPackFormatAttribute } from './mcdocAttributes.js';
|
|
9
9
|
import * as jeMcf from './mcfunction/index.js';
|
|
10
10
|
export * as binder from './binder/index.js';
|
|
11
11
|
export * as dependency from './dependency/index.js';
|
|
12
12
|
export * as json from './json/index.js';
|
|
13
|
+
export * from './mcdocAttributes.js';
|
|
13
14
|
export * as mcf from './mcfunction/index.js';
|
|
14
15
|
export const initialize = async (ctx) => {
|
|
15
16
|
const { config, downloader, externals, logger, meta, projectRoots } = ctx;
|
|
@@ -27,26 +28,28 @@ export const initialize = async (ctx) => {
|
|
|
27
28
|
}
|
|
28
29
|
return undefined;
|
|
29
30
|
}
|
|
30
|
-
async function
|
|
31
|
-
const
|
|
31
|
+
async function findPackMcmetas(versions) {
|
|
32
|
+
const searchedUris = new Set();
|
|
33
|
+
const packs = [];
|
|
32
34
|
for (let depth = 0; depth <= 2; depth += 1) {
|
|
33
35
|
for (const projectRoot of projectRoots) {
|
|
34
36
|
const files = await core.fileUtil.getAllFiles(externals, projectRoot, depth + 1);
|
|
35
37
|
for (const uri of files.filter(uri => uri.endsWith('/pack.mcmeta'))) {
|
|
36
|
-
if (
|
|
38
|
+
if (searchedUris.has(uri)) {
|
|
37
39
|
continue;
|
|
38
40
|
}
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
searchedUris.add(uri);
|
|
42
|
+
const packRoot = core.fileUtil.dirname(uri);
|
|
43
|
+
const [packMcmeta, type] = await Promise.all([
|
|
44
|
+
readPackMcmeta(uri),
|
|
45
|
+
PackMcmeta.getType(packRoot, externals),
|
|
46
|
+
]);
|
|
47
|
+
const versionInfo = resolveConfiguredVersion(config.env.gameVersion, versions, packMcmeta, type, logger);
|
|
48
|
+
packs.push({ type, packRoot, packMcmeta, versionInfo });
|
|
45
49
|
}
|
|
46
50
|
}
|
|
47
51
|
}
|
|
48
|
-
|
|
49
|
-
return undefined;
|
|
52
|
+
return packs;
|
|
50
53
|
}
|
|
51
54
|
meta.registerUriBinder(uriBinder);
|
|
52
55
|
const versions = await getVersions(ctx.externals, ctx.downloader);
|
|
@@ -54,9 +57,32 @@ export const initialize = async (ctx) => {
|
|
|
54
57
|
ctx.logger.error('[je-initialize] Failed loading game version list. Expect everything to be broken.');
|
|
55
58
|
return;
|
|
56
59
|
}
|
|
57
|
-
const
|
|
60
|
+
const packs = await findPackMcmetas(versions);
|
|
61
|
+
function selectVersionInfo(packs, versions) {
|
|
62
|
+
// Select the first valid pack.mcmeta, prioritizing data packs
|
|
63
|
+
const pack = packs.find(p => p.packMcmeta !== undefined && p.type === 'data')
|
|
64
|
+
?? packs.find(p => p.packMcmeta !== undefined && p.type === 'assets');
|
|
65
|
+
const version = pack === undefined
|
|
66
|
+
? resolveConfiguredVersion(config.env.gameVersion, versions, undefined, undefined, logger)
|
|
67
|
+
: pack.versionInfo;
|
|
68
|
+
const packMessage = pack === undefined
|
|
69
|
+
? 'Failed finding a valid pack.mcmeta'
|
|
70
|
+
: `Found a valid pack.mcmeta ${pack.packRoot}/pack.mcmeta`;
|
|
71
|
+
const reasonMessage = pack && version.reason === 'auto'
|
|
72
|
+
? `using ${pack.type} pack format ${pack.packMcmeta?.pack.pack_format} to select`
|
|
73
|
+
: version.reason === 'config'
|
|
74
|
+
? `but using config override "${config.env.gameVersion}" to select`
|
|
75
|
+
: version.reason === 'fallback'
|
|
76
|
+
? 'using fallback'
|
|
77
|
+
: 'impossible'; // should never occur
|
|
78
|
+
const versionMessage = `version ${version.release}${version.id === version.release ? '' : ` (${version.id})`}`;
|
|
79
|
+
ctx.logger.info(`[je.initialize] ${packMessage}, ${reasonMessage} ${versionMessage}`);
|
|
80
|
+
return version;
|
|
81
|
+
}
|
|
82
|
+
const version = selectVersionInfo(packs, versions);
|
|
58
83
|
const release = version.release;
|
|
59
84
|
meta.registerDependencyProvider('@vanilla-datapack', () => getVanillaDatapack(downloader, version.id, version.isLatest));
|
|
85
|
+
meta.registerDependencyProvider('@vanilla-resourcepack', () => getVanillaResourcepack(downloader, version.id, version.isLatest));
|
|
60
86
|
meta.registerDependencyProvider('@vanilla-mcdoc', () => getVanillaMcdoc(downloader));
|
|
61
87
|
const summary = await getMcmetaSummary(ctx.externals, downloader, logger, version.id, version.isLatest, config.env.dataSource, config.env.mcmetaSummaryOverrides);
|
|
62
88
|
if (!summary.blocks || !summary.commands || !summary.fluids || !summary.registries) {
|
|
@@ -64,8 +90,8 @@ export const initialize = async (ctx) => {
|
|
|
64
90
|
return;
|
|
65
91
|
}
|
|
66
92
|
meta.registerSymbolRegistrar('mcmeta-summary', {
|
|
67
|
-
checksum: summary.checksum
|
|
68
|
-
registrar: symbolRegistrar(summary),
|
|
93
|
+
checksum: `${summary.checksum}_v3`,
|
|
94
|
+
registrar: symbolRegistrar(summary, release),
|
|
69
95
|
});
|
|
70
96
|
meta.registerLinter('nameOfNbtKey', {
|
|
71
97
|
configValidator: core.linter.configValidator.nameConvention,
|
|
@@ -82,70 +108,15 @@ export const initialize = async (ctx) => {
|
|
|
82
108
|
&& mcdoc.StructKeyNode.is(n)
|
|
83
109
|
&& !n.symbol?.path[0]?.startsWith('::minecraft')),
|
|
84
110
|
});
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
});
|
|
94
|
-
mcdoc.runtime.registerAttribute(meta, 'until', mcdoc.runtime.attribute.validator.string, {
|
|
95
|
-
filterElement: (config, ctx) => {
|
|
96
|
-
if (!config.startsWith('1.')) {
|
|
97
|
-
ctx.logger.warn(`Invalid mcdoc attribute for "until": ${config}`);
|
|
98
|
-
return true;
|
|
99
|
-
}
|
|
100
|
-
return ReleaseVersion.cmp(release, config) < 0;
|
|
101
|
-
},
|
|
102
|
-
});
|
|
103
|
-
mcdoc.runtime.registerAttribute(meta, 'deprecated', mcdoc.runtime.attribute.validator.optional(mcdoc.runtime.attribute.validator.string), {
|
|
104
|
-
mapField: (config, field, ctx) => {
|
|
105
|
-
if (config === undefined) {
|
|
106
|
-
return { ...field, deprecated: true };
|
|
107
|
-
}
|
|
108
|
-
if (!config.startsWith('1.')) {
|
|
109
|
-
ctx.logger.warn(`Invalid mcdoc attribute for "deprecated": ${config}`);
|
|
110
|
-
return field;
|
|
111
|
-
}
|
|
112
|
-
if (ReleaseVersion.cmp(release, config) >= 0) {
|
|
113
|
-
return { ...field, deprecated: true };
|
|
114
|
-
}
|
|
115
|
-
return field;
|
|
116
|
-
},
|
|
117
|
-
});
|
|
118
|
-
const packFormats = new Map();
|
|
119
|
-
for (const version of versions) {
|
|
120
|
-
if (version.type === 'release' && !packFormats.has(version.data_pack_version)) {
|
|
121
|
-
packFormats.set(version.data_pack_version, version);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
mcdoc.runtime.registerAttribute(meta, 'pack_format', () => undefined, {
|
|
125
|
-
checker: (_, typeDef) => {
|
|
126
|
-
if (typeDef.kind !== 'literal' || typeof typeDef.value.value !== 'number') {
|
|
127
|
-
return undefined;
|
|
128
|
-
}
|
|
129
|
-
const target = typeDef.value.value;
|
|
130
|
-
return (node, ctx) => {
|
|
131
|
-
const targetVersion = packFormats.get(target);
|
|
132
|
-
if (!targetVersion) {
|
|
133
|
-
ctx.err.report(localize('java-edition.pack-format.unsupported', target), node, 2 /* core.ErrorSeverity.Warning */);
|
|
134
|
-
}
|
|
135
|
-
else if (targetVersion.id !== release) {
|
|
136
|
-
ctx.err.report(localize('java-edition.pack-format.not-loaded', target, release), node, 2 /* core.ErrorSeverity.Warning */);
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
},
|
|
140
|
-
numericCompleter: (_, ctx) => {
|
|
141
|
-
return [...packFormats.values()].map((v, i) => ({
|
|
142
|
-
range: core.Range.create(ctx.offset),
|
|
143
|
-
label: `${v.data_pack_version}`,
|
|
144
|
-
labelSuffix: ` (${v.id})`,
|
|
145
|
-
sortText: `${i}`.padStart(4, '0'),
|
|
146
|
-
}));
|
|
147
|
-
},
|
|
148
|
-
});
|
|
111
|
+
registerMcdocAttributes(meta, release);
|
|
112
|
+
registerPackFormatAttribute(meta, release, versions, packs);
|
|
113
|
+
meta.registerLanguage('zip', { extensions: ['.zip'] });
|
|
114
|
+
meta.registerLanguage('png', { extensions: ['.png'] });
|
|
115
|
+
meta.registerLanguage('ogg', { extensions: ['.ogg'] });
|
|
116
|
+
meta.registerLanguage('ttf', { extensions: ['.ttf'] });
|
|
117
|
+
meta.registerLanguage('otf', { extensions: ['.otf'] });
|
|
118
|
+
meta.registerLanguage('fsh', { extensions: ['.fsh'] });
|
|
119
|
+
meta.registerLanguage('vsh', { extensions: ['.vsh'] });
|
|
149
120
|
json.initialize(ctx);
|
|
150
121
|
jeJson.initialize(ctx);
|
|
151
122
|
jeMcf.initialize(ctx, summary.commands, release);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as core from '@spyglassmc/core';
|
|
2
|
+
import type { McmetaVersions, PackInfo } from './dependency';
|
|
3
|
+
import { ReleaseVersion } from './dependency';
|
|
4
|
+
export declare function registerMcdocAttributes(meta: core.MetaRegistry, release: ReleaseVersion): void;
|
|
5
|
+
export declare function registerPackFormatAttribute(meta: core.MetaRegistry, release: ReleaseVersion, versions: McmetaVersions, packs: PackInfo[]): void;
|
|
6
|
+
//# sourceMappingURL=mcdocAttributes.d.ts.map
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import * as core from '@spyglassmc/core';
|
|
2
|
+
import { localize } from '@spyglassmc/locales';
|
|
3
|
+
import * as mcdoc from '@spyglassmc/mcdoc';
|
|
4
|
+
import { NEXT_RELEASE_VERSION, ReleaseVersion } from './dependency';
|
|
5
|
+
export function registerMcdocAttributes(meta, release) {
|
|
6
|
+
mcdoc.runtime.registerAttribute(meta, 'since', mcdoc.runtime.attribute.validator.string, {
|
|
7
|
+
filterElement: (config, ctx) => {
|
|
8
|
+
if (!config.startsWith('1.')) {
|
|
9
|
+
ctx.logger.warn(`Invalid mcdoc attribute for "since": ${config}`);
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
return ReleaseVersion.cmp(release, config) >= 0;
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
mcdoc.runtime.registerAttribute(meta, 'until', mcdoc.runtime.attribute.validator.string, {
|
|
16
|
+
filterElement: (config, ctx) => {
|
|
17
|
+
if (!config.startsWith('1.')) {
|
|
18
|
+
ctx.logger.warn(`Invalid mcdoc attribute for "until": ${config}`);
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
return ReleaseVersion.cmp(release, config) < 0;
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
mcdoc.runtime.registerAttribute(meta, 'deprecated', mcdoc.runtime.attribute.validator.optional(mcdoc.runtime.attribute.validator.string), {
|
|
25
|
+
mapField: (config, field, ctx) => {
|
|
26
|
+
if (config === undefined) {
|
|
27
|
+
return { ...field, deprecated: true };
|
|
28
|
+
}
|
|
29
|
+
if (!config.startsWith('1.')) {
|
|
30
|
+
ctx.logger.warn(`Invalid mcdoc attribute for "deprecated": ${config}`);
|
|
31
|
+
return field;
|
|
32
|
+
}
|
|
33
|
+
if (ReleaseVersion.cmp(release, config) >= 0) {
|
|
34
|
+
return { ...field, deprecated: true };
|
|
35
|
+
}
|
|
36
|
+
return field;
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
export function registerPackFormatAttribute(meta, release, versions, packs) {
|
|
41
|
+
const dataFormats = new Map();
|
|
42
|
+
const assetsFormats = new Map();
|
|
43
|
+
if (versions[0]?.type !== 'release') {
|
|
44
|
+
dataFormats.set(versions[0].data_pack_version, [NEXT_RELEASE_VERSION]);
|
|
45
|
+
assetsFormats.set(versions[0].resource_pack_version, [NEXT_RELEASE_VERSION]);
|
|
46
|
+
}
|
|
47
|
+
for (const version of versions) {
|
|
48
|
+
if (version.type === 'release') {
|
|
49
|
+
dataFormats.set(version.data_pack_version, [
|
|
50
|
+
...dataFormats.get(version.data_pack_version) ?? [],
|
|
51
|
+
version.id,
|
|
52
|
+
]);
|
|
53
|
+
assetsFormats.set(version.resource_pack_version, [
|
|
54
|
+
...assetsFormats.get(version.resource_pack_version) ?? [],
|
|
55
|
+
version.id,
|
|
56
|
+
]);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function getFormats(packMcmetaUri) {
|
|
60
|
+
const thisPack = packs.find(p => core.fileUtil.isSubUriOf(packMcmetaUri, p.packRoot));
|
|
61
|
+
return thisPack?.type === 'assets' ? assetsFormats : dataFormats;
|
|
62
|
+
}
|
|
63
|
+
mcdoc.runtime.registerAttribute(meta, 'pack_format', () => undefined, {
|
|
64
|
+
checker: (_, typeDef) => {
|
|
65
|
+
if (typeDef.kind !== 'literal' || typeof typeDef.value.value !== 'number') {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
const target = typeDef.value.value;
|
|
69
|
+
return (node, ctx) => {
|
|
70
|
+
const targetVersions = getFormats(ctx.doc.uri).get(target);
|
|
71
|
+
if (!targetVersions) {
|
|
72
|
+
ctx.err.report(localize('java-edition.pack-format.unsupported', target), node, 2 /* core.ErrorSeverity.Warning */);
|
|
73
|
+
}
|
|
74
|
+
else if (!targetVersions.some(v => v === release)) {
|
|
75
|
+
ctx.err.report(localize('java-edition.pack-format.not-loaded', target, release), node, 2 /* core.ErrorSeverity.Warning */);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
},
|
|
79
|
+
numericCompleter: (_, ctx) => {
|
|
80
|
+
return [...getFormats(ctx.doc.uri).entries()].map(([k, v], i) => ({
|
|
81
|
+
range: core.Range.create(ctx.offset),
|
|
82
|
+
label: `${k}`,
|
|
83
|
+
labelSuffix: ` (${v[0]})`,
|
|
84
|
+
sortText: `${i}`.padStart(4, '0'),
|
|
85
|
+
}));
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=mcdocAttributes.js.map
|
|
@@ -131,17 +131,17 @@ const itemStack = (node, ctx) => {
|
|
|
131
131
|
return;
|
|
132
132
|
}
|
|
133
133
|
const groupedComponents = new Map();
|
|
134
|
-
for (const
|
|
135
|
-
if (!
|
|
134
|
+
for (const child of node.components.children) {
|
|
135
|
+
if (!child.key) {
|
|
136
136
|
continue;
|
|
137
137
|
}
|
|
138
|
-
const componentId = core.ResourceLocationNode.toString(
|
|
138
|
+
const componentId = core.ResourceLocationNode.toString(child.key, 'full');
|
|
139
139
|
if (!groupedComponents.has(componentId)) {
|
|
140
140
|
groupedComponents.set(componentId, []);
|
|
141
141
|
}
|
|
142
|
-
groupedComponents.get(componentId).push(
|
|
143
|
-
if (
|
|
144
|
-
nbt.checker.index('minecraft:data_component', componentId)(
|
|
142
|
+
groupedComponents.get(componentId).push(child.key);
|
|
143
|
+
if (child.type === 'mcfunction:component' && child.value) {
|
|
144
|
+
nbt.checker.index('minecraft:data_component', componentId)(child.value, ctx);
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
for (const [_, group] of groupedComponents) {
|
|
@@ -269,16 +269,13 @@ const particle = (node, ctx) => {
|
|
|
269
269
|
return;
|
|
270
270
|
}
|
|
271
271
|
const options = node.children?.find(nbt.NbtCompoundNode.is);
|
|
272
|
-
if (
|
|
273
|
-
if
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
else {
|
|
277
|
-
ctx.err.report(localize('expected', localize('nbt.node.compound')), core.Range.create(node.id.range.end, node.id.range.end + 1));
|
|
278
|
-
}
|
|
272
|
+
if (options) {
|
|
273
|
+
// Even if particle isn't explicitly marked as requiring options,
|
|
274
|
+
// run the type checker anyways to allow an empty compound
|
|
275
|
+
nbt.checker.index('minecraft:particle', core.ResourceLocation.lengthen(id))(options, ctx);
|
|
279
276
|
}
|
|
280
|
-
else if (
|
|
281
|
-
ctx.err.report(localize('expected', localize('
|
|
277
|
+
else if (ParticleNode.requiresOptions(id)) {
|
|
278
|
+
ctx.err.report(localize('expected', localize('nbt.node.compound')), core.Range.create(node.id.range.end, node.id.range.end + 1));
|
|
282
279
|
}
|
|
283
280
|
};
|
|
284
281
|
// #endregion
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AstNode, BooleanNode, BrigadierStringOptions, completer, CompletionItem, FloatNode, getStates, InsertTextBuilder, IntegerNode, LiteralNode, Range, ResourceLocation, ResourceLocationNode, StringNode, SymbolNode, } from '@spyglassmc/core';
|
|
1
|
+
import { AstNode, binarySearch, BooleanNode, BrigadierStringOptions, completer, CompletionItem, FloatNode, getStates, InsertTextBuilder, IntegerNode, LiteralNode, Range, ResourceLocation, ResourceLocationNode, StringNode, SymbolNode, } from '@spyglassmc/core';
|
|
2
2
|
import * as json from '@spyglassmc/json';
|
|
3
3
|
import { localeQuote, localize } from '@spyglassmc/locales';
|
|
4
4
|
import { getTagValues } from '../../common/index.js';
|
|
@@ -183,19 +183,32 @@ const blockStates = (node, ctx) => {
|
|
|
183
183
|
})(node, ctx);
|
|
184
184
|
};
|
|
185
185
|
const componentList = (node, ctx) => {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
186
|
+
if (!Range.contains(Range.translate(node, 1, -1), ctx.offset, true)) {
|
|
187
|
+
return [];
|
|
188
|
+
}
|
|
189
|
+
const completeKey = (key) => {
|
|
190
|
+
const id = key
|
|
191
|
+
?? ResourceLocationNode.mock(key ?? ctx.offset, { category: 'data_component_type' });
|
|
192
|
+
return completer.resourceLocation(id, ctx);
|
|
193
|
+
};
|
|
194
|
+
const index = binarySearch(node.children, ctx.offset, (n, o) => Range.compareOffset(n.range, o, true));
|
|
195
|
+
const child = index >= 0 ? node.children[index] : undefined;
|
|
196
|
+
if (!child) {
|
|
197
|
+
return [
|
|
198
|
+
...completer.literal(LiteralNode.mock(ctx.offset, { pool: ['!'] }), ctx),
|
|
199
|
+
...completeKey(undefined),
|
|
200
|
+
];
|
|
201
|
+
}
|
|
202
|
+
if (child.type === 'mcfunction:component_removal') {
|
|
203
|
+
return completeKey(child.key);
|
|
204
|
+
}
|
|
205
|
+
if ((child.key && Range.contains(child.key, ctx.offset, true))) {
|
|
206
|
+
return completeKey(child.key);
|
|
207
|
+
}
|
|
208
|
+
if (child.value && Range.contains(child.value, ctx.offset, true)) {
|
|
209
|
+
return completer.dispatch(child.value, ctx);
|
|
210
|
+
}
|
|
211
|
+
return [];
|
|
199
212
|
};
|
|
200
213
|
const componentTests = (node, ctx) => {
|
|
201
214
|
// TODO: improve this completer
|
|
@@ -57,7 +57,7 @@ export function registerMcdocAttributes(meta, rootTreeNode) {
|
|
|
57
57
|
stringMocker: (_, __, ctx) => ScoreHolderNode.mock(ctx.offset),
|
|
58
58
|
});
|
|
59
59
|
mcdoc.runtime.registerAttribute(meta, 'tag', () => undefined, {
|
|
60
|
-
stringParser: () => parser.tag('
|
|
60
|
+
stringParser: () => parser.tag('reference'),
|
|
61
61
|
stringMocker: (_, __, ctx) => core.SymbolNode.mock(ctx.offset, { category: 'tag' }),
|
|
62
62
|
});
|
|
63
63
|
mcdoc.runtime.registerAttribute(meta, 'block_predicate', () => undefined, {
|
|
@@ -86,7 +86,7 @@ export interface EntitySelectorNode extends core.AstNode {
|
|
|
86
86
|
export declare namespace EntitySelectorNode {
|
|
87
87
|
function is<T extends core.DeepReadonly<core.AstNode> | undefined>(node: T): node is core.InheritReadonly<EntitySelectorNode, T>;
|
|
88
88
|
function mock(range: core.RangeLike, options: core.LiteralOptions): EntitySelectorNode;
|
|
89
|
-
const ArgumentKeys: Set<"tag" | "team" | "predicate" | "type" | "level" | "
|
|
89
|
+
const ArgumentKeys: Set<"tag" | "team" | "predicate" | "type" | "level" | "sort" | "advancements" | "nbt" | "distance" | "gamemode" | "limit" | "name" | "scores" | "x" | "y" | "z" | "dx" | "dy" | "dz" | "x_rotation" | "y_rotation">;
|
|
90
90
|
type ArgumentKey = typeof ArgumentKeys extends Set<infer T> ? T : undefined;
|
|
91
91
|
const enum Result {
|
|
92
92
|
Ok = 0,
|
|
@@ -123,11 +123,29 @@ export declare namespace ItemStackNode {
|
|
|
123
123
|
}
|
|
124
124
|
export interface ComponentListNode extends core.AstNode {
|
|
125
125
|
type: 'mcfunction:component_list';
|
|
126
|
-
children:
|
|
126
|
+
children: (ComponentNode | ComponentRemovalNode)[];
|
|
127
127
|
}
|
|
128
128
|
export declare namespace ComponentListNode {
|
|
129
129
|
function is(node: core.AstNode): node is ComponentListNode;
|
|
130
130
|
}
|
|
131
|
+
export interface ComponentNode extends core.AstNode {
|
|
132
|
+
type: 'mcfunction:component';
|
|
133
|
+
children: (core.ResourceLocationNode | nbt.NbtNode)[];
|
|
134
|
+
key: core.ResourceLocationNode;
|
|
135
|
+
value?: nbt.NbtNode;
|
|
136
|
+
}
|
|
137
|
+
export declare namespace ComponentNode {
|
|
138
|
+
function is(node: core.AstNode): node is ComponentNode;
|
|
139
|
+
}
|
|
140
|
+
export interface ComponentRemovalNode extends core.AstNode {
|
|
141
|
+
type: 'mcfunction:component_removal';
|
|
142
|
+
children: (core.LiteralNode | core.ResourceLocationNode)[];
|
|
143
|
+
prefix: core.LiteralNode;
|
|
144
|
+
key: core.ResourceLocationNode;
|
|
145
|
+
}
|
|
146
|
+
export declare namespace ComponentRemovalNode {
|
|
147
|
+
function is(node: core.AstNode): node is ComponentRemovalNode;
|
|
148
|
+
}
|
|
131
149
|
export interface ItemPredicateNode extends core.AstNode {
|
|
132
150
|
type: 'mcfunction:item_predicate';
|
|
133
151
|
children: (core.ResourceLocationNode | core.LiteralNode | ComponentTestsNode | nbt.NbtCompoundNode)[];
|
|
@@ -233,7 +251,7 @@ export interface ObjectiveCriteriaNode extends core.AstNode {
|
|
|
233
251
|
}
|
|
234
252
|
export declare namespace ObjectiveCriteriaNode {
|
|
235
253
|
const SimpleValues: string[];
|
|
236
|
-
const ComplexCategories: Map<string, "block" | "fluid" | "instrument" | "activity" | "armor_material" | "attribute" | "block_entity_type" | "block_predicate_type" | "block_type" | "cat_variant" | "chunk_status" | "command_argument_type" | "creative_mode_tab" | "custom_stat" | "data_component_type" | "decorated_pot_pattern" | "enchantment_effect_component_type" | "enchantment_entity_effect_type" | "enchantment_level_based_value_type" | "enchantment_location_based_effect_type" | "enchantment_provider_type" | "enchantment_value_effect_type" | "entity_sub_predicate_type" | "entity_type" | "float_provider_type" | "frog_variant" | "game_event" | "height_provider_type" | "int_provider_type" | "item" | "item_sub_predicate_type" | "loot_condition_type" | "loot_function_type" | "loot_nbt_provider_type" | "loot_number_provider_type" | "loot_pool_entry_type" | "loot_score_provider_type" | "map_decoration_type" | "memory_module_type" | "menu" | "mob_effect" | "motive" | "number_format_type" | "particle_type" | "point_of_interest_type" | "pos_rule_test" | "position_source_type" | "potion" | "recipe_serializer" | "recipe_type" | "rule_block_entity_modifier" | "rule_test" | "schedule" | "sensor_type" | "sound_event" | "stat_type" | "trigger_type" | "villager_profession" | "villager_type" | "worldgen/biome_source" | "worldgen/block_placer_type" | "worldgen/block_state_provider_type" | "worldgen/carver" | "worldgen/chunk_generator" | "worldgen/decorator" | "worldgen/density_function_type" | "worldgen/feature" | "worldgen/feature_size_type" | "worldgen/foliage_placer_type" | "worldgen/material_condition" | "worldgen/material_rule" | "worldgen/placement_modifier_type" | "worldgen/pool_alias_binding" | "worldgen/root_placer_type" | "worldgen/structure_feature" | "worldgen/structure_piece" | "worldgen/structure_placement" | "worldgen/structure_pool_element" | "worldgen/structure_processor" | "worldgen/structure_type" | "worldgen/surface_builder" | "worldgen/tree_decorator_type" | "worldgen/trunk_placer_type">;
|
|
254
|
+
const ComplexCategories: Map<string, "block" | "fluid" | "instrument" | "activity" | "armor_material" | "attribute" | "block_entity_type" | "block_predicate_type" | "block_type" | "cat_variant" | "chunk_status" | "command_argument_type" | "consume_effect_type" | "creative_mode_tab" | "custom_stat" | "data_component_type" | "decorated_pot_pattern" | "decorated_pot_patterns" | "enchantment_effect_component_type" | "enchantment_entity_effect_type" | "enchantment_level_based_value_type" | "enchantment_location_based_effect_type" | "enchantment_provider_type" | "enchantment_value_effect_type" | "entity_sub_predicate_type" | "entity_type" | "float_provider_type" | "frog_variant" | "game_event" | "height_provider_type" | "int_provider_type" | "item" | "item_sub_predicate_type" | "loot_condition_type" | "loot_function_type" | "loot_nbt_provider_type" | "loot_number_provider_type" | "loot_pool_entry_type" | "loot_score_provider_type" | "map_decoration_type" | "memory_module_type" | "menu" | "mob_effect" | "motive" | "number_format_type" | "particle_type" | "point_of_interest_type" | "pos_rule_test" | "position_source_type" | "potion" | "recipe_book_category" | "recipe_display" | "recipe_serializer" | "recipe_type" | "rule_block_entity_modifier" | "rule_test" | "schedule" | "sensor_type" | "slot_display" | "sound_event" | "stat_type" | "trigger_type" | "villager_profession" | "villager_type" | "worldgen/biome_source" | "worldgen/block_placer_type" | "worldgen/block_state_provider_type" | "worldgen/carver" | "worldgen/chunk_generator" | "worldgen/decorator" | "worldgen/density_function_type" | "worldgen/feature" | "worldgen/feature_size_type" | "worldgen/foliage_placer_type" | "worldgen/material_condition" | "worldgen/material_rule" | "worldgen/placement_modifier_type" | "worldgen/pool_alias_binding" | "worldgen/root_placer_type" | "worldgen/structure_feature" | "worldgen/structure_piece" | "worldgen/structure_placement" | "worldgen/structure_pool_element" | "worldgen/structure_processor" | "worldgen/structure_type" | "worldgen/surface_builder" | "worldgen/tree_decorator_type" | "worldgen/trunk_placer_type">;
|
|
237
255
|
const ComplexSep = ":";
|
|
238
256
|
function mock(range: core.RangeLike): ObjectiveCriteriaNode;
|
|
239
257
|
}
|
|
@@ -254,9 +272,10 @@ export declare namespace ParticleNode {
|
|
|
254
272
|
}
|
|
255
273
|
export interface ScoreHolderNode extends core.AstNode {
|
|
256
274
|
type: 'mcfunction:score_holder';
|
|
257
|
-
children: [core.SymbolNode | EntitySelectorNode];
|
|
275
|
+
children: [core.LiteralNode | core.SymbolNode | EntitySelectorNode];
|
|
258
276
|
fakeName?: core.SymbolNode;
|
|
259
277
|
selector?: EntitySelectorNode;
|
|
278
|
+
wildcard?: core.LiteralNode;
|
|
260
279
|
}
|
|
261
280
|
export declare namespace ScoreHolderNode {
|
|
262
281
|
function mock(range: core.RangeLike): ScoreHolderNode;
|
|
@@ -181,6 +181,20 @@ export var ComponentListNode;
|
|
|
181
181
|
}
|
|
182
182
|
ComponentListNode.is = is;
|
|
183
183
|
})(ComponentListNode || (ComponentListNode = {}));
|
|
184
|
+
export var ComponentNode;
|
|
185
|
+
(function (ComponentNode) {
|
|
186
|
+
function is(node) {
|
|
187
|
+
return node.type === 'mcfunction:component';
|
|
188
|
+
}
|
|
189
|
+
ComponentNode.is = is;
|
|
190
|
+
})(ComponentNode || (ComponentNode = {}));
|
|
191
|
+
export var ComponentRemovalNode;
|
|
192
|
+
(function (ComponentRemovalNode) {
|
|
193
|
+
function is(node) {
|
|
194
|
+
return node.type === 'mcfunction:component_removal';
|
|
195
|
+
}
|
|
196
|
+
ComponentRemovalNode.is = is;
|
|
197
|
+
})(ComponentRemovalNode || (ComponentRemovalNode = {}));
|
|
184
198
|
export var ItemPredicateNode;
|
|
185
199
|
(function (ItemPredicateNode) {
|
|
186
200
|
function is(node) {
|
|
@@ -327,8 +341,10 @@ export var ParticleNode;
|
|
|
327
341
|
// since 1.20.5
|
|
328
342
|
const OptionTypes = new Set([
|
|
329
343
|
...SpecialTypes,
|
|
344
|
+
'block_crumble',
|
|
330
345
|
'dust_pillar',
|
|
331
346
|
'entity_effect',
|
|
347
|
+
'trail',
|
|
332
348
|
]);
|
|
333
349
|
function requiresOptions(type) {
|
|
334
350
|
return OptionTypes.has(type);
|