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

Commit 747c3b4

Browse files
Francisc Romanomarkelog
authored andcommitted
New Rule: disallowSpacesInGenerator
Opposite to the "requireSpacesInGenerator" rule Fixes #1945 Closes gh-1987
1 parent f4bc106 commit 747c3b4

4 files changed

Lines changed: 324 additions & 0 deletions

File tree

grouping.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@
158158
"requireSpread",
159159
"requireTemplateStrings",
160160
"requireSpacesInGenerator",
161+
"disallowSpacesInGenerator",
161162
"requireObjectDestructuring",
162163
"requireEnhancedObjectLiterals",
163164
"requireArrayDestructuring",

lib/config/configuration.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,7 @@ Configuration.prototype.registerDefaultRules = function() {
948948
this.registerRule(require('../rules/disallow-shorthand-arrow-functions'));
949949
this.registerRule(require('../rules/disallow-identical-destructuring-names'));
950950
this.registerRule(require('../rules/require-spaces-in-generator'));
951+
this.registerRule(require('../rules/disallow-spaces-in-generator'));
951952
this.registerRule(require('../rules/require-object-destructuring'));
952953
this.registerRule(require('../rules/require-enhanced-object-literals'));
953954
this.registerRule(require('../rules/require-array-destructuring'));
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/**
2+
* Disallow space before or after `*` in generator functions
3+
*
4+
* Types: `Object`
5+
*
6+
* - `Object` (at least one of properties must be present and it must be set to true):
7+
* - `'beforeStar'`
8+
* - `true` disallows space before `*`
9+
* - `'afterStar'`
10+
* - `true` disallows space after `*`
11+
*
12+
* #### Example
13+
*
14+
* ```js
15+
* "disallowSpacesInGenerator": {
16+
* "beforeStar": true,
17+
* "afterStar": true
18+
* }
19+
* ```
20+
*
21+
* ##### Valid for mode `{ "beforeStar": true, "afterStar": false }`
22+
* ```js
23+
* var x = function* () {};
24+
* function* a() {};
25+
* var x = async function* () {};
26+
* var x = async function* a () {};
27+
* async function* a() {}
28+
* var x = async function* (){};
29+
* ```
30+
*
31+
* ##### Valid for mode `{ "beforeStar": false, "afterStar": true }`
32+
* ```js
33+
* var x = function *() {};
34+
* function *a() {};
35+
* var x = async function *() {};
36+
* var x = async function *a () {};
37+
* async function *a() {}
38+
* var x = async function *(){};
39+
* ```
40+
*
41+
*/
42+
43+
var assert = require('assert');
44+
45+
module.exports = function() {};
46+
47+
module.exports.prototype = {
48+
configure: function(options) {
49+
assert(
50+
typeof options === 'object',
51+
this.getOptionName() + ' option must be an object'
52+
);
53+
54+
if ('beforeStar' in options) {
55+
assert(
56+
options.beforeStar === true,
57+
this.getOptionName() + '.beforeStar ' +
58+
'property requires true value or should be removed'
59+
);
60+
}
61+
if ('afterStar' in options) {
62+
assert(
63+
options.afterStar === true,
64+
this.getOptionName() + '.afterStar ' +
65+
'property requires true value or should be removed'
66+
);
67+
}
68+
69+
assert(
70+
options.beforeStar || options.afterStar,
71+
this.getOptionName() + ' must have beforeStar or afterStar property'
72+
);
73+
74+
this._beforeStar = options.beforeStar;
75+
this._afterStar = options.afterStar;
76+
},
77+
78+
getOptionName: function() {
79+
return 'disallowSpacesInGenerator';
80+
},
81+
82+
check: function(file, errors) {
83+
var beforeStar = this._beforeStar;
84+
var afterStar = this._afterStar;
85+
86+
file.iterateNodesByType(['FunctionDeclaration', 'FunctionExpression'], function(node) {
87+
if (!node.generator) {
88+
return;
89+
}
90+
91+
var parent = node.parentNode;
92+
93+
// Ignore syntactic sugar for getters and setters.
94+
if (parent.type === 'Property' && (parent.kind === 'get' || parent.kind === 'set')) {
95+
return;
96+
}
97+
98+
// shorthand or constructor methods
99+
if (parent.method || parent.type === 'MethodDefinition') {
100+
node = parent.key;
101+
}
102+
103+
var currentToken = file.getFirstNodeToken(node);
104+
105+
if (node.async && currentToken.value === 'async') {
106+
currentToken = file.getNextToken(currentToken);
107+
}
108+
109+
if (beforeStar) {
110+
// currentToken assigned outside of function
111+
errors.assert.noWhitespaceBetween({
112+
token: currentToken,
113+
nextToken: file.getNextToken(currentToken),
114+
message: 'Illegal space before star'
115+
});
116+
}
117+
118+
if (afterStar) {
119+
// currentToken reassigned for star token
120+
currentToken = file.getNextToken(currentToken);
121+
errors.assert.noWhitespaceBetween({
122+
token: currentToken,
123+
nextToken: file.getNextToken(currentToken),
124+
message: 'Illegal space after star'
125+
});
126+
}
127+
});
128+
}
129+
};
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
var Checker = require('../../../lib/checker');
2+
var expect = require('chai').expect;
3+
var reportAndFix = require('../../lib/assertHelpers').reportAndFix;
4+
5+
describe('rules/disallow-spaces-in-generator', function() {
6+
var checker;
7+
beforeEach(function() {
8+
checker = new Checker();
9+
checker.registerDefaultRules();
10+
});
11+
12+
describe('{beforeStar: true}', function() {
13+
var rules = {
14+
disallowSpacesInGenerator: {beforeStar: true},
15+
esnext: true
16+
};
17+
18+
beforeEach(function() {
19+
checker.configure(rules);
20+
});
21+
22+
reportAndFix({
23+
name: 'should report illegal space before the star with function declaration',
24+
rules: rules,
25+
errors: 1,
26+
input: 'function * asdf(){}',
27+
output: 'function* asdf(){}'
28+
});
29+
30+
reportAndFix({
31+
name: 'should report illegal space before the star with function declaration',
32+
rules: rules,
33+
errors: 1,
34+
input: 'function *asdf(){}',
35+
output: 'function*asdf(){}'
36+
});
37+
38+
reportAndFix({
39+
name: 'should report illegal space before the star with function expression',
40+
rules: rules,
41+
errors: 1,
42+
input: 'var x = function * (){}',
43+
output: 'var x = function* (){}'
44+
});
45+
46+
reportAndFix({
47+
name: 'should report illegal space before the star with function expression',
48+
rules: rules,
49+
errors: 1,
50+
input: 'var x = function *(){}',
51+
output: 'var x = function*(){}'
52+
});
53+
54+
reportAndFix({
55+
name: 'should report illegal space before the star with named function expression',
56+
rules: rules,
57+
errors: 1,
58+
input: 'var x = function * asdf(){}',
59+
output: 'var x = function* asdf(){}'
60+
});
61+
62+
reportAndFix({
63+
name: 'should report illegal space before the star with named function expression',
64+
rules: rules,
65+
errors: 1,
66+
input: 'var x = function *asdf(){}',
67+
output: 'var x = function*asdf(){}'
68+
});
69+
70+
it('should not report illegal space error', function() {
71+
expect(checker.checkString('var x = function* (){}')).to.have.no.errors();
72+
});
73+
74+
it('should not report illegal space error with named function expression', function() {
75+
expect(checker.checkString('var x = function* asdf(){}')).to.have.no.errors();
76+
});
77+
78+
it('should not report illegal space error with function delcaration', function() {
79+
expect(checker.checkString('function* asdf(){}')).to.have.no.errors();
80+
});
81+
82+
it('should not report illegal space error with async function', function() {
83+
expect(checker.checkString('var x = async function* (){}')).to.have.no.errors();
84+
});
85+
86+
it('should skip async functions with named function', function() {
87+
expect(checker.checkString('var x = async function* asdf(){}')).to.have.no.errors();
88+
});
89+
90+
it('should report illegal space before star for async function', function() {
91+
var testExp = checker.checkString('var x = async function *(){}');
92+
var reqTest = 'disallowSpacesInGenerator';
93+
expect(testExp).to.have.one.validation.error.from(reqTest);
94+
});
95+
96+
it('should report illegal space before star for named async function', function() {
97+
var testExp = checker.checkString('var x = async function *asdf(){}');
98+
var reqTest = 'disallowSpacesInGenerator';
99+
expect(testExp).to.have.one.validation.error.from(reqTest);
100+
});
101+
});
102+
103+
describe('{afterStar: true}', function() {
104+
var rules = {
105+
disallowSpacesInGenerator: {afterStar: true},
106+
esnext: true
107+
};
108+
109+
beforeEach(function() {
110+
checker.configure(rules);
111+
});
112+
113+
reportAndFix({
114+
name: 'should report illegal space after the star with function declaration',
115+
rules: rules,
116+
errors: 1,
117+
input: 'function * asdf(){}',
118+
output: 'function *asdf(){}'
119+
});
120+
121+
reportAndFix({
122+
name: 'should report illegal space after the star with function declaration',
123+
rules: rules,
124+
errors: 1,
125+
input: 'function* asdf(){}',
126+
output: 'function*asdf(){}'
127+
});
128+
129+
reportAndFix({
130+
name: 'should report illegal space after the star with function expression',
131+
rules: rules,
132+
errors: 1,
133+
input: 'var x = function * (){}',
134+
output: 'var x = function *(){}'
135+
});
136+
137+
reportAndFix({
138+
name: 'should report illegal space after the star with function expression',
139+
rules: rules,
140+
errors: 1,
141+
input: 'var x = function* (){}',
142+
output: 'var x = function*(){}'
143+
});
144+
145+
reportAndFix({
146+
name: 'should report illegal space after the star with named function expression',
147+
rules: rules,
148+
errors: 1,
149+
input: 'var x = function * asdf(){}',
150+
output: 'var x = function *asdf(){}'
151+
});
152+
153+
reportAndFix({
154+
name: 'should report illegal space after the star with named function expression',
155+
rules: rules,
156+
errors: 1,
157+
input: 'var x = function* asdf(){}',
158+
output: 'var x = function*asdf(){}'
159+
});
160+
161+
it('should not report illegal space error', function() {
162+
expect(checker.checkString('var x = function *(){}')).to.have.no.errors();
163+
});
164+
165+
it('should not report illegal space error with named function expression', function() {
166+
expect(checker.checkString('var x = function *asdf(){}')).to.have.no.errors();
167+
});
168+
169+
it('should not report illegal space error with function delcaration', function() {
170+
expect(checker.checkString('function *asdf(){}')).to.have.no.errors();
171+
});
172+
173+
it('should not report illegal space error with async function', function() {
174+
expect(checker.checkString('var x = async function *(){}')).to.have.no.errors();
175+
});
176+
177+
it('should skip async functions with named function', function() {
178+
expect(checker.checkString('var x = async function *asdf(){}')).to.have.no.errors();
179+
});
180+
181+
it('should report illegal space after star for async function', function() {
182+
var testExp = checker.checkString('var x = async function* (){}');
183+
var reqTest = 'disallowSpacesInGenerator';
184+
expect(testExp).to.have.one.validation.error.from(reqTest);
185+
});
186+
187+
it('should report illegal space after star for named async function', function() {
188+
var testExp = checker.checkString('var x = async function* asdf(){}');
189+
var reqTest = 'disallowSpacesInGenerator';
190+
expect(testExp).to.have.one.validation.error.from(reqTest);
191+
});
192+
});
193+
});

0 commit comments

Comments
 (0)