question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ANTLR4 runtime cannot be transpiled to ES5 because of incorrect inheritance

See original GitHub issue

Background

Web applications must be transpiled to ECMAScript 5 (ES5) if they need to support older JavaScript runtimes, for example Internet Explorer or hardware devices that shipped with older JavaScript engines. In the past, the ANTLR runtime was written using ES5 compatible code. But version 4.9.x recently introduced ES6 class definitions that require transpilation. This is fine.

However, the ANTLR library has some classes that inherit from the system Error class, which is incompatible with transpilation. The reason is that ES5 system APIs are modeled as ES6 classes, which use a different inheritance mechanism from transpiled classes. (See this article for some details.)

Repro

  1. Transpile ANTLR4 to ES5 and bundle it into a web application.

This code fails to catch LexerNoViableAltException:

                    catch (e) {
                        if (e instanceof RecognitionException) {
                            this.notifyListeners(e); // report error
                            this.recover(e);
                        }
                        else {
                            console.log(e.stack);
                            throw e;
                        }
                    }

The e instanceof RecognitionException test returns false, even though LexerNoViableAltException inherits from RecognitionException. This happens because of the incorrect prototype introduced when RecognitionException inherits from the Error base class.

Possible fixes

The two standard solutions are:

  1. Don’t inherit from the Error class; instead simply implement its contract using a custom base class. This will break instanceof Error, but generally nobody ever tests that, so this approach works fine in practice. The callstack property can be calculated using (new Error()).stack. - OR -
  2. Call Object.setPrototypeOf() in the constructor for every subclass of the Error class. This also works pretty well. Its main downside is that people sometimes forget to apply the workaround when adding new subclasses.

I would be willing to make a PR to fix this. Would you accept a fix?

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:29 (14 by maintainers)

github_iconTop GitHub Comments

6reactions
ericvergnaudcommented, Jan 20, 2021

I’m about to close this since this is not an ANTLR4 runtime issue.

BTW the TypeScript compiler maintainers replied and said they will not implement Babel’s solution because it requires too much extra code. Their behavior is “by design”.

My advice is: don’t use tools written by lazy people (it not incompetent)

1reaction
ericvergnaudcommented, Feb 1, 2021

@octogonz can you move your last comment to the PR itself - best to discuss there ?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Transpiling ES6 to ES5 with module loading and class ...
I was using traceur to transpile my code just fine and things have been running well ... So, the auto detection fails with...
Read more >
npmsearchfullcat_npm143.txt - GitHub
=jtblin 2014-02-24 0.0.6 model inherit extend augment object validation active ... JavaScript Runtime Library =herry13 2012-06-12 0.0.3 antlr antlr3 runtime ...
Read more >
N4JS Design Specification - Eclipse
However, in the context of N4JS, the target output is not machine code ... For inherited members no output code has to be...
Read more >
What is the problem with languages that compile into ... - Quora
First, that's not “everyone”, some people think JS is the greatest language ever made… :-) Not going this far, once you get to...
Read more >
Embedded Scripting Languages
User content; Allow application runtime changes without ... License: MPL 2; Implementation: C; Syntax type: ES5 - Javascript (ECMaScript).
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found