pxt-core 7.5.44 → 7.5.45

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/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(".")) {
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) {
@@ -442,7 +450,7 @@ var pxt;
442
450
  };
443
451
  }
444
452
  }
445
- // next free error 9575
453
+ // next free error 9576
446
454
  function error(astNode, code, msg) {
447
455
  diagnostics.push(mkDiag(astNode, pxtc.DiagnosticCategory.Error, code, msg));
448
456
  //const pos = position(astNode ? astNode.startPos || 0 : 0, mod.source)
@@ -653,12 +661,18 @@ var pxt;
653
661
  return n.symInfo;
654
662
  }
655
663
  // TODO optimize ?
656
- function listClassFields(cd) {
664
+ function listClassFields(cd, excludeVariables = true) {
657
665
  let qn = cd.symInfo.qName;
658
- return pxt.U.values(internalApis).filter(e => e.namespace == qn && e.kind == 2 /* Property */);
666
+ return pxt.U.values(internalApis).filter(e => e.namespace == qn && ((e.kind == 4 /* Variable */ && !excludeVariables) || e.kind == 2 /* Property */));
659
667
  }
660
668
  function getClassField(ct, n, checkOnly = false, skipBases = false) {
661
- let qid = ct.pyQName + "." + n;
669
+ let qid;
670
+ if (n === "__init__") {
671
+ qid = ct.pyQName + ".__constructor";
672
+ }
673
+ else {
674
+ qid = ct.pyQName + "." + n;
675
+ }
662
676
  let f = lookupGlobalSymbol(qid);
663
677
  if (f)
664
678
  return f;
@@ -885,14 +899,17 @@ var pxt;
885
899
  return mkType({});
886
900
  }
887
901
  function doArgs(n, isMethod) {
902
+ var _a;
888
903
  const args = n.args;
889
904
  if (args.kwonlyargs.length)
890
905
  error(n, 9517, pxt.U.lf("keyword-only arguments not supported yet"));
891
906
  let nargs = args.args.slice();
892
907
  if (isMethod) {
893
- if (nargs[0].arg != "self")
894
- error(n, 9518, pxt.U.lf("first argument of method has to be called 'self'"));
895
- nargs.shift();
908
+ if (((_a = nargs[0]) === null || _a === void 0 ? void 0 : _a.arg) !== "self")
909
+ n.symInfo.isStatic = true;
910
+ else {
911
+ nargs.shift();
912
+ }
896
913
  }
897
914
  else {
898
915
  if (nargs.some(a => a.arg == "self"))
@@ -1054,6 +1071,7 @@ var pxt;
1054
1071
  }
1055
1072
  function emitFunctionDef(n, inline = false) {
1056
1073
  return guardedScope(n, () => {
1074
+ var _a, _b, _c, _d;
1057
1075
  const isMethod = !!ctx.currClass && !ctx.currFun;
1058
1076
  const topLev = isTopLevel();
1059
1077
  const nested = !!ctx.currFun;
@@ -1114,6 +1132,9 @@ var pxt;
1114
1132
  }
1115
1133
  if (!prefix) {
1116
1134
  prefix = funname[0] == "_" ? (sym.isProtected ? "protected" : "private") : "public";
1135
+ if (n.symInfo.isStatic) {
1136
+ prefix += " static";
1137
+ }
1117
1138
  }
1118
1139
  nodes.push(B.mkText(prefix + " "), quote(funname));
1119
1140
  }
@@ -1125,7 +1146,7 @@ var pxt;
1125
1146
  else
1126
1147
  nodes.push(B.mkText("export function "), quote(funname));
1127
1148
  }
1128
- let retType = n.returns ? compileType(n.returns) : sym.pyRetType;
1149
+ let retType = n.name == "__init__" ? undefined : (n.returns ? compileType(n.returns) : sym.pyRetType);
1129
1150
  nodes.push(doArgs(n, isMethod), retType && canonicalize(retType) != tpVoid ? typeAnnot(retType) : B.mkText(""));
1130
1151
  // make sure type is initialized
1131
1152
  getOrSetSymbolType(sym);
@@ -1133,6 +1154,13 @@ var pxt;
1133
1154
  if (n.name == "__init__") {
1134
1155
  if (!ctx.currClass)
1135
1156
  error(n, 9533, lf("__init__ method '{0}' is missing current class context", sym.pyQName));
1157
+ if ((_a = ctx.currClass) === null || _a === void 0 ? void 0 : _a.baseClass) {
1158
+ const firstStatement = n.body[0];
1159
+ const superConstructor = ctx.currClass.baseClass.pyQName + ".__constructor";
1160
+ 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) {
1161
+ error(n, 9575, lf("Sub classes must call 'super().__init__' as the first statement inside an __init__ method"));
1162
+ }
1163
+ }
1136
1164
  for (let f of listClassFields(ctx.currClass)) {
1137
1165
  let p = f.pyAST;
1138
1166
  if (p && p.value) {
@@ -1176,22 +1204,59 @@ var pxt;
1176
1204
  nodes.push(B.mkCommaSep(n.bases.map(expr)));
1177
1205
  let b = getClassDef(n.bases[0]);
1178
1206
  if (b) {
1179
- n.baseClass = b;
1207
+ n.baseClass = b.symInfo;
1180
1208
  sym.extendsTypes = [b.symInfo.pyQName];
1181
1209
  }
1210
+ else {
1211
+ const nm = tryGetName(n.bases[0]);
1212
+ if (nm) {
1213
+ const localSym = lookupSymbol(nm);
1214
+ const globalSym = lookupGlobalSymbol(nm);
1215
+ n.baseClass = localSym || globalSym;
1216
+ if (n.baseClass)
1217
+ sym.extendsTypes = [n.baseClass.pyQName];
1218
+ }
1219
+ }
1182
1220
  }
1183
1221
  }
1184
- let body = stmts(n.body);
1222
+ const classDefs = n.body.filter(s => n.isNamespace || s.kind === "FunctionDef");
1223
+ const staticStmts = n.isNamespace ? [] : n.body.filter(s => classDefs.indexOf(s) === -1);
1224
+ let body = stmts(classDefs);
1185
1225
  nodes.push(body);
1186
- let fieldDefs = listClassFields(n)
1187
- .filter(f => f.kind == 2 /* Property */ && f.isInstance)
1188
- .map(f => {
1189
- if (!f.pyName || !f.pyRetType)
1190
- error(n, 9535, lf("field definition missing py name or ret type", f.qName));
1191
- return f;
1192
- })
1193
- .map((f) => B.mkStmt(accessAnnot(f), quote(f.pyName), typeAnnot(f.pyRetType)));
1194
- body.children = fieldDefs.concat(body.children);
1226
+ // Python classes allow arbitrary statements in their bodies, sort of like namespaces.
1227
+ // Take all of these statements and put them in a static method that we can call when
1228
+ // the class is defined.
1229
+ let generatedInitFunction = false;
1230
+ if (staticStmts.length) {
1231
+ generatedInitFunction = true;
1232
+ const staticBody = stmts(staticStmts);
1233
+ const initFun = B.mkStmt(B.mkGroup([
1234
+ B.mkText(`public static __init${n.name}() `),
1235
+ staticBody
1236
+ ]));
1237
+ body.children.unshift(initFun);
1238
+ }
1239
+ if (!n.isNamespace) {
1240
+ let isStatic = (f) => f.kind === 2 /* Property */ && !f.isInstance || f.kind === 4 /* Variable */;
1241
+ const fieldDefs = listClassFields(n, false)
1242
+ .filter(f => f.kind == 2 /* Property */ || isStatic(f))
1243
+ .map(f => {
1244
+ if (!f.pyName || !f.pyRetType)
1245
+ error(n, 9535, lf("field definition missing py name or return type", f.qName));
1246
+ return f;
1247
+ });
1248
+ const instanceFields = fieldDefs.filter(f => !isStatic(f))
1249
+ .map((f) => B.mkStmt(accessAnnot(f), quote(f.pyName), typeAnnot(f.pyRetType)));
1250
+ const staticFields = fieldDefs.filter(f => isStatic(f))
1251
+ .map((f) => B.mkStmt(accessAnnot(f), B.mkText("static "), quote(f.pyName), typeAnnot(f.pyRetType)));
1252
+ body.children = staticFields.concat(instanceFields).concat(body.children);
1253
+ }
1254
+ if (generatedInitFunction) {
1255
+ nodes = [
1256
+ B.mkStmt(B.mkGroup(nodes)),
1257
+ B.mkStmt(B.mkText(`${n.name}.__init${n.name}()`))
1258
+ ];
1259
+ }
1195
1260
  return B.mkStmt(B.mkGroup(nodes));
1196
1261
  }),
