Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError: Class constructor Lexer cannot be invoked without 'new' #326

Open
fdeitelhoff opened this issue Jun 27, 2017 · 29 comments
Open
Assignees

Comments

@fdeitelhoff
Copy link

fdeitelhoff commented Jun 27, 2017

I'm having trouble setting up the TypeScript target for ANTLR4 in my NodeJS + Angular environment.

The automatic generation from my grammars are working fine, but the following problem occurred in my code:

ERROR TypeError: Class constructor Lexer cannot be invoked without 'new'
    at new SimplexLexer (SimplexLexer.ts:111)
    at AppComponent.webpackJsonp.../../../../../src/app/app.component.ts.AppComponent.handler (app.component.ts:23)
    at Object.eval [as handleEvent] (AppComponent.html:1)
    at handleEvent (core.es5.js:12047)
    at callWithDebugContext (core.es5.js:13506)
    at Object.debugHandleEvent [as handleEvent] (core.es5.js:13094)
    at dispatchEvent (core.es5.js:8659)
    at core.es5.js:9270
    at HTMLButtonElement.<anonymous> (platform-browser.es5.js:2668)
    at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:424)

At this time I'm doing just this:

import { ANTLRInputStream, CommonTokenStream } from 'antlr4ts';
import { SimplexLexer } from './../simplex/grammar/SimplexLexer';
import { SimplexParser } from './../simplex/grammar/SimplexParser';

const inputStream = new ANTLRInputStream('text');
const simplexLexer = new SimplexLexer(inputStream);

I've tried various ways of generating code from my grammar files. The current solution looks like this:

"antlr4ts": "cd src/simplex/grammar/ && antlr4ts -listener -lib . SimplexParser.g4 SimplexLexer.g4"

Is there a fix or something? I think I will switch to the JavaScript target in the meantime because I think it is working.

Edit: Ok, I have to revert the statement that the JavaScript target works. Looks like I run into some problems within my TypeScript environment and the generated JavaScript target. :(

@fdeitelhoff
Copy link
Author

Another update:

I changed the target to "ES6" and the errors are gone.

But there are new ones. :) For example "SimplexContext is not defined". (Simplex is my grammar). I found out that if I move the complete SimplexParser from the SimplexParser.ts at the bottom of the generated file, everything works fine. TypeScript is much more restrictive on the order of types within a file (my guess).

Is this a problem on my side or do we have to modify the TypeScript generation process?

@BurtHarris
Copy link
Collaborator

Thanks for reporting this Fabian. So far we've only been testing with an ES6 target: specifically Node.JS is the only environment tested to date. Are you trying to build for browser execution? That's on our future goals list.

I've just come back from a vacation, and will have more time to look this over shortly, particularly the second problem you've reported, which sound strange. If you could share a source-code snapshot I could reproduce this with, I'll have a look, probably today.

@BurtHarris
Copy link
Collaborator

@fdeitelhoff, I've not been able to reproduce the SimplexContext is not defined message, but guess you may be having problems with the tsc options. Here's a minimal tsconfig.json that should work:

{
  "compilerOptions": {
    "target": "es2015",                 /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
    "module": "commonjs",               /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */
    "lib": ["es2015"],                  /* Specify library files to be included in the compilation:  */
    "sourceMap": true,                  /* Generates corresponding '.map' file. */
    "strict": true,                     /* Enable all strict type-checking options. */
    "experimentalDecorators": true      /* Enables experimental support for ES7 decorators. */
  }
}

@fdeitelhoff
Copy link
Author

fdeitelhoff commented Jun 29, 2017

@BurtHarris Thanks for the info. This is my configuration at the moment:

{
  "compileOnSave": false,
  "compilerOptions": {
    "outDir": "./dist/out-tsc",
    "baseUrl": "src",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es6",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2016",
      "dom"
    ]
  }
}

Not quite sure if the es6 and es2016 are actually good to solve my previous error message or if this can cause other problems.

Update: I still get the SimplexContext is not defined error with all targets pointing to es2015.

@BurtHarris
Copy link
Collaborator

@fdeitelhoff, Can you please share a repository that demonstrates the SimplexContext is not defined message?

P.S. I've just discovered some incompatibilities with TypeScript@2.4.1, not sure if that's involved.

@fdeitelhoff
Copy link
Author

@BurtHarris You can use my "real" test repository: https://github.com/fdeitelhoff/Simplex-Game-Web

A clone and npm install should do the magic. There's a npm script that creates the grammar.

I'm currently on a conference and don't have the time & space to provide a special repository. But maybe you can reproduce the error with the "real" test repository.

Thank you for your help so far! Very appreciated.

@BurtHarris
Copy link
Collaborator

@fdeitelhoff Thanks, I've started looking (and learning.) No special repo needed, I'm interested in what you are doing.

