pxt-core 13.2.14 → 13.2.15

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.
@@ -119,6 +119,14 @@ var pxtc = ts.pxtc;
119
119
  (function (pxtc) {
120
120
  var Util;
121
121
  (function (Util) {
122
+ function contains(str, contains) {
123
+ if (str.length < contains.length)
124
+ return false;
125
+ if (contains.length == 0)
126
+ return true;
127
+ return str.indexOf(contains) > -1;
128
+ }
129
+ Util.contains = contains;
122
130
  function assert(cond, msg = "Assertion failed") {
123
131
  if (!cond) {
124
132
  debugger;
@@ -469,10 +477,180 @@ var pxtc = ts.pxtc;
469
477
  })(pxtc = ts.pxtc || (ts.pxtc = {}));
470
478
  })(ts || (ts = {}));
471
479
  const lf = ts.pxtc.Util.lf;
472
- /// <reference path='../localtypings/pxtarget.d.ts' />
473
- /// <reference path='../localtypings/dompurify.d.ts' />
474
- /// <reference path="commonutil.ts"/>
475
- /// <reference path="./logger.ts" />
480
+ (function (ts) {
481
+ var pxtc;
482
+ (function (pxtc) {
483
+ /**
484
+ * atob replacement
485
+ * @param s
486
+ */
487
+ pxtc.decodeBase64 = function (s) { return atob(s); };
488
+ /**
489
+ * bota replacement
490
+ * @param s
491
+ */
492
+ pxtc.encodeBase64 = function (s) { return btoa(s); };
493
+ })(pxtc = ts.pxtc || (ts.pxtc = {}));
494
+ })(ts || (ts = {}));
495
+ (function (ts) {
496
+ var pxtc;
497
+ (function (pxtc) {
498
+ var Util;
499
+ (function (Util) {
500
+ function iterMap(m, f) {
501
+ Object.keys(m).forEach(k => f(k, m[k]));
502
+ }
503
+ Util.iterMap = iterMap;
504
+ function values(m) {
505
+ return Object.keys(m || {}).map(k => m[k]);
506
+ }
507
+ Util.values = values;
508
+ function pushRange(trg, src) {
509
+ if (src)
510
+ for (let i = 0; i < src.length; ++i)
511
+ trg.push(src[i]);
512
+ }
513
+ Util.pushRange = pushRange;
514
+ // TS gets lost in type inference when this is passed an array
515
+ function concatArrayLike(arrays) {
516
+ return concat(arrays);
517
+ }
518
+ Util.concatArrayLike = concatArrayLike;
519
+ function concat(arrays) {
520
+ let r = [];
521
+ for (let i = 0; i < arrays.length; ++i) {
522
+ pushRange(r, arrays[i]);
523
+ }
524
+ return r;
525
+ }
526
+ Util.concat = concat;
527
+ function isKV(v) {
528
+ return !!v && typeof v === "object" && !Array.isArray(v);
529
+ }
530
+ function jsonMergeFrom(trg, src) {
531
+ if (!src)
532
+ return;
533
+ Object.keys(src).forEach(k => {
534
+ if (isKV(trg[k]) && isKV(src[k]))
535
+ jsonMergeFrom(trg[k], src[k]);
536
+ else
537
+ trg[k] = Util.clone(src[k]);
538
+ });
539
+ }
540
+ Util.jsonMergeFrom = jsonMergeFrom;
541
+ function jsonCopyFrom(trg, src) {
542
+ let v = Util.clone(src);
543
+ for (let k of Object.keys(src)) {
544
+ trg[k] = v[k];
545
+ }
546
+ }
547
+ Util.jsonCopyFrom = jsonCopyFrom;
548
+ // { a: { b: 1 }, c: 2} => { "a.b": 1, c: 2 }
549
+ function jsonFlatten(v) {
550
+ let res = {};
551
+ let loop = (pref, v) => {
552
+ if (v !== null && typeof v == "object") {
553
+ Util.assert(!Array.isArray(v));
554
+ if (pref)
555
+ pref += ".";
556
+ for (let k of Object.keys(v)) {
557
+ loop(pref + k, v[k]);
558
+ }
559
+ }
560
+ else {
561
+ res[pref] = v;
562
+ }
563
+ };
564
+ loop("", v);
565
+ return res;
566
+ }
567
+ Util.jsonFlatten = jsonFlatten;
568
+ function jsonUnFlatten(v) {
569
+ let res = {};
570
+ for (let k of Object.keys(v)) {
571
+ let ptr = res;
572
+ let parts = k.split(".");
573
+ for (let i = 0; i < parts.length; ++i) {
574
+ let part = parts[i];
575
+ if (i == parts.length - 1)
576
+ ptr[part] = v[k];
577
+ else {
578
+ if (typeof ptr[part] != "object")
579
+ ptr[part] = {};
580
+ ptr = ptr[part];
581
+ }
582
+ }
583
+ }
584
+ return res;
585
+ }
586
+ Util.jsonUnFlatten = jsonUnFlatten;
587
+ function strcmp(a, b) {
588
+ if (a == b)
589
+ return 0;
590
+ if (a < b)
591
+ return -1;
592
+ else
593
+ return 1;
594
+ }
595
+ Util.strcmp = strcmp;
596
+ function endsWith(str, suffix) {
597
+ if (str.length < suffix.length)
598
+ return false;
599
+ if (suffix.length == 0)
600
+ return true;
601
+ return str.slice(-suffix.length) == suffix;
602
+ }
603
+ Util.endsWith = endsWith;
604
+ function startsWith(str, prefix) {
605
+ if (str.length < prefix.length)
606
+ return false;
607
+ if (prefix.length == 0)
608
+ return true;
609
+ return str.slice(0, prefix.length) == prefix;
610
+ }
611
+ Util.startsWith = startsWith;
612
+ function toUTF8(str, cesu8) {
613
+ let res = "";
614
+ if (!str)
615
+ return res;
616
+ for (let i = 0; i < str.length; ++i) {
617
+ let code = str.charCodeAt(i);
618
+ if (code <= 0x7f)
619
+ res += str.charAt(i);
620
+ else if (code <= 0x7ff) {
621
+ res += String.fromCharCode(0xc0 | (code >> 6), 0x80 | (code & 0x3f));
622
+ }
623
+ else {
624
+ if (!cesu8 && 0xd800 <= code && code <= 0xdbff) {
625
+ let next = str.charCodeAt(++i);
626
+ if (!isNaN(next))
627
+ code = 0x10000 + ((code - 0xd800) << 10) + (next - 0xdc00);
628
+ }
629
+ if (code <= 0xffff)
630
+ res += String.fromCharCode(0xe0 | (code >> 12), 0x80 | ((code >> 6) & 0x3f), 0x80 | (code & 0x3f));
631
+ else
632
+ res += String.fromCharCode(0xf0 | (code >> 18), 0x80 | ((code >> 12) & 0x3f), 0x80 | ((code >> 6) & 0x3f), 0x80 | (code & 0x3f));
633
+ }
634
+ }
635
+ return res;
636
+ }
637
+ Util.toUTF8 = toUTF8;
638
+ function toUTF8Array(s) {
639
+ return (new TextEncoder()).encode(s);
640
+ }
641
+ Util.toUTF8Array = toUTF8Array;
642
+ })(Util = pxtc.Util || (pxtc.Util = {}));
643
+ })(pxtc = ts.pxtc || (ts.pxtc = {}));
644
+ })(ts || (ts = {}));
645
+ var pxt;
646
+ (function (pxt) {
647
+ pxt.U = pxtc.Util;
648
+ pxt.Util = pxtc.Util;
649
+ })(pxt || (pxt = {}));
650
+ /// <reference path='../../localtypings/pxtarget.d.ts' />
651
+ /// <reference path='../../localtypings/dompurify.d.ts' />
652
+ /// <reference path="../commonutil.ts"/>
653
+ /// <reference path="../logger.ts" />
476
654
  var pxt;
477
655
  (function (pxt) {
478
656
  var docs;
@@ -1617,5 +1795,1993 @@ My links
1617
1795
  docs.hydrateYouTubeEmbeds = hydrateYouTubeEmbeds;
1618
1796
  })(docs = pxt.docs || (pxt.docs = {}));
1619
1797
  })(pxt || (pxt = {}));
