@spyglassmc/java-edition 0.3.22 → 0.3.24

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.
@@ -5,7 +5,7 @@ export declare function dissectUri(uri: string, ctx: UriBinderContext): {
5
5
  identifier: string;
6
6
  expected: string | undefined;
7
7
  path: string;
8
- category: "function" | "advancement" | "banner_pattern" | "chat_type" | "damage_type" | "dimension" | "dimension_type" | "enchantment" | "enchantment_provider" | "instrument" | "item_modifier" | "jukebox_song" | "loot_table" | "painting_variant" | "predicate" | "recipe" | "structure" | "trial_spawner" | "trim_material" | "trim_pattern" | "wolf_variant" | "tag/function" | "tag/activity" | "tag/armor_material" | "tag/attribute" | "tag/block" | "tag/block_entity_type" | "tag/block_predicate_type" | "tag/block_type" | "tag/cat_variant" | "tag/chunk_status" | "tag/command_argument_type" | "tag/consume_effect_type" | "tag/creative_mode_tab" | "tag/custom_stat" | "tag/data_component_type" | "tag/decorated_pot_pattern" | "tag/decorated_pot_patterns" | "tag/enchantment_effect_component_type" | "tag/enchantment_entity_effect_type" | "tag/enchantment_level_based_value_type" | "tag/enchantment_location_based_effect_type" | "tag/enchantment_provider_type" | "tag/enchantment_value_effect_type" | "tag/entity_sub_predicate_type" | "tag/entity_type" | "tag/float_provider_type" | "tag/fluid" | "tag/frog_variant" | "tag/game_event" | "tag/height_provider_type" | "tag/instrument" | "tag/int_provider_type" | "tag/item" | "tag/item_sub_predicate_type" | "tag/loot_condition_type" | "tag/loot_function_type" | "tag/loot_nbt_provider_type" | "tag/loot_number_provider_type" | "tag/loot_pool_entry_type" | "tag/loot_score_provider_type" | "tag/map_decoration_type" | "tag/memory_module_type" | "tag/menu" | "tag/mob_effect" | "tag/motive" | "tag/number_format_type" | "tag/particle_type" | "tag/point_of_interest_type" | "tag/pos_rule_test" | "tag/position_source_type" | "tag/potion" | "tag/recipe_book_category" | "tag/recipe_display" | "tag/recipe_serializer" | "tag/recipe_type" | "tag/rule_block_entity_modifier" | "tag/rule_test" | "tag/schedule" | "tag/sensor_type" | "tag/slot_display" | "tag/sound_event" | "tag/stat_type" | "tag/trigger_type" | "tag/villager_profession" | "tag/villager_type" | "tag/worldgen/biome_source" | "tag/worldgen/block_placer_type" | "tag/worldgen/block_state_provider_type" | "tag/worldgen/carver" | "tag/worldgen/chunk_generator" | "tag/worldgen/decorator" | "tag/worldgen/density_function_type" | "tag/worldgen/feature" | "tag/worldgen/feature_size_type" | "tag/worldgen/foliage_placer_type" | "tag/worldgen/material_condition" | "tag/worldgen/material_rule" | "tag/worldgen/placement_modifier_type" | "tag/worldgen/pool_alias_binding" | "tag/worldgen/root_placer_type" | "tag/worldgen/structure_feature" | "tag/worldgen/structure_piece" | "tag/worldgen/structure_placement" | "tag/worldgen/structure_pool_element" | "tag/worldgen/structure_processor" | "tag/worldgen/structure_type" | "tag/worldgen/surface_builder" | "tag/worldgen/tree_decorator_type" | "tag/worldgen/trunk_placer_type" | "tag/advancement" | "tag/banner_pattern" | "tag/chat_type" | "tag/damage_type" | "tag/dimension" | "tag/dimension_type" | "tag/enchantment" | "tag/enchantment_provider" | "tag/item_modifier" | "tag/jukebox_song" | "tag/loot_table" | "tag/painting_variant" | "tag/predicate" | "tag/recipe" | "tag/structure" | "tag/trial_spawner" | "tag/trim_material" | "tag/trim_pattern" | "tag/wolf_variant" | "tag/worldgen/biome" | "tag/worldgen/configured_carver" | "tag/worldgen/configured_feature" | "tag/worldgen/configured_structure_feature" | "tag/worldgen/configured_surface_builder" | "tag/worldgen/density_function" | "tag/worldgen/flat_level_generator_preset" | "tag/worldgen/multi_noise_biome_source_parameter_list" | "tag/worldgen/noise" | "tag/worldgen/noise_settings" | "tag/worldgen/placed_feature" | "tag/worldgen/processor_list" | "tag/worldgen/structure" | "tag/worldgen/structure_set" | "tag/worldgen/template_pool" | "tag/worldgen/world_preset" | "worldgen/biome" | "worldgen/configured_carver" | "worldgen/configured_feature" | "worldgen/configured_structure_feature" | "worldgen/configured_surface_builder" | "worldgen/density_function" | "worldgen/flat_level_generator_preset" | "worldgen/multi_noise_biome_source_parameter_list" | "worldgen/noise" | "worldgen/noise_settings" | "worldgen/placed_feature" | "worldgen/processor_list" | "worldgen/structure" | "worldgen/structure_set" | "worldgen/template_pool" | "worldgen/world_preset" | "atlas" | "block_definition" | "equipment" | "font" | "font/ttf" | "font/otf" | "font/unihex" | "item_definition" | "lang" | "model" | "particle" | "post_effect" | "shader" | "shader/fragment" | "shader/vertex" | "sound" | "texture";
8
+ category: "function" | "advancement" | "banner_pattern" | "chat_type" | "damage_type" | "dimension" | "dimension_type" | "enchantment" | "enchantment_provider" | "instrument" | "item_modifier" | "jukebox_song" | "loot_table" | "painting_variant" | "predicate" | "recipe" | "structure" | "trial_spawner" | "trim_material" | "trim_pattern" | "wolf_variant" | "tag/function" | "tag/activity" | "tag/armor_material" | "tag/attribute" | "tag/block" | "tag/block_entity_type" | "tag/block_predicate_type" | "tag/block_type" | "tag/cat_variant" | "tag/chunk_status" | "tag/command_argument_type" | "tag/consume_effect_type" | "tag/creative_mode_tab" | "tag/custom_stat" | "tag/data_component_type" | "tag/decorated_pot_pattern" | "tag/decorated_pot_patterns" | "tag/enchantment_effect_component_type" | "tag/enchantment_entity_effect_type" | "tag/enchantment_level_based_value_type" | "tag/enchantment_location_based_effect_type" | "tag/enchantment_provider_type" | "tag/enchantment_value_effect_type" | "tag/entity_sub_predicate_type" | "tag/entity_type" | "tag/float_provider_type" | "tag/fluid" | "tag/frog_variant" | "tag/game_event" | "tag/height_provider_type" | "tag/instrument" | "tag/int_provider_type" | "tag/item" | "tag/item_sub_predicate_type" | "tag/loot_condition_type" | "tag/loot_function_type" | "tag/loot_nbt_provider_type" | "tag/loot_number_provider_type" | "tag/loot_pool_entry_type" | "tag/loot_score_provider_type" | "tag/map_decoration_type" | "tag/memory_module_type" | "tag/menu" | "tag/mob_effect" | "tag/motive" | "tag/number_format_type" | "tag/particle_type" | "tag/point_of_interest_type" | "tag/pos_rule_test" | "tag/position_source_type" | "tag/potion" | "tag/recipe_book_category" | "tag/recipe_display" | "tag/recipe_serializer" | "tag/recipe_type" | "tag/rule_block_entity_modifier" | "tag/rule_test" | "tag/schedule" | "tag/sensor_type" | "tag/slot_display" | "tag/sound_event" | "tag/stat_type" | "tag/trigger_type" | "tag/villager_profession" | "tag/villager_type" | "tag/worldgen/biome_source" | "tag/worldgen/block_placer_type" | "tag/worldgen/block_state_provider_type" | "tag/worldgen/carver" | "tag/worldgen/chunk_generator" | "tag/worldgen/decorator" | "tag/worldgen/density_function_type" | "tag/worldgen/feature" | "tag/worldgen/feature_size_type" | "tag/worldgen/foliage_placer_type" | "tag/worldgen/material_condition" | "tag/worldgen/material_rule" | "tag/worldgen/placement_modifier_type" | "tag/worldgen/pool_alias_binding" | "tag/worldgen/root_placer_type" | "tag/worldgen/structure_feature" | "tag/worldgen/structure_piece" | "tag/worldgen/structure_placement" | "tag/worldgen/structure_pool_element" | "tag/worldgen/structure_processor" | "tag/worldgen/structure_type" | "tag/worldgen/surface_builder" | "tag/worldgen/tree_decorator_type" | "tag/worldgen/trunk_placer_type" | "tag/advancement" | "tag/banner_pattern" | "tag/chat_type" | "tag/damage_type" | "tag/dimension" | "tag/dimension_type" | "tag/enchantment" | "tag/enchantment_provider" | "tag/item_modifier" | "tag/jukebox_song" | "tag/loot_table" | "tag/painting_variant" | "tag/predicate" | "tag/recipe" | "tag/structure" | "tag/trial_spawner" | "tag/trim_material" | "tag/trim_pattern" | "tag/wolf_variant" | "tag/worldgen/biome" | "tag/worldgen/configured_carver" | "tag/worldgen/configured_feature" | "tag/worldgen/configured_structure_feature" | "tag/worldgen/configured_surface_builder" | "tag/worldgen/density_function" | "tag/worldgen/flat_level_generator_preset" | "tag/worldgen/multi_noise_biome_source_parameter_list" | "tag/worldgen/noise" | "tag/worldgen/noise_settings" | "tag/worldgen/placed_feature" | "tag/worldgen/processor_list" | "tag/worldgen/structure" | "tag/worldgen/structure_set" | "tag/worldgen/template_pool" | "tag/worldgen/world_preset" | "worldgen/biome" | "worldgen/configured_carver" | "worldgen/configured_feature" | "worldgen/configured_structure_feature" | "worldgen/configured_surface_builder" | "worldgen/density_function" | "worldgen/flat_level_generator_preset" | "worldgen/multi_noise_biome_source_parameter_list" | "worldgen/noise" | "worldgen/noise_settings" | "worldgen/placed_feature" | "worldgen/processor_list" | "worldgen/structure" | "worldgen/structure_set" | "worldgen/template_pool" | "worldgen/world_preset" | "atlas" | "block_definition" | "equipment" | "font" | "font/ttf" | "font/otf" | "font/unihex" | "gpu_warnlist" | "item_definition" | "lang" | "lang/deprecated" | "model" | "particle" | "post_effect" | "regional_compliancies" | "shader" | "shader/fragment" | "shader/vertex" | "sound" | "sounds" | "texture" | "texture_meta";
9
9
  ext: `.${string}`;
10
10
  pack: "assets" | "data";
11
11
  since?: `1.${number}` | undefined;
@@ -96,13 +96,13 @@ for (const registry of TaggableResourceLocationCategories) {
96
96
  // Resource pack
97
97
  resource('atlases', { pack: 'assets', category: 'atlas', since: '1.19.3' });
98
98
  resource('blockstates', { pack: 'assets', category: 'block_definition' });
99
- resource('equipment', { pack: 'assets', category: 'equipment', since: '1.21.4' });
100
- resource('font', { pack: 'assets', category: 'font', since: '1.16' });
99
+ resource('equipment', { pack: 'assets', since: '1.21.4' });
100
+ resource('font', { pack: 'assets', since: '1.16' });
101
101
  resource('font', { pack: 'assets', category: 'font/ttf', since: '1.16', ext: '.ttf' });
102
102
  resource('font', { pack: 'assets', category: 'font/otf', since: '1.16', ext: '.otf' });
103
103
  resource('font', { pack: 'assets', category: 'font/unihex', since: '1.20', ext: '.zip' });
104
104
  resource('items', { pack: 'assets', category: 'item_definition', since: '1.21.4' });
105
- resource('lang', { pack: 'assets', category: 'lang' });
105
+ resource('lang', { pack: 'assets' });
106
106
  resource('models', { pack: 'assets', category: 'model' });
107
107
  resource('models/equipment', {
108
108
  pack: 'assets',
@@ -118,6 +118,15 @@ resource('shaders', { pack: 'assets', category: 'shader/fragment', ext: '.fsh' }
118
118
  resource('shaders', { pack: 'assets', category: 'shader/vertex', ext: '.vsh' });
119
119
  resource('sounds', { pack: 'assets', category: 'sound', ext: '.ogg' });
120
120
  resource('textures', { pack: 'assets', category: 'texture', ext: '.png' });
121
+ resource('textures', { pack: 'assets', category: 'texture_meta', ext: '.png.mcmeta' });
122
+ resource('lang', { pack: 'assets', category: 'lang/deprecated', identifier: 'deprecated' });
123
+ resource('', { pack: 'assets', category: 'sounds', identifier: 'sounds' });
124
+ resource('', {
125
+ pack: 'assets',
126
+ category: 'regional_compliancies',
127
+ identifier: 'regional_compliancies',
128
+ });
129
+ resource('', { pack: 'assets', category: 'gpu_warnlist', identifier: 'gpu_warnlist' });
121
130
  export function* getRels(uri, rootUris) {
122
131
  yield* fileUtil.getRels(uri, rootUris);
123
132
  const parts = uri.split('/');
@@ -136,7 +145,7 @@ export function dissectUri(uri, ctx) {
136
145
  }
137
146
  for (const rel of rels) {
138
147
  const parts = rel.split('/');
139
- if (parts.length < 4) {
148
+ if (parts.length < 3) {
140
149
  continue;
141
150
  }
142
151
  const [pack, namespace, ...rest] = parts;
@@ -144,6 +153,23 @@ export function dissectUri(uri, ctx) {
144
153
  continue;
145
154
  }
146
155
  const candidateResources = [];
156
+ if (rest.length === 1) {
157
+ const resources = Resources.get('');
158
+ for (const res of resources ?? []) {
159
+ if (res.pack !== pack) {
160
+ continue;
161
+ }
162
+ let identifier = rest[0];
163
+ if (!identifier.endsWith(res.ext)) {
164
+ continue;
165
+ }
166
+ identifier = identifier.slice(0, -res.ext.length);
167
+ if (res.identifier && identifier !== res.identifier) {
168
+ continue;
169
+ }
170
+ candidateResources.push([res, identifier]);
171
+ }
172
+ }
147
173
  for (let i = 1; i < rest.length; i += 1) {
148
174
  const resources = Resources.get(rest.slice(0, i).join('/'));
149
175
  for (const res of resources ?? []) {
@@ -155,6 +181,9 @@ export function dissectUri(uri, ctx) {
155
181
  continue;
156
182
  }
157
183
  identifier = identifier.slice(0, -res.ext.length);
184
+ if (res.identifier && identifier !== res.identifier) {
185
+ continue;
186
+ }
158
187
  candidateResources.push([res, identifier]);
159
188
  }
160
189
  }
@@ -196,9 +225,7 @@ export const uriBinder = (uris, ctx) => {
196
225
  };
197
226
  export function registerCustomResources(config) {
198
227
  for (const [path, res] of Object.entries(config.env.customResources)) {
199
- if (res.pack === undefined || res.pack === 'data') {
200
- resource(path, { ...res, category: res.category });
201
- }
228
+ resource(path, { ...res, category: res.category });
202
229
  }
203
230
  }
204
231
  function matchVersion(target, since, until) {
@@ -207,8 +207,10 @@ export function symbolRegistrar(summary, release) {
207
207
  }
208
208
  symbols.query(McmetaSummaryUri, 'model', 'minecraft:builtin/generated')
209
209
  .enter({ usage: { type: 'declaration' } });
210
- symbols.query(McmetaSummaryUri, 'model', 'minecraft:builtin/entity')
211
- .enter({ usage: { type: 'declaration' } });
210
+ if (ReleaseVersion.cmp(release, '1.21.4') < 0) {
211
+ symbols.query(McmetaSummaryUri, 'model', 'minecraft:builtin/entity')
212
+ .enter({ usage: { type: 'declaration' } });
213
+ }
212
214
  }
213
215
  return (symbols) => {
214
216
  addRegistriesSymbols(summary.registries, symbols);
@@ -0,0 +1,3 @@
1
+ import * as core from '@spyglassmc/core';
2
+ export declare function register(meta: core.MetaRegistry): void;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,47 @@
1
+ import * as core from '@spyglassmc/core';
2
+ import * as json from '@spyglassmc/json';
3
+ function bindDeprecated(node, ctx) {
4
+ const renamed = node.children.find(p => p.key?.value === 'renamed')?.value;
5
+ if (json.JsonObjectNode.is(renamed)) {
6
+ for (const pair of renamed.children) {
7
+ if (json.JsonStringNode.is(pair.value)) {
8
+ const range = core.Range.translate(pair.value.range, 1, -1);
9
+ ctx.symbols.query(ctx.doc, 'translation_key', pair.value.value)
10
+ .enter({
11
+ usage: { type: 'definition', range, fullRange: pair },
12
+ });
13
+ }
14
+ }
15
+ }
16
+ }
17
+ function bindLanguage(node, ctx) {
18
+ const isEnglish = ctx.doc.uri.endsWith('/en_us.json');
19
+ for (const pair of node.children) {
20
+ if (pair.key) {
21
+ const desc = json.JsonStringNode.is(pair.value) ? pair.value.value : undefined;
22
+ const range = core.Range.translate(pair.key.range, 1, -1);
23
+ ctx.symbols.query(ctx.doc, 'translation_key', pair.key.value)
24
+ .enter({
25
+ data: { desc: isEnglish ? desc : undefined },
26
+ usage: { type: 'definition', range, fullRange: pair },
27
+ });
28
+ }
29
+ }
30
+ }
31
+ const file = (node, ctx) => {
32
+ if (ctx.doc.uri.match(/\/lang\/[a-z_]+.json$/)) {
33
+ const child = node.children[0];
34
+ if (json.JsonObjectNode.is(child)) {
35
+ if (ctx.doc.uri.endsWith('/deprecated.json')) {
36
+ bindDeprecated(child, ctx);
37
+ }
38
+ else {
39
+ bindLanguage(child, ctx);
40
+ }
41
+ }
42
+ }
43
+ };
44
+ export function register(meta) {
45
+ meta.registerBinder('json:file', file);
46
+ }
47
+ //# sourceMappingURL=index.js.map
@@ -22,7 +22,7 @@ export const file = (node, ctx) => {
22
22
  }
23
23
  const parts = dissectUri(ctx.doc.uri, ctx);
24
24
  if (parts?.ok) {
25
- if (parts?.category.startsWith('tag/')) {
25
+ if (parts.category.startsWith('tag/')) {
26
26
  const type = createTagDefinition(parts.category.slice(4));
27
27
  return json.checker.index(type)(child, ctx);
28
28
  }
@@ -0,0 +1,3 @@
1
+ import * as core from '@spyglassmc/core';
2
+ export declare function register(meta: core.MetaRegistry): void;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,25 @@
1
+ import * as core from '@spyglassmc/core';
2
+ const textureSlot = (node, ctx) => {
3
+ const slot = node.slot ?? core.SymbolNode.mock(node, {
4
+ category: 'texture_slot',
5
+ usageType: node.kind === 'definition' ? 'definition' : 'reference',
6
+ });
7
+ const slotItems = core.completer.symbol(slot, ctx);
8
+ if (node.kind === 'definition') {
9
+ return slotItems;
10
+ }
11
+ if (node.kind === 'reference') {
12
+ return slotItems.map(item => ({
13
+ ...item,
14
+ range: node.range,
15
+ label: '#' + item.label,
16
+ insertText: '#' + (item.insertText ?? item.label),
17
+ }));
18
+ }
19
+ const id = node.id ?? core.ResourceLocationNode.mock(node, { category: 'texture' });
20
+ return core.completer.resourceLocation(id, ctx);
21
+ };
22
+ export function register(meta) {
23
+ meta.registerCompleter('java_edition:texture_slot', textureSlot);
24
+ }
25
+ //# sourceMappingURL=index.js.map
package/lib/json/index.js CHANGED
@@ -1,8 +1,12 @@
1
1
  /* istanbul ignore file */
2
+ import * as binder from './binder/index.js';
2
3
  import * as checker from './checker/index.js';
4
+ import * as completer from './completer/index.js';
3
5
  import { registerMcdocAttributes } from './mcdocAttributes.js';
4
6
  export const initialize = (ctx) => {
5
7
  registerMcdocAttributes(ctx.meta);
8
+ binder.register(ctx.meta);
6
9
  checker.register(ctx.meta);
10
+ completer.register(ctx.meta);
7
11
  };
8
12
  //# sourceMappingURL=index.js.map
@@ -1,10 +1,17 @@
1
1
  import * as core from '@spyglassmc/core';
2
2
  import * as mcdoc from '@spyglassmc/mcdoc';
3
3
  import { dissectUri } from '../binder/index.js';
4
+ import { textureSlotParser, translationValueParser } from './parser/index.js';
4
5
  const validator = mcdoc.runtime.attribute.validator;
5
6
  const criterionValidator = validator.alternatives(validator.tree({
6
7
  definition: validator.boolean,
7
8
  }), () => ({ definition: false }));
9
+ const textureSlotValidator = validator.alternatives(validator.tree({
10
+ kind: validator.options('definition', 'value', 'reference'),
11
+ }), () => ({ kind: 'value' }));
12
+ const translationKeyValidator = validator.alternatives(validator.tree({
13
+ definition: validator.boolean,
14
+ }), () => ({ definition: false }));
8
15
  export function registerMcdocAttributes(meta) {
9
16
  mcdoc.runtime.registerAttribute(meta, 'criterion', criterionValidator, {
10
17
  stringParser: (config, _, ctx) => {
@@ -31,5 +38,35 @@ export function registerMcdocAttributes(meta) {
31
38
  });
32
39
  },
33
40
  });
41
+ mcdoc.runtime.registerAttribute(meta, 'texture_slot', textureSlotValidator, {
42
+ stringParser: (config, _, ctx) => {
43
+ return textureSlotParser(config.kind);
44
+ },
45
+ stringMocker: (config, _, ctx) => {
46
+ return {
47
+ type: 'java_edition:texture_slot',
48
+ range: core.Range.create(ctx.offset),
49
+ kind: config.kind,
50
+ children: [],
51
+ };
52
+ },
53
+ });
54
+ mcdoc.runtime.registerAttribute(meta, 'translation_key', translationKeyValidator, {
55
+ stringParser: (config, _, ctx) => {
56
+ return core.symbol({
57
+ category: 'translation_key',
58
+ usageType: config.definition ? 'definition' : 'reference',
59
+ });
60
+ },
61
+ stringMocker: (config, _, ctx) => {
62
+ return core.SymbolNode.mock(ctx.offset, {
63
+ category: 'translation_key',
64
+ usageType: config.definition ? 'definition' : 'reference',
65
+ });
66
+ },
67
+ });
68
+ mcdoc.runtime.registerAttribute(meta, 'translation_value', () => undefined, {
69
+ stringParser: () => translationValueParser,
70
+ });
34
71
  }
35
72
  //# sourceMappingURL=mcdocAttributes.js.map
@@ -0,0 +1,21 @@
1
+ import type * as core from '@spyglassmc/core';
2
+ export type TextureSlotKind = 'definition' | 'value' | 'reference';
3
+ export interface TextureSlotNode extends core.AstNode {
4
+ type: 'java_edition:texture_slot';
5
+ kind: TextureSlotKind;
6
+ children: (core.LiteralNode | core.SymbolNode | core.ResourceLocationNode)[];
7
+ slot?: core.SymbolNode;
8
+ id?: core.ResourceLocationNode;
9
+ }
10
+ export declare namespace TextureSlotNode {
11
+ function is(node: core.AstNode): node is TextureSlotNode;
12
+ }
13
+ export interface TranslationValueNode extends core.AstNode {
14
+ type: 'java_edition:translation_value';
15
+ children: core.LiteralNode[];
16
+ value: string;
17
+ }
18
+ export declare namespace TranslationValueNode {
19
+ function is(node: core.AstNode): node is TranslationValueNode;
20
+ }
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,15 @@
1
+ export var TextureSlotNode;
2
+ (function (TextureSlotNode) {
3
+ function is(node) {
4
+ return node?.type === 'java_edition:texture_slot';
5
+ }
6
+ TextureSlotNode.is = is;
7
+ })(TextureSlotNode || (TextureSlotNode = {}));
8
+ export var TranslationValueNode;
9
+ (function (TranslationValueNode) {
10
+ function is(node) {
11
+ return node?.type === 'java_edition:translation_value';
12
+ }
13
+ TranslationValueNode.is = is;
14
+ })(TranslationValueNode || (TranslationValueNode = {}));
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,5 @@
1
+ import * as core from '@spyglassmc/core';
2
+ import type { TextureSlotKind, TextureSlotNode, TranslationValueNode } from '../node/index.js';
3
+ export declare function textureSlotParser(kind: TextureSlotKind): core.InfallibleParser<TextureSlotNode>;
4
+ export declare const translationValueParser: core.InfallibleParser<TranslationValueNode>;
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,81 @@
1
+ import * as core from '@spyglassmc/core';
2
+ import { localeQuote, localize } from '@spyglassmc/locales';
3
+ export function textureSlotParser(kind) {
4
+ return (src, ctx) => {
5
+ const start = src.cursor;
6
+ const ans = {
7
+ type: 'java_edition:texture_slot',
8
+ range: core.Range.create(start),
9
+ kind,
10
+ children: [],
11
+ };
12
+ if (kind === 'definition') {
13
+ const slot = core.symbol({ category: 'texture_slot', usageType: 'definition' })(src, ctx);
14
+ ans.children.push(slot);
15
+ ans.slot = slot;
16
+ }
17
+ else if (src.tryPeek('#')) {
18
+ ans.children.push(core.literal('#')(src, ctx));
19
+ const slot = core.symbol({ category: 'texture_slot', usageType: 'reference' })(src, ctx);
20
+ ans.children.push(slot);
21
+ ans.slot = slot;
22
+ }
23
+ else if (kind === 'reference') {
24
+ ctx.err.report(localize('expected', localeQuote('#')), src);
25
+ }
26
+ else {
27
+ const id = core.resourceLocation({ category: 'texture', usageType: 'reference' })(src, ctx);
28
+ ans.children.push(id);
29
+ ans.id = id;
30
+ }
31
+ ans.range = core.Range.create(start, src);
32
+ return ans;
33
+ };
34
+ }
35
+ export const translationValueParser = (src, ctx) => {
36
+ const start = src.cursor;
37
+ const ans = {
38
+ type: 'java_edition:translation_value',
39
+ range: core.Range.create(start),
40
+ children: [],
41
+ value: '',
42
+ };
43
+ while (src.canRead()) {
44
+ src.skipUntilOrEnd('%');
45
+ const argStart = src.cursor;
46
+ if (src.trySkip('%')) {
47
+ if (src.trySkip('%')) {
48
+ const token = src.sliceToCursor(argStart);
49
+ ans.children.push({
50
+ type: 'literal',
51
+ range: core.Range.create(argStart, src),
52
+ options: { pool: [token], colorTokenType: 'escape' },
53
+ value: token,
54
+ });
55
+ continue;
56
+ }
57
+ let hasInteger = false;
58
+ while (src.canRead() && core.Source.isDigit(src.peek())) {
59
+ src.skip();
60
+ hasInteger = true;
61
+ }
62
+ if (hasInteger && !src.trySkip('$')) {
63
+ ctx.err.report(localize('expected', localeQuote('$')), src);
64
+ }
65
+ if (!src.trySkip('s')) {
66
+ ctx.err.report(localize('expected', localeQuote('s')), src);
67
+ }
68
+ const token = src.sliceToCursor(argStart);
69
+ ans.children.push({
70
+ type: 'literal',
71
+ range: core.Range.create(argStart, src),
72
+ options: { pool: [token] },
73
+ value: token,
74
+ });
75
+ }
76
+ }
77
+ ans.value = src.sliceToCursor(start);
78
+ ans.range = core.Range.create(start, src);
79
+ return ans;
80
+ };
81
+ //# sourceMappingURL=index.js.map
@@ -318,7 +318,7 @@ const scoreHolder = (node, ctx) => {
318
318
  }
319
319
  else {
320
320
  ans = completer.symbol(node.fakeName ?? SymbolNode.mock(node, { category: 'score_holder' }), ctx);
321
- ans.push(...selector(EntitySelectorNode.mock(node, { pool: EntitySelectorAtVariable.filterAvailable(ctx) }), ctx));
321
+ ans.push(...completer.literal(LiteralNode.mock(node, { pool: ['*'] }), ctx), ...selector(EntitySelectorNode.mock(node, { pool: EntitySelectorAtVariable.filterAvailable(ctx) }), ctx));
322
322
  }
323
323
  return ans;
324
324
  };
@@ -71,7 +71,7 @@ export function registerMcdocAttributes(meta, rootTreeNode) {
71
71
  }),
72
72
  });
73
73
  mcdoc.runtime.registerAttribute(meta, 'item_slots', () => undefined, {
74
- stringParser: () => parser.itemSlots,
74
+ stringParser: (_, __, ctx) => core.literal({ pool: getItemSlotsArgumentValues(ctx) }),
75
75
  stringMocker: (_, __, ctx) => core.LiteralNode.mock(ctx.offset, { pool: getItemSlotsArgumentValues(ctx) }),
76
76
  });
77
77
  mcdoc.runtime.registerAttribute(meta, 'uuid', () => undefined, {
@@ -61,14 +61,14 @@ export type EntitySelectorVariable = typeof EntitySelectorVariables[number];
61
61
  export declare namespace EntitySelectorVariable {
62
62
  function is(value: string): value is EntitySelectorVariable;
63
63
  }
64
- declare const EntitySelectorAtVariables: ("@a" | "@e" | "@p" | "@r" | "@s" | "@n")[];
64
+ declare const EntitySelectorAtVariables: ("@s" | "@a" | "@e" | "@p" | "@r" | "@n")[];
65
65
  export type EntitySelectorAtVariable = typeof EntitySelectorAtVariables[number];
66
66
  export declare namespace EntitySelectorAtVariable {
67
67
  function is(value: string): value is EntitySelectorAtVariable;
68
68
  /**
69
69
  * Should be used to get a list of available selectors for the current version.
70
70
  */
71
- function filterAvailable(ctx: core.ContextBase): ("@a" | "@e" | "@p" | "@r" | "@s" | "@n")[];
71
+ function filterAvailable(ctx: core.ContextBase): ("@s" | "@a" | "@e" | "@p" | "@r" | "@n")[];
72
72
  }
73
73
  export interface EntitySelectorNode extends core.AstNode {
74
74
  type: 'mcfunction:entity_selector';
@@ -11,7 +11,6 @@ export declare const argument: mcf.ArgumentParserGetter;
11
11
  export declare const blockPredicate: core.InfallibleParser<BlockNode>;
12
12
  export declare function criterion(advancement: core.FullResourceLocation, usageType?: core.SymbolUsageType, terminators?: string[]): core.InfallibleParser<core.SymbolNode>;
13
13
  export declare function entity(amount: 'multiple' | 'single', type: 'entities' | 'players'): core.Parser<EntityNode>;
14
- export declare const itemSlots: core.InfallibleParser<core.LiteralNode>;
15
14
  export declare function jsonParser(typeRef: `::${string}::${string}`): core.Parser<json.TypedJsonNode>;
16
15
  export declare const particle: core.InfallibleParser<ParticleNode>;
17
16
  /**
@@ -78,7 +78,7 @@ export const argument = (rawTreeNode, prevNodes) => {
78
78
  case 'minecraft:block_state':
79
79
  return wrap(blockState);
80
80
  case 'minecraft:color':
81
- return wrap(core.map(core.literal(...ColorArgumentValues), (res) => ({
81
+ return wrap(core.map(commandLiteral({ pool: ColorArgumentValues }), (res) => ({
82
82
  ...res,
83
83
  color: core.Color.NamedColors.has(res.value)
84
84
  ? core.Color.fromCompositeRGB(core.Color.NamedColors.get(res.value))
@@ -93,7 +93,7 @@ export const argument = (rawTreeNode, prevNodes) => {
93
93
  case 'minecraft:entity':
94
94
  return wrap(entity(treeNode.properties.amount, treeNode.properties.type));
95
95
  case 'minecraft:entity_anchor':
96
- return wrap(core.literal(...EntityAnchorArgumentValues));
96
+ return wrap(commandLiteral({ pool: EntityAnchorArgumentValues }));
97
97
  case 'minecraft:entity_summon':
98
98
  return wrap(core.resourceLocation({ category: 'entity_type' }));
99
99
  case 'minecraft:float_range':
@@ -101,11 +101,11 @@ export const argument = (rawTreeNode, prevNodes) => {
101
101
  case 'minecraft:function':
102
102
  return wrap(core.resourceLocation({ category: 'function', allowTag: true }));
103
103
  case 'minecraft:gamemode':
104
- return wrap(core.literal(...GamemodeArgumentValues));
104
+ return wrap(commandLiteral({ pool: GamemodeArgumentValues }));
105
105
  case 'minecraft:game_profile':
106
106
  return wrap(entity('multiple', 'players'));
107
107
  case 'minecraft:heightmap':
108
- return wrap(core.literal(...HeightmapValues));
108
+ return wrap(commandLiteral({ pool: HeightmapValues }));
109
109
  case 'minecraft:int_range':
110
110
  return wrap(range('integer', treeNode.properties?.min, treeNode.properties?.max, treeNode.properties?.minSpan, treeNode.properties?.maxSpan));
111
111
  case 'minecraft:item_enchantment':
@@ -113,9 +113,13 @@ export const argument = (rawTreeNode, prevNodes) => {
113
113
  case 'minecraft:item_predicate':
114
114
  return wrap(itemPredicate);
115
115
  case 'minecraft:item_slot':
116
- return wrap(itemSlot);
116
+ return wrap((src, ctx) => {
117
+ return commandLiteral({ pool: getItemSlotArgumentValues(ctx) })(src, ctx);
118
+ });
117
119
  case 'minecraft:item_slots':
118
- return wrap(itemSlots);
120
+ return wrap((src, ctx) => {
121
+ return commandLiteral({ pool: getItemSlotsArgumentValues(ctx) })(src, ctx);
122
+ });
119
123
  case 'minecraft:item_stack':
120
124
  return wrap(itemStack);
121
125
  case 'minecraft:loot_modifier':
@@ -141,7 +145,7 @@ export const argument = (rawTreeNode, prevNodes) => {
141
145
  case 'minecraft:objective_criteria':
142
146
  return wrap(objectiveCriteria);
143
147
  case 'minecraft:operation':
144
- return wrap(core.literal({ pool: OperationArgumentValues, colorTokenType: 'operator' }));
148
+ return wrap(commandLiteral({ pool: OperationArgumentValues, colorTokenType: 'operator' }));
145
149
  case 'minecraft:particle':
146
150
  return wrap(particle);
147
151
  case 'minecraft:resource':
@@ -164,20 +168,20 @@ export const argument = (rawTreeNode, prevNodes) => {
164
168
  // `BELOWNAME` and `sidebar.team.r--.+++e----__d` are also legal slots.
165
169
  // But I do not want to spend time supporting them.
166
170
  return wrap((src, ctx) => {
167
- return core.literal(...getScoreboardSlotArgumentValues(ctx))(src, ctx);
171
+ return commandLiteral({ pool: getScoreboardSlotArgumentValues(ctx) })(src, ctx);
168
172
  });
169
173
  case 'minecraft:style':
170
174
  return wrap(jsonParser('::java::server::util::text::TextStyle'));
171
175
  case 'minecraft:swizzle':
172
- return wrap(core.literal(...SwizzleArgumentValues));
176
+ return wrap(commandLiteral({ pool: SwizzleArgumentValues }));
173
177
  case 'minecraft:team':
174
178
  return wrap(team(core.SymbolUsageType.is(treeNode.properties?.usageType)
175
179
  ? treeNode.properties?.usageType
176
180
  : undefined));
177
181
  case 'minecraft:template_mirror':
178
- return wrap(core.literal(...MirrorValues));
182
+ return wrap(commandLiteral({ pool: MirrorValues }));
179
183
  case 'minecraft:template_rotation':
180
- return wrap(core.literal(...RotationValues));
184
+ return wrap(commandLiteral({ pool: RotationValues }));
181
185
  case 'minecraft:time':
182
186
  return wrap(time);
183
187
  case 'minecraft:uuid':
@@ -310,12 +314,6 @@ export function entity(amount, type) {
310
314
  const greedyString = core.string({
311
315
  unquotable: { blockList: new Set(['\n', '\r']) },
312
316
  });
313
- const itemSlot = (src, ctx) => {
314
- return core.literal(...getItemSlotArgumentValues(ctx))(src, ctx);
315
- };
316
- export const itemSlots = (src, ctx) => {
317
- return core.literal(...getItemSlotsArgumentValues(ctx))(src, ctx);
318
- };
319
317
  const itemStack = (src, ctx) => {
320
318
  const oldFormat = shouldUseOldItemStackFormat(ctx);
321
319
  return core.map(core.sequence([
@@ -368,6 +366,16 @@ export function jsonParser(typeRef) {
368
366
  targetType: { kind: 'reference', path: typeRef },
369
367
  }));
370
368
  }
369
+ function commandLiteral(options) {
370
+ return (src, ctx) => {
371
+ const ans = core.literal(options)(src, ctx);
372
+ if (ans.value.length === 0) {
373
+ ans.value = src.readUntil(...core.Whitespaces);
374
+ ans.range = core.Range.create(ans.range.start, src);
375
+ }
376
+ return ans;
377
+ };
378
+ }
371
379
  const message = (src, ctx) => {
372
380
  const ans = {
373
381
  type: 'mcfunction:message',
@@ -895,8 +903,11 @@ export function scoreHolderFakeName(usageType) {
895
903
  }
896
904
  export function scoreHolder(usageType, amount) {
897
905
  return core.map(core.select([
898
- // Technically score holders can start with *, but this doesn't account for it
899
- { prefix: '*', parser: core.literal('*') },
906
+ {
907
+ predicate: (src) => src.peek() === '*'
908
+ && (!src.canRead(2) || src.matchPattern(/^\s/, 1)),
909
+ parser: core.literal('*'),
910
+ },
900
911
  { prefix: '@', parser: selector() },
901
912
  { parser: scoreHolderFakeName(usageType) },
902
913
  ]), (res, _src, ctx) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spyglassmc/java-edition",
3
- "version": "0.3.22",
3
+ "version": "0.3.24",
4
4
  "type": "module",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -17,12 +17,12 @@
17
17
  "release:dry": "npm publish --dry-run"
18
18
  },
19
19
  "dependencies": {
20
- "@spyglassmc/core": "0.4.16",
21
- "@spyglassmc/json": "0.3.19",
20
+ "@spyglassmc/core": "0.4.18",
21
+ "@spyglassmc/json": "0.3.21",
22
22
  "@spyglassmc/locales": "0.3.10",
23
- "@spyglassmc/mcfunction": "0.2.18",
24
- "@spyglassmc/mcdoc": "0.3.20",
25
- "@spyglassmc/nbt": "0.3.20"
23
+ "@spyglassmc/mcfunction": "0.2.20",
24
+ "@spyglassmc/mcdoc": "0.3.22",
25
+ "@spyglassmc/nbt": "0.3.22"
26
26
  },
27
27
  "devDependencies": {
28
28
  "fast-glob": "^3.2.5"