For me, npm install generated no errors. I also tried npm run build and npm start both of which looks successful as well. Chrome against localhost:4200 seems to give a functional editor.

I dropped a try.ts into src with the following content, still no errors:

import { ANTLRInputStream, CommonTokenStream } from 'antlr4ts';
import { SimplexLexer } from './simplex/gen/SimplexLexer';
import { SimplexParser } from './simplex/gen/SimplexParser';

const inputStream = new ANTLRInputStream('text');
const simplexLexer = new SimplexLexer(inputStream);

Still no error. How do I reproduce the "SimplexContext is not defined" message?

@fdeitelhoff
Copy link
Author

@BurtHarris Oh sorry. I manually corrected the generated Simplex ANTLR4 code that's already in the repository.

Try this command to generate a new set of files: npm run antlr4ts

In the generated files there's the error.

@BurtHarris
Copy link
Collaborator

BurtHarris commented Jul 1, 2017

@fdeitelhoff . My mistake on the tsconfig issue.

I've opened #329 - Update codgen templates to supporess TSLint warnings to suppress the TSLint errors in our generated code that your example points up. I've Temporarily suppressed them using // tslint:disable, but I've still not seen that SimplexContext is not defined message.

In Visual Studio Code's "Output" window for "tslint", I see this warning. Could you be mistaking a lint error for a compiler error? I've not found TypeScript to require declaration before use!

[Info  - 8:19:38 AM] Linter is running.
Warning: The 'no-use-before-declare' rule requires type checking

P.S. In Visual Studio Code's "Problems" windows, after running npm build, I am now seeing 251 errors in \dist\assets\monaco-editor\Monaco.d.ts, starting with:

file: 'file:///c%3A/code/Simplex-Game-Web/dist/assets/monaco-editor/monaco.d.ts'
severity: 'Error'
message: 'Duplicate identifier 'Emitter'.'
at: '30,18'
source: 'ts'

P.S: I left you a private message on https://gitter.im

@fdeitelhoff
Copy link
Author

@BurtHarris Okay, weird. If I'm generating the new files with npm run antlr4ts and starting the application with npm run I got the error. But I got it within the browser, not within VS Code or somewhere else!

simplex-error

@BurtHarris
Copy link
Collaborator

Hmm, I don't know much about webpack, it's on my reading list... Could this have something to do with that?

@fdeitelhoff
Copy link
Author

@BurtHarris Sorry, late reply. I'm not into webpack that much, too. It is possible that the packing is the source of the problem. But hard to say in the current scenario.

But I assume that you've reproduced the error? Just to conform that I'm not stupid. :)

@BurtHarris BurtHarris self-assigned this Jul 12, 2017
@BurtHarris
Copy link
Collaborator

BurtHarris commented Jul 12, 2017

Frankly I don't remember if I've reproduced the error right now, but I'll take a look again.

@fdeitelhoff
Copy link
Author

@BurtHarris No problem. Don't worry and don't hurry. :)

My language is 99% fixed so there's no real need to generate it over and over again. Therefore the manual fix is fine for me.

But we should investigate in more detail if we might think this could be a general problem.

@BurtHarris
Copy link
Collaborator

Update: the original problem, message saying **TypeError: Class constructor Lexer cannot be invoked without 'new' ** is caused by a mismatch between the code generation target we used for building the antlr4ts runtime (which was es2015) and occurs when its called from code transpiled using the default target (which is es5).

JavaScript native class support is used when the target is es2015, and those native classes can't be extended using the code TypeScript generates when target is es5!

@marjan-georgiev
Copy link

