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

Commit

Permalink
Merge cab9f35 into bcac436
Browse files Browse the repository at this point in the history
  • Loading branch information
mikesherov committed Dec 8, 2014
2 parents bcac436 + cab9f35 commit 249b808
Show file tree
Hide file tree
Showing 11 changed files with 226 additions and 40 deletions.
48 changes: 45 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ But you also can specify your own reporter, since this flag accepts relative or
jscs path[ path[...]] --reporter=./some-dir/my-reporter.js
```

### `--es3`
Validates your code as targetted for an ES3 environment. This effects the behavior of certain rules, e.g., requireDotNotation.

### `--esnext`
Attempts to parse your code as ES6 using the harmony version of the esprima parser. Please note that this is currently experimental, and will improve over time.

Expand Down Expand Up @@ -226,6 +229,20 @@ Default: Infinity
"maxErrors": 10
```

### es3

Validates your code as targetted for an ES3 environment. This effects the behavior of certain rules, e.g., requireDotNotation.

Type: `Boolean`

Value: `true`

#### Example

```js
"es3": true
```

### esnext

Attempts to parse your code as ES6 using the harmony version of the esprima parser.
Expand Down Expand Up @@ -2896,18 +2913,19 @@ var d = new e();

### requireDotNotation

Requires member expressions to use dot notation when possible
Requires member expressions to use dot notation when possible. Note, if you specify the --es3 option to JSCS, ES3 keywords and future reserved words MUST remain quoted.

Type: `Boolean`

Values: `true`

