Skip to content

Commit

Permalink
chore: Merge develop into chunked-compilation
Browse files Browse the repository at this point in the history
- and update chunks.json to add core/loop_mixin.js
- and update deps.js with change to dependencies for
  that same file that appear to have been inadvertently
  omitted from PR google#5730.
  • Loading branch information
mark-friedman authored and cpcallen committed Nov 25, 2021
2 parents eaeee39 + da3df70 commit c11c67e
Show file tree
Hide file tree
Showing 20 changed files with 256 additions and 110 deletions.
71 changes: 1 addition & 70 deletions blocks/loops.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ goog.require('Blockly.FieldLabel');
goog.require('Blockly.FieldNumber');
goog.require('Blockly.FieldVariable');
goog.require('Blockly.Warning');
goog.require('Blockly.loopMixin');


/**
Expand Down Expand Up @@ -272,73 +273,3 @@ Blockly.Extensions.register('controls_for_tooltip',
Blockly.Extensions.register('controls_forEach_tooltip',
Blockly.Extensions.buildTooltipWithFieldText(
'%{BKY_CONTROLS_FOREACH_TOOLTIP}', 'VAR'));

/**
* This mixin adds a check to make sure the 'controls_flow_statements' block
* is contained in a loop. Otherwise a warning is added to the block.
* @mixin
* @augments Blockly.Block
* @package
* @readonly
*/
Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN = {
/**
* List of block types that are loops and thus do not need warnings.
* To add a new loop type add this to your code:
* Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.LOOP_TYPES.push('custom_loop');
*/
LOOP_TYPES: [
'controls_repeat',
'controls_repeat_ext',
'controls_forEach',
'controls_for',
'controls_whileUntil',
],

/**
* Is the given block enclosed (at any level) by a loop?
* @param {!Blockly.Block} block Current block.
* @return {Blockly.Block} The nearest surrounding loop, or null if none.
*/
getSurroundLoop: function(block) {
// Is the block nested in a loop?
do {
if (Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.LOOP_TYPES
.indexOf(block.type) !== -1) {
return block;
}
block = block.getSurroundParent();
} while (block);
return null;
},

/**
* Called whenever anything on the workspace changes.
* Add warning if this flow block is not nested inside a loop.
* @param {!Blockly.Events.Abstract} e Change event.
* @this {Blockly.Block}
*/
onchange: function(e) {
// Don't change state if:
// * It's at the start of a drag.
// * It's not a move event.
if (!this.workspace.isDragging || this.workspace.isDragging() ||
e.type !== Blockly.Events.BLOCK_MOVE) {
return;
}
const enabled = Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN
.getSurroundLoop(this);
this.setWarningText(enabled ? null :
Blockly.Msg['CONTROLS_FLOW_STATEMENTS_WARNING']);
if (!this.isInFlyout) {
const group = Blockly.Events.getGroup();
// Makes it so the move and the disable event get undone together.
Blockly.Events.setGroup(e.group);
this.setEnabled(enabled);
Blockly.Events.setGroup(group);
}
},
};

