pxt-core 7.5.44 → 7.5.47
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 +231 -38
- package/built/pxtblockly.js +24 -2
- package/built/pxtblocks.d.ts +1 -0
- package/built/pxtblocks.js +24 -2
- package/built/pxtlib.d.ts +1 -0
- package/built/pxtlib.js +8 -2
- package/built/pxtpy.d.ts +2 -1
- package/built/pxtpy.js +223 -36
- package/built/target.js +1 -1
- package/built/web/main.js +1 -1
- package/built/web/pxtapp.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/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 +3 -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/package.json +1 -1
- package/react-common/styles/extensions/ExtensionCard.less +5 -1
- package/theme/soundeffecteditor.less +7 -3
- package/theme/tutorial-sidebar.less +1 -0
- package/theme/tutorial.less +1 -0
package/built/pxtpy.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ declare namespace pxt.py {
|
|
|
16
16
|
pyAST?: AST;
|
|
17
17
|
isProtected?: boolean;
|
|
18
18
|
moduleTypeMarker?: {};
|
|
19
|
+
isStatic?: boolean;
|
|
19
20
|
declared?: number;
|
|
20
21
|
}
|
|
21
22
|
interface TypeOptions {
|
|
@@ -170,7 +171,7 @@ declare namespace pxt.py {
|
|
|
170
171
|
keywords: Keyword[];
|
|
171
172
|
body: Stmt[];
|
|
172
173
|
decorator_list: Expr[];
|
|
173
|
-
baseClass?:
|
|
174
|
+
baseClass?: SymbolInfo;
|
|
174
175
|
isEnum?: boolean;
|
|
175
176
|
isNamespace?: boolean;
|
|
176
177
|
}
|
package/built/pxtpy.js
CHANGED
|
@@ -186,6 +186,7 @@ var pxt;
|
|
|
186
186
|
return mkType({ primType: tp });
|
|
187
187
|
}
|
|
188
188
|
function getOrSetSymbolType(sym) {
|
|
189
|
+
var _a;
|
|
189
190
|
if (!sym.pySymbolType) {
|
|
190
191
|
currErrorCtx = sym.pyQName;
|
|
191
192
|
if (sym.parameters) {
|
|
@@ -207,8 +208,24 @@ var pxt;
|
|
|
207
208
|
sym.pyRetType = mkType({ moduleType: sym });
|
|
208
209
|
}
|
|
209
210
|
else {
|
|
210
|
-
if (sym.retType)
|
|
211
|
-
sym.
|
|
211
|
+
if (sym.retType) {
|
|
212
|
+
if (((_a = sym.qName) === null || _a === void 0 ? void 0 : _a.endsWith(".__constructor")) && sym.retType === "void") {
|
|
213
|
+
// This must be a TS class. Because python treats constructors as functions,
|
|
214
|
+
// set the return type to be the class instead of void
|
|
215
|
+
const classSym = lookupGlobalSymbol(sym.qName.substring(0, sym.qName.lastIndexOf(".")));
|
|
216
|
+
if (classSym) {
|
|
217
|
+
sym.pyRetType = mkType({
|
|
218
|
+
classType: classSym
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
sym.pyRetType = mapTsType(sym.retType);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
sym.pyRetType = mapTsType(sym.retType);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
212
229
|
else if (sym.pyRetType) {
|
|
213
230
|
// nothing to do
|
|
214
231
|
}
|
|
@@ -241,11 +258,19 @@ var pxt;
|
|
|
241
258
|
return pxt.U.lookup(internalApis, name) || pxt.U.lookup(externalApis, name);
|
|
242
259
|
}
|
|
243
260
|
function lookupGlobalSymbol(name) {
|
|
261
|
+
var _a;
|
|
244
262
|
if (!name)
|
|
245
263
|
return undefined;
|
|
246
264
|
let sym = lookupApi(name);
|
|
247
265
|
if (sym)
|
|
248
266
|
getOrSetSymbolType(sym);
|
|
267
|
+
else if (name.indexOf(".") && !name.endsWith(".__constructor")) {
|
|
268
|
+
const base = name.substring(0, name.lastIndexOf("."));
|
|
269
|
+
const baseSymbol = lookupGlobalSymbol(base);
|
|
270
|
+
if ((baseSymbol === null || baseSymbol === void 0 ? void 0 : baseSymbol.kind) === 8 /* Class */ && ((_a = baseSymbol.extendsTypes) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
271
|
+
return lookupGlobalSymbol(baseSymbol.extendsTypes[0] + name.substring(base.length));
|
|
272
|
+
}
|
|
273
|
+
}
|
|
249
274
|
return sym;
|
|
250
275
|
}
|
|
251
276
|
function initApis(apisInfo, tsShadowFiles) {
|
|
@@ -328,7 +353,10 @@ var pxt;
|
|
|
328
353
|
pref += ".";
|
|
329
354
|
}
|
|
330
355
|
let qualifiedName = pref + name;
|
|
331
|
-
if (
|
|
356
|
+
if (scope.kind === "ClassDef") {
|
|
357
|
+
varSym = addSymbol(2 /* Property */, qualifiedName);
|
|
358
|
+
}
|
|
359
|
+
else if (isLocalScope(scope)
|
|
332
360
|
&& (modifier === py_1.VarModifier.Global
|
|
333
361
|
|| modifier === py_1.VarModifier.NonLocal)) {
|
|
334
362
|
varSym = addSymbol(4 /* Variable */, name);
|
|
@@ -442,7 +470,7 @@ var pxt;
|
|
|
442
470
|
};
|
|
443
471
|
}
|
|
444
472
|
}
|
|
445
|
-
// next free error
|
|
473
|
+
// next free error 9576
|
|
446
474
|
function error(astNode, code, msg) {
|
|
447
475
|
diagnostics.push(mkDiag(astNode, pxtc.DiagnosticCategory.Error, code, msg));
|
|
448
476
|
//const pos = position(astNode ? astNode.startPos || 0 : 0, mod.source)
|
|
@@ -657,8 +685,19 @@ var pxt;
|
|
|
657
685
|
let qn = cd.symInfo.qName;
|
|
658
686
|
return pxt.U.values(internalApis).filter(e => e.namespace == qn && e.kind == 2 /* Property */);
|
|
659
687
|
}
|
|
660
|
-
function getClassField(ct, n, checkOnly = false, skipBases = false) {
|
|
661
|
-
let qid
|
|
688
|
+
function getClassField(ct, n, isStatic, checkOnly = false, skipBases = false) {
|
|
689
|
+
let qid;
|
|
690
|
+
if (n === "__init__") {
|
|
691
|
+
qid = ct.pyQName + ".__constructor";
|
|
692
|
+
}
|
|
693
|
+
else {
|
|
694
|
+
if (n.startsWith(ct.pyQName + ".")) {
|
|
695
|
+
qid = n;
|
|
696
|
+
}
|
|
697
|
+
else {
|
|
698
|
+
qid = ct.pyQName + "." + n;
|
|
699
|
+
}
|
|
700
|
+
}
|
|
662
701
|
let f = lookupGlobalSymbol(qid);
|
|
663
702
|
if (f)
|
|
664
703
|
return f;
|
|
@@ -668,7 +707,7 @@ var pxt;
|
|
|
668
707
|
if (sym) {
|
|
669
708
|
if (sym == ct)
|
|
670
709
|
pxt.U.userError("field lookup loop on: " + sym.qName + " / " + n);
|
|
671
|
-
let classF = getClassField(sym, n, true);
|
|
710
|
+
let classF = getClassField(sym, n, isStatic, true);
|
|
672
711
|
if (classF)
|
|
673
712
|
return classF;
|
|
674
713
|
}
|
|
@@ -676,7 +715,7 @@ var pxt;
|
|
|
676
715
|
}
|
|
677
716
|
if (!checkOnly && ct.pyAST && ct.pyAST.kind == "ClassDef") {
|
|
678
717
|
let sym = addSymbol(2 /* Property */, qid);
|
|
679
|
-
sym.isInstance =
|
|
718
|
+
sym.isInstance = !isStatic;
|
|
680
719
|
return sym;
|
|
681
720
|
}
|
|
682
721
|
return null;
|
|
@@ -693,16 +732,14 @@ var pxt;
|
|
|
693
732
|
const recvType = typeOf(recv);
|
|
694
733
|
const constructorTypes = getTypesForFieldLookup(recvType);
|
|
695
734
|
for (let ct of constructorTypes) {
|
|
696
|
-
let
|
|
735
|
+
let isModule = !!recvType.moduleType;
|
|
736
|
+
let f = getClassField(ct, n, isModule, checkOnly);
|
|
697
737
|
if (f) {
|
|
698
|
-
let isModule = !!recvType.moduleType;
|
|
699
738
|
if (isModule) {
|
|
700
739
|
if (f.isInstance)
|
|
701
740
|
error(null, 9505, pxt.U.lf("the field '{0}' of '{1}' is not static", n, ct.pyQName));
|
|
702
741
|
}
|
|
703
742
|
else {
|
|
704
|
-
if (!f.isInstance)
|
|
705
|
-
error(null, 9504, pxt.U.lf("the field '{0}' of '{1}' is static", n, ct.pyQName));
|
|
706
743
|
if (isSuper(recv))
|
|
707
744
|
f.isProtected = true;
|
|
708
745
|
else if (isThis(recv)) {
|
|
@@ -885,14 +922,17 @@ var pxt;
|
|
|
885
922
|
return mkType({});
|
|
886
923
|
}
|
|
887
924
|
function doArgs(n, isMethod) {
|
|
925
|
+
var _a;
|
|
888
926
|
const args = n.args;
|
|
889
927
|
if (args.kwonlyargs.length)
|
|
890
928
|
error(n, 9517, pxt.U.lf("keyword-only arguments not supported yet"));
|
|
891
929
|
let nargs = args.args.slice();
|
|
892
930
|
if (isMethod) {
|
|
893
|
-
if (nargs[0].arg
|
|
894
|
-
|
|
895
|
-
|
|
931
|
+
if (((_a = nargs[0]) === null || _a === void 0 ? void 0 : _a.arg) !== "self")
|
|
932
|
+
n.symInfo.isStatic = true;
|
|
933
|
+
else {
|
|
934
|
+
nargs.shift();
|
|
935
|
+
}
|
|
896
936
|
}
|
|
897
937
|
else {
|
|
898
938
|
if (nargs.some(a => a.arg == "self"))
|
|
@@ -1054,6 +1094,7 @@ var pxt;
|
|
|
1054
1094
|
}
|
|
1055
1095
|
function emitFunctionDef(n, inline = false) {
|
|
1056
1096
|
return guardedScope(n, () => {
|
|
1097
|
+
var _a, _b, _c, _d;
|
|
1057
1098
|
const isMethod = !!ctx.currClass && !ctx.currFun;
|
|
1058
1099
|
const topLev = isTopLevel();
|
|
1059
1100
|
const nested = !!ctx.currFun;
|
|
@@ -1106,7 +1147,7 @@ var pxt;
|
|
|
1106
1147
|
let scopeValueVar = n.vars["value"];
|
|
1107
1148
|
let valueVar = scopeValueVar === null || scopeValueVar === void 0 ? void 0 : scopeValueVar.symbol;
|
|
1108
1149
|
if (funname == "__set__" && valueVar) {
|
|
1109
|
-
let cf = getClassField(ctx.currClass.symInfo, "__get__");
|
|
1150
|
+
let cf = getClassField(ctx.currClass.symInfo, "__get__", false);
|
|
1110
1151
|
if (cf && cf.pyAST && cf.pyAST.kind == "FunctionDef")
|
|
1111
1152
|
unify(n, valueVar.pyRetType, cf.pyRetType);
|
|
1112
1153
|
}
|
|
@@ -1114,6 +1155,9 @@ var pxt;
|
|
|
1114
1155
|
}
|
|
1115
1156
|
if (!prefix) {
|
|
1116
1157
|
prefix = funname[0] == "_" ? (sym.isProtected ? "protected" : "private") : "public";
|
|
1158
|
+
if (n.symInfo.isStatic) {
|
|
1159
|
+
prefix += " static";
|
|
1160
|
+
}
|
|
1117
1161
|
}
|
|
1118
1162
|
nodes.push(B.mkText(prefix + " "), quote(funname));
|
|
1119
1163
|
}
|
|
@@ -1125,7 +1169,7 @@ var pxt;
|
|
|
1125
1169
|
else
|
|
1126
1170
|
nodes.push(B.mkText("export function "), quote(funname));
|
|
1127
1171
|
}
|
|
1128
|
-
let retType = n.returns ? compileType(n.returns) : sym.pyRetType;
|
|
1172
|
+
let retType = n.name == "__init__" ? undefined : (n.returns ? compileType(n.returns) : sym.pyRetType);
|
|
1129
1173
|
nodes.push(doArgs(n, isMethod), retType && canonicalize(retType) != tpVoid ? typeAnnot(retType) : B.mkText(""));
|
|
1130
1174
|
// make sure type is initialized
|
|
1131
1175
|
getOrSetSymbolType(sym);
|
|
@@ -1133,6 +1177,13 @@ var pxt;
|
|
|
1133
1177
|
if (n.name == "__init__") {
|
|
1134
1178
|
if (!ctx.currClass)
|
|
1135
1179
|
error(n, 9533, lf("__init__ method '{0}' is missing current class context", sym.pyQName));
|
|
1180
|
+
if ((_a = ctx.currClass) === null || _a === void 0 ? void 0 : _a.baseClass) {
|
|
1181
|
+
const firstStatement = n.body[0];
|
|
1182
|
+
const superConstructor = ctx.currClass.baseClass.pyQName + ".__constructor";
|
|
1183
|
+
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) {
|
|
1184
|
+
error(n, 9575, lf("Sub classes must call 'super().__init__' as the first statement inside an __init__ method"));
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1136
1187
|
for (let f of listClassFields(ctx.currClass)) {
|
|
1137
1188
|
let p = f.pyAST;
|
|
1138
1189
|
if (p && p.value) {
|
|
@@ -1176,22 +1227,61 @@ var pxt;
|
|
|
1176
1227
|
nodes.push(B.mkCommaSep(n.bases.map(expr)));
|
|
1177
1228
|
let b = getClassDef(n.bases[0]);
|
|
1178
1229
|
if (b) {
|
|
1179
|
-
n.baseClass = b;
|
|
1230
|
+
n.baseClass = b.symInfo;
|
|
1180
1231
|
sym.extendsTypes = [b.symInfo.pyQName];
|
|
1181
1232
|
}
|
|
1233
|
+
else {
|
|
1234
|
+
const nm = tryGetName(n.bases[0]);
|
|
1235
|
+
if (nm) {
|
|
1236
|
+
const localSym = lookupSymbol(nm);
|
|
1237
|
+
const globalSym = lookupGlobalSymbol(nm);
|
|
1238
|
+
n.baseClass = localSym || globalSym;
|
|
1239
|
+
if (n.baseClass)
|
|
1240
|
+
sym.extendsTypes = [n.baseClass.pyQName];
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1182
1243
|
}
|
|
1183
1244
|
}
|
|
1184
|
-
|
|
1245
|
+
const classDefs = n.body.filter(s => n.isNamespace || s.kind === "FunctionDef");
|
|
1246
|
+
const staticStmts = n.isNamespace ? [] : n.body.filter(s => classDefs.indexOf(s) === -1 && s.kind !== "Pass");
|
|
1247
|
+
let body = stmts(classDefs);
|
|
1185
1248
|
nodes.push(body);
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1249
|
+
// Python classes allow arbitrary statements in their bodies, sort of like namespaces.
|
|
1250
|
+
// Take all of these statements and put them in a static method that we can call when
|
|
1251
|
+
// the class is defined.
|
|
1252
|
+
let generatedInitFunction = false;
|
|
1253
|
+
if (staticStmts.length) {
|
|
1254
|
+
generatedInitFunction = true;
|
|
1255
|
+
const staticBody = stmts(staticStmts);
|
|
1256
|
+
const initFun = B.mkStmt(B.mkGroup([
|
|
1257
|
+
B.mkText(`public static __init${n.name}() `),
|
|
1258
|
+
staticBody
|
|
1259
|
+
]));
|
|
1260
|
+
body.children.unshift(initFun);
|
|
1261
|
+
}
|
|
1262
|
+
if (!n.isNamespace) {
|
|
1263
|
+
const fieldDefs = listClassFields(n)
|
|
1264
|
+
.map(f => {
|
|
1265
|
+
if (!f.pyName || !f.pyRetType)
|
|
1266
|
+
error(n, 9535, lf("field definition missing py name or return type", f.qName));
|
|
1267
|
+
return f;
|
|
1268
|
+
});
|
|
1269
|
+
const staticFieldSymbols = fieldDefs.filter(f => !f.isInstance);
|
|
1270
|
+
const instanceFields = fieldDefs.filter(f => f.isInstance)
|
|
1271
|
+
.map((f) => B.mkStmt(accessAnnot(f), quote(f.pyName), typeAnnot(f.pyRetType)));
|
|
1272
|
+
const staticFields = staticFieldSymbols
|
|
1273
|
+
.map((f) => B.mkGroup([
|
|
1274
|
+
B.mkStmt(accessAnnot(f), B.mkText("static "), quote(f.pyName), typeAnnot(f.pyRetType)),
|
|
1275
|
+
declareLocalStatic(quoteStr(n.name), quoteStr(f.pyName), t2s(f.pyRetType))
|
|
1276
|
+
]));
|
|
1277
|
+
body.children = staticFields.concat(instanceFields).concat(body.children);
|
|
1278
|
+
}
|
|
1279
|
+
if (generatedInitFunction) {
|
|
1280
|
+
nodes = [
|
|
1281
|
+
B.mkStmt(B.mkGroup(nodes)),
|
|
1282
|
+
B.mkStmt(B.mkText(`${n.name}.__init${n.name}()`))
|
|
1283
|
+
];
|
|
1284
|
+
}
|
|
1195
1285
|
return B.mkStmt(B.mkGroup(nodes));
|
|
1196
1286
|
}),
|
|
1197
1287
|
Return: (n) => {
|
|
@@ -1498,7 +1588,7 @@ var pxt;
|
|
|
1498
1588
|
// class fields can't be const
|
|
1499
1589
|
// hack: value in @namespace should always be const
|
|
1500
1590
|
isConstCall = !!(value && ctx.currClass.isNamespace);
|
|
1501
|
-
let fd = getClassField(ctx.currClass.symInfo, nm);
|
|
1591
|
+
let fd = getClassField(ctx.currClass.symInfo, nm, true);
|
|
1502
1592
|
if (!fd)
|
|
1503
1593
|
error(n, 9544, lf("cannot get class field"));
|
|
1504
1594
|
// TODO: use or remove this code
|
|
@@ -1540,7 +1630,9 @@ var pxt;
|
|
|
1540
1630
|
error(n, 9539, lf("function '{0}' missing return type", fd.pyQName));
|
|
1541
1631
|
unifyTypeOf(target, fd.pyRetType);
|
|
1542
1632
|
fd.isInstance = false;
|
|
1543
|
-
|
|
1633
|
+
if (ctx.currClass.isNamespace) {
|
|
1634
|
+
pref = `export ${isConstCall ? "const" : "let"} `;
|
|
1635
|
+
}
|
|
1544
1636
|
}
|
|
1545
1637
|
if (value)
|
|
1546
1638
|
unifyTypeOf(target, typeOf(value));
|
|
@@ -1606,6 +1698,7 @@ var pxt;
|
|
|
1606
1698
|
}
|
|
1607
1699
|
}
|
|
1608
1700
|
function possibleDef(n, excludeLet = false) {
|
|
1701
|
+
var _a, _b;
|
|
1609
1702
|
let id = n.id;
|
|
1610
1703
|
let currScopeVar = lookupScopeSymbol(id);
|
|
1611
1704
|
let curr = currScopeVar === null || currScopeVar === void 0 ? void 0 : currScopeVar.symbol;
|
|
@@ -1640,6 +1733,10 @@ var pxt;
|
|
|
1640
1733
|
if (n.isdef && !excludeLet) {
|
|
1641
1734
|
return B.mkGroup([B.mkText("let "), quote(id)]);
|
|
1642
1735
|
}
|
|
1736
|
+
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))) {
|
|
1737
|
+
// If this is a static variable in a class, we want the full qname
|
|
1738
|
+
return quote(curr.qName);
|
|
1739
|
+
}
|
|
1643
1740
|
else
|
|
1644
1741
|
return quote(id);
|
|
1645
1742
|
}
|
|
@@ -1653,20 +1750,27 @@ var pxt;
|
|
|
1653
1750
|
//return id.replace(/([a-z0-9])_([a-zA-Z0-9])/g, (f: string, x: string, y: string) => x + y.toUpperCase())
|
|
1654
1751
|
}
|
|
1655
1752
|
function tryGetName(e) {
|
|
1753
|
+
var _a;
|
|
1656
1754
|
if (e.kind == "Name") {
|
|
1657
1755
|
let s = e.id;
|
|
1658
1756
|
let scopeV = lookupVar(s);
|
|
1659
1757
|
let v = scopeV === null || scopeV === void 0 ? void 0 : scopeV.symbol;
|
|
1660
|
-
if (v
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1758
|
+
if (v) {
|
|
1759
|
+
if (v.expandsTo)
|
|
1760
|
+
return v.expandsTo;
|
|
1761
|
+
else if (ctx.currClass && !ctx.currFun && !(scopeV === null || scopeV === void 0 ? void 0 : scopeV.modifier) && v.qName)
|
|
1762
|
+
return v.qName;
|
|
1763
|
+
}
|
|
1764
|
+
return s;
|
|
1664
1765
|
}
|
|
1665
1766
|
if (e.kind == "Attribute") {
|
|
1666
1767
|
let pref = tryGetName(e.value);
|
|
1667
1768
|
if (pref)
|
|
1668
1769
|
return pref + "." + e.attr;
|
|
1669
1770
|
}
|
|
1771
|
+
if (isSuper(e) && ((_a = ctx.currClass) === null || _a === void 0 ? void 0 : _a.baseClass)) {
|
|
1772
|
+
return ctx.currClass.baseClass.qName;
|
|
1773
|
+
}
|
|
1670
1774
|
return undefined;
|
|
1671
1775
|
}
|
|
1672
1776
|
function getName(e) {
|
|
@@ -1874,6 +1978,7 @@ var pxt;
|
|
|
1874
1978
|
return r;
|
|
1875
1979
|
},
|
|
1876
1980
|
Call: (n) => {
|
|
1981
|
+
var _a, _b, _c, _d, _e;
|
|
1877
1982
|
// TODO(dz): move body out; needs seperate PR that doesn't touch content
|
|
1878
1983
|
n.func.inCalledPosition = true;
|
|
1879
1984
|
let nm = tryGetName(n.func);
|
|
@@ -1885,6 +1990,9 @@ var pxt;
|
|
|
1885
1990
|
let methName = "";
|
|
1886
1991
|
if (isClass) {
|
|
1887
1992
|
fun = lookupSymbol(namedSymbol.pyQName + ".__constructor");
|
|
1993
|
+
if (!fun) {
|
|
1994
|
+
fun = addSymbolFor(3 /* Function */, createDummyConstructorSymbol(namedSymbol === null || namedSymbol === void 0 ? void 0 : namedSymbol.pyAST));
|
|
1995
|
+
}
|
|
1888
1996
|
}
|
|
1889
1997
|
else {
|
|
1890
1998
|
if (n.func.kind == "Attribute") {
|
|
@@ -1904,7 +2012,7 @@ var pxt;
|
|
|
1904
2012
|
if (ctx.currClass && ctx.currClass.baseClass) {
|
|
1905
2013
|
if (!n.tsType)
|
|
1906
2014
|
error(n, 9543, lf("call expr missing ts type"));
|
|
1907
|
-
unifyClass(n, n.tsType, ctx.currClass.baseClass
|
|
2015
|
+
unifyClass(n, n.tsType, ctx.currClass.baseClass);
|
|
1908
2016
|
}
|
|
1909
2017
|
return B.mkText("super");
|
|
1910
2018
|
}
|
|
@@ -1964,6 +2072,17 @@ var pxt;
|
|
|
1964
2072
|
unify(n, n.tsType, tpString);
|
|
1965
2073
|
return B.mkInfix(B.mkText(`""`), "+", expr(n.args[0]));
|
|
1966
2074
|
}
|
|
2075
|
+
const isSuperAttribute = n.func.kind === "Attribute" && isSuper(n.func.value);
|
|
2076
|
+
if (!fun && isSuperAttribute) {
|
|
2077
|
+
fun = lookupGlobalSymbol(nm);
|
|
2078
|
+
}
|
|
2079
|
+
const isSuperConstructor = ((_a = ctx.currFun) === null || _a === void 0 ? void 0 : _a.name) === "__init__" &&
|
|
2080
|
+
(fun === null || fun === void 0 ? void 0 : fun.name) === "__constructor" &&
|
|
2081
|
+
((_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) &&
|
|
2082
|
+
isSuperAttribute;
|
|
2083
|
+
if (isSuperConstructor) {
|
|
2084
|
+
fun = lookupSymbol(((_e = (_d = ctx.currClass) === null || _d === void 0 ? void 0 : _d.baseClass) === null || _e === void 0 ? void 0 : _e.pyQName) + ".__constructor");
|
|
2085
|
+
}
|
|
1967
2086
|
if (!fun) {
|
|
1968
2087
|
error(n, 9508, pxt.U.lf("can't find called function '{0}'", nm));
|
|
1969
2088
|
}
|
|
@@ -2071,7 +2190,13 @@ var pxt;
|
|
|
2071
2190
|
]);
|
|
2072
2191
|
}
|
|
2073
2192
|
}
|
|
2074
|
-
let fn
|
|
2193
|
+
let fn;
|
|
2194
|
+
if (isSuperConstructor) {
|
|
2195
|
+
fn = B.mkText("super");
|
|
2196
|
+
}
|
|
2197
|
+
else {
|
|
2198
|
+
fn = methName ? B.mkInfix(expr(recv), ".", B.mkText(methName)) : expr(n.func);
|
|
2199
|
+
}
|
|
2075
2200
|
let nodes = [
|
|
2076
2201
|
fn,
|
|
2077
2202
|
B.mkText("("),
|
|
@@ -2728,6 +2853,68 @@ var pxt;
|
|
|
2728
2853
|
break;
|
|
2729
2854
|
}
|
|
2730
2855
|
}
|
|
2856
|
+
function createDummyConstructorSymbol(def, sym = def.symInfo) {
|
|
2857
|
+
var _a;
|
|
2858
|
+
const existing = lookupApi(sym.pyQName + ".__constructor");
|
|
2859
|
+
if (!existing && ((_a = sym.extendsTypes) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
2860
|
+
const parentSymbol = lookupSymbol(sym.extendsTypes[0]) || lookupGlobalSymbol(sym.extendsTypes[0]);
|
|
2861
|
+
if (parentSymbol) {
|
|
2862
|
+
return createDummyConstructorSymbol(def, parentSymbol);
|
|
2863
|
+
}
|
|
2864
|
+
}
|
|
2865
|
+
const result = {
|
|
2866
|
+
kind: "FunctionDef",
|
|
2867
|
+
name: "__init__",
|
|
2868
|
+
startPos: def.startPos,
|
|
2869
|
+
endPos: def.endPos,
|
|
2870
|
+
parent: def,
|
|
2871
|
+
body: [],
|
|
2872
|
+
args: {
|
|
2873
|
+
kind: "Arguments",
|
|
2874
|
+
startPos: 0,
|
|
2875
|
+
endPos: 0,
|
|
2876
|
+
args: [{
|
|
2877
|
+
startPos: 0,
|
|
2878
|
+
endPos: 0,
|
|
2879
|
+
kind: "Arg",
|
|
2880
|
+
arg: "self"
|
|
2881
|
+
}],
|
|
2882
|
+
kw_defaults: [],
|
|
2883
|
+
kwonlyargs: [],
|
|
2884
|
+
defaults: []
|
|
2885
|
+
},
|
|
2886
|
+
decorator_list: [],
|
|
2887
|
+
vars: {},
|
|
2888
|
+
symInfo: mkSymbol(3 /* Function */, def.symInfo.qName + ".__constructor")
|
|
2889
|
+
};
|
|
2890
|
+
result.symInfo.parameters = [];
|
|
2891
|
+
result.symInfo.pyRetType = mkType({ classType: def.symInfo });
|
|
2892
|
+
if (existing) {
|
|
2893
|
+
result.args.args.push(...existing.parameters.map(p => ({
|
|
2894
|
+
startPos: 0,
|
|
2895
|
+
endPos: 0,
|
|
2896
|
+
kind: "Arg",
|
|
2897
|
+
arg: p.name,
|
|
2898
|
+
})));
|
|
2899
|
+
result.symInfo.parameters.push(...existing.parameters.map(p => {
|
|
2900
|
+
if (p.pyType)
|
|
2901
|
+
return p;
|
|
2902
|
+
const res = Object.assign(Object.assign({}, p), { pyType: mapTsType(p.type) });
|
|
2903
|
+
return res;
|
|
2904
|
+
}));
|
|
2905
|
+
}
|
|
2906
|
+
return result;
|
|
2907
|
+
}
|
|
2908
|
+
function declareLocalStatic(className, name, type) {
|
|
2909
|
+
const isSetVar = `___${name}_is_set`;
|
|
2910
|
+
const localVar = `___${name}`;
|
|
2911
|
+
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([
|
|
2912
|
+
B.mkText(`return this.${isSetVar} ? this.${localVar} : ${className}.${name}`)
|
|
2913
|
+
])), B.mkStmt(B.mkText(`set ${name}(value: ${type})`), B.mkBlock([
|
|
2914
|
+
B.mkStmt(B.mkText(`this.${isSetVar} = true`)),
|
|
2915
|
+
B.mkStmt(B.mkText(`this.${localVar} = value`)),
|
|
2916
|
+
])));
|
|
2917
|
+
}
|
|
2731
2918
|
})(py = pxt.py || (pxt.py = {}));
|
|
2732
2919
|
})(pxt || (pxt = {}));
|
|
2733
2920
|
// Lexer spec: https://docs.python.org/3/reference/lexical_analysis.html
|