mike-lischke / antlr4ng

Next Generation TypeScript runtime for ANTLR4
Other
85 stars 15 forks source link

Issue with ReferenceError "u0 is not defined" in production mode #27

Closed pdalibor closed 8 months ago

pdalibor commented 8 months ago

We encountered an issue when upgrading from antlr4ts and antlr4-c3 to their latest versions at a time (antlr4-c3 v3.3.5 and antlr4ng v2.0.4). While there were no issues in Angular (v17) development mode, we encountered a runtime error in a production mode with the scripts optimization flag set to true in angular.json. The error message was: "ReferenceError: u0 is not defined." The error points to the following part of the minified JavaScript code:

yv =
          (new u0(),
          class {
            name = "";
            index = 0;
            data;
            constructor(t) {
              let e = [];
              for (let n of t) e.push(n.codePointAt(0));
              this.data = new Uint32Array(e);
            }
            reset() {
              this.index = 0;
            }
            consume() {
              if (this.index >= this.data.length)
                throw new Error("cannot consume EOF");
              this.index += 1;
            }
            LA(t) {
              if (0 === t) return 0;
              t < 0 && (t += 1);
              let e = this.index + t - 1;
              return e < 0 || e >= this.data.length ? F.EOF : this.data[e];
            }
            mark() {
              return -1;
            }
            release(t) {}
            seek(t) {
              t <= this.index
                ? (this.index = t)
                : (this.index = Math.min(t, this.data.length));
            }
            getText(t, e) {
              let n, r;
              return (
                t instanceof Pe
                  ? ((n = t.start), (r = t.stop))
                  : ((n = t), (r = e ?? this.data.length - 1)),
                r >= this.data.length && (r = this.data.length - 1),
                n >= this.data.length ? "" : this.#e(n, r + 1)
              );
            }
            toString() {
              return this.#e(0);
            }
            get size() {
              return this.data.length;
            }
            getSourceName() {
              return this.name ? this.name : pc.UNKNOWN_SOURCE_NAME;
            }
            #e(t, e) {
              let n = this.data.slice(t, e),
                r = "";
              return (
                n.forEach((i) => {
                  r += String.fromCodePoint(i);
                }),
                r
              );
            }
          }),

In our code, we initialize the lexer and parser as follows:

const inputCharStream = CharStreams.fromString(input);
const lexer = new FilterQueryLexer(inputCharStream);
const parser = new FilterQueryParser(new CommonTokenStream(lexer));

The methods from the problematic section of the JavaScript code are defined in the antlr4ng CharStream.

We attempted to upgrade antlr4ng to version 2.0.8 to address the issue but encountered a compile error as described in https://github.com/mike-lischke/antlr4ng/issues/26 Then, we made a temporary workaround: Changed default[] to any[] as suggested in the mentioned issue, but the error persisted (slightly different javascript code: new u0(), class is now new u0, class

mike-lischke commented 8 months ago

Usually, such an error comes up when you try to import a file it is being processed already (aka circular dependencies). However, because of the bundle this should not be an issue at all.

The code from your report seems to indicate this is about the CharStreamImpl class, which is used by CharStreams. I don't know Angular (and guess it uses webpack under the hood), so it might be that the CharStreamImpl has been optimized out with your setting.

pdalibor commented 8 months ago

CharStreamImpl seems to be available, but I was unable to identify the real reason for the error. Despite that, I was able to solve the problem. For anyone else encountering the same issue in an Angular application, here is what I have done:

In Angular 17, the default builder has been changed from webpack to esbuild package bundler. This means that in the angular.json file, "builder": "@angular-devkit/build-angular:browser" needs to be replaced with "builder": "@angular-devkit/build-angular:application".

mike-lischke commented 8 months ago

Glad you could solve the issue and thanks for letting us know. Closing this one then...