Blockly.Extensions.registerMixin('controls_flow_in_loop_check',
Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN);
21 changes: 7 additions & 14 deletions core/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,8 @@ Block.prototype.initModel = function() {
Block.prototype.unplug = function(opt_healStack) {
if (this.outputConnection) {
this.unplugFromRow_(opt_healStack);
} else if (this.previousConnection) {
}
if (this.previousConnection) {
this.unplugFromStack_(opt_healStack);
}
};
Expand Down Expand Up @@ -771,10 +772,12 @@ Block.prototype.setParent = function(newParent) {

// Check that block is connected to new parent if new parent is not null and
// that block is not connected to superior one if new parent is null.
const connection = this.previousConnection || this.outputConnection;
const isConnected = !!(connection && connection.targetBlock());
const targetBlock =
(this.previousConnection && this.previousConnection.targetBlock()) ||
(this.outputConnection && this.outputConnection.targetBlock());
const isConnected = !!targetBlock;

if (isConnected && newParent && connection.targetBlock() !== newParent) {
if (isConnected && newParent && targetBlock !== newParent) {
throw Error('Block connected to superior one that is not new parent.');
} else if (!isConnected && newParent) {
throw Error('Block not connected to new parent.');
Expand Down Expand Up @@ -1186,11 +1189,6 @@ Block.prototype.setPreviousStatement = function(newBoolean, opt_check) {
opt_check = null;
}
if (!this.previousConnection) {
if (this.outputConnection) {
throw Error(
'Remove output connection prior to adding previous ' +
'connection.');
}
this.previousConnection =
this.makeConnection_(ConnectionType.PREVIOUS_STATEMENT);
}
Expand Down Expand Up @@ -1249,11 +1247,6 @@ Block.prototype.setOutput = function(newBoolean, opt_check) {
opt_check = null;
}
if (!this.outputConnection) {
if (this.previousConnection) {
throw Error(
'Remove previous connection prior to adding output ' +
'connection.');
}
this.outputConnection = this.makeConnection_(ConnectionType.OUTPUT_VALUE);
}
this.outputConnection.setCheck(opt_check);
Expand Down
2 changes: 2 additions & 0 deletions core/blockly.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const dialog = goog.require('Blockly.dialog');
const fieldRegistry = goog.require('Blockly.fieldRegistry');
const geras = goog.require('Blockly.geras');
const internalConstants = goog.require('Blockly.internalConstants');
const loopMixin = goog.require('Blockly.loopMixin');
const minimalist = goog.require('Blockly.minimalist');
const registry = goog.require('Blockly.registry');
const svgMath = goog.require('Blockly.utils.svgMath');
Expand Down Expand Up @@ -682,6 +683,7 @@ exports.fieldRegistry = fieldRegistry;
exports.geras = geras;
exports.inject = inject;
exports.inputTypes = inputTypes;
exports.loopMixin = loopMixin;
exports.minimalist = minimalist;
exports.registry = registry;
exports.thrasos = thrasos;
Expand Down
5 changes: 4 additions & 1 deletion core/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,12 @@ const getSelected = function() {
exports.getSelected = getSelected;

/**
* Sets the currently selected block.
* Sets the currently selected block. This function does not visually mark the
* block as selected or fire the required events. If you wish to
* programmatically select a block, use `BlockSvg#select`.
* @param {?ICopyable} newSelection The newly selected block.
* @alias Blockly.common.setSelected
* @package
*/
const setSelected = function(newSelection) {
selected = newSelection;
Expand Down
1 change: 1 addition & 0 deletions core/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ Connection.REASON_CHECKS_FAILED = 4;
Connection.REASON_DIFFERENT_WORKSPACES = 5;
Connection.REASON_SHADOW_PARENT = 6;
Connection.REASON_DRAG_CHECKS_FAILED = 7;
Connection.REASON_PREVIOUS_AND_OUTPUT = 8;

/**
* Connection this connection connects to. Null if not connected.
Expand Down
40 changes: 30 additions & 10 deletions core/connection_checker.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ ConnectionChecker.prototype.getErrorMessage = function(errorCode, a, b) {
return 'Connecting non-shadow to shadow block.';
case Connection.REASON_DRAG_CHECKS_FAILED:
return 'Drag checks failed.';
case Connection.REASON_PREVIOUS_AND_OUTPUT:
return 'Block would have an output and a previous connection.';
default:
return 'Unknown connection failure: this should never happen!';
}
Expand All @@ -140,23 +142,41 @@ ConnectionChecker.prototype.doSafetyChecks = function(a, b) {
if (!a || !b) {
return Connection.REASON_TARGET_NULL;
}
let blockA;
let blockB;
let superiorBlock;
let inferiorBlock;
let superiorConnection;
let inferiorConnection;
if (a.isSuperior()) {
blockA = a.getSourceBlock();
blockB = b.getSourceBlock();
superiorBlock = a.getSourceBlock();
inferiorBlock = b.getSourceBlock();
superiorConnection = a;
inferiorConnection = b;
} else {
blockB = a.getSourceBlock();
blockA = b.getSourceBlock();
inferiorBlock = a.getSourceBlock();
superiorBlock = b.getSourceBlock();
inferiorConnection = a;
superiorConnection = b;
}
if (blockA === blockB) {
if (superiorBlock === inferiorBlock) {
return Connection.REASON_SELF_CONNECTION;
} else if (b.type !== internalConstants.OPPOSITE_TYPE[a.type]) {
} else if (
inferiorConnection.type !==
internalConstants.OPPOSITE_TYPE[superiorConnection.type]) {
return Connection.REASON_WRONG_TYPE;
} else if (blockA.workspace !== blockB.workspace) {
} else if (superiorBlock.workspace !== inferiorBlock.workspace) {
return Connection.REASON_DIFFERENT_WORKSPACES;
} else if (blockA.isShadow() && !blockB.isShadow()) {
} else if (superiorBlock.isShadow() && !inferiorBlock.isShadow()) {
return Connection.REASON_SHADOW_PARENT;
} else if (
inferiorConnection.type === ConnectionType.OUTPUT_VALUE &&
inferiorBlock.previousConnection &&
inferiorBlock.previousConnection.isConnected()) {
return Connection.REASON_PREVIOUS_AND_OUTPUT;
} else if (
inferiorConnection.type === ConnectionType.PREVIOUS_STATEMENT &&
inferiorBlock.outputConnection &&
inferiorBlock.outputConnection.isConnected()) {
return Connection.REASON_PREVIOUS_AND_OUTPUT;
}
return Connection.CAN_CONNECT;
};
Expand Down
6 changes: 5 additions & 1 deletion core/events/events_block_move.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,11 @@ BlockMove.prototype.run = function(forward) {
const xy = block.getRelativeToSurfaceXY();
block.moveBy(coordinate.x - xy.x, coordinate.y - xy.y);
} else {
const blockConnection = block.outputConnection || block.previousConnection;
let blockConnection = block.outputConnection;
if (!blockConnection ||
(block.previousConnection && block.previousConnection.isConnected())) {
blockConnection = block.previousConnection;
}
let parentConnection;
const connectionType = blockConnection.type;
if (inputName) {
Expand Down
28 changes: 23 additions & 5 deletions core/keyboard_nav/ast_node.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,25 @@ ASTNode.createWorkspaceNode = function(workspace, wsCoordinate) {
return new ASTNode(ASTNode.types.WORKSPACE, workspace, params);
};

/**
* Gets the parent connection on a block.
* This is either an output connection, previous connection or undefined.
* If both connections exist return the one that is actually connected
* to another block.
* @param {!Block} block The block to find the parent connection on.
* @return {Connection} The connection connecting to the parent of the
* block.
* @private
*/
const getParentConnection = function(block) {
let topConnection = block.outputConnection;
if (!topConnection ||
(block.previousConnection && block.previousConnection.isConnected())) {
topConnection = block.previousConnection;
}
return topConnection;
};

/**
* Creates an AST node for the top position on a block.
* This is either an output connection, previous connection, or block.
Expand All @@ -240,7 +259,7 @@ ASTNode.createWorkspaceNode = function(workspace, wsCoordinate) {
*/
ASTNode.createTopNode = function(block) {
let astNode;
const topConnection = block.previousConnection || block.outputConnection;
const topConnection = getParentConnection(block);
if (topConnection) {
astNode = ASTNode.createConnectionNode(topConnection);
} else {
Expand Down Expand Up @@ -466,7 +485,7 @@ ASTNode.prototype.navigateBetweenStacks_ = function(forward) {
* @private
*/
ASTNode.prototype.findTopASTNodeForBlock_ = function(block) {
const topConnection = block.previousConnection || block.outputConnection;
const topConnection = getParentConnection(block);
if (topConnection) {
return /** @type {!ASTNode} */ (
ASTNode.createConnectionNode(topConnection));
Expand All @@ -490,8 +509,7 @@ ASTNode.prototype.getOutAstNodeForBlock_ = function(block) {
// If the block doesn't have a previous connection then it is the top of the
// substack.
const topBlock = block.getTopStackBlock();
const topConnection =
topBlock.previousConnection || topBlock.outputConnection;
const topConnection = getParentConnection(topBlock);
// If the top connection has a parentInput, create an AST node pointing to
// that input.
if (topConnection && topConnection.targetConnection &&
Expand Down Expand Up @@ -642,7 +660,7 @@ ASTNode.prototype.prev = function() {

case ASTNode.types.BLOCK: {
const block = /** @type {!Block} */ (this.location_);
const topConnection = block.previousConnection || block.outputConnection;
const topConnection = getParentConnection(block);
return ASTNode.createConnectionNode(topConnection);
}
case ASTNode.types.PREVIOUS: {
Expand Down
Loading

0 comments on commit c11c67e

Please sign in to comment.