rapydscript-ns 0.8.2 → 0.8.4
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/.agignore +1 -1
- package/.github/workflows/ci.yml +38 -38
- package/=template.pyj +5 -5
- package/CHANGELOG.md +39 -0
- package/HACKING.md +103 -103
- package/LICENSE +24 -24
- package/PYTHON_DIFFERENCES_REPORT.md +291 -0
- package/PYTHON_FEATURE_COVERAGE.md +106 -15
- package/README.md +831 -52
- package/TODO.md +4 -286
- package/add-toc-to-readme +2 -2
- package/bin/export +75 -75
- package/bin/rapydscript +70 -70
- package/bin/web-repl-export +102 -102
- package/build +2 -2
- package/language-service/index.js +4623 -0
- package/language-service/language-service.d.ts +40 -0
- package/package.json +9 -7
- package/publish.py +37 -37
- package/release/baselib-plain-pretty.js +2006 -229
- package/release/baselib-plain-ugly.js +70 -3
- package/release/compiler.js +11554 -3870
- package/release/signatures.json +31 -29
- package/session.vim +4 -4
- package/setup.cfg +2 -2
- package/src/ast.pyj +93 -1
- package/src/baselib-builtins.pyj +99 -2
- package/src/baselib-containers.pyj +107 -4
- package/src/baselib-errors.pyj +44 -0
- package/src/baselib-internal.pyj +124 -5
- package/src/baselib-itertools.pyj +97 -97
- package/src/baselib-str.pyj +32 -1
- package/src/compiler.pyj +36 -36
- package/src/errors.pyj +30 -30
- package/src/lib/aes.pyj +646 -646
- package/src/lib/collections.pyj +1 -1
- package/src/lib/copy.pyj +120 -0
- package/src/lib/elementmaker.pyj +83 -83
- package/src/lib/encodings.pyj +126 -126
- package/src/lib/gettext.pyj +569 -569
- package/src/lib/itertools.pyj +580 -580
- package/src/lib/math.pyj +193 -193
- package/src/lib/numpy.pyj +10 -10
- package/src/lib/operator.pyj +11 -11
- package/src/lib/pythonize.pyj +20 -20
- package/src/lib/random.pyj +118 -118
- package/src/lib/re.pyj +470 -470
- package/src/lib/react.pyj +74 -0
- package/src/lib/traceback.pyj +63 -63
- package/src/lib/uuid.pyj +77 -77
- package/src/monaco-language-service/analyzer.js +131 -9
- package/src/monaco-language-service/builtins.js +17 -2
- package/src/monaco-language-service/completions.js +170 -1
- package/src/monaco-language-service/diagnostics.js +25 -3
- package/src/monaco-language-service/dts.js +550 -550
- package/src/monaco-language-service/index.js +17 -0
- package/src/monaco-language-service/scope.js +3 -0
- package/src/output/classes.pyj +128 -11
- package/src/output/codegen.pyj +17 -3
- package/src/output/comments.pyj +45 -45
- package/src/output/exceptions.pyj +201 -105
- package/src/output/functions.pyj +13 -16
- package/src/output/jsx.pyj +164 -0
- package/src/output/literals.pyj +28 -2
- package/src/output/loops.pyj +0 -9
- package/src/output/modules.pyj +2 -5
- package/src/output/operators.pyj +22 -2
- package/src/output/statements.pyj +2 -2
- package/src/output/stream.pyj +1 -13
- package/src/output/treeshake.pyj +182 -182
- package/src/output/utils.pyj +72 -72
- package/src/parse.pyj +434 -114
- package/src/string_interpolation.pyj +72 -72
- package/src/tokenizer.pyj +29 -0
- package/src/unicode_aliases.pyj +576 -576
- package/src/utils.pyj +192 -192
- package/test/_import_one.pyj +37 -37
- package/test/_import_two/__init__.pyj +11 -11
- package/test/_import_two/level2/deep.pyj +4 -4
- package/test/_import_two/other.pyj +6 -6
- package/test/_import_two/sub.pyj +13 -13
- package/test/aes_vectors.pyj +421 -421
- package/test/annotations.pyj +80 -80
- package/test/baselib.pyj +4 -4
- package/test/classes.pyj +56 -17
- package/test/collections.pyj +5 -5
- package/test/decorators.pyj +77 -77
- package/test/docstrings.pyj +39 -39
- package/test/elementmaker_test.pyj +45 -45
- package/test/functions.pyj +151 -151
- package/test/generators.pyj +41 -41
- package/test/generic.pyj +370 -370
- package/test/imports.pyj +72 -72
- package/test/internationalization.pyj +73 -73
- package/test/lint.pyj +164 -164
- package/test/loops.pyj +85 -85
- package/test/numpy.pyj +734 -734
- package/test/omit_function_metadata.pyj +20 -20
- package/test/python_compat.pyj +326 -0
- package/test/python_features.pyj +129 -29
- package/test/regexp.pyj +55 -55
- package/test/repl.pyj +121 -121
- package/test/scoped_flags.pyj +76 -76
- package/test/slice.pyj +105 -0
- package/test/str.pyj +25 -0
- package/test/unit/fixtures/fibonacci_expected.js +1 -1
- package/test/unit/index.js +2296 -71
- package/test/unit/language-service-builtins.js +70 -0
- package/test/unit/language-service-bundle.js +5 -5
- package/test/unit/language-service-completions.js +180 -0
- package/test/unit/language-service-dts.js +543 -543
- package/test/unit/language-service-hover.js +455 -455
- package/test/unit/language-service-index.js +350 -0
- package/test/unit/language-service-scope.js +255 -0
- package/test/unit/language-service.js +625 -4
- package/test/unit/run-language-service.js +1 -0
- package/test/unit/web-repl.js +437 -0
- package/tools/build-language-service.js +2 -2
- package/tools/cli.js +547 -547
- package/tools/compile.js +219 -219
- package/tools/compiler.js +0 -24
- package/tools/completer.js +131 -131
- package/tools/embedded_compiler.js +251 -251
- package/tools/export.js +3 -37
- package/tools/gettext.js +185 -185
- package/tools/ini.js +65 -65
- package/tools/msgfmt.js +187 -187
- package/tools/repl.js +223 -223
- package/tools/test.js +118 -118
- package/tools/utils.js +128 -128
- package/tools/web_repl.js +95 -95
- package/try +41 -41
- package/web-repl/env.js +196 -74
- package/web-repl/index.html +163 -163
- package/web-repl/main.js +252 -254
- package/web-repl/prism.css +139 -139
- package/web-repl/prism.js +113 -113
- package/web-repl/rapydscript.js +227 -139
- package/web-repl/sha1.js +25 -25
- package/hack_demo.pyj +0 -112
- package/web-repl/language-service.js +0 -4187
package/test/unit/web-repl.js
CHANGED
|
@@ -119,6 +119,70 @@ function run_js(js) {
|
|
|
119
119
|
});
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
+
// Minimal React stub — mirrors the one in web-repl/env.js so that compiled
|
|
123
|
+
// code that imports from the react library can run in a plain Node vm context.
|
|
124
|
+
var REACT_STUB = (function () {
|
|
125
|
+
var Fragment = Symbol("React.Fragment");
|
|
126
|
+
function createElement(type, props) {
|
|
127
|
+
var children = Array.prototype.slice.call(arguments, 2);
|
|
128
|
+
return { type: type, props: Object.assign({ children: children.length === 1 ? children[0] : children }, props) };
|
|
129
|
+
}
|
|
130
|
+
function useState(initial) {
|
|
131
|
+
var s = typeof initial === "function" ? initial() : initial;
|
|
132
|
+
return [s, function (v) { s = typeof v === "function" ? v(s) : v; }];
|
|
133
|
+
}
|
|
134
|
+
function useEffect(fn) { fn(); }
|
|
135
|
+
function useLayoutEffect(fn) { fn(); }
|
|
136
|
+
function useMemo(fn) { return fn(); }
|
|
137
|
+
function useCallback(fn) { return fn; }
|
|
138
|
+
function useRef(initial) { return { current: initial }; }
|
|
139
|
+
function useContext(ctx) { return ctx && ctx._currentValue !== undefined ? ctx._currentValue : undefined; }
|
|
140
|
+
function useReducer(reducer, initial) { return [initial, function (a) {}]; }
|
|
141
|
+
function useImperativeHandle(ref, create) { if (ref) ref.current = create(); }
|
|
142
|
+
function useDebugValue() {}
|
|
143
|
+
function useId() { return ":r" + (Math.random() * 1e9 | 0) + ":"; }
|
|
144
|
+
function useTransition() { return [false, function (fn) { fn(); }]; }
|
|
145
|
+
function useDeferredValue(v) { return v; }
|
|
146
|
+
function useSyncExternalStore(sub, get) { return get(); }
|
|
147
|
+
function useInsertionEffect(fn) { fn(); }
|
|
148
|
+
function createContext(def) { return { _currentValue: def }; }
|
|
149
|
+
function createRef() { return { current: null }; }
|
|
150
|
+
function forwardRef(render) { return function (props) { return render(props, null); }; }
|
|
151
|
+
function memo(C) { return C; }
|
|
152
|
+
function lazy(f) { return f; }
|
|
153
|
+
function cloneElement(el, props) { return Object.assign({}, el, { props: Object.assign({}, el.props, props) }); }
|
|
154
|
+
function isValidElement(o) { return o !== null && typeof o === "object" && o.type !== undefined; }
|
|
155
|
+
function Component() {}
|
|
156
|
+
Component.prototype.setState = function (u) { this.state = Object.assign({}, this.state, typeof u === "function" ? u(this.state) : u); };
|
|
157
|
+
function PureComponent() {}
|
|
158
|
+
PureComponent.prototype = Object.create(Component.prototype);
|
|
159
|
+
PureComponent.prototype.constructor = PureComponent;
|
|
160
|
+
return {
|
|
161
|
+
Fragment: Fragment, createElement: createElement,
|
|
162
|
+
useState: useState, useEffect: useEffect, useLayoutEffect: useLayoutEffect,
|
|
163
|
+
useMemo: useMemo, useCallback: useCallback, useRef: useRef,
|
|
164
|
+
useContext: useContext, useReducer: useReducer,
|
|
165
|
+
useImperativeHandle: useImperativeHandle, useDebugValue: useDebugValue,
|
|
166
|
+
useId: useId, useTransition: useTransition, useDeferredValue: useDeferredValue,
|
|
167
|
+
useSyncExternalStore: useSyncExternalStore, useInsertionEffect: useInsertionEffect,
|
|
168
|
+
createContext: createContext, createRef: createRef, forwardRef: forwardRef,
|
|
169
|
+
memo: memo, lazy: lazy, cloneElement: cloneElement, isValidElement: isValidElement,
|
|
170
|
+
Component: Component, PureComponent: PureComponent,
|
|
171
|
+
StrictMode: {}, Suspense: {}, Profiler: {},
|
|
172
|
+
};
|
|
173
|
+
})();
|
|
174
|
+
|
|
175
|
+
// Run compiled JS in a vm context that also has a React stub available.
|
|
176
|
+
function run_js_with_react(js) {
|
|
177
|
+
return vm.runInNewContext(js, {
|
|
178
|
+
__name__ : "<test>",
|
|
179
|
+
console : console,
|
|
180
|
+
assrt : assert,
|
|
181
|
+
ρσ_last_exception : undefined,
|
|
182
|
+
React : REACT_STUB,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
122
186
|
// ---------------------------------------------------------------------------
|
|
123
187
|
// Tests
|
|
124
188
|
// ---------------------------------------------------------------------------
|
|
@@ -445,6 +509,379 @@ var TESTS = [
|
|
|
445
509
|
},
|
|
446
510
|
},
|
|
447
511
|
|
|
512
|
+
{
|
|
513
|
+
name: "nested_class_web_repl",
|
|
514
|
+
description: "Nested class definitions compile and run correctly via the web-repl bundle",
|
|
515
|
+
run: function () {
|
|
516
|
+
var repl = RS.web_repl();
|
|
517
|
+
var js = bundle_compile(repl, [
|
|
518
|
+
"class Outer:",
|
|
519
|
+
" class Inner:",
|
|
520
|
+
" def __init__(self, val):",
|
|
521
|
+
" self.val = val",
|
|
522
|
+
" def __init__(self, v):",
|
|
523
|
+
" self.inner = Outer.Inner(v)",
|
|
524
|
+
"o = Outer(99)",
|
|
525
|
+
"assrt.equal(o.inner.val, 99)",
|
|
526
|
+
"assrt.ok(isinstance(o.inner, Outer.Inner))",
|
|
527
|
+
"assrt.ok(o.Inner is Outer.Inner)",
|
|
528
|
+
].join("\n"));
|
|
529
|
+
run_js(js);
|
|
530
|
+
},
|
|
531
|
+
},
|
|
532
|
+
|
|
533
|
+
// ── slice() builtin ───────────────────────────────────────────────────
|
|
534
|
+
|
|
535
|
+
{
|
|
536
|
+
name: "bundle_slice_constructor",
|
|
537
|
+
description: "slice() constructor stores start/stop/step attributes correctly",
|
|
538
|
+
run: function () {
|
|
539
|
+
var repl = RS.web_repl();
|
|
540
|
+
var js = bundle_compile(repl, [
|
|
541
|
+
"s1 = slice(5)",
|
|
542
|
+
"assrt.equal(s1.start, None)",
|
|
543
|
+
"assrt.equal(s1.stop, 5)",
|
|
544
|
+
"assrt.equal(s1.step, None)",
|
|
545
|
+
"s2 = slice(2, 8)",
|
|
546
|
+
"assrt.equal(s2.start, 2)",
|
|
547
|
+
"assrt.equal(s2.stop, 8)",
|
|
548
|
+
"assrt.equal(s2.step, None)",
|
|
549
|
+
"s3 = slice(1, 9, 2)",
|
|
550
|
+
"assrt.equal(s3.start, 1)",
|
|
551
|
+
"assrt.equal(s3.stop, 9)",
|
|
552
|
+
"assrt.equal(s3.step, 2)",
|
|
553
|
+
].join("\n"));
|
|
554
|
+
run_js(js);
|
|
555
|
+
},
|
|
556
|
+
},
|
|
557
|
+
|
|
558
|
+
{
|
|
559
|
+
name: "bundle_slice_subscript",
|
|
560
|
+
description: "slice object used as list subscript returns the correct sub-list",
|
|
561
|
+
run: function () {
|
|
562
|
+
var repl = RS.web_repl();
|
|
563
|
+
var js = bundle_compile(repl, [
|
|
564
|
+
"from __python__ import overload_getitem",
|
|
565
|
+
"lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]",
|
|
566
|
+
"s = slice(2, 5)",
|
|
567
|
+
"assrt.deepEqual(lst[s], [2, 3, 4])",
|
|
568
|
+
"assrt.deepEqual(lst[slice(0, 6, 2)], [0, 2, 4])",
|
|
569
|
+
"assrt.deepEqual(lst[slice(5, 1, -1)], [5, 4, 3, 2])",
|
|
570
|
+
].join("\n"));
|
|
571
|
+
run_js(js);
|
|
572
|
+
},
|
|
573
|
+
},
|
|
574
|
+
|
|
575
|
+
{
|
|
576
|
+
name: "bundle_slice_indices",
|
|
577
|
+
description: "slice.indices() returns normalised (start, stop, step) tuple",
|
|
578
|
+
run: function () {
|
|
579
|
+
var repl = RS.web_repl();
|
|
580
|
+
var js = bundle_compile(repl, [
|
|
581
|
+
"s = slice(2, 8)",
|
|
582
|
+
"idx = s.indices(10)",
|
|
583
|
+
"assrt.equal(idx[0], 2)",
|
|
584
|
+
"assrt.equal(idx[1], 8)",
|
|
585
|
+
"assrt.equal(idx[2], 1)",
|
|
586
|
+
"# negative indices normalised",
|
|
587
|
+
"s2 = slice(-3, -1)",
|
|
588
|
+
"idx2 = s2.indices(10)",
|
|
589
|
+
"assrt.equal(idx2[0], 7)",
|
|
590
|
+
"assrt.equal(idx2[1], 9)",
|
|
591
|
+
].join("\n"));
|
|
592
|
+
run_js(js);
|
|
593
|
+
},
|
|
594
|
+
},
|
|
595
|
+
|
|
596
|
+
{
|
|
597
|
+
name: "bundle_slice_repr",
|
|
598
|
+
description: "str(slice(...)) produces the Python-style repr",
|
|
599
|
+
run: function () {
|
|
600
|
+
var repl = RS.web_repl();
|
|
601
|
+
var js = bundle_compile(repl, [
|
|
602
|
+
"assrt.equal(str(slice(1, 5, None)), 'slice(1, 5, None)')",
|
|
603
|
+
"assrt.equal(str(slice(None, 5, 2)), 'slice(None, 5, 2)')",
|
|
604
|
+
].join("\n"));
|
|
605
|
+
run_js(js);
|
|
606
|
+
},
|
|
607
|
+
},
|
|
608
|
+
|
|
609
|
+
{
|
|
610
|
+
name: "bundle_slice_isinstance",
|
|
611
|
+
description: "isinstance(slice(...), slice) returns True in bundled baselib",
|
|
612
|
+
run: function () {
|
|
613
|
+
var repl = RS.web_repl();
|
|
614
|
+
var js = bundle_compile(repl, [
|
|
615
|
+
"s = slice(1, 5)",
|
|
616
|
+
"assrt.ok(isinstance(s, slice))",
|
|
617
|
+
].join("\n"));
|
|
618
|
+
run_js(js);
|
|
619
|
+
},
|
|
620
|
+
},
|
|
621
|
+
|
|
622
|
+
{
|
|
623
|
+
name: "bundle_tuple_annotation_variable",
|
|
624
|
+
description: "variable type annotation with tuple does not become a function call",
|
|
625
|
+
run: function () {
|
|
626
|
+
var repl = RS.web_repl();
|
|
627
|
+
var js = bundle_compile(repl, [
|
|
628
|
+
"# globals: assrt",
|
|
629
|
+
"range_limits: tuple = (0, 100)",
|
|
630
|
+
"assrt.equal(range_limits[0], 0)",
|
|
631
|
+
"assrt.equal(range_limits[1], 100)",
|
|
632
|
+
].join("\n"));
|
|
633
|
+
// Ensure it compiled to an assignment, not a call
|
|
634
|
+
if (/range_limits\s*\(/.test(js)) throw new Error("range_limits was compiled as a function call:\n" + js);
|
|
635
|
+
run_js(js);
|
|
636
|
+
},
|
|
637
|
+
},
|
|
638
|
+
|
|
639
|
+
{
|
|
640
|
+
name: "bundle_tuple_annotation_function_arg",
|
|
641
|
+
description: "function argument type annotation with tuple and int works at runtime",
|
|
642
|
+
run: function () {
|
|
643
|
+
var repl = RS.web_repl();
|
|
644
|
+
var js = bundle_compile(repl, [
|
|
645
|
+
"# globals: assrt",
|
|
646
|
+
"def clamp(val: int, bounds: tuple) -> int:",
|
|
647
|
+
" lo, hi = bounds",
|
|
648
|
+
" return max(lo, min(hi, val))",
|
|
649
|
+
"range_limits: tuple = (0, 100)",
|
|
650
|
+
"assrt.equal(clamp(150, range_limits), 100)",
|
|
651
|
+
"assrt.equal(clamp(-5, range_limits), 0)",
|
|
652
|
+
].join("\n"));
|
|
653
|
+
run_js(js);
|
|
654
|
+
},
|
|
655
|
+
},
|
|
656
|
+
|
|
657
|
+
{
|
|
658
|
+
name: "bundle_list_concatenation",
|
|
659
|
+
description: "list + list returns a concatenated list in the bundled baselib",
|
|
660
|
+
run: function () {
|
|
661
|
+
var repl = RS.web_repl();
|
|
662
|
+
var js = bundle_compile(repl, [
|
|
663
|
+
"a = [1, 2]",
|
|
664
|
+
"b = [3, 4]",
|
|
665
|
+
"c = a + b",
|
|
666
|
+
"assrt.deepEqual(c, [1, 2, 3, 4])",
|
|
667
|
+
"assrt.deepEqual(a, [1, 2])",
|
|
668
|
+
"assrt.deepEqual(b, [3, 4])",
|
|
669
|
+
"# iadd extends in-place",
|
|
670
|
+
"a += [5]",
|
|
671
|
+
"assrt.deepEqual(a, [1, 2, 5])",
|
|
672
|
+
"# numbers still work",
|
|
673
|
+
"assrt.equal(1 + 2, 3)",
|
|
674
|
+
"# strings still work",
|
|
675
|
+
"assrt.equal('foo' + 'bar', 'foobar')",
|
|
676
|
+
].join("\n"));
|
|
677
|
+
run_js(js);
|
|
678
|
+
},
|
|
679
|
+
},
|
|
680
|
+
|
|
681
|
+
// ── React stub tests ─────────────────────────────────────────────────────
|
|
682
|
+
// These tests require a React mock in the vm context because the compiled
|
|
683
|
+
// react.pyj module initialises with `React.*` references at load time.
|
|
684
|
+
|
|
685
|
+
{
|
|
686
|
+
name: "bundle_react_stub_memo",
|
|
687
|
+
description: "web-repl React stub: memo() returns its argument (identity wrapper)",
|
|
688
|
+
run: function () {
|
|
689
|
+
var repl = RS.web_repl();
|
|
690
|
+
var js = bundle_compile(repl, [
|
|
691
|
+
"from react import memo",
|
|
692
|
+
"def MyComp(props): return props.x",
|
|
693
|
+
"Memoised = memo(MyComp)",
|
|
694
|
+
"assrt.equal(Memoised, MyComp)",
|
|
695
|
+
].join("\n"));
|
|
696
|
+
run_js_with_react(js);
|
|
697
|
+
},
|
|
698
|
+
},
|
|
699
|
+
|
|
700
|
+
{
|
|
701
|
+
name: "bundle_react_stub_usestate",
|
|
702
|
+
description: "web-repl React stub: useState returns [initialValue, setter]",
|
|
703
|
+
run: function () {
|
|
704
|
+
var repl = RS.web_repl();
|
|
705
|
+
var js = bundle_compile(repl, [
|
|
706
|
+
"from react import useState",
|
|
707
|
+
"state, setState = useState(42)",
|
|
708
|
+
"assrt.equal(state, 42)",
|
|
709
|
+
"assrt.equal(jstype(setState), 'function')",
|
|
710
|
+
].join("\n"));
|
|
711
|
+
run_js_with_react(js);
|
|
712
|
+
},
|
|
713
|
+
},
|
|
714
|
+
|
|
715
|
+
{
|
|
716
|
+
name: "bundle_react_stub_useeffect",
|
|
717
|
+
description: "web-repl React stub: useEffect calls its callback immediately",
|
|
718
|
+
run: function () {
|
|
719
|
+
var repl = RS.web_repl();
|
|
720
|
+
var js = bundle_compile(repl, [
|
|
721
|
+
"from react import useEffect",
|
|
722
|
+
"ran = [False]",
|
|
723
|
+
"def effect(): ran[0] = True",
|
|
724
|
+
"useEffect(effect, [])",
|
|
725
|
+
"assrt.ok(ran[0])",
|
|
726
|
+
].join("\n"));
|
|
727
|
+
run_js_with_react(js);
|
|
728
|
+
},
|
|
729
|
+
},
|
|
730
|
+
|
|
731
|
+
{
|
|
732
|
+
name: "bundle_react_stub_usememo",
|
|
733
|
+
description: "web-repl React stub: useMemo returns the computed value",
|
|
734
|
+
run: function () {
|
|
735
|
+
var repl = RS.web_repl();
|
|
736
|
+
var js = bundle_compile(repl, [
|
|
737
|
+
"from react import useMemo",
|
|
738
|
+
"result = useMemo(def(): return 6 * 7;, [])",
|
|
739
|
+
"assrt.equal(result, 42)",
|
|
740
|
+
].join("\n"));
|
|
741
|
+
run_js_with_react(js);
|
|
742
|
+
},
|
|
743
|
+
},
|
|
744
|
+
|
|
745
|
+
{
|
|
746
|
+
name: "bundle_react_stub_useref",
|
|
747
|
+
description: "web-repl React stub: useRef returns {current: initialValue}",
|
|
748
|
+
run: function () {
|
|
749
|
+
var repl = RS.web_repl();
|
|
750
|
+
var js = bundle_compile(repl, [
|
|
751
|
+
"from react import useRef",
|
|
752
|
+
"ref = useRef(None)",
|
|
753
|
+
"assrt.equal(ref.current, None)",
|
|
754
|
+
"ref.current = 'hello'",
|
|
755
|
+
"assrt.equal(ref.current, 'hello')",
|
|
756
|
+
].join("\n"));
|
|
757
|
+
run_js_with_react(js);
|
|
758
|
+
},
|
|
759
|
+
},
|
|
760
|
+
|
|
761
|
+
{
|
|
762
|
+
name: "bundle_react_stub_usereducer",
|
|
763
|
+
description: "web-repl React stub: useReducer returns [initialState, dispatch]",
|
|
764
|
+
run: function () {
|
|
765
|
+
var repl = RS.web_repl();
|
|
766
|
+
var js = bundle_compile(repl, [
|
|
767
|
+
"from react import useReducer",
|
|
768
|
+
"def reducer(state, action):",
|
|
769
|
+
" if action == 'inc': return state + 1",
|
|
770
|
+
" return state",
|
|
771
|
+
"state, dispatch = useReducer(reducer, 0)",
|
|
772
|
+
"assrt.equal(state, 0)",
|
|
773
|
+
"assrt.equal(jstype(dispatch), 'function')",
|
|
774
|
+
].join("\n"));
|
|
775
|
+
run_js_with_react(js);
|
|
776
|
+
},
|
|
777
|
+
},
|
|
778
|
+
|
|
779
|
+
{
|
|
780
|
+
name: "bundle_react_stub_createcontext",
|
|
781
|
+
description: "web-repl React stub: createContext returns a context with default value",
|
|
782
|
+
run: function () {
|
|
783
|
+
var repl = RS.web_repl();
|
|
784
|
+
var js = bundle_compile(repl, [
|
|
785
|
+
"from react import createContext, useContext",
|
|
786
|
+
"ThemeCtx = createContext('dark')",
|
|
787
|
+
"theme = useContext(ThemeCtx)",
|
|
788
|
+
"assrt.equal(theme, 'dark')",
|
|
789
|
+
].join("\n"));
|
|
790
|
+
run_js_with_react(js);
|
|
791
|
+
},
|
|
792
|
+
},
|
|
793
|
+
|
|
794
|
+
{
|
|
795
|
+
name: "bundle_react_stub_forwardref",
|
|
796
|
+
description: "web-repl React stub: forwardRef wraps the render function",
|
|
797
|
+
run: function () {
|
|
798
|
+
var repl = RS.web_repl();
|
|
799
|
+
var js = bundle_compile(repl, [
|
|
800
|
+
"from react import forwardRef",
|
|
801
|
+
"def render(props, ref): return props.x",
|
|
802
|
+
"FancyInput = forwardRef(render)",
|
|
803
|
+
"assrt.equal(jstype(FancyInput), 'function')",
|
|
804
|
+
"assrt.equal(FancyInput({'x': 99}), 99)",
|
|
805
|
+
].join("\n"));
|
|
806
|
+
run_js_with_react(js);
|
|
807
|
+
},
|
|
808
|
+
},
|
|
809
|
+
|
|
810
|
+
{
|
|
811
|
+
name: "bundle_react_stub_jsx_and_memo",
|
|
812
|
+
description: "web-repl React stub: JSX component wrapped with memo compiles and runs",
|
|
813
|
+
run: function () {
|
|
814
|
+
var repl = RS.web_repl();
|
|
815
|
+
var js = bundle_compile(repl, [
|
|
816
|
+
"from __python__ import jsx",
|
|
817
|
+
"from react import useState, memo",
|
|
818
|
+
"def Counter(props):",
|
|
819
|
+
" count, setCount = useState(props.initial or 0)",
|
|
820
|
+
" return <span>{count}</span>",
|
|
821
|
+
"MemoCounter = memo(Counter)",
|
|
822
|
+
"assrt.equal(jstype(MemoCounter), 'function')",
|
|
823
|
+
"el = MemoCounter({'initial': 7})",
|
|
824
|
+
"assrt.equal(el.type, 'span')",
|
|
825
|
+
].join("\n"));
|
|
826
|
+
run_js_with_react(js);
|
|
827
|
+
},
|
|
828
|
+
},
|
|
829
|
+
|
|
830
|
+
// ── __import__() ─────────────────────────────────────────────────────
|
|
831
|
+
|
|
832
|
+
{
|
|
833
|
+
name: "bundle___import__-basic",
|
|
834
|
+
description: "__import__(name) returns a stdlib module reference in the web-repl bundle",
|
|
835
|
+
run: function () {
|
|
836
|
+
var repl = RS.web_repl();
|
|
837
|
+
var js = bundle_compile(repl, [
|
|
838
|
+
"from collections import Counter",
|
|
839
|
+
"m = __import__('collections')",
|
|
840
|
+
// m.Counter should be the same object as the statically-imported Counter
|
|
841
|
+
"assrt.ok(m.Counter is Counter)",
|
|
842
|
+
"c = m.Counter('aabb')",
|
|
843
|
+
"top = c.most_common(1)",
|
|
844
|
+
"assrt.equal(top[0][0], 'a')",
|
|
845
|
+
"assrt.equal(top[0][1], 2)",
|
|
846
|
+
].join("\n"));
|
|
847
|
+
run_js(js);
|
|
848
|
+
},
|
|
849
|
+
},
|
|
850
|
+
|
|
851
|
+
{
|
|
852
|
+
name: "bundle___import__-fromlist",
|
|
853
|
+
description: "__import__ with fromlist returns the exact named module",
|
|
854
|
+
run: function () {
|
|
855
|
+
var repl = RS.web_repl();
|
|
856
|
+
var js = bundle_compile(repl, [
|
|
857
|
+
"from collections import deque",
|
|
858
|
+
"m = __import__('collections', None, None, ['deque'])",
|
|
859
|
+
"d = m.deque([1, 2, 3])",
|
|
860
|
+
"assrt.equal(len(d), 3)",
|
|
861
|
+
"assrt.equal(d.popleft(), 1)",
|
|
862
|
+
].join("\n"));
|
|
863
|
+
run_js(js);
|
|
864
|
+
},
|
|
865
|
+
},
|
|
866
|
+
|
|
867
|
+
{
|
|
868
|
+
name: "bundle___import__-error",
|
|
869
|
+
description: "__import__ raises ModuleNotFoundError for unknown module in web-repl",
|
|
870
|
+
run: function () {
|
|
871
|
+
var repl = RS.web_repl();
|
|
872
|
+
var js = bundle_compile(repl, [
|
|
873
|
+
"from collections import Counter",
|
|
874
|
+
"caught = False",
|
|
875
|
+
"try:",
|
|
876
|
+
" __import__('no_such_module')",
|
|
877
|
+
"except ModuleNotFoundError as e:",
|
|
878
|
+
" caught = True",
|
|
879
|
+
"assrt.ok(caught)",
|
|
880
|
+
].join("\n"));
|
|
881
|
+
run_js(js);
|
|
882
|
+
},
|
|
883
|
+
},
|
|
884
|
+
|
|
448
885
|
];
|
|
449
886
|
|
|
450
887
|
// ---------------------------------------------------------------------------
|
|
@@ -14,7 +14,7 @@ var path = require("path");
|
|
|
14
14
|
|
|
15
15
|
var SRC_DIR = path.join(__dirname, "..", "src", "monaco-language-service");
|
|
16
16
|
var COMPILER_JS = path.join(__dirname, "..", "web-repl", "rapydscript.js");
|
|
17
|
-
var DEFAULT_OUT = path.join(__dirname, "..", "
|
|
17
|
+
var DEFAULT_OUT = path.join(__dirname, "..", "language-service", "index.js");
|
|
18
18
|
|
|
19
19
|
// Parse --out flag
|
|
20
20
|
var out_path = DEFAULT_OUT;
|
|
@@ -124,7 +124,7 @@ var chunks = [
|
|
|
124
124
|
"// language-service.js — RapydScript Monaco Language Service",
|
|
125
125
|
"// Auto-generated by tools/build-language-service.js — do not edit directly.",
|
|
126
126
|
"// Source: src/monaco-language-service/ + web-repl/rapydscript.js (embedded)",
|
|
127
|
-
"// Usage: import { registerRapydScript } from '
|
|
127
|
+
"// Usage: import { registerRapydScript } from 'rapydscript-ns/language-service';",
|
|
128
128
|
"// No external compiler bundle needed — the compiler is bundled inside.",
|
|
129
129
|
"",
|
|
130
130
|
compiler_chunk,
|