From da60293c4dfa06517c7ea23f3241de8c586058ff Mon Sep 17 00:00:00 2001 From: Misode Date: Fri, 27 Dec 2024 16:16:20 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fix=20score=20holders=20starting?= =?UTF-8?q?=20with=20`*`=20(#1692)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/source/Source.ts | 26 ++++++++++--------- .../src/mcfunction/completer/argument.ts | 1 + .../src/mcfunction/parser/argument.ts | 8 ++++-- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/packages/core/src/source/Source.ts b/packages/core/src/source/Source.ts index 68d141803..ddc813b92 100644 --- a/packages/core/src/source/Source.ts +++ b/packages/core/src/source/Source.ts @@ -72,6 +72,16 @@ export class ReadonlySource { return this.string.slice(this.innerCursor + offset, this.innerCursor + offset + length) } + canRead(length = 1) { + const needed = this.innerCursor + length + const available = this.string.length + return this.innerCursor + length <= this.string.length + } + + canReadInLine() { + return this.canRead() && this.peek() !== CR && this.peek() !== LF + } + /** * If the `expectedValue` is right after the cursor, returns `true`. Otherwise returns `false`. * @@ -109,12 +119,12 @@ export class ReadonlySource { return this.peekUntil(CR, LF) } - peekRemaining(): string { - return this.string.slice(this.innerCursor) + peekRemaining(offset = 0): string { + return this.string.slice(this.innerCursor + offset) } - matchPattern(regex: RegExp): boolean { - return regex.test(this.peekRemaining()) + matchPattern(regex: RegExp, offset = 0): boolean { + return regex.test(this.peekRemaining(offset)) } /** @@ -172,14 +182,6 @@ export class Source extends ReadonlySource { return ans } - canRead(length = 1) { - return this.innerCursor + length <= this.string.length - } - - canReadInLine() { - return this.canRead() && this.peek() !== CR && this.peek() !== LF - } - read() { return this.string.charAt(this.innerCursor++) } diff --git a/packages/java-edition/src/mcfunction/completer/argument.ts b/packages/java-edition/src/mcfunction/completer/argument.ts index be1b6c484..3d581b9d9 100644 --- a/packages/java-edition/src/mcfunction/completer/argument.ts +++ b/packages/java-edition/src/mcfunction/completer/argument.ts @@ -433,6 +433,7 @@ const scoreHolder: Completer = (node, ctx) => { ctx, ) ans.push( + ...completer.literal(LiteralNode.mock(node, { pool: ['*'] }), ctx), ...selector( EntitySelectorNode.mock(node, { pool: EntitySelectorAtVariable.filterAvailable(ctx) }), ctx, diff --git a/packages/java-edition/src/mcfunction/parser/argument.ts b/packages/java-edition/src/mcfunction/parser/argument.ts index a9e7f3359..c5a3fb234 100644 --- a/packages/java-edition/src/mcfunction/parser/argument.ts +++ b/packages/java-edition/src/mcfunction/parser/argument.ts @@ -1406,8 +1406,12 @@ export function scoreHolder( ): core.Parser { return core.map( core.select([ - // Technically score holders can start with *, but this doesn't account for it - { prefix: '*', parser: core.literal('*') }, + { + predicate: (src) => + src.peek() === '*' + && (!src.canRead(2) || src.matchPattern(/^\s/, 1)), + parser: core.literal('*'), + }, { prefix: '@', parser: selector() }, { parser: scoreHolderFakeName(usageType) }, ]),