1197
1262
  Return: (n) => {
@@ -1540,7 +1605,9 @@ var pxt;
1540
1605
  error(n, 9539, lf("function '{0}' missing return type", fd.pyQName));
1541
1606
  unifyTypeOf(target, fd.pyRetType);
1542
1607
  fd.isInstance = false;
1543
- pref = ctx.currClass.isNamespace ? `export ${isConstCall ? "const" : "let"} ` : "static ";
1608
+ if (ctx.currClass.isNamespace) {
1609
+ pref = `export ${isConstCall ? "const" : "let"} `;
1610
+ }
1544
1611
  }
1545
1612
  if (value)
1546
1613
  unifyTypeOf(target, typeOf(value));
@@ -1606,6 +1673,7 @@ var pxt;
1606
1673
  }
1607
1674
  }
1608
1675
  function possibleDef(n, excludeLet = false) {
1676
+ var _a, _b;
1609
1677
  let id = n.id;
1610
1678
  let currScopeVar = lookupScopeSymbol(id);
1611
1679
  let curr = currScopeVar === null || currScopeVar === void 0 ? void 0 : currScopeVar.symbol;
@@ -1640,6 +1708,10 @@ var pxt;
1640
1708
  if (n.isdef && !excludeLet) {
1641
1709
  return B.mkGroup([B.mkText("let "), quote(id)]);
1642
1710
  }
1711
+ 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))) {
1712
+ // If this is a static variable in a class, we want the full qname
1713
+ return quote(curr.qName);
1714
+ }
1643
1715
  else
