Add STATEMENT_SUFFIX

Also remove need to manually indent INFINITE_LOOP_TRAP.  This is a breaking change for Python users of this property.  However, very few users of this property exist, given that the existing code breaks if the block ID has a $ in it (also fixed in this PR).
This commit is contained in:
Neil Fraser
2019-05-10 23:19:35 -07:00
committed by Neil Fraser
parent 35cbed1584
commit ba18ae2159
7 changed files with 83 additions and 34 deletions

View File

@@ -62,6 +62,14 @@ Blockly.Generator.prototype.INFINITE_LOOP_TRAP = null;
*/
Blockly.Generator.prototype.STATEMENT_PREFIX = null;
/**
* Arbitrary code to inject after every statement.
* Any instances of '%1' will be replaced by the block ID of the statement.
* E.g. 'highlight(%1);\n'
* @type {?string}
*/
Blockly.Generator.prototype.STATEMENT_SUFFIX = null;
/**
* The method of indenting. Defaults to two spaces, but language generators
* may override this to increase indent or change to tabs.
@@ -126,6 +134,7 @@ Blockly.Generator.prototype.workspaceToCode = function(workspace) {
/**
* Prepend a common prefix onto each line of code.
* Intended for indenting code or adding comment markers.
* @param {string} text The lines of code.
* @param {string} prefix The common prefix.
* @return {string} The prefixed lines of code.
@@ -193,6 +202,9 @@ Blockly.Generator.prototype.blockToCode = function(block, opt_thisOnly) {
if (this.STATEMENT_PREFIX) {
code = this.STATEMENT_PREFIX.replace(/%1/g, '\'' + id + '\'') + code;
}
if (this.STATEMENT_SUFFIX) {
code = code + this.STATEMENT_SUFFIX.replace(/%1/g, '\'' + id + '\'');
}
return this.scrub_(block, code, opt_thisOnly);
} else if (code === null) {
// Block has handled code generation itself.
@@ -299,7 +311,9 @@ Blockly.Generator.prototype.statementToCode = function(block, name) {
/**
* Add an infinite loop trap to the contents of a loop.
* If loop is empty, add a statment prefix for the loop block.
* Add statement suffix at the start of the loop block (right after the loop
* statement executes), and a statement prefix to the end of the loop block
* (right before the loop statement executes).
* @param {string} branch Code for loop contents.
* @param {string} id ID of enclosing block.
* @return {string} Loop contents, with infinite loop trap added.
@@ -307,10 +321,15 @@ Blockly.Generator.prototype.statementToCode = function(block, name) {
Blockly.Generator.prototype.addLoopTrap = function(branch, id) {
id = id.replace(/\$/g, '$$$$'); // Issue 251.
if (this.INFINITE_LOOP_TRAP) {
branch = this.INFINITE_LOOP_TRAP.replace(/%1/g, '\'' + id + '\'') + branch;
branch = this.prefixLines(this.INFINITE_LOOP_TRAP.replace(/%1/g,
'\'' + id + '\''), this.INDENT) + branch;
}
if (this.STATEMENT_SUFFIX) {
branch = this.prefixLines(this.STATEMENT_SUFFIX.replace(/%1/g,
'\'' + id + '\''), this.INDENT) + branch;
}
if (this.STATEMENT_PREFIX) {
branch += this.prefixLines(this.STATEMENT_PREFIX.replace(/%1/g,
branch = branch + this.prefixLines(this.STATEMENT_PREFIX.replace(/%1/g,
'\'' + id + '\''), this.INDENT);
}
return branch;

View File

@@ -516,7 +516,7 @@ Code.initLanguage = function() {
* Just a quick and dirty eval. Catch infinite loops.
*/
Code.runJS = function() {
Blockly.JavaScript.INFINITE_LOOP_TRAP = ' checkTimeout();\n';
Blockly.JavaScript.INFINITE_LOOP_TRAP = 'checkTimeout();\n';
var timeouts = 0;
var checkTimeout = function() {
if (timeouts++ > 1000000) {

View File

@@ -34,15 +34,21 @@ Blockly.Dart['procedures_defreturn'] = function(block) {
var funcName = Blockly.Dart.variableDB_.getName(block.getFieldValue('NAME'),
Blockly.Procedures.NAME_TYPE);
var branch = Blockly.Dart.statementToCode(block, 'STACK');
if (Blockly.Dart.STATEMENT_PREFIX) {
var id = block.id.replace(/\$/g, '$$$$'); // Issue 251.
var id = block.id.replace(/\$/g, '$$$$'); // Issue 251.
if (Blockly.Dart.STATEMENT_SUFFIX) {
branch = Blockly.Dart.prefixLines(
Blockly.Dart.STATEMENT_PREFIX.replace(/%1/g,
'\'' + id + '\''), Blockly.Dart.INDENT) + branch;
Blockly.Dart.STATEMENT_SUFFIX.replace(/%1/g, '\'' + id + '\''),
Blockly.Dart.INDENT) + branch;
}
if (Blockly.Dart.INFINITE_LOOP_TRAP) {
branch = Blockly.Dart.INFINITE_LOOP_TRAP.replace(/%1/g,
'\'' + block.id + '\'') + branch;
branch = Blockly.Dart.prefixLines(
Blockly.Dart.INFINITE_LOOP_TRAP.replace(/%1/g, '\'' + id + '\''),
Blockly.Dart.INDENT) + branch;
}
if (Blockly.Dart.STATEMENT_PREFIX) {
branch = Blockly.Dart.prefixLines(
Blockly.Dart.STATEMENT_PREFIX.replace(/%1/g, '\'' + id + '\''),
Blockly.Dart.INDENT) + branch;
}
var returnValue = Blockly.Dart.valueToCode(block, 'RETURN',
Blockly.Dart.ORDER_NONE) || '';

View File

@@ -34,15 +34,21 @@ Blockly.JavaScript['procedures_defreturn'] = function(block) {
var funcName = Blockly.JavaScript.variableDB_.getName(
block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
var branch = Blockly.JavaScript.statementToCode(block, 'STACK');
if (Blockly.JavaScript.STATEMENT_PREFIX) {
var id = block.id.replace(/\$/g, '$$$$'); // Issue 251.
var id = block.id.replace(/\$/g, '$$$$'); // Issue 251.
if (Blockly.JavaScript.STATEMENT_SUFFIX) {
branch = Blockly.JavaScript.prefixLines(
Blockly.JavaScript.STATEMENT_PREFIX.replace(/%1/g,
'\'' + id + '\''), Blockly.JavaScript.INDENT) + branch;
Blockly.JavaScript.STATEMENT_SUFFIX.replace(/%1/g, '\'' + id + '\''),
Blockly.JavaScript.INDENT) + branch;
}
if (Blockly.JavaScript.INFINITE_LOOP_TRAP) {
branch = Blockly.JavaScript.INFINITE_LOOP_TRAP.replace(/%1/g,
'\'' + block.id + '\'') + branch;
branch = Blockly.JavaScript.prefixLines(
Blockly.JavaScript.INFINITE_LOOP_TRAP.replace(/%1/g, '\'' + id + '\''),
Blockly.JavaScript.INDENT) + branch;
}
if (Blockly.JavaScript.STATEMENT_PREFIX) {
branch = Blockly.JavaScript.prefixLines(
Blockly.JavaScript.STATEMENT_PREFIX.replace(/%1/g, '\'' + id + '\''),
Blockly.JavaScript.INDENT) + branch;
}
var returnValue = Blockly.JavaScript.valueToCode(block, 'RETURN',
Blockly.JavaScript.ORDER_NONE) || '';

View File

@@ -34,15 +34,21 @@ Blockly.Lua['procedures_defreturn'] = function(block) {
var funcName = Blockly.Lua.variableDB_.getName(
block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
var branch = Blockly.Lua.statementToCode(block, 'STACK');
if (Blockly.Lua.STATEMENT_PREFIX) {
var id = block.id.replace(/\$/g, '$$$$'); // Issue 251.
var id = block.id.replace(/\$/g, '$$$$'); // Issue 251.
if (Blockly.Lua.STATEMENT_SUFFIX) {
branch = Blockly.Lua.prefixLines(
Blockly.Lua.STATEMENT_PREFIX.replace(/%1/g,
'\'' + id + '\''), Blockly.Lua.INDENT) + branch;
Blockly.Lua.STATEMENT_SUFFIX.replace(/%1/g, '\'' + id + '\''),
Blockly.Lua.INDENT) + branch;
}
if (Blockly.Lua.INFINITE_LOOP_TRAP) {
branch = Blockly.Lua.INFINITE_LOOP_TRAP.replace(/%1/g,
'\'' + block.id + '\'') + branch;
branch = Blockly.Lua.prefixLines(
Blockly.Lua.INFINITE_LOOP_TRAP.replace(/%1/g, '\'' + id + '\''),
Blockly.Lua.INDENT) + branch;
}
if (Blockly.Lua.STATEMENT_PREFIX) {
branch = Blockly.Lua.prefixLines(
Blockly.Lua.STATEMENT_PREFIX.replace(/%1/g, '\'' + id + '\''),
Blockly.Lua.INDENT) + branch;
}
var returnValue = Blockly.Lua.valueToCode(block, 'RETURN',
Blockly.Lua.ORDER_NONE) || '';

View File

@@ -55,15 +55,21 @@ Blockly.PHP['procedures_defreturn'] = function(block) {
var funcName = Blockly.PHP.variableDB_.getName(
block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
var branch = Blockly.PHP.statementToCode(block, 'STACK');
if (Blockly.PHP.STATEMENT_PREFIX) {
var id = block.id.replace(/\$/g, '$$$$'); // Issue 251.
var id = block.id.replace(/\$/g, '$$$$'); // Issue 251.
if (Blockly.PHP.STATEMENT_SUFFIX) {
branch = Blockly.PHP.prefixLines(
Blockly.PHP.STATEMENT_PREFIX.replace(
/%1/g, '\'' + id + '\''), Blockly.PHP.INDENT) + branch;
Blockly.PHP.STATEMENT_SUFFIX.replace(/%1/g, '\'' + id + '\''),
Blockly.PHP.INDENT) + branch;
}
if (Blockly.PHP.INFINITE_LOOP_TRAP) {
branch = Blockly.PHP.INFINITE_LOOP_TRAP.replace(/%1/g,
'\'' + block.id + '\'') + branch;
branch = Blockly.PHP.prefixLines(
Blockly.PHP.INFINITE_LOOP_TRAP.replace(/%1/g, '\'' + id + '\''),
Blockly.PHP.INDENT) + branch;
}
if (Blockly.PHP.STATEMENT_PREFIX) {
branch = Blockly.PHP.prefixLines(
Blockly.PHP.STATEMENT_PREFIX.replace(/%1/g, '\'' + id + '\''),
Blockly.PHP.INDENT) + branch;
}
var returnValue = Blockly.PHP.valueToCode(block, 'RETURN',
Blockly.PHP.ORDER_NONE) || '';

View File

@@ -56,15 +56,21 @@ Blockly.Python['procedures_defreturn'] = function(block) {
var funcName = Blockly.Python.variableDB_.getName(
block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
var branch = Blockly.Python.statementToCode(block, 'STACK');
if (Blockly.Python.STATEMENT_PREFIX) {
var id = block.id.replace(/\$/g, '$$$$'); // Issue 251.
var id = block.id.replace(/\$/g, '$$$$'); // Issue 251.
if (Blockly.Python.STATEMENT_SUFFIX) {
branch = Blockly.Python.prefixLines(
Blockly.Python.STATEMENT_PREFIX.replace(
/%1/g, '\'' + id + '\''), Blockly.Python.INDENT) + branch;
Blockly.Python.STATEMENT_SUFFIX.replace( /%1/g, '\'' + id + '\''),
Blockly.Python.INDENT) + branch;
}
if (Blockly.Python.INFINITE_LOOP_TRAP) {
branch = Blockly.Python.INFINITE_LOOP_TRAP.replace(/%1/g,
'"' + block.id + '"') + branch;
branch = Blockly.Python.prefixLines(
Blockly.Python.INFINITE_LOOP_TRAP.replace(/%1/g, '\'' + id + '\''),
Blockly.Python.INDENT) + branch;
}
if (Blockly.Python.STATEMENT_PREFIX) {
branch = Blockly.Python.prefixLines(
Blockly.Python.STATEMENT_PREFIX.replace( /%1/g, '\'' + id + '\''),
Blockly.Python.INDENT) + branch;
}
var returnValue = Blockly.Python.valueToCode(block, 'RETURN',
Blockly.Python.ORDER_NONE) || '';