davidbonnet / astring

🌳 Tiny and fast JavaScript code generator from an ESTree-compliant AST.

Home Page:https://david.bonnet.cc/astring/demo/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Does not handle undefined private properties

brev opened this issue · comments

Hello, thanks for the great code!

Motivation

Uninitialized private properties in ESnext classes are failing under generate():

import { generate } from 'astring'
import { parse } from 'meriyah'

const src = `
  class Mine {
    #attribute

    constructor() {
      this.#attribute = 'hello'
    }
  }
`

const ast = parse(src, { module: true, next: true })
console.dir(ast, {depth:null})

const result = generate(ast)  // FAILURE!
console.dir(result)

Here is an example of this style of code in the wild:
https://github.com/node-fetch/fetch-blob/blob/main/from.js#L60-L65

Expected behavior

Should generate() code much like the original src above.

Actual behavior

Error:

file:///Users/brev/Desktop/tmp/node_modules/astring/dist/astring.mjs:830
    this[node.value.type](node.value, state)
                    ^
TypeError: Cannot read properties of null (reading 'type')
    at Object.PropertyDefinition (file:///Users/brev/Desktop/tmp/node_modules/astring/dist/astring.mjs:830:21)
    at Object.BlockStatement (file:///Users/brev/Desktop/tmp/node_modules/astring/dist/astring.mjs:286:29)
    at Object.ClassDeclaration (file:///Users/brev/Desktop/tmp/node_modules/astring/dist/astring.mjs:529:10)
    at Object.Program (file:///Users/brev/Desktop/tmp/node_modules/astring/dist/astring.mjs:261:27)
    at generate (file:///Users/brev/Desktop/tmp/node_modules/astring/dist/astring.mjs:1165:29)
    at file:///Users/brev/Desktop/tmp/index.js:18:16
    at ModuleJob.run (node:internal/modules/esm/module_job:197:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:337:24)
    at async loadESM (node:internal/process/esm_loader:88:5)

I believe this is an example of the failing section of the AST:

  {
    type: 'PropertyDefinition',
    key: { type: 'PrivateIdentifier', name: 'attribute' },
    value: null,
    static: false,
    computed: false,
    decorators: []
  },

Thanks @brev for raising the issue. Indeed, the value of a PropertyDefinition can be null.