1644
1716
  return quote(id);
1645
1717
  }
@@ -1653,20 +1725,27 @@ var pxt;
1653
1725
  //return id.replace(/([a-z0-9])_([a-zA-Z0-9])/g, (f: string, x: string, y: string) => x + y.toUpperCase())
1654
1726
  }
1655
1727
  function tryGetName(e) {
1728
+ var _a;
1656
1729
  if (e.kind == "Name") {
1657
1730
  let s = e.id;
1658
1731
  let scopeV = lookupVar(s);
1659
1732
  let v = scopeV === null || scopeV === void 0 ? void 0 : scopeV.symbol;
1660
- if (v && v.expandsTo)
1661
- return v.expandsTo;
1662
- else
1663
- return s;
1733
+ if (v) {
1734
+ if (v.expandsTo)
1735
+ return v.expandsTo;
1736
+ else if (ctx.currClass && !ctx.currFun && !(scopeV === null || scopeV === void 0 ? void 0 : scopeV.modifier) && v.qName)
1737
+ return v.qName;
1738
+ }
1739
+ return s;
1664
1740
  }
1665
1741
  if (e.kind == "Attribute") {
1666
1742
  let pref = tryGetName(e.value);
1667
1743
  if (pref)
1668
1744
  return pref + "." + e.attr;
1669
1745
  }
1746
+ if (isSuper(e) && ((_a = ctx.currClass) === null || _a === void 0 ? void 0 : _a.baseClass)) {
1747
+ return ctx.currClass.baseClass.qName;
1748
+ }
1670
1749
  return undefined;
1671
1750
  }
1672
1751
  function getName(e) {
@@ -1874,6 +1953,7 @@ var pxt;
1874
1953
  return r;
1875
1954
  },
1876
1955
  Call: (n) => {
1956
+ var _a, _b, _c, _d, _e;
1877
1957
  // TODO(dz): move body out; needs seperate PR that doesn't touch content
1878
1958
  n.func.inCalledPosition = true;
1879
1959
  let nm = tryGetName(n.func);
@@ -1904,7 +1984,7 @@ var pxt;
1904
1984
  if (ctx.currClass && ctx.currClass.baseClass) {
1905
1985
  if (!n.tsType)
1906
1986
  error(n, 9543, lf("call expr missing ts type"));
1907
- unifyClass(n, n.tsType, ctx.currClass.baseClass.symInfo);
1987
+ unifyClass(n, n.tsType, ctx.currClass.baseClass);
1908
1988
  }
1909
1989
  return B.mkText("super");
1910
1990
  }
@@ -1964,6 +2044,17 @@ var pxt;
1964
2044
  unify(n, n.tsType, tpString);
1965
2045
  return B.mkInfix(B.mkText(`""`), "+", expr(n.args[0]));
1966
2046
  }
2047
+ const isSuperAttribute = n.func.kind === "Attribute" && isSuper(n.func.value);
2048
+ if (!fun && isSuperAttribute) {
2049
+ fun = lookupGlobalSymbol(nm);
2050
+ }
2051
+ const isSuperConstructor = ((_a = ctx.currFun) === null || _a === void 0 ? void 0 : _a.name) === "__init__" &&
2052
+ (fun === null || fun === void 0 ? void 0 : fun.name) === "__constructor" &&
2053
+ ((_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) &&
2054
+ isSuperAttribute;
2055
+ if (isSuperConstructor) {
2056
+ fun = lookupSymbol(((_e = (_d = ctx.currClass) === null || _d === void 0 ? void 0 : _d.baseClass) === null || _e === void 0 ? void 0 : _e.pyQName) + ".__constructor");
2057
+ }
1967
2058
  if (!fun) {
1968
2059
  error(n, 9508, pxt.U.lf("can't find called function '{0}'", nm));
1969
2060
  }
@@ -2071,7 +2162,14 @@ var pxt;
2071
2162
  ]);
2072
2163
  }
2073
2164
  }
2074
- let fn = methName ? B.mkInfix(expr(recv), ".", B.mkText(methName)) : expr(n.func);
2165
+ // TODO (riknoll): Make sure __init__ isn't being added as a symbol by the super call in the subclass. Should be converted to .__constructor
2166
+ let fn;
2167
+ if (isSuperConstructor) {
2168
+ fn = B.mkText("super");
2169
+ }
2170
+ else {
2171
+ fn = methName ? B.mkInfix(expr(recv), ".", B.mkText(methName)) : expr(n.func);
2172
+ }
2075
2173
  let nodes = [
2076
2174
  fn,
2077
2175
  B.mkText("("),