Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Add support for item components #1131

Merged
merged 28 commits into from
Jun 15, 2024
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
52740d3
begin work
Trivaxy May 11, 2024
dc6c238
potentially fix error
Trivaxy May 11, 2024
bd7d1a6
make ParticleNode refer to ItemNode
Trivaxy May 11, 2024
6c8fdff
Rudimentary item component syntax support
Trivaxy May 12, 2024
3e0f112
✨ Implement various command parsers and tree patch changes (#1128)
misode May 12, 2024
4e05d80
fix `ItemOldNode.is` and `ItemNewNode.is`
Trivaxy May 13, 2024
797cfdf
report error when duplicate components are defined
Trivaxy May 13, 2024
ea2a2cb
make duplicate components error localize properly
Trivaxy May 13, 2024
6f975f3
make error for duplicate components consistent
Trivaxy May 13, 2024
e51dad1
make error reporting for duplicates smarter
Trivaxy May 13, 2024
0b3af75
rename `item_old` and `item_new`
Trivaxy May 13, 2024
27c395a
(very buggy) new item predicate syntax
Trivaxy May 17, 2024
4697366
undo changes to `list.ts`
Trivaxy May 17, 2024
e4bd254
Merge branch 'main' into pr/Trivaxy/1131-1
misode May 30, 2024
11a5537
Implement a few of SPGoding's suggestions
misode May 30, 2024
a5752fd
Refactor nodes to separate item stack and predicate instead of old an…
misode May 30, 2024
05f1010
Remove unused function
misode May 30, 2024
6ed3a53
Update snapshots
misode May 30, 2024
28be8e5
Use correct symbol categories + change duplicate check
misode May 30, 2024
3d8f860
Start of completers
misode May 30, 2024
a6d7d51
Refactor component test parser
misode May 30, 2024
8612a2e
fix equality component tests only expecting compounds
Trivaxy Jun 15, 2024
0b89a61
finish item predicates
Trivaxy Jun 15, 2024
89cdf23
Merge remote-tracking branch 'upstream/main' into item-components
Trivaxy Jun 15, 2024
e6f6a5d
fix weird merge
Trivaxy Jun 15, 2024
f0077d7
fix linting
Trivaxy Jun 15, 2024
5cfdfa1
return component test nodes to being infallible
Trivaxy Jun 15, 2024
3be2227
... fix lint. i forgot to make this automatic
Trivaxy Jun 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/core/src/parser/resourceLocation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const Terminators = new Set([
'\r',
'\n',
'=',
'~',
',',
'"',
"'",
Expand All @@ -24,6 +25,7 @@ const Terminators = new Set([
'(',
')',
';',
'|',
])
export const LegalResourceLocationCharacters = new Set([
'a',
Expand Down
51 changes: 40 additions & 11 deletions packages/java-edition/src/mcfunction/checker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { EntitySelectorInvertableArgumentValueNode } from '../node/index.js
import {
BlockNode,
EntityNode,
ItemNode,
ItemStackNode,
JsonNode,
NbtNode,
NbtResourceNode,
Expand Down Expand Up @@ -40,8 +40,8 @@ const rootCommand = (
block(node, ctx)
} else if (EntityNode.is(node)) {
entity(node, ctx)
} else if (ItemNode.is(node)) {
item(node, ctx)
} else if (ItemStackNode.is(node)) {
itemStack(node, ctx)
} else if (ParticleNode.is(node)) {
particle(node, ctx)
} else if (JsonNode.is(node)) {
Expand Down Expand Up @@ -81,15 +81,44 @@ const entity: core.SyncChecker<EntityNode> = (node, ctx) => {
}
}

const item: core.SyncChecker<ItemNode> = (node, ctx) => {
if (!node.nbt) {
return
const itemStack: core.SyncChecker<ItemStackNode> = (node, ctx) => {
if (node.nbt) {
nbt.checker.index(
'minecraft:item',
core.ResourceLocationNode.toString(node.id, 'full'),
)(node.nbt, ctx)
}
if (node.components) {
const groupedComponents = new Map<
string,
core.PairNode<core.ResourceLocationNode, nbt.NbtNode>[]
>()

nbt.checker.index(
'minecraft:item',
core.ResourceLocationNode.toString(node.id, 'full'),
)(node.nbt, ctx)
node.components!.children.forEach(component => {
const componentName = core.ResourceLocationNode.toString(
component.key!,
'full',
)

if (!groupedComponents.has(componentName)) {
groupedComponents.set(componentName, [])
}

groupedComponents.get(componentName)!.push(component)
})

groupedComponents.forEach((components) => {
if (components.length > 1) {
components.forEach(component => {
ctx.err.report(
localize('mcfunction.parser.duplicate-components'),
component.key!.range,
core.ErrorSeverity.Warning,
)
})
}
})
}
}

const jsonChecker: core.SyncChecker<JsonNode> = (node, ctx) => {
Expand Down Expand Up @@ -215,7 +244,7 @@ export function register(meta: core.MetaRegistry) {
meta.registerChecker<mcf.CommandNode>('mcfunction:command', command)
meta.registerChecker<BlockNode>('mcfunction:block', block)
meta.registerChecker<EntityNode>('mcfunction:entity', entity)
meta.registerChecker<ItemNode>('mcfunction:item', item)
meta.registerChecker<ItemStackNode>('mcfunction:item_stack', itemStack)
meta.registerChecker<JsonNode>('mcfunction:json', jsonChecker)
meta.registerChecker<ParticleNode>('mcfunction:particle', particle)
}
85 changes: 78 additions & 7 deletions packages/java-edition/src/mcfunction/completer/argument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
import * as json from '@spyglassmc/json'
import { localeQuote, localize } from '@spyglassmc/locales'
import type * as mcf from '@spyglassmc/mcfunction'
import * as nbt from '@spyglassmc/nbt'
import type * as nbt from '@spyglassmc/nbt'
import { getTagValues } from '../../common/index.js'
import { ReleaseVersion } from '../../dependency/common.js'
import {
Expand All @@ -45,6 +45,9 @@ import {
} from '../common/index.js'
import type {
BlockStatesNode,
ComponentListNode,
ComponentTestsAllOfNode,
ComponentTestsNode,
EntitySelectorArgumentsNode,
} from '../node/index.js'
import {
Expand All @@ -53,7 +56,8 @@ import {
EntitySelectorAtVariable,
EntitySelectorNode,
IntRangeNode,
ItemNode,
ItemPredicateNode,
ItemStackNode,
ObjectiveCriteriaNode,
ParticleNode,
ScoreHolderNode,
Expand Down Expand Up @@ -124,7 +128,7 @@ export const getMockNodes: mcf.completer.MockNodesGetter = (
case 'minecraft:item_enchantment':
return ResourceLocationNode.mock(range, { category: 'enchantment' })
case 'minecraft:item_predicate':
return ItemNode.mock(range, true)
return ItemPredicateNode.mock(range)
case 'minecraft:item_slot':
return LiteralNode.mock(range, {
pool: getItemSlotArgumentValues(ctx),
Expand All @@ -134,7 +138,7 @@ export const getMockNodes: mcf.completer.MockNodesGetter = (
pool: getItemSlotsArgumentValues(ctx),
})
case 'minecraft:item_stack':
return ItemNode.mock(range, false)
return ItemStackNode.mock(range)
case 'minecraft:loot_modifier':
return ResourceLocationNode.mock(range, { category: 'item_modifier' })
case 'minecraft:loot_predicate':
Expand Down Expand Up @@ -280,15 +284,70 @@ const blockStates: Completer<BlockStatesNode> = (node, ctx) => {
})(node, ctx)
}

const componentList: Completer<ComponentListNode> = (node, ctx) => {
return completer.record<
ResourceLocationNode,
nbt.NbtNode,
ComponentListNode
>({
key: (
_record,
pair,
ctx,
range,
_insertValue,
_insertComma,
_existingKeys,
) => {
const id = pair?.key ??
ResourceLocationNode.mock(pair?.key ?? range, {
category: 'data_component_type',
})
return completer.resourceLocation(id, ctx)
},
value: () => {
return [] // TODO
},
})(node, ctx)
}

const componentTests: Completer<ComponentTestsNode> = (node, ctx) => {
// TODO: improve this completer
return []
}

const coordinate: Completer<CoordinateNode> = (node, _ctx) => {
return [CompletionItem.create('~', node)]
}

const item: Completer<ItemNode> = (node, ctx) => {
const itemStack: Completer<ItemStackNode> = (node, ctx) => {
const ans: CompletionItem[] = []
if (Range.contains(node.id, ctx.offset, true)) {
ans.push(...completer.resourceLocation(node.id, ctx))
}
if (node.components && Range.contains(node.components, ctx.offset, true)) {
ans.push(...componentList(node.components, ctx))
}
if (node.nbt && Range.contains(node.nbt, ctx.offset, true)) {
// TODO
}
return ans
}

const itemPredicate: Completer<ItemPredicateNode> = (node, ctx) => {
const ans: CompletionItem[] = []
if (Range.contains(node.id, ctx.offset, true)) {
ans.push(CompletionItem.create('*', node, { sortText: '##' }))
if (node.id.type === 'resource_location') {
ans.push(...completer.resourceLocation(node.id, ctx))
}
}
if (node.tests && Range.contains(node.tests, ctx.offset, true)) {
ans.push(...componentTests(node.tests, ctx))
}
if (node.nbt && Range.contains(node.nbt, ctx.offset, true)) {
// TODO
}
return ans
}

Expand Down Expand Up @@ -344,7 +403,7 @@ const particle: Completer<ParticleNode> = (node, ctx) => {
VectorNode.mock(ctx.offset, { dimension: 3 }),
],
falling_dust: [BlockNode.mock(ctx.offset, false)],
item: [ItemNode.mock(ctx.offset, false)],
item: [ItemStackNode.mock(ctx.offset)],
sculk_charge: [FloatNode.mock(ctx.offset)],
shriek: [IntegerNode.mock(ctx.offset)],
vibration: [
Expand Down Expand Up @@ -476,6 +535,14 @@ const vector: Completer<VectorNode> = (node, _ctx) => {

export function register(meta: MetaRegistry) {
meta.registerCompleter<BlockNode>('mcfunction:block', block)
meta.registerCompleter<ComponentListNode>(
'mcfunction:component_list',
componentList,
)
meta.registerCompleter<ComponentTestsNode>(
'mcfunction:component_tests',
componentTests,
)
meta.registerCompleter<CoordinateNode>('mcfunction:coordinate', coordinate)
meta.registerCompleter<EntitySelectorNode>(
'mcfunction:entity_selector',
Expand All @@ -486,7 +553,11 @@ export function register(meta: MetaRegistry) {
selectorArguments,
)
meta.registerCompleter<IntRangeNode>('mcfunction:int_range', intRange)
meta.registerCompleter<ItemNode>('mcfunction:item', item)
meta.registerCompleter<ItemStackNode>('mcfunction:item_stack', itemStack)
meta.registerCompleter<ItemPredicateNode>(
'mcfunction:item_predicate',
itemPredicate,
)
meta.registerCompleter<ObjectiveCriteriaNode>(
'mcfunction:objective_criteria',
objectiveCriteria,
Expand Down
Loading
Loading