Skip to content

Commit

Permalink
Merge branch 'ahstro-feature/require-variable-type'
Browse files Browse the repository at this point in the history
  • Loading branch information
danharper committed Nov 27, 2016
2 parents 02249b9 + 206ff8a commit 7bcb047
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 0 deletions.
1 change: 1 addition & 0 deletions .README/README.md
Expand Up @@ -152,6 +152,7 @@ When `true`, only checks files with a [`@flow` annotation](http://flowtype.org/d
{"gitdown": "include", "file": "./rules/require-parameter-type.md"}
{"gitdown": "include", "file": "./rules/require-return-type.md"}
{"gitdown": "include", "file": "./rules/require-valid-file-annotation.md"}
{"gitdown": "include", "file": "./rules/require-variable-type.md"}
{"gitdown": "include", "file": "./rules/semi.md"}
{"gitdown": "include", "file": "./rules/sort-keys.md"}
{"gitdown": "include", "file": "./rules/space-after-type-colon.md"}
Expand Down
50 changes: 50 additions & 0 deletions .README/rules/require-variable-type.md
@@ -0,0 +1,50 @@
### `require-variable-type`

Requires that all variable declarators have type annotations.

#### Options

You can exclude variables that match a certain regex by using `excludeVariableMatch`.

This excludes all parameters that start with an underscore (`_`).
The default pattern is `a^`, which doesn't match anything, i.e., all parameters are checked.

```js
{
"rules": {
"flowtype/require-variable-type": [
2,
{
"excludeVariableMatch": "^_"
}
]
}
}
```


You can choose specific variable types (`var`, `let`, and `const`) to ignore using `excludeVariableTypes`.

This excludes `var` and `let` declarations from needing type annotations, but forces `const` declarations to have it.
By default, all declarations are checked.

```js
{
"rules": {
"flowtype/require-variable-type": [
2,
{
"excludeVariableTypes": {
"var": true,
"let": true,
"const": false,
}
}
]
}
}
```



<!-- assertions requireVariableType -->
3 changes: 3 additions & 0 deletions src/index.js
Expand Up @@ -4,6 +4,7 @@ import noWeakTypes from './rules/noWeakTypes';
import requireParameterType from './rules/requireParameterType';
import requireReturnType from './rules/requireReturnType';
import requireValidFileAnnotation from './rules/requireValidFileAnnotation';
import requireVariableType from './rules/requireVariableType';
import semi from './rules/semi';
import spaceAfterTypeColon from './rules/spaceAfterTypeColon';
import spaceBeforeGenericBracket from './rules/spaceBeforeGenericBracket';
Expand Down Expand Up @@ -36,6 +37,7 @@ export default {
'require-parameter-type': requireParameterType,
'require-return-type': requireReturnType,
'require-valid-file-annotation': requireValidFileAnnotation,
'require-variable-type': requireVariableType,
semi,
'sort-keys': sortKeys,
'space-after-type-colon': spaceAfterTypeColon,
Expand All @@ -56,6 +58,7 @@ export default {
'object-type-delimiter': 0,
'require-parameter-type': 0,
'require-return-type': 0,
'require-variable-type': 0,
semi: 0,
'sort-keys': 0,
'space-after-type-colon': 0,
Expand Down
47 changes: 47 additions & 0 deletions src/rules/requireVariableType.js
@@ -0,0 +1,47 @@
import _ from 'lodash';
import {
isFlowFile,
quoteName
} from './../utilities';

export default (context) => {
const checkThisFile = !_.get(context, 'settings.flowtype.onlyFilesWithFlowAnnotation') || isFlowFile(context);

if (!checkThisFile) {
return () => {};
}

const excludeVariableMatch = new RegExp(_.get(context, 'options[0].excludeVariableMatch', 'a^'));
const excludeVariableTypes = _.get(context, 'options[0].excludeVariableTypes', {});

return {
VariableDeclaration: (variableDeclaration) => {
const variableType = _.get(variableDeclaration, 'kind');

if (_.get(excludeVariableTypes, variableType)) {
return;
}

_.forEach(variableDeclaration.declarations, (variableDeclarator) => {
const identifierNode = _.get(variableDeclarator, 'id');
const identifierName = _.get(identifierNode, 'name');

if (excludeVariableMatch.test(identifierName)) {
return;
}

const typeAnnotation = _.get(identifierNode, 'typeAnnotation');

if (!typeAnnotation) {
context.report({
data: {
name: quoteName(identifierName)
},
message: 'Missing {{name}}variable type annotation.',
node: identifierNode
});
}
});
}
};
};
86 changes: 86 additions & 0 deletions tests/rules/assertions/requireVariableType.js
@@ -0,0 +1,86 @@
export default {
invalid: [
{
code: 'var foo = "bar"',
errors: [
{
message: 'Missing "foo" variable type annotation.'
}
]
},
{
code: 'var foo : string = "bar", bar = 1',
errors: [
{
message: 'Missing "bar" variable type annotation.'
}
]
},
{
code: 'var _foo = "bar", bar = 1',
errors: [
{
message: 'Missing "bar" variable type annotation.'
}
],
options: [
{
excludeVariableMatch: '^_'
}
]
},
{
code: 'var foo = "bar", bar = 1; const oob : string = "oob"; let hey = "yah"',
errors: [
{
message: 'Missing "hey" variable type annotation.'
}
],
options: [
{
excludeVariableTypes: {
let: false,
var: true
}
}
]
}
],
valid: [
{
code: 'var foo : string = "bar"'
},
{
code: 'var foo : string = "bar", bar : number = 1'
},
{
code: 'var _foo = "bar", bar : number = 1',
options: [
{
excludeVariableMatch: '^_'
}
]
},
{
code: 'var foo = "bar", bar = 1',
options: [
{
excludeVariableTypes: {
var: true
}
}
]
},
{
code: 'var foo = "bar", bar = 1; const oob : string = "oob"; let hey = "yah"',
options: [
{
excludeVariableTypes: {
let: true,
var: true
}
}
]
}
]
};
1 change: 1 addition & 0 deletions tests/rules/index.js
Expand Up @@ -18,6 +18,7 @@ const reportingRules = [
'require-parameter-type',
'require-return-type',
'require-valid-file-annotation',
'require-variable-type',
'semi',
'sort-keys',
'space-after-type-colon',
Expand Down

0 comments on commit 7bcb047

Please sign in to comment.