Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Convert renderer typecheck methods to typeguards. #8656

Open
wants to merge 2 commits into
base: rc/v12.0.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 7 additions & 13 deletions core/renderers/common/drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import type {ExternalValueInput} from '../measurables/external_value_input.js';
import type {Field} from '../measurables/field.js';
import type {Icon} from '../measurables/icon.js';
import type {InlineInput} from '../measurables/inline_input.js';
import type {PreviousConnection} from '../measurables/previous_connection.js';
import type {Row} from '../measurables/row.js';
import {Types} from '../measurables/types.js';

Expand Down Expand Up @@ -117,13 +116,8 @@ export class Drawer {
this.outlinePath_ += this.constants_.OUTSIDE_CORNERS.topLeft;
} else if (Types.isRightRoundedCorner(elem)) {
this.outlinePath_ += this.constants_.OUTSIDE_CORNERS.topRight;
} else if (
Types.isPreviousConnection(elem) &&
elem instanceof Connection
) {
this.outlinePath_ += (
(elem as PreviousConnection).shape as Notch
).pathLeft;
} else if (Types.isPreviousConnection(elem)) {
this.outlinePath_ += (elem.shape as Notch).pathLeft;
} else if (Types.isHat(elem)) {
this.outlinePath_ += this.constants_.START_HAT.path;
} else if (Types.isSpacer(elem)) {
Expand Down Expand Up @@ -218,7 +212,7 @@ export class Drawer {
let rightCornerYOffset = 0;
let outlinePath = '';
for (let i = elems.length - 1, elem; (elem = elems[i]); i--) {
if (Types.isNextConnection(elem) && elem instanceof Connection) {
if (Types.isNextConnection(elem)) {
outlinePath += (elem.shape as Notch).pathRight;
} else if (Types.isLeftSquareCorner(elem)) {
outlinePath += svgPaths.lineOnAxis('H', bottomRow.xPos);
Expand Down Expand Up @@ -270,9 +264,9 @@ export class Drawer {
for (let i = 0, row; (row = this.info_.rows[i]); i++) {
for (let j = 0, elem; (elem = row.elements[j]); j++) {
if (Types.isInlineInput(elem)) {
this.drawInlineInput_(elem as InlineInput);
this.drawInlineInput_(elem);
} else if (Types.isIcon(elem) || Types.isField(elem)) {
this.layoutField_(elem as Field | Icon);
this.layoutField_(elem);
}
}
}
Expand All @@ -296,13 +290,13 @@ export class Drawer {
}

if (Types.isIcon(fieldInfo)) {
const icon = (fieldInfo as Icon).icon;
const icon = fieldInfo.icon;
icon.setOffsetInBlock(new Coordinate(xPos, yPos));
if (this.info_.isInsertionMarker) {
icon.hideForInsertionMarker();
}
} else {
const svgGroup = (fieldInfo as Field).field.getSvgRoot()!;
const svgGroup = fieldInfo.field.getSvgRoot()!;
svgGroup.setAttribute(
'transform',
'translate(' + xPos + ',' + yPos + ')' + scale,
Expand Down
9 changes: 3 additions & 6 deletions core/renderers/common/info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -672,20 +672,17 @@ export class RenderInfo {
return row.yPos + elem.height / 2;
}
if (Types.isBottomRow(row)) {
const bottomRow = row as BottomRow;
const baseline =
bottomRow.yPos + bottomRow.height - bottomRow.descenderHeight;
const baseline = row.yPos + row.height - row.descenderHeight;
if (Types.isNextConnection(elem)) {
return baseline + elem.height / 2;
}
return baseline - elem.height / 2;
}
if (Types.isTopRow(row)) {
const topRow = row as TopRow;
if (Types.isHat(elem)) {
return topRow.capline - elem.height / 2;
return row.capline - elem.height / 2;
}
return topRow.capline + elem.height / 2;
return row.capline + elem.height / 2;
}
return row.yPos + row.height / 2;
}
Expand Down
2 changes: 1 addition & 1 deletion core/renderers/geras/drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export class Drawer extends BaseDrawer {
}

override drawInlineInput_(input: InlineInput) {
this.highlighter_.drawInlineInput(input as InlineInput);
this.highlighter_.drawInlineInput(input);

super.drawInlineInput_(input);
}
Expand Down
25 changes: 9 additions & 16 deletions core/renderers/geras/info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,12 @@ import type {BlockSvg} from '../../block_svg.js';
import type {Input} from '../../inputs/input.js';
import {RenderInfo as BaseRenderInfo} from '../common/info.js';
import type {Measurable} from '../measurables/base.js';
import type {BottomRow} from '../measurables/bottom_row.js';
import {DummyInput} from '../../inputs/dummy_input.js';
import {EndRowInput} from '../../inputs/end_row_input.js';
import {ExternalValueInput} from '../measurables/external_value_input.js';
import type {Field} from '../measurables/field.js';
import {InRowSpacer} from '../measurables/in_row_spacer.js';
import type {InputRow} from '../measurables/input_row.js';
import type {Row} from '../measurables/row.js';
import {StatementInput} from '../../inputs/statement_input.js';
import type {TopRow} from '../measurables/top_row.js';
import {Types} from '../measurables/types.js';
import {ValueInput} from '../../inputs/value_input.js';

Expand Down Expand Up @@ -151,7 +147,7 @@ export class RenderInfo extends BaseRenderInfo {
override getInRowSpacing_(prev: Measurable | null, next: Measurable | null) {
if (!prev) {
// Between an editable field and the beginning of the row.
if (next && Types.isField(next) && (next as Field).isEditable) {
if (next && Types.isField(next) && next.isEditable) {
return this.constants_.MEDIUM_PADDING;
}
// Inline input at the beginning of the row.
Expand All @@ -168,7 +164,7 @@ export class RenderInfo extends BaseRenderInfo {
// Spacing between a non-input and the end of the row or a statement input.
if (!Types.isInput(prev) && (!next || Types.isStatementInput(next))) {
// Between an editable field and the end of the row.
if (Types.isField(prev) && (prev as Field).isEditable) {
if (Types.isField(prev) && prev.isEditable) {
return this.constants_.MEDIUM_PADDING;
}
// Padding at the end of an icon-only row to make the block shape clearer.
Expand Down Expand Up @@ -209,7 +205,7 @@ export class RenderInfo extends BaseRenderInfo {
// Spacing between a non-input and an input.
if (!Types.isInput(prev) && next && Types.isInput(next)) {
// Between an editable field and an input.
if (Types.isField(prev) && (prev as Field).isEditable) {
if (Types.isField(prev) && prev.isEditable) {
if (Types.isInlineInput(next)) {
return this.constants_.SMALL_PADDING;
} else if (Types.isExternalInput(next)) {
Expand All @@ -234,7 +230,7 @@ export class RenderInfo extends BaseRenderInfo {
// Spacing between an inline input and a field.
if (Types.isInlineInput(prev) && next && Types.isField(next)) {
// Editable field after inline input.
if ((next as Field).isEditable) {
if (next.isEditable) {
return this.constants_.MEDIUM_PADDING;
} else {
// Noneditable field after inline input.
Expand Down Expand Up @@ -279,7 +275,7 @@ export class RenderInfo extends BaseRenderInfo {
Types.isField(prev) &&
next &&
Types.isField(next) &&
(prev as Field).isEditable === (next as Field).isEditable
prev.isEditable === next.isEditable
) {
return this.constants_.LARGE_PADDING;
}
Expand Down Expand Up @@ -324,20 +320,17 @@ export class RenderInfo extends BaseRenderInfo {
return row.yPos + elem.height / 2;
}
if (Types.isBottomRow(row)) {
const bottomRow = row as BottomRow;
const baseline =
bottomRow.yPos + bottomRow.height - bottomRow.descenderHeight;
const baseline = row.yPos + row.height - row.descenderHeight;
if (Types.isNextConnection(elem)) {
return baseline + elem.height / 2;
}
return baseline - elem.height / 2;
}
if (Types.isTopRow(row)) {
const topRow = row as TopRow;
if (Types.isHat(elem)) {
return topRow.capline - elem.height / 2;
return row.capline - elem.height / 2;
}
return topRow.capline + elem.height / 2;
return row.capline + elem.height / 2;
}

let result = row.yPos;
Expand Down Expand Up @@ -371,7 +364,7 @@ export class RenderInfo extends BaseRenderInfo {
rowNextRightEdges.set(row, nextRightEdge);
if (Types.isInputRow(row)) {
if (row.hasStatement) {
this.alignStatementRow_(row as InputRow);
this.alignStatementRow_(row);
}
if (
prevInput &&
Expand Down
8 changes: 8 additions & 0 deletions core/renderers/measurables/in_row_spacer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ import {Types} from './types.js';
* row.
*/
export class InRowSpacer extends Measurable {
// This field exists solely to structurally distinguish this type from other
// Measurable subclasses. Because this class otherwise has the same fields as
// Measurable, and Typescript doesn't support nominal typing, Typescript will
// consider it and other subclasses in the same situation as being of the same
// type, even if typeguards are used, which could result in Typescript typing
// objects of this class as `never`.
private inRowSpacer: undefined;

/**
* @param constants The rendering constants provider.
* @param width The width of the spacer.
Expand Down
9 changes: 2 additions & 7 deletions core/renderers/measurables/input_row.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@
// Former goog.module ID: Blockly.blockRendering.InputRow

import type {ConstantProvider} from '../common/constants.js';

import {ExternalValueInput} from './external_value_input.js';
import {InputConnection} from './input_connection.js';
import {Row} from './row.js';
import {StatementInput} from './statement_input.js';
import {Types} from './types.js';

/**
Expand Down Expand Up @@ -41,12 +37,11 @@ export class InputRow extends Row {
for (let i = 0; i < this.elements.length; i++) {
const elem = this.elements[i];
this.width += elem.width;
if (Types.isInput(elem) && elem instanceof InputConnection) {
if (Types.isStatementInput(elem) && elem instanceof StatementInput) {
if (Types.isInput(elem)) {
if (Types.isStatementInput(elem)) {
connectedBlockWidths += elem.connectedBlockWidth;
} else if (
Types.isExternalInput(elem) &&
elem instanceof ExternalValueInput &&
elem.connectedBlockWidth !== 0
) {
connectedBlockWidths +=
Expand Down
8 changes: 8 additions & 0 deletions core/renderers/measurables/jagged_edge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ import {Types} from './types.js';
* collapsed block takes up during rendering.
*/
export class JaggedEdge extends Measurable {
// This field exists solely to structurally distinguish this type from other
// Measurable subclasses. Because this class otherwise has the same fields as
// Measurable, and Typescript doesn't support nominal typing, Typescript will
// consider it and other subclasses in the same situation as being of the same
// type, even if typeguards are used, which could result in Typescript typing
// objects of this class as `never`.
private jaggedEdge: undefined;

/**
* @param constants The rendering constants provider.
*/
Expand Down
8 changes: 8 additions & 0 deletions core/renderers/measurables/next_connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ import {Types} from './types.js';
* up during rendering.
*/
export class NextConnection extends Connection {
// This field exists solely to structurally distinguish this type from other
// Measurable subclasses. Because this class otherwise has the same fields as
// Measurable, and Typescript doesn't support nominal typing, Typescript will
// consider it and other subclasses in the same situation as being of the same
// type, even if typeguards are used, which could result in Typescript typing
// objects of this class as `never`.
private nextConnection: undefined;

/**
* @param constants The rendering constants provider.
* @param connectionModel The connection object on the block that this
Expand Down
8 changes: 8 additions & 0 deletions core/renderers/measurables/previous_connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ import {Types} from './types.js';
* up during rendering.
*/
export class PreviousConnection extends Connection {
// This field exists solely to structurally distinguish this type from other
// Measurable subclasses. Because this class otherwise has the same fields as
// Measurable, and Typescript doesn't support nominal typing, Typescript will
// consider it and other subclasses in the same situation as being of the same
// type, even if typeguards are used, which could result in Typescript typing
// objects of this class as `never`.
private previousConnection: undefined;

/**
* @param constants The rendering constants provider.
* @param connectionModel The connection object on the block that this
Expand Down
8 changes: 8 additions & 0 deletions core/renderers/measurables/round_corner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ import {Types} from './types.js';
* during rendering.
*/
export class RoundCorner extends Measurable {
// This field exists solely to structurally distinguish this type from other
// Measurable subclasses. Because this class otherwise has the same fields as
// Measurable, and Typescript doesn't support nominal typing, Typescript will
// consider it and other subclasses in the same situation as being of the same
// type, even if typeguards are used, which could result in Typescript typing
// objects of this class as `never`.
private roundCorner: undefined;

/**
* @param constants The rendering constants provider.
* @param opt_position The position of this corner.
Expand Down
10 changes: 5 additions & 5 deletions core/renderers/measurables/row.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export class Row {
for (let i = this.elements.length - 1; i >= 0; i--) {
const elem = this.elements[i];
if (Types.isInput(elem)) {
return elem as InputConnection;
return elem;
}
}
return null;
Expand Down Expand Up @@ -167,8 +167,8 @@ export class Row {
getFirstSpacer(): InRowSpacer | null {
for (let i = 0; i < this.elements.length; i++) {
const elem = this.elements[i];
if (Types.isSpacer(elem)) {
return elem as InRowSpacer;
if (Types.isInRowSpacer(elem)) {
return elem;
}
}
return null;
Expand All @@ -182,8 +182,8 @@ export class Row {
getLastSpacer(): InRowSpacer | null {
for (let i = this.elements.length - 1; i >= 0; i--) {
const elem = this.elements[i];
if (Types.isSpacer(elem)) {
return elem as InRowSpacer;
if (Types.isInRowSpacer(elem)) {
return elem;
}
}
return null;
Expand Down
8 changes: 8 additions & 0 deletions core/renderers/measurables/square_corner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ import {Types} from './types.js';
* during rendering.
*/
export class SquareCorner extends Measurable {
// This field exists solely to structurally distinguish this type from other
// Measurable subclasses. Because this class otherwise has the same fields as
// Measurable, and Typescript doesn't support nominal typing, Typescript will
// consider it and other subclasses in the same situation as being of the same
// type, even if typeguards are used, which could result in Typescript typing
// objects of this class as `never`.
private squareCorner: undefined;

/**
* @param constants The rendering constants provider.
* @param opt_position The position of this corner.
Expand Down
8 changes: 8 additions & 0 deletions core/renderers/measurables/statement_input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ import {Types} from './types.js';
* during rendering
*/
export class StatementInput extends InputConnection {
// This field exists solely to structurally distinguish this type from other
// Measurable subclasses. Because this class otherwise has the same fields as
// Measurable, and Typescript doesn't support nominal typing, Typescript will
// consider it and other subclasses in the same situation as being of the same
// type, even if typeguards are used, which could result in Typescript typing
// objects of this class as `never`.
private statementInput: undefined;

/**
* @param constants The rendering constants provider.
* @param input The statement input to measure and store information for.
Expand Down
4 changes: 1 addition & 3 deletions core/renderers/measurables/top_row.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@

import type {BlockSvg} from '../../block_svg.js';
import type {ConstantProvider} from '../common/constants.js';

import {Hat} from './hat.js';
import type {PreviousConnection} from './previous_connection.js';
import {Row} from './row.js';
import {Types} from './types.js';
Expand Down Expand Up @@ -86,7 +84,7 @@ export class TopRow extends Row {
const elem = this.elements[i];
width += elem.width;
if (!Types.isSpacer(elem)) {
if (Types.isHat(elem) && elem instanceof Hat) {
if (Types.isHat(elem)) {
ascenderHeight = Math.max(ascenderHeight, elem.ascenderHeight);
} else {
height = Math.max(height, elem.height);
Expand Down
Loading
Loading