1620
- /// <reference path="../pxtlib/docsrender.ts"/>
1798
+ /// <reference path="../commonutil.ts"/>
1799
+ var ts;
1800
+ (function (ts) {
1801
+ var pxtc;
1802
+ (function (pxtc) {
1803
+ var BrowserImpl;
1804
+ (function (BrowserImpl) {
1805
+ function rotr(v, b) {
1806
+ return (v >>> b) | (v << (32 - b));
1807
+ }
1808
+ const sha256_k = new Uint32Array([
1809
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
1810
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
1811
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
1812
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
1813
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
1814
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
1815
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
1816
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
1817
+ ]);
1818
+ function sha256round(hs, w) {
1819
+ pxtc.Util.assert(hs.length == 8);
1820
+ pxtc.Util.assert(w.length == 64);
1821
+ for (let i = 16; i < 64; ++i) {
1822
+ let s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ (w[i - 15] >>> 3);
1823
+ let s1 = rotr(w[i - 2], 17) ^ rotr(w[i - 2], 19) ^ (w[i - 2] >>> 10);
1824
+ w[i] = (w[i - 16] + s0 + w[i - 7] + s1) | 0;
1825
+ }
1826
+ let a = hs[0];
1827
+ let b = hs[1];
1828
+ let c = hs[2];
1829
+ let d = hs[3];
1830
+ let e = hs[4];
1831
+ let f = hs[5];
1832
+ let g = hs[6];
1833
+ let h = hs[7];
1834
+ for (let i = 0; i < 64; ++i) {
1835
+ let s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
1836
+ let ch = (e & f) ^ (~e & g);
1837
+ let temp1 = (h + s1 + ch + sha256_k[i] + w[i]) | 0;
1838
+ let s0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
1839
+ let maj = (a & b) ^ (a & c) ^ (b & c);
1840
+ let temp2 = (s0 + maj) | 0;
1841
+ h = g;
1842
+ g = f;
1843
+ f = e;
1844
+ e = (d + temp1) | 0;
1845
+ d = c;
1846
+ c = b;
1847
+ b = a;
1848
+ a = (temp1 + temp2) | 0;
1849
+ }
1850
+ hs[0] += a;
1851
+ hs[1] += b;
1852
+ hs[2] += c;
1853
+ hs[3] += d;
1854
+ hs[4] += e;
1855
+ hs[5] += f;
1856
+ hs[6] += g;
1857
+ hs[7] += h;
1858
+ }
1859
+ function sha256buffer(buf) {
1860
+ let h = new Uint32Array(8);
1861
+ h[0] = 0x6a09e667;
1862
+ h[1] = 0xbb67ae85;
1863
+ h[2] = 0x3c6ef372;
1864
+ h[3] = 0xa54ff53a;
1865
+ h[4] = 0x510e527f;
1866
+ h[5] = 0x9b05688c;
1867
+ h[6] = 0x1f83d9ab;
1868
+ h[7] = 0x5be0cd19;
1869
+ let work = new Uint32Array(64);
1870
+ let chunkLen = 16 * 4;
1871
+ function addBuf(buf) {
1872
+ let end = buf.length - (chunkLen - 1);
1873
+ for (let i = 0; i < end; i += chunkLen) {
1874
+ for (let j = 0; j < 16; j++) {
1875
+ let off = (j << 2) + i;
1876
+ work[j] = (buf[off] << 24) | (buf[off + 1] << 16) | (buf[off + 2] << 8) | buf[off + 3];
1877
+ }
1878
+ sha256round(h, work);
1879
+ }
1880
+ }
1881
+ addBuf(buf);
1882
+ let padSize = 64 - (buf.length + 9) % 64;
1883
+ if (padSize == 64)
1884
+ padSize = 0;
1885
+ let endPos = buf.length - (buf.length % chunkLen);
1886
+ let padBuf = new Uint8Array((buf.length - endPos) + 1 + padSize + 8);
1887
+ let dst = 0;
1888
+ while (endPos < buf.length)
1889
+ padBuf[dst++] = buf[endPos++];
1890
+ padBuf[dst++] = 0x80;
1891
+ while (padSize-- > 0)
1892
+ padBuf[dst++] = 0x00;
1893
+ let len = buf.length * 8;
1894
+ dst = padBuf.length;
1895
+ while (len > 0) {
1896
+ padBuf[--dst] = len & 0xff;
1897
+ len >>= 8;
1898
+ }
1899
+ addBuf(padBuf);
1900
+ let res = "";
1901
+ for (let i = 0; i < h.length; ++i)
1902
+ res += ("000000000" + h[i].toString(16)).slice(-8);
1903
+ return res.toLowerCase();
1904
+ }
1905
+ BrowserImpl.sha256buffer = sha256buffer;
1906
+ })(BrowserImpl = pxtc.BrowserImpl || (pxtc.BrowserImpl = {}));
1907
+ })(pxtc = ts.pxtc || (ts.pxtc = {}));
1908
+ })(ts || (ts = {}));
1909
+ var Measurements;
1910
+ (function (Measurements) {
1911
+ Measurements.TutorialInfoDbSetAsync = "tutorial info db setAsync";
1912
+ Measurements.ReloadAppTargetVariant = "reloadAppTargetVariant";
1913
+ Measurements.Sha256Buffer = "sha256buffer";
1914
+ Measurements.WebworkerRecvHandler = "webworker recvHandler";
1915
+ Measurements.NetworkRequest = "network.request";
1916
+ })(Measurements || (Measurements = {}));
1917
+ /// <reference path="../../localtypings/pxtpackage.d.ts"/>
1918
+ /// <reference path="../commonutil.ts"/>
1919
+ var pxt;
1920
+ (function (pxt) {
1921
+ var packageUtils;
1922
+ (function (packageUtils) {
1923
+ var U = pxtc.Util;
1924
+ function getVersionProtocol(version) {
1925
+ const separator = version.indexOf(":");
1926
+ return separator < 0 ? "" : version.slice(0, separator);
1927
+ }
1928
+ packageUtils.getVersionProtocol = getVersionProtocol;
1929
+ function isVariantDisabled(config, variant) {
1930
+ return !!config && !!config.disablesVariants && config.disablesVariants.indexOf(variant) >= 0;
1931
+ }
1932
+ packageUtils.isVariantDisabled = isVariantDisabled;
1933
+ function getConfigDependencies(config, includeTests, includeCpp, isTestDependencyAvailable) {
1934
+ if (!config)
1935
+ return {};
1936
+ const dependencies = Object.assign({}, config.dependencies);
1937
+ if (includeTests) {
1938
+ for (const id of Object.keys(config.testDependencies || {})) {
1939
+ const version = config.testDependencies[id];
1940
+ if (isTestDependencyAvailable(id, version))
1941
+ dependencies[id] = version;
1942
+ }
1943
+ }
1944
+ if (includeCpp)
1945
+ U.jsonMergeFrom(dependencies, config.cppDependencies);
1946
+ return dependencies;
1947
+ }
1948
+ packageUtils.getConfigDependencies = getConfigDependencies;
1949
+ /** Evaluates fileDependencies with && taking precedence over ||, without reading target or package globals. */
1950
+ function evaluateDependencyCondition(condition, target, hasDependency, onInvalidCondition) {
1951
+ if (!condition || !condition.trim())
1952
+ return true;
1953
+ const evaluate = (term) => {
1954
+ term = term.trim();
1955
+ if (term[0] == "!")
1956
+ return !evaluate(term.slice(1));
1957
+ if (/^[\w-]+$/.test(term))
1958
+ return hasDependency(term);
1959
+ const match = /^target:(\w+)$/.exec(term);
1960
+ if (match)
1961
+ return match[1] == target.id || match[1] == target.platformid;
1962
+ onInvalidCondition(term);
1963
+ return false;
1964
+ };
1965
+ return condition.split("||").some(c => c.split("&&").every(evaluate));
1966
+ }
1967
+ packageUtils.evaluateDependencyCondition = evaluateDependencyCondition;
1968
+ function getConfigFiles(config, includeTests, target, hasDependency, onInvalidCondition) {
1969
+ const files = config.files.concat(includeTests ? config.testFiles || [] : []);
1970
+ if (!config.fileDependencies)
1971
+ return files;
1972
+ return files.filter(filename => evaluateDependencyCondition(U.lookup(config.fileDependencies, filename), target, hasDependency, condition => onInvalidCondition(condition, filename)));
1973
+ }
1974
+ packageUtils.getConfigFiles = getConfigFiles;
1975
+ })(packageUtils = pxt.packageUtils || (pxt.packageUtils = {}));
1976
+ })(pxt || (pxt = {}));
1977
+ /// <reference path="../../localtypings/pxtarget.d.ts"/>
1978
+ /// <reference path="../commonutil.ts"/>
1979
+ var pxt;
1980
+ (function (pxt) {
1981
+ /** Resolves compile defaults and a variant without modifying the supplied target. */
1982
+ function getAppTargetVariant(target, variant) {
1983
+ const result = pxt.U.cloneTargetBundle(target);
1984
+ if (variant) {
1985
+ const overrides = result.variants && result.variants[variant];
1986
+ if (!overrides)
1987
+ pxt.U.userError(pxt.U.lf("Variant '{0}' not defined in pxtarget.json", variant));
1988
+ pxt.U.jsonMergeFrom(result, overrides);
1989
+ }
1990
+ patchCompileTarget(result);
1991
+ return result;
1992
+ }
1993
+ pxt.getAppTargetVariant = getAppTargetVariant;
1994
+ function patchCompileTarget(target) {
1995
+ let comp = target.compile;
1996
+ if (!comp)
1997
+ comp = target.compile = { isNative: false, hasHex: false, switches: {} };
1998
+ if (comp.hasHex) {
1999
+ if (!comp.nativeType)
2000
+ comp.nativeType = pxtc.NATIVE_TYPE_THUMB;
2001
+ }
2002
+ if (!comp.switches)
2003
+ comp.switches = {};
2004
+ if (comp.nativeType == pxtc.NATIVE_TYPE_VM)
2005
+ comp.sourceMap = true;
2006
+ // JS ref counting currently not supported
2007
+ comp.jsRefCounting = false;
2008
+ if (!comp.useUF2 && !comp.useELF && comp.noSourceInFlash == undefined)
2009
+ comp.noSourceInFlash = true; // no point putting sources in hex to be flashed
2010
+ if (comp.utf8 === undefined)
2011
+ comp.utf8 = true;
2012
+ let cs = target.compileService;
2013
+ if (cs) {
2014
+ if (cs.yottaTarget && !cs.yottaBinary)
2015
+ cs.yottaBinary = "pxt-microbit-app-combined.hex";
2016
+ }
2017
+ }
2018
+ pxt.patchCompileTarget = patchCompileTarget;
2019
+ })(pxt || (pxt = {}));
2020
+ var ts;
2021
+ (function (ts) {
2022
+ var pxtc;
2023
+ (function (pxtc) {
2024
+ var Util;
2025
+ (function (Util) {
2026
+ function cloneTargetBundle(target) {
2027
+ target = Object.assign({}, target);
2028
+ const apiInfo = target.apiInfo;
2029
+ delete target.apiInfo;
2030
+ const bundleddirs = target.bundleddirs;
2031
+ delete target.bundleddirs;
2032
+ const bundledpkgs = target.bundledpkgs;
2033
+ delete target.bundledpkgs;
2034
+ const tutorialInfo = target.tutorialInfo;
2035
+ delete target.tutorialInfo;
2036
+ const res = Util.clone(target);
2037
+ if (apiInfo) {
2038
+ res.apiInfo = {};
2039
+ for (const key of Object.keys(apiInfo)) {
2040
+ const apis = apiInfo[key].apis;
2041
+ res.apiInfo[key] = {
2042
+ sha: apiInfo[key].sha,
2043
+ apis: {
2044
+ jres: Object.assign({}, apis.jres),
2045
+ byQName: cloneApis(apis.byQName)
2046
+ }
2047
+ };
2048
+ }
2049
+ }
2050
+ if (bundleddirs) {
2051
+ res.bundleddirs = [...bundleddirs];
2052
+ }
2053
+ if (bundledpkgs) {
2054
+ res.bundledpkgs = {};
2055
+ for (const key of Object.keys(bundledpkgs)) {
2056
+ res.bundledpkgs[key] = Object.assign({}, bundledpkgs[key]);
2057
+ }
2058
+ }
2059
+ if (tutorialInfo) {
2060
+ res.tutorialInfo = {};
2061
+ for (const key of Object.keys(tutorialInfo)) {
2062
+ const built = tutorialInfo[key];
2063
+ res.tutorialInfo[key] = {
2064
+ hash: built.hash,
2065
+ usedBlocks: Object.assign({}, built.usedBlocks),
2066
+ snippetBlocks: Object.assign({}, built.snippetBlocks),
2067
+ highlightBlocks: Object.assign({}, built.highlightBlocks),
2068
+ validateBlocks: Object.assign({}, built.validateBlocks),
2069
+ };
2070
+ }
2071
+ }
2072
+ return res;
2073
+ }
2074
+ Util.cloneTargetBundle = cloneTargetBundle;
2075
+ function cloneApis(byQName) {
2076
+ const res = {};
2077
+ for (const key of Object.keys(byQName)) {
2078
+ res[key] = cloneSymbolInfo(byQName[key]);
2079
+ }
2080
+ return res;
2081
+ }
2082
+ Util.cloneApis = cloneApis;
2083
+ function cloneSymbolInfo(sym) {
2084
+ var _a;
2085
+ return {
2086
+ // FIXME: This is a little dangerous, because we do edit the symbol attributes in some places
2087
+ // for localization. However, most of those edits are to top-level properties and only edits
2088
+ // to child objects matter so it *should* be fine
2089
+ attributes: Object.assign({}, sym.attributes),
2090
+ parameters: (_a = sym.parameters) === null || _a === void 0 ? void 0 : _a.map(cloneParameterDesc),
2091
+ extendsTypes: sym.extendsTypes ? [...sym.extendsTypes] : undefined,
2092
+ pkgs: sym.pkgs ? [...sym.pkgs] : undefined,
2093
+ combinedProperties: sym.combinedProperties ? [...sym.combinedProperties] : undefined,
2094
+ name: sym.name,
2095
+ namespace: sym.namespace,
2096
+ fileName: sym.fileName,
2097
+ kind: sym.kind,
2098
+ retType: sym.retType,
2099
+ isInstance: sym.isInstance,
2100
+ isContextual: sym.isContextual,
2101
+ qName: sym.qName,
2102
+ pkg: sym.pkg,
2103
+ snippet: sym.snippet,
2104
+ snippetName: sym.snippetName,
2105
+ snippetWithMarkers: sym.snippetWithMarkers,
2106
+ pySnippet: sym.pySnippet,
2107
+ pySnippetName: sym.pySnippetName,
2108
+ pySnippetWithMarkers: sym.pySnippetWithMarkers,
2109
+ blockFields: sym.blockFields,
2110
+ isReadOnly: sym.isReadOnly,
2111
+ pyName: sym.pyName,
2112
+ pyQName: sym.pyQName,
2113
+ snippetAddsDefinitions: sym.snippetAddsDefinitions,
2114
+ };
2115
+ }
2116
+ Util.cloneSymbolInfo = cloneSymbolInfo;
2117
+ function cloneParameterDesc(param) {
2118
+ var _a, _b;
2119
+ return {
2120
+ name: param.name,
2121
+ description: param.description,
2122
+ type: param.type,
2123
+ pyTypeString: param.pyTypeString,
2124
+ initializer: param.initializer,
2125
+ default: param.default,
2126
+ properties: (_a = param.properties) === null || _a === void 0 ? void 0 : _a.map(clonePropertyDesc),
2127
+ handlerParameters: (_b = param.handlerParameters) === null || _b === void 0 ? void 0 : _b.map(clonePropertyDesc),
2128
+ options: param.options ? Util.clone(param.options) : undefined,
2129
+ isEnum: param.isEnum
2130
+ };
2131
+ }
2132
+ function clonePropertyDesc(prop) {
2133
+ return {
2134
+ name: prop.name,
2135
+ type: prop.type
2136
+ };
2137
+ }
2138
+ })(Util = pxtc.Util || (pxtc.Util = {}));
2139
+ })(pxtc = ts.pxtc || (ts.pxtc = {}));
2140
+ })(ts || (ts = {}));
2141
+ /// <reference path="../commonutil.ts"/>
2142
+ var ts;
2143
+ (function (ts) {
2144
+ var pxtc;
2145
+ (function (pxtc) {
2146
+ var U = pxtc.Util;
2147
+ const numberAttributes = [
2148
+ "weight",
2149
+ "imageLiteral",
2150
+ "gridLiteral",
2151
+ "colorGridLiteral",
2152
+ "topblockWeight",
2153
+ "inlineInputModeLimit",
2154
+ "gridLiteralVerticalSpacing",
2155
+ "gridLiteralHorizontalSpacing",
2156
+ "gridLiteralBorderRadius",
2157
+ ];
2158
+ const booleanAttributes = [
2159
+ "advanced",
2160
+ "handlerStatement",
2161
+ "forceStatement",
2162
+ "afterOnStart",
2163
+ "optionalVariableArgs",
2164
+ "blockHidden",
2165
+ "constantShim",
2166
+ "blockCombine",
2167
+ "enumIsBitMask",
2168
+ "enumIsHash",
2169
+ "decompileIndirectFixedInstances",
2170
+ "topblock",
2171
+ "callInDebugger",
2172
+ "duplicateShadowOnDrag",
2173
+ "argsNullable",
2174
+ "compileHiddenArguments",
2175
+ "expandArgumentsInToolbox",
2176
+ "gridLiteralUseProjectPalette"
2177
+ ];
2178
+ function parseCommentString(cmt) {
2179
+ let res = {
2180
+ paramDefl: {},
2181
+ callingConvention: 0 /* ir.CallingConvention.Plain */,
2182
+ _source: cmt
2183
+ };
2184
+ let didSomething = true;
2185
+ while (didSomething) {
2186
+ didSomething = false;
2187
+ cmt = cmt.replace(/\/\/%[ \t]*([\w\.-]+)(=(("[^"\n]*")|'([^'\n]*)'|([^\s]*)))?/, (f, n, d0, d1, v0, v1, v2) => {
2188
+ let v = v0 ? JSON.parse(v0) : (d0 ? (v0 || v1 || v2) : "true");
2189
+ if (!v)
2190
+ v = "";
2191
+ if (U.startsWith(n, "block.loc.")) {
2192
+ if (!res.locs)
2193
+ res.locs = {};
2194
+ res.locs[n.slice("block.loc.".length).toLowerCase() + "|block"] = v;
2195
+ }
2196
+ else if (U.startsWith(n, "jsdoc.loc.")) {
2197
+ if (!res.locs)
2198
+ res.locs = {};
2199
+ res.locs[n.slice("jsdoc.loc.".length).toLowerCase() + "|jsdoc"] = v;
2200
+ }
2201
+ else if (U.startsWith(n, "ariaLabel.loc.")) {
2202
+ if (!res.locs)
2203
+ res.locs = {};
2204
+ res.locs[n.slice("ariaLabel.loc.".length).toLowerCase() + "|ariaLabel"] = v;
2205
+ }
2206
+ else if (U.contains(n, ".loc.")) {
2207
+ if (!res.locs)
2208
+ res.locs = {};
2209
+ const p = n.slice(0, n.indexOf('.loc.'));
2210
+ const l = n.slice(n.indexOf('.loc.') + '.loc.'.length);
2211
+ res.locs[l + "|param|" + p] = v;
2212
+ }
2213
+ else if (U.endsWith(n, ".defl")) {
2214
+ if (v.indexOf(" ") > -1) {
2215
+ res.paramDefl[n.slice(0, n.length - 5)] = `"${v}"`;
2216
+ }
2217
+ else {
2218
+ res.paramDefl[n.slice(0, n.length - 5)] = v;
2219
+ }
2220
+ if (!res.explicitDefaults)
2221
+ res.explicitDefaults = [];
2222
+ res.explicitDefaults.push(n.slice(0, n.length - 5));
2223
+ }
2224
+ else if (U.endsWith(n, ".shadow")) {
2225
+ if (!res._shadowOverrides)
2226
+ res._shadowOverrides = {};
2227
+ res._shadowOverrides[n.slice(0, n.length - 7)] = v;
2228
+ }
2229
+ else if (U.endsWith(n, ".snippet")) {
2230
+ if (!res.paramSnippets)
2231
+ res.paramSnippets = {};
2232
+ const paramName = n.slice(0, n.length - 8);
2233
+ if (!res.paramSnippets[paramName])
2234
+ res.paramSnippets[paramName] = {};
2235
+ res.paramSnippets[paramName].ts = v;
2236
+ }
2237
+ else if (U.endsWith(n, ".pySnippet")) {
2238
+ if (!res.paramSnippets)
2239
+ res.paramSnippets = {};
2240
+ const paramName = n.slice(0, n.length - 10);
2241
+ if (!res.paramSnippets[paramName])
2242
+ res.paramSnippets[paramName] = {};
2243
+ res.paramSnippets[paramName].python = v;
2244
+ }
2245
+ else if (U.endsWith(n, ".fieldEditor")) {
2246
+ if (!res.paramFieldEditor)
2247
+ res.paramFieldEditor = {};
2248
+ res.paramFieldEditor[n.slice(0, n.length - 12)] = v;
2249
+ }
2250
+ else if (U.contains(n, ".fieldOptions.")) {
2251
+ if (!res.paramFieldEditorOptions)
2252
+ res.paramFieldEditorOptions = {};
2253
+ const field = n.slice(0, n.indexOf('.fieldOptions.'));
2254
+ const key = n.slice(n.indexOf('.fieldOptions.') + 14, n.length);
2255
+ if (!res.paramFieldEditorOptions[field])
2256
+ res.paramFieldEditorOptions[field] = {};
2257
+ res.paramFieldEditorOptions[field][key] = v;
2258
+ }
2259
+ else if (U.contains(n, ".shadowOptions.")) {
2260
+ if (!res.paramShadowOptions)
2261
+ res.paramShadowOptions = {};
2262
+ const field = n.slice(0, n.indexOf('.shadowOptions.'));
2263
+ const key = n.slice(n.indexOf('.shadowOptions.') + 15, n.length);
2264
+ if (!res.paramShadowOptions[field])
2265
+ res.paramShadowOptions[field] = {};
2266
+ res.paramShadowOptions[field][key] = v;
2267
+ }
2268
+ else if (U.endsWith(n, ".label")) {
2269
+ if (!res.paramLabels)
2270
+ res.paramLabels = {};
2271
+ res.paramLabels[n.slice(0, n.length - 6)] = v;
2272
+ }
2273
+ else if (U.endsWith(n, ".min")) {
2274
+ if (!res.paramMin)
2275
+ res.paramMin = {};
2276
+ res.paramMin[n.slice(0, n.length - 4)] = v;
2277
+ }
2278
+ else if (U.endsWith(n, ".max")) {
2279
+ if (!res.paramMax)
2280
+ res.paramMax = {};
2281
+ res.paramMax[n.slice(0, n.length - 4)] = v;
2282
+ }
2283
+ else {
2284
+ res[n] = v;
2285
+ }
2286
+ didSomething = true;
2287
+ return "//% ";
2288
+ });
2289
+ }
2290
+ for (let n of numberAttributes) {
2291
+ if (typeof res[n] == "string")
2292
+ res[n] = parseInt(res[n]);
2293
+ }
2294
+ for (let n of booleanAttributes) {
2295
+ if (typeof res[n] == "string")
2296
+ res[n] = res[n] == 'true' || res[n] == '1' ? true : false;
2297
+ }
2298
+ if (res.trackArgs) {
2299
+ res.trackArgs = res.trackArgs.split(/[ ,]+/).map(s => parseInt(s) || 0);
2300
+ }
2301
+ if (res.enumInitialMembers) {
2302
+ res.enumInitialMembers = res.enumInitialMembers.split(/[ ,]+/);
2303
+ }
2304
+ if (res.blockExternalInputs && !res.inlineInputMode) {
2305
+ res.inlineInputMode = "external";
2306
+ }
2307
+ res.paramHelp = {};
2308
+ res.jsDoc = "";
2309
+ cmt = cmt.replace(/\/\*\*([^]*?)\*\//g, (full, doccmt) => {
2310
+ doccmt = doccmt.replace(/\n\s*(\*\s*)?/g, "\n");
2311
+ doccmt = doccmt.replace(/^\s*@param\s+(\w+)\s+(.*)$/mg, (full, name, desc) => {
2312
+ res.paramHelp[name] = desc;
2313
+ if (!res.paramDefl[name]) {
2314
+ // these don't add to res.explicitDefaults
2315
+ let m = /\beg\.?:\s*(.+)/.exec(desc);
2316
+ if (m && m[1]) {
2317
+ let defaultValue = /(?:"([^"]*)")|(?:'([^']*)')|(?:([^\s,]+))/g.exec(m[1]);
2318
+ if (defaultValue) {
2319
+ let val = defaultValue[1] || defaultValue[2] || defaultValue[3];
2320
+ if (!val)
2321
+ val = "";
2322
+ // If there are spaces in the value, it means the value was surrounded with quotes, so add them back
2323
+ if (val.indexOf(" ") > -1) {
2324
+ res.paramDefl[name] = `"${val}"`;
2325
+ }
2326
+ else {
2327
+ res.paramDefl[name] = val;
2328
+ }
2329
+ }
2330
+ }
2331
+ }
2332
+ return "";
2333
+ });
2334
+ res.jsDoc += doccmt;
2335
+ return "";
2336
+ });
2337
+ res.jsDoc = res.jsDoc.trim();
2338
+ if (res.async)
2339
+ res.callingConvention = 1 /* ir.CallingConvention.Async */;
2340
+ if (res.promise)
2341
+ res.callingConvention = 2 /* ir.CallingConvention.Promise */;
2342
+ if (res.jres)
2343
+ res.whenUsed = true;
2344
+ if (res.subcategories) {
2345
+ try {
2346
+ res.subcategories = JSON.parse(res.subcategories);
2347
+ }
2348
+ catch (e) {
2349
+ res.subcategories = undefined;
2350
+ }
2351
+ }
2352
+ if (res.groups) {
2353
+ try {
2354
+ res.groups = JSON.parse(res.groups);
2355
+ }
2356
+ catch (e) {
2357
+ res.groups = undefined;
2358
+ }
2359
+ }
2360
+ if (res.groupIcons) {
2361
+ try {
2362
+ res.groupIcons = JSON.parse(res.groupIcons);
2363
+ }
2364
+ catch (e) {
2365
+ res.groupIcons = undefined;
2366
+ }
2367
+ }
2368
+ if (res.groupHelp) {
2369
+ try {
2370
+ res.groupHelp = JSON.parse(res.groupHelp);
2371
+ }
2372
+ catch (e) {
2373
+ res.groupHelp = undefined;
2374
+ }
2375
+ }
2376
+ updateBlockDef(res);
2377
+ return res;
2378
+ }
2379
+ pxtc.parseCommentString = parseCommentString;
2380
+ function updateBlockDef(attrs) {
2381
+ if (attrs.block) {
2382
+ const parts = attrs.block.split("||");
2383
+ attrs._def = applyOverrides(parseBlockDefinition(parts[0]));
2384
+ if (!attrs._def)
2385
+ pxt.debug("Unable to parse block def for id: " + attrs.blockId);
2386
+ if (parts[1])
2387
+ attrs._expandedDef = applyOverrides(parseBlockDefinition(parts[1]));
2388
+ if (parts[1] && !attrs._expandedDef)
2389
+ pxt.debug("Unable to parse expanded block def for id: " + attrs.blockId);
2390
+ }
2391
+ function applyOverrides(def) {
2392
+ if (attrs._shadowOverrides) {
2393
+ def.parameters.forEach(p => {
2394
+ const shadow = attrs._shadowOverrides[p.name];
2395
+ if (shadow === "unset")
2396
+ delete p.shadowBlockId;
2397
+ else if (shadow != null)
2398
+ p.shadowBlockId = shadow;
2399
+ });
2400
+ }
2401
+ return def;
2402
+ }
2403
+ }
2404
+ pxtc.updateBlockDef = updateBlockDef;
2405
+ function parseBlockDefinition(def) {
2406
+ const tokens = [];
2407
+ let currentWord;
2408
+ let strIndex = 0;
2409
+ for (; strIndex < def.length; strIndex++) {
2410
+ const char = def[strIndex];
2411
+ const restoreIndex = strIndex;
2412
+ let newToken;
2413
+ switch (char) {
2414
+ case "*":
2415
+ case "_":
2416
+ const tk = eatToken(c => c == char);
2417
+ const offset = char === "_" ? 2 : 0;
2418
+ if (tk.length === 1)
2419
+ newToken = { kind: 1 /* TokenKind.SingleAsterisk */ << offset, content: tk };
2420
+ else if (tk.length === 2)
2421
+ newToken = { kind: 2 /* TokenKind.DoubleAsterisk */ << offset, content: tk };
2422
+ else if (tk.length === 3)
2423
+ newToken = { kind: 3 /* TokenKind.TripleAsterisk */ << offset, content: tk };
2424
+ else
2425
+ strIndex = restoreIndex; // error: no more than three style marks
2426
+ break;
2427
+ case "`":
2428
+ const image = eatEnclosure("`");
2429
+ if (image === undefined) {
2430
+ strIndex = restoreIndex; // error: not terminated
2431
+ break;
2432
+ }
2433
+ newToken = { kind: 256 /* TokenKind.Image */, content: image };
2434
+ break;
2435
+ case "|":
2436
+ newToken = { kind: 32 /* TokenKind.Pipe */ };
2437
+ break;
2438
+ case "\\":
2439
+ if (strIndex < (def.length - 1))
2440
+ newToken = { kind: 16 /* TokenKind.Escape */, content: def[1 + (strIndex++)] };
2441
+ break;
2442
+ case "[":
2443
+ const contentText = eatEnclosure("]");
2444
+ if (contentText !== undefined && def[strIndex++ + 1] === "(") {
2445
+ const contentClass = eatEnclosure(")");
2446
+ if (contentClass !== undefined) {
2447
+ newToken = { kind: 512 /* TokenKind.TaggedText */, content: contentText, type: contentClass };
2448
+ break;
2449
+ }
2450
+ }
2451
+ strIndex = restoreIndex; // error: format should be [text](class)
2452
+ break;
2453
+ case "$":
2454
+ case "%":
2455
+ const param = eatToken(c => /[a-zA-Z0-9_=]/.test(c), true).split("=");
2456
+ if (param.length > 2) {
2457
+ strIndex = restoreIndex; // error: too many equals signs
2458
+ break;
2459
+ }
2460
+ let varName;
2461
+ if (def[strIndex + 1] === "(") {
2462
+ const oldIndex = strIndex;
2463
+ ++strIndex;
2464
+ varName = eatEnclosure(")");
2465
+ if (!varName)
2466
+ strIndex = oldIndex;
2467
+ }
2468
+ newToken = { kind: (char === "$") ? 1024 /* TokenKind.ParamRef */ : 64 /* TokenKind.Parameter */, content: param[0], type: param[1], name: varName };
2469
+ break;
2470
+ }
2471
+ if (newToken) {
2472
+ if (currentWord)
2473
+ tokens.push({ kind: 128 /* TokenKind.Word */, content: currentWord });
2474
+ currentWord = undefined;
2475
+ tokens.push(newToken);
2476
+ }
2477
+ else if (!currentWord) {
2478
+ currentWord = char;
2479
+ }
2480
+ else {
2481
+ currentWord += char;
2482
+ }
2483
+ }
2484
+ if (currentWord)
2485
+ tokens.push({ kind: 128 /* TokenKind.Word */, content: currentWord });
2486
+ const parts = [];
2487
+ const parameters = [];
2488
+ let stack = [];
2489
+ let open = 0;
2490
+ let currentLabel = "";
2491
+ let labelStack = [];
2492
+ for (let i = 0; i < tokens.length; i++) {
2493
+ const token = tokens[i].kind;
2494
+ const top = stack[stack.length - 1];
2495
+ if (token & 15 /* TokenKind.StyleMarks */) {
2496
+ pushCurrentLabel(tokens[i].content);
2497
+ if (token & open) {
2498
+ if (top & token) {
2499
+ stack.pop();
2500
+ open ^= token;
2501
+ // Handle triple tokens
2502
+ const remainder = (top & open) | (token & open);
2503
+ if (remainder) {
2504
+ stack.push(remainder);
2505
+ }
2506
+ }
2507
+ else {
2508
+ // We encountered a mismatched mark, so clear previous styles
2509
+ collapseLabels();
2510
+ }
2511
+ }
2512
+ else {
2513
+ open |= token;
2514
+ stack.push(token);
2515
+ }
2516
+ }
2517
+ else if (token & 144 /* TokenKind.Text */) {
2518
+ currentLabel += tokens[i].content;
2519
+ }
2520
+ else if (token & 1120 /* TokenKind.Unstylable */) {
2521
+ pushLabels();
2522
+ }
2523
+ if (token == 64 /* TokenKind.Parameter */) {
2524
+ const param = { kind: "param", name: tokens[i].content, shadowBlockId: tokens[i].type, ref: false };
2525
+ if (tokens[i].name)
2526
+ param.varName = tokens[i].name;
2527
+ parts.push(param);
2528
+ parameters.push(param);
2529
+ }
2530
+ else if (token == 1024 /* TokenKind.ParamRef */) {
2531
+ const param = { kind: "param", name: tokens[i].content, shadowBlockId: tokens[i].type, ref: true };
2532
+ if (tokens[i].name)
2533
+ param.varName = tokens[i].name;
2534
+ parts.push(param);
2535
+ parameters.push(param);
2536
+ }
2537
+ else if (token == 256 /* TokenKind.Image */) {
2538
+ pushCurrentLabel();
2539
+ labelStack.push({ kind: "image", uri: tokens[i].content });
2540
+ }
2541
+ else if (token == 512 /* TokenKind.TaggedText */) {
2542
+ pushCurrentLabel();
2543
+ labelStack.push({ kind: "label", text: tokens[i].content, cssClass: tokens[i].type });
2544
+ }
2545
+ else if (token == 32 /* TokenKind.Pipe */) {
2546
+ parts.push({ kind: "break" });
2547
+ }
2548
+ }
2549
+ pushLabels();
2550
+ return { parts, parameters };
2551
+ function eatToken(pred, skipCurrent = false) {
2552
+ let current = "";
2553
+ if (skipCurrent)
2554
+ strIndex++;
2555
+ while (strIndex < def.length && pred(def[strIndex])) {
2556
+ current += def[strIndex];
2557
+ ++strIndex;
2558
+ }
2559
+ if (current)
2560
+ strIndex--;
2561
+ return current;
2562
+ }
2563
+ function eatEnclosure(endMark) {
2564
+ const content = eatToken(c => c !== endMark, true);
2565
+ if (def[strIndex + 1] !== endMark)
2566
+ return undefined;
2567
+ ++strIndex;
2568
+ return content;
2569
+ }
2570
+ function collapseLabels() {
2571
+ let combined = "";
2572
+ let newStack = [];
2573
+ for (const item of labelStack) {
2574
+ if (isBlockPart(item)) {
2575
+ newStack.push({
2576
+ content: combined,
2577
+ styles: 0
2578
+ });
2579
+ newStack.push(item);
2580
+ combined = "";
2581
+ }
2582
+ else {
2583
+ combined += item.content;
2584
+ if (item.endingToken) {
2585
+ combined += item.endingToken;
2586
+ }
2587
+ }
2588
+ }
2589
+ labelStack = newStack;
2590
+ if (combined) {
2591
+ labelStack.push({
2592
+ content: combined,
2593
+ styles: 0
2594
+ });
2595
+ }
2596
+ // Clear the style state as well
2597
+ stack = [];
2598
+ open = 0;
2599
+ }
2600
+ function pushLabels() {
2601
+ pushCurrentLabel();
2602
+ if (open) {
2603
+ collapseLabels();
2604
+ }
2605
+ while (labelStack.length) {
2606
+ const label = labelStack.shift();
2607
+ if (isBlockPart(label)) {
2608
+ parts.push(label);
2609
+ }
2610
+ else {
2611
+ if (!label.content)
2612
+ continue;
2613
+ const styles = [];
2614
+ if (label.styles & 10 /* TokenKind.Bold */)
2615
+ styles.push("bold");
2616
+ if (label.styles & 5 /* TokenKind.Italics */)
2617
+ styles.push("italics");
2618
+ parts.push({ kind: "label", text: label.content, style: styles });
2619
+ }
2620
+ }
2621
+ }
2622
+ function pushCurrentLabel(endingToken) {
2623
+ labelStack.push({
2624
+ content: currentLabel,
2625
+ styles: open,
2626
+ endingToken
2627
+ });
2628
+ currentLabel = "";
2629
+ }
2630
+ }
2631
+ pxtc.parseBlockDefinition = parseBlockDefinition;
2632
+ function isBlockPart(p) {
2633
+ return !!(p.kind);
2634
+ }
2635
+ })(pxtc = ts.pxtc || (ts.pxtc = {}));
2636
+ })(ts || (ts = {}));
2637
+ var pxt;
2638
+ (function (pxt) {
2639
+ var github;
2640
+ (function (github) {
2641
+ // parse https://github.com/[company]/[project](/filepath)(#tag)
2642
+ function parseRepoId(repo) {
2643
+ if (!repo)
2644
+ return undefined;
2645
+ // clean out whitespaces
2646
+ repo = repo.trim();
2647
+ // trim trailing /
2648
+ repo = repo.replace(/\/$/, '');
2649
+ // convert github pages into github repo
2650
+ const mgh = /^https:\/\/([^./#]+)\.github\.io\/([^/#]+)\/?$/i.exec(repo);
2651
+ if (mgh)
2652
+ repo = `github:${mgh[1]}/${mgh[2]}`;
2653
+ repo = repo.replace(/^github:/i, "");
2654
+ repo = repo.replace(/^https:\/\/github\.com\//i, "");
2655
+ repo = repo.replace(/\.git\b/i, "");
2656
+ const m = /^([^#\/:]+)\/([^#\/:]+)(\/([^#]+))?(#([^\/:]*))?$/.exec(repo);
2657
+ if (!m)
2658
+ return undefined;
2659
+ const owner = m[1];
2660
+ const project = m[2];
2661
+ let fileName = m[4];
2662
+ const tag = m[6];
2663
+ const treeM = fileName && /^tree\/([^\/]+\/)/.exec(fileName);
2664
+ if (treeM) {
2665
+ // https://github.com/pelikhan/mono-demo/tree/master/demo2
2666
+ fileName = fileName.slice(treeM[0].length);
2667
+ // branch info?
2668
+ }
2669
+ return {
2670
+ owner,
2671
+ project,
2672
+ slug: join(owner, project),
2673
+ fullName: join(owner, project, fileName),
2674
+ tag,
2675
+ fileName
2676
+ };
2677
+ }
2678
+ github.parseRepoId = parseRepoId;
2679
+ function stringifyRepo(p, ignoreCase = false) {
2680
+ return p ? "github:" + (ignoreCase ? p.fullName : p.fullName.toLowerCase()) + (p.tag ? `#${p.tag}` : '') : undefined;
2681
+ }
2682
+ github.stringifyRepo = stringifyRepo;
2683
+ function join(...parts) {
2684
+ return parts.filter(p => !!p).join('/');
2685
+ }
2686
+ github.join = join;
2687
+ })(github = pxt.github || (pxt.github = {}));
2688
+ })(pxt || (pxt = {}));
2689
+ /// <reference path="../../localtypings/pxtarget.d.ts"/>
2690
+ /// <reference path="../commonutil.ts"/>
2691
+ /// <reference path="sha256.ts"/>
2692
+ /// <reference path="../constants.ts"/>
2693
+ /// <reference path="packageutils.ts"/>
2694
+ /// <reference path="targetutils.ts"/>
2695
+ /// <reference path="commentattrs.ts"/>
2696
+ /// <reference path="githubid.ts"/>
2697
+ var ts;
2698
+ (function (ts) {
2699
+ var pxtc;
2700
+ (function (pxtc) {
2701
+ pxtc.NATIVE_TYPE_THUMB = "thumb";
2702
+ pxtc.NATIVE_TYPE_VM = "vm";
2703
+ function emptyExtInfo(compileService) {
2704
+ let cs = compileService;
2705
+ if (!cs)
2706
+ cs = {};
2707
+ const pio = !!cs.platformioIni;
2708
+ const docker = cs.buildEngine == "dockermake" || cs.buildEngine == "dockercross" || cs.buildEngine == "dockerespidf";
2709
+ const r = {
2710
+ functions: [],
2711
+ generatedFiles: {},
2712
+ extensionFiles: {},
2713
+ sha: "",
2714
+ compileData: "",
2715
+ shimsDTS: "",
2716
+ enumsDTS: "",
2717
+ onlyPublic: true
2718
+ };
2719
+ if (pio)
2720
+ r.platformio = { dependencies: {} };
2721
+ else if (docker)
2722
+ r.npmDependencies = {};
2723
+ else
2724
+ r.yotta = { config: {}, dependencies: {} };
2725
+ return r;
2726
+ }
2727
+ pxtc.emptyExtInfo = emptyExtInfo;
2728
+ })(pxtc = ts.pxtc || (ts.pxtc = {}));
2729
+ })(ts || (ts = {}));
2730
+ var pxt;
2731
+ (function (pxt) {
2732
+ var cpp;
2733
+ (function (cpp) {
2734
+ var U = pxtc.Util;
2735
+ const lf = U.lf;
2736
+ const vmKeepFunctions = {
2737
+ "pxt::mkAction": 1,
2738
+ "pxt::dumpPerfCounters": 1,
2739
+ "pxt::deepSleep": 1,
2740
+ "pxt::getConfig": 1,
2741
+ "pxtrt::mkMap": 1,
2742
+ "pxtrt::mapSet": 1,
2743
+ "pxtrt::stclo": 1,
2744
+ "pxtrt::mklocRef": 1,
2745
+ "pxtrt::stlocRef": 1,
2746
+ "pxtrt::ldlocRef": 1,
2747
+ "pxtrt::panic": 1,
2748
+ };
2749
+ function nsWriter(nskw = "namespace") {
2750
+ let text = "";
2751
+ let currNs = "";
2752
+ let setNs = (ns, over = "") => {
2753
+ if (currNs == ns)
2754
+ return;
2755
+ if (currNs)
2756
+ text += "}\n";
2757
+ if (ns)
2758
+ text += over || (nskw + " " + ns + " {\n");
2759
+ currNs = ns;
2760
+ };
2761
+ let indent = " ";
2762
+ return {
2763
+ setNs,
2764
+ clear: () => {
2765
+ text = "";
2766
+ currNs = "";
2767
+ },
2768
+ write: (s) => {
2769
+ if (!s.trim())
2770
+ text += "\n";
2771
+ else {
2772
+ s = s.trim()
2773
+ .replace(/^\s*/mg, indent)
2774
+ .replace(/^(\s*)\*/mg, (f, s) => s + " *");
2775
+ text += s + "\n";
2776
+ }
2777
+ },
2778
+ incrIndent: () => {
2779
+ indent += " ";
2780
+ },
2781
+ decrIndent: () => {
2782
+ indent = indent.slice(4);
2783
+ },
2784
+ finish: () => {
2785
+ setNs("");
2786
+ return text;
2787
+ }
2788
+ };
2789
+ }
2790
+ cpp.nsWriter = nsWriter;
2791
+ function parseCppInt(v) {
2792
+ if (!v)
2793
+ return null;
2794
+ v = v.trim();
2795
+ let mm = /^\((.*)\)/.exec(v);
2796
+ if (mm)
2797
+ v = mm[1];
2798
+ if (/^-?(\d+|0[xX][0-9a-fA-F]+)$/.test(v))
2799
+ return parseInt(v);
2800
+ return null;
2801
+ }
2802
+ cpp.parseCppInt = parseCppInt;
2803
+ class PkgConflictError extends Error {
2804
+ constructor(msg) {
2805
+ super(msg);
2806
+ this.isUserError = true;
2807
+ this.message = msg;
2808
+ }
2809
+ }
2810
+ cpp.PkgConflictError = PkgConflictError;
2811
+ /**
2812
+ * Generates native extension files from pxt.json and project files, with dependencies
2813
+ * under pxt_modules/<directory>/. Dependencies resolve by directory, pxt.json name,
2814
+ * or their prefix before "---".
2815
+ * The target must not have variant overrides applied.
2816
+ * @example getExtensionInfo({ "pxt.json": config, "main.cpp": source }, target, "v2", host)
2817
+ */
2818
+ function getExtensionInfo(files, target, variant, host) {
2819
+ const appTarget = pxt.getAppTargetVariant(target, variant);
2820
+ const constsName = "dal.d.ts";
2821
+ let sourcePath = "/source/";
2822
+ let disabledDeps = "";
2823
+ const packages = {};
2824
+ const runtimePackages = {};
2825
+ const packagePaths = Object.create(null);
2826
+ for (const path of Object.keys(files)) {
2827
+ const match = /^pxt_modules\/([^/]+)\/pxt\.json$/.exec(path);
2828
+ if (!match)
2829
+ continue;
2830
+ const config = JSON.parse(files[path]);
2831
+ const directory = path.slice(0, -"pxt.json".length);
2832
+ for (const id of [match[1], config.name]) {
2833
+ if (!id)
2834
+ continue;
2835
+ for (const alias of [id, id.replace(/---.*/, "")]) {
2836
+ const paths = packagePaths[alias] || (packagePaths[alias] = []);
2837
+ if (paths.indexOf(directory) < 0)
2838
+ paths.push(directory);
2839
+ }
2840
+ }
2841
+ }
2842
+ const resolvePath = (id) => {
2843
+ if (id == "this")
2844
+ return "";
2845
+ const path = "pxt_modules/" + id + "/";
2846
+ if (files[path + "pxt.json"] != null)
2847
+ return path;
2848
+ const paths = packagePaths[id];
2849
+ if (paths && paths.length > 1)
2850
+ U.userError(`extension ${id} matches multiple directories: ${paths.join(", ")}`);
2851
+ return paths && paths[0];
2852
+ };
2853
+ const readFile = (pkg, name) => files[pkg.path + name];
2854
+ const dependencies = (pkg) => pxt.packageUtils.getConfigDependencies(pkg.config, pkg.id == "this", false, id => resolvePath(id) != null);
2855
+ const visit = (id, version, runtime) => {
2856
+ const path = resolvePath(id);
2857
+ if (path == null)
2858
+ U.userError(`extension ${id} is missing pxt.json`);
2859
+ if (runtimePackages[path] || (!runtime && packages[path]))
2860
+ return;
2861
+ if (runtime)
2862
+ runtimePackages[path] = true;
2863
+ let pkg = packages[path];
2864
+ if (!pkg) {
2865
+ const configText = files[path + "pxt.json"];
2866
+ if (!configText)
2867
+ U.userError(`extension ${id} is missing pxt.json`);
2868
+ const config = JSON.parse(configText);
2869
+ if (!config.dependencies || !Array.isArray(config.files))
2870
+ U.userError(`Invalid pxt.json in extension ${id}`);
2871
+ const packageId = path ? path.slice("pxt_modules/".length, -1) : "this";
2872
+ pkg = packages[path] = { id: packageId, path, config, files: [], version };
2873
+ }
2874
+ const deps = dependencies(pkg);
2875
+ for (const dep of Object.keys(deps))
2876
+ visit(dep, deps[dep], runtime);
2877
+ for (const dep of Object.keys(pkg.config.cppDependencies || {}))
2878
+ visit(dep, pkg.config.cppDependencies[dep], false);
2879
+ };
2880
+ visit("this", "file:.", true);
2881
+ const mainPkg = packages[""];
2882
+ const mainPkgDeps = U.values(packages).sort((a, b) => a.id == b.id ? 0 : a.id == "this" ? 1 : b.id == "this" ? -1 : U.strcmp(a.id, b.id));
2883
+ for (const pkg of mainPkgDeps) {
2884
+ pkg.files = pxt.packageUtils.getConfigFiles(pkg.config, pkg == mainPkg, appTarget, id => !!runtimePackages[resolvePath(id)], condition => host.logger.log(`invalid dependency expression: ${condition} in ${pkg.id}`));
2885
+ }
2886
+ const mainDeps = [];
2887
+ const disablesVariant = (pkg) => pxt.packageUtils.isVariantDisabled(pkg.config, variant);
2888
+ for (let pkg of mainPkgDeps) {
2889
+ if (disablesVariant(pkg) ||
2890
+ Object.keys(dependencies(pkg)).some(id => disablesVariant(packages[resolvePath(id)]))) {
2891
+ if (disabledDeps)
2892
+ disabledDeps += ", ";
2893
+ disabledDeps += pkg.id;
2894
+ host.logger.debug(`disable variant ${variant} due to ${pkg.id}`);
2895
+ continue;
2896
+ }
2897
+ mainDeps.push(pkg);
2898
+ }
2899
+ let compileService = appTarget.compileService;
2900
+ if (!compileService)
2901
+ compileService = {
2902
+ gittag: "none",
2903
+ serviceId: "nocompile"
2904
+ };
2905
+ compileService = U.clone(compileService);
2906
+ const compile = appTarget.compile;
2907
+ if (mainPkgDeps.some(pkg => pkg.config.utf8))
2908
+ compile.utf8 = true;
2909
+ const key = JSON.stringify({
2910
+ variant: variant || "",
2911
+ targetId: appTarget.id,
2912
+ compile,
2913
+ compileService,
2914
+ mainConfig: mainPkg.config,
2915
+ packages: mainDeps.map(pkg => ({
2916
+ id: pkg.id,
2917
+ config: pkg.config,
2918
+ version: pkg.version,
2919
+ files: pkg.files.filter(fn => fn == constsName ||
2920
+ /\.(h|cpp|c|S|s|mk)$/.test(fn) ||
2921
+ ["Makefile", "sdkconfig.defaults", "CMakeLists.txt"].indexOf(fn) >= 0)
2922
+ .map(fn => [fn, readFile(pkg, fn)])
2923
+ }))
2924
+ });
2925
+ const prevInfo = host.cache[key];
2926
+ if (prevInfo) {
2927
+ host.logger.debug("Using cached extinfo");
2928
+ const result = U.clone(prevInfo);
2929
+ result.disabledDeps = disabledDeps;
2930
+ return result;
2931
+ }
2932
+ host.logger.debug("Generating new extinfo");
2933
+ const res = pxtc.emptyExtInfo(compileService);
2934
+ res.disabledDeps = disabledDeps;
2935
+ const isPlatformio = !!compileService.platformioIni;
2936
+ const isCodal = compileService.buildEngine == "codal" || compileService.buildEngine == "dockercodal";
2937
+ const isDockerMake = compileService.buildEngine == "dockermake" || compileService.buildEngine == "dockercross";
2938
+ const isEspIdf = compileService.buildEngine == "dockerespidf";
2939
+ const isYotta = !isPlatformio && !isCodal && !isDockerMake && !isEspIdf;
2940
+ const isVM = compile.nativeType == pxtc.NATIVE_TYPE_VM;
2941
+ if (isPlatformio)
2942
+ sourcePath = "/src/";
2943
+ else if (isCodal || isDockerMake)
2944
+ sourcePath = "/pxtapp/";
2945
+ else if (isEspIdf)
2946
+ sourcePath = "/main/";
2947
+ let pxtConfig = "// Configuration defines\n";
2948
+ let pointersInc = "\nPXT_SHIMS_BEGIN\n";
2949
+ let pointerIncPre = "";
2950
+ let abiInc = "";
2951
+ let includesInc = `#include "pxt.h"\n`;
2952
+ let thisErrors = "";
2953
+ let dTsNamespace = "";
2954
+ let err = (s) => thisErrors += ` ${fileName}(${lineNo}): ${s}\n`;
2955
+ let lineNo = 0;
2956
+ let fileName = "";
2957
+ let protos = nsWriter("namespace");
2958
+ let shimsDTS = nsWriter("declare namespace");
2959
+ let enumsDTS = nsWriter("declare namespace");
2960
+ let allErrors = "";
2961
+ let knownEnums = {};
2962
+ let vmVisitedFunctions = {};
2963
+ const enumVals = {
2964
+ "true": "1",
2965
+ "false": "0",
2966
+ "null": "0",
2967
+ "NULL": "0",
2968
+ };
2969
+ // we sometimes append _ to C++ names to avoid name clashes
2970
+ function toJs(name) {
2971
+ return name.trim().replace(/[\_\*]$/, "");
2972
+ }
2973
+ for (const pkg of mainDeps) {
2974
+ if (pkg.files.indexOf(constsName) >= 0) {
2975
+ const src = readFile(pkg, constsName);
2976
+ pxt.Util.assert(!!src, `${constsName} not found in ${pkg.id}`);
2977
+ src.split(/\r?\n/).forEach(ln => {
2978
+ let m = /^\s*(\w+) = (.*),/.exec(ln);
2979
+ if (m) {
2980
+ enumVals[m[1]] = m[2];
2981
+ }
2982
+ });
2983
+ }
2984
+ for (const fn of pkg.files) {
2985
+ if (["Makefile", "sdkconfig.defaults", "CMakeLists.txt"].indexOf(fn) >= 0 || U.endsWith(fn, ".mk")) {
2986
+ res.generatedFiles["/" + fn] = readFile(pkg, fn);
2987
+ }
2988
+ }
2989
+ }
2990
+ let hash_if_options = ["0", "false", "PXT_UTF8"];
2991
+ let cpp_options = {};
2992
+ if (compile.switches.boxDebug)
2993
+ cpp_options["PXT_BOX_DEBUG"] = 1;
2994
+ if (compile.utf8)
2995
+ cpp_options["PXT_UTF8"] = 1;
2996
+ if (compile.switches.profile)
2997
+ cpp_options["PXT_PROFILE"] = 1;
2998
+ if (compile.switches.gcDebug)
2999
+ cpp_options["PXT_GC_DEBUG"] = 1;
3000
+ if (compile.switches.numFloat)
3001
+ cpp_options["PXT_USE_FLOAT"] = 1;
3002
+ if (compile.nativeType == pxtc.NATIVE_TYPE_VM)
3003
+ cpp_options["PXT_VM"] = 1;
3004
+ function stripComments(ln) {
3005
+ return ln.replace(/\/\/.*/, "").replace(/\/\*/, "");
3006
+ }
3007
+ let enumVal = 0;
3008
+ let inEnum = false;
3009
+ let currNs = "";
3010
+ let currDocComment = "";
3011
+ let currAttrs = "";
3012
+ let inDocComment = false;
3013
+ function handleComments(ln) {
3014
+ if (inEnum)
3015
+ return true;
3016
+ if (/^\s*\/\*\*/.test(ln)) {
3017
+ inDocComment = true;
3018
+ currDocComment = ln + "\n";
3019
+ if (/\*\//.test(ln))
3020
+ inDocComment = false;
3021
+ return true;
3022
+ }
3023
+ if (inDocComment) {
3024
+ currDocComment += ln + "\n";
3025
+ if (/\*\//.test(ln)) {
3026
+ inDocComment = false;
3027
+ }
3028
+ return true;
3029
+ }
3030
+ if (/^\s*\/\/%/.test(ln)) {
3031
+ currAttrs += ln + "\n";
3032
+ return true;
3033
+ }
3034
+ return false;
3035
+ }
3036
+ function enterEnum(cpname, brace) {
3037
+ inEnum = true;
3038
+ enumVal = -1;
3039
+ enumsDTS.write("");
3040
+ enumsDTS.write("");
3041
+ if (currAttrs || currDocComment) {
3042
+ enumsDTS.write(currDocComment);
3043
+ enumsDTS.write(currAttrs);
3044
+ currAttrs = "";
3045
+ currDocComment = "";
3046
+ }
3047
+ enumsDTS.write(`declare const enum ${toJs(cpname)} ${brace}`);
3048
+ knownEnums[cpname] = true;
3049
+ }
3050
+ function processEnumLine(ln) {
3051
+ let lnNC = stripComments(ln);
3052
+ if (inEnum && lnNC.indexOf("}") >= 0) {
3053
+ inEnum = false;
3054
+ enumsDTS.write("}");
3055
+ }
3056
+ if (!inEnum)
3057
+ return;
3058
+ // parse the enum case, with lots of optional stuff (?)
3059
+ let mm = /^\s*(\w+)\s*(=\s*(.*?))?,?\s*$/.exec(lnNC);
3060
+ if (mm) {
3061
+ let nm = mm[1];
3062
+ let v = mm[3];
3063
+ let opt = "";
3064
+ if (v) {
3065
+ // user-supplied value
3066
+ v = v.trim();
3067
+ let curr = U.lookup(enumVals, v);
3068
+ if (curr != null) {
3069
+ opt = " // " + v;
3070
+ v = curr;
3071
+ }
3072
+ enumVal = parseCppInt(v);
3073
+ if (enumVal == null)
3074
+ err("cannot determine value of " + lnNC);
3075
+ }
3076
+ else {
3077
+ // no user-supplied value
3078
+ enumVal++;
3079
+ v = enumVal + "";
3080
+ }
3081
+ enumsDTS.write(` ${toJs(nm)} = ${v},${opt}`);
3082
+ }
3083
+ else {
3084
+ enumsDTS.write(ln);
3085
+ }
3086
+ }
3087
+ function finishNamespace() {
3088
+ shimsDTS.setNs("");
3089
+ shimsDTS.write("");
3090
+ shimsDTS.write("");
3091
+ if (currAttrs || currDocComment) {
3092
+ shimsDTS.write(currDocComment);
3093
+ shimsDTS.write(currAttrs);
3094
+ currAttrs = "";
3095
+ currDocComment = "";
3096
+ }
3097
+ }
3098
+ function parseArg(parsedAttrs, s) {
3099
+ s = s.trim();
3100
+ let m = /(.*)=\s*(-?\w+)$/.exec(s);
3101
+ let defl = "";
3102
+ let qm = "";
3103
+ if (m) {
3104
+ defl = m[2];
3105
+ qm = "?";
3106
+ s = m[1].trim();
3107
+ }
3108
+ m = /^(.*?)(\w+)$/.exec(s);
3109
+ if (!m) {
3110
+ err("invalid argument: " + s);
3111
+ return {
3112
+ name: "???",
3113
+ type: "int"
3114
+ };
3115
+ }
3116
+ let argName = m[2];
3117
+ if (parsedAttrs.paramDefl[argName]) {
3118
+ defl = parsedAttrs.paramDefl[argName];
3119
+ qm = "?";
3120
+ }
3121
+ let numVal = defl ? U.lookup(enumVals, defl) : null;
3122
+ if (numVal != null)
3123
+ defl = numVal;
3124
+ if (defl) {
3125
+ if (parseCppInt(defl) == null)
3126
+ err("Invalid default value (non-integer): " + defl);
3127
+ currAttrs += ` ${argName}.defl=${defl}`;
3128
+ }
3129
+ return {
3130
+ name: argName + qm,
3131
+ type: m[1]
3132
+ };
3133
+ }
3134
+ function parseCpp(src, isHeader) {
3135
+ currNs = "";
3136
+ currDocComment = "";
3137
+ currAttrs = "";
3138
+ inDocComment = false;
3139
+ let indexedInstanceAttrs;
3140
+ let indexedInstanceIdx = -1;
3141
+ // replace #if 0 .... #endif with newlines
3142
+ src = src.replace(/^(\s*#\s*if\s+(\w+)\s*$)([^]*?)(^\s*#\s*(elif|else|endif)\s*$)/mg, (f, _if, arg, middle, _endif) => hash_if_options.indexOf(arg) >= 0 && !cpp_options[arg] ?
3143
+ _if + middle.replace(/[^\n]/g, "") + _endif : f);
3144
+ // special handling of C++ namespace that ends with Methods (e.g. FooMethods)
3145
+ // such a namespace will be converted into a TypeScript interface
3146
+ // this enables simple objects with methods to be defined. See, for example:
3147
+ // https://github.com/microsoft/pxt-microbit/blob/master/libs/core/buffer.cpp
3148
+ // within that namespace, the first parameter of each function should have
3149
+ // the type Foo
3150
+ function interfaceName() {
3151
+ let n = currNs.replace(/Methods$/, "");
3152
+ if (n == currNs)
3153
+ return null;
3154
+ return n;
3155
+ }
3156
+ lineNo = 0;
3157
+ // the C++ types we can map to TypeScript
3158
+ function mapType(tp) {
3159
+ switch (tp.replace(/\s+/g, "")) {
3160
+ case "void": return "void";
3161
+ // TODO: need int16_t
3162
+ case "int32_t":
3163
+ case "int":
3164
+ return "int32";
3165
+ case "uint32_t":
3166
+ case "unsigned":
3167
+ return "uint32";
3168
+ case "TNumber":
3169
+ case "float":
3170
+ case "double":
3171
+ return "number";
3172
+ case "uint16_t": return "uint16";
3173
+ case "int16_t":
3174
+ case "short": return "int16";
3175
+ case "uint8_t":
3176
+ case "byte": return "uint8";
3177
+ case "int8_t":
3178
+ case "sbyte": return "int8";
3179
+ case "bool":
3180
+ if (compile.shortPointers)
3181
+ err("use 'boolean' not 'bool' on 8 bit targets");
3182
+ return "boolean";
3183
+ case "StringData*": return "string";
3184
+ case "String": return "string";
3185
+ case "ImageLiteral_": return "string";
3186
+ case "ImageLiteral": return "string";
3187
+ case "Action": return "() => void";
3188
+ case "TValue": return "any";
3189
+ default:
3190
+ return toJs(tp);
3191
+ //err("Don't know how to map type: " + tp)
3192
+ //return "any"
3193
+ }
3194
+ }
3195
+ function mapRunTimeType(tp) {
3196
+ tp = tp.replace(/\s+/g, "");
3197
+ switch (tp) {
3198
+ case "int32_t":
3199
+ case "uint32_t":
3200
+ case "unsigned":
3201
+ case "uint16_t":
3202
+ case "int16_t":
3203
+ case "short":
3204
+ case "uint8_t":
3205
+ case "byte":
3206
+ case "int8_t":
3207
+ case "sbyte":
3208
+ case "int":
3209
+ case "ramint_t":
3210
+ return "I";
3211
+ case "void": return "V";
3212
+ case "float": return "F";
3213
+ case "TNumber": return "N";
3214
+ case "TValue": return "T";
3215
+ case "bool": return "B";
3216
+ case "double": return "D";
3217
+ case "ImageLiteral_":
3218
+ return "T";
3219
+ case "String":
3220
+ return "S";
3221
+ default:
3222
+ if (U.lookup(knownEnums, tp))
3223
+ return "I";
3224
+ return "_" + tp.replace(/[\*_]+$/, "");
3225
+ }
3226
+ }
3227
+ function generateVMWrapper(fi, argTypes) {
3228
+ if (argTypes[0] == "FiberContext*")
3229
+ return "::" + fi.name; // no wrapper
3230
+ let wrap = "_wrp_" + fi.name.replace(/:/g, "_");
3231
+ if (vmVisitedFunctions[fi.name])
3232
+ return wrap;
3233
+ vmVisitedFunctions[fi.name] = true;
3234
+ /*
3235
+ void call_getConfig(FiberContext *ctx) {
3236
+ int a0 = toInt(ctx->sp[0]);
3237
+ int a1 = toInt(ctx->r0); // last argument in r0
3238
+ int r = getConfig(a0, a1);
3239
+ ctx->r0 = fromInt(r);
3240
+ ctx->sp += 1;
3241
+ }
3242
+ */
3243
+ pointerIncPre += `\nvoid ${wrap}(FiberContext *ctx) {\n`;
3244
+ const numArgs = argTypes.length;
3245
+ let refs = [];
3246
+ let needsStackSave = false;
3247
+ let allConvs = "";
3248
+ for (let i = 0; i < numArgs; ++i) {
3249
+ const ind = fi.argsFmt[i + 1];
3250
+ const tp = argTypes[i];
3251
+ let conv = ind == "I" ? "toInt" :
3252
+ ind == "B" ? "numops::toBool" :
3253
+ "";
3254
+ const inp = i == numArgs - 1 ? "ctx->r0" : `ctx->sp[${numArgs - i - 2}]`;
3255
+ let argPref = "";
3256
+ switch (tp) {
3257
+ case "TValue":
3258
+ case "TNumber":
3259
+ break;
3260
+ case "Action":
3261
+ conv = "asRefAction";
3262
+ break;
3263
+ case "String":
3264
+ conv = "convertToString";
3265
+ argPref = "ctx, ";
3266
+ needsStackSave = true;
3267
+ break;
3268
+ default:
3269
+ if (!conv)
3270
+ conv = "as" + tp.replace(/\*/g, "");
3271
+ break;
3272
+ }
3273
+ allConvs += ` ${tp} a${i} = (${tp}) ${conv}(${argPref}${inp});\n`;
3274
+ refs.push("a" + i);
3275
+ }
3276
+ if (needsStackSave)
3277
+ pointerIncPre += " auto prevSP = ctx->sp;\n";
3278
+ pointerIncPre += allConvs;
3279
+ if (needsStackSave)
3280
+ pointerIncPre += " if (panicCode) { ctx->sp = prevSP; return; }\n";
3281
+ const call = `::${fi.name}(${refs.join(", ")})`;
3282
+ if (fi.argsFmt[0] == "V") {
3283
+ pointerIncPre += ` ${call};\n`;
3284
+ pointerIncPre += ` ctx->r0 = NULL;\n`;
3285
+ }
3286
+ else if (fi.argsFmt[0] == "I") {
3287
+ pointerIncPre += ` ctx->r0 = fromInt(${call});\n`;
3288
+ }
3289
+ else if (fi.argsFmt[0] == "B") {
3290
+ pointerIncPre += ` ctx->r0 = fromBool(${call});\n`;
3291
+ }
3292
+ else {
3293
+ pointerIncPre += ` ctx->r0 = (TValue)${call};\n`;
3294
+ }
3295
+ if (needsStackSave)
3296
+ pointerIncPre += " ctx->sp = prevSP;\n";
3297
+ if (numArgs > 1)
3298
+ pointerIncPre += ` ctx->sp += ${numArgs - 1};\n`;
3299
+ pointerIncPre += `}\n`;
3300
+ return wrap;
3301
+ }
3302
+ inEnum = false;
3303
+ enumVal = 0;
3304
+ enumsDTS.setNs("");
3305
+ shimsDTS.setNs("");
3306
+ src.split(/\r?\n/).forEach(ln => {
3307
+ ++lineNo;
3308
+ // remove comments (NC = no comments)
3309
+ let lnNC = stripComments(ln);
3310
+ processEnumLine(ln);
3311
+ // "enum class" and "enum struct" is C++ syntax to force scoping of
3312
+ // enum members
3313
+ let enM = /^\s*enum\s+(|class\s+|struct\s+)(\w+)\s*({|$)/.exec(lnNC);
3314
+ if (enM) {
3315
+ enterEnum(enM[2], enM[3]);
3316
+ if (!isHeader) {
3317
+ protos.setNs(currNs);
3318
+ protos.write(`enum ${enM[2]} : int;`);
3319
+ }
3320
+ }
3321
+ if (handleComments(ln))
3322
+ return;
3323
+ if (/^typedef.*;\s*$/.test(ln)) {
3324
+ protos.setNs(currNs);
3325
+ protos.write(ln);
3326
+ }
3327
+ let m = /^\s*namespace\s+(\w+)/.exec(ln);
3328
+ if (m) {
3329
+ //if (currNs) err("more than one namespace declaration not supported")
3330
+ currNs = m[1];
3331
+ if (interfaceName()) {
3332
+ finishNamespace();
3333
+ let tpName = interfaceName();
3334
+ shimsDTS.setNs(currNs, `declare interface ${tpName} {`);
3335
+ }
3336
+ else if (currAttrs || currDocComment) {
3337
+ finishNamespace();
3338
+ shimsDTS.setNs(toJs(currNs));
3339
+ enumsDTS.setNs(toJs(currNs));
3340
+ }
3341
+ return;
3342
+ }
3343
+ m = /^PXT_ABI\((\w+)\)/.exec(ln);
3344
+ if (m && !isVM) {
3345
+ pointersInc += `PXT_FNPTR(::${m[1]}),\n`;
3346
+ abiInc += `extern "C" void ${m[1]}();\n`;
3347
+ res.functions.push({
3348
+ name: m[1],
3349
+ argsFmt: [],
3350
+ value: 0
3351
+ });
3352
+ }
3353
+ m = /^\s*PXT_EXPORT\(([:\&\w]+)\)/.exec(ln);
3354
+ if (m) {
3355
+ if (!res.vmPointers)
3356
+ res.vmPointers = [];
3357
+ res.vmPointers.push(m[1]);
3358
+ }
3359
+ m = /^#define\s+PXT_COMM_BASE\s+([0-9a-fx]+)/.exec(ln);
3360
+ if (m)
3361
+ res.commBase = parseInt(m[1]);
3362
+ // function definition
3363
+ m = /^\s*(\w+)([\*\&]*\s+[\*\&]*)(\w+)\s*\(([^\(\)]*)\)\s*(;\s*$|\{|$)/.exec(ln);
3364
+ if (currAttrs && m) {
3365
+ indexedInstanceAttrs = null;
3366
+ let parsedAttrs = pxtc.parseCommentString(currAttrs);
3367
+ // top-level functions (outside of a namespace) are not permitted
3368
+ if (!currNs)
3369
+ err("missing namespace declaration");
3370
+ let retTp = (m[1] + m[2]).replace(/\s+/g, "");
3371
+ let funName = m[3];
3372
+ let origArgs = m[4];
3373
+ currAttrs = currAttrs.trim().replace(/ \w+\.defl=\w+/g, "");
3374
+ let argsFmt = [mapRunTimeType(retTp)];
3375
+ let argTypes = [];
3376
+ let args = origArgs.split(/,/).filter(s => !!s).map(s => {
3377
+ let r = parseArg(parsedAttrs, s);
3378
+ argsFmt.push(mapRunTimeType(r.type));
3379
+ argTypes.push(r.type.replace(/ /g, ""));
3380
+ return `${r.name}: ${mapType(r.type)}`;
3381
+ });
3382
+ let fi = {
3383
+ name: currNs + "::" + funName,
3384
+ argsFmt,
3385
+ value: null
3386
+ };
3387
+ //pxt.log(`${ln.trim()} : ${argsFmt}`)
3388
+ if (currDocComment) {
3389
+ shimsDTS.setNs(toJs(currNs));
3390
+ shimsDTS.write("");
3391
+ shimsDTS.write(currDocComment);
3392
+ if (/ImageLiteral/.test(m[4]) && !/imageLiteral=/.test(currAttrs))
3393
+ currAttrs += ` imageLiteral=1`;
3394
+ currAttrs += ` shim=${fi.name}`;
3395
+ shimsDTS.write(currAttrs);
3396
+ funName = toJs(funName);
3397
+ if (interfaceName()) {
3398
+ let tp0 = (args[0] || "").replace(/^.*:\s*/, "").trim();
3399
+ if (tp0.toLowerCase() != interfaceName().toLowerCase()) {
3400
+ err(lf("Invalid first argument; should be of type '{0}', but is '{1}'", interfaceName(), tp0));
3401
+ }
3402
+ args.shift();
3403
+ if (args.length == 0 && /\bproperty\b/.test(currAttrs))
3404
+ shimsDTS.write(`${funName}: ${mapType(retTp)};`);
3405
+ else
3406
+ shimsDTS.write(`${funName}(${args.join(", ")}): ${mapType(retTp)};`);
3407
+ }
3408
+ else {
3409
+ shimsDTS.write(`function ${funName}(${args.join(", ")}): ${mapType(retTp)};`);
3410
+ }
3411
+ }
3412
+ currDocComment = "";
3413
+ currAttrs = "";
3414
+ if (!isHeader) {
3415
+ protos.setNs(currNs);
3416
+ protos.write(`${retTp} ${funName}(${origArgs});`);
3417
+ }
3418
+ res.functions.push(fi);
3419
+ if (isYotta)
3420
+ pointersInc += "(uint32_t)(void*)::" + fi.name + ",\n";
3421
+ else if (isVM) {
3422
+ if (U.startsWith(fi.name, "pxt::op_") ||
3423
+ vmKeepFunctions[fi.name] ||
3424
+ parsedAttrs.expose ||
3425
+ (!U.startsWith(fi.name, "pxt::") && !U.startsWith(fi.name, "pxtrt::"))) {
3426
+ const wrap = generateVMWrapper(fi, argTypes);
3427
+ const nargs = fi.argsFmt.length - 1;
3428
+ pointersInc += `{ "${fi.name}", (OpFun)(void*)${wrap}, ${nargs} },\n`;
3429
+ }
3430
+ }
3431
+ else
3432
+ pointersInc += "PXT_FNPTR(::" + fi.name + "),\n";
3433
+ return;
3434
+ }
3435
+ m = /^\s*extern const (\w+) (\w+);/.exec(ln);
3436
+ if (currAttrs && m) {
3437
+ let fi = {
3438
+ name: currNs + "::" + m[2],
3439
+ argsFmt: [],
3440
+ value: null
3441
+ };
3442
+ res.functions.push(fi);
3443
+ if (!isVM)
3444
+ pointersInc += "PXT_FNPTR(&::" + fi.name + "),\n";
3445
+ currAttrs = "";
3446
+ return;
3447
+ }
3448
+ m = /^\s*(\w+)\s+(\w+)\s*;/.exec(ln);
3449
+ if (currAttrs && m) {
3450
+ let parsedAttrs = pxtc.parseCommentString(currAttrs);
3451
+ if (parsedAttrs.indexedInstanceNS) {
3452
+ indexedInstanceAttrs = parsedAttrs;
3453
+ shimsDTS.setNs(parsedAttrs.indexedInstanceNS);
3454
+ indexedInstanceIdx = 0;
3455
+ }
3456
+ let tp = m[1];
3457
+ let nm = m[2];
3458
+ if (indexedInstanceAttrs) {
3459
+ currAttrs = currAttrs.trim();
3460
+ currAttrs += ` fixedInstance shim=${indexedInstanceAttrs.indexedInstanceShim}(${indexedInstanceIdx++})`;
3461
+ shimsDTS.write("");
3462
+ shimsDTS.write(currDocComment);
3463
+ shimsDTS.write(currAttrs);
3464
+ shimsDTS.write(`const ${nm}: ${mapType(tp)};`);
3465
+ currDocComment = "";
3466
+ currAttrs = "";
3467
+ return;
3468
+ }
3469
+ }
3470
+ if (currAttrs && ln.trim()) {
3471
+ err("declaration not understood: " + ln);
3472
+ currAttrs = "";
3473
+ currDocComment = "";
3474
+ return;
3475
+ }
3476
+ });
3477
+ }
3478
+ const currSettings = U.clone(compileService.yottaConfig || {});
3479
+ const optSettings = {};
3480
+ const settingSrc = {};
3481
+ const codalLibraries = {};
3482
+ function parseJson(pkg) {
3483
+ const j0 = pkg.config.platformio;
3484
+ if (j0 && j0.dependencies) {
3485
+ U.jsonCopyFrom(res.platformio.dependencies, j0.dependencies);
3486
+ }
3487
+ if (res.npmDependencies && pkg.config.npmDependencies)
3488
+ U.jsonCopyFrom(res.npmDependencies, pkg.config.npmDependencies);
3489
+ const codal = pkg.config.codal;
3490
+ if (isCodal && codal) {
3491
+ for (const lib of codal.libraries || []) {
3492
+ const repo = pxt.github.parseRepoId(lib);
3493
+ if (!repo)
3494
+ U.userError(lf("codal library {0} doesn't look like github repo", lib));
3495
+ const canonical = pxt.github.stringifyRepo(repo);
3496
+ const existing = U.lookup(codalLibraries, repo.project);
3497
+ if (existing) {
3498
+ if (pxt.github.stringifyRepo(existing) != canonical)
3499
+ U.userError(lf("conflict between codal libraries: {0} and {1}", pxt.github.stringifyRepo(existing), canonical));
3500
+ }
3501
+ else {
3502
+ codalLibraries[repo.project] = repo;
3503
+ }
3504
+ }
3505
+ }
3506
+ const json = pkg.config.yotta;
3507
+ if (!json)
3508
+ return;
3509
+ // TODO check for conflicts
3510
+ if (json.dependencies) {
3511
+ U.jsonCopyFrom(res.yotta.dependencies, json.dependencies);
3512
+ }
3513
+ if (json.config) {
3514
+ const cfg = U.jsonFlatten(json.config);
3515
+ for (const settingName of Object.keys(cfg)) {
3516
+ const prev = U.lookup(settingSrc, settingName);
3517
+ const settingValue = cfg[settingName];
3518
+ if (!prev || prev.config.yotta.configIsJustDefaults) {
3519
+ settingSrc[settingName] = pkg;
3520
+ currSettings[settingName] = settingValue;
3521
+ }
3522
+ else if (currSettings[settingName] === settingValue) {
3523
+ // OK
3524
+ }
3525
+ else if (!mainPkg.config.yotta || !mainPkg.config.yotta.ignoreConflicts) {
3526
+ let err = new PkgConflictError(lf("conflict on yotta setting {0} between extensions {1} and {2}", settingName, pkg.id, prev.id));
3527
+ err.pkg0Id = prev.id;
3528
+ err.pkg1Id = pkg.id;
3529
+ err.settingName = settingName;
3530
+ throw err;
3531
+ }
3532
+ }
3533
+ }
3534
+ if (json.optionalConfig) {
3535
+ const cfg = U.jsonFlatten(json.optionalConfig);
3536
+ for (const settingName of Object.keys(cfg)) {
3537
+ const settingValue = cfg[settingName];
3538
+ // last one wins
3539
+ optSettings[settingName] = settingValue;
3540
+ }
3541
+ }
3542
+ }
3543
+ // This is overridden on the build server, but we need it for command line build
3544
+ if (isYotta && compile.hasHex) {
3545
+ let cs = compileService;
3546
+ U.assert(!!cs.yottaCorePackage);
3547
+ U.assert(!!cs.githubCorePackage);
3548
+ U.assert(!!cs.gittag);
3549
+ let tagged = cs.githubCorePackage + "#" + compileService.gittag;
3550
+ res.yotta.dependencies[cs.yottaCorePackage] = tagged;
3551
+ }
3552
+ if (mainPkg) {
3553
+ let seenMain = false;
3554
+ for (let pkg of mainDeps) {
3555
+ thisErrors = "";
3556
+ parseJson(pkg);
3557
+ if (pkg == mainPkg) {
3558
+ seenMain = true;
3559
+ // we only want the main package in generated .d.ts
3560
+ shimsDTS.clear();
3561
+ enumsDTS.clear();
3562
+ }
3563
+ else {
3564
+ U.assert(!seenMain);
3565
+ }
3566
+ // Generally, headers need to be processed before sources, as they contain definitions
3567
+ // (in particular of enums, which are needed to decide if we're doing conversions for
3568
+ // function arguments). This can still fail if one header uses another and they are
3569
+ // listed in invalid order...
3570
+ const isHeaderFn = (fn) => U.endsWith(fn, ".h");
3571
+ const ext = ".cpp";
3572
+ const files = pkg.files.filter(isHeaderFn)
3573
+ .concat(pkg.files.filter(s => !isHeaderFn(s)));
3574
+ for (let fn of files) {
3575
+ const isHeader = isHeaderFn(fn);
3576
+ if (isHeader || U.endsWith(fn, ext)) {
3577
+ let fullName = pkg.config.name + "/" + fn;
3578
+ if ((pkg.config.name == "base" || /^core($|---)/.test(pkg.config.name)) && isHeader)
3579
+ fullName = fn;
3580
+ if (isHeader)
3581
+ includesInc += `#include "${isYotta ? sourcePath.slice(1) : ""}${fullName}"\n`;
3582
+ let src = readFile(pkg, fn);
3583
+ if (src == null)
3584
+ U.userError(lf("C++ file {0} is missing in extension {1}.", fn, pkg.config.name));
3585
+ fileName = fullName;
3586
+ parseCpp(src, isHeader);
3587
+ // src = src.replace(/^[ \t]*/mg, "") // HACK: shrink the files
3588
+ res.extensionFiles[sourcePath + fullName] = src;
3589
+ if (pkg == mainPkg)
3590
+ res.onlyPublic = false;
3591
+ const protocol = pxt.packageUtils.getVersionProtocol(pkg.version);
3592
+ if (protocol && protocol != "pub" && protocol != "embed")
3593
+ res.onlyPublic = false;
3594
+ }
3595
+ if (U.endsWith(fn, ".c") || U.endsWith(fn, ".S") || U.endsWith(fn, ".s")) {
3596
+ let src = readFile(pkg, fn);
3597
+ res.extensionFiles[sourcePath + pkg.config.name + "/" + fn.replace(/\.S$/, ".s")] = src;
3598
+ }
3599
+ }
3600
+ if (thisErrors) {
3601
+ allErrors += lf("Extension {0}:\n", pkg.id) + thisErrors;
3602
+ }
3603
+ }
3604
+ if (!seenMain) {
3605
+ // this can happen if the main package is disabled in current variant
3606
+ shimsDTS.clear();
3607
+ enumsDTS.clear();
3608
+ }
3609
+ }
3610
+ if (allErrors)
3611
+ U.userError(allErrors);
3612
+ // merge optional settings
3613
+ U.jsonCopyFrom(optSettings, currSettings);
3614
+ U.iterMap(optSettings, (k, v) => {
3615
+ if (v === null) {
3616
+ delete optSettings[k];
3617
+ }
3618
+ });
3619
+ // fix keys - ==> _
3620
+ Object.keys(optSettings)
3621
+ .filter(k => /-/.test(k)).forEach(k => {
3622
+ const v = optSettings[k];
3623
+ delete optSettings[k];
3624
+ optSettings[k.replace(/-/g, '_')] = v;
3625
+ });
3626
+ if (!isYotta && compileService.yottaConfigCompatibility) { // yotta automatically adds YOTTA_CFG_
3627
+ Object.keys(optSettings)
3628
+ .forEach(k => optSettings["YOTTA_CFG_" + k] = optSettings[k]);
3629
+ }
3630
+ optSettings["PXT_TARGET"] = JSON.stringify(appTarget.id);
3631
+ function allFilesWithExt(ext) {
3632
+ let allfiles = Object.keys(res.extensionFiles).concat(Object.keys(res.generatedFiles));
3633
+ return allfiles.filter(f => U.endsWith(f, ext)).map(s => s.slice(1));
3634
+ }
3635
+ const configJson = U.jsonUnFlatten(optSettings);
3636
+ if (isDockerMake) {
3637
+ let packageJson = {
3638
+ name: "pxt-app",
3639
+ private: true,
3640
+ dependencies: res.npmDependencies,
3641
+ };
3642
+ res.generatedFiles["/package.json"] = JSON.stringify(packageJson, null, 4) + "\n";
3643
+ }
3644
+ else if (isEspIdf) {
3645
+ const files = U.concatArrayLike([
3646
+ allFilesWithExt(".c"),
3647
+ allFilesWithExt(".cpp"),
3648
+ allFilesWithExt(".s")
3649
+ ]).map(s => s.slice(sourcePath.length - 1)).concat(["main.cpp"]);
3650
+ files.push("pointers.cpp");
3651
+ res.generatedFiles[sourcePath + "CMakeLists.txt"] =
3652
+ `idf_component_register(\n SRCS\n` +
3653
+ files.map(f => ` "${f}"\n`).join("") +
3654
+ ` INCLUDE_DIRS\n "."\n)\n`;
3655
+ }
3656
+ else if (isCodal) {
3657
+ let cs = compileService;
3658
+ let cfg = U.clone(cs.codalDefinitions) || {};
3659
+ let trg = cs.codalTarget;
3660
+ if (typeof trg == "string")
3661
+ trg = trg + ".json";
3662
+ let codalJson = {
3663
+ "target": trg,
3664
+ "definitions": cfg,
3665
+ "config": cfg,
3666
+ "application": "pxtapp",
3667
+ "output_folder": "build",
3668
+ // include these, because we use hash of this file to see if anything changed
3669
+ "pxt_gitrepo": cs.githubCorePackage,
3670
+ "pxt_gittag": cs.gittag,
3671
+ "libraries": U.values(codalLibraries).map(r => ({
3672
+ "name": r.project,
3673
+ "url": "https://github.com/" + r.fullName,
3674
+ "branch": r.tag || "master",
3675
+ "type": "git"
3676
+ }))
3677
+ };
3678
+ if (codalJson.libraries.length == 0)
3679
+ delete codalJson.libraries;
3680
+ U.iterMap(U.jsonFlatten(configJson), (k, v) => {
3681
+ k = k.replace(/^codal\./, "device.").toUpperCase().replace(/\./g, "_");
3682
+ cfg[k] = v;
3683
+ });
3684
+ res.generatedFiles["/codal.json"] = JSON.stringify(codalJson, null, 4) + "\n";
3685
+ host.logger.debug(`codal.json: ${res.generatedFiles["/codal.json"]}`);
3686
+ res.codal = codalJson;
3687
+ }
3688
+ else if (isPlatformio) {
3689
+ const iniLines = compileService.platformioIni.slice();
3690
+ // TODO merge configjson
3691
+ iniLines.push("lib_deps =");
3692
+ U.iterMap(res.platformio.dependencies, (pkg, ver) => {
3693
+ let pkgSpec = /[@#\/]/.test(ver) ? ver : pkg + "@" + ver;
3694
+ iniLines.push(" " + pkgSpec);
3695
+ });
3696
+ res.generatedFiles["/platformio.ini"] = iniLines.join("\n") + "\n";
3697
+ }
3698
+ else {
3699
+ res.yotta.config = configJson;
3700
+ let name = "pxt-app";
3701
+ if (compileService.yottaBinary)
3702
+ name = compileService.yottaBinary.replace(/-combined/, "").replace(/\.hex$/, "");
3703
+ let moduleJson = {
3704
+ "name": name,
3705
+ "version": "0.0.0",
3706
+ "description": "Auto-generated. Do not edit.",
3707
+ "license": "n/a",
3708
+ "dependencies": res.yotta.dependencies,
3709
+ "targetDependencies": {},
3710
+ "bin": "./source"
3711
+ };
3712
+ res.generatedFiles["/module.json"] = JSON.stringify(moduleJson, null, 4) + "\n";
3713
+ host.logger.debug(`module.json: ${res.generatedFiles["/module.json"]}`);
3714
+ }
3715
+ for (let k of Object.keys(cpp_options)) {
3716
+ pxtConfig += `#define ${k} ${cpp_options[k]}\n`;
3717
+ }
3718
+ if (compile.uf2Family)
3719
+ pxtConfig += `#define PXT_UF2_FAMILY ${compile.uf2Family}\n`;
3720
+ res.generatedFiles[sourcePath + "pointers.cpp"] = includesInc + protos.finish() + abiInc +
3721
+ pointerIncPre + pointersInc + "\nPXT_SHIMS_END\n";
3722
+ res.generatedFiles[sourcePath + "pxtconfig.h"] = pxtConfig;
3723
+ host.logger.debug(`pxtconfig.h: ${res.generatedFiles[sourcePath + "pxtconfig.h"]}`);
3724
+ if (isYotta) {
3725
+ res.generatedFiles["/config.json"] = JSON.stringify(configJson, null, 4) + "\n";
3726
+ host.logger.debug(`yotta config.json: ${res.generatedFiles["/config.json"]}`);
3727
+ }
3728
+ res.generatedFiles[sourcePath + "main.cpp"] = `
3729
+ #include "pxt.h"
3730
+ #ifdef PXT_MAIN
3731
+ PXT_MAIN
3732
+ #else
3733
+ int main() {
3734
+ uBit.init();
3735
+ pxt::start();
3736
+ release_fiber();
3737
+ return 0; // your program will never reach this line.
3738
+ }
3739
+ #endif
3740
+ `;
3741
+ if (res.generatedFiles["/Makefile"]) {
3742
+ let inc = "";
3743
+ let add = (name, ext) => {
3744
+ inc += `${name} = ${allFilesWithExt(ext).join(" ")}\n`;
3745
+ };
3746
+ add("PXT_C", ".c");
3747
+ add("PXT_CPP", ".cpp");
3748
+ add("PXT_S", ".s");
3749
+ add("PXT_HEADERS", ".h");
3750
+ inc += "PXT_SOURCES := $(PXT_C) $(PXT_S) $(PXT_CPP)\n";
3751
+ inc += "PXT_OBJS := $(addprefix bld/, $(PXT_C:.c=.o) $(PXT_S:.s=.o) $(PXT_CPP:.cpp=.o))\n";
3752
+ res.generatedFiles["/Makefile.inc"] = inc;
3753
+ }
3754
+ res.generatedFiles["/functions.json"] = JSON.stringify(res.functions, null, 1);
3755
+ let tmp = res.extensionFiles;
3756
+ U.jsonCopyFrom(tmp, res.generatedFiles);
3757
+ let creq = {
3758
+ config: compileService.serviceId,
3759
+ tag: compileService.gittag,
3760
+ replaceFiles: tmp,
3761
+ dependencies: (isYotta ? res.yotta.dependencies : null)
3762
+ };
3763
+ let data = JSON.stringify(creq);
3764
+ host.perf.measureStart(Measurements.Sha256Buffer);
3765
+ try {
3766
+ res.sha = pxtc.BrowserImpl.sha256buffer(U.toUTF8Array(data));
3767
+ }
3768
+ finally {
3769
+ host.perf.measureEnd(Measurements.Sha256Buffer);
3770
+ }
3771
+ res.skipCloudBuild = !!compileService.skipCloudBuild;
3772
+ res.compileData = ts.pxtc.encodeBase64(U.toUTF8(data));
3773
+ res.shimsDTS = shimsDTS.finish();
3774
+ res.enumsDTS = enumsDTS.finish();
3775
+ if (Object.keys(host.cache).length > 10) {
3776
+ for (const key of Object.keys(host.cache))
3777
+ delete host.cache[key];
3778
+ }
3779
+ host.cache[key] = U.clone(res);
3780
+ return res;
3781
+ }
3782
+ cpp.getExtensionInfo = getExtensionInfo;
3783
+ })(cpp = pxt.cpp || (pxt.cpp = {}));
3784
+ })(pxt || (pxt = {}));
3785
+ /// <reference path="../pxtlib/shared/docsrender.ts"/>
3786
+ /// <reference path="../pxtlib/shared/extensioninfo.ts"/>
1621
3787
  global.pxt = pxt;