JSHint: [`sub`](http://www.jshint.com/docs/options/#sub)

#### Example
#### Example for `"es3": true`

```js
"requireDotNotation": true
"requireDotNotation": true,
"es3": true
```

##### Valid
Expand All @@ -2926,6 +2944,30 @@ var a = b['while']; //reserved word
var a = b['c'];
```

#### Example for `"es3": false` or `"es3": null`

```js
"requireDotNotation": true,
"es3": false
```

##### Valid

```js
var a = b[c];
var a = b.c;
var a = b[c.d];
var a = b[1];
var a = b.while;
```

##### Invalid

```js
var a = b['c'];
var a = b['while']; //reserved words can be property names in ES5
```

### requireYodaConditions

Requires the variable to be the right hand operator when doing a boolean comparison
Expand Down
1 change: 1 addition & 0 deletions bin/jscs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ program
.usage('[options] <file ...>')
.option('-c, --config [path]', 'configuration file path')
.option('-e, --esnext', 'attempts to parse esnext code (currently es6)')
.option('-t, --es3', 'validates code as es3')
.option('-s, --esprima <path>', 'attempts to use a custom version of Esprima')
.option('-n, --no-colors', 'clean output without colors')
.option('-p, --preset <preset>', 'preset config')
Expand Down
20 changes: 20 additions & 0 deletions lib/config/configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ var BUILTIN_OPTIONS = {
maxErrors: true,
configPath: true,
esnext: true,
es3: true,
esprima: true,
errorFilter: true
};
Expand All @@ -35,6 +36,7 @@ function Configuration() {
this._overrides = {};
this._presetName = null;
this._esnextEnabled = false;
this._es3Enabled = true;
this._esprima = null;
this._errorFilter = null;
}
Expand Down Expand Up @@ -91,6 +93,7 @@ Configuration.prototype.getProcessedConfig = function() {
result.maxErrors = this._maxErrors;
result.preset = this._presetName;
result.esnext = this._esnextEnabled;
result.es3 = this._es3Enabled;
result.esprima = this._esprima;
result.errorFilter = this._errorFilter;
return result;
Expand Down Expand Up @@ -163,6 +166,15 @@ Configuration.prototype.isESNextEnabled = function() {
return this._esnextEnabled;
};

/**
* Returns `true` if `es3` option is enabled.
*
* @returns {Boolean}
*/
Configuration.prototype.isES3Enabled = function() {
return this._es3Enabled;
};

/**
* Returns `true` if `esprima` option is not null.
*
Expand Down Expand Up @@ -292,6 +304,14 @@ Configuration.prototype._processConfig = function(config) {
this._esnextEnabled = Boolean(config.esnext);
}

if (config.hasOwnProperty('es3')) {
assert(
typeof config.es3 === 'boolean' || config.es3 === null,
'`es3` option requires boolean or null value'
);
this._es3Enabled = Boolean(config.es3);
}

if (config.hasOwnProperty('esprima')) {
this._loadEsprima(config.esprima);
}
Expand Down
3 changes: 2 additions & 1 deletion lib/config/node-configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ var OVERRIDE_OPTIONS = [
'preset',
'maxErrors',
'errorFilter',
'esprima'
'esprima',
'es3'
];

/**
Expand Down
24 changes: 23 additions & 1 deletion lib/js-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,16 @@ var KEYWORD_OPERATORS = {
*
* @name JsFile
*/
var JsFile = function(filename, source, tree) {
var JsFile = function(filename, source, tree, options) {
options = options || {};

this._filename = filename;
this._source = source;
this._tree = tree || {tokens: []};

this._es3 = options.es3 || false;
this._es6 = options.es6 || false;

this._lines = source.split(/\r\n|\r|\n/);
this._tokenRangeStartIndex = null;
this._tokenRangeEndIndex = null;
Expand Down Expand Up @@ -361,6 +367,22 @@ JsFile.prototype = {
}
});
},
/**
* Returns whether this file supports es3.
*
* @returns {Boolean}
*/
isES3Enabled: function() {
return this._es3;
},
/**
* Returns whether this file supports es6.
*
* @returns {Boolean}
*/
isES6Enabled: function() {
return this._es6;
},
/**
* Returns string representing contents of the file.
*
Expand Down
7 changes: 5 additions & 2 deletions lib/rules/require-dot-notation.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ module.exports.prototype = {
},

check: function(file, errors) {
function isES3Allowed(value) {
return file.isES3Enabled() && (utils.isEs3Keyword(value) || utils.isEs3FutureReservedWord(value));
}

file.iterateNodesByType('MemberExpression', function(node) {
if (!node.computed || node.property.type !== 'Literal') {
return;
Expand All @@ -36,8 +40,7 @@ module.exports.prototype = {
value === 'null' ||
value === 'true' ||
value === 'false' ||
utils.isEs3Keyword(value) ||
utils.isEs3FutureReservedWord(value)
isES3Allowed(value)
) {
return;
}
Expand Down
7 changes: 6 additions & 1 deletion lib/string-checker.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,12 @@ StringChecker.prototype = {
} catch (e) {
parseError = e;
}
var file = new JsFile(filename, str, tree);

var file = new JsFile(filename, str, tree, {
es3: this._configuration.isES3Enabled(),
es6: this._configuration.isESNextEnabled()
});

var errors = new Errors(file, this._verbose);
var errorFilter = this._configuration.getErrorFilter();

Expand Down
22 changes: 22 additions & 0 deletions test/config/configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,28 @@ describe('modules/config/configuration', function() {
});
});

describe('isES3Enabled', function() {
it('should return false when null is specified', function() {
configuration.load({es3: null});
assert.equal(configuration.isES3Enabled(), false);
});

it('should return false when false is specified', function() {
configuration.load({es3: false});
assert.equal(configuration.isES3Enabled(), false);
});

it('should return true when true is specified', function() {
configuration.load({es3: true});
assert.equal(configuration.isES3Enabled(), true);
});

it('should return true when unspecified', function() {
configuration.load({});
assert.equal(configuration.isES3Enabled(), true);
});
});

describe('getRegisteredPresets', function() {
it('should return registered presets object', function() {
var preset = {maxErrors: 5};
Expand Down
4 changes: 3 additions & 1 deletion test/config/node-configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ describe('modules/config/node-configuration', function() {
preset: 'jquery',
maxErrors: '2',
errorFilter: path.resolve(__dirname, '../data/error-filter.js'),
esprima: 'esprima-harmony-jscs'
esprima: 'esprima-harmony-jscs',
es3: true
});

configuration.registerPreset('jquery', {});
configuration.load({});

assert.equal(configuration.getProcessedConfig().preset, 'jquery');
assert.equal(configuration.getMaxErrors(), 2);
assert.equal(configuration.isES3Enabled(), true);
assert.equal(typeof configuration.getErrorFilter, 'function');
assert.equal(configuration.hasCustomEsprima(), true);
});
Expand Down
45 changes: 43 additions & 2 deletions test/js-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ var sinon = require('sinon');

describe('modules/js-file', function() {

function createJsFile(sources) {
function createJsFile(sources, options) {
return new JsFile(
'example.js',
sources,
esprima.parse(sources, {loc: true, range: true, comment: true, tokens: true})
esprima.parse(sources, {loc: true, range: true, comment: true, tokens: true}),
options || {}
);
}

Expand Down Expand Up @@ -677,6 +678,46 @@ describe('modules/js-file', function() {
});
});

describe('isES3Enabled', function() {
it('should return false when unspecified', function() {
var sources = 'var x = 1;\nvar y = 2;';
var file = createJsFile(sources);
assert.equal(file.isES3Enabled(), false);
});

it('should return false when specified', function() {
var sources = 'var x = 1;\nvar y = 2;';
var file = createJsFile(sources, {es3: false});
assert.equal(file.isES3Enabled(), false);
});

it('should return true when specified', function() {
var sources = 'var x = 1;\nvar y = 2;';
var file = createJsFile(sources, {es3: true});
assert.equal(file.isES3Enabled(), true);
});
});

describe('isES6Enabled', function() {
it('should return false when unspecified', function() {
var sources = 'var x = 1;\nvar y = 2;';
var file = createJsFile(sources);
assert.equal(file.isES6Enabled(), false);
});

it('should return false when specified', function() {
var sources = 'var x = 1;\nvar y = 2;';
var file = createJsFile(sources, {es6: false});
assert.equal(file.isES6Enabled(), false);
});

it('should return true when specified', function() {
var sources = 'var x = 1;\nvar y = 2;';
var file = createJsFile(sources, {es6: true});
assert.equal(file.isES6Enabled(), true);
});
});

describe('getLines', function() {
it('should return specified source code lines', function() {
var sources = ['var x = 1;', 'var y = 2;'];
Expand Down

0 comments on commit 249b808

Please sign in to comment.