Skip to content
This repository has been archived by the owner on Mar 23, 2024. It is now read-only.

Commit

Permalink
Merge 6dfb0d3 into 7a547b2
Browse files Browse the repository at this point in the history
  • Loading branch information
lukeapage committed Nov 19, 2015
2 parents 7a547b2 + 6dfb0d3 commit 591f09d
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 91 deletions.
100 changes: 97 additions & 3 deletions lib/rules/disallow-trailing-whitespace.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,102 @@ module.exports.prototype = {
},

check: function(file, errors) {
errors.assert.noTrailingSpaces({
ignoreEmptyLines: this._ignoreEmptyLines
});
var ignoreEmptyLines = this._ignoreEmptyLines;
var lines = file.getLines();

for (var i = 0, l = lines.length; i < l; i++) {
if (lines[i].match(/\s$/) && !(ignoreEmptyLines && lines[i].match(/^\s*$/))) {

errors.cast({
message: 'Illegal trailing whitespace',
line: i + 1,
column: lines[i].length
});
}
}
},

_fix: function(file, error) {
var ignoreEmptyLines = this._ignoreEmptyLines;
var currentLineNumber = error.line;
var linebreak = file.getLineBreaks()[0] || '\n';
var lines = file.getLines();

var fixed = false;
var startLineNumber;
var precedingToken;
var targetToken;

while (!precedingToken && currentLineNumber > 0) {
precedingToken = file.getLastTokenOnLine(currentLineNumber, {
includeComments: true
});
currentLineNumber--;
}

if (precedingToken === null) {
targetToken = file.getFirstToken({includeComments: true});
startLineNumber = 1;
} else {
targetToken = file.getNextToken(precedingToken, {
includeComments: true
});
startLineNumber = precedingToken.loc.end.line;

if (precedingToken.isComment &&
precedingToken.loc.start.line <= error.line &&
precedingToken.loc.end.line >= error.line) {

if (precedingToken.type === 'Block') {

if (ignoreEmptyLines) {
var blockLines = precedingToken.value.split(/\r\n|\n|\r/);

for (var k = 0; k < blockLines.length; k++) {

if (!blockLines[k].match(/^\s*$/) || k === 0) {
blockLines[k] = blockLines[k].split(/\s+$/).join('');
}
}

precedingToken.value = blockLines.join(linebreak);
} else {
precedingToken.value = precedingToken.value
.split(/[^\S\r\n]+\r\n|[^\S\n]+\n|[^\S\r]+\r/)
.join(linebreak);
}
} else {
precedingToken.value = precedingToken.value.split(/\s+$/).join('');
}

fixed = true;
}
}

if (targetToken !== null && !fixed) {
var eolCount = targetToken.loc.start.line - startLineNumber + 1;
var targetIndent = '';
var targetLine = lines[targetToken.loc.start.line - 1];
for (var j = 0, whitespace = targetLine.charAt(j);
whitespace.match(/\s/);
j++, whitespace = targetLine.charAt(j)) {
targetIndent += whitespace;
}

file.setWhitespaceBefore(targetToken, new Array(eolCount).join(linebreak) + targetIndent);
fixed = true;
}

if (!fixed && precedingToken && precedingToken.type === 'EOF') {
precedingToken = file.getPrevToken(precedingToken, { includeWhitespace: true });
if (precedingToken.isWhitespace) {
precedingToken.value = precedingToken.value.replace(/[^\S\n\r]$/g, '');
fixed = true;
}
}

if (!fixed) {
error.fixed = false;
}
}
};
88 changes: 0 additions & 88 deletions lib/token-assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -508,92 +508,4 @@ TokenAssert.prototype.noTokenBefore = function(options) {
}
};

