简体   繁体   中英

Babel, Maximum call stack size exceeded while using path.replaceWith

I was trying to play with babel modules, babylon , babel-traverse . When I tried to replace a node, the program crashed with Maximum call stack size exceeded . Here is my code

import * as babylon from 'babylon'
import traverse from 'babel-traverse'
import generate from 'babel-generator'
import * as t from 'babel-types'


const code = `
import a from 'b'
n === 3
`
const ast = babylon.parse(code, {
  sourceType: 'module'
})

const visitor = {
  BinaryExpression(path) {
    console.log((path.node))
    path.replaceWith(t.binaryExpression('**', t.numericLiteral(3), t.numericLiteral(4)))
  }
}

traverse(ast, visitor)

let generated = generate(ast, null, code)
console.log(generated.code)

And I'am using below babel dependencies, any idea?

"dependencies": {
"babel-generator": "^6.9.0",
"babel-preset-es2015": "^6.9.0",
"babel-traverse": "^6.9.0",
"babel-types": "^6.9.1",
"babylon": "^6.8.0"
}

The reason you're getting a stack error is because your binary expression replacement generates another binary expression. Your replacement binary expression is fed into the visitor over and over again, ad infinitum.

To break the infinite loop, you need to check whether your replacement has already occurred, possibly by ignoring the replaceWith step whenever you see the operator is ** .

Adding the new binaryExpression while you have a visitor on BinaryExpression causes the new binaryExpression to be visited, and so it is an infinite loop. You can call path.skip after path.replaceWith to skip visiting the new expression.

path.replaceWith(t.binaryExpression('**', t.numericLiteral(3), t.numericLiteral(4)))
path.skip()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM