99import fs from "fs" ;
1010import path from "path" ;
1111
12- import { generate as astToCode } from "escodegen" ;
12+ import { traverse } from "estraverse" ;
13+ import { generate as astToCode } from "astring" ;
1314import { parse as codeToAst } from "acorn" ;
1415
1516function ensureParentDirExists ( filepath )
@@ -37,7 +38,7 @@ function removeLocations(ast)
3738export function parseScript ( contents )
3839{
3940 let ast = codeToAst ( contents , {
40- ecmaVersion : 2021 ,
41+ ecmaVersion : "latest" ,
4142 sourceType : "module" ,
4243 allowReturnOutsideFunction : true
4344 } ) ;
@@ -62,15 +63,37 @@ export function saveScript(ast, filepath)
6263 return ;
6364 }
6465
66+ // Make sure to wrap any single-statement blocks in block statements, otherwise astring will put
67+ // everything in one line.
68+ function wrap ( node )
69+ {
70+ if ( ! node || node . type == "BlockStatement" )
71+ return node ;
72+ else
73+ {
74+ return {
75+ type : "BlockStatement" ,
76+ body : [ node ] ,
77+ } ;
78+ }
79+ }
80+
81+ traverse ( ast , {
82+ enter ( node )
83+ {
84+ if ( node . type == "IfStatement" )
85+ {
86+ node . consequent = wrap ( node . consequent ) ;
87+ node . alternate = wrap ( node . alternate ) ;
88+ }
89+ else if ( [ "WithStatement" , "WhileStatement" , "DoWhileStatement" , "ForStatement" , "ForInStatement" , "ForOfStatement" ] . includes ( node . type ) )
90+ node . body = wrap ( node . body ) ;
91+ }
92+ } ) ;
93+
6594 let code = astToCode ( ast , {
66- format : {
67- indent : {
68- style : " "
69- } ,
70- quotes : "double" ,
71- escapeless : true
72- } ,
73- comment : true
95+ indent : " " ,
96+ comments : true
7497 } ) ;
7598
7699 fs . writeFileSync ( filepath , code , { encoding : "utf-8" } ) ;
0 commit comments