Skip to content
This repository was archived by the owner on Jan 19, 2019. It is now read-only.

Commit f612bdf

Browse files
authored
[FIX] [indent] Add more indent cases + tests (#274)
1 parent 08124d4 commit f612bdf

3 files changed

Lines changed: 858 additions & 39 deletions

File tree

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ When adding or changing a rule, you must:
3434
- (if any) outline the settings; how to configure them and what each one does
3535
- have clear examples of valid and invalid code when using the rule. Bonus points for extra cases showing what each setting does.
3636

37-
When adding a rule, you must also add a link to the rule in the README.md.
37+
When adding a rule, you must also add a link to the rule in the README.md (`yarn docs` will help you with this).
3838

3939
## Submitting Issues
4040

lib/rules/indent.js

Lines changed: 208 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,68 @@ const util = require("../util");
1414
const KNOWN_NODES = new Set([
1515
// Class properties aren't yet supported by eslint...
1616
"ClassProperty",
17+
18+
// ts keywords
19+
"TSAbstractKeyword",
20+
"TSAnyKeyword",
21+
"TSBooleanKeyword",
22+
"TSNeverKeyword",
23+
"TSNumberKeyword",
24+
"TSStringKeyword",
25+
"TSSymbolKeyword",
26+
"TSUndefinedKeyword",
27+
"TSUnknownKeyword",
28+
"TSVoidKeyword",
29+
"TSNullKeyword",
30+
1731
// ts specific nodes we want to support
1832
"TSAbstractClassDeclaration",
1933
"TSAbstractClassProperty",
34+
"TSAbstractMethodDefinition",
35+
"TSArrayType",
36+
"TSAsExpression",
37+
"TSConditionalType",
38+
"TSConstructorType",
2039
"TSConstructSignature",
2140
"TSEmptyBodyDeclareFunction",
41+
"TSEmptyBodyFunctionExpression",
2242
"TSEnumDeclaration",
2343
"TSEnumMember",
2444
"TSExportAssignment",
45+
"TSExternalModuleReference",
46+
"TSFunctionType",
47+
"TSImportType",
48+
"TSIndexedAccessType",
49+
"TSIndexSignature",
50+
"TSInferType",
2551
"TSInterfaceBody",
2652
"TSInterfaceDeclaration",
2753
"TSInterfaceHeritage",
54+
"TSIntersectionType",
2855
"TSImportEqualsDeclaration",
56+
"TSLiteralType",
57+
"TSMappedType",
2958
"TSMethodSignature",
59+
"TSMinusToken",
60+
"TSModuleBlock",
3061
"TSModuleDeclaration",
62+
"TSNonNullExpression",
3163
"TSParameterProperty",
64+
"TSParenthesizedType",
65+
"TSPlusToken",
3266
"TSPropertySignature",
67+
"TSQualifiedName",
68+
"TSQuestionToken",
69+
"TSRestType",
70+
"TSThisType",
71+
"TSTupleType",
3372
"TSTypeAnnotation",
3473
"TSTypeLiteral",
74+
"TSTypeOperator",
75+
"TSTypeParameter",
76+
"TSTypeParameterDeclaration",
3577
"TSTypeReference",
78+
"TSUnionType",
3679
]);
3780

3881
const defaultOptions = [
@@ -43,22 +86,7 @@ const defaultOptions = [
4386
// https://www.typescriptlang.org/docs/handbook/release-notes/typescript-1-8.html#example-4
4487
SwitchCase: 1,
4588
flatTernaryExpressions: false,
46-
// list derived from https://github.com/benjamn/ast-types/blob/HEAD/def/jsx.js
47-
ignoredNodes: [
48-
"JSXElement",
49-
"JSXElement > *",
50-
"JSXAttribute",
51-
"JSXIdentifier",
52-
"JSXNamespacedName",
53-
"JSXMemberExpression",
54-
"JSXSpreadAttribute",
55-
"JSXExpressionContainer",
56-
"JSXOpeningElement",
57-
"JSXClosingElement",
58-
"JSXText",
59-
"JSXEmptyExpression",
60-
"JSXSpreadChild",
61-
],
89+
ignoredNodes: [],
6290
},
6391
];
6492

@@ -124,11 +152,14 @@ module.exports = Object.assign({}, baseRule, {
124152
}
125153
},
126154

127-
"TSTypeLiteral, TSEnumDeclaration"(node) {
128-
// transform it to an ObjectExpression
129-
return rules["ObjectExpression, ObjectPattern"]({
130-
type: "ObjectExpression",
131-
properties: node.members.map(TSPropertySignatureToProperty),
155+
TSAsExpression(node) {
156+
// transform it to a BinaryExpression
157+
return rules["BinaryExpression, LogicalExpression"]({
158+
type: "BinaryExpression",
159+
operator: "as",
160+
left: node.expression,
161+
// the first typeAnnotation includes the as token
162+
right: node.typeAnnotation.typeAnnotation,
132163

133164
// location data
134165
parent: node.parent,
@@ -137,29 +168,41 @@ module.exports = Object.assign({}, baseRule, {
137168
});
138169
},
139170

140-
// handle the interface extends clause
141-
"TSInterfaceDeclaration[heritage.length > 0]"(node) {
142-
return rules[
143-
"ClassDeclaration[superClass], ClassExpression[superClass]"
144-
]({
145-
type: "ClassDeclaration",
146-
body: node.body,
147-
superClass: node.heritage[0].id,
171+
TSConditionalType(node) {
172+
// transform it to a ConditionalExpression
173+
return rules.ConditionalExpression({
174+
type: "ConditionalExpression",
175+
test: {
176+
type: "BinaryExpression",
177+
operator: "extends",
178+
left: node.checkType,
179+
right: node.extendsType,
180+
181+
// location data
182+
range: [
183+
node.checkType.range[0],
184+
node.extendsType.range[1],
185+
],
186+
loc: {
187+
start: node.checkType.loc.start,
188+
end: node.extendsType.loc.end,
189+
},
190+
},
191+
consequent: node.trueType,
192+
alternate: node.falseType,
148193

149194
// location data
150195
parent: node.parent,
151196
range: node.range,
152197
loc: node.loc,
153198
});
154199
},
155-
// handle the interface body
156-
TSInterfaceBody(node) {
157-
// transform it to an ClassBody
158-
return rules["BlockStatement, ClassBody"]({
159-
type: "ClassBody",
160-
body: node.body.map(p =>
161-
TSPropertySignatureToProperty(p, "ClassProperty")
162-
),
200+
201+
"TSEnumDeclaration, TSTypeLiteral"(node) {
202+
// transform it to an ObjectExpression
203+
return rules["ObjectExpression, ObjectPattern"]({
204+
type: "ObjectExpression",
205+
properties: node.members.map(TSPropertySignatureToProperty),
163206

164207
// location data
165208
parent: node.parent,
@@ -220,8 +263,89 @@ module.exports = Object.assign({}, baseRule, {
220263
});
221264
},
222265

266+
TSIndexedAccessType(node) {
267+
// convert to a MemberExpression
268+
return rules[
269+
"MemberExpression, JSXMemberExpression, MetaProperty"
270+
]({
271+
type: "MemberExpression",
272+
object: node.objectType,
273+
property: node.indexType,
274+
275+
// location data
276+
parent: node.parent,
277+
range: node.range,
278+
loc: node.loc,
279+
});
280+
},
281+
282+
TSInterfaceBody(node) {
283+
// transform it to an ClassBody
284+
return rules["BlockStatement, ClassBody"]({
285+
type: "ClassBody",
286+
body: node.body.map(p =>
287+
TSPropertySignatureToProperty(p, "ClassProperty")
288+
),
289+
290+
// location data
291+
parent: node.parent,
292+
range: node.range,
293+
loc: node.loc,
294+
});
295+
},
296+
297+
"TSInterfaceDeclaration[heritage.length > 0]"(node) {
298+
// transform it to a ClassDeclaration
299+
return rules[
300+
"ClassDeclaration[superClass], ClassExpression[superClass]"
301+
]({
302+
type: "ClassDeclaration",
303+
body: node.body,
304+
superClass: node.heritage[0].id,
305+
306+
// location data
307+
parent: node.parent,
308+
range: node.range,
309+
loc: node.loc,
310+
});
311+
},
312+
313+
TSMappedType(node) {
314+
const sourceCode = context.getSourceCode();
315+
const squareBracketStart = sourceCode.getTokenBefore(
316+
node.typeParameter
317+
);
318+
319+
// transform it to an ObjectExpression
320+
return rules["ObjectExpression, ObjectPattern"]({
321+
type: "ObjectExpression",
322+
properties: [
323+
{
324+
type: "Property",
325+
key: node.typeParameter,
326+
value: node.typeAnnotation,
327+
328+
// location data
329+
range: [
330+
squareBracketStart.range[0],
331+
node.typeAnnotation.range[1],
332+
],
333+
loc: {
334+
start: squareBracketStart.loc.start,
335+
end: node.typeAnnotation.loc.end,
336+
},
337+
},
338+
],
339+
340+
// location data
341+
parent: node.parent,
342+
range: node.range,
343+
loc: node.loc,
344+
});
345+
},
346+
223347
TSModuleBlock(node) {
224-
// transform it to a block statement
348+
// transform it to a BlockStatement
225349
return rules["BlockStatement, ClassBody"]({
226350
type: "BlockStatement",
227351
body: node.body,
@@ -232,6 +356,52 @@ module.exports = Object.assign({}, baseRule, {
232356
loc: node.loc,
233357
});
234358
},
359+
360+
TSQualifiedName(node) {
361+
return rules[
362+
"MemberExpression, JSXMemberExpression, MetaProperty"
363+
]({
364+
type: "MemberExpression",
365+
object: node.left,
366+
property: node.right,
367+
368+
// location data
369+
parent: node.parent,
370+
range: node.range,
371+
loc: node.loc,
372+
});
373+
},
374+
375+
TSTupleType(node) {
376+
// transform it to an ArrayExpression
377+
return rules["ArrayExpression, ArrayPattern"]({
378+
type: "ArrayExpression",
379+
elements: node.elementTypes,
380+
381+
// location data
382+
parent: node.parent,
383+
range: node.range,
384+
loc: node.loc,
385+
});
386+
},
387+
388+
TSTypeParameterDeclaration(node) {
389+
const [name, ...attributes] = node.params;
390+
391+
// JSX is about the closest we can get because the angle brackets
392+
// it's not perfect but it works!
393+
return rules.JSXOpeningElement({
394+
type: "JSXOpeningElement",
395+
selfClosing: false,
396+
name,
397+
attributes,
398+
399+
// location data
400+
parent: node.parent,
401+
range: node.range,
402+
loc: node.loc,
403+
});
404+
},
235405
});
236406
},
237407
});

0 commit comments

Comments
 (0)