mirror of
https://github.com/google/blockly.git
synced 2026-01-15 12:57:12 +01:00
Merge pull request #1522 from rachel-fenichel/bugfix/variables_procedures
Fix generator tests
This commit is contained in:
@@ -26,6 +26,14 @@
|
||||
|
||||
goog.provide('Blockly.Names');
|
||||
|
||||
/**
|
||||
* Constant to separate developer variable names from user-defined variable
|
||||
* names when running generators.
|
||||
* A developer variable will be declared as a global in the generated code, but
|
||||
* will never be shown to the user in the workspace or stored in the variable
|
||||
* map.
|
||||
*/
|
||||
Blockly.Names.DEVELOPER_VARIABLE_TYPE = 'DEVELOPER_VARIABLE';
|
||||
|
||||
/**
|
||||
* Class for a database of entity names (variables, functions, etc).
|
||||
@@ -62,6 +70,41 @@ Blockly.Names = function(reservedWords, opt_variablePrefix) {
|
||||
Blockly.Names.prototype.reset = function() {
|
||||
this.db_ = Object.create(null);
|
||||
this.dbReverse_ = Object.create(null);
|
||||
this.variableMap_ = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the variable map that maps from variable name to variable object.
|
||||
* @param {!Blockly.VariableMap} map The map to track.
|
||||
* @package
|
||||
*/
|
||||
Blockly.Names.prototype.setVariableMap = function(map) {
|
||||
this.variableMap_ = map;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the name for a user-defined variable, based on its ID.
|
||||
* This should only be used for variables of type Blockly.Variables.NAME_TYPE.
|
||||
* @param {string} id The ID to look up in the variable map.
|
||||
* @return {?string} The name of the referenced variable, or null if there was
|
||||
* no variable map or the variable was not found in the map.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Names.prototype.getNameForUserVariable_ = function(id) {
|
||||
if (!this.variableMap_) {
|
||||
console.log('Deprecated call to Blockly.Names.prototype.getName without ' +
|
||||
'defining a variable map. To fix, add the folowing code in your ' +
|
||||
'generator\'s init() function:\n' +
|
||||
'Blockly.YourGeneratorName.variableDB_.setVariableMap(' +
|
||||
'workspace.getVariableMap());');
|
||||
return null;
|
||||
}
|
||||
var variable = this.variableMap_.getVariableById(id);
|
||||
if (variable) {
|
||||
return variable.name;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -72,9 +115,18 @@ Blockly.Names.prototype.reset = function() {
|
||||
* @return {string} An entity name legal for the exported language.
|
||||
*/
|
||||
Blockly.Names.prototype.getName = function(name, type) {
|
||||
if (type == Blockly.Variables.NAME_TYPE) {
|
||||
var varName = this.getNameForUserVariable_(name);
|
||||
if (varName) {
|
||||
name = varName;
|
||||
}
|
||||
}
|
||||
var normalized = name.toLowerCase() + '_' + type;
|
||||
var prefix = (type == Blockly.Variables.NAME_TYPE) ?
|
||||
this.variablePrefix_ : '';
|
||||
|
||||
var isVarType = type == Blockly.Variables.NAME_TYPE ||
|
||||
type == Blockly.Names.DEVELOPER_VARIABLE_TYPE;
|
||||
|
||||
var prefix = isVarType ? this.variablePrefix_ : '';
|
||||
if (normalized in this.db_) {
|
||||
return prefix + this.db_[normalized];
|
||||
}
|
||||
@@ -103,8 +155,9 @@ Blockly.Names.prototype.getDistinctName = function(name, type) {
|
||||
}
|
||||
safeName += i;
|
||||
this.dbReverse_[safeName] = true;
|
||||
var prefix = (type == Blockly.Variables.NAME_TYPE) ?
|
||||
this.variablePrefix_ : '';
|
||||
var isVarType = type == Blockly.Variables.NAME_TYPE ||
|
||||
type == Blockly.Names.DEVELOPER_VARIABLE_TYPE;
|
||||
var prefix = isVarType ? this.variablePrefix_ : '';
|
||||
return prefix + safeName;
|
||||
};
|
||||
|
||||
|
||||
@@ -100,6 +100,38 @@ Blockly.Variables.allVariables = function(root) {
|
||||
return root.getAllVariables();
|
||||
};
|
||||
|
||||
/**
|
||||
* Find all developer variables used by blocks in the workspace.
|
||||
* Developer variables are never shown to the user, but are declared as global
|
||||
* variables in the generated code.
|
||||
* To declare developer variables, define the getDeveloperVariables function on
|
||||
* your block and return a list of variable names.
|
||||
* For use by generators.
|
||||
* @param {!Blockly.Workspace} workspace The workspace to search.
|
||||
* @return {!Array.<string>} A list of non-duplicated variable names.
|
||||
* @package
|
||||
*/
|
||||
Blockly.Variables.allDeveloperVariables = function(workspace) {
|
||||
var blocks = workspace.getAllBlocks();
|
||||
var hash = {};
|
||||
for (var i = 0; i < blocks.length; i++) {
|
||||
var block = blocks[i];
|
||||
if (block.getDeveloperVars) {
|
||||
var devVars = block.getDeveloperVars();
|
||||
for (var j = 0; j < devVars.length; j++) {
|
||||
hash[devVars[j]] = devVars[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flatten the hash into a list.
|
||||
var list = [];
|
||||
for (var name in hash) {
|
||||
list.push(hash[name]);
|
||||
}
|
||||
return list;
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct the elements (blocks and button) required by the flyout for the
|
||||
* variable category.
|
||||
|
||||
@@ -102,13 +102,25 @@ Blockly.Dart.init = function(workspace) {
|
||||
Blockly.Dart.variableDB_.reset();
|
||||
}
|
||||
|
||||
Blockly.Dart.variableDB_.setVariableMap(workspace.getVariableMap());
|
||||
|
||||
var defvars = [];
|
||||
// Add user variables.
|
||||
var variables = workspace.getAllVariables();
|
||||
if (variables.length) {
|
||||
for (var i = 0; i < variables.length; i++) {
|
||||
defvars[i] = Blockly.Dart.variableDB_.getName(variables[i].name,
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
}
|
||||
for (var i = 0; i < variables.length; i++) {
|
||||
defvars[i] = Blockly.Dart.variableDB_.getName(variables[i].name,
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
}
|
||||
|
||||
// Add developer variables (not created or named by the user).
|
||||
var devVarList = Blockly.Variables.allDeveloperVariables(workspace);
|
||||
for (var i = 0; i < devVarList.length; i++) {
|
||||
defvars.push(Blockly.Dart.variableDB_.getName(devVarList[i],
|
||||
Blockly.Names.DEVELOPER_VARIABLE_TYPE));
|
||||
}
|
||||
|
||||
// Declare all of the variables.
|
||||
if (defvars.length) {
|
||||
Blockly.Dart.definitions_['variables'] =
|
||||
'var ' + defvars.join(', ') + ';';
|
||||
}
|
||||
|
||||
@@ -152,13 +152,25 @@ Blockly.JavaScript.init = function(workspace) {
|
||||
Blockly.JavaScript.variableDB_.reset();
|
||||
}
|
||||
|
||||
Blockly.JavaScript.variableDB_.setVariableMap(workspace.getVariableMap());
|
||||
|
||||
var defvars = [];
|
||||
// Add user variables.
|
||||
var variables = workspace.getAllVariables();
|
||||
if (variables.length) {
|
||||
for (var i = 0; i < variables.length; i++) {
|
||||
defvars[i] = Blockly.JavaScript.variableDB_.getName(variables[i].name,
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
}
|
||||
for (var i = 0; i < variables.length; i++) {
|
||||
defvars[i] = Blockly.JavaScript.variableDB_.getName(variables[i].name,
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
}
|
||||
|
||||
// Add developer variables (not created or named by the user).
|
||||
var devVarList = Blockly.Variables.allDeveloperVariables(workspace);
|
||||
for (var i = 0; i < devVarList.length; i++) {
|
||||
defvars.push(Blockly.JavaScript.variableDB_.getName(devVarList[i],
|
||||
Blockly.Names.DEVELOPER_VARIABLE_TYPE));
|
||||
}
|
||||
|
||||
// Declare all of the variables.
|
||||
if (defvars.length) {
|
||||
Blockly.JavaScript.definitions_['variables'] =
|
||||
'var ' + defvars.join(', ') + ';';
|
||||
}
|
||||
|
||||
@@ -109,6 +109,7 @@ Blockly.Lua.init = function(workspace) {
|
||||
} else {
|
||||
Blockly.Lua.variableDB_.reset();
|
||||
}
|
||||
Blockly.Lua.variableDB_.setVariableMap(workspace.getVariableMap());
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -149,14 +149,25 @@ Blockly.PHP.init = function(workspace) {
|
||||
Blockly.PHP.variableDB_.reset();
|
||||
}
|
||||
|
||||
Blockly.PHP.variableDB_.setVariableMap(workspace.getVariableMap());
|
||||
|
||||
var defvars = [];
|
||||
var varName;
|
||||
var variables = Blockly.Variables.allVariables(workspace);
|
||||
var variables = workspace.getAllVariables();
|
||||
for (var i = 0, variable; variable = variables[i]; i++) {
|
||||
varName = variable.name;
|
||||
defvars[i] = Blockly.PHP.variableDB_.getName(varName,
|
||||
Blockly.Variables.NAME_TYPE) + ';';
|
||||
}
|
||||
|
||||
// Add developer variables (not created or named by the user).
|
||||
var devVarList = Blockly.Variables.allDeveloperVariables(workspace);
|
||||
for (var i = 0; i < devVarList.length; i++) {
|
||||
defvars.push(Blockly.PHP.variableDB_.getName(devVarList[i],
|
||||
Blockly.Names.DEVELOPER_VARIABLE_TYPE) + ';');
|
||||
}
|
||||
|
||||
// Declare all of the variables.
|
||||
Blockly.PHP.definitions_['variables'] = defvars.join('\n');
|
||||
};
|
||||
|
||||
|
||||
@@ -160,12 +160,21 @@ Blockly.Python.init = function(workspace) {
|
||||
Blockly.Python.variableDB_.reset();
|
||||
}
|
||||
|
||||
Blockly.Python.variableDB_.setVariableMap(workspace.getVariableMap());
|
||||
|
||||
var defvars = [];
|
||||
var variables = workspace.getAllVariables();
|
||||
for (var i = 0; i < variables.length; i++) {
|
||||
defvars[i] = Blockly.Python.variableDB_.getName(variables[i].name,
|
||||
Blockly.Variables.NAME_TYPE) + ' = None';
|
||||
}
|
||||
|
||||
// Add developer variables (not created or named by the user).
|
||||
var devVarList = Blockly.Variables.allDeveloperVariables(workspace);
|
||||
for (var i = 0; i < devVarList.length; i++) {
|
||||
defvars.push(Blockly.Python.variableDB_.getName(devVarList[i],
|
||||
Blockly.Names.DEVELOPER_VARIABLE_TYPE) + ' = None');
|
||||
}
|
||||
Blockly.Python.definitions_['variables'] = defvars.join('\n');
|
||||
};
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ Blockly.Blocks['unittest_main'] = {
|
||||
this.setTooltip('Executes the enclosed unit tests,\n' +
|
||||
'then prints a summary.');
|
||||
},
|
||||
getVars: function() {
|
||||
getDeveloperVars: function() {
|
||||
return ['unittestResults'];
|
||||
}
|
||||
};
|
||||
@@ -54,7 +54,7 @@ Blockly.Blocks['unittest_assertequals'] = {
|
||||
.appendField('expected');
|
||||
this.setTooltip('Tests that "actual == expected".');
|
||||
},
|
||||
getVars: function() {
|
||||
getDeveloperVars: function() {
|
||||
return ['unittestResults'];
|
||||
}
|
||||
};
|
||||
@@ -74,7 +74,7 @@ Blockly.Blocks['unittest_assertvalue'] = {
|
||||
[['true', 'TRUE'], ['false', 'FALSE'], ['null', 'NULL']]), 'EXPECTED');
|
||||
this.setTooltip('Tests that the value is true, false, or null.');
|
||||
},
|
||||
getVars: function() {
|
||||
getDeveloperVars: function() {
|
||||
return ['unittestResults'];
|
||||
}
|
||||
};
|
||||
@@ -90,7 +90,7 @@ Blockly.Blocks['unittest_fail'] = {
|
||||
.appendField('fail');
|
||||
this.setTooltip('Records an error.');
|
||||
},
|
||||
getVars: function() {
|
||||
getDeveloperVars: function() {
|
||||
return ['unittestResults'];
|
||||
}
|
||||
};
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
Blockly.Dart['unittest_main'] = function(block) {
|
||||
// Container for unit tests.
|
||||
var resultsVar = Blockly.Dart.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
Blockly.Names.DEVELOPER_VARIABLE_TYPE);
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'unittest_report',
|
||||
[ 'String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + '() {',
|
||||
@@ -71,7 +71,7 @@ Blockly.Dart['unittest_main'] = function(block) {
|
||||
|
||||
Blockly.Dart['unittest_main'].defineAssert_ = function() {
|
||||
var resultsVar = Blockly.Dart.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
Blockly.Names.DEVELOPER_VARIABLE_TYPE);
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'unittest_assertequals',
|
||||
[ 'void ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
@@ -139,7 +139,7 @@ Blockly.Dart['unittest_assertvalue'] = function(block) {
|
||||
Blockly.Dart['unittest_fail'] = function(block) {
|
||||
// Always assert an error.
|
||||
var resultsVar = Blockly.Dart.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
Blockly.Names.DEVELOPER_VARIABLE_TYPE);
|
||||
var message = Blockly.Dart.quote_(block.getFieldValue('MESSAGE'));
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'unittest_fail',
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
Blockly.JavaScript['unittest_main'] = function(block) {
|
||||
// Container for unit tests.
|
||||
var resultsVar = Blockly.JavaScript.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
Blockly.Names.DEVELOPER_VARIABLE_TYPE);
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'unittest_report',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '() {',
|
||||
@@ -72,7 +72,7 @@ Blockly.JavaScript['unittest_main'] = function(block) {
|
||||
|
||||
Blockly.JavaScript['unittest_main'].defineAssert_ = function(block) {
|
||||
var resultsVar = Blockly.JavaScript.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
Blockly.Names.DEVELOPER_VARIABLE_TYPE);
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'assertEquals',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
@@ -143,7 +143,7 @@ Blockly.JavaScript['unittest_assertvalue'] = function(block) {
|
||||
Blockly.JavaScript['unittest_fail'] = function(block) {
|
||||
// Always assert an error.
|
||||
var resultsVar = Blockly.JavaScript.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
Blockly.Names.DEVELOPER_VARIABLE_TYPE);
|
||||
var message = Blockly.JavaScript.quote_(block.getFieldValue('MESSAGE'));
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'unittest_fail',
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
Blockly.Lua['unittest_main'] = function(block) {
|
||||
// Container for unit tests.
|
||||
var resultsVar = Blockly.Lua.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
Blockly.Names.DEVELOPER_VARIABLE_TYPE);
|
||||
var functionName = Blockly.Lua.provideFunction_(
|
||||
'unittest_report',
|
||||
['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '()',
|
||||
@@ -70,7 +70,7 @@ Blockly.Lua['unittest_main'] = function(block) {
|
||||
|
||||
Blockly.Lua['unittest_main'].defineAssert_ = function(block) {
|
||||
var resultsVar = Blockly.Lua.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
Blockly.Names.DEVELOPER_VARIABLE_TYPE);
|
||||
var functionName = Blockly.Lua.provideFunction_(
|
||||
'assertEquals',
|
||||
['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
@@ -149,7 +149,7 @@ Blockly.Lua['unittest_assertvalue'] = function(block) {
|
||||
Blockly.Lua['unittest_fail'] = function(block) {
|
||||
// Always assert an error.
|
||||
var resultsVar = Blockly.Lua.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
Blockly.Names.DEVELOPER_VARIABLE_TYPE);
|
||||
var message = Blockly.Lua.quote_(block.getFieldValue('MESSAGE'));
|
||||
var functionName = Blockly.Lua.provideFunction_(
|
||||
'unittest_fail',
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
Blockly.PHP['unittest_main'] = function(block) {
|
||||
// Container for unit tests.
|
||||
var resultsVar = Blockly.PHP.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
Blockly.Names.DEVELOPER_VARIABLE_TYPE);
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'unittest_report',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '() {',
|
||||
@@ -72,7 +72,7 @@ Blockly.PHP['unittest_main'] = function(block) {
|
||||
|
||||
Blockly.PHP['unittest_main'].defineAssert_ = function(block) {
|
||||
var resultsVar = Blockly.PHP.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
Blockly.Names.DEVELOPER_VARIABLE_TYPE);
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'assertEquals',
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
@@ -129,7 +129,7 @@ Blockly.PHP['unittest_assertvalue'] = function(block) {
|
||||
Blockly.PHP['unittest_fail'] = function(block) {
|
||||
// Always assert an error.
|
||||
var resultsVar = Blockly.PHP.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
Blockly.Names.DEVELOPER_VARIABLE_TYPE);
|
||||
var message = Blockly.PHP.quote_(block.getFieldValue('MESSAGE'));
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'unittest_fail',
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
Blockly.Python['unittest_main'] = function(block) {
|
||||
// Container for unit tests.
|
||||
var resultsVar = Blockly.Python.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
Blockly.Names.DEVELOPER_VARIABLE_TYPE);
|
||||
var functionName = Blockly.Python.provideFunction_(
|
||||
'unittest_report',
|
||||
['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '():',
|
||||
@@ -68,7 +68,7 @@ Blockly.Python['unittest_main'] = function(block) {
|
||||
|
||||
Blockly.Python['unittest_main'].defineAssert_ = function() {
|
||||
var resultsVar = Blockly.Python.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
Blockly.Names.DEVELOPER_VARIABLE_TYPE);
|
||||
var functionName = Blockly.Python.provideFunction_(
|
||||
'assertEquals',
|
||||
['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
@@ -117,7 +117,7 @@ Blockly.Python['unittest_assertvalue'] = function(block) {
|
||||
Blockly.Python['unittest_fail'] = function(block) {
|
||||
// Always assert an error.
|
||||
var resultsVar = Blockly.Python.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
Blockly.Names.DEVELOPER_VARIABLE_TYPE);
|
||||
var message = Blockly.Python.quote_(block.getFieldValue('MESSAGE'));
|
||||
var functionName = Blockly.Python.provideFunction_(
|
||||
'fail',
|
||||
|
||||
Reference in New Issue
Block a user