From e9c2959dda139f4bbc19b60fd2bf6a216803f4db Mon Sep 17 00:00:00 2001 From: Erik Demaine Date: Sat, 2 Nov 2024 15:44:20 -0400 Subject: [PATCH] Fix `for key: T, value in` loop to define `value` using typed `key` Helps with #1562 --- civet.dev/reference.md | 5 ++--- source/parser/for.civet | 14 ++++++++++---- test/types/for.civet | 13 ++++++++++++- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/civet.dev/reference.md b/civet.dev/reference.md index af8db6f5..13aa3afd 100644 --- a/civet.dev/reference.md +++ b/civet.dev/reference.md @@ -1758,9 +1758,8 @@ for own key in object You can add types to the declarations (unlike TypeScript): -for var key: string, value: unknown in object - console.log key, JSON.stringify value -key ?= "no last key" +for key: keyof typeof object, value in object + process key, value ### Loop Expressions diff --git a/source/parser/for.civet b/source/parser/for.civet index 55f50979..cab4fbc1 100644 --- a/source/parser/for.civet +++ b/source/parser/for.civet @@ -338,17 +338,18 @@ function processForInOf($0: [ children: [declaration, " = ", itemRef] names: declaration.names }, ";"] - pattern = itemRef declaration = type: "ForDeclaration" binding: { type: "Binding" - pattern - children: [ pattern ] + pattern: itemRef + children: [ itemRef ] names: [] } children: ["const ", itemRef] names: [] + unless pattern.type is "Identifier" + pattern = itemRef unless declaration2 or own return { @@ -392,7 +393,12 @@ function processForInOf($0: [ if decl2 blockPrefix.push ["", { type: "Declaration" - children: [trimFirstSpace(ws2), decl2, " = ", trimFirstSpace(expRef), "[", trimFirstSpace(pattern), "]"] + children: [ + trimFirstSpace(ws2), decl2, " = " + trimFirstSpace(expRef) + "[", trimFirstSpace(pattern), "]" + ] + decl: decl2 names: decl2.names }, ";"] diff --git a/test/types/for.civet b/test/types/for.civet index 8641de33..3e39967d 100644 --- a/test/types/for.civet +++ b/test/types/for.civet @@ -51,11 +51,22 @@ describe "[TS] for", -> for x: T, y in z console.log x, y --- - for (const key in z) {const x: T = key;const y = z[key]; + for (const key in z) {const x: T = key;const y = z[x]; console.log(x, y) } """ + testCase """ + destructuring for..in with two declarations + --- + for [a, b]: T, value in z + console.log x + --- + for (const key in z) {const [a, b]: T = key;const value = z[key]; + console.log(x) + } + """ + testCase """ parenthesized ---