Skip to content

Commit a7df28e

Browse files
authored
adding options for break / continue (microsoft#5910)
* adding options for break / continue * guard decompiler * fix examples * update test apptarget
1 parent 857065b commit a7df28e

8 files changed

Lines changed: 87 additions & 43 deletions

File tree

common-docs/blocks/loops/break.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Break out of the current loop and continue the program.
44

55
```block
66
while(true) {
7-
if (Math.random() > 0.5) {
7+
if (Math.randomRange(0, 10) > 5) {
88
break;
99
}
1010
}

common-docs/blocks/loops/continue.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Skip the rest of the code in a loop and start the loop again.
44

55
```block
66
while(true) {
7-
if (Math.random() > 0.5) {
7+
if (Math.randomRange(0, 10) > 5) {
88
// skip the rest of the loop
99
continue;
1010
}

docs/playground-runner.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@
8080
tsprj: undefined,
8181
blocksprj: undefined,
8282
runtime: {
83-
pauseUntilBlock: { category: "Loops", color: "0x0000ff" }
83+
pauseUntilBlock: { category: "Loops", color: "0x0000ff" },
84+
breakBlock: { category: "Loops", color: "0x0000ff" },
85+
continueBlock: { category: "Loops", color: "0x0000ff" }
8486
},
8587
corepkg: undefined
8688
});

localtypings/pxtarget.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ declare namespace pxt {
103103
onStartWeight?: number;
104104
onStartUnDeletable?: boolean;
105105
pauseUntilBlock?: BlockOptions;
106+
breakBlock?: BlockOptions;
107+
continueBlock?: BlockOptions;
106108
extraBlocks?: BlockToolboxDefinition[]; // deprecated
107109
assetExtensions?: string[];
108110
palette?: string[];

pxtblocks/blocklyloader.ts

Lines changed: 58 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ namespace pxt.blocks {
612612
block.setPreviousStatement(!(hasHandlers && !fn.attributes.handlerStatement) && fn.retType == "void");
613613
block.setNextStatement(!(hasHandlers && !fn.attributes.handlerStatement) && fn.retType == "void");
614614

615-
block.setTooltip( /^__/.test(fn.namespace) ? "" : fn.attributes.jsDoc);
615+
block.setTooltip(/^__/.test(fn.namespace) ? "" : fn.attributes.jsDoc);
616616
function buildBlockFromDef(def: pxtc.ParsedBlockDef, expanded = false) {
617617
let anonIndex = 0;
618618
let firstParam = !expanded && !!comp.thisParameter;
@@ -919,9 +919,9 @@ namespace pxt.blocks {
919919
output.push("Boolean");
920920
break;
921921
case "T":
922-
// The type is generic, so accept any checks. This is mostly used with functions that
923-
// get values from arrays. This could be improved if we ever add proper type
924-
// inference for generic types
922+
// The type is generic, so accept any checks. This is mostly used with functions that
923+
// get values from arrays. This could be improved if we ever add proper type
924+
// inference for generic types
925925
case "any":
926926
return null;
927927
case "void":
@@ -1252,46 +1252,64 @@ namespace pxt.blocks {
12521252
};
12531253

12541254
// break statement
1255-
Blockly.Blocks[pxtc.TS_BREAK_TYPE] = {
1256-
init: function () {
1257-
let that: Blockly.Block = this;
1258-
that.setColour(pxt.toolbox.getNamespaceColor('loops'))
1259-
that.setPreviousStatement(true);
1260-
that.setNextStatement(true);
1261-
that.setInputsInline(false);
1262-
that.appendDummyInput()
1263-
.appendField(new Blockly.FieldLabel(lf("break"), undefined))
1255+
if (pxt.appTarget.runtime && pxt.appTarget.runtime.breakBlock) {
1256+
const blockOptions = pxt.appTarget.runtime.breakBlock;
1257+
const blockDef = pxt.blocks.getBlockDefinition(ts.pxtc.TS_BREAK_TYPE);
1258+
Blockly.Blocks[pxtc.TS_BREAK_TYPE] = {
1259+
init: function () {
1260+
const color = blockOptions.color || pxt.toolbox.getNamespaceColor('loops');
12641261

1265-
setHelpResources(this,
1266-
pxtc.TS_BREAK_TYPE,
1267-
lf("Break statement"),
1268-
lf("Break out of the current loop or switch"),
1269-
'/blocks/loops/break',
1270-
pxt.toolbox.getNamespaceColor('loops')
1271-
);
1262+
this.jsonInit({
1263+
"message0": blockDef.block["message0"],
1264+
"inputsInline": true,
1265+
"previousStatement": null,
1266+
"nextStatement": null,
1267+
"colour": color
1268+
});
1269+
1270+
setHelpResources(this,
1271+
ts.pxtc.TS_BREAK_TYPE,
1272+
blockDef.name,
1273+
blockDef.tooltip,
1274+
blockDef.url,
1275+
color,
1276+
undefined/*colourSecondary*/,
1277+
undefined/*colourTertiary*/,
1278+
false/*undeletable*/
1279+
);
1280+
}
12721281
}
1273-
};
1282+
}
12741283

1275-
// loops statement
1276-
Blockly.Blocks[pxtc.TS_CONTINUE_TYPE] = {
1277-
init: function () {
1278-
let that: Blockly.Block = this;
1279-
that.setColour(pxt.toolbox.getNamespaceColor('loops'))
1280-
that.setPreviousStatement(true);
1281-
that.setNextStatement(true);
1282-
that.setInputsInline(false);
1283-
that.appendDummyInput()
1284-
.appendField(new Blockly.FieldLabel(lf("continue"), undefined))
1284+
// continue statement
1285+
if (pxt.appTarget.runtime && pxt.appTarget.runtime.continueBlock) {
1286+
const blockOptions = pxt.appTarget.runtime.continueBlock;
1287+
const blockDef = pxt.blocks.getBlockDefinition(ts.pxtc.TS_CONTINUE_TYPE);
1288+
Blockly.Blocks[pxtc.TS_CONTINUE_TYPE] = {
1289+
init: function () {
1290+
const color = blockOptions.color || pxt.toolbox.getNamespaceColor('loops');
12851291

1286-
setHelpResources(this,
1287-
pxtc.TS_CONTINUE_TYPE,
1288-
lf("Continue statement"),
1289-
lf("The continue statement breaks one iteration (in the loop) and continues with the next iteration in the loop."),
1290-
'/blocks/loops/continue',
1291-
pxt.toolbox.getNamespaceColor('loops')
1292-
);
1292+
this.jsonInit({
1293+
"message0": blockDef.block["message0"],
1294+
"inputsInline": true,
1295+
"previousStatement": null,
1296+
"nextStatement": null,
1297+
"colour": color
1298+
});
1299+
1300+
setHelpResources(this,
1301+
ts.pxtc.TS_BREAK_TYPE,
1302+
blockDef.name,
1303+
blockDef.tooltip,
1304+
blockDef.url,
1305+
color,
1306+
undefined/*colourSecondary*/,
1307+
undefined/*colourTertiary*/,
1308+
false/*undeletable*/
1309+
);
1310+
}
12931311
}
1294-
};
1312+
}
12951313
}
12961314

12971315
export let onShowContextMenu: (workspace: Blockly.Workspace,
@@ -2402,7 +2420,7 @@ namespace pxt.blocks {
24022420
// The logic for setting the output check relies on the internals of PXT
24032421
// too much to be refactored into pxt-blockly, so we need to monkey patch
24042422
// it here
2405-
Blockly.Blocks["argument_reporter_custom"].domToMutation = function(xmlElement: Element) {
2423+
Blockly.Blocks["argument_reporter_custom"].domToMutation = function (xmlElement: Element) {
24062424
const typeName = xmlElement.getAttribute('typename');
24072425
this.typeName_ = typeName;
24082426

pxtcompiler/emitter/decompiler.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2272,7 +2272,9 @@ ${output}</xml>`;
22722272
case SK.ModuleDeclaration:
22732273
return checkNamespaceDeclaration(node as ts.NamespaceDeclaration);
22742274
case SK.BreakStatement:
2275+
return pxt.appTarget.runtime && !!pxt.appTarget.runtime.breakBlock ? undefined : lf("Unsupported in blocks.");
22752276
case SK.ContinueStatement:
2277+
return pxt.appTarget.runtime && !!pxt.appTarget.runtime.continueBlock ? undefined : lf("Unsupported in blocks.");
22762278
case SK.DebuggerStatement:
22772279
case SK.EmptyStatement:
22782280
return undefined;

pxtlib/blocks.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,5 +703,23 @@ namespace pxt.blocks {
703703
message0: Util.lf("pause until %1")
704704
}
705705
};
706+
_blockDefinitions[pxtc.TS_BREAK_TYPE] = {
707+
name: Util.lf("break"),
708+
tooltip: Util.lf("Break out of the current loop or switch"),
709+
url: '/blocks/loops/break',
710+
category: 'loops',
711+
block: {
712+
message0: Util.lf("break")
713+
}
714+
}
715+
_blockDefinitions[pxtc.TS_CONTINUE_TYPE] = {
716+
name: Util.lf("continue"),
717+
tooltip: Util.lf("Skip current iteration and continues with the next iteration in the loop"),
718+
url: '/blocks/loops/continue',
719+
category: 'loops',
720+
block: {
721+
message0: Util.lf("continue")
722+
}
723+
}
706724
}
707725
}

tests/common/testUtils.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ export const testAppTarget: pxt.TargetBundle = {
3333
blocksprj: undefined,
3434
runtime: {
3535
pauseUntilBlock: { category: "Loops", color: "0x0000ff" },
36+
breakBlock: {},
37+
continueBlock: {},
3638
bannedCategories: ["banned"]
3739
},
3840
corepkg: undefined

0 commit comments

Comments
 (0)