Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Autofixing: token data

  • Loading branch information...
mdevils committed Feb 7, 2015
1 parent 59f18a6 commit 845a6b2a8d78e25c038fcb981c0334fe6f9c2d30

Large diffs are not rendered by default.

@@ -53,22 +53,12 @@ module.exports.prototype = {
},

check: function(file, errors) {
var tokens = file.getTokens();
var lastToken;
var operators = this._operators;

tokens.forEach(function(token) {
if (lastToken) {
if (lastToken.type === 'Punctuator' && operators.indexOf(lastToken.value) > -1) {
if (lastToken.loc.end.line < token.loc.end.line) {
errors.add(
'Operator needs to either be on the same line or after a line break.',
token.loc.start
);
}
}
}
lastToken = token;
file.iterateTokensByTypeAndValue('Punctuator', this._operators, function(token) {
errors.assert.sameLine({
token: token,
nextToken: file.getNextToken(token),
message: 'Operator needs to either be on the same line or after a line break.'
});
});
}
};
@@ -43,15 +43,13 @@ module.exports.prototype = {
},

check: function(file, errors) {
file.getTokens()
.filter(function(token) {
return token.type === 'Punctuator' && token.value === ';';
})
.forEach(function(token) {
var nextToken = file.getNextToken(token);
if (!nextToken || nextToken.loc.end.line > token.loc.end.line) {
errors.add('semicolons are disallowed at the end of a line.', token.loc.end);
}
file.iterateTokensByTypeAndValue('Punctuator', ';', function(token) {
errors.assert.sameLine({
token: token,
nextToken: file.getNextToken(token),
requireNextToken: true,
message: 'Semicolons are disallowed at the end of a line.'
});
});
}
};
@@ -75,53 +75,10 @@ StringChecker.prototype = {
this._maxErrors = this._configuration.getMaxErrors();
},

/**
* Parses source code into an AST
*
* @param {String} str the source code to parse
* @return {Object} the output AST
* @throws Error on invalid source code.
*/
_parse: function(str) {
var hashbang = str.indexOf('#!') === 0;
var tree;

// Convert bin annotation to a comment
if (hashbang) {
str = '//' + str.substr(2);
}

// Strip special case code like iOS instrumentation imports: `#import 'abc.js';`
str = str.replace(/^#!?[^\n]+\n/gm, '');

var esprimaOptions = {
tolerant: true
};
var esprimaOptionsFromConfig = this._configuration.getEsprimaOptions();
for (var key in esprimaOptionsFromConfig) {
esprimaOptions[key] = esprimaOptionsFromConfig[key];
}
// Set required options
esprimaOptions.loc = true;
esprimaOptions.range = true;
esprimaOptions.comment = true;
esprimaOptions.tokens = true;
esprimaOptions.sourceType = 'module';

tree = this._esprima.parse(str, esprimaOptions);

// Remove the bin annotation comment
if (hashbang) {
tree.comments = tree.comments.slice(1);
}

return tree;
},

/**
* Checks file provided with a string.
* @param {String} str
* @param {String} filename
* @param {String} [filename]
* @returns {Errors}
*/
checkString: function(str, filename) {
@@ -131,7 +88,7 @@ StringChecker.prototype = {
var parseError;

try {
tree = this._parse(str);
tree = JsFile.parse(str, this._esprima, this._configuration.getEsprimaOptions());
} catch (e) {
parseError = e;
}
@@ -77,11 +77,21 @@ TokenAssert.prototype.noWhitespaceBetween = function(options) {
* @param {Object} options.token
* @param {Object} options.nextToken
* @param {String} [options.message]
* @param {Boolean} [options.requireNextToken=false]
*/
TokenAssert.prototype.sameLine = function(options) {
var token = options.token;
var nextToken = options.nextToken;

if (options.requireNextToken && (!nextToken || nextToken.type === 'EOF')) {
this.emit('error', {
message: options.message || token.value + ' should not be the last in the file',
line: token.loc.end.line,
column: token.loc.end.column
});
return;
}

if (!token || !nextToken) {
return;
}
@@ -0,0 +1,10 @@
// Hello world!

/* A little block comment */

console.log('Hello World');

// The rest of this file is an array of empty lines



@@ -0,0 +1,3 @@
#!/usr/bin/env node

console.log('NodeJs!');
@@ -0,0 +1,10 @@

#! random stuff
#! 1234
var a = 5;

/* comment */

#import "abc.js"
#import abc.js
var a = 5;
@@ -0,0 +1,6 @@

var a = "123"; // Double-quoted string

var b = '123'; // Single-quoted string

var c = `123`; // ES6 template string
@@ -99,18 +99,30 @@ describe('modules/errors', function() {
errors = checker.checkString('yay');
});

it('should throw an error on invalid line', function() {
it('should throw an error on invalid line type', function() {
assert.throws(function() {
errors.add('msg', '0');
});
});

it('should throw an error on invalid line value', function() {
assert.throws(function() {
errors.add('msg', 0);
});
});

it('should throw an error on invalid column', function() {
it('should throw an error on invalid column type', function() {
assert.throws(function() {
errors.add('msg', 1, '2');
});
});

it('should throw an error on invalid column value', function() {
assert.throws(function() {
errors.add('msg', 1, -1);
});
});

it('should not throw with good parameters', function() {
errors.setCurrentRule('anyRule');
errors.add('msg', 1, 0);
@@ -132,4 +144,21 @@ describe('modules/errors', function() {
assert(errors.isEmpty());
});
});

describe('stripErrorList', function() {
it('should stip error list to specified length', function() {
var errors = checker.checkString('var x;');
errors.add('msg1', 1, 0);
errors.add('msg2', 1, 1);
errors.add('msg3', 1, 2);
errors.stripErrorList(2);
assert.equal(errors.getErrorCount(), 2);
assert.equal(errors.getErrorList()[0].message, 'msg1');
assert.equal(errors.getErrorList()[0].line, 1);
assert.equal(errors.getErrorList()[0].column, 0);
assert.equal(errors.getErrorList()[1].message, 'msg2');
assert.equal(errors.getErrorList()[1].line, 1);
assert.equal(errors.getErrorList()[1].column, 1);
});
});
});

0 comments on commit 845a6b2

Please sign in to comment.
You can’t perform that action at this time.