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

Babel Parser with estree plugin non passive change regarding ChainedExpression #11908

Closed
1 task
mjhenkes opened this issue Aug 3, 2020 · 3 comments
Closed
1 task
Labels
i: question outdated A closed issue/PR that is archived due to age. Recommended to make a new issue

Comments

@mjhenkes
Copy link

mjhenkes commented Aug 3, 2020

Bug Report

  • I would like to work on a fix!

Current behavior
Previously babel parser, using the estree plugin, would read optional chaining as a OptionalMemberExpression, now the optional chain is broken into two nodes a ChainExpression and a MemberExpression.

This change was made in: #11815

I stumbled upon this while trying to use react-doc-gen against a component with optional chanining and the ast-types library that it uses fails when it tries to understand the ChainExpression type.

Input Code
I have setup a repo to recreate the issue here:

https://github.com/mjhenkes/babel-parser-test

It contains sample AST outputs that can be compared from version 1.11.0 and 1.10.5.

Expected behavior

Is this considered a breaking change? If so i'd expect it to be included in a major version.

Or is it a bug in ast-types that ChainExpression isn't supported?

Babel Configuration (babel.config.js, .babelrc, package.json#babel, cli command, .eslintrc)

  • Filename: babel.config.js

Below is how i'm calling the babel parser.

const babel = require('@babel/core');
const fs = require('fs');

const filePath = './class.jsx';

const source = fs.readFileSync(filePath, 'utf8');

const options = {
  parserOpts: {
    plugins: [
      'jsx',
      'flow',
      'asyncGenerators',
      'bigInt',
      'classProperties',
      'classPrivateProperties',
      'classPrivateMethods',
      'doExpressions',
      'dynamicImport',
      'exportDefaultFrom',
      'exportNamespaceFrom',
      'functionBind',
      'functionSent',
      'importMeta',
      'logicalAssignment',
      'nullishCoalescingOperator',
      'numericSeparator',
      'objectRestSpread',
      'optionalCatchBinding',
      'optionalChaining',
      'throwExpressions',
      'topLevelAwait',
      'estree',
    ],
  },
};

const ast = babel.parseSync(source, options);

console.log('parsed', JSON.stringify(ast, null, 2));

Environment


  • Babel version(s): 7.11.0
  • Node/npm version: 10
  • OS: OSX 10.15.5
  • Monorepo: no
  • How you are using Babel: parser?

Possible Solution

Additional context
Example diff of the AST as well as i could make in MD 🤷‍♂️

-    "type": "OptionalMemberExpression",
+    "type": "ChainExpression",
+    "start": 175,
+    "end": 187,
+    "loc": {
+      "start": {
+        "line": 9,
+        "column": 17
+      },
+      "end": {
+        "line": 9,
+        "column": 29
+      }
+    },
+    "expression": {
+      "type": "MemberExpression",
      "start": 175,
      "end": 187,
      "loc": {
        "start": {
          "line": 9,
          "column": 17
        },
        "end": {
          "line": 9,
          "column": 29
        }
      },
      "object": {
        "type": "Identifier",
        "start": 175,
        "end": 180,
        "loc": {
          "start": {
            "line": 9,
            "column": 17
          },
          "end": {
            "line": 9,
            "column": 22
          },
          "identifierName": "thing"
        },
        "name": "thing"
      },
      "property": {
        "type": "Identifier",
        "start": 182,
        "end": 187,
        "loc": {
          "start": {
            "line": 9,
            "column": 24
          },
          "end": {
            "line": 9,
            "column": 29
          },
          "identifierName": "stuff"
        },
        "name": "stuff"
      },
      "computed": false,
      "optional": true
    }
  }
+ }
@babel-bot
Copy link
Collaborator

Hey @mjhenkes! We really appreciate you taking the time to report an issue. The collaborators on this project attempt to help as many people as possible, but we're a limited number of volunteers, so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack community that typically always has someone willing to help. You can sign-up here for an invite."

@JLHwung
Copy link
Contributor

JLHwung commented Aug 3, 2020

The change is intentional: estree does not support experimental features so when optional chaining was a proposal, Babel used own AST. When estree supports optional chaining in a way different to Babel's AST design, we have to implement changes in the estree plugin. In this case, it is considered a new feature because optional chaining's estree AST is never well-defined before.

See also #9506 (comment)

@mjhenkes
Copy link
Author

mjhenkes commented Aug 3, 2020

Thanks @JLHwung, to close the loop here I've logged an enhancement/bug asking for ast-types to support the ChainExpression type.

@JLHwung JLHwung closed this as completed Aug 3, 2020
@github-actions github-actions bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Nov 3, 2020
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 3, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
i: question outdated A closed issue/PR that is archived due to age. Recommended to make a new issue
Projects
None yet
Development

No branches or pull requests

3 participants