-
-
Save jzaefferer/23bef744ffea751b2668 to your computer and use it in GitHub Desktop.
Copyright Jörn Zaefferer; licensed MIT
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var rocambole = require('rocambole'); | |
var _tk = require('rocambole-token'); | |
var MAX_LINE_LENGTH = 75; | |
exports.transformAfter = function(ast) { | |
rocambole.recursive(ast, transform); | |
}; | |
function transform(node) { | |
if (node.type !== 'ObjectExpression') return; | |
// Don't collapse nested objects | |
if (node.parent.type === 'Property') return; | |
// It collapses objects that are short enough | |
// 0 indicates measurement failed, ignore | |
var length = expectedLength(node); | |
if (length === 0 || length > MAX_LINE_LENGTH) return; | |
// This one seems short | |
_tk.eachInBetween(node.startToken, node.endToken, function(token) { | |
if (_tk.isBr(token)) { | |
// Insert one blank to replace the line break | |
_tk.before(token, { | |
type: 'WhiteSpace', | |
value: ' ' | |
}); | |
// Remove all whitespace/indent after the line break | |
var next = token.next; | |
while (_tk.isEmpty(next)) { | |
_tk.remove(next); | |
next = next.next; | |
} | |
// Remove the line break itself | |
_tk.remove(token); | |
} | |
}); | |
} | |
function expectedLength(node) { | |
var length = 0; | |
var startOfTheLine = _tk.findPrev(node.startToken, 'LineBreak'); | |
// No linebreak indicates first line of the file, find first token instead | |
if (!startOfTheLine) { | |
startOfTheLine = _tk.findPrev(node.startToken, function(token) { | |
return !token.prev; | |
}); | |
} | |
var firstChar = _tk.findNextNonEmpty(startOfTheLine); | |
// Need to take into consideration the indent | |
_tk.eachInBetween(startOfTheLine, firstChar, function(token) { | |
length += String(token.raw || token.value).length; | |
}); | |
var prev; | |
_tk.eachInBetween(firstChar, node.endToken, function(token) { | |
if (_tk.isEmpty(token)) { | |
// Empty tokens are "collapsed" (multiple linebreaks/whitespace becomes | |
// a single whitespace) | |
length += _tk.isEmpty(prev) ? 0 : 1; | |
prev = token; | |
return; | |
} | |
// Don't collapse objects with line comments; block comments should be okay | |
if (token.type === 'LineComment') { | |
length += 1000; | |
} | |
length += String(token.raw || token.value).length; | |
prev = token; | |
}); | |
if (length === 0) { | |
throw new Error('Failed to measure length of object expression: ' + node.toString()); | |
} | |
return length; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment