[gjs/ewlsh/nova-repl] Port to mozjs91




commit 297ed75451501e1b9dc088b0028fb0b78fbbd047
Author: Evan Welsh <contact evanwelsh com>
Date:   Sun Jan 16 17:34:39 2022 -0800

    Port to mozjs91

 js.gresource.xml            |   1 -
 modules/console.cpp         |   4 -
 modules/esm/_repl/cliffy.js |   4 +-
 modules/esm/_repl/deno.js   |  11 ---
 modules/esm/repl.js         | 211 +++++++++++++++++++++++---------------------
 tools/cliffy/transform.js   |   4 +-
 6 files changed, 111 insertions(+), 124 deletions(-)
---
diff --git a/js.gresource.xml b/js.gresource.xml
index c7b922db..6817f0b3 100644
--- a/js.gresource.xml
+++ b/js.gresource.xml
@@ -17,7 +17,6 @@
 
     <file>modules/esm/_timers.js</file>
 
-    <file>modules/esm/_repl/deno.js</file>
     <file>modules/esm/_repl/cliffy.js</file>
   
     <file>modules/esm/cairo.js</file>
diff --git a/modules/console.cpp b/modules/console.cpp
index 4dfaad64..aa80546a 100644
--- a/modules/console.cpp
+++ b/modules/console.cpp
@@ -32,10 +32,6 @@ namespace mozilla {
 union Utf8Unit;
 }
 
