-
-
Notifications
You must be signed in to change notification settings - Fork 153
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'pnevyk-feat/array-style'
- Loading branch information
Showing
12 changed files
with
434 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
### `array-style-complex-type` | ||
|
||
_The `--fix` option on the command line automatically fixes problems reported by this rule._ | ||
|
||
Enforces a particular annotation style of complex types. | ||
|
||
Type is considered complex in these cases: | ||
|
||
* [Maybe type](https://flow.org/en/docs/types/maybe/) | ||
* [Function type](https://flow.org/en/docs/types/functions/) | ||
* [Object type](https://flow.org/en/docs/types/objects/) | ||
* [Tuple type](https://flow.org/en/docs/types/tuples/) | ||
* [Union type](https://flow.org/en/docs/types/unions/) | ||
* [Intersection type](https://flow.org/en/docs/types/intersections/) | ||
|
||
This rule takes one argument. | ||
|
||
If it is `'verbose'` then a problem is raised when using `Type[]` instead of `Array<Type>`. | ||
|
||
If it is `'shorthand'` then a problem is raised when using `Array<Type>` instead of `Type[]`. | ||
|
||
The default value is `'verbose'`. | ||
|
||
<!-- assertions arrayStyleComplexType --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
### `array-style-simple-type` | ||
|
||
_The `--fix` option on the command line automatically fixes problems reported by this rule._ | ||
|
||
Enforces a particular array type annotation style of simple types. | ||
|
||
Type is considered simple in these cases: | ||
|
||
* [Primitive types](https://flow.org/en/docs/types/primitives/) | ||
* [Literal types](https://flow.org/en/docs/types/literals/) | ||
* [Mixed type](https://flow.org/en/docs/types/mixed/) | ||
* [Any type](https://flow.org/en/docs/types/any/) | ||
* [Class type](https://flow.org/en/docs/types/classes/) | ||
* [Generic type](https://flow.org/en/docs/types/generics/) | ||
* Array type [shorthand notation](https://flow.org/en/docs/types/arrays/#toc-array-type-shorthand-syntax) | ||
|
||
This rule takes one argument. | ||
|
||
If it is `'verbose'` then a problem is raised when using `Type[]` instead of `Array<Type>`. | ||
|
||
If it is `'shorthand'` then a problem is raised when using `Array<Type>` instead of `Type[]`. | ||
|
||
The default value is `'verbose'`. | ||
|
||
<!-- assertions arrayStyleSimpleType --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import isSimpleType from './isSimpleType'; | ||
import needWrap from './needWrap'; | ||
|
||
const schema = [ | ||
{ | ||
enum: ['verbose', 'shorthand'], | ||
type: 'string' | ||
} | ||
]; | ||
|
||
const inlineType = (type) => { | ||
const inlined = type.replace(/\s+/g, ' '); | ||
|
||
if (inlined.length <= 50) { | ||
return inlined; | ||
} else { | ||
return 'Type'; | ||
} | ||
}; | ||
|
||
export default (defaultConfig, simpleType) => { | ||
const create = (context) => { | ||
const verbose = (context.options[0] || defaultConfig) === 'verbose'; | ||
|
||
return { | ||
// shorthand | ||
ArrayTypeAnnotation (node) { | ||
const rawElementType = context.getSourceCode().getText(node.elementType); | ||
const inlinedType = inlineType(rawElementType); | ||
const wrappedInlinedType = needWrap(node.elementType) ? '(' + inlinedType + ')' : inlinedType; | ||
|
||
if (isSimpleType(node.elementType) === simpleType && verbose) { | ||
context.report({ | ||
data: { | ||
type: inlinedType, | ||
wrappedType: wrappedInlinedType | ||
}, | ||
fix (fixer) { | ||
return fixer.replaceText(node, 'Array<' + rawElementType + '>'); | ||
}, | ||
message: 'Use "Array<{{ type }}>", not "{{ wrappedType }}[]"', | ||
node | ||
}); | ||
} | ||
}, | ||
// verbose | ||
GenericTypeAnnotation (node) { | ||
if (node.id.name === 'Array') { | ||
if (node.typeParameters.params.length === 1) { | ||
const elementTypeNode = node.typeParameters.params[0]; | ||
const rawElementType = context.getSourceCode().getText(elementTypeNode); | ||
const inlinedType = inlineType(rawElementType); | ||
const wrappedInlinedType = needWrap(elementTypeNode) ? '(' + inlinedType + ')' : inlinedType; | ||
|
||
if (isSimpleType(elementTypeNode) === simpleType && !verbose) { | ||
context.report({ | ||
data: { | ||
type: inlinedType, | ||
wrappedType: wrappedInlinedType | ||
}, | ||
fix (fixer) { | ||
if (needWrap(elementTypeNode)) { | ||
return fixer.replaceText(node, '(' + rawElementType + ')[]'); | ||
} else { | ||
return fixer.replaceText(node, rawElementType + '[]'); | ||
} | ||
}, | ||
message: 'Use "{{ wrappedType }}[]", not "Array<{{ type }}>"', | ||
node | ||
}); | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
}; | ||
|
||
return { | ||
create, | ||
schema | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/** | ||
* Types considered simple: | ||
* | ||
* - primitive types | ||
* - literal types | ||
* - mixed and any types | ||
* - generic types (such as Date, Promise<string>, $Keys<T>, etc.) | ||
* - array type written in shorthand notation | ||
* | ||
* Types not considered simple: | ||
* | ||
* - maybe type | ||
* - function type | ||
* - object type | ||
* - tuple type | ||
* - union and intersection types | ||
* | ||
* Reminder: if you change these semantics, don't forget to modify documentation of `array-style-...` rules | ||
*/ | ||
|
||
const simpleTypePatterns = [ | ||
/^(?:Any|Array|Boolean|Generic|Mixed|Number|String|Void)TypeAnnotation$/, | ||
/.+LiteralTypeAnnotation$/ | ||
]; | ||
|
||
export default (node) => { | ||
return simpleTypePatterns.some((pattern) => { | ||
return pattern.test(node.type); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import isSimpleType from './isSimpleType'; | ||
|
||
const complexTypesWithoutWrap = ['TupleTypeAnnotation', 'ObjectTypeAnnotation']; | ||
|
||
export default (node) => { | ||
return !isSimpleType(node) && complexTypesWithoutWrap.indexOf(node.type) === -1; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import makeArrayStyleRule from './arrayStyle'; | ||
|
||
export default makeArrayStyleRule('verbose', false); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import makeArrayStyleRule from './arrayStyle'; | ||
|
||
export default makeArrayStyleRule('verbose', true); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
export default { | ||
invalid: [ | ||
{ | ||
code: 'type X = (?string)[]', | ||
errors: [{message: 'Use "Array<?string>", not "(?string)[]"'}], | ||
output: 'type X = Array<?string>' | ||
}, | ||
{ | ||
code: 'type X = (?string)[]', | ||
errors: [{message: 'Use "Array<?string>", not "(?string)[]"'}], | ||
options: ['verbose'], | ||
output: 'type X = Array<?string>' | ||
}, | ||
{ | ||
code: 'type X = Array<?string>', | ||
errors: [{message: 'Use "(?string)[]", not "Array<?string>"'}], | ||
options: ['shorthand'], | ||
output: 'type X = (?string)[]' | ||
}, | ||
{ | ||
code: 'type X = Array<{foo: string}>', | ||
errors: [{message: 'Use "{foo: string}[]", not "Array<{foo: string}>"'}], | ||
options: ['shorthand'], | ||
output: 'type X = {foo: string}[]' | ||
}, | ||
{ | ||
code: 'type X = (string | number)[]', | ||
errors: [{message: 'Use "Array<string | number>", not "(string | number)[]"'}], | ||
output: 'type X = Array<string | number>' | ||
}, | ||
{ | ||
code: 'type X = (string & number)[]', | ||
errors: [{message: 'Use "Array<string & number>", not "(string & number)[]"'}], | ||
output: 'type X = Array<string & number>' | ||
}, | ||
{ | ||
code: 'type X = [string, number][]', | ||
errors: [{message: 'Use "Array<[string, number]>", not "[string, number][]"'}], | ||
output: 'type X = Array<[string, number]>' | ||
}, | ||
{ | ||
code: 'type X = {foo: string}[]', | ||
errors: [{message: 'Use "Array<{foo: string}>", not "{foo: string}[]"'}], | ||
output: 'type X = Array<{foo: string}>' | ||
}, | ||
{ | ||
code: 'type X = (string => number)[]', | ||
errors: [{message: 'Use "Array<string => number>", not "(string => number)[]"'}], | ||
output: 'type X = Array<string => number>' | ||
}, | ||
{ | ||
code: 'type X = {\n foo: string,\n bar: number\n}[]', | ||
errors: [{message: 'Use "Array<{ foo: string, bar: number }>", not "{ foo: string, bar: number }[]"'}], | ||
output: 'type X = Array<{\n foo: string,\n bar: number\n}>' | ||
}, | ||
{ | ||
code: 'type X = {\n foo: string,\n bar: number,\n quo: boolean,\n hey: Date\n}[]', | ||
errors: [{message: 'Use "Array<Type>", not "Type[]"'}], | ||
output: 'type X = Array<{\n foo: string,\n bar: number,\n quo: boolean,\n hey: Date\n}>' | ||
} | ||
], | ||
misconfigured: [ | ||
{ | ||
errors: [ | ||
{ | ||
data: 'normal', | ||
dataPath: '[0]', | ||
keyword: 'enum', | ||
message: 'should be equal to one of the allowed values', | ||
params: { | ||
allowedValues: [ | ||
'verbose', | ||
'shorthand' | ||
] | ||
}, | ||
parentSchema: { | ||
enum: [ | ||
'verbose', | ||
'shorthand' | ||
], | ||
type: 'string' | ||
}, | ||
schema: [ | ||
'verbose', | ||
'shorthand' | ||
], | ||
schemaPath: '#/items/0/enum' | ||
} | ||
], | ||
options: ['normal'] | ||
} | ||
], | ||
valid: [ | ||
{ | ||
code: 'type X = Array<?string>' | ||
}, | ||
{ | ||
code: 'type X = Array<?string>', | ||
options: ['verbose'] | ||
}, | ||
{ | ||
code: 'type X = (?string)[]', | ||
options: ['shorthand'] | ||
}, | ||
{ | ||
code: 'type X = Array<string>', | ||
options: ['shorthand'] | ||
}, | ||
{ | ||
code: 'type X = Array<?string>', | ||
options: ['shorthand'], | ||
settings: { | ||
flowtype: { | ||
onlyFilesWithFlowAnnotation: true | ||
} | ||
} | ||
} | ||
] | ||
}; |
Oops, something went wrong.