Skip to content

Commit 8630e60

Browse files
committed
feat: add fixer function
1 parent 6e86cea commit 8630e60

File tree

2 files changed

+197
-34
lines changed
  • lib/node_modules/@stdlib/_tools/eslint/rules/repl-namespace-order

2 files changed

+197
-34
lines changed

lib/node_modules/@stdlib/_tools/eslint/rules/repl-namespace-order/lib/main.js

Lines changed: 117 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -37,67 +37,159 @@ var OPTS_COMPARE = {
3737
* @returns {Object} validators
3838
*/
3939
function main( context ) {
40+
var expressions;
4041
var prevAlias;
42+
var sorted;
4143

42-
return {
43-
'ObjectExpression': validate
44-
};
44+
expressions = [];
4545

4646
/**
47-
* Checks whether packages are added to a REPL namespace object in alphabetical order according to alias (namespace key).
47+
* Extracts the alias value from a given node.
4848
*
4949
* @private
50-
* @param {ASTNode} node - node to examine
50+
* @param {ASTNode} node - node containing properties to search
51+
* @returns {string} alias value
5152
*/
52-
function validate( node ) {
53-
var properties;
53+
function getAlias( node ) {
54+
var props;
5455
var alias;
55-
var prop;
5656
var i;
5757

58-
properties = node.properties;
59-
for ( i = 0; i < properties.length; i++ ) {
60-
prop = properties[ i ];
61-
if ( prop.key.value === 'alias' ) {
62-
alias = prop.value.value;
58+
props = node.properties;
59+
for ( i = 0; i < props.length; i++ ) {
60+
if ( props[ i ].key.value === 'alias' ) {
61+
alias = props[ i ].value.value;
6362
if ( alias ) {
64-
if (
65-
prevAlias &&
66-
alias.localeCompare( prevAlias, 'en', OPTS_COMPARE ) < 0 )
67-
{
68-
report( prevAlias, alias, node );
69-
} else {
70-
prevAlias = alias;
71-
}
63+
return alias;
7264
}
7365
}
7466
}
7567
}
7668

69+
/**
70+
* Compares two nodes and determines their order based on the alias property.
71+
*
72+
* @private
73+
* @param {ASTNode} a - first node
74+
* @param {ASTNode} b - second node
75+
* @returns {number} number indicating sort order
76+
*/
77+
function sortExpressions( a, b ) {
78+
var aliasA = getAlias( a.arguments[ 0 ] );
79+
var aliasB = getAlias( b.arguments[ 0 ] );
80+
return aliasA.localeCompare( aliasB, 'en', OPTS_COMPARE );
81+
}
82+
7783
/**
7884
* Reports the error message.
7985
*
8086
* @private
81-
* @param {string} last - name of first package
82-
* @param {string} current - name of second package
87+
* @param {string} current - name of first package
88+
* @param {string} last - name of second package
8389
* @param {ASTNode} node - node to report
8490
*/
85-
function report( last, current, node ) {
91+
function report( current, last, node ) {
8692
context.report({
8793
'node': node,
88-
'message': '"'+current+'" should come before "'+last+'"'
94+
'message': '"'+last+'" should come before "'+current+'"',
95+
'fix': fix
8996
});
97+
98+
/**
99+
* Fixes the lint error by reordering the packages.
100+
* @private
101+
* @param {Function} fixer - ESLint fixer
102+
* @returns {(Object|null)} fix or null
103+
*/
104+
function fix( fixer ) {
105+
var replacingText;
106+
var startRange;
107+
var endRange;
108+
var source;
109+
var txt;
110+
var i;
111+
112+
source = context.getSourceCode();
113+
replacingText = '';
114+
startRange = expressions[0].range[ 0 ];
115+
endRange = expressions[ expressions.length - 1 ].range[ 1 ];
116+
117+
sorted = expressions.slice().sort( sortExpressions );
118+
119+
for ( i = 0; i < sorted.length; i++ ) {
120+
txt = source.getText( sorted[ i ] );
121+
replacingText += txt;
122+
if ( i < sorted.length - 1 ) {
123+
replacingText += ';\n\n';
124+
}
125+
}
126+
return fixer.replaceTextRange( [ startRange, endRange ], replacingText ); // eslint-disable-line max-len
127+
}
128+
}
129+
130+
/**
131+
* Checks whether the packages are added to REPL namespace object in alphabetical order according to alias (namespace key).
132+
*
133+
* @private
134+
*/
135+
function validate( ) {
136+
var alias;
137+
var i;
138+
139+
for ( i = 0; i < expressions.length; i++ ) {
140+
alias = getAlias( expressions[ i ].arguments[ 0 ] );
141+
if (
142+
prevAlias &&
143+
alias.localeCompare( prevAlias, 'en', OPTS_COMPARE ) < 0
144+
) {
145+
report( prevAlias, alias, expressions[ i ].arguments[ 0 ] );
146+
} else {
147+
prevAlias = alias;
148+
}
149+
}
150+
}
151+
152+
/**
153+
* Collects all expressions which add a package to REPL namespace.
154+
*
155+
* @private
156+
* @param {ASTNode} node - node to examine
157+
*/
158+
function collectExpressions( node ) {
159+
var object;
160+
var alias;
161+
162+
if (
163+
node.callee.type === 'MemberExpression' &&
164+
node.callee.object.name === 'ns' &&
165+
node.callee.property.name === 'push'
166+
) {
167+
object = node.arguments[ 0 ];
168+
if ( object.type === 'ObjectExpression' ) {
169+
alias = getAlias( object );
170+
if ( alias ) {
171+
expressions.push( node );
172+
}
173+
}
174+
}
90175
}
176+
177+
return {
178+
'CallExpression': collectExpressions,
179+
'Program:exit': validate
180+
};
91181
}
92182

93183

94184
// MAIN //
95185

96186
rule = {
97187
'meta': {
188+
'type': 'layout',
98189
'docs': {
99190
'description': 'enforce that packages are added to a REPL namespace object in alphabetical order according to alias (namespace key)'
100191
},
192+
'fixable': 'code',
101193
'schema': []
102194
},
103195
'create': main

lib/node_modules/@stdlib/_tools/eslint/rules/repl-namespace-order/test/fixtures/invalid.js

Lines changed: 80 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,67 @@ test = {
5858
'message': '"hasInt8ArraySupport" should come before "hasMapSupport"',
5959
'type': 'ObjectExpression'
6060
}
61-
]
61+
],
62+
'output': [
63+
'ns.push({',
64+
' \'alias\': \'hasInt8ArraySupport\',',
65+
' \'path\': \'@stdlib/assert/has-int8array-support\',',
66+
' \'value\': require( \'@stdlib/assert/has-int8array-support\' ),',
67+
' \'type\': \'Function\',',
68+
' \'related\': []',
69+
'});',
70+
'',
71+
'ns.push({',
72+
' \'alias\': \'hasInt32ArraySupport\',',
73+
' \'path\': \'@stdlib/assert/has-int32array-support\',',
74+
' \'value\': require( \'@stdlib/assert/has-int32array-support\' ),',
75+
' \'type\': \'Function\',',
76+
' \'related\': []',
77+
'});',
78+
'',
79+
'ns.push({',
80+
' \'alias\': \'hasMapSupport\',',
81+
' \'path\': \'@stdlib/assert/has-map-support\',',
82+
' \'value\': require( \'@stdlib/assert/has-map-support\' ),',
83+
' \'type\': \'Function\',',
84+
' \'related\': []',
85+
'});'
86+
].join( '\n' )
6287
};
6388
invalid.push( test );
6489

6590
test = {
6691
'code': [
92+
'ns.push({',
93+
' \'alias\': \'pop\',',
94+
' \'path\': \'@stdlib/utils/pop\',',
95+
' \'value\': require( \'@stdlib/utils/pop\' ),',
96+
' \'type\': \'Function\',',
97+
' \'related\': [',
98+
' \'@stdlib/utils/push\',',
99+
' \'@stdlib/utils/shift\',',
100+
' \'@stdlib/utils/unshift\'',
101+
' ]',
102+
'});',
103+
'',
104+
'ns.push({',
105+
' \'alias\': \'pluck\',',
106+
' \'path\': \'@stdlib/utils/pluck\',',
107+
' \'value\': require( \'@stdlib/utils/pluck\' ),',
108+
' \'type\': \'Function\',',
109+
' \'related\': [',
110+
' \'@stdlib/utils/deep-pluck\',',
111+
' \'@stdlib/utils/pick\'',
112+
' ]',
113+
'});'
114+
].join( '\n' ),
115+
'errors': [
116+
{
117+
'message': '"pluck" should come before "pop"',
118+
'type': 'ObjectExpression'
119+
}
120+
],
121+
'output': [
67122
'ns.push({',
68123
' \'alias\': \'pluck\',',
69124
' \'path\': \'@stdlib/utils/pluck\',',
@@ -86,14 +141,9 @@ test = {
86141
' \'@stdlib/utils/unshift\'',
87142
' ]',
88143
'});'
89-
].join( '\n' ),
90-
'errors': [
91-
{
92-
'message': '"hasInt32ArraySupport" should come before "hasMapSupport"',
93-
'type': 'ObjectExpression'
94-
}
95-
]
144+
].join( '\n' )
96145
};
146+
invalid.push( test );
97147

98148
test = {
99149
'code': [
@@ -122,7 +172,28 @@ test = {
122172
'message': '"AFINN_96" should come before "AFINN_111"',
123173
'type': 'ObjectExpression'
124174
}
125-
]
175+
],
176+
'output': [
177+
'ns.push({',
178+
' \'alias\': \'AFINN_96\',',
179+
' \'path\': \'@stdlib/datasets/afinn-96\',',
180+
' \'value\': require( \'@stdlib/datasets/afinn-96\' ),',
181+
' \'type\': \'Function\',',
182+
' \'related\': [',
183+
' \'@stdlib/datasets/afinn-111\'',
184+
' ]',
185+
'});',
186+
'',
187+
'ns.push({',
188+
' \'alias\': \'AFINN_111\',',
189+
' \'path\': \'@stdlib/datasets/afinn-111\',',
190+
' \'value\': require( \'@stdlib/datasets/afinn-111\' ),',
191+
' \'type\': \'Function\',',
192+
' \'related\': [',
193+
' \'@stdlib/datasets/afinn-96\'',
194+
' ]',
195+
'});'
196+
].join( '\n' )
126197
};
127198
invalid.push( test );
128199

0 commit comments

Comments
 (0)