@spyglassmc/java-edition 0.3.8 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/lib/binder/index.d.ts +11 -9
  2. package/lib/binder/index.js +149 -150
  3. package/lib/common/index.js +6 -9
  4. package/lib/dependency/common.d.ts +5 -0
  5. package/lib/dependency/common.js +8 -0
  6. package/lib/dependency/index.js +7 -17
  7. package/lib/dependency/mcmeta.d.ts +6 -12
  8. package/lib/dependency/mcmeta.js +21 -38
  9. package/lib/index.d.ts +1 -0
  10. package/lib/index.js +74 -32
  11. package/lib/json/checker/index.d.ts +3 -10
  12. package/lib/json/checker/index.js +36 -244
  13. package/lib/json/index.d.ts +0 -1
  14. package/lib/json/index.js +0 -3
  15. package/lib/mcfunction/checker/index.d.ts +0 -2
  16. package/lib/mcfunction/checker/index.js +254 -183
  17. package/lib/mcfunction/common/index.d.ts +4 -2
  18. package/lib/mcfunction/common/index.js +56 -52
  19. package/lib/mcfunction/completer/argument.js +112 -57
  20. package/lib/mcfunction/index.d.ts +3 -2
  21. package/lib/mcfunction/index.js +18 -19
  22. package/lib/mcfunction/inlayHintProvider.js +2 -3
  23. package/lib/mcfunction/mcdocAttributes.d.ts +4 -0
  24. package/lib/mcfunction/mcdocAttributes.js +71 -0
  25. package/lib/mcfunction/node/argument.d.ts +115 -12
  26. package/lib/mcfunction/node/argument.js +131 -63
  27. package/lib/mcfunction/parser/argument.d.ts +14 -4
  28. package/lib/mcfunction/parser/argument.js +380 -212
  29. package/lib/mcfunction/signatureHelpProvider.d.ts +2 -1
  30. package/lib/mcfunction/signatureHelpProvider.js +10 -18
  31. package/lib/mcfunction/tree/argument.d.ts +68 -1
  32. package/lib/mcfunction/tree/patch.js +279 -77
  33. package/lib/mcfunction/tree/patchValidator.d.ts +7 -0
  34. package/lib/mcfunction/tree/patchValidator.js +25 -0
  35. package/package.json +8 -9