-static void gjs_console_warning_reporter(JSContext*, JSErrorReport* report) {
-    JS::PrintError(stderr, report, /* reportWarnings = */ true);
-}
-
 /* Based on js::shell::AutoReportException from SpiderMonkey. */
 class AutoReportException {
     JSContext *m_cx;
diff --git a/modules/esm/_repl/cliffy.js b/modules/esm/_repl/cliffy.js
index 9c59d47c..0f951ac3 100644
--- a/modules/esm/_repl/cliffy.js
+++ b/modules/esm/_repl/cliffy.js
@@ -2,7 +2,7 @@
 // SPDX-FileCopyrightText: 2022 Benjamin Fischer <c4spar gmx de>
 
 // Inject our shim for the Deno global...
-import * as Deno from './deno.js';
+const Deno = { noColor: false, build: { os: 'linux' } };
 let globalThis = { Deno };
 const base64abc = [
     "A",
@@ -561,7 +561,7 @@ function bgRgb24(str, color) {
     ], 49));
 }
 const ANSI_PATTERN = new RegExp([
-    "[\\u001B\\u009B][[\\]()$;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/$&.:=?%@~_]*)*)?\\u0007)",
+    "[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
     "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))", 
 ].join("|"), "g");
 function stripColor(string) {
diff --git a/modules/esm/repl.js b/modules/esm/repl.js
index b02d9902..7dac78ef 100644
--- a/modules/esm/repl.js
+++ b/modules/esm/repl.js
@@ -9,6 +9,7 @@ import {Ansi, Keycode} from './_repl/cliffy.js';
 const Console = import.meta.importSync('_consoleNative');
 
 // TODO: Integrate with new printer once it is merged...
+
 /**
  * @param {any} value any valid JavaScript value to stringify
  */
@@ -28,10 +29,15 @@ function toString(value) {
     return `${value}`;
 }
 
-const sInputHandler = Symbol('input handler');
-const sExitHandler = Symbol('exit handler');
-const sExitWarning = Symbol('exit warning');
 class ReplInput {
+    #inputHandler;
+    #exitHandler;
+    #exitWarning;
+
+    #prompt;
+    #cancelling = false;
+    #cancellable = null;
+
     /**
      * @param {object} _ _
      * @param {Gio.UnixOutputStream} _.stdin the input stream to treat as stdin
@@ -45,8 +51,8 @@ class ReplInput {
         this.stderr = stderr;
         this.enableColor = enableColor;
 
-        this._prompt = this._buildPrompt();
-        this._cancelled = false;
+        this.#prompt = this.#buildPrompt();
+        this.#cancelling = false;
 
         /**
          * Store previously inputted lines
@@ -76,24 +82,28 @@ class ReplInput {
          */
         this.cursorColumn = 0;
 
-        this[sInputHandler] =
+        this.#inputHandler =
             /**
              * @param {string} _input the inputted line or lines (separated by \n)
              */
             _input => { };
 
-        this[sExitWarning] = false;
+        this.#exitWarning = false;
     }
 
     [Symbol.toStringTag]() {
         return 'Repl';
     }
 
+    get cancelled() {
+        return this.#cancelling;
+    }
+
     /**
      * @param {string} pointer the pointer to prefix the line with
      */
-    _buildPrompt(pointer = '>') {
-        const renderedPrompt =  `${pointer} `;
+    #buildPrompt(pointer = '>') {
+        const renderedPrompt = `${pointer} `;
         const length = renderedPrompt.length;
 
         return {
@@ -146,11 +156,11 @@ class ReplInput {
     }
 
     exit() {
-        if (this[sExitWarning]) {
-            this[sExitWarning] = false;
-            this[sExitHandler]?.();
+        if (this.#exitWarning) {
+            this.#exitWarning = false;
+            this.#exitHandler?.();
         } else {
-            this[sExitWarning] = true;
+            this.#exitWarning = true;
             this.writeSync('\n(To exit, press Ctrl+C again or Ctrl+D)\n');
             this.flush();
         }
@@ -317,8 +327,8 @@ class ReplInput {
         if (this.validate(js)) {
             // Reset lines before input is triggered
             this.pendingInputLines = [];
-            this[sExitWarning] = false;
-            this[sInputHandler]?.(js);
+            this.#exitWarning = false;
+            this.#inputHandler?.(js);
         } else {
             // Buffer the input until a compilable unit is found...
             this.pendingInputLines.push(value);
@@ -437,7 +447,7 @@ class ReplInput {
             return ' '.padStart(4, '.');
         }
 
-        return this._prompt.renderedPrompt;
+        return this.#prompt.renderedPrompt;
     }
 
     render() {
@@ -476,17 +486,17 @@ class ReplInput {
         for (const event of Keycode.parse(bytes)) {
             this.handleEvent(event);
 
-            if (this._cancelled)
+            if (this.#cancelling)
                 break;
 
             this.render();
         }
     }
 
-    _asyncReadHandler(stream, result) {
-        this.cancellable = null;
+    #asyncReadHandler(stream, result) {
+        this.#cancellable = null;
 
-        if (this._cancelled)
+        if (this.#cancelling)
             return;
 
         if (result) {
@@ -495,14 +505,15 @@ class ReplInput {
             this.handleInput(gbytes.toArray());
         }
 
-        this.cancellable = new Gio.Cancellable();
-        stream.read_bytes_async(8, 0, this.cancellable, this._asyncReadHandler.bind(this));
+        this.#cancellable = new Gio.Cancellable();
+        stream.read_bytes_async(8, 0, this.#cancellable, this.#asyncReadHandler.bind(this));
     }
 
     cancel() {
-        this._cancelled = true;
-        this.cancellable?.cancel();
-        this.cancellable = null;
+        this.#cancelling = true;
+
+        this.#cancellable?.cancel();
+        this.#cancellable = null;
 
         this.writeSync('\n');
         this.flush();
@@ -512,7 +523,7 @@ class ReplInput {
         this.render();
 
         // Start the async read loop...
-        this._asyncReadHandler(this.stdin);
+        this.#asyncReadHandler(this.stdin);
     }
 
     /**
@@ -520,13 +531,13 @@ class ReplInput {
      * @param {(input: string) => void} inputHandler a callback when new lines are processed
      */
     prompt(inputHandler) {
-        this[sInputHandler] = inputHandler;
-        this._cancelled = false;
+        this.#inputHandler = inputHandler;
+        this.#cancelling = false;
         this.read();
     }
 
     onExit(exitHandler) {
-        this[sExitHandler] = exitHandler;
+        this.#exitHandler = exitHandler;
     }
 }
 
@@ -536,10 +547,14 @@ class FallbackReplInput extends ReplInput {
     }
 
     read() {
-        while (!this._cancelled) {
+        while (!this.cancelled) {
             const prompt = this.getPrompt();
             this.editValue(() => {
-                return Console.interact(prompt).split('');
+                try {
+                    return Console.interact(prompt).split('');
+                } catch {
+                    return '';
+                }
             });
 
             this.processLine();
@@ -559,43 +574,31 @@ class FallbackReplInput extends ReplInput {
     flush() { }
 }
 
-const sCheckEnvironment = Symbol('check environment');
-const sSupportsColor = Symbol('supports color');
-const sMainLoop = Symbol('main loop');
-
 export class Repl {
+    #lineNumber = 0;
+    #isRaw = false;
+
+    #supportsColor;
+    #mainloop;
+    #version;
+
     constructor() {
         ({Gio} = imports.gi);
 
-        this._version = imports.system.versionString;
-        this.lineNumber = 0;
-        this.isRaw = false;
-
-        Object.defineProperties(this, {
-            [sCheckEnvironment]: {
-                writable: true,
-                enumerable: false,
-                configurable: true,
-                value: this[sCheckEnvironment].bind(this),
-            },
-            [sSupportsColor]: {
-                writable: true,
-                enumerable: false,
-                configurable: true,
-                value: true,
-            },
-            [sMainLoop]: {
-                writable: true,
-                enumerable: false,
-                configurable: true,
-                value: null,
-            },
-        });
+        this.#version = imports.system.versionString;
     }
 
-    [sCheckEnvironment]() {
-        this[sSupportsColor] = GLib.log_writer_supports_color(1);
-        this[sSupportsColor] = this[sSupportsColor] && GLib.getenv('NO_COLOR') === null;
+    get lineNumber() {
+        return this.#lineNumber;
+    }
+
+    get isRaw() {
+        return this.#isRaw;
+    }
+
+    #checkEnvironment() {
+        this.#supportsColor = GLib.log_writer_supports_color(1);
+        this.#supportsColor &&= GLib.getenv('NO_COLOR') === null;
 
         let hasUnixStreams = 'UnixInputStream' in Gio;
         hasUnixStreams = hasUnixStreams && 'UnixOutputStream' in Gio;
@@ -603,19 +606,37 @@ export class Repl {
         if (!hasUnixStreams)
             return false;
 
+        const noMainLoop = GLib.getenv('GJS_REPL_NO_MAINLOOP');
         // TODO: Environment variable for testing.
-        if (GLib.getenv('GJS_REPL_NO_MAINLOOP'))
+        if (noMainLoop && noMainLoop === 'true')
             return false;
 
         return true;
     }
 
-    _evaluate(lines) {
+    #registerInputHandler() {
+        this.#print(`GJS v${this.#version}`);
+
+        // Start accepting input and rendering...
+        this.input.prompt(lines => {
+            if (lines.trim().startsWith('exit()'))
+                this.exit();
+            else
+                this.evaluate(lines);
+        });
+    }
+
+    #print(string) {
+        this.input.writeSync(`${string}${this.#isRaw ? '\n' : ''}`);
+        this.input.flush();
+    }
+
+    #evaluateInternal(lines) {
         try {
-            const result = Console.eval(lines, this.lineNumber);
+            const result = Console.eval(lines, this.#lineNumber);
 
             if (result !== undefined)
-                this._print(`${toString(result)}`);
+                this.#print(`${toString(result)}`);
 
             return null;
         } catch (error) {
@@ -623,64 +644,50 @@ export class Repl {
         }
     }
 
-    _printError(error) {
+    #printError(error) {
         if (error.message)
-            this._print(`Uncaught ${error.name}: ${error.message}`);
+            this.#print(`Uncaught ${error.name}: ${error.message}`);
         else
-            this._print(`${toString(error)}`);
+            this.#print(`${toString(error)}`);
     }
 
     evaluate(lines) {
-        this.lineNumber++;
+        this.#lineNumber++;
 
         // TODO(ewlsh): Object/code block detection similar to Node
         let wrappedLines = lines.trim();
         if (wrappedLines.startsWith('{') &&
-                !wrappedLines.endsWith(';'))
+            !wrappedLines.endsWith(';'))
             wrappedLines = `(${wrappedLines})\n`;
 
         // Attempt to evaluate any object literals in () first
-        let error = this._evaluate(wrappedLines);
+        let error = this.#evaluateInternal(wrappedLines);
         if (!error)
             return;
 
-        error = this._evaluate(lines);
+        error = this.#evaluateInternal(lines);
         if (!error)
             return;
 
-        this._printError(error);
-    }
-
-    _print(string) {
-        this.input.writeSync(`${string}${this.isRaw ? '\n' : ''}`);
-        this.input.flush();
+        this.#printError(error);
     }
 
-    _registerInputHandler() {
-        // Start accepting input and rendering...
-        this.input.prompt(lines => {
-            if (lines.trim().startsWith('exit()'))
-                this.exit();
-            else
-                this.evaluate(lines);
-        });
-    }
 
     run() {
-        if (!this[sCheckEnvironment]()) {
+        if (!this.#checkEnvironment()) {
             this.input = new FallbackReplInput();
 
-            this._registerInputHandler();
+            this.#registerInputHandler();
             return;
         }
 
         try {
-            this.isRaw = Console.enableRawMode();
+            this.#isRaw = Console.enableRawMode();
 
-            if (!this.isRaw) {
+            if (!this.#isRaw) {
                 this.input = new FallbackReplInput();
 
-                this._registerInputHandler();
+                this.#registerInputHandler();
                 return;
             }
 
@@ -692,16 +699,14 @@ export class Repl {
                 stdin,
                 stdout,
                 stderr,
-                enableColor: this[sSupportsColor],
+                enableColor: this.#supportsColor,
             });
 
             this.input.onExit(() => {
                 this.exit();
             });
 
-            this._print(`GJS v${this._version}`);
-
-            this._registerInputHandler();
+            this.#registerInputHandler();
 
             // Install our default mainloop...
             this.replaceMainLoop(() => {
@@ -710,13 +715,13 @@ export class Repl {
                 imports.mainloop.quit('repl');
             });
 
-            let mainloop = this[sMainLoop];
+            let mainloop = this.#mainloop;
             while (mainloop) {
                 const [start] = mainloop;
 
                 start();
 
-                mainloop = this[sMainLoop];
+                mainloop = this.#mainloop;
             }
         } finally {
             Console.disableRawMode();
@@ -726,8 +731,8 @@ export class Repl {
     exit() {
         this.input.cancel();
 
-        const mainloop = this[sMainLoop];
-        this[sMainLoop] = null;
+        const mainloop = this.#mainloop;
+        this.#mainloop = null;
 
         if (mainloop) {
             const [, quit] = mainloop;
@@ -744,8 +749,8 @@ export class Repl {
         if (!(this.input instanceof ReplInput))
             return;
 
-        const mainloop = this[sMainLoop];
-        this[sMainLoop] = [start, quit];
+        const mainloop = this.#mainloop;
+        this.#mainloop = [start, quit];
 
         if (mainloop) {
             const [, previousQuit] = mainloop;
diff --git a/tools/cliffy/transform.js b/tools/cliffy/transform.js
index 2c2a1b90..aa2268c1 100644
--- a/tools/cliffy/transform.js
+++ b/tools/cliffy/transform.js
@@ -8,14 +8,12 @@ const file = Gio.File.new_for_commandline_arg(System.programArgs[0]);
 const [, contents] = file.load_contents(null);
 
 let source = new TextDecoder().decode(contents);
-// Remove all private variable names until mozjs91 is supported.
-source = source.replace(/#/g, '$');
 source =
     `// SPDX-License-Identifier: MIT
 // SPDX-FileCopyrightText: 2022 Benjamin Fischer <c4spar gmx de>
 
 // Inject our shim for the Deno global...
-import * as Deno from './deno.js';
+const Deno = { noColor: false, build: { os: 'linux' } };
 let globalThis = { Deno };
 ${source}`;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]