* Generate code representing the specified value input. * * @param block The block containing the input. * @param name The name of the input. * @param outerOrder The maximum binding strength (minimum order value) of any * operators adjacent to "block". * @returns Generated code
(block: Block, name: string, outerOrder: number)
| 298 | * @throws ReferenceError if the specified input does not exist. |
| 299 | */ |
| 300 | valueToCode(block: Block, name: string, outerOrder: number): string { |
| 301 | if (isNaN(outerOrder)) { |
| 302 | throw TypeError('Expecting valid order from block: ' + block.type); |
| 303 | } |
| 304 | const targetBlock = block.getInputTargetBlock(name); |
| 305 | if (!targetBlock && !block.getInput(name)) { |
| 306 | throw ReferenceError(`Input "${name}" doesn't exist on "${block.type}"`); |
| 307 | } |
| 308 | if (!targetBlock) { |
| 309 | return ''; |
| 310 | } |
| 311 | const tuple = this.blockToCode(targetBlock); |
| 312 | if (tuple === '') { |
| 313 | // Disabled block. |
| 314 | return ''; |
| 315 | } |
| 316 | // Value blocks must return code and order of operations info. |
| 317 | // Statement blocks must only return code. |
| 318 | if (!Array.isArray(tuple)) { |
| 319 | throw TypeError( |
| 320 | `Expecting tuple from value block: ${targetBlock.type} See ` + |
| 321 | `developers.google.com/blockly/guides/create-custom-blocks/generating-code ` + |
| 322 | `for more information`, |
| 323 | ); |
| 324 | } |
| 325 | let code = tuple[0]; |
| 326 | const innerOrder = tuple[1]; |
| 327 | if (isNaN(innerOrder)) { |
| 328 | throw TypeError( |
| 329 | 'Expecting valid order from value block: ' + targetBlock.type, |
| 330 | ); |
| 331 | } |
| 332 | if (!code) { |
| 333 | return ''; |
| 334 | } |
| 335 | |
| 336 | // Add parentheses if needed. |
| 337 | let parensNeeded = false; |
| 338 | const outerOrderClass = Math.floor(outerOrder); |
| 339 | const innerOrderClass = Math.floor(innerOrder); |
| 340 | if (outerOrderClass <= innerOrderClass) { |
| 341 | if ( |
| 342 | outerOrderClass === innerOrderClass && |
| 343 | (outerOrderClass === 0 || outerOrderClass === 99) |
| 344 | ) { |
| 345 | // Don't generate parens around NONE-NONE and ATOMIC-ATOMIC pairs. |
| 346 | // 0 is the atomic order, 99 is the none order. No parentheses needed. |
| 347 | // In all known languages multiple such code blocks are not order |
| 348 | // sensitive. In fact in Python ('a' 'b') 'c' would fail. |
| 349 | } else { |
| 350 | // The operators outside this code are stronger than the operators |
| 351 | // inside this code. To prevent the code from being pulled apart, |
| 352 | // wrap the code in parentheses. |
| 353 | parensNeeded = true; |
| 354 | // Check for special exceptions. |
| 355 | for (let i = 0; i < this.ORDER_OVERRIDES.length; i++) { |
| 356 | if ( |
| 357 | this.ORDER_OVERRIDES[i][0] === outerOrder && |
no test coverage detected