pxt-core 7.5.2 → 7.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/built/cli.js +61 -46
- package/built/pxt.js +256 -91
- package/built/pxtblockly.js +652 -657
- package/built/pxtblocks.d.ts +1 -0
- package/built/pxtblocks.js +98 -42
- package/built/pxtcompiler.js +45 -4
- package/built/pxtlib.d.ts +7 -2
- package/built/pxtlib.js +77 -39
- package/built/pxtpy.js +73 -2
- package/built/server.js +4 -0
- package/built/target.js +1 -1
- package/built/web/authcode/css/main.1cf9dc37.css +2 -0
- package/built/web/authcode/js/main.03da4c20.js +2 -0
- package/built/web/main.js +1 -1
- package/built/web/pxtapp.js +1 -1
- package/built/web/pxtasseteditor.js +1 -1
- package/built/web/pxtblockly.js +2 -2
- package/built/web/pxtblocks.js +1 -1
- package/built/web/pxtcompiler.js +1 -1
- package/built/web/pxtembed.js +2 -2
- package/built/web/pxtlib.js +1 -1
- package/built/web/pxtpy.js +1 -1
- package/built/web/pxtworker.js +1 -1
- package/built/web/react-common-authcode.css +6200 -0
- package/built/web/react-common-skillmap.css +1 -1
- package/built/web/rtlreact-common-skillmap.css +1 -1
- package/built/web/rtlsemantic.css +1 -1
- package/built/web/semantic.css +1 -1
- package/built/web/skillmap/css/{main.e0620cee.chunk.css → main.73b22966.chunk.css} +1 -1
- package/built/web/skillmap/js/{2.f7cdfd75.chunk.js → 2.3e47a285.chunk.js} +2 -2
- package/built/web/skillmap/js/main.2485091f.chunk.js +1 -0
- package/common-docs/faq.md +1 -1
- package/common-docs/translate.md +2 -2
- package/docfiles/apptracking.html +1 -1
- package/docfiles/tracking.html +1 -1
- package/localtypings/projectheader.d.ts +6 -0
- package/package.json +5 -3
- package/pxtarget.json +1 -1
- package/react-common/components/controls/Button.tsx +4 -1
- package/react-common/components/controls/EditorToggle.tsx +153 -0
- package/react-common/components/controls/FocusList.tsx +120 -0
- package/react-common/components/controls/Input.tsx +4 -4
- package/react-common/components/controls/Link.tsx +36 -0
- package/react-common/components/controls/MenuBar.tsx +5 -95
- package/react-common/components/controls/MenuDropdown.tsx +4 -1
- package/react-common/components/controls/Textarea.tsx +103 -0
- package/react-common/components/share/GifInfo.tsx +63 -0
- package/react-common/components/share/GifRecorder.tsx +97 -0
- package/react-common/components/share/Share.tsx +49 -0
- package/react-common/components/share/ShareInfo.tsx +186 -0
- package/react-common/components/share/SocialButton.tsx +53 -0
- package/react-common/styles/controls/Button.less +4 -0
- package/react-common/styles/controls/EditorToggle.less +271 -0
- package/react-common/styles/controls/Modal.less +7 -5
- package/react-common/styles/controls/Textarea.less +81 -0
- package/react-common/styles/react-common-authcode-core.less +10 -0
- package/react-common/styles/react-common-authcode.less +12 -0
- package/react-common/styles/react-common-variables.less +19 -0
- package/react-common/styles/react-common.less +3 -0
- package/react-common/styles/share/share.less +116 -0
- package/theme/image-editor/imageEditor.less +8 -116
- package/webapp/public/authcode.html +1 -0
- package/webapp/public/blockly/blockly_compressed.js +554 -615
- package/webapp/public/index.html +1 -1
- package/webapp/public/run.html +32 -5
- package/webapp/public/skillmap.html +2 -2
- package/built/web/skillmap/js/main.f6866fc6.chunk.js +0 -1
package/built/pxtblocks.d.ts
CHANGED
|
@@ -39,6 +39,7 @@ declare namespace pxt.blocks {
|
|
|
39
39
|
alreadyDeclared?: BlockDeclarationType;
|
|
40
40
|
firstReference?: Blockly.Block;
|
|
41
41
|
isAssigned?: boolean;
|
|
42
|
+
isFunctionParameter?: boolean;
|
|
42
43
|
}
|
|
43
44
|
function compileExpression(e: Environment, b: Blockly.Block, comments: string[]): JsNode;
|
|
44
45
|
interface Environment {
|
package/built/pxtblocks.js
CHANGED
|
@@ -179,7 +179,7 @@ var pxt;
|
|
|
179
179
|
}
|
|
180
180
|
else if (b.type == "argument_reporter_array") {
|
|
181
181
|
if (!tp) {
|
|
182
|
-
tp =
|
|
182
|
+
tp = lookup(e, b, b.getFieldValue("VALUE")).type;
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
185
|
if (tp)
|
|
@@ -492,8 +492,14 @@ var pxt;
|
|
|
492
492
|
// Last pass: if some variable has no type (because it was never used or
|
|
493
493
|
// assigned to), just unify it with int...
|
|
494
494
|
e.allVariables.forEach((v) => {
|
|
495
|
-
if (getConcreteType(v.type).type == null)
|
|
496
|
-
|
|
495
|
+
if (getConcreteType(v.type).type == null) {
|
|
496
|
+
if (!v.isFunctionParameter) {
|
|
497
|
+
union(v.type, ground(v.type.isArrayType ? "number[]" : pNumber.type));
|
|
498
|
+
}
|
|
499
|
+
else if (v.type.isArrayType) {
|
|
500
|
+
v.type.type = "any[]";
|
|
501
|
+
}
|
|
502
|
+
}
|
|
497
503
|
});
|
|
498
504
|
function connectionCheck(i) {
|
|
499
505
|
return i.name ? i.connection && i.connection.check_ && i.connection.check_.length ? i.connection.check_[0] : "T" : undefined;
|
|
@@ -582,9 +588,31 @@ var pxt;
|
|
|
582
588
|
function compileNumber(e, b, comments) {
|
|
583
589
|
return blocks_1.H.mkNumberLiteral(extractNumber(b));
|
|
584
590
|
}
|
|
591
|
+
function isNumericLiteral(e, b) {
|
|
592
|
+
if (!b)
|
|
593
|
+
return false;
|
|
594
|
+
if (b.type === "math_number" || b.type === "math_integer" || b.type === "math_number_minmax" || b.type === "math_whole_number") {
|
|
595
|
+
return true;
|
|
596
|
+
}
|
|
597
|
+
const blockInfo = e.stdCallTable[b.type];
|
|
598
|
+
if (!blockInfo)
|
|
599
|
+
return false;
|
|
600
|
+
const { comp } = blockInfo;
|
|
601
|
+
if (blockInfo.attrs.shim === "TD_ID" && comp.parameters.length === 1) {
|
|
602
|
+
const fieldValue = b.getFieldValue(comp.parameters[0].definitionName);
|
|
603
|
+
if (fieldValue) {
|
|
604
|
+
return !isNaN(parseInt(fieldValue));
|
|
605
|
+
}
|
|
606
|
+
else {
|
|
607
|
+
return isNumericLiteral(e, getInputTargetBlock(b, comp.parameters[0].definitionName));
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
return false;
|
|
611
|
+
}
|
|
612
|
+
function isLiteral(e, b) {
|
|
613
|
+
return isNumericLiteral(e, b) || b.type === "logic_boolean" || b.type === "text";
|
|
614
|
+
}
|
|
585
615
|
let opToTok = {
|
|
586
|
-
// POWER gets a special treatment because there's no operator for it in
|
|
587
|
-
// TouchDevelop
|
|
588
616
|
"ADD": "+",
|
|
589
617
|
"MINUS": "-",
|
|
590
618
|
"MULTIPLY": "*",
|
|
@@ -599,11 +627,21 @@ var pxt;
|
|
|
599
627
|
"NEQ": "!=",
|
|
600
628
|
"POWER": "**"
|
|
601
629
|
};
|
|
630
|
+
function isComparisonOp(op) {
|
|
631
|
+
return ["LT", "LTE", "GT", "GTE", "EQ", "NEQ"].indexOf(op) !== -1;
|
|
632
|
+
}
|
|
602
633
|
function compileArithmetic(e, b, comments) {
|
|
603
634
|
let bOp = b.getFieldValue("OP");
|
|
604
635
|
let left = getInputTargetBlock(b, "A");
|
|
605
636
|
let right = getInputTargetBlock(b, "B");
|
|
606
637
|
let args = [compileExpression(e, left, comments), compileExpression(e, right, comments)];
|
|
638
|
+
// Special handling for the case of comparing two literals (e.g. 0 === 5). TypeScript
|
|
639
|
+
// throws an error if we don't first cast to any
|
|
640
|
+
if (isComparisonOp(bOp) && isLiteral(e, left) && isLiteral(e, right)) {
|
|
641
|
+
if (blocks_1.flattenNode([args[0]]).output !== blocks_1.flattenNode([args[1]]).output) {
|
|
642
|
+
args = args.map(arg => blocks_1.H.mkParenthesizedExpression(blocks_1.mkGroup([arg, blocks_1.mkText(" as any")])));
|
|
643
|
+
}
|
|
644
|
+
}
|
|
607
645
|
let t = returnType(e, left).type;
|
|
608
646
|
if (t == pString.type) {
|
|
609
647
|
if (bOp == "EQ")
|
|
@@ -711,7 +749,10 @@ var pxt;
|
|
|
711
749
|
const stmts = getInputTargetBlock(b, "STACK");
|
|
712
750
|
const argsDeclaration = b.getArguments().map(a => {
|
|
713
751
|
if (a.type == "Array") {
|
|
714
|
-
|
|
752
|
+
const binding = lookup(e, b, a.name);
|
|
753
|
+
const declaredType = getConcreteType(binding.type);
|
|
754
|
+
const paramType = ((declaredType === null || declaredType === void 0 ? void 0 : declaredType.type) && declaredType.type !== "Array") ? declaredType.type : "any[]";
|
|
755
|
+
return `${escapeVarName(a.name, e)}: ${paramType}`;
|
|
715
756
|
}
|
|
716
757
|
return `${escapeVarName(a.name, e)}: ${a.type}`;
|
|
717
758
|
});
|
|
@@ -1859,7 +1900,7 @@ var pxt;
|
|
|
1859
1900
|
return res;
|
|
1860
1901
|
}
|
|
1861
1902
|
function getEscapedCBParameters(b, stdfun, e) {
|
|
1862
|
-
return getCBParameters(b, stdfun).map(binding => lookup(e, b, binding
|
|
1903
|
+
return getCBParameters(b, stdfun).map(binding => lookup(e, b, binding.name).escapedName);
|
|
1863
1904
|
}
|
|
1864
1905
|
function getCBParameters(b, stdfun) {
|
|
1865
1906
|
let handlerArgs = [];
|
|
@@ -1875,7 +1916,10 @@ var pxt;
|
|
|
1875
1916
|
varName = varBlock && varBlock.getField("VAR").getText();
|
|
1876
1917
|
}
|
|
1877
1918
|
if (varName !== null) {
|
|
1878
|
-
handlerArgs.push(
|
|
1919
|
+
handlerArgs.push({
|
|
1920
|
+
name: varName,
|
|
1921
|
+
type: mkPoint(arg.type)
|
|
1922
|
+
});
|
|
1879
1923
|
}
|
|
1880
1924
|
else {
|
|
1881
1925
|
break;
|
|
@@ -1888,7 +1932,10 @@ var pxt;
|
|
|
1888
1932
|
const varField = b.getField("HANDLER_" + arg.name);
|
|
1889
1933
|
const varName = varField && varField.getText();
|
|
1890
1934
|
if (varName !== null) {
|
|
1891
|
-
handlerArgs.push(
|
|
1935
|
+
handlerArgs.push({
|
|
1936
|
+
name: varName,
|
|
1937
|
+
type: mkPoint(arg.type)
|
|
1938
|
+
});
|
|
1892
1939
|
}
|
|
1893
1940
|
else {
|
|
1894
1941
|
break;
|
|
@@ -2091,11 +2138,7 @@ var pxt;
|
|
|
2091
2138
|
}
|
|
2092
2139
|
if (hasStatementInput(block)) {
|
|
2093
2140
|
const vars = getDeclaredVariables(block, e).map(binding => {
|
|
2094
|
-
return {
|
|
2095
|
-
name: binding[0],
|
|
2096
|
-
type: binding[1],
|
|
2097
|
-
id: id++
|
|
2098
|
-
};
|
|
2141
|
+
return Object.assign(Object.assign({}, binding), { id: id++ });
|
|
2099
2142
|
});
|
|
2100
2143
|
let parentScope = currentScope;
|
|
2101
2144
|
if (vars.length) {
|
|
@@ -2179,17 +2222,37 @@ var pxt;
|
|
|
2179
2222
|
switch (block.type) {
|
|
2180
2223
|
case 'pxt_controls_for':
|
|
2181
2224
|
case 'controls_simple_for':
|
|
2182
|
-
return [
|
|
2225
|
+
return [{
|
|
2226
|
+
name: getLoopVariableField(block).getField("VAR").getText(),
|
|
2227
|
+
type: pNumber
|
|
2228
|
+
}];
|
|
2183
2229
|
case 'pxt_controls_for_of':
|
|
2184
2230
|
case 'controls_for_of':
|
|
2185
|
-
return [
|
|
2231
|
+
return [{
|
|
2232
|
+
name: getLoopVariableField(block).getField("VAR").getText(),
|
|
2233
|
+
type: mkPoint(null)
|
|
2234
|
+
}];
|
|
2235
|
+
case 'function_definition':
|
|
2236
|
+
return block.getArguments().filter(arg => arg.type === "Array")
|
|
2237
|
+
.map(arg => {
|
|
2238
|
+
const point = mkPoint(null);
|
|
2239
|
+
point.isArrayType = true;
|
|
2240
|
+
return {
|
|
2241
|
+
name: arg.name,
|
|
2242
|
+
type: point,
|
|
2243
|
+
isFunctionParameter: true
|
|
2244
|
+
};
|
|
2245
|
+
});
|
|
2186
2246
|
default:
|
|
2187
2247
|
break;
|
|
2188
2248
|
}
|
|
2189
2249
|
if (isMutatingBlock(block)) {
|
|
2190
2250
|
const declarations = block.mutation.getDeclaredVariables();
|
|
2191
2251
|
if (declarations) {
|
|
2192
|
-
return Object.keys(declarations).map(varName =>
|
|
2252
|
+
return Object.keys(declarations).map(varName => ({
|
|
2253
|
+
name: varName,
|
|
2254
|
+
type: mkPoint(declarations[varName])
|
|
2255
|
+
}));
|
|
2193
2256
|
}
|
|
2194
2257
|
}
|
|
2195
2258
|
let stdFunc = e.stdCallTable[block.type];
|
|
@@ -4078,21 +4141,9 @@ var pxt;
|
|
|
4078
4141
|
|| (nsinfo && nsinfo.attributes.color)
|
|
4079
4142
|
|| pxt.toolbox.getNamespaceColor(ns)
|
|
4080
4143
|
|| 255;
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
block.setHelpUrl(helpUrl);
|
|
4085
|
-
}
|
|
4086
|
-
else if (helpUrl !== "none") {
|
|
4087
|
-
block.setHelpUrl("/reference/" + helpUrl);
|
|
4088
|
-
}
|
|
4089
|
-
}
|
|
4090
|
-
else if (fn.pkg && !pxt.appTarget.bundledpkgs[fn.pkg]) { // added package
|
|
4091
|
-
let anchor = fn.qName.toLowerCase().split('.');
|
|
4092
|
-
if (anchor[0] == fn.pkg)
|
|
4093
|
-
anchor.shift();
|
|
4094
|
-
block.setHelpUrl(`/pkg/${fn.pkg}#${encodeURIComponent(anchor.join('-'))}`);
|
|
4095
|
-
}
|
|
4144
|
+
const helpUrl = pxt.blocks.getHelpUrl(fn);
|
|
4145
|
+
if (helpUrl)
|
|
4146
|
+
block.setHelpUrl(helpUrl);
|
|
4096
4147
|
block.setColour(color);
|
|
4097
4148
|
let blockShape = Blockly.OUTPUT_SHAPE_ROUND;
|
|
4098
4149
|
if (fn.retType == "boolean")
|
|
@@ -5428,10 +5479,13 @@ var pxt;
|
|
|
5428
5479
|
}
|
|
5429
5480
|
}
|
|
5430
5481
|
xmlList[xmlList.length - 1].setAttribute('gap', '24');
|
|
5431
|
-
if (Blockly.Blocks['variables_set']) {
|
|
5432
|
-
|
|
5482
|
+
if (Blockly.Blocks['variables_change'] || Blockly.Blocks['variables_set']) {
|
|
5483
|
+
xmlList.unshift(createFlyoutGroupLabel("Your Variables"));
|
|
5484
|
+
}
|
|
5485
|
+
if (Blockly.Blocks['variables_change']) {
|
|
5486
|
+
let gap = Blockly.Blocks['variables_get'] ? 20 : 8;
|
|
5433
5487
|
let blockText = '<xml>' +
|
|
5434
|
-
'<block type="
|
|
5488
|
+
'<block type="variables_change" gap="' + gap + '">' +
|
|
5435
5489
|
Blockly.Variables.generateVariableFieldXmlString(mostRecentVariable) +
|
|
5436
5490
|
'</block>' +
|
|
5437
5491
|
'</xml>';
|
|
@@ -5444,16 +5498,16 @@ var pxt;
|
|
|
5444
5498
|
value.appendChild(shadow);
|
|
5445
5499
|
let field = goog.dom.createDom('field');
|
|
5446
5500
|
field.setAttribute('name', 'NUM');
|
|
5447
|
-
field.appendChild(document.createTextNode("
|
|
5501
|
+
field.appendChild(document.createTextNode("1"));
|
|
5448
5502
|
shadow.appendChild(field);
|
|
5449
5503
|
block.appendChild(value);
|
|
5450
5504
|
}
|
|
5451
|
-
xmlList.
|
|
5505
|
+
xmlList.unshift(block);
|
|
5452
5506
|
}
|
|
5453
|
-
if (Blockly.Blocks['
|
|
5454
|
-
let gap = Blockly.Blocks['
|
|
5507
|
+
if (Blockly.Blocks['variables_set']) {
|
|
5508
|
+
let gap = Blockly.Blocks['variables_change'] ? 8 : 24;
|
|
5455
5509
|
let blockText = '<xml>' +
|
|
5456
|
-
'<block type="
|
|
5510
|
+
'<block type="variables_set" gap="' + gap + '">' +
|
|
5457
5511
|
Blockly.Variables.generateVariableFieldXmlString(mostRecentVariable) +
|
|
5458
5512
|
'</block>' +
|
|
5459
5513
|
'</xml>';
|
|
@@ -5466,11 +5520,11 @@ var pxt;
|
|
|
5466
5520
|
value.appendChild(shadow);
|
|
5467
5521
|
let field = goog.dom.createDom('field');
|
|
5468
5522
|
field.setAttribute('name', 'NUM');
|
|
5469
|
-
field.appendChild(document.createTextNode("
|
|
5523
|
+
field.appendChild(document.createTextNode("0"));
|
|
5470
5524
|
shadow.appendChild(field);
|
|
5471
5525
|
block.appendChild(value);
|
|
5472
5526
|
}
|
|
5473
|
-
xmlList.
|
|
5527
|
+
xmlList.unshift(block);
|
|
5474
5528
|
}
|
|
5475
5529
|
}
|
|
5476
5530
|
return xmlList;
|
|
@@ -5862,6 +5916,8 @@ var pxt;
|
|
|
5862
5916
|
const elems = oldFlyout(workspace);
|
|
5863
5917
|
if (elems.length > 1) {
|
|
5864
5918
|
let returnBlock = mkReturnStatementBlock();
|
|
5919
|
+
// Add divider
|
|
5920
|
+
elems.splice(1, 0, createFlyoutGroupLabel("Your Functions"));
|
|
5865
5921
|
// Insert after the "make a function" button
|
|
5866
5922
|
elems.splice(1, 0, returnBlock);
|
|
5867
5923
|
}
|
package/built/pxtcompiler.js
CHANGED
|
@@ -32,6 +32,9 @@ var pxt;
|
|
|
32
32
|
});
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
|
+
latestVersionAsync(repopath, config) {
|
|
36
|
+
return this.db.latestVersionAsync(repopath, config);
|
|
37
|
+
}
|
|
35
38
|
loadConfigAsync(repopath, tag) {
|
|
36
39
|
return this.loadAsync(repopath, tag, "pxt", (r, t) => this.db.loadConfigAsync(r, t));
|
|
37
40
|
}
|
|
@@ -4620,6 +4623,8 @@ ${output}</xml>`;
|
|
|
4620
4623
|
return getTaggedTemplateExpression(n);
|
|
4621
4624
|
case SK.CallExpression:
|
|
4622
4625
|
return getStatementBlock(n, undefined, undefined, true);
|
|
4626
|
+
case SK.AsExpression:
|
|
4627
|
+
return getOutputBlock(n.expression);
|
|
4623
4628
|
default:
|
|
4624
4629
|
error(n, pxtc.Util.lf("Unsupported syntax kind for output expression block: {0}", SK[n.kind]));
|
|
4625
4630
|
break;
|
|
@@ -5500,11 +5505,14 @@ ${output}</xml>`;
|
|
|
5500
5505
|
r.mutationChildren = [];
|
|
5501
5506
|
n.parameters.forEach(p => {
|
|
5502
5507
|
const paramName = p.name.getText();
|
|
5508
|
+
let type = normalizeType(p.type.getText());
|
|
5509
|
+
if (pxt.U.endsWith(type, "[]"))
|
|
5510
|
+
type = "Array";
|
|
5503
5511
|
r.mutationChildren.push({
|
|
5504
5512
|
nodeName: "arg",
|
|
5505
5513
|
attributes: {
|
|
5506
5514
|
name: paramName,
|
|
5507
|
-
type
|
|
5515
|
+
type,
|
|
5508
5516
|
id: env.functionParamIds[name][paramName]
|
|
5509
5517
|
}
|
|
5510
5518
|
});
|
|
@@ -5580,11 +5588,14 @@ ${output}</xml>`;
|
|
|
5580
5588
|
env.declaredFunctions[name].parameters.forEach((p, i) => {
|
|
5581
5589
|
const paramName = p.name.getText();
|
|
5582
5590
|
const argId = env.functionParamIds[name][paramName];
|
|
5591
|
+
let type = normalizeType(p.type.getText());
|
|
5592
|
+
if (pxt.U.endsWith(type, "[]"))
|
|
5593
|
+
type = "Array";
|
|
5583
5594
|
r.mutationChildren.push({
|
|
5584
5595
|
nodeName: "arg",
|
|
5585
5596
|
attributes: {
|
|
5586
5597
|
name: paramName,
|
|
5587
|
-
type:
|
|
5598
|
+
type: type,
|
|
5588
5599
|
id: argId
|
|
5589
5600
|
}
|
|
5590
5601
|
});
|
|
@@ -6452,7 +6463,8 @@ ${output}</xml>`;
|
|
|
6452
6463
|
if (!type) {
|
|
6453
6464
|
return pxtc.Util.lf("Function parameters must declare a type");
|
|
6454
6465
|
}
|
|
6455
|
-
|
|
6466
|
+
const normalized = normalizeType(type);
|
|
6467
|
+
if (env.opts.allowedArgumentTypes.indexOf(normalized) === -1 && !pxtc.U.endsWith(normalized, "[]")) {
|
|
6456
6468
|
return pxtc.Util.lf("Only types that can be added in blocks can be used for function arguments");
|
|
6457
6469
|
}
|
|
6458
6470
|
}
|
|
@@ -6727,6 +6739,8 @@ ${output}</xml>`;
|
|
|
6727
6739
|
return checkStatement(n, env, true, undefined);
|
|
6728
6740
|
case SK.TaggedTemplateExpression:
|
|
6729
6741
|
return checkTaggedTemplateExpression(n, env);
|
|
6742
|
+
case SK.AsExpression:
|
|
6743
|
+
return checkAsExpression(n);
|
|
6730
6744
|
}
|
|
6731
6745
|
return pxtc.Util.lf("Unsupported syntax kind for output expression block: {0}", SK[n.kind]);
|
|
6732
6746
|
function checkStringLiteral(n) {
|
|
@@ -6823,6 +6837,31 @@ ${output}</xml>`;
|
|
|
6823
6837
|
// The compiler will have already caught any invalid tags or templates
|
|
6824
6838
|
return undefined;
|
|
6825
6839
|
}
|
|
6840
|
+
function checkAsExpression(n) {
|
|
6841
|
+
// The only time we allow casts to decompile is in the very special case where someone has
|
|
6842
|
+
// written a program comparing two string, boolean, or numeric literals in blocks and
|
|
6843
|
+
// converted to text. e.g. 3 == 5 or true != false
|
|
6844
|
+
if (n.type.getText().trim() === "any" && (ts.isStringOrNumericLiteral(n.expression) ||
|
|
6845
|
+
n.expression.kind === SK.TrueKeyword || n.expression.kind === SK.FalseKeyword)) {
|
|
6846
|
+
const [parent] = getParent(n);
|
|
6847
|
+
if (parent.kind === SK.BinaryExpression) {
|
|
6848
|
+
switch (parent.operatorToken.kind) {
|
|
6849
|
+
case SK.EqualsEqualsToken:
|
|
6850
|
+
case SK.EqualsEqualsEqualsToken:
|
|
6851
|
+
case SK.ExclamationEqualsToken:
|
|
6852
|
+
case SK.ExclamationEqualsEqualsToken:
|
|
6853
|
+
case SK.LessThanToken:
|
|
6854
|
+
case SK.LessThanEqualsToken:
|
|
6855
|
+
case SK.GreaterThanToken:
|
|
6856
|
+
case SK.GreaterThanEqualsToken:
|
|
6857
|
+
return undefined;
|
|
6858
|
+
default:
|
|
6859
|
+
break;
|
|
6860
|
+
}
|
|
6861
|
+
}
|
|
6862
|
+
}
|
|
6863
|
+
return pxtc.Util.lf("Casting not supported in blocks");
|
|
6864
|
+
}
|
|
6826
6865
|
function getParent(node) {
|
|
6827
6866
|
if (!node.parent) {
|
|
6828
6867
|
return [undefined, node];
|
|
@@ -12615,8 +12654,10 @@ ${lbl}: .short 0xffff
|
|
|
12615
12654
|
return needsNumberConversions() ? pxtc.ir.rtcall("pxt::toInt", [e]) : e;
|
|
12616
12655
|
};
|
|
12617
12656
|
// c = a[i]
|
|
12618
|
-
if (iterVar)
|
|
12657
|
+
if (iterVar) {
|
|
12619
12658
|
proc.emitExpr(iterVar.storeByRef(pxtc.ir.rtcall(indexer, [collectionVar.loadCore(), toInt(intVarIter.loadCore())])));
|
|
12659
|
+
emitBrk(node.initializer);
|
|
12660
|
+
}
|
|
12620
12661
|
flushHoistedFunctionDefinitions();
|
|
12621
12662
|
emit(node.statement);
|
|
12622
12663
|
proc.emitLblDirect(l.cont);
|
package/built/pxtlib.d.ts
CHANGED
|
@@ -552,6 +552,7 @@ declare namespace pxt {
|
|
|
552
552
|
multiUrl?: string;
|
|
553
553
|
asseteditorUrl?: string;
|
|
554
554
|
skillmapUrl?: string;
|
|
555
|
+
authcodeUrl?: string;
|
|
555
556
|
isStatic?: boolean;
|
|
556
557
|
verprefix?: string;
|
|
557
558
|
}
|
|
@@ -656,6 +657,7 @@ declare namespace pxt.blocks {
|
|
|
656
657
|
function normalizeBlock(b: string, err?: (msg: string) => void): string;
|
|
657
658
|
function compileInfo(fn: pxtc.SymbolInfo): BlockCompileInfo;
|
|
658
659
|
function hasHandler(fn: pxtc.SymbolInfo): boolean;
|
|
660
|
+
function getHelpUrl(fn: pxtc.SymbolInfo): string;
|
|
659
661
|
/**
|
|
660
662
|
* Returns which Blockly block type to use for an argument reporter based
|
|
661
663
|
* on the specified TypeScript type.
|
|
@@ -1215,16 +1217,19 @@ declare namespace pxt.github {
|
|
|
1215
1217
|
files: Map<string>;
|
|
1216
1218
|
}
|
|
1217
1219
|
interface IGithubDb {
|
|
1220
|
+
latestVersionAsync(repopath: string, config: PackagesConfig): Promise<string>;
|
|
1218
1221
|
loadConfigAsync(repopath: string, tag: string): Promise<pxt.PackageConfig>;
|
|
1219
1222
|
loadPackageAsync(repopath: string, tag: string): Promise<CachedPackage>;
|
|
1220
1223
|
}
|
|
1221
1224
|
function isOrgAsync(owner: string): Promise<boolean>;
|
|
1222
1225
|
class MemoryGithubDb implements IGithubDb {
|
|
1226
|
+
private latestVersions;
|
|
1223
1227
|
private configs;
|
|
1224
1228
|
private packages;
|
|
1225
1229
|
private proxyWithCdnLoadPackageAsync;
|
|
1226
1230
|
private cacheConfig;
|
|
1227
1231
|
loadConfigAsync(repopath: string, tag: string): Promise<pxt.PackageConfig>;
|
|
1232
|
+
latestVersionAsync(repopath: string, config: PackagesConfig): Promise<string>;
|
|
1228
1233
|
loadPackageAsync(repopath: string, tag: string): Promise<CachedPackage>;
|
|
1229
1234
|
private githubLoadPackageAsync;
|
|
1230
1235
|
}
|
|
@@ -1260,7 +1265,7 @@ declare namespace pxt.github {
|
|
|
1260
1265
|
function forkRepoAsync(repopath: string, commitid: string, pref?: string): Promise<string>;
|
|
1261
1266
|
function listRefsAsync(repopath: string, namespace?: string, useProxy?: boolean, noCache?: boolean): Promise<string[]>;
|
|
1262
1267
|
function listRefsExtAsync(repopath: string, namespace?: string, useProxy?: boolean, noCache?: boolean): Promise<RefsResult>;
|
|
1263
|
-
function pkgConfigAsync(repopath: string, tag
|
|
1268
|
+
function pkgConfigAsync(repopath: string, tag: string, config: pxt.PackagesConfig): Promise<PackageConfig>;
|
|
1264
1269
|
function downloadPackageAsync(repoWithTag: string, config: pxt.PackagesConfig): Promise<CachedPackage>;
|
|
1265
1270
|
function downloadLatestPackageAsync(repo: ParsedRepo): Promise<{
|
|
1266
1271
|
version: string;
|
|
@@ -1311,7 +1316,7 @@ declare namespace pxt.github {
|
|
|
1311
1316
|
function toGithubDependencyPath(path: string, tag?: string): string;
|
|
1312
1317
|
function isGithubId(id: string): boolean;
|
|
1313
1318
|
function stringifyRepo(p: ParsedRepo): string;
|
|
1314
|
-
function normalizeRepoId(id: string): string;
|
|
1319
|
+
function normalizeRepoId(id: string, defaultTag?: string): string;
|
|
1315
1320
|
function join(...parts: string[]): string;
|
|
1316
1321
|
function upgradedPackageReference(cfg: PackagesConfig, id: string): string;
|
|
1317
1322
|
function upgradedPackageId(cfg: PackagesConfig, id: string): string;
|
package/built/pxtlib.js
CHANGED
|
@@ -3909,6 +3909,25 @@ var pxt;
|
|
|
3909
3909
|
});
|
|
3910
3910
|
}
|
|
3911
3911
|
blocks.hasHandler = hasHandler;
|
|
3912
|
+
function getHelpUrl(fn) {
|
|
3913
|
+
if (fn.attributes.help) {
|
|
3914
|
+
const helpUrl = fn.attributes.help.replace(/^\//, '');
|
|
3915
|
+
if (/^github:/.test(helpUrl)) {
|
|
3916
|
+
return helpUrl;
|
|
3917
|
+
}
|
|
3918
|
+
else if (helpUrl !== "none") {
|
|
3919
|
+
return "/reference/" + helpUrl;
|
|
3920
|
+
}
|
|
3921
|
+
}
|
|
3922
|
+
else if (fn.pkg && !pxt.appTarget.bundledpkgs[fn.pkg]) { // added package
|
|
3923
|
+
let anchor = fn.qName.toLowerCase().split('.');
|
|
3924
|
+
if (anchor[0] == fn.pkg)
|
|
3925
|
+
anchor.shift();
|
|
3926
|
+
return `/pkg/${fn.pkg}#${encodeURIComponent(anchor.join('-'))}`;
|
|
3927
|
+
}
|
|
3928
|
+
return undefined;
|
|
3929
|
+
}
|
|
3930
|
+
blocks.getHelpUrl = getHelpUrl;
|
|
3912
3931
|
/**
|
|
3913
3932
|
* Returns which Blockly block type to use for an argument reporter based
|
|
3914
3933
|
* on the specified TypeScript type.
|
|
@@ -3920,6 +3939,9 @@ var pxt;
|
|
|
3920
3939
|
if (varType === "boolean" || varType === "number" || varType === "string") {
|
|
3921
3940
|
reporterType = `argument_reporter_${varType}`;
|
|
3922
3941
|
}
|
|
3942
|
+
if (/^(?:Array<(?:.+)>)|(?:(?:.+)\[\])$/.test(varType)) {
|
|
3943
|
+
reporterType = "argument_reporter_array";
|
|
3944
|
+
}
|
|
3923
3945
|
return reporterType;
|
|
3924
3946
|
}
|
|
3925
3947
|
blocks.reporterTypeForArgType = reporterTypeForArgType;
|
|
@@ -9827,6 +9849,7 @@ var pxt;
|
|
|
9827
9849
|
github.isOrgAsync = isOrgAsync;
|
|
9828
9850
|
class MemoryGithubDb {
|
|
9829
9851
|
constructor() {
|
|
9852
|
+
this.latestVersions = {};
|
|
9830
9853
|
this.configs = {};
|
|
9831
9854
|
this.packages = {};
|
|
9832
9855
|
}
|
|
@@ -9849,8 +9872,10 @@ var pxt;
|
|
|
9849
9872
|
return pxt.U.clone(cfg);
|
|
9850
9873
|
}
|
|
9851
9874
|
async loadConfigAsync(repopath, tag) {
|
|
9852
|
-
if (!tag)
|
|
9875
|
+
if (!tag) {
|
|
9876
|
+
pxt.debug(`dep: default to master branch`);
|
|
9853
9877
|
tag = "master";
|
|
9878
|
+
}
|
|
9854
9879
|
// cache lookup
|
|
9855
9880
|
const key = `${repopath}/${tag}`;
|
|
9856
9881
|
let res = this.configs[key];
|
|
@@ -9873,9 +9898,19 @@ var pxt;
|
|
|
9873
9898
|
const cfg = await downloadTextAsync(repopath, tag, pxt.CONFIG_NAME);
|
|
9874
9899
|
return this.cacheConfig(key, cfg);
|
|
9875
9900
|
}
|
|
9901
|
+
async latestVersionAsync(repopath, config) {
|
|
9902
|
+
let resolved = this.latestVersions[repopath];
|
|
9903
|
+
if (!resolved) {
|
|
9904
|
+
pxt.debug(`dep: resolve latest version of ${repopath}`);
|
|
9905
|
+
this.latestVersions[repopath] = resolved = await pxt.github.latestVersionAsync(repopath, config, true, false);
|
|
9906
|
+
}
|
|
9907
|
+
return resolved;
|
|
9908
|
+
}
|
|
9876
9909
|
async loadPackageAsync(repopath, tag) {
|
|
9877
|
-
if (!tag)
|
|
9910
|
+
if (!tag) {
|
|
9911
|
+
pxt.debug(`load pkg: default to master branch`);
|
|
9878
9912
|
tag = "master";
|
|
9913
|
+
}
|
|
9879
9914
|
// try using github proxy first
|
|
9880
9915
|
if (hasProxy()) {
|
|
9881
9916
|
try {
|
|
@@ -10191,34 +10226,38 @@ var pxt;
|
|
|
10191
10226
|
.then(resolveRefAsync, e => ghGetJsonAsync(`https://api.github.com/repos/${parsed.slug}/git/refs/heads/${tag}`)
|
|
10192
10227
|
.then(resolveRefAsync));
|
|
10193
10228
|
}
|
|
10194
|
-
function pkgConfigAsync(repopath, tag
|
|
10195
|
-
|
|
10229
|
+
async function pkgConfigAsync(repopath, tag, config) {
|
|
10230
|
+
if (!tag)
|
|
10231
|
+
tag = await github.db.latestVersionAsync(repopath, config);
|
|
10232
|
+
return await github.db.loadConfigAsync(repopath, tag);
|
|
10196
10233
|
}
|
|
10197
10234
|
github.pkgConfigAsync = pkgConfigAsync;
|
|
10198
|
-
function downloadPackageAsync(repoWithTag, config) {
|
|
10235
|
+
async function downloadPackageAsync(repoWithTag, config) {
|
|
10199
10236
|
const p = parseRepoId(repoWithTag);
|
|
10200
10237
|
if (!p) {
|
|
10201
10238
|
pxt.log('Unknown GitHub syntax');
|
|
10202
|
-
return
|
|
10239
|
+
return undefined;
|
|
10203
10240
|
}
|
|
10204
10241
|
if (isRepoBanned(p, config)) {
|
|
10205
10242
|
pxt.tickEvent("github.download.banned");
|
|
10206
10243
|
pxt.log('Github repo is banned');
|
|
10207
|
-
return
|
|
10244
|
+
return undefined;
|
|
10208
10245
|
}
|
|
10209
|
-
|
|
10210
|
-
|
|
10211
|
-
|
|
10212
|
-
|
|
10213
|
-
|
|
10214
|
-
|
|
10215
|
-
|
|
10216
|
-
|
|
10217
|
-
|
|
10218
|
-
}
|
|
10246
|
+
// always try to upgrade unbound versions
|
|
10247
|
+
if (!p.tag) {
|
|
10248
|
+
p.tag = await github.db.latestVersionAsync(p.slug, config);
|
|
10249
|
+
}
|
|
10250
|
+
const cached = await github.db.loadPackageAsync(p.fullName, p.tag);
|
|
10251
|
+
const dv = upgradedDisablesVariants(config, repoWithTag);
|
|
10252
|
+
if (dv) {
|
|
10253
|
+
const cfg = pxt.Package.parseAndValidConfig(cached.files[pxt.CONFIG_NAME]);
|
|
10254
|
+
if (cfg) {
|
|
10255
|
+
pxt.log(`auto-disable ${dv.join(",")} due to targetconfig entry for ${repoWithTag}`);
|
|
10256
|
+
cfg.disablesVariants = dv;
|
|
10257
|
+
cached.files[pxt.CONFIG_NAME] = pxt.Package.stringifyConfig(cfg);
|
|
10219
10258
|
}
|
|
10220
|
-
|
|
10221
|
-
|
|
10259
|
+
}
|
|
10260
|
+
return cached;
|
|
10222
10261
|
}
|
|
10223
10262
|
github.downloadPackageAsync = downloadPackageAsync;
|
|
10224
10263
|
async function downloadLatestPackageAsync(repo) {
|
|
@@ -10228,7 +10267,7 @@ var pxt;
|
|
|
10228
10267
|
const repoWithTag = `${repo.fullName}#${tag}`;
|
|
10229
10268
|
await pxt.github.downloadPackageAsync(repoWithTag, packageConfig);
|
|
10230
10269
|
// return config
|
|
10231
|
-
const config = await pkgConfigAsync(repo.fullName, tag);
|
|
10270
|
+
const config = await pkgConfigAsync(repo.fullName, tag, packageConfig);
|
|
10232
10271
|
const version = `github:${repoWithTag}`;
|
|
10233
10272
|
return { version, config };
|
|
10234
10273
|
}
|
|
@@ -10558,14 +10597,15 @@ var pxt;
|
|
|
10558
10597
|
}
|
|
10559
10598
|
github.isGithubId = isGithubId;
|
|
10560
10599
|
function stringifyRepo(p) {
|
|
10561
|
-
return p ? "github:" + p.fullName.toLowerCase() +
|
|
10600
|
+
return p ? "github:" + p.fullName.toLowerCase() + (p.tag ? `#${p.tag}` : '') : undefined;
|
|
10562
10601
|
}
|
|
10563
10602
|
github.stringifyRepo = stringifyRepo;
|
|
10564
|
-
function normalizeRepoId(id) {
|
|
10603
|
+
function normalizeRepoId(id, defaultTag) {
|
|
10565
10604
|
const gid = parseRepoId(id);
|
|
10566
10605
|
if (!gid)
|
|
10567
10606
|
return undefined;
|
|
10568
|
-
|
|
10607
|
+
if (!gid.tag && defaultTag)
|
|
10608
|
+
gid.tag = defaultTag;
|
|
10569
10609
|
return stringifyRepo(gid);
|
|
10570
10610
|
}
|
|
10571
10611
|
github.normalizeRepoId = normalizeRepoId;
|
|
@@ -13707,22 +13747,20 @@ var pxt;
|
|
|
13707
13747
|
&& json.dependencies && Object.keys(json.dependencies).every(k => typeof json.dependencies[k] === "string")
|
|
13708
13748
|
&& json;
|
|
13709
13749
|
}
|
|
13710
|
-
static getConfigAsync(pkgTargetVersion, id, fullVers) {
|
|
13711
|
-
|
|
13712
|
-
|
|
13713
|
-
|
|
13714
|
-
|
|
13715
|
-
|
|
13716
|
-
|
|
13717
|
-
|
|
13718
|
-
|
|
13719
|
-
|
|
13720
|
-
|
|
13721
|
-
|
|
13722
|
-
|
|
13723
|
-
|
|
13724
|
-
}
|
|
13725
|
-
});
|
|
13750
|
+
static async getConfigAsync(pkgTargetVersion, id, fullVers) {
|
|
13751
|
+
if (pxt.github.isGithubId(fullVers)) {
|
|
13752
|
+
const repoInfo = pxt.github.parseRepoId(fullVers);
|
|
13753
|
+
const packagesConfig = await pxt.packagesConfigAsync();
|
|
13754
|
+
const gitRepo = await pxt.github.repoAsync(repoInfo.fullName, packagesConfig); // Make sure repo exists and is whitelisted
|
|
13755
|
+
return gitRepo ? await pxt.github.pkgConfigAsync(repoInfo.fullName, repoInfo.tag, packagesConfig) : null;
|
|
13756
|
+
}
|
|
13757
|
+
else {
|
|
13758
|
+
// If it's not from GH, assume it's a bundled package
|
|
13759
|
+
// TODO: Add logic for shared packages if we enable that
|
|
13760
|
+
const updatedRef = pxt.patching.upgradePackageReference(pkgTargetVersion, id, fullVers);
|
|
13761
|
+
const bundledPkg = pxt.appTarget.bundledpkgs[updatedRef];
|
|
13762
|
+
return JSON.parse(bundledPkg[pxt.CONFIG_NAME]);
|
|
13763
|
+
}
|
|
13726
13764
|
}
|
|
13727
13765
|
static corePackages() {
|
|
13728
13766
|
const pkgs = pxt.appTarget.bundledpkgs;
|