UNPKG

7.95 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
8
9var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
10
11var _lodash = require('lodash');
12
13var _lodash2 = _interopRequireDefault(_lodash);
14
15var _utilities = require('./../utilities');
16
17function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18
19var parseOptions = function parseOptions(context) {
20 return {
21 always: (context.options[0] || 'always') === 'always'
22 };
23};
24
25var propertyEvaluator = function propertyEvaluator(context, typeForMessage) {
26 var _parseOptions = parseOptions(context);
27
28 var always = _parseOptions.always;
29
30
31 var sourceCode = context.getSourceCode();
32
33 var getSpacesAfterColon = function getSpacesAfterColon(node, typeAnnotation) {
34 if (node.type === 'FunctionTypeParam') {
35 var colon = sourceCode.getFirstToken(node, node.optional ? 2 : 1);
36
37 return {
38 colon: colon,
39 spaceAfter: sourceCode.getTokenAfter(colon).start - colon.end
40 };
41 } else {
42 var _sourceCode$getFirstT = sourceCode.getFirstTokens(typeAnnotation, 2);
43
44 var _sourceCode$getFirstT2 = _slicedToArray(_sourceCode$getFirstT, 2);
45
46 var _colon = _sourceCode$getFirstT2[0];
47 var token = _sourceCode$getFirstT2[1];
48
49
50 return {
51 colon: _colon,
52 spaceAfter: token.start - typeAnnotation.start - 1
53 };
54 }
55 };
56
57 return function (node) {
58 var typeAnnotation = _lodash2.default.get(node, 'typeAnnotation') || _lodash2.default.get(node, 'left.typeAnnotation');
59
60 if (typeAnnotation) {
61 var _getSpacesAfterColon = getSpacesAfterColon(node, typeAnnotation);
62
63 var colon = _getSpacesAfterColon.colon;
64 var spaceAfter = _getSpacesAfterColon.spaceAfter;
65
66
67 var data = {
68 name: (0, _utilities.quoteName)((0, _utilities.getParameterName)(node, context)),
69 type: typeForMessage
70 };
71
72 if (always && spaceAfter > 1) {
73 context.report({
74 data: data,
75 fix: _utilities.spacingFixers.stripSpacesAfter(colon, spaceAfter - 1),
76 message: 'There must be 1 space after {{name}}{{type}} type annotation colon.',
77 node: node
78 });
79 } else if (always && spaceAfter === 0) {
80 context.report({
81 data: data,
82 fix: _utilities.spacingFixers.addSpaceAfter(colon),
83 message: 'There must be a space after {{name}}{{type}} type annotation colon.',
84 node: node
85 });
86 } else if (!always && spaceAfter > 0) {
87 context.report({
88 data: data,
89 fix: _utilities.spacingFixers.stripSpacesAfter(colon, spaceAfter),
90 message: 'There must be no space after {{name}}{{type}} type annotation colon.',
91 node: node
92 });
93 }
94 }
95 };
96};
97
98var returnTypeEvaluator = function returnTypeEvaluator(context) {
99 var _parseOptions2 = parseOptions(context);
100
101 var always = _parseOptions2.always;
102
103
104 var sourceCode = context.getSourceCode();
105
106 return function (functionNode) {
107 // skip FunctionTypeAnnotation, possibly another rule as it's an arrow, not a colon?
108 // (foo: number) => string
109 // ^^^^
110 if (functionNode.returnType && functionNode.type !== 'FunctionTypeAnnotation') {
111 var _sourceCode$getFirstT3 = sourceCode.getFirstTokens(functionNode.returnType, 2);
112
113 var _sourceCode$getFirstT4 = _slicedToArray(_sourceCode$getFirstT3, 2);
114
115 var colon = _sourceCode$getFirstT4[0];
116 var token = _sourceCode$getFirstT4[1];
117
118 var spaces = token.start - functionNode.returnType.start - 1;
119
120 if (always && spaces > 1) {
121 context.report({
122 fix: _utilities.spacingFixers.stripSpacesAfter(colon, spaces - 1),
123 message: 'There must be 1 space after return type colon.',
124 node: functionNode
125 });
126 } else if (always && spaces === 0) {
127 context.report({
128 fix: _utilities.spacingFixers.addSpaceAfter(colon),
129 message: 'There must be a space after return type colon.',
130 node: functionNode
131 });
132 } else if (!always && spaces > 0) {
133 context.report({
134 fix: _utilities.spacingFixers.stripSpacesAfter(colon, spaces),
135 message: 'There must be no space after return type colon.',
136 node: functionNode
137 });
138 }
139 }
140 };
141};
142
143var functionEvaluators = (0, _utilities.iterateFunctionNodes)(function (context) {
144 var checkParam = propertyEvaluator(context, 'parameter');
145 var checkReturnType = returnTypeEvaluator(context);
146
147 return function (functionNode) {
148 _lodash2.default.forEach(functionNode.params, checkParam);
149 checkReturnType(functionNode);
150 };
151});
152
153// 1) type X = { foo(): A; }
154// 2) type X = { foo: () => A; }
155// the above have identical ASTs (save for their ranges)
156// case 1 doesn't have a type annotation colon and should be ignored
157var isShortPropertyFunction = function isShortPropertyFunction(objectTypeProperty) {
158 return objectTypeProperty.value.type === 'FunctionTypeAnnotation' && objectTypeProperty.start === objectTypeProperty.value.start;
159};
160
161var objectTypePropertyEvaluator = function objectTypePropertyEvaluator(context) {
162 var _parseOptions3 = parseOptions(context);
163
164 var always = _parseOptions3.always;
165
166
167 var sourceCode = context.getSourceCode();
168
169 var getColon = function getColon(objectTypeProperty) {
170 if (objectTypeProperty.optional || objectTypeProperty.static) {
171 return sourceCode.getFirstToken(objectTypeProperty, 2);
172 } else {
173 return sourceCode.getFirstToken(objectTypeProperty, 1);
174 }
175 };
176
177 return function (objectTypeProperty) {
178 if (isShortPropertyFunction(objectTypeProperty)) {
179 return;
180 }
181
182 var colon = getColon(objectTypeProperty);
183 var typeAnnotation = sourceCode.getTokenAfter(colon);
184
185 var spaces = typeAnnotation.start - colon.end;
186
187 var data = {
188 name: (0, _utilities.quoteName)((0, _utilities.getParameterName)(objectTypeProperty, context))
189 };
190
191 if (always && spaces > 1) {
192 context.report({
193 data: data,
194 fix: _utilities.spacingFixers.stripSpacesAfter(colon, spaces - 1),
195 message: 'There must be 1 space after {{name}}type annotation colon.',
196 node: objectTypeProperty
197 });
198 } else if (always && spaces === 0) {
199 context.report({
200 data: data,
201 fix: _utilities.spacingFixers.addSpaceAfter(colon),
202 message: 'There must be a space after {{name}}type annotation colon.',
203 node: objectTypeProperty
204 });
205 } else if (!always && spaces > 0) {
206 context.report({
207 data: data,
208 fix: _utilities.spacingFixers.stripSpacesAfter(colon, spaces),
209 message: 'There must be no space after {{name}}type annotation colon.',
210 node: objectTypeProperty
211 });
212 }
213 };
214};
215
216exports.default = function (context) {
217 return _extends({}, functionEvaluators(context), {
218 ClassProperty: propertyEvaluator(context, 'class property'),
219 ObjectTypeProperty: objectTypePropertyEvaluator(context)
220 });
221};
222
223module.exports = exports['default'];
\No newline at end of file