Local identifier from an import specifier is ignored
prantlf opened this issue · comments
When printing a modified AST, after removing one import specifier and inserting another one with different imported and local specifiers, the local identifier is ignored.
Original statement:
import { parse, print } from "fast-nls"
Desired statement:
import { load as $loadMessages$, print } from "fast-nls"
Obtained statement:
import { $loadMessages$, print } from "fast-nls"
The imported identifier load
is missing.
Details
Let us remove the parse
specifier and insert load as $loadMessages$
:
const { parse, print, types } = require('recast')
const { builders: b } = types
let ast = parse('import { parse, print } from "fast-nls"')
let { specifiers } = ast.program.body[0]
specifiers.splice(0, 1)
specifiers.unshift(b.importSpecifier(
b.identifier('load'), b.identifier('$loadMessages$')))
print(ast).code
Result:
import { $loadMessages$, print } from "fast-nls"
The imported identifier load
was not included in the printed code.
When omitting the removal of parse
:
let { specifiers } = ast.program.body[0]
- specifiers.splice(0, 1)
The new import specifier becomes complete:
import { load as $loadMessages$, parse, print } from "fast-nls";
It appears, that if the count of import specifiers does not change, the presence of imported and local identifiers is not checked. If original import specifiers did not contain different imported and local identifiers, the newly inserted ones at the position of previous ones will be printed with local identifiers only.
Workaround - force recast
to reprint the specifier, although it was newly created:
specifiers.unshift(b.importSpecifier(
b.identifier('load'), b.identifier('$loadMessages$')))
+ specifiers[0].original = null
I wonder why it works or what it breaks.