From 58d0132d0ef83b05b238e79925bf8ab30052cad2 Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Sat, 18 May 2024 01:55:35 -0400 Subject: [PATCH 01/25] fix typo --- packages/core/src/parser/util.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/core/src/parser/util.ts b/packages/core/src/parser/util.ts index ae589f85a..0ea588c39 100644 --- a/packages/core/src/parser/util.ts +++ b/packages/core/src/parser/util.ts @@ -478,17 +478,17 @@ export function validate( */ export function stopBefore( parser: InfallibleParser, - ...teminators: (string | readonly string[])[] + ...terminators: (string | readonly string[])[] ): InfallibleParser export function stopBefore( parser: Parser, - ...teminators: (string | readonly string[])[] + ...terminators: (string | readonly string[])[] ): Parser export function stopBefore( parser: Parser, - ...teminators: (string | readonly string[])[] + ...terminators: (string | readonly string[])[] ): Parser { - const flatTerminators = teminators.flat() + const flatTerminators = terminators.flat() return (src, ctx): Result => { const tmpSrc = src.clone() // Cut tmpSrc.string before the nearest terminator. From d95506f6aca3a508e11b9806577b0e44cdb0cb09 Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Sat, 18 May 2024 02:09:30 -0400 Subject: [PATCH 02/25] add support for offset from cursor for `Source.hasNonSpaceAheadInLine()` - also add unit tests for method --- packages/core/src/source/Source.ts | 9 ++++++-- packages/core/test/source/Source.spec.ts | 28 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/packages/core/src/source/Source.ts b/packages/core/src/source/Source.ts index 126126b01..9c9e2590c 100644 --- a/packages/core/src/source/Source.ts +++ b/packages/core/src/source/Source.ts @@ -103,9 +103,14 @@ export class ReadonlySource { return regex.test(this.peekRemaining()) } - hasNonSpaceAheadInLine(): boolean { + /** + * If there is a non-space character between `cursor + offset` (inclusive) and the next newline, returns `true`. Otherwise returns `false`. + * + * @param offset Defaults to 0. + */ + hasNonSpaceAheadInLine(offset = 0): boolean { for ( - let cursor = this.innerCursor; + let cursor = this.innerCursor + offset; cursor < this.string.length; cursor++ ) { diff --git a/packages/core/test/source/Source.spec.ts b/packages/core/test/source/Source.spec.ts index d2d80391b..a4d152f68 100644 --- a/packages/core/test/source/Source.spec.ts +++ b/packages/core/test/source/Source.spec.ts @@ -522,6 +522,34 @@ describe('Source', () => { ) } }) + describe('hasNonSpaceAheadInLine', () => { + const suites: { + string: string + cursor: number + offset?: number + expected: boolean + }[] = [ + { string: 'foo', cursor: 0, expected: true }, + { string: 'foo', cursor: 2, expected: true }, + { string: 'foo', cursor: 3, expected: false }, + { string: 'foo ', cursor: 3, expected: false }, + { string: 'fooo ', cursor: 3, expected: true }, + { string: 'foooo ', cursor: 3, offset: 1, expected: true }, + { string: 'foooo ', cursor: 3, offset: 2, expected: false }, + ] + for (const { string, cursor, offset, expected } of suites) { + it( + `Should return ${expected} for from ${ + markOffsetInString(string, cursor + (offset ?? 0)) + }}`, + () => { + const src = new Source(string) + src.cursor = cursor + assert.strictEqual(src.hasNonSpaceAheadInLine(offset), expected) + }, + ) + } + }) describe('static', () => { describe('isBrigadierQuote()', () => { const suites: { c: string; expected: boolean }[] = [ From 2cbab8655169b16173509f8b27adee0471da162e Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Sat, 18 May 2024 22:53:58 -0400 Subject: [PATCH 03/25] add `concatOnTrailingBackslash` util parser - concatenates lines together when we hit a trailing backslash - `terminators` param is used differently for `argument`/`command` parser - difference is `command` parser adds in a space terminator ` ` in addition to newline terminators `\n` and `\r` - also add unit tests :] --- .../core/test-out/parser/util.spec.js | 104 ++++++++++++++++++ packages/core/src/parser/util.ts | 69 +++++++++++- packages/core/test/parser/util.spec.ts | 43 +++++++- 3 files changed, 213 insertions(+), 3 deletions(-) diff --git a/__snapshots__/packages/core/test-out/parser/util.spec.js b/__snapshots__/packages/core/test-out/parser/util.spec.js index 66806b622..bc2cd9e9a 100644 --- a/__snapshots__/packages/core/test-out/parser/util.spec.js +++ b/__snapshots__/packages/core/test-out/parser/util.spec.js @@ -93,6 +93,110 @@ exports['any() Parse "qux" with "foo | bar" 1'] = { "errors": [] } +exports['concatOnTrailingBackslash() Parse "true" 1'] = { + "node": { + "type": "boolean", + "range": { + "start": 0, + "end": 4 + }, + "value": true + }, + "errors": [] +} + +exports['concatOnTrailingBackslash() Parse "true↓" 1'] = { + "node": { + "type": "boolean", + "range": { + "start": 0, + "end": 4 + }, + "value": true + }, + "errors": [] +} + +exports['concatOnTrailingBackslash() Parse "tru⧵ ↓ e" 1'] = { + "node": { + "type": "boolean", + "range": { + "start": 0, + "end": 8 + }, + "value": true + }, + "errors": [] +} + +exports['concatOnTrailingBackslash() Parse "tru⧵ ↓ ⧵↓ e" 1'] = { + "node": { + "type": "boolean", + "range": { + "start": 0, + "end": 11 + }, + "value": true + }, + "errors": [] +} + +exports['concatOnTrailingBackslash() Parse "tru⧵ ↓e" 1'] = { + "node": { + "type": "boolean", + "range": { + "start": 0, + "end": 7 + }, + "value": true + }, + "errors": [] +} + +exports['concatOnTrailingBackslash() Parse "tru⧵e ⧵ ↓ e" 1'] = { + "node": { + "type": "boolean", + "range": { + "start": 0, + "end": 0 + } + }, + "errors": [ + { + "range": { + "start": 0, + "end": 0 + }, + "message": "Expected “false” or “true”", + "severity": 3 + } + ] +} + +exports['concatOnTrailingBackslash() Parse "tru⧵↓ e" 1'] = { + "node": { + "type": "boolean", + "range": { + "start": 0, + "end": 7 + }, + "value": true + }, + "errors": [] +} + +exports['concatOnTrailingBackslash() Parse "tru⧵↓e" 1'] = { + "node": { + "type": "boolean", + "range": { + "start": 0, + "end": 6 + }, + "value": true + }, + "errors": [] +} + exports['dumpErrors() should not output errors when wrapped with `dumpErrors()` 1'] = { "node": { "type": "boolean", diff --git a/packages/core/src/parser/util.ts b/packages/core/src/parser/util.ts index 0ea588c39..64419655b 100644 --- a/packages/core/src/parser/util.ts +++ b/packages/core/src/parser/util.ts @@ -2,8 +2,8 @@ import type { AstNode } from '../node/index.js' import { SequenceUtil, SequenceUtilDiscriminator } from '../node/index.js' import type { ParserContext } from '../service/index.js' import { ErrorReporter } from '../service/index.js' -import type { ErrorSeverity, ReadonlySource, Source } from '../source/index.js' -import { Range } from '../source/index.js' +import type { ErrorSeverity, ReadonlySource } from '../source/index.js' +import { IndexMap, Range, Source } from '../source/index.js' import type { InfallibleParser, Parser, Result, Returnable } from './Parser.js' import { Failure } from './Parser.js' @@ -506,6 +506,71 @@ export function stopBefore( } } +/** + * @param terminators A list of characters the parser will stop at if it finds them + * before a backslash + * @returns A parser that is based on the passed-in `parser`, but concatenates lines + * together when we reach, in order: + * - a backslash + * - whitespace (optional) + * - a newline + * - whitespace (optional) + */ +export function concatOnTrailingBackslash( + parser: InfallibleParser, + terminators: string[], +): InfallibleParser +export function concatOnTrailingBackslash( + parser: Parser, + terminators: string[], +): Parser +export function concatOnTrailingBackslash( + parser: Parser, + terminators: string[], +): Parser { + return (src, ctx): Result => { + let wrappedStr = src.sliceToCursor(0) + const wrapper = '\\' + const wrappedSrcCursor = wrappedStr.length + const indexMap: IndexMap = [] + + while (src.canRead() && !terminators.includes(src.peek())) { + wrappedStr += src.readUntil(wrapper, ...terminators) + if (!src.canRead() || terminators.includes(src.peek())) { + // Stop wrapping `src` if we reach end of file or a terminator before a wrapper + break + } + + // If we get here, then `src.cursor` is at a wrapper + if (src.hasNonSpaceAheadInLine(1)) { + wrappedStr += src.read() + continue + } + + // Create an index map that skips the trailing backslash + whitespace + const from = src.getCharRange() + // skip the `\` + src.skip() + // skip trailing whitespace + newline + preceding whitespace on the next line + src.skipWhitespace() + const to = src.getCharRange(-1) + indexMap.push({ + inner: Range.create(wrappedStr.length), + outer: Range.span(from, to), + }) + } + + const wrappedSrc = new Source( + wrappedStr, + IndexMap.merge(src.indexMap, indexMap), + ) + wrappedSrc.innerCursor = wrappedSrcCursor + const ans = parser(wrappedSrc, ctx) + src.cursor = wrappedSrc.cursor + return ans + } +} + /** * @returns A parser that is based on the passed-in `parser`, but will only read the acceptable characters. */ diff --git a/packages/core/test/parser/util.spec.ts b/packages/core/test/parser/util.spec.ts index adb115871..5375db823 100644 --- a/packages/core/test/parser/util.spec.ts +++ b/packages/core/test/parser/util.spec.ts @@ -8,7 +8,14 @@ import type { Result, Source, } from '../../lib/index.js' -import { any, boolean, dumpErrors, Failure, Range } from '../../lib/index.js' +import { + any, + boolean, + concatOnTrailingBackslash, + dumpErrors, + Failure, + Range, +} from '../../lib/index.js' import { showWhitespaceGlyph, testParser } from '../utils.js' interface LiteralNode extends AstNode { @@ -119,3 +126,37 @@ describe('dumpErrors()', () => { }) } }) + +describe('concatOnTrailingBackslash()', () => { + const parsers: { + parser: Parser + suites: Array<{ + content: string + }> + }[] = [ + { + parser: boolean, + suites: [ + { content: 'true' }, + { content: 'true\n' }, + { content: 'tru\\\ne' }, + { content: 'tru\\ \ne' }, + { content: 'tru\\\n e' }, + { content: 'tru\\ \n e' }, + { content: 'tru\\ \n \\\n e' }, + { content: 'tru\\e \\ \n e' }, + ], + }, + ] + for (const { parser, suites } of parsers) { + for (const { content } of suites) { + it( + `Parse "${showWhitespaceGlyph(content)}"`, + () => { + const wrappedParser = concatOnTrailingBackslash(parser, ['\n']) + snapshot(testParser(wrappedParser, content)) + }, + ) + } + } +}) From b79623c7a151b34b2baadae9390247ac5a5cbb5f Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Sat, 18 May 2024 22:56:49 -0400 Subject: [PATCH 04/25] add backslash continuation to `argument` parsers --- .../argument/minecraftComponent.spec.js | 235 ++++++++++++++++++ .../src/mcfunction/parser/argument.ts | 2 +- .../test/mcfunction/parser/argument.spec.ts | 12 +- 3 files changed, 247 insertions(+), 2 deletions(-) diff --git a/__snapshots__/packages/java-edition/test-out/mcfunction/parser/argument/minecraftComponent.spec.js b/__snapshots__/packages/java-edition/test-out/mcfunction/parser/argument/minecraftComponent.spec.js index d657d65c6..77af2d2b5 100644 --- a/__snapshots__/packages/java-edition/test-out/mcfunction/parser/argument/minecraftComponent.spec.js +++ b/__snapshots__/packages/java-edition/test-out/mcfunction/parser/argument/minecraftComponent.spec.js @@ -108,6 +108,241 @@ exports['mcfunction argument minecraft:component Parse "[""]" 1'] = { "errors": [] } +exports['mcfunction argument minecraft:component Parse "["hello ⧵ ↓world"]" 1'] = { + "node": { + "type": "json:array", + "range": { + "start": 0, + "end": 18 + }, + "children": [ + { + "type": "item", + "range": { + "start": 1, + "end": 17 + }, + "children": [ + { + "type": "json:string", + "range": { + "start": 1, + "end": 17 + }, + "value": "hello world", + "valueMap": [ + { + "inner": { + "start": 0, + "end": 0 + }, + "outer": { + "start": 2, + "end": 2 + } + } + ] + } + ], + "value": { + "type": "json:string", + "range": { + "start": 1, + "end": 17 + }, + "value": "hello world", + "valueMap": [ + { + "inner": { + "start": 0, + "end": 0 + }, + "outer": { + "start": 2, + "end": 2 + } + } + ] + } + } + ] + }, + "errors": [] +} + +exports['mcfunction argument minecraft:component Parse "["⧵u12⧵ ↓ 34"]" 1'] = { + "node": { + "type": "json:array", + "range": { + "start": 0, + "end": 16 + }, + "children": [ + { + "type": "item", + "range": { + "start": 1, + "end": 15 + }, + "children": [ + { + "type": "json:string", + "range": { + "start": 1, + "end": 15 + }, + "value": "ሴ", + "valueMap": [ + { + "inner": { + "start": 0, + "end": 0 + }, + "outer": { + "start": 2, + "end": 2 + } + }, + { + "inner": { + "start": 0, + "end": 1 + }, + "outer": { + "start": 2, + "end": 14 + } + } + ] + } + ], + "value": { + "type": "json:string", + "range": { + "start": 1, + "end": 15 + }, + "value": "ሴ", + "valueMap": [ + { + "inner": { + "start": 0, + "end": 0 + }, + "outer": { + "start": 2, + "end": 2 + } + }, + { + "inner": { + "start": 0, + "end": 1 + }, + "outer": { + "start": 2, + "end": 14 + } + } + ] + } + } + ] + }, + "errors": [] +} + +exports['mcfunction argument minecraft:component Parse "["⧵uab⧵ ↓ nd"]" 1'] = { + "node": { + "type": "json:array", + "range": { + "start": 0, + "end": 16 + }, + "children": [ + { + "type": "item", + "range": { + "start": 1, + "end": 15 + }, + "children": [ + { + "type": "json:string", + "range": { + "start": 1, + "end": 15 + }, + "value": "uabnd", + "valueMap": [ + { + "inner": { + "start": 0, + "end": 0 + }, + "outer": { + "start": 2, + "end": 2 + } + }, + { + "inner": { + "start": 0, + "end": 1 + }, + "outer": { + "start": 2, + "end": 4 + } + } + ] + } + ], + "value": { + "type": "json:string", + "range": { + "start": 1, + "end": 15 + }, + "value": "uabnd", + "valueMap": [ + { + "inner": { + "start": 0, + "end": 0 + }, + "outer": { + "start": 2, + "end": 2 + } + }, + { + "inner": { + "start": 0, + "end": 1 + }, + "outer": { + "start": 2, + "end": 4 + } + } + ] + } + } + ] + }, + "errors": [ + { + "range": { + "start": 4, + "end": 14 + }, + "message": "Hexadecimal digit expected", + "severity": 3 + } + ] +} + exports['mcfunction argument minecraft:component Parse "{"text":"hello world"}" 1'] = { "node": { "type": "json:object", diff --git a/packages/java-edition/src/mcfunction/parser/argument.ts b/packages/java-edition/src/mcfunction/parser/argument.ts index 981f9ddf8..19cf08327 100644 --- a/packages/java-edition/src/mcfunction/parser/argument.ts +++ b/packages/java-edition/src/mcfunction/parser/argument.ts @@ -91,7 +91,7 @@ export const argument: mcf.ArgumentParserGetter = ( const treeNode = rawTreeNode as ArgumentTreeNode const wrap = (parser: core.Parser): core.Parser => - core.failOnEmpty(core.stopBefore(parser, '\r', '\n')) + core.failOnEmpty(core.concatOnTrailingBackslash(parser, ['\r', '\n'])) switch (treeNode.parser) { case 'brigadier:bool': diff --git a/packages/java-edition/test/mcfunction/parser/argument.spec.ts b/packages/java-edition/test/mcfunction/parser/argument.spec.ts index ccd79ae85..d62433302 100644 --- a/packages/java-edition/test/mcfunction/parser/argument.spec.ts +++ b/packages/java-edition/test/mcfunction/parser/argument.spec.ts @@ -73,7 +73,17 @@ const Suites: Partial< 'minecraft:color': [{ content: ['red', 'green'] }], 'minecraft:column_pos': [{ content: ['0 0', '~ ~', '~1 ~-2'] }], 'minecraft:component': [ - { content: ['"hello world"', '""', '{"text":"hello world"}', '[""]'] }, + { + content: [ + '"hello world"', + '""', + '{"text":"hello world"}', + '[""]', + '["hello \\ \nworld"]', + '["\\u12\\ \n 34"]', + '["\\uab\\ \n nd"]', + ], + }, ], 'minecraft:dimension': [ { content: ['minecraft:overworld', 'minecraft:the_nether'] }, From 9addc6cf416e6f4ce2fa27722824725dfd585b58 Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Sat, 18 May 2024 23:01:38 -0400 Subject: [PATCH 05/25] add backslash continuation to `command` parser - add space char ` ` as a terminator to improve performance (needed to pass test) --- .../test-out/parser/command.spec.js | 162 ++++++++++++++++++ packages/mcfunction/src/parser/command.ts | 9 +- .../mcfunction/test/parser/command.spec.ts | 3 + 3 files changed, 171 insertions(+), 3 deletions(-) diff --git a/__snapshots__/packages/mcfunction/test-out/parser/command.spec.js b/__snapshots__/packages/mcfunction/test-out/parser/command.spec.js index 032c7ed53..b21a9b1fc 100644 --- a/__snapshots__/packages/mcfunction/test-out/parser/command.spec.js +++ b/__snapshots__/packages/mcfunction/test-out/parser/command.spec.js @@ -515,6 +515,168 @@ exports['mcfunction parser command() Parse "say" 1'] = { ] } +exports['mcfunction parser command() Parse "sa⧵ ↓ y hi" 1'] = { + "node": { + "type": "mcfunction:command", + "range": { + "start": 0, + "end": 12 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 0, + "end": 9 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 0, + "end": 9 + }, + "value": "say" + } + ], + "path": [ + "say" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 10, + "end": 12 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 10, + "end": 12 + }, + "value": "hi" + } + ], + "path": [ + "say", + "hi" + ] + } + ] + }, + "errors": [] +} + +exports['mcfunction parser command() Parse "sa⧵ ↓ y h⧵ ↓ i" 1'] = { + "node": { + "type": "mcfunction:command", + "range": { + "start": 0, + "end": 16 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 0, + "end": 9 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 0, + "end": 9 + }, + "value": "say" + } + ], + "path": [ + "say" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 10, + "end": 16 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 10, + "end": 16 + }, + "value": "hi" + } + ], + "path": [ + "say", + "hi" + ] + } + ] + }, + "errors": [] +} + +exports['mcfunction parser command() Parse "sa⧵↓y hi" 1'] = { + "node": { + "type": "mcfunction:command", + "range": { + "start": 0, + "end": 8 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 0, + "end": 5 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 0, + "end": 5 + }, + "value": "say" + } + ], + "path": [ + "say" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 6, + "end": 8 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 6, + "end": 8 + }, + "value": "hi" + } + ], + "path": [ + "say", + "hi" + ] + } + ] + }, + "errors": [] +} + exports['mcfunction parser command() Should not exceed max call stack 1'] = { "node": "OMITTED", "errors": [ diff --git a/packages/mcfunction/src/parser/command.ts b/packages/mcfunction/src/parser/command.ts index a3041c92a..81e3ac610 100644 --- a/packages/mcfunction/src/parser/command.ts +++ b/packages/mcfunction/src/parser/command.ts @@ -94,9 +94,12 @@ function dispatch( parser: argument(treeNode) ?? unknown(treeNode), })) const literalParser = literalTreeNodes.length - ? literal( - literalTreeNodes.map(([name, _treeNode]) => name), - parent.type === 'root', + ? core.concatOnTrailingBackslash( + literal( + literalTreeNodes.map(([name, _treeNode]) => name), + parent.type === 'root', + ), + [' ', '\n', '\r'], ) : undefined diff --git a/packages/mcfunction/test/parser/command.spec.ts b/packages/mcfunction/test/parser/command.spec.ts index 59a47afe7..df2a4e756 100644 --- a/packages/mcfunction/test/parser/command.spec.ts +++ b/packages/mcfunction/test/parser/command.spec.ts @@ -50,6 +50,9 @@ describe('mcfunction parser command()', () => { { content: 'say hi ' }, { content: 'say hi garbage text' }, { content: 'execute if true if true run say hi' }, + { content: 'sa\\\ny hi' }, + { content: 'sa\\ \n y hi' }, + { content: 'sa\\ \n y h\\ \n i' }, ] for (const { content } of cases) { it(`Parse "${showWhitespaceGlyph(content)}"`, () => { From ec8760ddba0b83979b1d7b8301bc4bf9b48e8158 Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Mon, 20 May 2024 11:46:00 -0400 Subject: [PATCH 06/25] =?UTF-8?q?=F0=9F=A7=AA=20Add=20tests=20with=20incor?= =?UTF-8?q?rect=20parse=20result=20-=20we=20want=20these=20to=20result=20i?= =?UTF-8?q?n=20errors,=20but=20they=20pass=20right=20now?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/test-out/parser/util.spec.js | 12 ++++ .../argument/minecraftComponent.spec.js | 62 +++++++++++++++++++ .../test-out/parser/command.spec.js | 54 ++++++++++++++++ packages/core/test/parser/util.spec.ts | 1 + .../test/mcfunction/parser/argument.spec.ts | 1 + .../mcfunction/test/parser/command.spec.ts | 1 + 6 files changed, 131 insertions(+) diff --git a/__snapshots__/packages/core/test-out/parser/util.spec.js b/__snapshots__/packages/core/test-out/parser/util.spec.js index bc2cd9e9a..b9c3785ee 100644 --- a/__snapshots__/packages/core/test-out/parser/util.spec.js +++ b/__snapshots__/packages/core/test-out/parser/util.spec.js @@ -197,6 +197,18 @@ exports['concatOnTrailingBackslash() Parse "tru⧵↓e" 1'] = { "errors": [] } +exports['concatOnTrailingBackslash() Parse "tru⧵↓↓e" 1'] = { + "node": { + "type": "boolean", + "range": { + "start": 0, + "end": 7 + }, + "value": true + }, + "errors": [] +} + exports['dumpErrors() should not output errors when wrapped with `dumpErrors()` 1'] = { "node": { "type": "boolean", diff --git a/__snapshots__/packages/java-edition/test-out/mcfunction/parser/argument/minecraftComponent.spec.js b/__snapshots__/packages/java-edition/test-out/mcfunction/parser/argument/minecraftComponent.spec.js index 77af2d2b5..3e18c5e13 100644 --- a/__snapshots__/packages/java-edition/test-out/mcfunction/parser/argument/minecraftComponent.spec.js +++ b/__snapshots__/packages/java-edition/test-out/mcfunction/parser/argument/minecraftComponent.spec.js @@ -170,6 +170,68 @@ exports['mcfunction argument minecraft:component Parse "["hello ⧵ ↓world"]" "errors": [] } +exports['mcfunction argument minecraft:component Parse "["hello⧵↓↓world"]" 1'] = { + "node": { + "type": "json:array", + "range": { + "start": 0, + "end": 17 + }, + "children": [ + { + "type": "item", + "range": { + "start": 1, + "end": 16 + }, + "children": [ + { + "type": "json:string", + "range": { + "start": 1, + "end": 16 + }, + "value": "helloworld", + "valueMap": [ + { + "inner": { + "start": 0, + "end": 0 + }, + "outer": { + "start": 2, + "end": 2 + } + } + ] + } + ], + "value": { + "type": "json:string", + "range": { + "start": 1, + "end": 16 + }, + "value": "helloworld", + "valueMap": [ + { + "inner": { + "start": 0, + "end": 0 + }, + "outer": { + "start": 2, + "end": 2 + } + } + ] + } + } + ] + }, + "errors": [] +} + exports['mcfunction argument minecraft:component Parse "["⧵u12⧵ ↓ 34"]" 1'] = { "node": { "type": "json:array", diff --git a/__snapshots__/packages/mcfunction/test-out/parser/command.spec.js b/__snapshots__/packages/mcfunction/test-out/parser/command.spec.js index b21a9b1fc..06c0358c9 100644 --- a/__snapshots__/packages/mcfunction/test-out/parser/command.spec.js +++ b/__snapshots__/packages/mcfunction/test-out/parser/command.spec.js @@ -677,6 +677,60 @@ exports['mcfunction parser command() Parse "sa⧵↓y hi" 1'] = { "errors": [] } +exports['mcfunction parser command() Parse "sa⧵↓↓y h⧵ ↓ i" 1'] = { + "node": { + "type": "mcfunction:command", + "range": { + "start": 0, + "end": 13 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 0, + "end": 6 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 0, + "end": 6 + }, + "value": "say" + } + ], + "path": [ + "say" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 7, + "end": 13 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 7, + "end": 13 + }, + "value": "hi" + } + ], + "path": [ + "say", + "hi" + ] + } + ] + }, + "errors": [] +} + exports['mcfunction parser command() Should not exceed max call stack 1'] = { "node": "OMITTED", "errors": [ diff --git a/packages/core/test/parser/util.spec.ts b/packages/core/test/parser/util.spec.ts index 5375db823..93d867526 100644 --- a/packages/core/test/parser/util.spec.ts +++ b/packages/core/test/parser/util.spec.ts @@ -145,6 +145,7 @@ describe('concatOnTrailingBackslash()', () => { { content: 'tru\\ \n e' }, { content: 'tru\\ \n \\\n e' }, { content: 'tru\\e \\ \n e' }, + { content: 'tru\\\n\ne' }, ], }, ] diff --git a/packages/java-edition/test/mcfunction/parser/argument.spec.ts b/packages/java-edition/test/mcfunction/parser/argument.spec.ts index d62433302..52544cb9c 100644 --- a/packages/java-edition/test/mcfunction/parser/argument.spec.ts +++ b/packages/java-edition/test/mcfunction/parser/argument.spec.ts @@ -80,6 +80,7 @@ const Suites: Partial< '{"text":"hello world"}', '[""]', '["hello \\ \nworld"]', + '["hello\\\n\nworld"]', '["\\u12\\ \n 34"]', '["\\uab\\ \n nd"]', ], diff --git a/packages/mcfunction/test/parser/command.spec.ts b/packages/mcfunction/test/parser/command.spec.ts index df2a4e756..d41f4f91b 100644 --- a/packages/mcfunction/test/parser/command.spec.ts +++ b/packages/mcfunction/test/parser/command.spec.ts @@ -53,6 +53,7 @@ describe('mcfunction parser command()', () => { { content: 'sa\\\ny hi' }, { content: 'sa\\ \n y hi' }, { content: 'sa\\ \n y h\\ \n i' }, + { content: 'sa\\\n\ny h\\ \n i' }, ] for (const { content } of cases) { it(`Parse "${showWhitespaceGlyph(content)}"`, () => { From 059a825c4ea4e799b9ed2ebb17929e492d9a2b33 Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Mon, 20 May 2024 11:58:59 -0400 Subject: [PATCH 07/25] =?UTF-8?q?=F0=9F=90=9B=20Fix=20backslash=20parser?= =?UTF-8?q?=20allowing=20multiple=20newlines=20per=20single=20backslash?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/test-out/parser/util.spec.js | 16 +++++-- .../argument/minecraftComponent.spec.js | 31 ++++++++++---- .../test-out/parser/command.spec.js | 42 +++++++------------ packages/core/src/parser/util.ts | 9 ++-- 4 files changed, 55 insertions(+), 43 deletions(-) diff --git a/__snapshots__/packages/core/test-out/parser/util.spec.js b/__snapshots__/packages/core/test-out/parser/util.spec.js index b9c3785ee..bdd771064 100644 --- a/__snapshots__/packages/core/test-out/parser/util.spec.js +++ b/__snapshots__/packages/core/test-out/parser/util.spec.js @@ -202,11 +202,19 @@ exports['concatOnTrailingBackslash() Parse "tru⧵↓↓e" 1'] = { "type": "boolean", "range": { "start": 0, - "end": 7 - }, - "value": true + "end": 0 + } }, - "errors": [] + "errors": [ + { + "range": { + "start": 0, + "end": 0 + }, + "message": "Expected “false” or “true”", + "severity": 3 + } + ] } exports['dumpErrors() should not output errors when wrapped with `dumpErrors()` 1'] = { diff --git a/__snapshots__/packages/java-edition/test-out/mcfunction/parser/argument/minecraftComponent.spec.js b/__snapshots__/packages/java-edition/test-out/mcfunction/parser/argument/minecraftComponent.spec.js index 3e18c5e13..e4d8a7fe1 100644 --- a/__snapshots__/packages/java-edition/test-out/mcfunction/parser/argument/minecraftComponent.spec.js +++ b/__snapshots__/packages/java-edition/test-out/mcfunction/parser/argument/minecraftComponent.spec.js @@ -175,23 +175,23 @@ exports['mcfunction argument minecraft:component Parse "["hello⧵↓↓world"]" "type": "json:array", "range": { "start": 0, - "end": 17 + "end": 9 }, "children": [ { "type": "item", "range": { "start": 1, - "end": 16 + "end": 9 }, "children": [ { "type": "json:string", "range": { "start": 1, - "end": 16 + "end": 9 }, - "value": "helloworld", + "value": "hello", "valueMap": [ { "inner": { @@ -210,9 +210,9 @@ exports['mcfunction argument minecraft:component Parse "["hello⧵↓↓world"]" "type": "json:string", "range": { "start": 1, - "end": 16 + "end": 9 }, - "value": "helloworld", + "value": "hello", "valueMap": [ { "inner": { @@ -229,7 +229,24 @@ exports['mcfunction argument minecraft:component Parse "["hello⧵↓↓world"]" } ] }, - "errors": [] + "errors": [ + { + "range": { + "start": 9, + "end": 9 + }, + "message": "Expected “\"”", + "severity": 3 + }, + { + "range": { + "start": 9, + "end": 9 + }, + "message": "Expected “]”", + "severity": 3 + } + ] } exports['mcfunction argument minecraft:component Parse "["⧵u12⧵ ↓ 34"]" 1'] = { diff --git a/__snapshots__/packages/mcfunction/test-out/parser/command.spec.js b/__snapshots__/packages/mcfunction/test-out/parser/command.spec.js index 06c0358c9..69862a207 100644 --- a/__snapshots__/packages/mcfunction/test-out/parser/command.spec.js +++ b/__snapshots__/packages/mcfunction/test-out/parser/command.spec.js @@ -682,53 +682,41 @@ exports['mcfunction parser command() Parse "sa⧵↓↓y h⧵ ↓ i" 1'] = { "type": "mcfunction:command", "range": { "start": 0, - "end": 13 + "end": 4 }, "children": [ { "type": "mcfunction:command_child", "range": { "start": 0, - "end": 6 + "end": 4 }, "children": [ { "type": "mcfunction:command_child/literal", "range": { "start": 0, - "end": 6 + "end": 4 }, - "value": "say" + "value": "sa" } ], "path": [ - "say" - ] - }, - { - "type": "mcfunction:command_child", - "range": { - "start": 7, - "end": 13 - }, - "children": [ - { - "type": "mcfunction:command_child/literal", - "range": { - "start": 7, - "end": 13 - }, - "value": "hi" - } - ], - "path": [ - "say", - "hi" + "sa" ] } ] }, - "errors": [] + "errors": [ + { + "range": { + "start": 0, + "end": 4 + }, + "message": "Expected “execute” or “say”", + "severity": 3 + } + ] } exports['mcfunction parser command() Should not exceed max call stack 1'] = { diff --git a/packages/core/src/parser/util.ts b/packages/core/src/parser/util.ts index 64419655b..5dcd9516f 100644 --- a/packages/core/src/parser/util.ts +++ b/packages/core/src/parser/util.ts @@ -547,12 +547,11 @@ export function concatOnTrailingBackslash( continue } - // Create an index map that skips the trailing backslash + whitespace + // Create an index map that skips from the trailing backslash to the + // next line's first non-whitespace character const from = src.getCharRange() - // skip the `\` - src.skip() - // skip trailing whitespace + newline + preceding whitespace on the next line - src.skipWhitespace() + src.nextLine() + src.skipSpace() const to = src.getCharRange(-1) indexMap.push({ inner: Range.create(wrappedStr.length), From 97b897ff6138a6e31fa44be5425774628d68c353 Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Mon, 20 May 2024 18:00:49 -0400 Subject: [PATCH 08/25] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor=20parser=20?= =?UTF-8?q?test=20tree=20into=20test=20util=20file=20-=20will=20be=20used?= =?UTF-8?q?=20in=20next=20commit=20for=20new=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mcfunction/test/parser/command.spec.ts | 34 +------------------ packages/mcfunction/test/parser/utils.ts | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+), 33 deletions(-) create mode 100644 packages/mcfunction/test/parser/utils.ts diff --git a/packages/mcfunction/test/parser/command.spec.ts b/packages/mcfunction/test/parser/command.spec.ts index d41f4f91b..da1f4f667 100644 --- a/packages/mcfunction/test/parser/command.spec.ts +++ b/packages/mcfunction/test/parser/command.spec.ts @@ -6,41 +6,9 @@ import { fail } from 'assert' import { describe, it } from 'mocha' import snapshot from 'snap-shot-it' import { command } from '../../lib/parser/index.js' -import type { RootTreeNode } from '../../lib/tree/index.js' +import { tree } from './utils.js' describe('mcfunction parser command()', () => { - const tree: RootTreeNode = { - type: 'root', - children: { - execute: { - type: 'literal', - children: { - if: { - type: 'literal', - children: { - true: { - type: 'literal', - executable: true, - redirect: ['execute'], - }, - }, - }, - run: { - type: 'literal', - }, - }, - }, - say: { - type: 'literal', - children: { - hi: { - type: 'literal', - executable: true, - }, - }, - }, - }, - } const cases: { content: string }[] = [ { content: '' }, { content: 's' }, diff --git a/packages/mcfunction/test/parser/utils.ts b/packages/mcfunction/test/parser/utils.ts new file mode 100644 index 000000000..d5cb0556b --- /dev/null +++ b/packages/mcfunction/test/parser/utils.ts @@ -0,0 +1,34 @@ +import type { RootTreeNode } from '../../lib/tree/index.js' + +export const tree: RootTreeNode = { + type: 'root', + children: { + execute: { + type: 'literal', + children: { + if: { + type: 'literal', + children: { + true: { + type: 'literal', + executable: true, + redirect: ['execute'], + }, + }, + }, + run: { + type: 'literal', + }, + }, + }, + say: { + type: 'literal', + children: { + hi: { + type: 'literal', + executable: true, + }, + }, + }, + }, +} From ed7f45c0bd486294b2a7d44495bb0ce582d92450 Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Mon, 20 May 2024 18:49:03 -0400 Subject: [PATCH 09/25] =?UTF-8?q?=E2=9C=85=20Add=20base=20tests=20for=20mc?= =?UTF-8?q?function=20`entry`=20parser=20-=20the=20main=20behaviors=20we?= =?UTF-8?q?=20want=20to=20test=20are:=20=20=20-=20comment=20detection=20?= =?UTF-8?q?=20=20-=20macro=20detection=20=20=20-=20splitting=20multiple=20?= =?UTF-8?q?lines=20into=20multiple=20commands/comments/macros=20accordingl?= =?UTF-8?q?y?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mcfunction/test-out/parser/entry.spec.js | 496 ++++++++++++++++++ packages/mcfunction/test/parser/entry.spec.ts | 30 ++ packages/mcfunction/test/parser/utils.ts | 2 +- 3 files changed, 527 insertions(+), 1 deletion(-) create mode 100644 __snapshots__/packages/mcfunction/test-out/parser/entry.spec.js create mode 100644 packages/mcfunction/test/parser/entry.spec.ts diff --git a/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js b/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js new file mode 100644 index 000000000..598cbdaa2 --- /dev/null +++ b/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js @@ -0,0 +1,496 @@ +exports['mcfunction parser entry() Parse "" 1'] = { + "node": { + "type": "mcfunction:entry", + "range": { + "start": 0, + "end": 0 + }, + "children": [] + }, + "errors": [] +} + +exports['mcfunction parser entry() Parse "# this is a comment" 1'] = { + "node": { + "type": "mcfunction:entry", + "range": { + "start": 0, + "end": 19 + }, + "children": [ + { + "type": "comment", + "range": { + "start": 0, + "end": 19 + }, + "comment": " this is a comment" + } + ] + }, + "errors": [] +} + +exports['mcfunction parser entry() Parse "# this is a comment↓say hi↓$this is a macro ↓" 1'] = { + "node": { + "type": "mcfunction:entry", + "range": { + "start": 0, + "end": 45 + }, + "children": [ + { + "type": "comment", + "range": { + "start": 0, + "end": 19 + }, + "comment": " this is a comment" + }, + { + "type": "mcfunction:command", + "range": { + "start": 20, + "end": 26 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 20, + "end": 23 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 20, + "end": 23 + }, + "value": "say" + } + ], + "path": [ + "say" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 24, + "end": 26 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 24, + "end": 26 + }, + "value": "hi" + } + ], + "path": [ + "say", + "hi" + ] + } + ] + }, + { + "type": "mcfunction:command_macro", + "range": { + "start": 27, + "end": 44 + } + } + ] + }, + "errors": [] +} + +exports['mcfunction parser entry() Parse "$ this is a macro command" 1'] = { + "node": { + "type": "mcfunction:entry", + "range": { + "start": 0, + "end": 25 + }, + "children": [ + { + "type": "mcfunction:command_macro", + "range": { + "start": 0, + "end": 25 + } + } + ] + }, + "errors": [] +} + +exports['mcfunction parser entry() Parse "execute if true if true run say hi" 1'] = { + "node": { + "type": "mcfunction:entry", + "range": { + "start": 0, + "end": 34 + }, + "children": [ + { + "type": "mcfunction:command", + "range": { + "start": 0, + "end": 34 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 0, + "end": 7 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 0, + "end": 7 + }, + "value": "execute" + } + ], + "path": [ + "execute" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 8, + "end": 10 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 8, + "end": 10 + }, + "value": "if" + } + ], + "path": [ + "execute", + "if" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 11, + "end": 15 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 11, + "end": 15 + }, + "value": "true" + } + ], + "path": [ + "execute", + "if", + "true" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 16, + "end": 18 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 16, + "end": 18 + }, + "value": "if" + } + ], + "path": [ + "execute", + "if" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 19, + "end": 23 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 19, + "end": 23 + }, + "value": "true" + } + ], + "path": [ + "execute", + "if", + "true" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 24, + "end": 27 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 24, + "end": 27 + }, + "value": "run" + } + ], + "path": [ + "execute", + "run" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 28, + "end": 31 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 28, + "end": 31 + }, + "value": "say" + } + ], + "path": [ + "say" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 32, + "end": 34 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 32, + "end": 34 + }, + "value": "hi" + } + ], + "path": [ + "say", + "hi" + ] + } + ] + } + ] + }, + "errors": [] +} + +exports['mcfunction parser entry() Parse "say hi" 1'] = { + "node": { + "type": "mcfunction:entry", + "range": { + "start": 0, + "end": 6 + }, + "children": [ + { + "type": "mcfunction:command", + "range": { + "start": 0, + "end": 6 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 0, + "end": 3 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 0, + "end": 3 + }, + "value": "say" + } + ], + "path": [ + "say" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 4, + "end": 6 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 4, + "end": 6 + }, + "value": "hi" + } + ], + "path": [ + "say", + "hi" + ] + } + ] + } + ] + }, + "errors": [] +} + +exports['mcfunction parser entry() Parse "say hi↓say hi" 1'] = { + "node": { + "type": "mcfunction:entry", + "range": { + "start": 0, + "end": 13 + }, + "children": [ + { + "type": "mcfunction:command", + "range": { + "start": 0, + "end": 6 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 0, + "end": 3 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 0, + "end": 3 + }, + "value": "say" + } + ], + "path": [ + "say" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 4, + "end": 6 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 4, + "end": 6 + }, + "value": "hi" + } + ], + "path": [ + "say", + "hi" + ] + } + ] + }, + { + "type": "mcfunction:command", + "range": { + "start": 7, + "end": 13 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 7, + "end": 10 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 7, + "end": 10 + }, + "value": "say" + } + ], + "path": [ + "say" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 11, + "end": 13 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 11, + "end": 13 + }, + "value": "hi" + } + ], + "path": [ + "say", + "hi" + ] + } + ] + } + ] + }, + "errors": [] +} diff --git a/packages/mcfunction/test/parser/entry.spec.ts b/packages/mcfunction/test/parser/entry.spec.ts new file mode 100644 index 000000000..3e5a30760 --- /dev/null +++ b/packages/mcfunction/test/parser/entry.spec.ts @@ -0,0 +1,30 @@ +import { + mockProjectData, + showWhitespaceGlyph, + testParser, +} from '@spyglassmc/core/test-out/utils.js' +import { describe, it } from 'mocha' +import snapshot from 'snap-shot-it' +import { initialize } from '../../../java-edition/lib/mcfunction/index.js' +import { entry } from '../../lib/parser/index.js' +import { tree } from './utils.js' + +describe('mcfunction parser entry()', () => { + const cases: { content: string }[] = [ + { content: '' }, + { content: 'say hi' }, + { content: 'say hi\nsay hi' }, + { content: '# this is a comment' }, + { content: '$ this is a macro command' }, + { content: '# this is a comment\nsay hi\n$this is a macro \n' }, + { content: 'execute if true if true run say hi' }, + ] + for (const { content } of cases) { + it(`Parse "${showWhitespaceGlyph(content)}"`, () => { + const release = '1.99' + initialize(mockProjectData(), tree, release) + const parser = entry(release, () => undefined) + snapshot(testParser(parser, content)) + }) + } +}) diff --git a/packages/mcfunction/test/parser/utils.ts b/packages/mcfunction/test/parser/utils.ts index d5cb0556b..3e4c2622e 100644 --- a/packages/mcfunction/test/parser/utils.ts +++ b/packages/mcfunction/test/parser/utils.ts @@ -1,4 +1,4 @@ -import type { RootTreeNode } from '../../lib/tree/index.js' +import type { RootTreeNode } from '../../../java-edition/lib/dependency/mcmeta.js' export const tree: RootTreeNode = { type: 'root', From bc18311d721c519ba10b6ece790e3a5e2547bfd9 Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Mon, 20 May 2024 18:55:19 -0400 Subject: [PATCH 10/25] =?UTF-8?q?=F0=9F=A7=AA=20Add=20`entry`=20test=20cas?= =?UTF-8?q?es=20containing=20trailing=20backslashes=20-=20output=20wrong?= =?UTF-8?q?=20thing=20right=20now,=20fixed=20next=20commit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mcfunction/test-out/parser/entry.spec.js | 560 ++++++++++++++++++ packages/mcfunction/test/parser/entry.spec.ts | 5 + 2 files changed, 565 insertions(+) diff --git a/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js b/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js index 598cbdaa2..cdc3155ef 100644 --- a/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js +++ b/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js @@ -10,6 +10,91 @@ exports['mcfunction parser entry() Parse "" 1'] = { "errors": [] } +exports['mcfunction parser entry() Parse "# this is a comment ⧵ ↓ still a comment" 1'] = { + "node": { + "type": "mcfunction:entry", + "range": { + "start": 0, + "end": 39 + }, + "children": [ + { + "type": "comment", + "range": { + "start": 0, + "end": 22 + }, + "comment": " this is a comment \\ " + }, + { + "type": "mcfunction:command", + "range": { + "start": 24, + "end": 39 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 24, + "end": 29 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 24, + "end": 29 + }, + "value": "still" + } + ], + "path": [ + "still" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 29, + "end": 39 + }, + "children": [ + { + "type": "mcfunction:command_child/trailing", + "range": { + "start": 29, + "end": 39 + }, + "value": " a comment" + } + ], + "path": [] + } + ] + } + ] + }, + "errors": [ + { + "range": { + "start": 24, + "end": 29 + }, + "message": "Expected “execute” or “say”", + "severity": 3 + }, + { + "range": { + "start": 29, + "end": 39 + }, + "message": "Trailing data encountered: “ a comment”", + "severity": 3 + } + ] +} + exports['mcfunction parser entry() Parse "# this is a comment" 1'] = { "node": { "type": "mcfunction:entry", @@ -129,6 +214,90 @@ exports['mcfunction parser entry() Parse "$ this is a macro command" 1'] = { "errors": [] } +exports['mcfunction parser entry() Parse "$ this is a macro ⧵ ↓ this is still a macro" 1'] = { + "node": { + "type": "mcfunction:entry", + "range": { + "start": 0, + "end": 43 + }, + "children": [ + { + "type": "mcfunction:command_macro", + "range": { + "start": 0, + "end": 20 + } + }, + { + "type": "mcfunction:command", + "range": { + "start": 22, + "end": 43 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 22, + "end": 26 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 22, + "end": 26 + }, + "value": "this" + } + ], + "path": [ + "this" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 26, + "end": 43 + }, + "children": [ + { + "type": "mcfunction:command_child/trailing", + "range": { + "start": 26, + "end": 43 + }, + "value": " is still a macro" + } + ], + "path": [] + } + ] + } + ] + }, + "errors": [ + { + "range": { + "start": 22, + "end": 26 + }, + "message": "Expected “execute” or “say”", + "severity": 3 + }, + { + "range": { + "start": 26, + "end": 43 + }, + "message": "Trailing data encountered: “ is still a macro”", + "severity": 3 + } + ] +} + exports['mcfunction parser entry() Parse "execute if true if true run say hi" 1'] = { "node": { "type": "mcfunction:entry", @@ -494,3 +663,394 @@ exports['mcfunction parser entry() Parse "say hi↓say hi" 1'] = { }, "errors": [] } + +exports['mcfunction parser entry() Parse "say trailing ⧵↓ data" 1'] = { + "node": { + "type": "mcfunction:entry", + "range": { + "start": 0, + "end": 20 + }, + "children": [ + { + "type": "mcfunction:command", + "range": { + "start": 0, + "end": 14 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 0, + "end": 3 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 0, + "end": 3 + }, + "value": "say" + } + ], + "path": [ + "say" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 4, + "end": 12 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 4, + "end": 12 + }, + "value": "trailing" + } + ], + "path": [ + "say", + "trailing" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 12, + "end": 14 + }, + "children": [ + { + "type": "mcfunction:command_child/trailing", + "range": { + "start": 12, + "end": 14 + }, + "value": " \\" + } + ], + "path": [] + } + ] + }, + { + "type": "mcfunction:command", + "range": { + "start": 16, + "end": 20 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 16, + "end": 20 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 16, + "end": 20 + }, + "value": "data" + } + ], + "path": [ + "data" + ] + } + ] + } + ] + }, + "errors": [ + { + "range": { + "start": 4, + "end": 12 + }, + "message": "Expected “hi”", + "severity": 3 + }, + { + "range": { + "start": 12, + "end": 14 + }, + "message": "Trailing data encountered: “ \\”", + "severity": 3 + }, + { + "range": { + "start": 16, + "end": 20 + }, + "message": "Expected “execute” or “say”", + "severity": 3 + }, + { + "range": { + "start": 20, + "end": 20 + }, + "message": "Expected more arguments", + "severity": 3 + } + ] +} + +exports['mcfunction parser entry() Parse "say ⧵↓ hi ↓ # comment start ⧵↓ end ↓ say hi" 1'] = { + "node": { + "type": "mcfunction:entry", + "range": { + "start": 0, + "end": 43 + }, + "children": [ + { + "type": "mcfunction:command", + "range": { + "start": 0, + "end": 10 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 0, + "end": 3 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 0, + "end": 3 + }, + "value": "say" + } + ], + "path": [ + "say" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 7, + "end": 9 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 7, + "end": 9 + }, + "value": "hi" + } + ], + "path": [ + "say", + "hi" + ] + } + ] + }, + { + "type": "comment", + "range": { + "start": 12, + "end": 29 + }, + "comment": " comment start \\" + }, + { + "type": "mcfunction:command", + "range": { + "start": 31, + "end": 35 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 31, + "end": 34 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 31, + "end": 34 + }, + "value": "end" + } + ], + "path": [ + "end" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 34, + "end": 35 + }, + "children": [ + { + "type": "mcfunction:command_child/trailing", + "range": { + "start": 34, + "end": 35 + }, + "value": " " + } + ], + "path": [] + } + ] + }, + { + "type": "mcfunction:command", + "range": { + "start": 37, + "end": 43 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 37, + "end": 40 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 37, + "end": 40 + }, + "value": "say" + } + ], + "path": [ + "say" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 41, + "end": 43 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 41, + "end": 43 + }, + "value": "hi" + } + ], + "path": [ + "say", + "hi" + ] + } + ] + } + ] + }, + "errors": [ + { + "range": { + "start": 31, + "end": 34 + }, + "message": "Expected “execute” or “say”", + "severity": 3 + }, + { + "range": { + "start": 34, + "end": 35 + }, + "message": "Trailing data encountered: “ ”", + "severity": 3 + } + ] +} + +exports['mcfunction parser entry() Parse "sa⧵ ↓ y ⧵ ↓ hi" 1'] = { + "node": { + "type": "mcfunction:entry", + "range": { + "start": 0, + "end": 16 + }, + "children": [ + { + "type": "mcfunction:command", + "range": { + "start": 0, + "end": 16 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 0, + "end": 9 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 0, + "end": 9 + }, + "value": "say" + } + ], + "path": [ + "say" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 14, + "end": 16 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 14, + "end": 16 + }, + "value": "hi" + } + ], + "path": [ + "say", + "hi" + ] + } + ] + } + ] + }, + "errors": [] +} diff --git a/packages/mcfunction/test/parser/entry.spec.ts b/packages/mcfunction/test/parser/entry.spec.ts index 3e5a30760..51478c8c1 100644 --- a/packages/mcfunction/test/parser/entry.spec.ts +++ b/packages/mcfunction/test/parser/entry.spec.ts @@ -18,6 +18,11 @@ describe('mcfunction parser entry()', () => { { content: '$ this is a macro command' }, { content: '# this is a comment\nsay hi\n$this is a macro \n' }, { content: 'execute if true if true run say hi' }, + { content: '# this is a comment \\ \n still a comment' }, + { content: '$ this is a macro \\ \n this is still a macro' }, + { content: 'sa\\ \n y \\ \n hi' }, + { content: 'say trailing \\\n data' }, + { content: 'say \\\n hi \n # comment start \\\n end \n say hi' }, ] for (const { content } of cases) { it(`Parse "${showWhitespaceGlyph(content)}"`, () => { From 37989acb398be7704a19d6f6ff27bdb09b185621 Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Mon, 20 May 2024 19:42:51 -0400 Subject: [PATCH 11/25] =?UTF-8?q?=F0=9F=90=9B=20Wrap=20mcfunction=20`entry?= =?UTF-8?q?`=20parser=20with=20backslash=20continuation=20parser=20-=20no?= =?UTF-8?q?=20terminators=20specified=20since=20this=20wrapper=20parser=20?= =?UTF-8?q?runs=20once=20at=20the=20start=20of=20mcfunction=20file=20parsi?= =?UTF-8?q?ng=20-=20need=20to=20remove=20backslash=20cont.=20parser=20from?= =?UTF-8?q?=20internal=20`command`=20parser=20for=20these=20tests=20to=20p?= =?UTF-8?q?ass,=20so=20that's=20in=20this=20commit=20too=20=20=20-=20remov?= =?UTF-8?q?e=20command=20parser=20specific=20tests=20around=20backslash=20?= =?UTF-8?q?continuation=20since=20its=20handled=20by=20mcfunction=20entry?= =?UTF-8?q?=20parser=20earlier=20anyway?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test-out/parser/command.spec.js | 204 -------------- .../mcfunction/test-out/parser/entry.spec.js | 259 +----------------- packages/mcfunction/src/parser/command.ts | 9 +- packages/mcfunction/src/parser/entry.ts | 7 +- .../mcfunction/test/parser/command.spec.ts | 4 - 5 files changed, 20 insertions(+), 463 deletions(-) diff --git a/__snapshots__/packages/mcfunction/test-out/parser/command.spec.js b/__snapshots__/packages/mcfunction/test-out/parser/command.spec.js index 69862a207..032c7ed53 100644 --- a/__snapshots__/packages/mcfunction/test-out/parser/command.spec.js +++ b/__snapshots__/packages/mcfunction/test-out/parser/command.spec.js @@ -515,210 +515,6 @@ exports['mcfunction parser command() Parse "say" 1'] = { ] } -exports['mcfunction parser command() Parse "sa⧵ ↓ y hi" 1'] = { - "node": { - "type": "mcfunction:command", - "range": { - "start": 0, - "end": 12 - }, - "children": [ - { - "type": "mcfunction:command_child", - "range": { - "start": 0, - "end": 9 - }, - "children": [ - { - "type": "mcfunction:command_child/literal", - "range": { - "start": 0, - "end": 9 - }, - "value": "say" - } - ], - "path": [ - "say" - ] - }, - { - "type": "mcfunction:command_child", - "range": { - "start": 10, - "end": 12 - }, - "children": [ - { - "type": "mcfunction:command_child/literal", - "range": { - "start": 10, - "end": 12 - }, - "value": "hi" - } - ], - "path": [ - "say", - "hi" - ] - } - ] - }, - "errors": [] -} - -exports['mcfunction parser command() Parse "sa⧵ ↓ y h⧵ ↓ i" 1'] = { - "node": { - "type": "mcfunction:command", - "range": { - "start": 0, - "end": 16 - }, - "children": [ - { - "type": "mcfunction:command_child", - "range": { - "start": 0, - "end": 9 - }, - "children": [ - { - "type": "mcfunction:command_child/literal", - "range": { - "start": 0, - "end": 9 - }, - "value": "say" - } - ], - "path": [ - "say" - ] - }, - { - "type": "mcfunction:command_child", - "range": { - "start": 10, - "end": 16 - }, - "children": [ - { - "type": "mcfunction:command_child/literal", - "range": { - "start": 10, - "end": 16 - }, - "value": "hi" - } - ], - "path": [ - "say", - "hi" - ] - } - ] - }, - "errors": [] -} - -exports['mcfunction parser command() Parse "sa⧵↓y hi" 1'] = { - "node": { - "type": "mcfunction:command", - "range": { - "start": 0, - "end": 8 - }, - "children": [ - { - "type": "mcfunction:command_child", - "range": { - "start": 0, - "end": 5 - }, - "children": [ - { - "type": "mcfunction:command_child/literal", - "range": { - "start": 0, - "end": 5 - }, - "value": "say" - } - ], - "path": [ - "say" - ] - }, - { - "type": "mcfunction:command_child", - "range": { - "start": 6, - "end": 8 - }, - "children": [ - { - "type": "mcfunction:command_child/literal", - "range": { - "start": 6, - "end": 8 - }, - "value": "hi" - } - ], - "path": [ - "say", - "hi" - ] - } - ] - }, - "errors": [] -} - -exports['mcfunction parser command() Parse "sa⧵↓↓y h⧵ ↓ i" 1'] = { - "node": { - "type": "mcfunction:command", - "range": { - "start": 0, - "end": 4 - }, - "children": [ - { - "type": "mcfunction:command_child", - "range": { - "start": 0, - "end": 4 - }, - "children": [ - { - "type": "mcfunction:command_child/literal", - "range": { - "start": 0, - "end": 4 - }, - "value": "sa" - } - ], - "path": [ - "sa" - ] - } - ] - }, - "errors": [ - { - "range": { - "start": 0, - "end": 4 - }, - "message": "Expected “execute” or “say”", - "severity": 3 - } - ] -} - exports['mcfunction parser command() Should not exceed max call stack 1'] = { "node": "OMITTED", "errors": [ diff --git a/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js b/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js index cdc3155ef..7b338e73f 100644 --- a/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js +++ b/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js @@ -22,77 +22,13 @@ exports['mcfunction parser entry() Parse "# this is a comment ⧵ ↓ still a co "type": "comment", "range": { "start": 0, - "end": 22 - }, - "comment": " this is a comment \\ " - }, - { - "type": "mcfunction:command", - "range": { - "start": 24, "end": 39 }, - "children": [ - { - "type": "mcfunction:command_child", - "range": { - "start": 24, - "end": 29 - }, - "children": [ - { - "type": "mcfunction:command_child/literal", - "range": { - "start": 24, - "end": 29 - }, - "value": "still" - } - ], - "path": [ - "still" - ] - }, - { - "type": "mcfunction:command_child", - "range": { - "start": 29, - "end": 39 - }, - "children": [ - { - "type": "mcfunction:command_child/trailing", - "range": { - "start": 29, - "end": 39 - }, - "value": " a comment" - } - ], - "path": [] - } - ] + "comment": " this is a comment still a comment" } ] }, - "errors": [ - { - "range": { - "start": 24, - "end": 29 - }, - "message": "Expected “execute” or “say”", - "severity": 3 - }, - { - "range": { - "start": 29, - "end": 39 - }, - "message": "Trailing data encountered: “ a comment”", - "severity": 3 - } - ] + "errors": [] } exports['mcfunction parser entry() Parse "# this is a comment" 1'] = { @@ -226,76 +162,12 @@ exports['mcfunction parser entry() Parse "$ this is a macro ⧵ ↓ this is stil "type": "mcfunction:command_macro", "range": { "start": 0, - "end": 20 - } - }, - { - "type": "mcfunction:command", - "range": { - "start": 22, "end": 43 - }, - "children": [ - { - "type": "mcfunction:command_child", - "range": { - "start": 22, - "end": 26 - }, - "children": [ - { - "type": "mcfunction:command_child/literal", - "range": { - "start": 22, - "end": 26 - }, - "value": "this" - } - ], - "path": [ - "this" - ] - }, - { - "type": "mcfunction:command_child", - "range": { - "start": 26, - "end": 43 - }, - "children": [ - { - "type": "mcfunction:command_child/trailing", - "range": { - "start": 26, - "end": 43 - }, - "value": " is still a macro" - } - ], - "path": [] - } - ] + } } ] }, - "errors": [ - { - "range": { - "start": 22, - "end": 26 - }, - "message": "Expected “execute” or “say”", - "severity": 3 - }, - { - "range": { - "start": 26, - "end": 43 - }, - "message": "Trailing data encountered: “ is still a macro”", - "severity": 3 - } - ] + "errors": [] } exports['mcfunction parser entry() Parse "execute if true if true run say hi" 1'] = { @@ -676,7 +548,7 @@ exports['mcfunction parser entry() Parse "say trailing ⧵↓ data" 1'] = { "type": "mcfunction:command", "range": { "start": 0, - "end": 14 + "end": 20 }, "children": [ { @@ -724,48 +596,19 @@ exports['mcfunction parser entry() Parse "say trailing ⧵↓ data" 1'] = { "type": "mcfunction:command_child", "range": { "start": 12, - "end": 14 + "end": 20 }, "children": [ { "type": "mcfunction:command_child/trailing", "range": { "start": 12, - "end": 14 - }, - "value": " \\" - } - ], - "path": [] - } - ] - }, - { - "type": "mcfunction:command", - "range": { - "start": 16, - "end": 20 - }, - "children": [ - { - "type": "mcfunction:command_child", - "range": { - "start": 16, - "end": 20 - }, - "children": [ - { - "type": "mcfunction:command_child/literal", - "range": { - "start": 16, "end": 20 }, - "value": "data" + "value": " data" } ], - "path": [ - "data" - ] + "path": [] } ] } @@ -783,25 +626,9 @@ exports['mcfunction parser entry() Parse "say trailing ⧵↓ data" 1'] = { { "range": { "start": 12, - "end": 14 - }, - "message": "Trailing data encountered: “ \\”", - "severity": 3 - }, - { - "range": { - "start": 16, - "end": 20 - }, - "message": "Expected “execute” or “say”", - "severity": 3 - }, - { - "range": { - "start": 20, "end": 20 }, - "message": "Expected more arguments", + "message": "Trailing data encountered: “ data”", "severity": 3 } ] @@ -869,56 +696,9 @@ exports['mcfunction parser entry() Parse "say ⧵↓ hi ↓ # comment start ⧵ "type": "comment", "range": { "start": 12, - "end": 29 - }, - "comment": " comment start \\" - }, - { - "type": "mcfunction:command", - "range": { - "start": 31, "end": 35 }, - "children": [ - { - "type": "mcfunction:command_child", - "range": { - "start": 31, - "end": 34 - }, - "children": [ - { - "type": "mcfunction:command_child/literal", - "range": { - "start": 31, - "end": 34 - }, - "value": "end" - } - ], - "path": [ - "end" - ] - }, - { - "type": "mcfunction:command_child", - "range": { - "start": 34, - "end": 35 - }, - "children": [ - { - "type": "mcfunction:command_child/trailing", - "range": { - "start": 34, - "end": 35 - }, - "value": " " - } - ], - "path": [] - } - ] + "comment": " comment start end " }, { "type": "mcfunction:command", @@ -972,24 +752,7 @@ exports['mcfunction parser entry() Parse "say ⧵↓ hi ↓ # comment start ⧵ } ] }, - "errors": [ - { - "range": { - "start": 31, - "end": 34 - }, - "message": "Expected “execute” or “say”", - "severity": 3 - }, - { - "range": { - "start": 34, - "end": 35 - }, - "message": "Trailing data encountered: “ ”", - "severity": 3 - } - ] + "errors": [] } exports['mcfunction parser entry() Parse "sa⧵ ↓ y ⧵ ↓ hi" 1'] = { diff --git a/packages/mcfunction/src/parser/command.ts b/packages/mcfunction/src/parser/command.ts index 81e3ac610..a3041c92a 100644 --- a/packages/mcfunction/src/parser/command.ts +++ b/packages/mcfunction/src/parser/command.ts @@ -94,12 +94,9 @@ function dispatch( parser: argument(treeNode) ?? unknown(treeNode), })) const literalParser = literalTreeNodes.length - ? core.concatOnTrailingBackslash( - literal( - literalTreeNodes.map(([name, _treeNode]) => name), - parent.type === 'root', - ), - [' ', '\n', '\r'], + ? literal( + literalTreeNodes.map(([name, _treeNode]) => name), + parent.type === 'root', ) : undefined diff --git a/packages/mcfunction/src/parser/entry.ts b/packages/mcfunction/src/parser/entry.ts index c4522e9aa..fbff4d947 100644 --- a/packages/mcfunction/src/parser/entry.ts +++ b/packages/mcfunction/src/parser/entry.ts @@ -11,7 +11,7 @@ import { command } from './command.js' /** * @throws When there's no command tree associated with `commandTreeName`. */ -export function entry( +function mcfunction( commandTreeName: string, argument: ArgumentParserGetter, ): core.Parser { @@ -52,3 +52,8 @@ export function entry( const comment = core.comment({ singleLinePrefixes: new Set(['#']), }) + +export const entry = ( + commandTreeName: string, + argument: ArgumentParserGetter, +) => core.concatOnTrailingBackslash(mcfunction(commandTreeName, argument), []) diff --git a/packages/mcfunction/test/parser/command.spec.ts b/packages/mcfunction/test/parser/command.spec.ts index da1f4f667..e572bbea9 100644 --- a/packages/mcfunction/test/parser/command.spec.ts +++ b/packages/mcfunction/test/parser/command.spec.ts @@ -18,10 +18,6 @@ describe('mcfunction parser command()', () => { { content: 'say hi ' }, { content: 'say hi garbage text' }, { content: 'execute if true if true run say hi' }, - { content: 'sa\\\ny hi' }, - { content: 'sa\\ \n y hi' }, - { content: 'sa\\ \n y h\\ \n i' }, - { content: 'sa\\\n\ny h\\ \n i' }, ] for (const { content } of cases) { it(`Parse "${showWhitespaceGlyph(content)}"`, () => { From 5bd35001ef078b5ca417aba6003b7d8de66b4d2e Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Mon, 20 May 2024 19:44:01 -0400 Subject: [PATCH 12/25] =?UTF-8?q?=F0=9F=94=A7=20Add=20long=20timeout=20arg?= =?UTF-8?q?=20to=20unit=20test=20launch=20configuration=20-=20when=20you'r?= =?UTF-8?q?e=20debugging=20these,=20it's=20not=20unlikely=20you'd=20be=20i?= =?UTF-8?q?n=20a=20test=20longer=20than=2030s=20(the=20default=20timeout)?= =?UTF-8?q?=20-=20new=20default=20is=20999999s=20(11.5=20days)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index cb4b95ef3..c875b646f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,7 +8,9 @@ "request": "launch", "name": "Launch Client", "runtimeExecutable": "${execPath}", - "args": ["--extensionDevelopmentPath=${workspaceRoot}/packages/vscode-extension"], + "args": [ + "--extensionDevelopmentPath=${workspaceRoot}/packages/vscode-extension" + ], "outFiles": ["${workspaceRoot}/packages/vscode-extension/dist/**/*.js"], "preLaunchTask": "npm: watch" }, @@ -26,6 +28,7 @@ "request": "launch", "name": "Run Unit Tests", "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": ["--timeout", "999999"], "console": "integratedTerminal", "internalConsoleOptions": "neverOpen" } From 80262775e2d9a1a1a0d1338775a2e70e02fc3945 Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Mon, 20 May 2024 19:51:15 -0400 Subject: [PATCH 13/25] =?UTF-8?q?=E2=8F=AA=20Revert=20`argument`=20parser?= =?UTF-8?q?=20to=20use=20`stopBefore`=20again=20-=20no=20child=20parsers?= =?UTF-8?q?=20should=20really=20directly=20use=20the=20new=20`concat`=20pa?= =?UTF-8?q?rser=20-=20remove=20tests=20specific=20to=20backslash=20continu?= =?UTF-8?q?ation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../argument/minecraftComponent.spec.js | 314 ------------------ .../src/mcfunction/parser/argument.ts | 2 +- .../test/mcfunction/parser/argument.spec.ts | 4 - 3 files changed, 1 insertion(+), 319 deletions(-) diff --git a/__snapshots__/packages/java-edition/test-out/mcfunction/parser/argument/minecraftComponent.spec.js b/__snapshots__/packages/java-edition/test-out/mcfunction/parser/argument/minecraftComponent.spec.js index e4d8a7fe1..d657d65c6 100644 --- a/__snapshots__/packages/java-edition/test-out/mcfunction/parser/argument/minecraftComponent.spec.js +++ b/__snapshots__/packages/java-edition/test-out/mcfunction/parser/argument/minecraftComponent.spec.js @@ -108,320 +108,6 @@ exports['mcfunction argument minecraft:component Parse "[""]" 1'] = { "errors": [] } -exports['mcfunction argument minecraft:component Parse "["hello ⧵ ↓world"]" 1'] = { - "node": { - "type": "json:array", - "range": { - "start": 0, - "end": 18 - }, - "children": [ - { - "type": "item", - "range": { - "start": 1, - "end": 17 - }, - "children": [ - { - "type": "json:string", - "range": { - "start": 1, - "end": 17 - }, - "value": "hello world", - "valueMap": [ - { - "inner": { - "start": 0, - "end": 0 - }, - "outer": { - "start": 2, - "end": 2 - } - } - ] - } - ], - "value": { - "type": "json:string", - "range": { - "start": 1, - "end": 17 - }, - "value": "hello world", - "valueMap": [ - { - "inner": { - "start": 0, - "end": 0 - }, - "outer": { - "start": 2, - "end": 2 - } - } - ] - } - } - ] - }, - "errors": [] -} - -exports['mcfunction argument minecraft:component Parse "["hello⧵↓↓world"]" 1'] = { - "node": { - "type": "json:array", - "range": { - "start": 0, - "end": 9 - }, - "children": [ - { - "type": "item", - "range": { - "start": 1, - "end": 9 - }, - "children": [ - { - "type": "json:string", - "range": { - "start": 1, - "end": 9 - }, - "value": "hello", - "valueMap": [ - { - "inner": { - "start": 0, - "end": 0 - }, - "outer": { - "start": 2, - "end": 2 - } - } - ] - } - ], - "value": { - "type": "json:string", - "range": { - "start": 1, - "end": 9 - }, - "value": "hello", - "valueMap": [ - { - "inner": { - "start": 0, - "end": 0 - }, - "outer": { - "start": 2, - "end": 2 - } - } - ] - } - } - ] - }, - "errors": [ - { - "range": { - "start": 9, - "end": 9 - }, - "message": "Expected “\"”", - "severity": 3 - }, - { - "range": { - "start": 9, - "end": 9 - }, - "message": "Expected “]”", - "severity": 3 - } - ] -} - -exports['mcfunction argument minecraft:component Parse "["⧵u12⧵ ↓ 34"]" 1'] = { - "node": { - "type": "json:array", - "range": { - "start": 0, - "end": 16 - }, - "children": [ - { - "type": "item", - "range": { - "start": 1, - "end": 15 - }, - "children": [ - { - "type": "json:string", - "range": { - "start": 1, - "end": 15 - }, - "value": "ሴ", - "valueMap": [ - { - "inner": { - "start": 0, - "end": 0 - }, - "outer": { - "start": 2, - "end": 2 - } - }, - { - "inner": { - "start": 0, - "end": 1 - }, - "outer": { - "start": 2, - "end": 14 - } - } - ] - } - ], - "value": { - "type": "json:string", - "range": { - "start": 1, - "end": 15 - }, - "value": "ሴ", - "valueMap": [ - { - "inner": { - "start": 0, - "end": 0 - }, - "outer": { - "start": 2, - "end": 2 - } - }, - { - "inner": { - "start": 0, - "end": 1 - }, - "outer": { - "start": 2, - "end": 14 - } - } - ] - } - } - ] - }, - "errors": [] -} - -exports['mcfunction argument minecraft:component Parse "["⧵uab⧵ ↓ nd"]" 1'] = { - "node": { - "type": "json:array", - "range": { - "start": 0, - "end": 16 - }, - "children": [ - { - "type": "item", - "range": { - "start": 1, - "end": 15 - }, - "children": [ - { - "type": "json:string", - "range": { - "start": 1, - "end": 15 - }, - "value": "uabnd", - "valueMap": [ - { - "inner": { - "start": 0, - "end": 0 - }, - "outer": { - "start": 2, - "end": 2 - } - }, - { - "inner": { - "start": 0, - "end": 1 - }, - "outer": { - "start": 2, - "end": 4 - } - } - ] - } - ], - "value": { - "type": "json:string", - "range": { - "start": 1, - "end": 15 - }, - "value": "uabnd", - "valueMap": [ - { - "inner": { - "start": 0, - "end": 0 - }, - "outer": { - "start": 2, - "end": 2 - } - }, - { - "inner": { - "start": 0, - "end": 1 - }, - "outer": { - "start": 2, - "end": 4 - } - } - ] - } - } - ] - }, - "errors": [ - { - "range": { - "start": 4, - "end": 14 - }, - "message": "Hexadecimal digit expected", - "severity": 3 - } - ] -} - exports['mcfunction argument minecraft:component Parse "{"text":"hello world"}" 1'] = { "node": { "type": "json:object", diff --git a/packages/java-edition/src/mcfunction/parser/argument.ts b/packages/java-edition/src/mcfunction/parser/argument.ts index 19cf08327..981f9ddf8 100644 --- a/packages/java-edition/src/mcfunction/parser/argument.ts +++ b/packages/java-edition/src/mcfunction/parser/argument.ts @@ -91,7 +91,7 @@ export const argument: mcf.ArgumentParserGetter = ( const treeNode = rawTreeNode as ArgumentTreeNode const wrap = (parser: core.Parser): core.Parser => - core.failOnEmpty(core.concatOnTrailingBackslash(parser, ['\r', '\n'])) + core.failOnEmpty(core.stopBefore(parser, '\r', '\n')) switch (treeNode.parser) { case 'brigadier:bool': diff --git a/packages/java-edition/test/mcfunction/parser/argument.spec.ts b/packages/java-edition/test/mcfunction/parser/argument.spec.ts index 52544cb9c..5ff006186 100644 --- a/packages/java-edition/test/mcfunction/parser/argument.spec.ts +++ b/packages/java-edition/test/mcfunction/parser/argument.spec.ts @@ -79,10 +79,6 @@ const Suites: Partial< '""', '{"text":"hello world"}', '[""]', - '["hello \\ \nworld"]', - '["hello\\\n\nworld"]', - '["\\u12\\ \n 34"]', - '["\\uab\\ \n nd"]', ], }, ], From 7f63ab2c3fe422ecf9dca86c9fd3a4ad7a081f15 Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Mon, 20 May 2024 19:56:56 -0400 Subject: [PATCH 14/25] =?UTF-8?q?=E2=9A=B0=EF=B8=8F=20Remove=20`terminator?= =?UTF-8?q?s`=20argument=20from=20concat=20parser=20-=20it=20never=20stops?= =?UTF-8?q?=20at=20specific=20terminators=20other=20than=20end=20of=20stri?= =?UTF-8?q?ng=20since=20its=20called=20on=20entry=20now?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/parser/util.ts | 11 +++-------- packages/core/test/parser/util.spec.ts | 2 +- packages/mcfunction/src/parser/entry.ts | 2 +- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/packages/core/src/parser/util.ts b/packages/core/src/parser/util.ts index 5dcd9516f..9fecbf150 100644 --- a/packages/core/src/parser/util.ts +++ b/packages/core/src/parser/util.ts @@ -507,8 +507,6 @@ export function stopBefore( } /** - * @param terminators A list of characters the parser will stop at if it finds them - * before a backslash * @returns A parser that is based on the passed-in `parser`, but concatenates lines * together when we reach, in order: * - a backslash @@ -518,15 +516,12 @@ export function stopBefore( */ export function concatOnTrailingBackslash( parser: InfallibleParser, - terminators: string[], ): InfallibleParser export function concatOnTrailingBackslash( parser: Parser, - terminators: string[], ): Parser export function concatOnTrailingBackslash( parser: Parser, - terminators: string[], ): Parser { return (src, ctx): Result => { let wrappedStr = src.sliceToCursor(0) @@ -534,9 +529,9 @@ export function concatOnTrailingBackslash( const wrappedSrcCursor = wrappedStr.length const indexMap: IndexMap = [] - while (src.canRead() && !terminators.includes(src.peek())) { - wrappedStr += src.readUntil(wrapper, ...terminators) - if (!src.canRead() || terminators.includes(src.peek())) { + while (src.canRead()) { + wrappedStr += src.readUntil(wrapper) + if (!src.canRead()) { // Stop wrapping `src` if we reach end of file or a terminator before a wrapper break } diff --git a/packages/core/test/parser/util.spec.ts b/packages/core/test/parser/util.spec.ts index 93d867526..8cac53539 100644 --- a/packages/core/test/parser/util.spec.ts +++ b/packages/core/test/parser/util.spec.ts @@ -154,7 +154,7 @@ describe('concatOnTrailingBackslash()', () => { it( `Parse "${showWhitespaceGlyph(content)}"`, () => { - const wrappedParser = concatOnTrailingBackslash(parser, ['\n']) + const wrappedParser = concatOnTrailingBackslash(parser) snapshot(testParser(wrappedParser, content)) }, ) diff --git a/packages/mcfunction/src/parser/entry.ts b/packages/mcfunction/src/parser/entry.ts index fbff4d947..b02838dc1 100644 --- a/packages/mcfunction/src/parser/entry.ts +++ b/packages/mcfunction/src/parser/entry.ts @@ -56,4 +56,4 @@ const comment = core.comment({ export const entry = ( commandTreeName: string, argument: ArgumentParserGetter, -) => core.concatOnTrailingBackslash(mcfunction(commandTreeName, argument), []) +) => core.concatOnTrailingBackslash(mcfunction(commandTreeName, argument)) From eafa3a4935159034e9341577d1c4a288f5009718 Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Mon, 20 May 2024 20:03:08 -0400 Subject: [PATCH 15/25] =?UTF-8?q?=F0=9F=8E=A8=20Revert=20formatting=20chan?= =?UTF-8?q?ge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java-edition/test/mcfunction/parser/argument.spec.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/java-edition/test/mcfunction/parser/argument.spec.ts b/packages/java-edition/test/mcfunction/parser/argument.spec.ts index 5ff006186..3aa7cdee8 100644 --- a/packages/java-edition/test/mcfunction/parser/argument.spec.ts +++ b/packages/java-edition/test/mcfunction/parser/argument.spec.ts @@ -74,12 +74,7 @@ const Suites: Partial< 'minecraft:column_pos': [{ content: ['0 0', '~ ~', '~1 ~-2'] }], 'minecraft:component': [ { - content: [ - '"hello world"', - '""', - '{"text":"hello world"}', - '[""]', - ], + content: ['"hello world"', '""', '{"text":"hello world"}', '[""]'], }, ], 'minecraft:dimension': [ From f3b36b493d1e2dd2a42c25b4eb05b82adae19f20 Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Mon, 20 May 2024 20:09:27 -0400 Subject: [PATCH 16/25] =?UTF-8?q?=F0=9F=93=9D=20Add=20documentation=20to?= =?UTF-8?q?=20new=20`entry`=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/mcfunction/src/parser/entry.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/mcfunction/src/parser/entry.ts b/packages/mcfunction/src/parser/entry.ts index b02838dc1..5c80c7a80 100644 --- a/packages/mcfunction/src/parser/entry.ts +++ b/packages/mcfunction/src/parser/entry.ts @@ -53,6 +53,10 @@ const comment = core.comment({ singleLinePrefixes: new Set(['#']), }) +/** + * Concatenates lines together on trailing backslashes before running the main + * {@link mcfunction} parser + */ export const entry = ( commandTreeName: string, argument: ArgumentParserGetter, From 4bbe49868371987a26a024c9d3eb41bcd59d5c92 Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Mon, 20 May 2024 20:57:22 -0400 Subject: [PATCH 17/25] =?UTF-8?q?=E2=9A=B0=EF=B8=8F=20Remove=20old=20comme?= =?UTF-8?q?nt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/parser/util.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/src/parser/util.ts b/packages/core/src/parser/util.ts index 9fecbf150..59cf5bfd7 100644 --- a/packages/core/src/parser/util.ts +++ b/packages/core/src/parser/util.ts @@ -532,7 +532,6 @@ export function concatOnTrailingBackslash( while (src.canRead()) { wrappedStr += src.readUntil(wrapper) if (!src.canRead()) { - // Stop wrapping `src` if we reach end of file or a terminator before a wrapper break } From 4ac277e9079744b48da41c8b77fce6502d8ee155 Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Mon, 20 May 2024 20:58:16 -0400 Subject: [PATCH 18/25] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Replace=20`wrapper`?= =?UTF-8?q?=20var=20with=20inline=20string?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/parser/util.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/core/src/parser/util.ts b/packages/core/src/parser/util.ts index 59cf5bfd7..ed87eb0c0 100644 --- a/packages/core/src/parser/util.ts +++ b/packages/core/src/parser/util.ts @@ -525,17 +525,16 @@ export function concatOnTrailingBackslash( ): Parser { return (src, ctx): Result => { let wrappedStr = src.sliceToCursor(0) - const wrapper = '\\' const wrappedSrcCursor = wrappedStr.length const indexMap: IndexMap = [] while (src.canRead()) { - wrappedStr += src.readUntil(wrapper) + wrappedStr += src.readUntil('\\') if (!src.canRead()) { break } - // If we get here, then `src.cursor` is at a wrapper + // If we get here, then `src.cursor` is at a backslash if (src.hasNonSpaceAheadInLine(1)) { wrappedStr += src.read() continue From 67eab687f83e4c6757fa9fcb4cb54f15cc763fd0 Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Mon, 20 May 2024 22:21:44 -0400 Subject: [PATCH 19/25] =?UTF-8?q?=F0=9F=92=9A=20Register=20command=20tree?= =?UTF-8?q?=20smarter=20-=20no=20more=20java-edition=20dependency=20-=20it?= =?UTF-8?q?=20was=20pretty=20easy=20idk=20why=20i=20didn't=20think=20of=20?= =?UTF-8?q?this=20before?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/mcfunction/test/parser/entry.spec.ts | 6 +++--- packages/mcfunction/test/parser/utils.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/mcfunction/test/parser/entry.spec.ts b/packages/mcfunction/test/parser/entry.spec.ts index 51478c8c1..6ed2a792f 100644 --- a/packages/mcfunction/test/parser/entry.spec.ts +++ b/packages/mcfunction/test/parser/entry.spec.ts @@ -5,11 +5,13 @@ import { } from '@spyglassmc/core/test-out/utils.js' import { describe, it } from 'mocha' import snapshot from 'snap-shot-it' -import { initialize } from '../../../java-edition/lib/mcfunction/index.js' +import { CommandTreeRegistry } from '../../lib/index.js' import { entry } from '../../lib/parser/index.js' import { tree } from './utils.js' describe('mcfunction parser entry()', () => { + const release = '1.99' + CommandTreeRegistry.instance.register(release, tree) const cases: { content: string }[] = [ { content: '' }, { content: 'say hi' }, @@ -26,8 +28,6 @@ describe('mcfunction parser entry()', () => { ] for (const { content } of cases) { it(`Parse "${showWhitespaceGlyph(content)}"`, () => { - const release = '1.99' - initialize(mockProjectData(), tree, release) const parser = entry(release, () => undefined) snapshot(testParser(parser, content)) }) diff --git a/packages/mcfunction/test/parser/utils.ts b/packages/mcfunction/test/parser/utils.ts index 3e4c2622e..2f39aa69f 100644 --- a/packages/mcfunction/test/parser/utils.ts +++ b/packages/mcfunction/test/parser/utils.ts @@ -1,4 +1,4 @@ -import type { RootTreeNode } from '../../../java-edition/lib/dependency/mcmeta.js' +import type { RootTreeNode } from '../../lib/index.js' export const tree: RootTreeNode = { type: 'root', From 0cf6c177da3b82b1f329547edb6e47a73debab26 Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Mon, 20 May 2024 22:31:16 -0400 Subject: [PATCH 20/25] =?UTF-8?q?=E2=8F=AA=20Revert=20launch.json=20change?= =?UTF-8?q?s=20-=20split=20to=20https://github.com/SpyglassMC/Spyglass/pul?= =?UTF-8?q?l/1189?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index c875b646f..cb4b95ef3 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,9 +8,7 @@ "request": "launch", "name": "Launch Client", "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceRoot}/packages/vscode-extension" - ], + "args": ["--extensionDevelopmentPath=${workspaceRoot}/packages/vscode-extension"], "outFiles": ["${workspaceRoot}/packages/vscode-extension/dist/**/*.js"], "preLaunchTask": "npm: watch" }, @@ -28,7 +26,6 @@ "request": "launch", "name": "Run Unit Tests", "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", - "args": ["--timeout", "999999"], "console": "integratedTerminal", "internalConsoleOptions": "neverOpen" } From c16a08a191a2d157d981528a4ab7d1efd782ec4a Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Tue, 21 May 2024 11:19:17 -0400 Subject: [PATCH 21/25] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Gate=20backslash=20c?= =?UTF-8?q?ontinuation=20behind=20parameter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mcfunction/test-out/parser/entry.spec.js | 488 ++++++++++++++++++ packages/java-edition/src/mcfunction/index.ts | 2 +- packages/mcfunction/src/parser/entry.ts | 12 +- packages/mcfunction/test/parser/entry.spec.ts | 13 + 4 files changed, 511 insertions(+), 4 deletions(-) diff --git a/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js b/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js index 7b338e73f..f77ecc777 100644 --- a/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js +++ b/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js @@ -423,6 +423,69 @@ exports['mcfunction parser entry() Parse "say hi" 1'] = { "errors": [] } +exports['mcfunction parser entry() Parse "say hi" without backslash continuation 1'] = { + "node": { + "type": "mcfunction:entry", + "range": { + "start": 0, + "end": 6 + }, + "children": [ + { + "type": "mcfunction:command", + "range": { + "start": 0, + "end": 6 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 0, + "end": 3 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 0, + "end": 3 + }, + "value": "say" + } + ], + "path": [ + "say" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 4, + "end": 6 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 4, + "end": 6 + }, + "value": "hi" + } + ], + "path": [ + "say", + "hi" + ] + } + ] + } + ] + }, + "errors": [] +} + exports['mcfunction parser entry() Parse "say hi↓say hi" 1'] = { "node": { "type": "mcfunction:entry", @@ -536,6 +599,119 @@ exports['mcfunction parser entry() Parse "say hi↓say hi" 1'] = { "errors": [] } +exports['mcfunction parser entry() Parse "say hi↓say hi" without backslash continuation 1'] = { + "node": { + "type": "mcfunction:entry", + "range": { + "start": 0, + "end": 13 + }, + "children": [ + { + "type": "mcfunction:command", + "range": { + "start": 0, + "end": 6 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 0, + "end": 3 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 0, + "end": 3 + }, + "value": "say" + } + ], + "path": [ + "say" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 4, + "end": 6 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 4, + "end": 6 + }, + "value": "hi" + } + ], + "path": [ + "say", + "hi" + ] + } + ] + }, + { + "type": "mcfunction:command", + "range": { + "start": 7, + "end": 13 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 7, + "end": 10 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 7, + "end": 10 + }, + "value": "say" + } + ], + "path": [ + "say" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 11, + "end": 13 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 11, + "end": 13 + }, + "value": "hi" + } + ], + "path": [ + "say", + "hi" + ] + } + ] + } + ] + }, + "errors": [] +} + exports['mcfunction parser entry() Parse "say trailing ⧵↓ data" 1'] = { "node": { "type": "mcfunction:entry", @@ -634,6 +810,141 @@ exports['mcfunction parser entry() Parse "say trailing ⧵↓ data" 1'] = { ] } +exports['mcfunction parser entry() Parse "say trailing ⧵↓ data" without backslash continuation 1'] = { + "node": { + "type": "mcfunction:entry", + "range": { + "start": 0, + "end": 20 + }, + "children": [ + { + "type": "mcfunction:command", + "range": { + "start": 0, + "end": 14 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 0, + "end": 3 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 0, + "end": 3 + }, + "value": "say" + } + ], + "path": [ + "say" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 4, + "end": 12 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 4, + "end": 12 + }, + "value": "trailing" + } + ], + "path": [ + "say", + "trailing" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 12, + "end": 14 + }, + "children": [ + { + "type": "mcfunction:command_child/trailing", + "range": { + "start": 12, + "end": 14 + }, + "value": " \\" + } + ], + "path": [] + } + ] + }, + { + "type": "mcfunction:command", + "range": { + "start": 16, + "end": 20 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 16, + "end": 20 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 16, + "end": 20 + }, + "value": "data" + } + ], + "path": [ + "data" + ] + } + ] + } + ] + }, + "errors": [ + { + "range": { + "start": 4, + "end": 12 + }, + "message": "Expected “hi”", + "severity": 3 + }, + { + "range": { + "start": 12, + "end": 14 + }, + "message": "Trailing data encountered: “ \\”", + "severity": 3 + }, + { + "range": { + "start": 16, + "end": 20 + }, + "message": "Expected “execute” or “say”", + "severity": 3 + } + ] +} + exports['mcfunction parser entry() Parse "say ⧵↓ hi ↓ # comment start ⧵↓ end ↓ say hi" 1'] = { "node": { "type": "mcfunction:entry", @@ -817,3 +1128,180 @@ exports['mcfunction parser entry() Parse "sa⧵ ↓ y ⧵ ↓ hi" 1'] = { }, "errors": [] } + +exports['mcfunction parser entry() Parse "sa⧵ ↓ y ⧵ ↓ hi" without backslash continuation 1'] = { + "node": { + "type": "mcfunction:entry", + "range": { + "start": 0, + "end": 16 + }, + "children": [ + { + "type": "mcfunction:command", + "range": { + "start": 0, + "end": 5 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 0, + "end": 3 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 0, + "end": 3 + }, + "value": "sa\\" + } + ], + "path": [ + "sa\\" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 3, + "end": 5 + }, + "children": [ + { + "type": "mcfunction:command_child/trailing", + "range": { + "start": 3, + "end": 5 + }, + "value": " " + } + ], + "path": [] + } + ] + }, + { + "type": "mcfunction:command", + "range": { + "start": 8, + "end": 12 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 8, + "end": 9 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 8, + "end": 9 + }, + "value": "y" + } + ], + "path": [ + "y" + ] + }, + { + "type": "mcfunction:command_child", + "range": { + "start": 9, + "end": 12 + }, + "children": [ + { + "type": "mcfunction:command_child/trailing", + "range": { + "start": 9, + "end": 12 + }, + "value": " \\ " + } + ], + "path": [] + } + ] + }, + { + "type": "mcfunction:command", + "range": { + "start": 14, + "end": 16 + }, + "children": [ + { + "type": "mcfunction:command_child", + "range": { + "start": 14, + "end": 16 + }, + "children": [ + { + "type": "mcfunction:command_child/literal", + "range": { + "start": 14, + "end": 16 + }, + "value": "hi" + } + ], + "path": [ + "hi" + ] + } + ] + } + ] + }, + "errors": [ + { + "range": { + "start": 0, + "end": 3 + }, + "message": "Expected “execute” or “say”", + "severity": 3 + }, + { + "range": { + "start": 3, + "end": 5 + }, + "message": "Trailing data encountered: “ ”", + "severity": 3 + }, + { + "range": { + "start": 8, + "end": 9 + }, + "message": "Expected “execute” or “say”", + "severity": 3 + }, + { + "range": { + "start": 9, + "end": 12 + }, + "message": "Trailing data encountered: “ \\ ”", + "severity": 3 + }, + { + "range": { + "start": 14, + "end": 16 + }, + "message": "Expected “execute” or “say”", + "severity": 3 + } + ] +} diff --git a/packages/java-edition/src/mcfunction/index.ts b/packages/java-edition/src/mcfunction/index.ts index 9809bbbea..34ce81e2a 100644 --- a/packages/java-edition/src/mcfunction/index.ts +++ b/packages/java-edition/src/mcfunction/index.ts @@ -31,7 +31,7 @@ export const initialize = ( meta.registerLanguage('mcfunction', { extensions: ['.mcfunction'], - parser: mcf.entry(releaseVersion, parser.argument), + parser: mcf.entry(releaseVersion, parser.argument, true), completer: mcf.completer.entry(releaseVersion, completer.getMockNodes), triggerCharacters: [ ' ', diff --git a/packages/mcfunction/src/parser/entry.ts b/packages/mcfunction/src/parser/entry.ts index 5c80c7a80..e5d6dcfba 100644 --- a/packages/mcfunction/src/parser/entry.ts +++ b/packages/mcfunction/src/parser/entry.ts @@ -54,10 +54,16 @@ const comment = core.comment({ }) /** - * Concatenates lines together on trailing backslashes before running the main - * {@link mcfunction} parser + * @param supportsBackslashContinuation Whether or not to concatenate lines together on trailing backslashes. + * Disabled by default. */ export const entry = ( commandTreeName: string, argument: ArgumentParserGetter, -) => core.concatOnTrailingBackslash(mcfunction(commandTreeName, argument)) + supportsBackslashContinuation = false, +) => { + const parser = mcfunction(commandTreeName, argument) + return supportsBackslashContinuation + ? core.concatOnTrailingBackslash(parser) + : parser +} diff --git a/packages/mcfunction/test/parser/entry.spec.ts b/packages/mcfunction/test/parser/entry.spec.ts index 6ed2a792f..3d5bae907 100644 --- a/packages/mcfunction/test/parser/entry.spec.ts +++ b/packages/mcfunction/test/parser/entry.spec.ts @@ -28,6 +28,19 @@ describe('mcfunction parser entry()', () => { ] for (const { content } of cases) { it(`Parse "${showWhitespaceGlyph(content)}"`, () => { + const parser = entry(release, () => undefined, true) + snapshot(testParser(parser, content)) + }) + } + + const casesWithoutBackslashContinuation: { content: string }[] = [ + { content: 'say hi' }, + { content: 'say hi\nsay hi' }, + { content: 'sa\\ \n y \\ \n hi' }, + { content: 'say trailing \\\n data' }, + ] + for (const { content } of casesWithoutBackslashContinuation) { + it(`Parse "${showWhitespaceGlyph(content)}" without backslash continuation`, () => { const parser = entry(release, () => undefined) snapshot(testParser(parser, content)) }) From 0548d94fcdf84656a3532de7bd3d8afdde983a8f Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Thu, 23 May 2024 22:18:55 -0400 Subject: [PATCH 22/25] =?UTF-8?q?=F0=9F=A5=85=20Add=20parse=20error=20for?= =?UTF-8?q?=20line=20continuation=20at=20end=20of=20file=20-=20it=20doesn'?= =?UTF-8?q?t=20count=20as=20end=20of=20file=20iff=20there=20is=20any=20con?= =?UTF-8?q?tent=20after=20the=20newline=20after=20the=20backslash=20(inclu?= =?UTF-8?q?ding=20spaces),=20so=20catch=20that=20in=20an=20explicit=20case?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/test-out/parser/util.spec.js | 76 +++++++++++++++++++ packages/core/src/parser/util.ts | 17 ++++- packages/core/test/parser/util.spec.ts | 3 + packages/locales/src/locales/en.json | 1 + 4 files changed, 96 insertions(+), 1 deletion(-) diff --git a/__snapshots__/packages/core/test-out/parser/util.spec.js b/__snapshots__/packages/core/test-out/parser/util.spec.js index bdd771064..55a444c2f 100644 --- a/__snapshots__/packages/core/test-out/parser/util.spec.js +++ b/__snapshots__/packages/core/test-out/parser/util.spec.js @@ -117,6 +117,26 @@ exports['concatOnTrailingBackslash() Parse "true↓" 1'] = { "errors": [] } +exports['concatOnTrailingBackslash() Parse "tru⧵ ↓ " 1'] = { + "node": { + "type": "boolean", + "range": { + "start": 0, + "end": 0 + } + }, + "errors": [ + { + "range": { + "start": 0, + "end": 0 + }, + "message": "Expected “false” or “true”", + "severity": 3 + } + ] +} + exports['concatOnTrailingBackslash() Parse "tru⧵ ↓ e" 1'] = { "node": { "type": "boolean", @@ -141,6 +161,34 @@ exports['concatOnTrailingBackslash() Parse "tru⧵ ↓ ⧵↓ e" 1'] = { "errors": [] } +exports['concatOnTrailingBackslash() Parse "tru⧵ ↓" 1'] = { + "node": { + "type": "boolean", + "range": { + "start": 0, + "end": 0 + } + }, + "errors": [ + { + "range": { + "start": 3, + "end": 6 + }, + "message": "A line continuation cannot be the end of the file", + "severity": 3 + }, + { + "range": { + "start": 0, + "end": 0 + }, + "message": "Expected “false” or “true”", + "severity": 3 + } + ] +} + exports['concatOnTrailingBackslash() Parse "tru⧵ ↓e" 1'] = { "node": { "type": "boolean", @@ -153,6 +201,34 @@ exports['concatOnTrailingBackslash() Parse "tru⧵ ↓e" 1'] = { "errors": [] } +exports['concatOnTrailingBackslash() Parse "tru⧵" 1'] = { + "node": { + "type": "boolean", + "range": { + "start": 0, + "end": 0 + } + }, + "errors": [ + { + "range": { + "start": 3, + "end": 4 + }, + "message": "A line continuation cannot be the end of the file", + "severity": 3 + }, + { + "range": { + "start": 0, + "end": 0 + }, + "message": "Expected “false” or “true”", + "severity": 3 + } + ] +} + exports['concatOnTrailingBackslash() Parse "tru⧵e ⧵ ↓ e" 1'] = { "node": { "type": "boolean", diff --git a/packages/core/src/parser/util.ts b/packages/core/src/parser/util.ts index ed87eb0c0..6a3bca014 100644 --- a/packages/core/src/parser/util.ts +++ b/packages/core/src/parser/util.ts @@ -1,4 +1,5 @@ -import type { AstNode } from '../node/index.js' +import { localize } from '@spyglassmc/locales' +import type { AstNode, ErrorNode } from '../node/index.js' import { SequenceUtil, SequenceUtilDiscriminator } from '../node/index.js' import type { ParserContext } from '../service/index.js' import { ErrorReporter } from '../service/index.js' @@ -544,6 +545,20 @@ export function concatOnTrailingBackslash( // next line's first non-whitespace character const from = src.getCharRange() src.nextLine() + + // Minecraft raises a `Line continuation at end of file` if a backslash + // (+ optional whitespace to the next line) is right before the end of the file + if (!src.canRead()) { + const ans: ErrorNode = { + type: 'error', + range: Range.span(from, src), + } + ctx.err.report( + localize('mcfunction.parser.line-continuation-end-of-file'), + ans, + ) + } + src.skipSpace() const to = src.getCharRange(-1) indexMap.push({ diff --git a/packages/core/test/parser/util.spec.ts b/packages/core/test/parser/util.spec.ts index 8cac53539..bb3d6b99c 100644 --- a/packages/core/test/parser/util.spec.ts +++ b/packages/core/test/parser/util.spec.ts @@ -146,6 +146,9 @@ describe('concatOnTrailingBackslash()', () => { { content: 'tru\\ \n \\\n e' }, { content: 'tru\\e \\ \n e' }, { content: 'tru\\\n\ne' }, + { content: 'tru\\' }, + { content: 'tru\\ \n' }, + { content: 'tru\\ \n ' }, ], }, ] diff --git a/packages/locales/src/locales/en.json b/packages/locales/src/locales/en.json index 8742873c5..ae3eb9562 100644 --- a/packages/locales/src/locales/en.json +++ b/packages/locales/src/locales/en.json @@ -74,6 +74,7 @@ "mcfunction.parser.entity-selector.player-name.too-long": "Player names cannot be longer than %0% characters", "mcfunction.parser.eoc-unexpected": "Expected more arguments", "mcfunction.parser.leading-slash": "a leading slash %0%", + "mcfunction.parser.line-continuation-end-of-file": "A line continuation cannot be the end of the file", "mcfunction.parser.no-permission": "Permission level %0% is required, which is higher than %1% defined in config", "mcfunction.parser.objective.too-long": "Objective names cannot be longer than %0% characters", "mcfunction.parser.range.min>max": "The minimum value %0% is larger than the maximum value %1%", From 163283ec04e09f7317fb45c494a1b6672843df57 Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Sat, 25 May 2024 13:23:42 -0400 Subject: [PATCH 23/25] =?UTF-8?q?=F0=9F=9A=9A=20Rename=20locale=20key=20to?= =?UTF-8?q?=20be=20more=20generic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/parser/util.ts | 2 +- packages/locales/src/locales/en.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/src/parser/util.ts b/packages/core/src/parser/util.ts index 6a3bca014..4dd2616d5 100644 --- a/packages/core/src/parser/util.ts +++ b/packages/core/src/parser/util.ts @@ -554,7 +554,7 @@ export function concatOnTrailingBackslash( range: Range.span(from, src), } ctx.err.report( - localize('mcfunction.parser.line-continuation-end-of-file'), + localize('parser.line-continuation-end-of-file'), ans, ) } diff --git a/packages/locales/src/locales/en.json b/packages/locales/src/locales/en.json index 20cc04879..060e72d1c 100644 --- a/packages/locales/src/locales/en.json +++ b/packages/locales/src/locales/en.json @@ -75,7 +75,6 @@ "mcfunction.parser.entity-selector.player-name.too-long": "Player names cannot be longer than %0% characters", "mcfunction.parser.eoc-unexpected": "Expected more arguments", "mcfunction.parser.leading-slash": "a leading slash %0%", - "mcfunction.parser.line-continuation-end-of-file": "A line continuation cannot be the end of the file", "mcfunction.parser.no-permission": "Permission level %0% is required, which is higher than %1% defined in config", "mcfunction.parser.objective.too-long": "Objective names cannot be longer than %0% characters", "mcfunction.parser.range.min>max": "The minimum value %0% is larger than the maximum value %1%", @@ -153,6 +152,7 @@ "objective-not-following-convention": "Invalid objective %0% which doesn't follow %1% convention", "parser.float.illegal": "Illegal float numeral that doesn't follow %0%", "parser.integer.illegal": "Illegal integer that doesn't follow %0%", + "parser.line-continuation-end-of-file": "A line continuation cannot be the end of the file", "parser.list.value": "a value", "parser.list.trailing-sep": "Trailing separation", "parser.long.illegal": "Illegal long numeral that doesn't follow %0%", From bdb8343a7fcd3f1bfae13c2a01fb8440eeffc963 Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Sun, 26 May 2024 16:11:23 -0400 Subject: [PATCH 24/25] =?UTF-8?q?=F0=9F=93=B8=20Update=20snapshots=20-=20t?= =?UTF-8?q?hey=20have=20errors=20now,=20so=20we're=20gonna=20remove=20thos?= =?UTF-8?q?e=20in=20next=20commit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mcfunction/test-out/parser/entry.spec.js | 75 ++++++++++++++++--- 1 file changed, 66 insertions(+), 9 deletions(-) diff --git a/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js b/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js index f77ecc777..407916ff6 100644 --- a/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js +++ b/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js @@ -119,15 +119,34 @@ exports['mcfunction parser entry() Parse "# this is a comment↓say hi↓$this i ] }, { - "type": "mcfunction:command_macro", + "type": "mcfunction:macro", "range": { "start": 27, "end": 44 - } + }, + "children": [ + { + "type": "mcfunction:macro/other", + "range": { + "start": 28, + "end": 44 + }, + "value": "this is a macro " + } + ] } ] }, - "errors": [] + "errors": [ + { + "range": { + "start": 28, + "end": 44 + }, + "message": "Expected at least one macro argument", + "severity": 3 + } + ] } exports['mcfunction parser entry() Parse "$ this is a macro command" 1'] = { @@ -139,15 +158,34 @@ exports['mcfunction parser entry() Parse "$ this is a macro command" 1'] = { }, "children": [ { - "type": "mcfunction:command_macro", + "type": "mcfunction:macro", "range": { "start": 0, "end": 25 - } + }, + "children": [ + { + "type": "mcfunction:macro/other", + "range": { + "start": 1, + "end": 25 + }, + "value": " this is a macro command" + } + ] } ] }, - "errors": [] + "errors": [ + { + "range": { + "start": 1, + "end": 25 + }, + "message": "Expected at least one macro argument", + "severity": 3 + } + ] } exports['mcfunction parser entry() Parse "$ this is a macro ⧵ ↓ this is still a macro" 1'] = { @@ -159,15 +197,34 @@ exports['mcfunction parser entry() Parse "$ this is a macro ⧵ ↓ this is stil }, "children": [ { - "type": "mcfunction:command_macro", + "type": "mcfunction:macro", "range": { "start": 0, "end": 43 - } + }, + "children": [ + { + "type": "mcfunction:macro/other", + "range": { + "start": 1, + "end": 43 + }, + "value": " this is a macro this is still a macro" + } + ] } ] }, - "errors": [] + "errors": [ + { + "range": { + "start": 1, + "end": 43 + }, + "message": "Expected at least one macro argument", + "severity": 3 + } + ] } exports['mcfunction parser entry() Parse "execute if true if true run say hi" 1'] = { From c3a1bc9919560ff72fe4b32e0965fa0eb69a9717 Mon Sep 17 00:00:00 2001 From: TheAfroOfDoom Date: Sun, 26 May 2024 16:12:45 -0400 Subject: [PATCH 25/25] =?UTF-8?q?=E2=9C=85=20Update=20`entry`=20parser=20t?= =?UTF-8?q?ests=20to=20not=20report=20errors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mcfunction/test-out/parser/entry.spec.js | 127 +++++++++++------- packages/mcfunction/test/parser/entry.spec.ts | 6 +- 2 files changed, 85 insertions(+), 48 deletions(-) diff --git a/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js b/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js index 407916ff6..38648cb50 100644 --- a/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js +++ b/__snapshots__/packages/mcfunction/test-out/parser/entry.spec.js @@ -52,12 +52,12 @@ exports['mcfunction parser entry() Parse "# this is a comment" 1'] = { "errors": [] } -exports['mcfunction parser entry() Parse "# this is a comment↓say hi↓$this is a macro ↓" 1'] = { +exports['mcfunction parser entry() Parse "# this is a comment↓say hi↓$this is a $(macro) ↓" 1'] = { "node": { "type": "mcfunction:entry", "range": { "start": 0, - "end": 45 + "end": 48 }, "children": [ { @@ -122,109 +122,146 @@ exports['mcfunction parser entry() Parse "# this is a comment↓say hi↓$this i "type": "mcfunction:macro", "range": { "start": 27, - "end": 44 + "end": 47 }, "children": [ { "type": "mcfunction:macro/other", "range": { "start": 28, - "end": 44 + "end": 38 }, - "value": "this is a macro " + "value": "this is a " + }, + { + "type": "mcfunction:macro/argument", + "range": { + "start": 38, + "end": 46 + }, + "value": "macro" + }, + { + "type": "mcfunction:macro/other", + "range": { + "start": 46, + "end": 47 + }, + "value": " " } ] } ] }, - "errors": [ - { - "range": { - "start": 28, - "end": 44 - }, - "message": "Expected at least one macro argument", - "severity": 3 - } - ] + "errors": [] } -exports['mcfunction parser entry() Parse "$ this is a macro command" 1'] = { +exports['mcfunction parser entry() Parse "$ this is a $(macro) command" 1'] = { "node": { "type": "mcfunction:entry", "range": { "start": 0, - "end": 25 + "end": 28 }, "children": [ { "type": "mcfunction:macro", "range": { "start": 0, - "end": 25 + "end": 28 }, "children": [ { "type": "mcfunction:macro/other", "range": { "start": 1, - "end": 25 + "end": 12 }, - "value": " this is a macro command" + "value": " this is a " + }, + { + "type": "mcfunction:macro/argument", + "range": { + "start": 12, + "end": 20 + }, + "value": "macro" + }, + { + "type": "mcfunction:macro/other", + "range": { + "start": 20, + "end": 28 + }, + "value": " command" } ] } ] }, - "errors": [ - { - "range": { - "start": 1, - "end": 25 - }, - "message": "Expected at least one macro argument", - "severity": 3 - } - ] + "errors": [] } -exports['mcfunction parser entry() Parse "$ this is a macro ⧵ ↓ this is still a macro" 1'] = { +exports['mcfunction parser entry() Parse "$ this is a $(macro) ⧵ ↓ this is $(still) a macro" 1'] = { "node": { "type": "mcfunction:entry", "range": { "start": 0, - "end": 43 + "end": 49 }, "children": [ { "type": "mcfunction:macro", "range": { "start": 0, - "end": 43 + "end": 49 }, "children": [ { "type": "mcfunction:macro/other", "range": { "start": 1, - "end": 43 + "end": 12 + }, + "value": " this is a " + }, + { + "type": "mcfunction:macro/argument", + "range": { + "start": 12, + "end": 20 + }, + "value": "macro" + }, + { + "type": "mcfunction:macro/other", + "range": { + "start": 20, + "end": 33 }, - "value": " this is a macro this is still a macro" + "value": " this is " + }, + { + "type": "mcfunction:macro/argument", + "range": { + "start": 33, + "end": 41 + }, + "value": "still" + }, + { + "type": "mcfunction:macro/other", + "range": { + "start": 41, + "end": 49 + }, + "value": " a macro" } ] } ] }, - "errors": [ - { - "range": { - "start": 1, - "end": 43 - }, - "message": "Expected at least one macro argument", - "severity": 3 - } - ] + "errors": [] } exports['mcfunction parser entry() Parse "execute if true if true run say hi" 1'] = { diff --git a/packages/mcfunction/test/parser/entry.spec.ts b/packages/mcfunction/test/parser/entry.spec.ts index 72a06d45b..63aa5ccef 100644 --- a/packages/mcfunction/test/parser/entry.spec.ts +++ b/packages/mcfunction/test/parser/entry.spec.ts @@ -14,11 +14,11 @@ describe('mcfunction parser entry()', () => { { content: 'say hi' }, { content: 'say hi\nsay hi' }, { content: '# this is a comment' }, - { content: '$ this is a macro command' }, - { content: '# this is a comment\nsay hi\n$this is a macro \n' }, + { content: '$ this is a $(macro) command' }, + { content: '# this is a comment\nsay hi\n$this is a $(macro) \n' }, { content: 'execute if true if true run say hi' }, { content: '# this is a comment \\ \n still a comment' }, - { content: '$ this is a macro \\ \n this is still a macro' }, + { content: '$ this is a $(macro) \\ \n this is $(still) a macro' }, { content: 'sa\\ \n y \\ \n hi' }, { content: 'say trailing \\\n data' }, { content: 'say \\\n hi \n # comment start \\\n end \n say hi' },