pxt-core 7.5.43 → 7.5.46
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/pxt.js +204 -34
- package/built/pxtblockly.js +15 -1
- package/built/pxtblocks.js +15 -1
- package/built/pxtpy.d.ts +2 -1
- package/built/pxtpy.js +204 -34
- package/built/pxtrunner.d.ts +2 -1
- package/built/pxtrunner.js +34 -7
- package/built/target.js +1 -1
- package/built/web/blockly.css +1 -1
- package/built/web/main.js +1 -1
- package/built/web/pxtblockly.js +1 -1
- package/built/web/pxtblocks.js +1 -1
- package/built/web/pxtembed.js +2 -2
- package/built/web/pxtpy.js +1 -1
- package/built/web/pxtrunner.js +1 -1
- package/built/web/pxtworker.js +1 -1
- package/built/web/rtlblockly.css +1 -1
- package/package.json +1 -1
- package/theme/blockly-core.less +4 -0
- package/webapp/public/run.html +4 -0
package/built/pxtpy.js
CHANGED
|
@@ -241,11 +241,19 @@ var pxt;
|
|
|
241
241
|
return pxt.U.lookup(internalApis, name) || pxt.U.lookup(externalApis, name);
|
|
242
242
|
}
|
|
243
243
|
function lookupGlobalSymbol(name) {
|
|
244
|
+
var _a;
|
|
244
245
|
if (!name)
|
|
245
246
|
return undefined;
|
|
246
247
|
let sym = lookupApi(name);
|
|
247
248
|
if (sym)
|
|
248
249
|
getOrSetSymbolType(sym);
|
|
250
|
+
else if (name.indexOf(".") && !name.endsWith(".__constructor")) {
|
|
251
|
+
const base = name.substring(0, name.lastIndexOf("."));
|
|
252
|
+
const baseSymbol = lookupGlobalSymbol(base);
|
|
253
|
+
if ((baseSymbol === null || baseSymbol === void 0 ? void 0 : baseSymbol.kind) === 8 /* Class */ && ((_a = baseSymbol.extendsTypes) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
254
|
+
return lookupGlobalSymbol(baseSymbol.extendsTypes[0] + name.substring(base.length));
|
|
255
|
+
}
|
|
256
|
+
}
|
|
249
257
|
return sym;
|
|
250
258
|
}
|
|
251
259
|
function initApis(apisInfo, tsShadowFiles) {
|
|
@@ -328,7 +336,10 @@ var pxt;
|
|
|
328
336
|
pref += ".";
|
|
329
337
|
}
|
|
330
338
|
let qualifiedName = pref + name;
|
|
331
|
-
if (
|
|
339
|
+
if (scope.kind === "ClassDef") {
|
|
340
|
+
varSym = addSymbol(2 /* Property */, qualifiedName);
|
|
341
|
+
}
|
|
342
|
+
else if (isLocalScope(scope)
|
|
332
343
|
&& (modifier === py_1.VarModifier.Global
|
|
333
344
|
|| modifier === py_1.VarModifier.NonLocal)) {
|
|
334
345
|
varSym = addSymbol(4 /* Variable */, name);
|
|
@@ -442,7 +453,7 @@ var pxt;
|
|
|
442
453
|
};
|
|
443
454
|
}
|
|
444
455
|
}
|
|
445
|
-
// next free error
|
|
456
|
+
// next free error 9576
|
|
446
457
|
function error(astNode, code, msg) {
|
|
447
458
|
diagnostics.push(mkDiag(astNode, pxtc.DiagnosticCategory.Error, code, msg));
|
|
448
459
|
//const pos = position(astNode ? astNode.startPos || 0 : 0, mod.source)
|
|
@@ -657,8 +668,19 @@ var pxt;
|
|
|
657
668
|
let qn = cd.symInfo.qName;
|
|
658
669
|
return pxt.U.values(internalApis).filter(e => e.namespace == qn && e.kind == 2 /* Property */);
|
|
659
670
|
}
|
|
660
|
-
function getClassField(ct, n, checkOnly = false, skipBases = false) {
|
|
661
|
-
let qid
|
|
671
|
+
function getClassField(ct, n, isStatic, checkOnly = false, skipBases = false) {
|
|
672
|
+
let qid;
|
|
673
|
+
if (n === "__init__") {
|
|
674
|
+
qid = ct.pyQName + ".__constructor";
|
|
675
|
+
}
|
|
676
|
+
else {
|
|
677
|
+
if (n.startsWith(ct.pyQName + ".")) {
|
|
678
|
+
qid = n;
|
|
679
|
+
}
|
|
680
|
+
else {
|
|
681
|
+
qid = ct.pyQName + "." + n;
|
|
682
|
+
}
|
|
683
|
+
}
|
|
662
684
|
let f = lookupGlobalSymbol(qid);
|
|
663
685
|
if (f)
|
|
664
686
|
return f;
|
|
@@ -668,7 +690,7 @@ var pxt;
|
|
|
668
690
|
if (sym) {
|
|
669
691
|
if (sym == ct)
|
|
670
692
|
pxt.U.userError("field lookup loop on: " + sym.qName + " / " + n);
|
|
671
|
-
let classF = getClassField(sym, n, true);
|
|
693
|
+
let classF = getClassField(sym, n, isStatic, true);
|
|
672
694
|
if (classF)
|
|
673
695
|
return classF;
|
|
674
696
|
}
|
|
@@ -676,7 +698,7 @@ var pxt;
|
|
|
676
698
|
}
|
|
677
699
|
if (!checkOnly && ct.pyAST && ct.pyAST.kind == "ClassDef") {
|
|
678
700
|
let sym = addSymbol(2 /* Property */, qid);
|
|
679
|
-
sym.isInstance =
|
|
701
|
+
sym.isInstance = !isStatic;
|
|
680
702
|
return sym;
|
|
681
703
|
}
|
|
682
704
|
return null;
|
|
@@ -693,16 +715,14 @@ var pxt;
|
|
|
693
715
|
const recvType = typeOf(recv);
|
|
694
716
|
const constructorTypes = getTypesForFieldLookup(recvType);
|
|
695
717
|
for (let ct of constructorTypes) {
|
|
696
|
-
let
|
|
718
|
+
let isModule = !!recvType.moduleType;
|
|
719
|
+
let f = getClassField(ct, n, isModule, checkOnly);
|
|
697
720
|
if (f) {
|
|
698
|
-
let isModule = !!recvType.moduleType;
|
|
699
721
|
if (isModule) {
|
|
700
722
|
if (f.isInstance)
|
|
701
723
|
error(null, 9505, pxt.U.lf("the field '{0}' of '{1}' is not static", n, ct.pyQName));
|
|
702
724
|
}
|
|
703
725
|
else {
|
|
704
|
-
if (!f.isInstance)
|
|
705
|
-
error(null, 9504, pxt.U.lf("the field '{0}' of '{1}' is static", n, ct.pyQName));
|
|
706
726
|
if (isSuper(recv))
|
|
707
727
|
f.isProtected = true;
|
|
708
728
|
else if (isThis(recv)) {
|
|
@@ -885,14 +905,17 @@ var pxt;
|
|
|
885
905
|
return mkType({});
|
|
886
906
|
}
|
|
887
907
|
function doArgs(n, isMethod) {
|
|
908
|
+
var _a;
|
|
888
909
|
const args = n.args;
|
|
889
910
|
if (args.kwonlyargs.length)
|
|
890
911
|
error(n, 9517, pxt.U.lf("keyword-only arguments not supported yet"));
|
|
891
912
|
let nargs = args.args.slice();
|
|
892
913
|
if (isMethod) {
|
|
893
|
-
if (nargs[0].arg
|
|
894
|
-
|
|
895
|
-
|
|
914
|
+
if (((_a = nargs[0]) === null || _a === void 0 ? void 0 : _a.arg) !== "self")
|
|
915
|
+
n.symInfo.isStatic = true;
|
|
916
|
+
else {
|
|
917
|
+
nargs.shift();
|
|
918
|
+
}
|
|
896
919
|
}
|
|
897
920
|
else {
|
|
898
921
|
if (nargs.some(a => a.arg == "self"))
|
|
@@ -1054,6 +1077,7 @@ var pxt;
|
|
|
1054
1077
|
}
|
|
1055
1078
|
function emitFunctionDef(n, inline = false) {
|
|
1056
1079
|
return guardedScope(n, () => {
|
|
1080
|
+
var _a, _b, _c, _d;
|
|
1057
1081
|
const isMethod = !!ctx.currClass && !ctx.currFun;
|
|
1058
1082
|
const topLev = isTopLevel();
|
|
1059
1083
|
const nested = !!ctx.currFun;
|
|
@@ -1106,7 +1130,7 @@ var pxt;
|
|
|
1106
1130
|
let scopeValueVar = n.vars["value"];
|
|
1107
1131
|
let valueVar = scopeValueVar === null || scopeValueVar === void 0 ? void 0 : scopeValueVar.symbol;
|
|
1108
1132
|
if (funname == "__set__" && valueVar) {
|
|
1109
|
-
let cf = getClassField(ctx.currClass.symInfo, "__get__");
|
|
1133
|
+
let cf = getClassField(ctx.currClass.symInfo, "__get__", false);
|
|
1110
1134
|
if (cf && cf.pyAST && cf.pyAST.kind == "FunctionDef")
|
|
1111
1135
|
unify(n, valueVar.pyRetType, cf.pyRetType);
|
|
1112
1136
|
}
|
|
@@ -1114,6 +1138,9 @@ var pxt;
|
|
|
1114
1138
|
}
|
|
1115
1139
|
if (!prefix) {
|
|
1116
1140
|
prefix = funname[0] == "_" ? (sym.isProtected ? "protected" : "private") : "public";
|
|
1141
|
+
if (n.symInfo.isStatic) {
|
|
1142
|
+
prefix += " static";
|
|
1143
|
+
}
|
|
1117
1144
|
}
|
|
1118
1145
|
nodes.push(B.mkText(prefix + " "), quote(funname));
|
|
1119
1146
|
}
|
|
@@ -1125,7 +1152,7 @@ var pxt;
|
|
|
1125
1152
|
else
|
|
1126
1153
|
nodes.push(B.mkText("export function "), quote(funname));
|
|
1127
1154
|
}
|
|
1128
|
-
let retType = n.returns ? compileType(n.returns) : sym.pyRetType;
|
|
1155
|
+
let retType = n.name == "__init__" ? undefined : (n.returns ? compileType(n.returns) : sym.pyRetType);
|
|
1129
1156
|
nodes.push(doArgs(n, isMethod), retType && canonicalize(retType) != tpVoid ? typeAnnot(retType) : B.mkText(""));
|
|
1130
1157
|
// make sure type is initialized
|
|
1131
1158
|
getOrSetSymbolType(sym);
|
|
@@ -1133,6 +1160,13 @@ var pxt;
|
|
|
1133
1160
|
if (n.name == "__init__") {
|
|
1134
1161
|
if (!ctx.currClass)
|
|
1135
1162
|
error(n, 9533, lf("__init__ method '{0}' is missing current class context", sym.pyQName));
|
|
1163
|
+
if ((_a = ctx.currClass) === null || _a === void 0 ? void 0 : _a.baseClass) {
|
|
1164
|
+
const firstStatement = n.body[0];
|
|
1165
|
+
const superConstructor = ctx.currClass.baseClass.pyQName + ".__constructor";
|
|
1166
|
+
if (((_d = (_c = (_b = firstStatement.value) === null || _b === void 0 ? void 0 : _b.func) === null || _c === void 0 ? void 0 : _c.symbolInfo) === null || _d === void 0 ? void 0 : _d.pyQName) !== superConstructor) {
|
|
1167
|
+
error(n, 9575, lf("Sub classes must call 'super().__init__' as the first statement inside an __init__ method"));
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1136
1170
|
for (let f of listClassFields(ctx.currClass)) {
|
|
1137
1171
|
let p = f.pyAST;
|
|
1138
1172
|
if (p && p.value) {
|
|
@@ -1176,22 +1210,61 @@ var pxt;
|
|
|
1176
1210
|
nodes.push(B.mkCommaSep(n.bases.map(expr)));
|
|
1177
1211
|
let b = getClassDef(n.bases[0]);
|
|
1178
1212
|
if (b) {
|
|
1179
|
-
n.baseClass = b;
|
|
1213
|
+
n.baseClass = b.symInfo;
|
|
1180
1214
|
sym.extendsTypes = [b.symInfo.pyQName];
|
|
1181
1215
|
}
|
|
1216
|
+
else {
|
|
1217
|
+
const nm = tryGetName(n.bases[0]);
|
|
1218
|
+
if (nm) {
|
|
1219
|
+
const localSym = lookupSymbol(nm);
|
|
1220
|
+
const globalSym = lookupGlobalSymbol(nm);
|
|
1221
|
+
n.baseClass = localSym || globalSym;
|
|
1222
|
+
if (n.baseClass)
|
|
1223
|
+
sym.extendsTypes = [n.baseClass.pyQName];
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1182
1226
|
}
|
|
1183
1227
|
}
|
|
1184
|
-
|
|
1228
|
+
const classDefs = n.body.filter(s => n.isNamespace || s.kind === "FunctionDef");
|
|
1229
|
+
const staticStmts = n.isNamespace ? [] : n.body.filter(s => classDefs.indexOf(s) === -1 && s.kind !== "Pass");
|
|
1230
|
+
let body = stmts(classDefs);
|
|
1185
1231
|
nodes.push(body);
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1232
|
+
// Python classes allow arbitrary statements in their bodies, sort of like namespaces.
|
|
1233
|
+
// Take all of these statements and put them in a static method that we can call when
|
|
1234
|
+
// the class is defined.
|
|
1235
|
+
let generatedInitFunction = false;
|
|
1236
|
+
if (staticStmts.length) {
|
|
1237
|
+
generatedInitFunction = true;
|
|
1238
|
+
const staticBody = stmts(staticStmts);
|
|
1239
|
+
const initFun = B.mkStmt(B.mkGroup([
|
|
1240
|
+
B.mkText(`public static __init${n.name}() `),
|
|
1241
|
+
staticBody
|
|
1242
|
+
]));
|
|
1243
|
+
body.children.unshift(initFun);
|
|
1244
|
+
}
|
|
1245
|
+
if (!n.isNamespace) {
|
|
1246
|
+
const fieldDefs = listClassFields(n)
|
|
1247
|
+
.map(f => {
|
|
1248
|
+
if (!f.pyName || !f.pyRetType)
|
|
1249
|
+
error(n, 9535, lf("field definition missing py name or return type", f.qName));
|
|
1250
|
+
return f;
|
|
1251
|
+
});
|
|
1252
|
+
const staticFieldSymbols = fieldDefs.filter(f => !f.isInstance);
|
|
1253
|
+
const instanceFields = fieldDefs.filter(f => f.isInstance)
|
|
1254
|
+
.map((f) => B.mkStmt(accessAnnot(f), quote(f.pyName), typeAnnot(f.pyRetType)));
|
|
1255
|
+
const staticFields = staticFieldSymbols
|
|
1256
|
+
.map((f) => B.mkGroup([
|
|
1257
|
+
B.mkStmt(accessAnnot(f), B.mkText("static "), quote(f.pyName), typeAnnot(f.pyRetType)),
|
|
1258
|
+
declareLocalStatic(quoteStr(n.name), quoteStr(f.pyName), t2s(f.pyRetType))
|
|
1259
|
+
]));
|
|
1260
|
+
body.children = staticFields.concat(instanceFields).concat(body.children);
|
|
1261
|
+
}
|
|
1262
|
+
if (generatedInitFunction) {
|
|
1263
|
+
nodes = [
|
|
1264
|
+
B.mkStmt(B.mkGroup(nodes)),
|
|
1265
|
+
B.mkStmt(B.mkText(`${n.name}.__init${n.name}()`))
|
|
1266
|
+
];
|
|
1267
|
+
}
|
|
1195
1268
|
return B.mkStmt(B.mkGroup(nodes));
|
|
1196
1269
|
}),
|
|
1197
1270
|
Return: (n) => {
|
|
@@ -1498,7 +1571,7 @@ var pxt;
|
|
|
1498
1571
|
// class fields can't be const
|
|
1499
1572
|
// hack: value in @namespace should always be const
|
|
1500
1573
|
isConstCall = !!(value && ctx.currClass.isNamespace);
|
|
1501
|
-
let fd = getClassField(ctx.currClass.symInfo, nm);
|
|
1574
|
+
let fd = getClassField(ctx.currClass.symInfo, nm, true);
|
|
1502
1575
|
if (!fd)
|
|
1503
1576
|
error(n, 9544, lf("cannot get class field"));
|
|
1504
1577
|
// TODO: use or remove this code
|
|
@@ -1540,7 +1613,9 @@ var pxt;
|
|
|
1540
1613
|
error(n, 9539, lf("function '{0}' missing return type", fd.pyQName));
|
|
1541
1614
|
unifyTypeOf(target, fd.pyRetType);
|
|
1542
1615
|
fd.isInstance = false;
|
|
1543
|
-
|
|
1616
|
+
if (ctx.currClass.isNamespace) {
|
|
1617
|
+
pref = `export ${isConstCall ? "const" : "let"} `;
|
|
1618
|
+
}
|
|
1544
1619
|
}
|
|
1545
1620
|
if (value)
|
|
1546
1621
|
unifyTypeOf(target, typeOf(value));
|
|
@@ -1606,6 +1681,7 @@ var pxt;
|
|
|
1606
1681
|
}
|
|
1607
1682
|
}
|
|
1608
1683
|
function possibleDef(n, excludeLet = false) {
|
|
1684
|
+
var _a, _b;
|
|
1609
1685
|
let id = n.id;
|
|
1610
1686
|
let currScopeVar = lookupScopeSymbol(id);
|
|
1611
1687
|
let curr = currScopeVar === null || currScopeVar === void 0 ? void 0 : currScopeVar.symbol;
|
|
@@ -1640,6 +1716,10 @@ var pxt;
|
|
|
1640
1716
|
if (n.isdef && !excludeLet) {
|
|
1641
1717
|
return B.mkGroup([B.mkText("let "), quote(id)]);
|
|
1642
1718
|
}
|
|
1719
|
+
else if ((curr === null || curr === void 0 ? void 0 : curr.namespace) && (curr === null || curr === void 0 ? void 0 : curr.qName) && !(((_a = ctx.currClass) === null || _a === void 0 ? void 0 : _a.isNamespace) && ((_b = ctx.currClass) === null || _b === void 0 ? void 0 : _b.name) === (curr === null || curr === void 0 ? void 0 : curr.namespace))) {
|
|
1720
|
+
// If this is a static variable in a class, we want the full qname
|
|
1721
|
+
return quote(curr.qName);
|
|
1722
|
+
}
|
|
1643
1723
|
else
|
|
1644
1724
|
return quote(id);
|
|
1645
1725
|
}
|
|
@@ -1653,20 +1733,27 @@ var pxt;
|
|
|
1653
1733
|
//return id.replace(/([a-z0-9])_([a-zA-Z0-9])/g, (f: string, x: string, y: string) => x + y.toUpperCase())
|
|
1654
1734
|
}
|
|
1655
1735
|
function tryGetName(e) {
|
|
1736
|
+
var _a;
|
|
1656
1737
|
if (e.kind == "Name") {
|
|
1657
1738
|
let s = e.id;
|
|
1658
1739
|
let scopeV = lookupVar(s);
|
|
1659
1740
|
let v = scopeV === null || scopeV === void 0 ? void 0 : scopeV.symbol;
|
|
1660
|
-
if (v
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1741
|
+
if (v) {
|
|
1742
|
+
if (v.expandsTo)
|
|
1743
|
+
return v.expandsTo;
|
|
1744
|
+
else if (ctx.currClass && !ctx.currFun && !(scopeV === null || scopeV === void 0 ? void 0 : scopeV.modifier) && v.qName)
|
|
1745
|
+
return v.qName;
|
|
1746
|
+
}
|
|
1747
|
+
return s;
|
|
1664
1748
|
}
|
|
1665
1749
|
if (e.kind == "Attribute") {
|
|
1666
1750
|
let pref = tryGetName(e.value);
|
|
1667
1751
|
if (pref)
|
|
1668
1752
|
return pref + "." + e.attr;
|
|
1669
1753
|
}
|
|
1754
|
+
if (isSuper(e) && ((_a = ctx.currClass) === null || _a === void 0 ? void 0 : _a.baseClass)) {
|
|
1755
|
+
return ctx.currClass.baseClass.qName;
|
|
1756
|
+
}
|
|
1670
1757
|
return undefined;
|
|
1671
1758
|
}
|
|
1672
1759
|
function getName(e) {
|
|
@@ -1874,6 +1961,7 @@ var pxt;
|
|
|
1874
1961
|
return r;
|
|
1875
1962
|
},
|
|
1876
1963
|
Call: (n) => {
|
|
1964
|
+
var _a, _b, _c, _d, _e;
|
|
1877
1965
|
// TODO(dz): move body out; needs seperate PR that doesn't touch content
|
|
1878
1966
|
n.func.inCalledPosition = true;
|
|
1879
1967
|
let nm = tryGetName(n.func);
|
|
@@ -1885,6 +1973,9 @@ var pxt;
|
|
|
1885
1973
|
let methName = "";
|
|
1886
1974
|
if (isClass) {
|
|
1887
1975
|
fun = lookupSymbol(namedSymbol.pyQName + ".__constructor");
|
|
1976
|
+
if (!fun) {
|
|
1977
|
+
fun = addSymbolFor(3 /* Function */, createDummyConstructorSymbol(namedSymbol === null || namedSymbol === void 0 ? void 0 : namedSymbol.pyAST));
|
|
1978
|
+
}
|
|
1888
1979
|
}
|
|
1889
1980
|
else {
|
|
1890
1981
|
if (n.func.kind == "Attribute") {
|
|
@@ -1904,7 +1995,7 @@ var pxt;
|
|
|
1904
1995
|
if (ctx.currClass && ctx.currClass.baseClass) {
|
|
1905
1996
|
if (!n.tsType)
|
|
1906
1997
|
error(n, 9543, lf("call expr missing ts type"));
|
|
1907
|
-
unifyClass(n, n.tsType, ctx.currClass.baseClass
|
|
1998
|
+
unifyClass(n, n.tsType, ctx.currClass.baseClass);
|
|
1908
1999
|
}
|
|
1909
2000
|
return B.mkText("super");
|
|
1910
2001
|
}
|
|
@@ -1964,6 +2055,17 @@ var pxt;
|
|
|
1964
2055
|
unify(n, n.tsType, tpString);
|
|
1965
2056
|
return B.mkInfix(B.mkText(`""`), "+", expr(n.args[0]));
|
|
1966
2057
|
}
|
|
2058
|
+
const isSuperAttribute = n.func.kind === "Attribute" && isSuper(n.func.value);
|
|
2059
|
+
if (!fun && isSuperAttribute) {
|
|
2060
|
+
fun = lookupGlobalSymbol(nm);
|
|
2061
|
+
}
|
|
2062
|
+
const isSuperConstructor = ((_a = ctx.currFun) === null || _a === void 0 ? void 0 : _a.name) === "__init__" &&
|
|
2063
|
+
(fun === null || fun === void 0 ? void 0 : fun.name) === "__constructor" &&
|
|
2064
|
+
((_c = (_b = ctx.currClass) === null || _b === void 0 ? void 0 : _b.baseClass) === null || _c === void 0 ? void 0 : _c.pyQName) === (fun === null || fun === void 0 ? void 0 : fun.namespace) &&
|
|
2065
|
+
isSuperAttribute;
|
|
2066
|
+
if (isSuperConstructor) {
|
|
2067
|
+
fun = lookupSymbol(((_e = (_d = ctx.currClass) === null || _d === void 0 ? void 0 : _d.baseClass) === null || _e === void 0 ? void 0 : _e.pyQName) + ".__constructor");
|
|
2068
|
+
}
|
|
1967
2069
|
if (!fun) {
|
|
1968
2070
|
error(n, 9508, pxt.U.lf("can't find called function '{0}'", nm));
|
|
1969
2071
|
}
|
|
@@ -2071,7 +2173,13 @@ var pxt;
|
|
|
2071
2173
|
]);
|
|
2072
2174
|
}
|
|
2073
2175
|
}
|
|
2074
|
-
let fn
|
|
2176
|
+
let fn;
|
|
2177
|
+
if (isSuperConstructor) {
|
|
2178
|
+
fn = B.mkText("super");
|
|
2179
|
+
}
|
|
2180
|
+
else {
|
|
2181
|
+
fn = methName ? B.mkInfix(expr(recv), ".", B.mkText(methName)) : expr(n.func);
|
|
2182
|
+
}
|
|
2075
2183
|
let nodes = [
|
|
2076
2184
|
fn,
|
|
2077
2185
|
B.mkText("("),
|
|
@@ -2728,6 +2836,68 @@ var pxt;
|
|
|
2728
2836
|
break;
|
|
2729
2837
|
}
|
|
2730
2838
|
}
|
|
2839
|
+
function createDummyConstructorSymbol(def, sym = def.symInfo) {
|
|
2840
|
+
var _a;
|
|
2841
|
+
const existing = lookupApi(sym.pyQName + ".__constructor");
|
|
2842
|
+
if (!existing && ((_a = sym.extendsTypes) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
2843
|
+
const parentSymbol = lookupSymbol(sym.extendsTypes[0]) || lookupGlobalSymbol(sym.extendsTypes[0]);
|
|
2844
|
+
if (parentSymbol) {
|
|
2845
|
+
return createDummyConstructorSymbol(def, parentSymbol);
|
|
2846
|
+
}
|
|
2847
|
+
}
|
|
2848
|
+
const result = {
|
|
2849
|
+
kind: "FunctionDef",
|
|
2850
|
+
name: "__init__",
|
|
2851
|
+
startPos: def.startPos,
|
|
2852
|
+
endPos: def.endPos,
|
|
2853
|
+
parent: def,
|
|
2854
|
+
body: [],
|
|
2855
|
+
args: {
|
|
2856
|
+
kind: "Arguments",
|
|
2857
|
+
startPos: 0,
|
|
2858
|
+
endPos: 0,
|
|
2859
|
+
args: [{
|
|
2860
|
+
startPos: 0,
|
|
2861
|
+
endPos: 0,
|
|
2862
|
+
kind: "Arg",
|
|
2863
|
+
arg: "self"
|
|
2864
|
+
}],
|
|
2865
|
+
kw_defaults: [],
|
|
2866
|
+
kwonlyargs: [],
|
|
2867
|
+
defaults: []
|
|
2868
|
+
},
|
|
2869
|
+
decorator_list: [],
|
|
2870
|
+
vars: {},
|
|
2871
|
+
symInfo: mkSymbol(3 /* Function */, def.symInfo.qName + ".__constructor")
|
|
2872
|
+
};
|
|
2873
|
+
result.symInfo.parameters = [];
|
|
2874
|
+
result.symInfo.pyRetType = mkType({ classType: def.symInfo });
|
|
2875
|
+
if (existing) {
|
|
2876
|
+
result.args.args.push(...existing.parameters.map(p => ({
|
|
2877
|
+
startPos: 0,
|
|
2878
|
+
endPos: 0,
|
|
2879
|
+
kind: "Arg",
|
|
2880
|
+
arg: p.name,
|
|
2881
|
+
})));
|
|
2882
|
+
result.symInfo.parameters.push(...existing.parameters.map(p => {
|
|
2883
|
+
if (p.pyType)
|
|
2884
|
+
return p;
|
|
2885
|
+
const res = Object.assign(Object.assign({}, p), { pyType: mapTsType(p.type) });
|
|
2886
|
+
return res;
|
|
2887
|
+
}));
|
|
2888
|
+
}
|
|
2889
|
+
return result;
|
|
2890
|
+
}
|
|
2891
|
+
function declareLocalStatic(className, name, type) {
|
|
2892
|
+
const isSetVar = `___${name}_is_set`;
|
|
2893
|
+
const localVar = `___${name}`;
|
|
2894
|
+
return B.mkStmt(B.mkStmt(B.mkText(`private ${isSetVar}: boolean`)), B.mkStmt(B.mkText(`private ${localVar}: ${type}`)), B.mkStmt(B.mkText(`get ${name}(): ${type}`), B.mkBlock([
|
|
2895
|
+
B.mkText(`return this.${isSetVar} ? this.${localVar} : ${className}.${name}`)
|
|
2896
|
+
])), B.mkStmt(B.mkText(`set ${name}(value: ${type})`), B.mkBlock([
|
|
2897
|
+
B.mkStmt(B.mkText(`this.${isSetVar} = true`)),
|
|
2898
|
+
B.mkStmt(B.mkText(`this.${localVar} = value`)),
|
|
2899
|
+
])));
|
|
2900
|
+
}
|
|
2731
2901
|
})(py = pxt.py || (pxt.py = {}));
|
|
2732
2902
|
})(pxt || (pxt = {}));
|
|
2733
2903
|
// Lexer spec: https://docs.python.org/3/reference/lexical_analysis.html
|
package/built/pxtrunner.d.ts
CHANGED
|
@@ -107,7 +107,8 @@ declare namespace pxt.runner {
|
|
|
107
107
|
function buildSimJsInfo(simOptions: SimulateOptions): Promise<pxtc.BuiltSimJsInfo>;
|
|
108
108
|
enum LanguageMode {
|
|
109
109
|
Blocks = 0,
|
|
110
|
-
TypeScript = 1
|
|
110
|
+
TypeScript = 1,
|
|
111
|
+
Python = 2
|
|
111
112
|
}
|
|
112
113
|
let editorLanguageMode: LanguageMode;
|
|
113
114
|
function setEditorContextAsync(mode: LanguageMode, localeInfo: string): Promise<void>;
|
package/built/pxtrunner.js
CHANGED
|
@@ -1845,6 +1845,7 @@ var pxt;
|
|
|
1845
1845
|
(function (LanguageMode) {
|
|
1846
1846
|
LanguageMode[LanguageMode["Blocks"] = 0] = "Blocks";
|
|
1847
1847
|
LanguageMode[LanguageMode["TypeScript"] = 1] = "TypeScript";
|
|
1848
|
+
LanguageMode[LanguageMode["Python"] = 2] = "Python";
|
|
1848
1849
|
})(LanguageMode = runner.LanguageMode || (runner.LanguageMode = {}));
|
|
1849
1850
|
runner.editorLanguageMode = LanguageMode.Blocks;
|
|
1850
1851
|
function setEditorContextAsync(mode, localeInfo) {
|
|
@@ -1874,7 +1875,14 @@ var pxt;
|
|
|
1874
1875
|
case "fileloaded":
|
|
1875
1876
|
let fm = m;
|
|
1876
1877
|
let name = fm.name;
|
|
1877
|
-
|
|
1878
|
+
let mode = LanguageMode.Blocks;
|
|
1879
|
+
if (/\.ts$/i.test(name)) {
|
|
1880
|
+
mode = LanguageMode.TypeScript;
|
|
1881
|
+
}
|
|
1882
|
+
else if (/\.py$/i.test(name)) {
|
|
1883
|
+
mode = LanguageMode.Python;
|
|
1884
|
+
}
|
|
1885
|
+
setEditorContextAsync(mode, fm.locale);
|
|
1878
1886
|
break;
|
|
1879
1887
|
case "popout":
|
|
1880
1888
|
let mp = /((\/v[0-9+])\/)?[^\/]*#(doc|md):([^&?:]+)/i.exec(window.location.href);
|
|
@@ -2072,24 +2080,33 @@ var pxt;
|
|
|
2072
2080
|
el.setAttribute("aria-disabled", "false");
|
|
2073
2081
|
}
|
|
2074
2082
|
}
|
|
2075
|
-
function
|
|
2083
|
+
async function renderHashAsync() {
|
|
2076
2084
|
let m = /^#(doc|md|tutorial|book|project|projectid|print):([^&?:]+)(:([^&?:]+):([^&?:]+))?/i.exec(window.location.hash);
|
|
2077
2085
|
if (m) {
|
|
2078
2086
|
pushHistory();
|
|
2087
|
+
if (m[4]) {
|
|
2088
|
+
let mode = LanguageMode.TypeScript;
|
|
2089
|
+
if (/^blocks$/i.test(m[4])) {
|
|
2090
|
+
mode = LanguageMode.Blocks;
|
|
2091
|
+
}
|
|
2092
|
+
else if (/^python$/i.test(m[4])) {
|
|
2093
|
+
mode = LanguageMode.Python;
|
|
2094
|
+
}
|
|
2095
|
+
await setEditorContextAsync(mode, m[5]);
|
|
2096
|
+
}
|
|
2079
2097
|
// navigation occured
|
|
2080
|
-
|
|
2081
|
-
p.then(() => render(m[1], decodeURIComponent(m[2])));
|
|
2098
|
+
render(m[1], decodeURIComponent(m[2]));
|
|
2082
2099
|
}
|
|
2083
2100
|
}
|
|
2084
2101
|
let promise = pxt.editor.initEditorExtensionsAsync();
|
|
2085
2102
|
promise.then(() => {
|
|
2086
2103
|
window.addEventListener("message", receiveDocMessage, false);
|
|
2087
2104
|
window.addEventListener("hashchange", () => {
|
|
2088
|
-
|
|
2105
|
+
renderHashAsync();
|
|
2089
2106
|
}, false);
|
|
2090
2107
|
parent.postMessage({ type: "sidedocready" }, "*");
|
|
2091
2108
|
// delay load doc page to allow simulator to load first
|
|
2092
|
-
setTimeout(() =>
|
|
2109
|
+
setTimeout(() => renderHashAsync(), 1);
|
|
2093
2110
|
});
|
|
2094
2111
|
}
|
|
2095
2112
|
runner.startDocsServer = startDocsServer;
|
|
@@ -2108,7 +2125,7 @@ var pxt;
|
|
|
2108
2125
|
if (files[readme])
|
|
2109
2126
|
md += files[readme].replace(/^#+/, "$0#") + '\n'; // bump all headers down 1
|
|
2110
2127
|
cfg.files.filter(f => f != pxt.CONFIG_NAME && f != readme)
|
|
2111
|
-
.filter(f => (runner.editorLanguageMode
|
|
2128
|
+
.filter(f => matchesLanguageMode(f, runner.editorLanguageMode))
|
|
2112
2129
|
.forEach(f => {
|
|
2113
2130
|
if (!/^main\.(ts|blocks)$/.test(f))
|
|
2114
2131
|
md += `
|
|
@@ -2163,6 +2180,16 @@ ${linkString}
|
|
|
2163
2180
|
return renderMarkdownAsync(content, md, options);
|
|
2164
2181
|
}
|
|
2165
2182
|
runner.renderProjectFilesAsync = renderProjectFilesAsync;
|
|
2183
|
+
function matchesLanguageMode(filename, mode) {
|
|
2184
|
+
switch (mode) {
|
|
2185
|
+
case LanguageMode.Blocks:
|
|
2186
|
+
return /\.blocks?$/.test(filename);
|
|
2187
|
+
case LanguageMode.TypeScript:
|
|
2188
|
+
return /\.ts?$/.test(filename);
|
|
2189
|
+
case LanguageMode.Python:
|
|
2190
|
+
return /\.py?$/.test(filename);
|
|
2191
|
+
}
|
|
2192
|
+
}
|
|
2166
2193
|
function renderDocAsync(content, docid) {
|
|
2167
2194
|
docid = docid.replace(/^\//, "");
|
|
2168
2195
|
return pxt.Cloud.markdownAsync(docid)
|