@@ -310,6 +310,17 @@ class RubyToBlocksConverter {
310310 return block ;
311311 }
312312
313+ _addField ( block , name , value ) {
314+ if ( ! this . _isBlock ( block ) ) {
315+ return ;
316+ }
317+ block . fields [ name ] = {
318+ name : name ,
319+ value : value
320+ } ;
321+ return block . fields [ name ] ;
322+ }
323+
313324 _addInput ( block , name , inputBlock , shadowBlock ) {
314325 if ( ! name ) {
315326 name = inputBlock . id ;
@@ -468,6 +479,20 @@ class RubyToBlocksConverter {
468479 return null ;
469480 }
470481
482+ _processCondition ( node ) {
483+ let cond = this . _process ( node . children [ 0 ] ) ;
484+ if ( _ . isArray ( cond ) && cond . length === 1 ) {
485+ cond = cond [ 0 ] ;
486+ }
487+ if ( ! this . _isFalseOrBooleanBlock ( cond ) ) {
488+ throw new RubyToBlocksConverterError (
489+ node ,
490+ `condition is not boolean: ${ this . _getSource ( node . children [ 0 ] ) } `
491+ ) ;
492+ }
493+ return cond ;
494+ }
495+
471496 _getBlockType ( block ) {
472497 return this . _context . blockTypes [ block . id ] ;
473498 }
@@ -1225,28 +1250,45 @@ class RubyToBlocksConverter {
12251250 this . _checkNumChildren ( node , 3 ) ;
12261251
12271252 const saved = this . _saveContext ( ) ;
1228- let cond = this . _process ( node . children [ 0 ] ) ;
1229- if ( ! this . _isFalseOrBooleanBlock ( cond ) ) {
1230- this . _restoreContext ( saved ) ;
1231- cond = this . _createRubyExpressionBlock ( this . _getSource ( node . children [ 0 ] ) ) ;
1232- }
1253+
1254+ const cond = this . _processCondition ( node ) ;
12331255 let statement = this . _process ( node . children [ 1 ] ) ;
12341256 if ( ! _ . isArray ( statement ) ) {
12351257 statement = [ statement ] ;
12361258 }
1237- let elseStatement = this . _process ( node . children [ 2 ] ) ;
1238- if ( ! _ . isArray ( elseStatement ) ) {
1239- elseStatement = [ elseStatement ] ;
1259+ let elseStatement ;
1260+ if ( node . $loc ( ) . $else ( ) !== Opal . nil ) {
1261+ elseStatement = this . _process ( node . children [ 2 ] ) ;
1262+ if ( ! _ . isArray ( elseStatement ) ) {
1263+ elseStatement = [ elseStatement ] ;
1264+ }
12401265 }
12411266
1242- const block = this . _createBlock ( 'control_if' , 'statement' ) ;
1243- if ( cond !== false ) {
1244- this . _addInput ( block , 'CONDITION' , cond ) ;
1267+ let block = this . _callConvertersHandler ( 'onIf' , cond , statement , elseStatement ) ;
1268+ if ( ! block ) {
1269+ this . _restoreContext ( saved ) ;
1270+
1271+ block = this . _createRubyStatementBlock ( this . _getSource ( node ) ) ;
1272+ }
1273+ return block ;
1274+ }
1275+
1276+ _onUntil ( node ) {
1277+ this . _checkNumChildren ( node , 2 ) ;
1278+
1279+ const saved = this . _saveContext ( ) ;
1280+
1281+ const cond = this . _processCondition ( node ) ;
1282+ let statement = this . _process ( node . children [ 1 ] ) ;
1283+ if ( ! _ . isArray ( statement ) ) {
1284+ statement = [ statement ] ;
12451285 }
1246- this . _addSubstack ( block , statement ) ;
1247- if ( this . _isBlock ( elseStatement [ 0 ] ) ) {
1248- block . opcode = 'control_if_else' ;
1249- this . _addSubstack ( block , elseStatement , 2 ) ;
1286+
1287+ let block = this . _callConvertersHandler ( 'onUntil' , cond , statement ) ;
1288+ if ( ! block ) {
1289+ this . _restoreContext ( saved ) ;
1290+
1291+ block = this . _createRubyStatementBlock ( this . _getSource ( node ) ) ;
12501292 }
12511293 return block ;
12521294 }
0 commit comments