mo4islona / node-blockly

Blockly for Node.js and Browser via CommonJS module
133 stars 81 forks source link

Generator type is not always the same as block type for certain blocks #39

Closed Alexejhero closed 4 years ago

Alexejhero commented 4 years ago

I have the following block: image

with the following definition:

{
  "icons": [
    "event"
  ],
  "max": 1,
  "block": {
    "type": "on_message",
    "message0": "on message received %1 %2",
    "args0": [
      {
        "type": "input_dummy"
      },
      {
        "type": "input_statement",
        "name": "code"
      }
    ],
    "colour": 0,
    "tooltip": "Triggers when a message is received",
    "helpUrl": ""
  },
  "generator": "_return = '\\\\nmodule.exports.message = async message => { try { var channel = message.channel; var member = message.member; var guild = message.guild; ' + Blockly.JavaScript.statementToCode(block, 'code') + '} catch (e) { require(\"../../src/errors\").onerror(\"' + data.req.body.guild  + '\", e); } }'"
}
How the generator property is handled ```js if (json.generator || json.returnGen) { generators.push({ type: json.block.type, generator: json.generator, returnGen: json.returnGen, }); } ``` Client-side (not used for anything except debugging): ```ejs <% generators.forEach(g => { %> Blockly.JavaScript['<%= g.type %>'] = function(block) { var _return; if (block.returns) eval(decode("<%= g.returnGen %>")); else eval(decode("<%= g.generator %>")); return _return; } <% }); %> ``` Server-side (used for compiling): ```js for (var generator of dlocklyInstance.generators) { Blockly.JavaScript[generator.type] = function (block) { var _return; if (block.returns) eval(generator.returnGen.replace(/\\\\/g, "\\")); else eval(generator.generator.replace(/\\\\/g, "\\")); return _return; } } ``` Basically, in the end, the block's generator is set correctly. The `returns` property of the block is used for a generic mutation, and this error only occurs with event/root blocks. (unmutated)

I use two environments. I use the browser version of Blockly (obviously), and I also use the Node version of Blockly in order to compile XML server-side and avoid code injection.

When running the workspaceToCode function in the browser, the returned code is correct:

module.exports.message = async message => {
    try {
        var channel = message.channel;
        var member = message.member;
        var guild = message.guild;
    } catch (e) {
        require("../../src/errors").onerror("591692042304880815", e);
    }
}

However, when running the workspaceToCode function server-side, an error is thrown

TypeError: Expecting string from statement block: on_message
    at module.exports.Blockly.Generator.blockToCode (C:\Users\user\Desktop\Dlockly\node_modules\.pnpm\registry.npmjs.org\node-blockly\1.2.5\node_modules\node-blockly\lib\blockly_compressed.js:864:348)      
    at module.exports.Blockly.Generator.workspaceToCode (C:\Users\user\Desktop\Dlockly\node_modules\.pnpm\registry.npmjs.org\node-blockly\1.2.5\node_modules\node-blockly\lib\blockly_compressed.js:862:246)  

I replaced the server-side generator with this, in order to add some console logs:

for (var generator of dlocklyInstance.generators) {
  Blockly.JavaScript[generator.type] = function (block) {
    var _return;
    console.log(generator.type);
    console.log(block.type);
    if (block.returns) eval(generator.returnGen.replace(/\\\\/g, "\\"));
    else eval(generator.generator.replace(/\\\\/g, "\\"));
    console.log(_return);
    return _return;
  }
}

And I got the following result: generator.type = send_message block.type = on_message _return = await .send(); // Code generated via the send_message generator

What?? The block uses a different generator?

I have been trying to wrap my head around this for a while. I do not think this is an issue with my code, since no matter how badly I mess up the code, generator.type should never be different from block.type. Right?


I decided to post this issue here first before posting it on the main blockly repository, in case there was any relation specifically to the node version.

Alexejhero commented 4 years ago

Update:

I added this to the generator, and it now causes an infinite loop.

if (generator.type != block.type) return Blockly.JavaScript[block.type](block);

I don't understand what's happening anymore.

Alexejhero commented 4 years ago

Fixed. There was a bug in my code.