Skip to content

Commit 4a6f03d

Browse files
committedSep 29, 2017
feat: Implement fixation in array style rules
1 parent afd4210 commit 4a6f03d

File tree

8 files changed

+88
-26
lines changed

8 files changed

+88
-26
lines changed
 

‎.README/rules/array-style-complex-type.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
### `array-style-complex-type`
22

3+
_The `--fix` option on the command line automatically fixes problems reported by this rule._
4+
35
Enforces a particular style for array type annotations for complex types. Type is considered complex in these cases:
46

57
* [Maybe type](https://flow.org/en/docs/types/maybe/)

‎.README/rules/array-style-simple-type.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
### `array-style-simple-type`
22

3+
_The `--fix` option on the command line automatically fixes problems reported by this rule._
4+
35
Enforces a particular style for array type annotations for complex types. Type is considered simple in these cases:
46

57
* Primitive types

‎src/rules/arrayStyle/index.js

+24-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import isSimpleType from './isSimpleType';
2+
import needWrap from './needWrap';
23

34
const schema = [
45
{
@@ -7,20 +8,41 @@ const schema = [
78
}
89
];
910

11+
const fixShorthand = (context, node) => {
12+
return (fixer) => {
13+
const rawElementType = context.getSourceCode().getText(node.elementType);
14+
15+
return fixer.replaceText(node, 'Array<' + rawElementType + '>');
16+
};
17+
};
18+
19+
const fixVerbose = (context, node) => {
20+
return (fixer) => {
21+
const elementTypeNode = node.typeParameters.params[0];
22+
const rawElementType = context.getSourceCode().getText(elementTypeNode);
23+
24+
if (needWrap(elementTypeNode)) {
25+
return fixer.replaceText(node, '(' + rawElementType + ')[]');
26+
} else {
27+
return fixer.replaceText(node, rawElementType + '[]');
28+
}
29+
};
30+
};
31+
1032
export default (defaultConfig, shorthandHandler, verboseHandler) => {
1133
const create = (context) => {
1234
const verbose = (context.options[0] || defaultConfig) === 'verbose';
1335

1436
return {
1537
// shorthand
1638
ArrayTypeAnnotation (node) {
17-
shorthandHandler(isSimpleType(node.elementType), verbose, context, node);
39+
shorthandHandler(isSimpleType(node.elementType), verbose, context, node, fixShorthand(context, node));
1840
},
1941
// verbose
2042
GenericTypeAnnotation (node) {
2143
if (node.id.name === 'Array') {
2244
if (node.typeParameters.params.length === 1) {
23-
verboseHandler(isSimpleType(node.typeParameters.params[0]), verbose, context, node);
45+
verboseHandler(isSimpleType(node.typeParameters.params[0]), verbose, context, node, fixVerbose(context, node));
2446
}
2547
}
2648
}

‎src/rules/arrayStyle/needWrap.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import isSimpleType from './isSimpleType';
2+
3+
const complexTypesWithoutWrap = ['TupleTypeAnnotation', 'ObjectTypeAnnotation'];
4+
5+
export default (node) => {
6+
return !isSimpleType(node) && complexTypesWithoutWrap.indexOf(node.type) === -1;
7+
};

‎src/rules/arrayStyleComplexType.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
import makeArrayStyleRule from './arrayStyle';
22

3-
const shorthandHandler = (isSimpleType, verbose, context, node) => {
3+
const shorthandHandler = (isSimpleType, verbose, context, node, fix) => {
44
if (!isSimpleType && verbose) {
55
context.report({
6+
fix,
67
message: 'Use "Array<ComplexType>", not "ComplexType[]"',
78
node
89
});
910
}
1011
};
1112

12-
const verboseHandler = (isSimpleType, verbose, context, node) => {
13+
const verboseHandler = (isSimpleType, verbose, context, node, fix) => {
1314
if (!isSimpleType && !verbose) {
1415
context.report({
16+
fix,
1517
message: 'Use "ComplexType[]", not "Array<ComplexType>"',
1618
node
1719
});

‎src/rules/arrayStyleSimpleType.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
import makeArrayStyleRule from './arrayStyle';
22

3-
const shorthandHandler = (isSimpleType, verbose, context, node) => {
3+
const shorthandHandler = (isSimpleType, verbose, context, node, fix) => {
44
if (isSimpleType && verbose) {
55
context.report({
6+
fix,
67
message: 'Use "Array<SimpleType>", not "SimpleType[]"',
78
node
89
});
910
}
1011
};
1112

12-
const verboseHandler = (isSimpleType, verbose, context, node) => {
13+
const verboseHandler = (isSimpleType, verbose, context, node, fix) => {
1314
if (isSimpleType && !verbose) {
1415
context.report({
16+
fix,
1517
message: 'Use "SimpleType[]", not "Array<SimpleType>"',
1618
node
1719
});

‎tests/rules/assertions/arrayStyleComplexType.js

+23-9
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,51 @@ export default {
22
invalid: [
33
{
44
code: 'type X = (?string)[]',
5-
errors: [{message: 'Use "Array<ComplexType>", not "ComplexType[]"'}]
5+
errors: [{message: 'Use "Array<ComplexType>", not "ComplexType[]"'}],
6+
output: 'type X = Array<?string>'
67
},
78
{
89
code: 'type X = (?string)[]',
910
errors: [{message: 'Use "Array<ComplexType>", not "ComplexType[]"'}],
10-
options: ['verbose']
11+
options: ['verbose'],
12+
output: 'type X = Array<?string>'
1113
},
1214
{
1315
code: 'type X = Array<?string>',
1416
errors: [{message: 'Use "ComplexType[]", not "Array<ComplexType>"'}],
15-
options: ['shorthand']
17+
options: ['shorthand'],
18+
output: 'type X = (?string)[]'
19+
},
20+
{
21+
code: 'type X = Array<{foo: string}>',
22+
errors: [{message: 'Use "ComplexType[]", not "Array<ComplexType>"'}],
23+
options: ['shorthand'],
24+
output: 'type X = {foo: string}[]'
1625
},
1726
{
1827
code: 'type X = (string | number)[]',
19-
errors: [{message: 'Use "Array<ComplexType>", not "ComplexType[]"'}]
28+
errors: [{message: 'Use "Array<ComplexType>", not "ComplexType[]"'}],
29+
output: 'type X = Array<string | number>'
2030
},
2131
{
2232
code: 'type X = (string & number)[]',
23-
errors: [{message: 'Use "Array<ComplexType>", not "ComplexType[]"'}]
33+
errors: [{message: 'Use "Array<ComplexType>", not "ComplexType[]"'}],
34+
output: 'type X = Array<string & number>'
2435
},
2536
{
2637
code: 'type X = [string, number][]',
27-
errors: [{message: 'Use "Array<ComplexType>", not "ComplexType[]"'}]
38+
errors: [{message: 'Use "Array<ComplexType>", not "ComplexType[]"'}],
39+
output: 'type X = Array<[string, number]>'
2840
},
2941
{
30-
code: 'type X = ({foo: string})[]',
31-
errors: [{message: 'Use "Array<ComplexType>", not "ComplexType[]"'}]
42+
code: 'type X = {foo: string}[]',
43+
errors: [{message: 'Use "Array<ComplexType>", not "ComplexType[]"'}],
44+
output: 'type X = Array<{foo: string}>'
3245
},
3346
{
3447
code: 'type X = (string => number)[]',
35-
errors: [{message: 'Use "Array<ComplexType>", not "ComplexType[]"'}]
48+
errors: [{message: 'Use "Array<ComplexType>", not "ComplexType[]"'}],
49+
output: 'type X = Array<string => number>'
3650
}
3751
],
3852
misconfigured: [

‎tests/rules/assertions/arrayStyleSimpleType.js

+22-11
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,60 @@ export default {
22
invalid: [
33
{
44
code: 'type X = Array<string>',
5-
errors: [{message: 'Use "SimpleType[]", not "Array<SimpleType>"'}]
5+
errors: [{message: 'Use "SimpleType[]", not "Array<SimpleType>"'}],
6+
output: 'type X = string[]'
67
},
78
{
89
code: 'type X = string[]',
910
errors: [{message: 'Use "Array<SimpleType>", not "SimpleType[]"'}],
10-
options: ['verbose']
11+
options: ['verbose'],
12+
output: 'type X = Array<string>'
1113
},
1214
{
1315
code: 'type X = Array<string>',
1416
errors: [{message: 'Use "SimpleType[]", not "Array<SimpleType>"'}],
15-
options: ['shorthand']
17+
options: ['shorthand'],
18+
output: 'type X = string[]'
1619
},
1720
{
1821
code: 'type X = Array<Date>',
19-
errors: [{message: 'Use "SimpleType[]", not "Array<SimpleType>"'}]
22+
errors: [{message: 'Use "SimpleType[]", not "Array<SimpleType>"'}],
23+
output: 'type X = Date[]'
2024
},
2125
{
2226
code: 'type X = Array<Promise<string>>',
23-
errors: [{message: 'Use "SimpleType[]", not "Array<SimpleType>"'}]
27+
errors: [{message: 'Use "SimpleType[]", not "Array<SimpleType>"'}],
28+
output: 'type X = Promise<string>[]'
2429
},
2530
{
2631
code: 'type X = Array<$Keys<{ foo: string }>>',
27-
errors: [{message: 'Use "SimpleType[]", not "Array<SimpleType>"'}]
32+
errors: [{message: 'Use "SimpleType[]", not "Array<SimpleType>"'}],
33+
output: 'type X = $Keys<{ foo: string }>[]'
2834
},
2935
{
3036
code: 'type X = Array<any>',
31-
errors: [{message: 'Use "SimpleType[]", not "Array<SimpleType>"'}]
37+
errors: [{message: 'Use "SimpleType[]", not "Array<SimpleType>"'}],
38+
output: 'type X = any[]'
3239
},
3340
{
3441
code: 'type X = Array<mixed>',
35-
errors: [{message: 'Use "SimpleType[]", not "Array<SimpleType>"'}]
42+
errors: [{message: 'Use "SimpleType[]", not "Array<SimpleType>"'}],
43+
output: 'type X = mixed[]'
3644
},
3745
{
3846
code: 'type X = Array<void>',
39-
errors: [{message: 'Use "SimpleType[]", not "Array<SimpleType>"'}]
47+
errors: [{message: 'Use "SimpleType[]", not "Array<SimpleType>"'}],
48+
output: 'type X = void[]'
4049
},
4150
{
4251
code: 'type X = Array<null>',
43-
errors: [{message: 'Use "SimpleType[]", not "Array<SimpleType>"'}]
52+
errors: [{message: 'Use "SimpleType[]", not "Array<SimpleType>"'}],
53+
output: 'type X = null[]'
4454
},
4555
{
4656
code: 'type X = Array<string[]>',
47-
errors: [{message: 'Use "SimpleType[]", not "Array<SimpleType>"'}]
57+
errors: [{message: 'Use "SimpleType[]", not "Array<SimpleType>"'}],
58+
output: 'type X = string[][]'
4859
}
4960
],
5061
misconfigured: [

0 commit comments

Comments
 (0)
Please sign in to comment.