@BurtHarris is there any way to fix the Class constructor Lexer cannot be invoked without 'new' without changing the target to es2015? We are using angular 4.x, and it is currently not supporting es2015 as a build target. (angular/angular#15127)

I would be open to manually changing the generated antlr files if that would help.

@BurtHarris
Copy link
Collaborator

@marjan-georgiev, frankly I don't know.

Supporting multiple targets in a complex TypeScript package like this seems like something there should be best practices on, but as of now I'm not sure what they are. I think it's tied into supporting browser-based execution, and I've simply not done browser coding for ten years or more. If you're an Angular user, you may have a better idea on how to do this than I do, can you point to any articles explaining how to do so?

@pluthraarkin
Copy link

Are there any updates on es5 support for antlr4ts? We also need it for our project.

@BurtHarris
Copy link
Collaborator

BurtHarris commented Feb 15, 2018

Sorry, I think both Sam and I have been busy with other matters. We could really use at least one more developer who has skills and interest to contribute some to the project. ES5 support I think is within reach, but I've got very little browser experience and that seems to be where it's really needed.

@sjkillen
Copy link

I also get this error and my tsconfig.json target is "esnext".
I've tracked the error down to something from babel.js, which in my setup runs after typescript in webpack.json. Babel seems to be performing the super call to Lexer incorrectly.
For now, I fixed the error by removing all babel plugins that affect classes (for me this was just the "env" preset)

@v3rb0s3
Copy link

v3rb0s3 commented May 16, 2019

I'm encountering this issue as well. I'm using the most basic setup imaginable, with nothing installed but node.js (12.2.0), typescript (3.3.1), and antlr4ts (0.5.0-alpha.3), and a minimalistic grammar. I don't specifically care about the target, and have tried various ones (es5, es6, es2015, es2018) without success. Does anybody have a hint what I need to do to make this work?

@sarod
Copy link

sarod commented May 16, 2019

I'm using babel with preset-typescript and I have the same " Class constructor Lexer cannot be invoked without 'new'" error

@sharwell
Copy link
Member

sharwell commented Jun 4, 2019

@v3rb0s3 Can you provide an example project to reproduce this?

@sdiguana
Copy link

sdiguana commented Jul 10, 2019

I've just spent the last several evenings on the same issue (" Class constructor Lexer cannot be invoked without 'new'" error). As @Spensaur-K mentioned, babel is breaking the super() call for the lexer.

I've changed the following things to finally get it resolved:

  1. tsconfig.json for my parser was set to target: es2015, module: es2015
  2. babel presets were altered as follows:
    browsers: [">0.5%", "not ie 11", "not op_mini all", "not samsung 4" ]

Item 1 may not be required, e.g. leaving commonjs as the module type (antlr4ts still is commonjs, hence why i think my modules being changed isn't the real solution).
Item 2 i think is because babel is going too far back in time, something is getting garbled in the transpiling. the browsers list was to ensure all supported arrows so they wouldn't get downgraded to functions. i figured if arrows are supported, whatever else needed to be is too.

for reference my project is browser facing. If i run unit tests in mocha, i have to set modules to commonjs. then back to es2015 for the web project.

@BurtHarris
Copy link
Collaborator

@sdiguana, that sounds big. Can you share a repro where you have it working in a browser based context. I would like to understand in more detail what you accomplished. We can certainly have typescript generate both the commonjs and es2015 module formats into separate directories by having two different tsconfig.json files.

@sdiguana
Copy link

sdiguana commented Jul 12, 2019

@BurtHarris Let me know if this is enough information:
I have two projects, one is the antlr based calculator, the second is a Nuxt.js based website. I build the calculator and then drop the es6 module js files into the browser's project at the moment. There is a dependency on antlr4ts for the browser project.

ANTLR Calculator project:
Use Module: CommonJS for testing with mocha
Use Module: ES2015 for sending to browser project

Calculator: https://github.com/sdiguana/XCalc

relevant web project details:
XCalc.vue
nuxt.config.js
I pushed the existing calculator onto my site so you can play with it if you like.

a few notes:
. the calculator was used to teach myself antlr and typescript... so it needs some work before its more than a toy
. for the browser project, if the above isn't enough i can clean the API keys and pass it to you privately.
. im still not certain that building my antlr project as es2015 is required. at present, if i don't, i get exports is not defined issues on the browser project. However antlr4ts is in commonjs, and the project understands it, hence why i think i just haven't spent enough time rooting around in my own settings to make it so i can build commonjs too.
. as noted previously, i suspect that the babel settings i listed above solve the invalid super() call.

@BurtHarris
Copy link
Collaborator

I'll have a look, thanks.

@crainsaw
Copy link

crainsaw commented Apr 5, 2020

In my case I was able to solve the issue by explicitly defining the tsconfig file for ts-jest in the jest config. In my case in the package.json:

{
  // [...]
  "jest": {
    "globals": {
      "ts-jest": {
        "tsConfig": "test/tsconfig.json"
      }
    }
  }
}

It seems that ts-jest ignored my tsconfig file in which I already had specified es2015 as a build target. My tsconfig for my tests test/tsconfig.json looks like that:

{
  "include": [
    "./**/*"
  ],
  "extends": "../tsconfig_base",
  "references": [
		{ "path": "../antlr_ts_build/" },
		{ "path": "../src/" }
  ],
  "compilerOptions": {
    // strictPropertyInitialization need to be disabled when using antlr4ts and variables (otherwise build will fail)
    "strictPropertyInitialization": false
  }
}

With tsconfig_base.json beeing in my root folder with the following options set:

"compilerOptions": {
    "target": "es2015",
    "module": "commonjs",
    "lib": ["ES2015"],
}

I hope it helps anybody.

@albanx
Copy link

albanx commented Oct 19, 2021

if you use an old version of ts-jest, use this config (tsConfigFile):

{
  "jest": {
    "globals": {
      "ts-jest": {
        "tsConfigFile": "test/tsconfig.json"
      }
    }
  }
}

Make sure the test/tsconfig.json has the target set to es5. This worked for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests