From 582e19a0f1603b88535023113e64700b53b1651d Mon Sep 17 00:00:00 2001 From: Christopher Allen Date: Fri, 20 Oct 2023 16:59:30 +0200 Subject: [PATCH] fix(generators): Modify type signature of forBlock (#7555) Make two changes to the forBlock dictionary on CodeGenerator objects: - Change the type of the second argument to the special 'this' type (was CodeGenerator), so that e.g. JS block generator functions can call JavascriptGenerator.prototype.getAdjusted (not defined on CodeGenerator). - Change the way forBlock is declared from using an index signature to using the Record<> template type. The two should be equivalent but for some reason the former provokes type errors when used with the 'this' type. Additionally, deprecate the now-unused (but exported) BlockGenerator type alias. Technically the change of signaure is a breaking chnage, but it is unlikely to affect any developers in practice, since any block generator function (Block, CodeGenerator) => ... can be substituted in for (Block, C extends CodeGenerator) => ..., so any existing generator functions can still be added to any CodeGenerator or subclass instance's .forBlock. The only situation in which this would be breaking is if a developer was obtaining block generator functions FROM a subclass instance's .forBlock dictionary and assuming they were (Block CodeGenerator) => ... --- core/generator.ts | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/core/generator.ts b/core/generator.ts index e4518681d..d94597fc1 100644 --- a/core/generator.ts +++ b/core/generator.ts @@ -19,8 +19,10 @@ import type {Workspace} from './workspace.js'; import {warn} from './utils/deprecation.js'; /** - * Type declaration for per-block-type generator functions. + * Deprecated, no-longer used type declaration for per-block-type generator + * functions. * + * @deprecated * @see {@link https://developers.google.com/blockly/guides/create-custom-blocks/generating-code} * @param block The Block instance to generate code for. * @param genearator The CodeGenerator calling the function. @@ -39,8 +41,25 @@ export type BlockGenerator = ( export class CodeGenerator { name_: string; - /** A dictionary of block generator functions keyed by block type. */ - forBlock: {[type: string]: BlockGenerator} = Object.create(null); + /** + * A dictionary of block generator functions, keyed by block type. + * Each block generator function takes two parameters: + * + * - the Block to generate code for, and + * - the calling CodeGenerator (or subclass) instance, so the + * function can call methods defined below (e.g. blockToCode) or + * on the relevant subclass (e.g. JavascripGenerator), + * + * and returns: + * + * - a [code, precedence] tuple (for value/expression blocks), or + * - a string containing the generated code (for statement blocks), or + * - null if no code should be emitted for block. + */ + forBlock: Record< + string, + (block: Block, generator: this) => [string, number] | string | null + > = Object.create(null); /** * This is used as a placeholder in functions defined using