/**
* Disallows specific token before given.
*
* @param {Object} options
* @param {Boolean} options.ignoreEmptyLines
*/
TokenAssert.prototype.noTrailingSpaces = function(options) {
var ignoreEmptyLines = options.ignoreEmptyLines;
var lines = this._file.getLines();

for (var i = 0, l = lines.length; i < l; i++) {
if (lines[i].match(/\s$/) && !(ignoreEmptyLines && lines[i].match(/^\s*$/))) {
var fixed = false;
var currentLineNumber = i + 1;
var startLineNumber;
var precendingToken;
var targetToken;

while (!precendingToken && currentLineNumber > 0) {
precendingToken = this._file.getLastTokenOnLine(currentLineNumber, {
includeComments: true
});
currentLineNumber--;
}

if (precendingToken === null) {
targetToken = this._file.getFirstToken({includeComments: true});
startLineNumber = 1;
} else {
targetToken = this._file.getNextToken(precendingToken, {
includeComments: true
});
startLineNumber = precendingToken.loc.end.line;

if (precendingToken.isComment &&
precendingToken.loc.start.line <= (i + 1) &&
precendingToken.loc.end.line >= (i + 1)) {

if (precendingToken.type === 'Block') {

if (ignoreEmptyLines) {
var blockLines = precendingToken.value.split(/\n/);

for (var k = 0; k < blockLines.length; k++) {

if (!blockLines[k].match(/^\s*$/) || k === 0) {
blockLines[k] = blockLines[k].split(/\s$/).join('');
}
}

precendingToken.value = blockLines.join('\n');
} else {
precendingToken.value = precendingToken.value.split(/\s\n/).join('\n');
}
} else {
precendingToken.value = precendingToken.value.split(/\s$/).join('');
}

fixed = true;
}
}

if (targetToken !== null && !fixed) {
var eolCount = targetToken.loc.start.line - startLineNumber + 1;
var targetIndent = '';
var targetLine = lines[targetToken.loc.start.line - 1];
for (var j = 0, whitespace = targetLine.charAt(j);
whitespace.match(/\s/);
j++, whitespace = targetLine.charAt(j)) {
targetIndent += whitespace;
}

this._file.setWhitespaceBefore(targetToken, new Array(eolCount).join('\n') + targetIndent);
fixed = true;
}

precendingToken = null;

this.emit('error', {
message: 'Illegal trailing whitespace',
line: i + 1,
column: lines[i].length,
fixed: fixed
});
}
}
};

module.exports = TokenAssert;
76 changes: 76 additions & 0 deletions test/specs/rules/disallow-trailing-whitespace.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,22 @@ describe('rules/disallow-trailing-whitespace', function() {
output: '/*\n *\n */'
});

reportAndFix({
name: 'illegal multiple-whitespace in comment block',
rules: rules,
errors: 1,
input: '/*\n * \n */',
output: '/*\n *\n */'
});

reportAndFix({
name: 'illegal multiple-whitespace in comment block when ignoring empty lines',
rules: { disallowTrailingWhitespace: 'ignoreEmptyLines' },
errors: 1,
input: '/*\n * \n\n */',
output: '/*\n *\n\n */'
});

reportAndFix({
name: 'illegal whitespace in comment line',
rules: rules,
Expand All @@ -59,6 +75,14 @@ describe('rules/disallow-trailing-whitespace', function() {
output: '// line 1\n// line 2\n'
});

reportAndFix({
name: 'illegal multiple-whitespace in comment line',
rules: rules,
errors: 1,
input: '// line 1 \n// line 2\n',
output: '// line 1\n// line 2\n'
});

reportAndFix({
name: 'should fix trailing space in block comments',
rules: rules,
Expand All @@ -75,6 +99,58 @@ describe('rules/disallow-trailing-whitespace', function() {
output: '/*\nbla\n\t\n*/'
});

reportAndFix({
name: 'supports windows line breaks',
rules: rules,
errors: 2,
input: ' \r\nvar a; \r\nvar b;\r\n var c;\r\n',
output: '\r\nvar a;\r\nvar b;\r\n var c;\r\n'
});

reportAndFix({
name: 'supports windows line breaks in a comment',
rules: rules,
errors: 1,
input: '//hey \r\n',
output: '//hey\r\n'
});

reportAndFix({
name: 'supports mac line breaks',
rules: rules,
errors: 2,
input: ' \rvar a; \rvar b;\r var c;\r',
output: '\rvar a;\rvar b;\r var c;\r'
});

reportAndFix({
name: 'fixes spaces on the last line',
rules: rules,
errors: 1,
input: 'var a;\n ',
output: 'var a;\n'
});

reportAndFix({
name: 'fixes space and comment on the last line',
rules: rules,
errors: 1,
input: 'var a;\n/**/ ',
output: 'var a;\n/**/'
});

reportAndFix({
name: 'fixes spaces on the last lines',
rules: rules,
errors: 3,
input: 'var a;\n \n \n ',
output: 'var a;\n\n\n'
});

it('should handle an empty file', function() {
expect(checker.checkString('')).to.have.no.errors();
});

describe('option value true', function() {
beforeEach(function() {
checker.configure({ disallowTrailingWhitespace: true });
Expand Down

0 comments on commit 591f09d

Please sign in to comment.