1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | "use strict";
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | module.exports = function(context) {
|
15 |
|
16 | var configuration = context.options[0] || {},
|
17 | ignoreCase = configuration.ignoreCase || false,
|
18 | ignoreMemberSort = configuration.ignoreMemberSort || false,
|
19 | memberSyntaxSortOrder = configuration.memberSyntaxSortOrder || ["none", "all", "multiple", "single"],
|
20 | previousDeclaration = null;
|
21 |
|
22 | |
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 | function usedMemberSyntax(node) {
|
34 | if (node.specifiers.length === 0) {
|
35 | return "none";
|
36 | } else if (node.specifiers[0].type === "ImportNamespaceSpecifier") {
|
37 | return "all";
|
38 | } else if (node.specifiers.length === 1) {
|
39 | return "single";
|
40 | } else {
|
41 | return "multiple";
|
42 | }
|
43 | }
|
44 |
|
45 | |
46 |
|
47 |
|
48 |
|
49 |
|
50 | function getMemberParameterGroupIndex(node) {
|
51 | return memberSyntaxSortOrder.indexOf(usedMemberSyntax(node));
|
52 | }
|
53 |
|
54 | |
55 |
|
56 |
|
57 |
|
58 |
|
59 | function getFirstLocalMemberName(node) {
|
60 | if (node.specifiers[0]) {
|
61 | return node.specifiers[0].local.name;
|
62 | } else {
|
63 | return null;
|
64 | }
|
65 | }
|
66 |
|
67 | return {
|
68 | "ImportDeclaration": function(node) {
|
69 | if (previousDeclaration) {
|
70 | var currentLocalMemberName = getFirstLocalMemberName(node),
|
71 | currentMemberSyntaxGroupIndex = getMemberParameterGroupIndex(node),
|
72 | previousLocalMemberName = getFirstLocalMemberName(previousDeclaration),
|
73 | previousMemberSyntaxGroupIndex = getMemberParameterGroupIndex(previousDeclaration);
|
74 |
|
75 | if (ignoreCase) {
|
76 | previousLocalMemberName = previousLocalMemberName.toLowerCase();
|
77 | currentLocalMemberName = currentLocalMemberName.toLowerCase();
|
78 | }
|
79 |
|
80 |
|
81 |
|
82 |
|
83 | if (currentMemberSyntaxGroupIndex !== previousMemberSyntaxGroupIndex) {
|
84 | if (currentMemberSyntaxGroupIndex < previousMemberSyntaxGroupIndex) {
|
85 | context.report({
|
86 | node: node,
|
87 | message: "Expected '{{syntaxA}}' syntax before '{{syntaxB}}' syntax.",
|
88 | data: {
|
89 | syntaxA: memberSyntaxSortOrder[currentMemberSyntaxGroupIndex],
|
90 | syntaxB: memberSyntaxSortOrder[previousMemberSyntaxGroupIndex]
|
91 | }
|
92 | });
|
93 | }
|
94 | } else {
|
95 | if (currentLocalMemberName < previousLocalMemberName) {
|
96 | context.report({
|
97 | node: node,
|
98 | message: "Imports should be sorted alphabetically."
|
99 | });
|
100 | }
|
101 | }
|
102 | }
|
103 |
|
104 |
|
105 | if (!ignoreMemberSort && node.specifiers.length > 1) {
|
106 | node.specifiers.reduce(function(previousSpecifier, currentSpecifier) {
|
107 | var currentSpecifierName = currentSpecifier.local.name,
|
108 | previousSpecifierName = previousSpecifier.local.name;
|
109 |
|
110 | if (ignoreCase) {
|
111 | currentSpecifierName = currentSpecifierName.toLowerCase();
|
112 | previousSpecifierName = previousSpecifierName.toLowerCase();
|
113 | }
|
114 |
|
115 | if (currentSpecifierName < previousSpecifierName) {
|
116 | context.report({
|
117 | node: currentSpecifier,
|
118 | message: "Member '{{memberName}}' of the import declaration should be sorted alphabetically.",
|
119 | data: {
|
120 | memberName: currentSpecifier.local.name
|
121 | }
|
122 | });
|
123 | }
|
124 |
|
125 | return currentSpecifier;
|
126 | }, node.specifiers[0]);
|
127 | }
|
128 |
|
129 | previousDeclaration = node;
|
130 | }
|
131 | };
|
132 | };
|
133 |
|
134 | module.exports.schema = [
|
135 | {
|
136 | "type": "object",
|
137 | "properties": {
|
138 | "ignoreCase": {
|
139 | "type": "boolean"
|
140 | },
|
141 | "memberSyntaxSortOrder": {
|
142 | "type": "array",
|
143 | "items": {
|
144 | "enum": ["none", "all", "multiple", "single"]
|
145 | },
|
146 | "uniqueItems": true,
|
147 | "minItems": 4,
|
148 | "maxItems": 4
|
149 | },
|
150 | "ignoreMemberSort": {
|
151 | "type": "boolean"
|
152 | }
|
153 | },
|
154 | "additionalProperties": false
|
155 | }
|
156 | ];
|