esprima icon indicating copy to clipboard operation
esprima copied to clipboard

Support class fields

Open sanderd17 opened this issue 6 years ago • 3 comments

Support for class fields (currently stage-3 proposal) is missing.

The class fields proposal is currently in Stage 3, and has a working implementation in Chrome, as well as being implemented in some other AST parsers (like babel).

I don't know at what stage features are normally added to esprima, but stage 3 looks like a solid stage to me.

Steps to reproduce

Parsing a class with a field just gives an Unexpected token error on the =-sign (expects a function with parentheses).

esprima.parse(`
class MyClass {
    myField = 1;
    #myPrivateField = 2;
}
`)

Expected output

Babel calls it a ClassProperty, with an key and value.

            {
              "type": "ClassProperty",
              "start": 15,
              "end": 28,
              "loc": { ... },
              "computed": false,
              "key": {
                "type": "Identifier",
                "start": 15,
                "end": 22,
                "loc": { ... },
                "name": "myField"
              },
              "static": false,
              "value": {
                "type": "Literal",
                "start": 25,
                "end": 28,
                "loc": { ... },
                "value": "1",
                "rawValue": "1",
                "raw": "'1'"
              }
            },

Private fields (starting wit #) are called a PrivateClassProperty.

Relevant references

https://github.com/tc39/proposal-class-fields

sanderd17 avatar May 07 '19 12:05 sanderd17

Sorry for my English. I work through this with a monkey patch in the dist version esprima.js

Add these code in method parseClassElement, before the throwUnexpectedToken is called:

if (!kind && key && this.match('(')) {
    kind = 'init';
    value = isAsync ? this.parsePropertyMethodAsyncFunction() : this.parsePropertyMethodFunction();
    method = true;
}
// === custom code start ===
if (!kind && key && this.match('=')) {
    console.log('Warning: custom esprima for class field assignment expression: ' + token.value);
    const left = new Node.Identifier(token.value);
    this.nextToken();
    const right = this.isolateCoverGrammar(this.parseAssignmentExpression);
    return this.finalize(node, new Node.AssignmentExpression('=', left, right));
}
// === custom code end ===
if (!kind) {
    this.throwUnexpectedToken(this.lookahead);
}

It's only for the base assignment expression in class field, no static, no private. And I don't know if this will lead to other problems. But, it's enough for my project.

tringcooler avatar Jun 20 '20 11:06 tringcooler

This is in ES2022 https://github.com/estree/estree/blob/master/es2022.md

ljqx avatar May 13 '21 05:05 ljqx

I've created a patch forthis in my fork: https://github.com/node-projects/esprima-next/pull/11 I'll will create a pull here, when there are signs that someone would merge it.

jogibear9988 avatar Jun 20 '21 17:06 jogibear9988