Skip to content

Commit

Permalink
feature: @putout/engine-parser: add ability to handle cases when reca…
Browse files Browse the repository at this point in the history
…st produces 1 additional brace thet brokes code (benjamn/recast#1248)
  • Loading branch information
coderaiser committed Mar 3, 2023
1 parent 2ebf88c commit 966f50d
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 12 deletions.
37 changes: 32 additions & 5 deletions packages/engine-parser/lib/print.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
'use strict';

const {print} = require('@putout/recast');

const generate = require('@babel/generator').default;
const fixStrictMode = (a) => a.replace(`\n\n\n'use strict'`, `\n\n'use strict'`);
const btoa = (a) => Buffer.from(a, 'binary').toString('base64');
const addSourceMap = (sourceMapName, {code, map}) => !sourceMapName ? code : `${code}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,${btoa(stringify(map))}\n`;

const {stringify} = JSON;

const {assign} = Object;
module.exports = (ast, options = {}) => {
const {sourceMapName} = options;
const printOptions = {
Expand All @@ -16,8 +15,17 @@ module.exports = (ast, options = {}) => {
wrapColumn: Infinity,
...options,
};

const printed = print(ast, printOptions);

if (checkBrackets(printed.code))
assign(printed, {
code: generate(ast, {
indent: {
style: ' ',
},
}).code,
});

const {map} = printed;
const code = fixStrictMode(printed.code);

Expand All @@ -26,4 +34,23 @@ module.exports = (ast, options = {}) => {
map,
});
};

function checkBrackets(source) {
const brackets = [];
let i = source.length;

while (--i) {
const current = source[i];

if (current === ')') {
brackets.push(current);
continue;
}

if (current === '(') {
brackets.pop();
continue;
}
}

return brackets.length;
}
54 changes: 47 additions & 7 deletions packages/engine-parser/lib/print.spec.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,72 @@
'use strict';

const test = require('supertape');
const mockRequire = require('mock-require');
const {
test,
stub,
} = require('supertape');
const montag = require('montag');

const putout = require('putout');
const {
stopAll,
reRequire,
} = mockRequire;
const {parse} = putout;

test('putout: parser: print: long lines', (t) => {
const source = montag`
test.only('putout: parseOptions: code mods directory: .putout: exclude node_modules', (t) => {
const empty = {};
});
`;

const expected = montag`
import {test} from 'supertape';
test('putout: parseOptions: code mods directory: .putout: exclude node_modules', (t) => {
const empty = {};
t.end();
});
`;

const {code} = putout(source, {
plugins: [
'tape',
],
plugins: ['tape'],
});

t.equal(code, expected);
t.end();
});

test('putout: parser: print: bad recast output', (t) => {
const source = montag`
export default () => {
return (
<h1>hello</h1>
);
}
`;
const invalid = montag`
export default () => {
return (
<h1>hello</h1>)
);
}
`;
const expected = montag`
export default (() => {
return <h1>hello</h1>;
});
`;
const recastPrint = stub().returns({
code: invalid,
});

mockRequire('@putout/recast', {
print: recastPrint,
});
const print = reRequire('./print');
const ast = parse(source);
const result = print(ast);

stopAll();

t.equal(result, expected);
t.end();
});
1 change: 1 addition & 0 deletions packages/engine-parser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"just-camel-case": "^4.0.2",
"lerna": "^6.0.1",
"madrun": "^9.0.0",
"mock-require": "^3.0.3",
"montag": "^1.0.0",
"nodemon": "^2.0.1",
"putout": "*",
Expand Down

0 comments on commit 966f50d

Please sign in to comment.