Skip to content

Commit

Permalink
refactor(generators): Migrate PHP generators to TypeScript (#7647)
Browse files Browse the repository at this point in the history
* refactor(generators): Migrate dart_generator.js to TypeScript

* refactor(generators): Simplify getAdjusted

  Slightly simplify the implementation of getAdjusted, in part to
  make it more readable.  Also improve its JSDoc comment.

* refactor(generators): Migrate generators/php/* to TypeScript

  First pass doing very mechanistic migration, not attempting to fix
  all the resulting type errors.

* fix(generators): Fix type errors in generator functions

  This consists almost entirely of adding casts, so the code output
  by tsc should be as similar as possible to the pre-migration .js
  source files.

* fix(generators): Fix more minor inconsistencies in JS and Python

  The migration of the JavaScript and Python generators
  inadvertently introduced some inconsistencies in the code,
  e.g. putting executable code before the initial comment line that
  most generator functions begin with.  This fixes another instance
  of this (but n.b. that these inline comments should have been
  JSDocs and a task has been added to #7600 to convert them).

  Additionally, I noticed while doing the PHP migration that
  ORDER_OVERRIDES was not typed as specifically as it could be,
  in previous migrations, so this is fixed here (along with the
  formatting of the associated JSDoc, which can fit on one line
  now.)

* refactor(generators): Migrate generators/php.js to TypeScript

  The way the generator functions are added to
  phpGenerator.forBlock has been modified so that incorrect
  generator function signatures will cause tsc to generate a type
  error.

* chore(generator): Format

  One block protected with // prettier-ignore to preserve careful
  comment formatting.

  Where there are repeated concatenations prettier has made a pretty
  mess of things, but the correct fix is probably to use template
  literals instead (rather than just locally disabling prettier).
  This is one of the items in the to-do list in #7600.

* docs(generators): @fileoverview -> @file

  With an update to the wording for generators/php.ts.

* fix(generators): Fixes for PR #7647.

  - Don't declare unused wherePascalCase dictionary.
  - Don't allow null in OPERATOR dictionary when not needed.
  - Fix return type (and documentation thereof) of getAdjusted.
  • Loading branch information
cpcallen authored Nov 28, 2023
1 parent b198e2f commit 7bda309
Show file tree
Hide file tree
Showing 16 changed files with 1,107 additions and 756 deletions.
6 changes: 2 additions & 4 deletions generators/javascript/javascript_generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,8 @@ export enum Order {
* JavaScript code generator class.
*/
export class JavascriptGenerator extends CodeGenerator {
/**
* List of outer-inner pairings that do NOT require parentheses.
*/
ORDER_OVERRIDES: number[][] = [
/** List of outer-inner pairings that do NOT require parentheses. */
ORDER_OVERRIDES: [Order, Order][] = [
// (foo()).bar -> foo().bar
// (foo())[0] -> foo()[0]
[Order.FUNCTION_CALL, Order.MEMBER],
Expand Down
2 changes: 1 addition & 1 deletion generators/javascript/lists.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ export function lists_getSublist(
block: Block,
generator: JavascriptGenerator,
): [string, Order] {
// Get sublist.
// Dictionary of WHEREn field choices and their CamelCase equivalents.
const wherePascalCase = {
'FIRST': 'First',
Expand All @@ -310,7 +311,6 @@ export function lists_getSublist(
'FROM_END': 'FromEnd',
};
type WhereOption = keyof typeof wherePascalCase;
// Get sublist.
const list = generator.valueToCode(block, 'LIST', Order.MEMBER) || '[]';
const where1 = block.getFieldValue('WHERE1') as WhereOption;
const where2 = block.getFieldValue('WHERE2') as WhereOption;
Expand Down
25 changes: 17 additions & 8 deletions generators/php.js → generators/php.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
*/

/**
* @fileoverview Complete helper functions for generating PHP for
* blocks. This is the entrypoint for php_compressed.js.
* @suppress {extraRequire}
* @file Instantiate a PhpGenerator and populate it with the complete
* set of block generator functions for PHP. This is the entrypoint
* for php_compressed.js.
*/

// Former goog.module ID: Blockly.PHP.all
Expand All @@ -32,8 +32,17 @@ export * from './php/php_generator.js';
export const phpGenerator = new PhpGenerator();

// Install per-block-type generator functions:
Object.assign(
phpGenerator.forBlock,
colour, lists, logic, loops, math, procedures,
text, variables, variablesDynamic
);
const generators: typeof phpGenerator.forBlock = {
...colour,
...lists,
...logic,
...loops,
...math,
...procedures,
...text,
...variables,
...variablesDynamic,
};
for (const name in generators) {
phpGenerator.forBlock[name] = generators[name];
}
60 changes: 40 additions & 20 deletions generators/php/colour.js → generators/php/colour.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,52 @@
*/

/**
* @fileoverview Generating PHP for colour blocks.
* @file Generating PHP for colour blocks.
*/

// Former goog.module ID: Blockly.PHP.colour

import type {Block} from '../../core/block.js';
import {Order} from './php_generator.js';
import type {PhpGenerator} from './php_generator.js';


export function colour_picker(block, generator) {
export function colour_picker(
block: Block,
generator: PhpGenerator,
): [string, Order] {
// Colour picker.
const code = generator.quote_(block.getFieldValue('COLOUR'));
return [code, Order.ATOMIC];
};
}

export function colour_random(block, generator) {
export function colour_random(
block: Block,
generator: PhpGenerator,
): [string, Order] {
// Generate a random colour.
const functionName = generator.provideFunction_('colour_random', `
const functionName = generator.provideFunction_(
'colour_random',
`
function ${generator.FUNCTION_NAME_PLACEHOLDER_}() {
return '#' . str_pad(dechex(mt_rand(0, 0xFFFFFF)), 6, '0', STR_PAD_LEFT);
}
`);
`,
);
const code = functionName + '()';
return [code, Order.FUNCTION_CALL];
};
}

export function colour_rgb(block, generator) {
export function colour_rgb(
block: Block,
generator: PhpGenerator,
): [string, Order] {
// Compose a colour from RGB components expressed as percentages.
const red = generator.valueToCode(block, 'RED', Order.NONE) || 0;
const green = generator.valueToCode(block, 'GREEN', Order.NONE) || 0;
const blue = generator.valueToCode(block, 'BLUE', Order.NONE) || 0;
const functionName = generator.provideFunction_('colour_rgb', `
const functionName = generator.provideFunction_(
'colour_rgb',
`
function ${generator.FUNCTION_NAME_PLACEHOLDER_}($r, $g, $b) {
$r = round(max(min($r, 100), 0) * 2.55);
$g = round(max(min($g, 100), 0) * 2.55);
Expand All @@ -46,19 +61,23 @@ function ${generator.FUNCTION_NAME_PLACEHOLDER_}($r, $g, $b) {
$hex .= str_pad(dechex($b), 2, '0', STR_PAD_LEFT);
return $hex;
}
`);
`,
);
const code = functionName + '(' + red + ', ' + green + ', ' + blue + ')';
return [code, Order.FUNCTION_CALL];
};
}

export function colour_blend(block, generator) {
export function colour_blend(
block: Block,
generator: PhpGenerator,
): [string, Order] {
// Blend two colours together.
const c1 =
generator.valueToCode(block, 'COLOUR1', Order.NONE) || "'#000000'";
const c2 =
generator.valueToCode(block, 'COLOUR2', Order.NONE) || "'#000000'";
const c1 = generator.valueToCode(block, 'COLOUR1', Order.NONE) || "'#000000'";
const c2 = generator.valueToCode(block, 'COLOUR2', Order.NONE) || "'#000000'";
const ratio = generator.valueToCode(block, 'RATIO', Order.NONE) || 0.5;
const functionName = generator.provideFunction_('colour_blend', `
const functionName = generator.provideFunction_(
'colour_blend',
`
function ${generator.FUNCTION_NAME_PLACEHOLDER_}($c1, $c2, $ratio) {
$ratio = max(min($ratio, 1), 0);
$r1 = hexdec(substr($c1, 1, 2));
Expand All @@ -76,7 +95,8 @@ function ${generator.FUNCTION_NAME_PLACEHOLDER_}($c1, $c2, $ratio) {
$hex .= str_pad(dechex($b), 2, '0', STR_PAD_LEFT);
return $hex;
}
`);
`,
);
const code = functionName + '(' + c1 + ', ' + c2 + ', ' + ratio + ')';
return [code, Order.FUNCTION_CALL];
};
}
Loading

0 comments on commit 7bda309

Please sign in to comment.