@@ -2,9 +2,11 @@ import { AstNode, BooleanNode, BrigadierStringOptions, completer, CompletionItem
2
2
  import * as json from '@spyglassmc/json';
3
3
  import { localeQuote, localize } from '@spyglassmc/locales';
4
4
  import { getTagValues } from '../../common/index.js';
5
- import { ColorArgumentValues, EntityAnchorArgumentValues, GamemodeArgumentValues, HeightmapValues, ItemSlotArgumentValues, MirrorValues, OperationArgumentValues, RotationValues, ScoreboardSlotArgumentValues, SwizzleArgumentValues, } from '../common/index.js';
6
- import { BlockNode, CoordinateNode, EntitySelectorNode, IntRangeNode, ItemNode, ObjectiveCriteriaNode, ParticleNode, ScoreHolderNode, VectorNode, } from '../node/index.js';
7
- export const getMockNodes = (rawTreeNode, range) => {
5
+ import { ReleaseVersion } from '../../dependency/common.js';
6
+ import { ColorArgumentValues, EntityAnchorArgumentValues, GamemodeArgumentValues, getItemSlotArgumentValues, getItemSlotsArgumentValues, getScoreboardSlotArgumentValues, HeightmapValues, MirrorValues, OperationArgumentValues, RotationValues, SwizzleArgumentValues, } from '../common/index.js';
7
+ import { BlockNode, ComponentTestExactNode, ComponentTestSubpredicateNode, CoordinateNode, EntitySelectorAtVariable, EntitySelectorNode, IntRangeNode, ItemPredicateNode, ItemStackNode, ObjectiveCriteriaNode, ParticleNode, ScoreHolderNode, VectorNode, } from '../node/index.js';
8
+ export const getMockNodes = (rawTreeNode, ctx) => {
9
+ const range = ctx.offset;
8
10
  const treeNode = rawTreeNode;
9
11
  switch (treeNode.parser) {
10
12
  case 'brigadier:bool':
@@ -44,7 +46,9 @@ export const getMockNodes = (rawTreeNode, range) => {
44
46
  return ResourceLocationNode.mock(range, { category: 'dimension' });
45
47
  case 'minecraft:entity':
46
48
  case 'minecraft:game_profile':
47
- return EntitySelectorNode.mock(range);
49
+ return EntitySelectorNode.mock(range, {
50
+ pool: EntitySelectorAtVariable.filterAvailable(ctx),
51
+ });
48
52
  case 'minecraft:heightmap':
49
53
  return LiteralNode.mock(range, { pool: HeightmapValues });
50
54
  case 'minecraft:entity_anchor':
@@ -60,11 +64,19 @@ export const getMockNodes = (rawTreeNode, range) => {
60
64
  case 'minecraft:item_enchantment':
61
65
  return ResourceLocationNode.mock(range, { category: 'enchantment' });
62
66
  case 'minecraft:item_predicate':
63
- return ItemNode.mock(range, true);
67
+ return ItemPredicateNode.mock(range);
64
68
  case 'minecraft:item_slot':
65
- return LiteralNode.mock(range, { pool: ItemSlotArgumentValues });
69
+ return LiteralNode.mock(range, { pool: getItemSlotArgumentValues(ctx) });
70
+ case 'minecraft:item_slots':
71
+ return LiteralNode.mock(range, { pool: getItemSlotsArgumentValues(ctx) });
66
72
  case 'minecraft:item_stack':
67
- return ItemNode.mock(range, false);
73
+ return ItemStackNode.mock(range);
74
+ case 'minecraft:loot_modifier':
75
+ return ResourceLocationNode.mock(range, { category: 'item_modifier' });
76
+ case 'minecraft:loot_predicate':
77
+ return ResourceLocationNode.mock(range, { category: 'predicate' });
78
+ case 'minecraft:loot_table':
79
+ return ResourceLocationNode.mock(range, { category: 'loot_table' });
68
80
  case 'minecraft:mob_effect':
69
81
  return ResourceLocationNode.mock(range, { category: 'mob_effect' });
70
82
  case 'minecraft:objective':
@@ -81,18 +93,23 @@ export const getMockNodes = (rawTreeNode, range) => {
81
93
  case 'minecraft:resource':
82
94
  case 'minecraft:resource_key':
83
95
  case 'minecraft:resource_or_tag':
96
+ case 'minecraft:resource_or_tag_key':
97
+ const allowTag = treeNode.parser === 'minecraft:resource_or_tag'
98
+ || treeNode.parser === 'minecraft:resource_or_tag_key';
84
99
  return ResourceLocationNode.mock(range, {
85
100
  category: ResourceLocation.shorten(treeNode.properties.registry),
86
- allowTag: treeNode.parser === 'minecraft:resource_or_tag',
101
+ allowTag,
87
102
  });
88
103
  case 'minecraft:resource_location':
89
104
  return ResourceLocationNode.mock(range, treeNode.properties ?? { pool: [], allowUnknown: true });
90
105
  case 'minecraft:rotation':
91
106
  return VectorNode.mock(range, { dimension: 2, noLocal: true });
92
107
  case 'minecraft:scoreboard_slot':
93
- return LiteralNode.mock(range, { pool: ScoreboardSlotArgumentValues });
108
+ return LiteralNode.mock(range, { pool: getScoreboardSlotArgumentValues(ctx) });
94
109
  case 'minecraft:score_holder':
95
110
  return ScoreHolderNode.mock(range);
111
+ case 'minecraft:style':
112
+ return json.JsonObjectNode.mock(range);
96
113
  case 'minecraft:swizzle':
97
114
  return LiteralNode.mock(range, { pool: SwizzleArgumentValues });
98
115
  case 'minecraft:team':
@@ -121,10 +138,12 @@ const block = (node, ctx) => {
121
138
  if (Range.contains(node.id, ctx.offset, true)) {
122
139
  ans.push(...completer.resourceLocation(node.id, ctx));
123
140
  }
124
- if (node.states &&
125
- Range.contains(Range.translate(node.states, 1, -1), ctx.offset, true)) {
141
+ if (node.states && Range.contains(Range.translate(node.states, 1, -1), ctx.offset, true)) {
126
142
  ans.push(...blockStates(node.states, ctx));
127
143
  }
144
+ if (node.nbt && Range.contains(Range.translate(node.nbt, 1, -1), ctx.offset, true)) {
145
+ ans.push(...completer.dispatch(node.nbt, ctx));
146
+ }
128
147
  return ans;
129
148
  };
130
149
  const blockStates = (node, ctx) => {
@@ -137,51 +156,90 @@ const blockStates = (node, ctx) => {
137
156
  const states = getStates('block', blocks, ctx);
138
157
  return completer.record({
139
158
  key: (_record, pair, _ctx, range, insertValue, insertComma, existingKeys) => {
140
- return Object.keys(states)
141
- .filter((k) => pair?.key?.value === k ||
142
- !existingKeys.some((ek) => ek.value === k))
143
- .map((k) => CompletionItem.create(k, range, {
159
+ return Object.keys(states).filter((k) => pair?.key?.value === k || !existingKeys.some((ek) => ek.value === k)).map((k) => CompletionItem.create(k, range, {
144
160
  kind: 10 /* CompletionKind.Property */,
145
161
  detail: localize('mcfunction.completer.block.states.default-value', localeQuote(states[k][0])),
146
- insertText: new InsertTextBuilder()
147
- .literal(k)
148
- .if(insertValue, (b) => b.literal('=').placeholder(...states[k]))
149
- .if(insertComma, (b) => b.literal(','))
150
- .build(),
162
+ insertText: new InsertTextBuilder().literal(k).if(insertValue, (b) => b.literal('=').placeholder(...states[k])).if(insertComma, (b) => b.literal(',')).build(),
151
163
  }));
152
164
  },
153
165
  value: (_record, pair, ctx) => {
154
166
  if (pair.key && states[pair.key.value]) {
155
- return states[pair.key.value].map((v) => CompletionItem.create(v, pair.value ?? ctx.offset, {
156
- kind: 12 /* CompletionKind.Value */,
157
- }));
167
+ return states[pair.key.value].map((v) => CompletionItem.create(v, pair.value ?? ctx.offset, { kind: 12 /* CompletionKind.Value */ }));
158
168
  }
159
169
  return [];
160
170
  },
161
171
  })(node, ctx);
162
172
  };
173
+ const componentList = (node, ctx) => {
174
+ return completer.record({
175
+ key: (_record, pair, ctx, range) => {
176
+ const id = pair?.key
177
+ ?? ResourceLocationNode.mock(pair?.key ?? range, { category: 'data_component_type' });
178
+ return completer.resourceLocation(id, ctx);
179
+ },
180
+ value: (_record, pair, ctx) => {
181
+ if (!pair.value) {
182
+ return [];
183
+ }
184
+ return completer.dispatch(pair.value, ctx);
185
+ },
186
+ })(node, ctx);
187
+ };
188
+ const componentTests = (node, ctx) => {
189
+ // TODO: improve this completer
190
+ const test = AstNode.findShallowestChild({
191
+ node: node,
192
+ needle: ctx.offset,
193
+ endInclusive: true,
194
+ predicate: (n) => ComponentTestExactNode.is(n) || ComponentTestSubpredicateNode.is(n),
195
+ });
196
+ if (test && ComponentTestExactNode.is(test) && test.value) {
197
+ return completer.dispatch(test.value, ctx);
198
+ }
199
+ else if (test && ComponentTestSubpredicateNode.is(test) && test.value) {
200
+ return completer.dispatch(test.value, ctx);
201
+ }
202
+ return [];
203
+ };
163
204
  const coordinate = (node, _ctx) => {
164
205
  return [CompletionItem.create('~', node)];
165
206
  };
166
- const item = (node, ctx) => {
207
+ const itemStack = (node, ctx) => {
167
208
  const ans = [];
168
209
  if (Range.contains(node.id, ctx.offset, true)) {
169
210
  ans.push(...completer.resourceLocation(node.id, ctx));
170
211
  }
212
+ if (node.components && Range.contains(node.components, ctx.offset, true)) {
213
+ ans.push(...componentList(node.components, ctx));
214
+ }
215
+ if (node.nbt && Range.contains(node.nbt, ctx.offset, true)) {
216
+ ans.push(...completer.dispatch(node.nbt, ctx));
217
+ }
218
+ return ans;
219
+ };
220
+ const itemPredicate = (node, ctx) => {
221
+ const ans = [];
222
+ if (Range.contains(node.id, ctx.offset, true)) {
223
+ ans.push(CompletionItem.create('*', node, { sortText: '##' }));
224
+ if (node.id.type === 'resource_location') {
225
+ ans.push(...completer.resourceLocation(node.id, ctx));
226
+ }
227
+ }
228
+ if (node.tests && Range.contains(node.tests, ctx.offset, true)) {
229
+ ans.push(...componentTests(node.tests, ctx));
230
+ }
231
+ if (node.nbt && Range.contains(node.nbt, ctx.offset, true)) {
232
+ ans.push(...completer.dispatch(node.nbt, ctx));
233
+ }
171
234
  return ans;
172
235
  };
173
236
  const objectiveCriteria = (node, ctx) => {
174
237
  const ans = ObjectiveCriteriaNode.SimpleValues.map((v) => CompletionItem.create(v, node));
175
- if (!node.children?.[0] ||
176
- Range.contains(node.children[0], ctx.offset, true)) {
177
- ans.push(...completer.resourceLocation(node.children?.[0] ??
178
- ResourceLocationNode.mock(node, {
179
- category: 'stat_type',
180
- namespacePathSep: '.',
181
- }), ctx));
238
+ if (!node.children?.[0] || Range.contains(node.children[0], ctx.offset, true)) {
239
+ ans.push(...completer.resourceLocation(node.children?.[0]
240
+ ?? ResourceLocationNode.mock(node, { category: 'stat_type', namespacePathSep: '.' }), ctx));
182
241
  }
183
- if (node.children?.[1] &&
184
- Range.contains(node.children[1], ctx.offset, true)) {
242
+ if (node.children?.[1] && Range.contains(node.children[1], ctx.offset, true)) {
185
243
  ans.push(...completer.resourceLocation(node.children[1], ctx));
186
244
  }
187
245
  return ans;
@@ -191,21 +249,22 @@ const particle = (node, ctx) => {
191
249
  if (child) {
192
250
  return completer.dispatch(child, ctx);
193
251
  }
252
+ const release = ctx.project['loadedVersion'];
253
+ if (!release || ReleaseVersion.cmp(release, '1.20.5') >= 0) {
254
+ return [];
255
+ }
194
256
  const id = ResourceLocationNode.toString(node.id, 'short');
195
257
  const map = {
196
258
  block: [BlockNode.mock(ctx.offset, false)],
197
259
  block_marker: [BlockNode.mock(ctx.offset, false)],
198
- dust: [
199
- VectorNode.mock(ctx.offset, { dimension: 3 }),
200
- FloatNode.mock(ctx.offset),
201
- ],
260
+ dust: [VectorNode.mock(ctx.offset, { dimension: 3 }), FloatNode.mock(ctx.offset)],
202
261
  dust_color_transition: [
203
262
  VectorNode.mock(ctx.offset, { dimension: 3 }),
204
263
  FloatNode.mock(ctx.offset),
205
264
  VectorNode.mock(ctx.offset, { dimension: 3 }),
206
265
  ],
207
266
  falling_dust: [BlockNode.mock(ctx.offset, false)],
208
- item: [ItemNode.mock(ctx.offset, false)],
267
+ item: [ItemStackNode.mock(ctx.offset)],
209
268
  sculk_charge: [FloatNode.mock(ctx.offset)],
210
269
  shriek: [IntegerNode.mock(ctx.offset)],
211
270
  vibration: [
@@ -215,8 +274,8 @@ const particle = (node, ctx) => {
215
274
  ],
216
275
  };
217
276
  if (ParticleNode.isSpecialType(id)) {
218
- const numParamsBefore = node.children?.slice(1).filter((n) => n.range.end < ctx.offset).length ??
219
- 0;
277
+ const numParamsBefore = node.children?.slice(1).filter((n) => n.range.end < ctx.offset).length
278
+ ?? 0;
220
279
  const mock = map[id][numParamsBefore];
221
280
  if (mock) {
222
281
  return completer.dispatch(mock, ctx);
@@ -234,7 +293,7 @@ const scoreHolder = (node, ctx) => {
234
293
  }
235
294
  else {
236
295
  ans = completer.symbol(node.fakeName ?? SymbolNode.mock(node, { category: 'score_holder' }), ctx);
237
- ans.push(...selector(EntitySelectorNode.mock(node), ctx));
296
+ ans.push(...selector(EntitySelectorNode.mock(node, { pool: EntitySelectorAtVariable.filterAvailable(ctx) }), ctx));
238
297
  }
239
298
  return ans;
240
299
  };
@@ -242,8 +301,7 @@ const selector = (node, ctx) => {
242
301
  if (Range.contains(node.children[0], ctx.offset, true)) {
243
302
  return completer.literal(node.children[0], ctx);
244
303
  }
245
- if (node.arguments &&
246
- Range.contains(Range.translate(node.arguments, 1, -1), ctx.offset, true)) {
304
+ if (node.arguments && Range.contains(Range.translate(node.arguments, 1, -1), ctx.offset, true)) {
247
305
  return selectorArguments(node.arguments, ctx);
248
306
  }
249
307
  return [];
@@ -255,16 +313,10 @@ const selectorArguments = (node, ctx) => {
255
313
  }
256
314
  return completer.record({
257
315
  key: (record, pair, _ctx, range, insertValue, insertComma) => {
258
- return [...EntitySelectorNode.ArgumentKeys]
259
- .filter((k) => EntitySelectorNode.canKeyExist(selector, record, k) ===
260
- 0 /* EntitySelectorNode.Result.Ok */)
261
- .map((k) => CompletionItem.create(k, range, {
316
+ return [...EntitySelectorNode.ArgumentKeys].filter((k) => EntitySelectorNode.canKeyExist(selector, record, k) === 0 /* EntitySelectorNode.Result.Ok */).map((k) => CompletionItem.create(k, range, {
262
317
  kind: 10 /* CompletionKind.Property */,
263
- insertText: new InsertTextBuilder()
264
- .literal(k)
265
- .if(insertValue, (b) => b.literal('=').placeholder()) // TODO
266
- .if(insertComma, (b) => b.literal(','))
267
- .build(),
318
+ insertText: new InsertTextBuilder().literal(k).if(insertValue, (b) => b.literal('=').placeholder()) // TODO
319
+ .if(insertComma, (b) => b.literal(',')).build(),
268
320
  }));
269
321
  },
270
322
  value: (_record, pair, ctx) => {
@@ -277,13 +329,13 @@ const selectorArguments = (node, ctx) => {
277
329
  };
278
330
  const intRange = (node, _ctx) => {
279
331
  return [
280
- CompletionItem.create('-2147483648..2147483647', node, {
281
- kind: 21 /* CompletionKind.Constant */,
282
- }),
332
+ CompletionItem.create('-2147483648..2147483647', node, { kind: 21 /* CompletionKind.Constant */ }),
283
333
  ];
284
334
  };
285
335
  const vector = (node, _ctx) => {
286
- const createCompletion = (coordinate, sortText) => CompletionItem.create(new Array(node.options.dimension).fill(coordinate).join(' '), node, { sortText });
336
+ const createCompletion = (coordinate, sortText) => CompletionItem.create(new Array(node.options.dimension).fill(coordinate).join(' '), node, {
337
+ sortText,
338
+ });
287
339
  const ans = [];
288
340
  ans.push(createCompletion('~', 'a'));
289
341
  if (!node.options.noLocal) {
@@ -294,11 +346,14 @@ const vector = (node, _ctx) => {
294
346
  };
295
347
  export function register(meta) {
296
348
  meta.registerCompleter('mcfunction:block', block);
349
+ meta.registerCompleter('mcfunction:component_list', componentList);
350
+ meta.registerCompleter('mcfunction:component_tests', componentTests);
297
351
  meta.registerCompleter('mcfunction:coordinate', coordinate);
298
352
  meta.registerCompleter('mcfunction:entity_selector', selector);
299
353
  meta.registerCompleter('mcfunction:entity_selector/arguments', selectorArguments);
300
354
  meta.registerCompleter('mcfunction:int_range', intRange);
301
- meta.registerCompleter('mcfunction:item', item);
355
+ meta.registerCompleter('mcfunction:item_stack', itemStack);
356
+ meta.registerCompleter('mcfunction:item_predicate', itemPredicate);
302
357
  meta.registerCompleter('mcfunction:objective_criteria', objectiveCriteria);
303
358
  meta.registerCompleter('mcfunction:particle', particle);
304
359
  meta.registerCompleter('mcfunction:score_holder', scoreHolder);
@@ -1,5 +1,6 @@
1
- import type * as core from '@spyglassmc/core';
2
- import type { McmetaCommands, ReleaseVersion } from '../dependency/index.js';
1
+ import * as core from '@spyglassmc/core';
2
+ import type { McmetaCommands } from '../dependency/index.js';
3
+ import { ReleaseVersion } from '../dependency/index.js';
3
4
  export * as checker from './checker/index.js';
4
5
  export * as colorizer from './colorizer/index.js';
5
6
  export * as completer from './completer/index.js';
@@ -1,11 +1,16 @@
1
+ import * as core from '@spyglassmc/core';
1
2
  import * as mcf from '@spyglassmc/mcfunction';
3
+ import { registerCustomResources } from '../binder/index.js';
4
+ import { ReleaseVersion } from '../dependency/index.js';
2
5
  import * as checker from './checker/index.js';
3
6
  import * as colorizer from './colorizer/index.js';
4
7
  import * as completer from './completer/index.js';
5
8
  import { inlayHintProvider } from './inlayHintProvider.js';
9
+ import { registerMcdocAttributes } from './mcdocAttributes.js';
6
10
  import * as parser from './parser/index.js';
7
11
  import { signatureHelpProvider } from './signatureHelpProvider.js';
8
12
  import { getPatch } from './tree/patch.js';
13
+ import { validatePatchedTree } from './tree/patchValidator.js';
9
14
  export * as checker from './checker/index.js';
10
15
  export * as colorizer from './colorizer/index.js';
11
16
  export * as completer from './completer/index.js';
@@ -13,36 +18,30 @@ export * as parser from './parser/index.js';
13
18
  /* istanbul ignore next */
14
19
  export const initialize = (ctx, commands, releaseVersion) => {
15
20
  const { meta } = ctx;
21
+ registerCustomResources(ctx.config);
22
+ const tree = core.merge(commands, getPatch(releaseVersion));
23
+ if (ctx.isDebugging) {
24
+ validatePatchedTree(tree, ctx.logger);
25
+ }
16
26
  mcf.initialize(ctx);
17
- mcf.CommandTreeRegistry.instance.register(releaseVersion, commands, getPatch(releaseVersion));
27
+ const supportsBackslashContinuation = ReleaseVersion.cmp(releaseVersion, '1.20.2') >= 0;
28
+ const supportsMacros = ReleaseVersion.cmp(releaseVersion, '1.20.2') >= 0;
18
29
  meta.registerLanguage('mcfunction', {
19
30
  extensions: ['.mcfunction'],
20
- parser: mcf.entry(releaseVersion, parser.argument),
21
- completer: mcf.completer.entry(releaseVersion, completer.getMockNodes),
22
- triggerCharacters: [
23
- ' ',
24
- '[',
25
- '=',
26
- '!',
27
- ',',
28
- '{',
29
- ':',
30
- '/',
31
- '.',
32
- '"',
33
- "'",
34
- ],
31
+ parser: mcf.entry(tree, parser.argument, { supportsBackslashContinuation, supportsMacros }),
32
+ completer: mcf.completer.entry(tree, completer.getMockNodes),
33
+ triggerCharacters: [' ', '[', '=', '!', ',', '{', ':', '/', '.', '"', "'"],
35
34
  });
36
35
  meta.registerParser('mcfunction:block_predicate', parser.blockPredicate);
37
- meta.registerParser('mcfunction:component', parser.component);
38
36
  meta.registerParser('mcfunction:particle', parser.particle);
39
37
  meta.registerParser('mcfunction:tag', parser.tag());
40
38
  meta.registerParser('mcfunction:team', parser.team());
41
- meta.registerParser('mcfunction:command', mcf.command(mcf.CommandTreeRegistry.instance.get(releaseVersion), parser.argument));
39
+ meta.registerParser('mcfunction:command', mcf.command(tree, parser.argument));
40
+ registerMcdocAttributes(meta, tree);
42
41
  checker.register(meta);
43
42
  colorizer.register(meta);
44
43
  completer.register(meta);
45
44
  meta.registerInlayHintProvider(inlayHintProvider);
46
- meta.registerSignatureHelpProvider(signatureHelpProvider(releaseVersion));
45
+ meta.registerSignatureHelpProvider(signatureHelpProvider(tree));
47
46
  };
48
47
  //# sourceMappingURL=index.js.map
@@ -8,9 +8,8 @@ export const inlayHintProvider = (node, ctx) => {
8
8
  core.traversePreOrder(node, (_) => true, mcf.CommandChildNode.is, (n) => {
9
9
  const node = n;
10
10
  const config = ctx.config.env.feature.inlayHint;
11
- if (config === true ||
12
- (typeof config === 'object' &&
13
- config.enabledNodes.includes(node.children[0].type))) {
11
+ if (config === true
12
+ || (typeof config === 'object' && config.enabledNodes.includes(node.children[0].type))) {
14
13
  ans.push({
15
14
  offset: node.range.start,
16
15
  label: `${node.path[node.path.length - 1]}:`,
@@ -0,0 +1,4 @@
1
+ import * as core from '@spyglassmc/core';
2
+ import * as mcf from '@spyglassmc/mcfunction';
3
+ export declare function registerMcdocAttributes(meta: core.MetaRegistry, rootTreeNode: mcf.RootTreeNode): void;
4
+ //# sourceMappingURL=mcdocAttributes.d.ts.map
@@ -0,0 +1,71 @@
1
+ import * as core from '@spyglassmc/core';
2
+ import * as json from '@spyglassmc/json';
3
+ import { localize } from '@spyglassmc/locales';
4
+ import * as mcdoc from '@spyglassmc/mcdoc';
5
+ import * as mcf from '@spyglassmc/mcfunction';
6
+ import { getItemSlotsArgumentValues } from './common/index.js';
7
+ import { EntitySelectorAtVariable, EntitySelectorNode, ScoreHolderNode } from './node/argument.js';
8
+ import * as parser from './parser/index.js';
9
+ const validator = mcdoc.runtime.attribute.validator;
10
+ const entityValidator = validator.alternatives(validator.tree({
11
+ amount: validator.options('multiple', 'single'),
12
+ type: validator.options('entities', 'players'),
13
+ }), () => ({ amount: 'multiple', type: 'entities' }));
14
+ export function registerMcdocAttributes(meta, rootTreeNode) {
15
+ mcdoc.runtime.registerAttribute(meta, 'command', () => undefined, {
16
+ // TODO: validate slash
17
+ // TODO: fix completer inside commands
18
+ stringParser: () => {
19
+ return mcf.command(rootTreeNode, parser.argument);
20
+ },
21
+ });
22
+ mcdoc.runtime.registerAttribute(meta, 'text_component', () => undefined, {
23
+ stringParser: () => makeInfallible(core.map(json.parser.entry, (res) => ({
24
+ type: 'json:typed',
25
+ range: res.range,
26
+ children: [res],
27
+ targetType: { kind: 'reference', path: '::java::server::util::text::Text' },
28
+ })), localize('text-component')),
29
+ });
30
+ mcdoc.runtime.registerAttribute(meta, 'objective', () => undefined, {
31
+ stringParser: () => parser.objective('reference'),
32
+ stringMocker: (_, __, ctx) => core.SymbolNode.mock(ctx.offset, { category: 'objective' }),
33
+ });
34
+ mcdoc.runtime.registerAttribute(meta, 'team', () => undefined, {
35
+ stringParser: () => parser.team('reference'),
36
+ stringMocker: (_, __, ctx) => core.SymbolNode.mock(ctx.offset, { category: 'team' }),
37
+ });
38
+ mcdoc.runtime.registerAttribute(meta, 'score_holder', () => undefined, {
39
+ stringParser: () => makeInfallible(parser.scoreHolder('reference', 'multiple'), localize('score-holder')),
40
+ stringMocker: (_, __, ctx) => ScoreHolderNode.mock(ctx.offset),
41
+ });
42
+ mcdoc.runtime.registerAttribute(meta, 'tag', () => undefined, {
43
+ stringParser: () => parser.tag('definition'), // TODO: make this a config
44
+ stringMocker: (_, __, ctx) => core.SymbolNode.mock(ctx.offset, { category: 'tag' }),
45
+ });
46
+ mcdoc.runtime.registerAttribute(meta, 'entity', entityValidator, {
47
+ stringParser: (config) => makeInfallible(parser.entity(config.amount, config.type), localize('selector')),
48
+ stringMocker: (_, __, ctx) => EntitySelectorNode.mock(ctx.offset, {
49
+ pool: EntitySelectorAtVariable.filterAvailable(ctx),
50
+ }),
51
+ });
52
+ mcdoc.runtime.registerAttribute(meta, 'item_slots', () => undefined, {
53
+ stringParser: () => parser.itemSlots,
54
+ stringMocker: (_, __, ctx) => core.LiteralNode.mock(ctx.offset, { pool: getItemSlotsArgumentValues(ctx) }),
55
+ });
56
+ mcdoc.runtime.registerAttribute(meta, 'uuid', () => undefined, {
57
+ stringParser: () => parser.uuid,
58
+ });
59
+ }
60
+ function makeInfallible(parser, message) {
61
+ return (src, ctx) => {
62
+ const start = src.cursor;
63
+ const res = parser(src, ctx);
64
+ if (res === core.Failure) {
65
+ ctx.err.report(localize('expected', message), core.Range.create(start, src.skipRemaining()));
66
+ return undefined;
67
+ }
68
+ return res;
69
+ };
70
+ }
71
+ //# sourceMappingURL=mcdocAttributes.js.map