babel: Could not traverse ClassPrivateMethod when estree plugin enabled

Bug Report

Current Behavior When I’m using estree and classPrivateMethods and try to traverse ClassPrivateMethod I get crash:

coderaiser@cloudcmd:~/issues$ node traverse.js
/home/coderaiser/issues/node_modules/@babel/traverse/lib/scope/index.js:667
      for (const param of params) {
                          ^

TypeError: params is not iterable
    at Scope.crawl (/home/coderaiser/@iocmd/issues/babel-traverse/node_modules/@babel/traverse/lib/scope/index.js:667:27)
    at Scope.init (/home/coderaiser/@iocmd/issues/babel-traverse/node_modules/@babel/traverse/lib/scope/index.js:634:32)
    at NodePath.setScope (/home/coderaiser/@iocmd/issues/babel-traverse/node_modules/@babel/traverse/lib/path/context.js:126:30)
    at NodePath.setContext (/home/coderaiser/@iocmd/issues/babel-traverse/node_modules/@babel/traverse/lib/path/context.js:141:8)
    at NodePath.pushContext (/home/coderaiser/@iocmd/issues/babel-traverse/node_modules/@babel/traverse/lib/path/context.js:207:8)
    at TraversalContext.visitQueue (/home/coderaiser/@iocmd/issues/babel-traverse/node_modules/@babel/traverse/lib/context.js:106:14)
    at TraversalContext.visitMultiple (/home/coderaiser/@iocmd/issues/babel-traverse/node_modules/@babel/traverse/lib/context.js:85:17)
    at TraversalContext.visit (/home/coderaiser/@iocmd/issues/babel-traverse/node_modules/@babel/traverse/lib/context.js:144:19)
    at Function.traverse.node (/home/coderaiser/@iocmd/issues/babel-traverse/node_modules/@babel/traverse/lib/index.js:94:17)
    at NodePath.visit (/home/coderaiser/@iocmd/issues/babel-traverse/node_modules/@babel/traverse/lib/path/context.js:95:18)

Input Code

  • REPL or Repo link if applicable:
const babel = require('@babel/parser');
const traverse = require('@babel/traverse').default;

const source = `
    class User {
        #set() {
        }

        #get() {
        }

        get() {
            return this.#get();
        }
    }
`;

const babelAST = babel.parse(source, {
    plugins: [
        'estree',
        'classPrivateMethods',
    ],
});

traverse(babelAST, {
    enter(path) {
        console.log('+');
    }
});

Expected behavior/code I expected no crash, regular traverse. Some time ago everything worked good, but after update everything is broke.

Environment @babel/parser: v7.3.2 @babel/traverse: v7.2.3

Possible Solution

params is empty in ClassPrivateMethod so path.get(‘params’) returns single path, not an array. MethodDefinition also has no params but it works good and not processed by this code.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 2
  • Comments: 19 (16 by maintainers)

Most upvoted comments

I propose this policy:

  1. Only adapt things in the estree @babel/parser plugin once they are part of the ESTree specification
  2. Experimental features use the normal Babel AST, even when estree is enabled
  3. If needed (for example, for https://github.com/babel/babel-eslint/issues/749), the experimental Babel AST can be adapted by @babel/eslint-parser so that it works with ESLint’s existing features
  4. When they became stage 4, we can “fix” the estree plugin and make it compliant. Every bugfix is technically breaking, and while this could break anyone relying on the old behavior it’s just because the old behavior wasn’t doing what they asked @babel/parser to do (i.e. follow the ESTree spec)

I think that we should never have an AST node which is neither Babel’s AST nor ESTree: we don’t need a new AST format.

Ok, calling babel.parse definitely shouldn’t do any scope analysis. It should only call parser.parse + all the config loading logic.