@cookshack/eslint-config 3.0.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +12 -0
- package/dist/formatter.cjs +2 -1
- package/dist/formatter.js +2 -1
- package/dist/index.cjs +344 -199
- package/dist/index.js +344 -199
- package/formatter.js +2 -1
- package/index.js +63 -67
- package/package.json +1 -1
- package/plugins/always-let.js +5 -4
- package/plugins/fn-args-nl.js +47 -0
- package/plugins/fn-decl-block-start.js +1 -2
- package/plugins/indent-struct.js +145 -0
- package/plugins/init-before-use.js +57 -62
- package/plugins/narrowest-scope.js +24 -25
- package/plugins/positive-vibes.js +15 -15
- package/plugins/use-risky-equal.js +7 -5
- package/plugins/var-decl-block-start.js +2 -2
- package/test/rules/fn-args-nl.js +114 -0
- package/test/rules/indent-struct.js +198 -0
- package/test/rules/init-before-use.js +8 -4
- package/test/rules/narrowest-scope.js +10 -5
- package/test/rules/no-shadow.js +42 -0
package/dist/index.cjs
CHANGED
|
@@ -15,7 +15,7 @@ function print
|
|
|
15
15
|
printBuffer.push(args.join(' '));
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
function trace$
|
|
18
|
+
function trace$2
|
|
19
19
|
(...args) {
|
|
20
20
|
}
|
|
21
21
|
|
|
@@ -124,7 +124,8 @@ function getConditionalContext
|
|
|
124
124
|
return ''
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
function nodeContains
|
|
127
|
+
function nodeContains
|
|
128
|
+
(node, target) {
|
|
128
129
|
if (node == target)
|
|
129
130
|
return true
|
|
130
131
|
if (node && typeof node == 'object')
|
|
@@ -134,7 +135,8 @@ function nodeContains(node, target) {
|
|
|
134
135
|
return false
|
|
135
136
|
}
|
|
136
137
|
|
|
137
|
-
function nodeHas
|
|
138
|
+
function nodeHas
|
|
139
|
+
(value, target) {
|
|
138
140
|
if (value == target)
|
|
139
141
|
return true
|
|
140
142
|
if (Array.isArray(value))
|
|
@@ -198,7 +200,8 @@ function mayBeReadBeforeAnyWrite
|
|
|
198
200
|
}
|
|
199
201
|
}
|
|
200
202
|
|
|
201
|
-
function scopeStart
|
|
203
|
+
function scopeStart
|
|
204
|
+
(scope) {
|
|
202
205
|
if (scope.block == null)
|
|
203
206
|
return Infinity
|
|
204
207
|
if (scope.type == 'function' && scope.block.id)
|
|
@@ -226,12 +229,11 @@ function buildScopeTree
|
|
|
226
229
|
(scope, prefix, scopeToNode, astToTree) {
|
|
227
230
|
let node, siblingNum;
|
|
228
231
|
|
|
229
|
-
node = {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
};
|
|
232
|
+
node = { scope,
|
|
233
|
+
prefix,
|
|
234
|
+
items: [],
|
|
235
|
+
children: [] };
|
|
236
|
+
|
|
235
237
|
scopeToNode.set(scope, node);
|
|
236
238
|
if (scope.block && astToTree)
|
|
237
239
|
astToTree.set(scope.block, node);
|
|
@@ -333,38 +335,36 @@ function checkScopeNode
|
|
|
333
335
|
|
|
334
336
|
defScope = getDefinitionScope(variable);
|
|
335
337
|
defNodePrefix = scopeToNode.get(defScope)?.prefix ?? '?';
|
|
336
|
-
trace$
|
|
338
|
+
trace$2(indent, '1 found decl scope of', variable.name + ':', defNodePrefix + ' ' + defScope.type.toUpperCase());
|
|
337
339
|
|
|
338
340
|
narrowestScope = getNarrowestScope(variable);
|
|
339
341
|
if (narrowestScope) {
|
|
340
342
|
let narrowestPrefix;
|
|
341
343
|
|
|
342
344
|
narrowestPrefix = scopeToNode.get(narrowestScope)?.prefix ?? '?';
|
|
343
|
-
trace$
|
|
345
|
+
trace$2(indent, '2 found narrowest scope of', variable.name + ':', narrowestPrefix + ' ' + narrowestScope?.type.toUpperCase());
|
|
344
346
|
|
|
345
347
|
markConditionalRefs(variable, scopeToNode, narrowestScope);
|
|
346
348
|
|
|
347
349
|
if (defScope == narrowestScope)
|
|
348
350
|
continue
|
|
349
|
-
trace$
|
|
351
|
+
trace$2(indent, '3', variable.name, 'could be moved to a narrower scope');
|
|
350
352
|
|
|
351
353
|
if (defScope.type == 'for') {
|
|
352
|
-
trace$
|
|
354
|
+
trace$2(indent, '4 exception:', variable.name, 'is in a for loop header');
|
|
353
355
|
continue
|
|
354
356
|
}
|
|
355
357
|
if (mayBeReadBeforeAnyWrite(variable, scopeToNode, narrowestScope)) {
|
|
356
|
-
trace$
|
|
358
|
+
trace$2(indent, '4 exception:', variable.name, 'mayBeReadBeforeAnyWrite');
|
|
357
359
|
continue
|
|
358
360
|
}
|
|
359
361
|
|
|
360
|
-
trace$
|
|
362
|
+
trace$2(indent, '5', variable.name, 'is too broad');
|
|
361
363
|
|
|
362
364
|
reported.add(variable);
|
|
363
|
-
context.report({
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
data: { name: variable.name }
|
|
367
|
-
});
|
|
365
|
+
context.report({ node: defNode,
|
|
366
|
+
messageId: 'tooBroad',
|
|
367
|
+
data: { name: variable.name } });
|
|
368
368
|
}
|
|
369
369
|
}
|
|
370
370
|
}
|
|
@@ -409,17 +409,16 @@ function createNarrowestScope
|
|
|
409
409
|
clearPrintBuffer();
|
|
410
410
|
scopeManager = context.sourceCode.scopeManager;
|
|
411
411
|
if (scopeManager)
|
|
412
|
-
return {
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
}
|
|
412
|
+
return { 'Program:exit'
|
|
413
|
+
() {
|
|
414
|
+
let tree, scopeToNode;
|
|
415
|
+
|
|
416
|
+
scopeToNode = new Map;
|
|
417
|
+
nextVarId = 0;
|
|
418
|
+
tree = buildScopeTree(scopeManager.scopes[0], '1', scopeToNode);
|
|
419
|
+
checkScopeNode(context, tree, null, scopeToNode);
|
|
420
|
+
printTree(tree, 0);
|
|
421
|
+
} }
|
|
423
422
|
}
|
|
424
423
|
|
|
425
424
|
var narrowestScopePlugin = { meta: { type: 'suggestion',
|
|
@@ -430,21 +429,21 @@ var narrowestScopePlugin = { meta: { type: 'suggestion',
|
|
|
430
429
|
|
|
431
430
|
function createPositiveVibes
|
|
432
431
|
(context) {
|
|
433
|
-
return {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
432
|
+
return { UnaryExpression
|
|
433
|
+
(node) {
|
|
434
|
+
if (node.operator == '!')
|
|
435
|
+
context.report({ node,
|
|
436
|
+
messageId: 'positiveVibes' });
|
|
437
|
+
},
|
|
438
|
+
BinaryExpression
|
|
439
|
+
(node) {
|
|
440
|
+
if (node.operator == '!=')
|
|
441
|
+
context.report({ node,
|
|
442
|
+
messageId: 'equality' });
|
|
443
|
+
else if (node.operator == '!==')
|
|
444
|
+
context.report({ node,
|
|
445
|
+
messageId: 'strictEquality' });
|
|
446
|
+
} }
|
|
448
447
|
}
|
|
449
448
|
|
|
450
449
|
var positiveVibesPlugin = { meta: { type: 'problem',
|
|
@@ -459,57 +458,60 @@ var useRiskyEqualPlugin = { meta: { type: 'problem',
|
|
|
459
458
|
docs: { description: 'Enforce use of == instead of ===.' },
|
|
460
459
|
messages: { risky: 'Use ==.' },
|
|
461
460
|
schema: [] },
|
|
462
|
-
create
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
461
|
+
create
|
|
462
|
+
(context) {
|
|
463
|
+
return { BinaryExpression
|
|
464
|
+
(node) {
|
|
465
|
+
if (node.operator == '===')
|
|
466
|
+
context.report({ node, messageId: 'risky' });
|
|
467
|
+
} }
|
|
467
468
|
} };
|
|
468
469
|
|
|
469
|
-
function create$
|
|
470
|
+
function create$4
|
|
470
471
|
(context) {
|
|
471
|
-
return { VariableDeclaration
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
472
|
+
return { VariableDeclaration
|
|
473
|
+
(node) {
|
|
474
|
+
if (node.kind == 'const' || node.kind == 'var')
|
|
475
|
+
context.report({ node, messageId: 'useLet' });
|
|
476
|
+
} }
|
|
475
477
|
}
|
|
476
478
|
|
|
477
479
|
var alwaysLetPlugin = { meta: { type: 'problem',
|
|
478
480
|
docs: { description: 'Enforce use of let instead of const or var.' },
|
|
479
481
|
messages: { useLet: 'Use let.' },
|
|
480
482
|
schema: [] },
|
|
481
|
-
create: create$
|
|
483
|
+
create: create$4 };
|
|
482
484
|
|
|
483
|
-
let ostIdCounter,
|
|
485
|
+
let ostIdCounter, $lastOst;
|
|
484
486
|
|
|
485
487
|
ostIdCounter = 0;
|
|
486
|
-
|
|
488
|
+
$lastOst = 0;
|
|
487
489
|
|
|
488
|
-
function trace
|
|
490
|
+
function trace$1
|
|
489
491
|
(...args) {
|
|
490
492
|
}
|
|
491
493
|
|
|
492
|
-
function createInitBeforeUse
|
|
494
|
+
function createInitBeforeUse
|
|
495
|
+
(context) {
|
|
493
496
|
let scopeManager;
|
|
494
497
|
|
|
495
498
|
scopeManager = context.sourceCode.scopeManager;
|
|
496
499
|
if (scopeManager)
|
|
497
|
-
return {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
500
|
+
return { 'Program:exit'
|
|
501
|
+
() {
|
|
502
|
+
let scopeToNode, astToTree, astToOst;
|
|
503
|
+
scopeToNode = new Map;
|
|
504
|
+
astToTree = new Map;
|
|
505
|
+
astToOst = new Map;
|
|
506
|
+
buildScopeTree(scopeManager.scopes[0], '1', scopeToNode, astToTree);
|
|
504
507
|
|
|
505
|
-
|
|
506
|
-
|
|
508
|
+
ostIdCounter = 0;
|
|
509
|
+
$lastOst = processAst(context.sourceCode.ast, null, astToTree, astToOst, '', new Set());
|
|
507
510
|
|
|
508
|
-
|
|
511
|
+
ostAnnotate($lastOst, astToOst, context);
|
|
509
512
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
}
|
|
513
|
+
ostCheck($lastOst, context);
|
|
514
|
+
} }
|
|
513
515
|
}
|
|
514
516
|
|
|
515
517
|
function isRegularDeclaration
|
|
@@ -522,7 +524,8 @@ function isRegularDeclaration
|
|
|
522
524
|
return 0
|
|
523
525
|
}
|
|
524
526
|
|
|
525
|
-
function processAst
|
|
527
|
+
function processAst
|
|
528
|
+
(astNode, parentOst, astToTree, astToOst, indent, visited) {
|
|
526
529
|
if (astNode) {
|
|
527
530
|
let treeNode, scopeName, lets, reads, writes, ost, children;
|
|
528
531
|
|
|
@@ -535,7 +538,7 @@ function processAst(astNode, parentOst, astToTree, astToOst, indent, visited) {
|
|
|
535
538
|
scopeName = treeNode?.scope ? `${treeNode.scope.type}` : 'no-scope';
|
|
536
539
|
if (treeNode?.scope?.block?.id?.name)
|
|
537
540
|
scopeName += `(${treeNode.scope.block.id.name})`;
|
|
538
|
-
trace(`${indent}${astNode.type}`);
|
|
541
|
+
trace$1(`${indent}${astNode.type}`);
|
|
539
542
|
|
|
540
543
|
lets = [];
|
|
541
544
|
reads = [];
|
|
@@ -548,31 +551,29 @@ function processAst(astNode, parentOst, astToTree, astToOst, indent, visited) {
|
|
|
548
551
|
scopeCreator = treeNode?.scope?.block;
|
|
549
552
|
if (scopeCreator && astNode == scopeCreator) {
|
|
550
553
|
lets.push({ item });
|
|
551
|
-
trace(`${indent} | LET ${item.name}:${item.varId}`);
|
|
554
|
+
trace$1(`${indent} | LET ${item.name}:${item.varId}`);
|
|
552
555
|
}
|
|
553
556
|
}
|
|
554
557
|
else if (item.ref)
|
|
555
558
|
if (astNode == item.ref.identifier)
|
|
556
559
|
if (item.type == 'READ') {
|
|
557
560
|
reads.push({ item });
|
|
558
|
-
trace(`${indent} | READ ${item.name}:${item.varId}`);
|
|
561
|
+
trace$1(`${indent} | READ ${item.name}:${item.varId}`);
|
|
559
562
|
}
|
|
560
563
|
else if (item.type == 'WRITE') {
|
|
561
564
|
writes.push({ item });
|
|
562
|
-
trace(`${indent} | WRITE ${item.name}:${item.varId}`);
|
|
565
|
+
trace$1(`${indent} | WRITE ${item.name}:${item.varId}`);
|
|
563
566
|
}
|
|
564
567
|
|
|
565
|
-
ost = {
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
fnDefOst: null
|
|
575
|
-
};
|
|
568
|
+
ost = { id: ostIdCounter++,
|
|
569
|
+
astNode,
|
|
570
|
+
treeNode,
|
|
571
|
+
scopeItems: treeNode?.items ?? [],
|
|
572
|
+
lets,
|
|
573
|
+
reads,
|
|
574
|
+
writes,
|
|
575
|
+
children: [],
|
|
576
|
+
fnDefOst: null };
|
|
576
577
|
|
|
577
578
|
astToOst.set(astNode, ost);
|
|
578
579
|
|
|
@@ -658,7 +659,8 @@ function processAst(astNode, parentOst, astToTree, astToOst, indent, visited) {
|
|
|
658
659
|
}
|
|
659
660
|
}
|
|
660
661
|
|
|
661
|
-
function ostAnnotate
|
|
662
|
+
function ostAnnotate
|
|
663
|
+
(ost, astToOst, context) {
|
|
662
664
|
if (ost) {
|
|
663
665
|
for (let letInfo of ost.lets) {
|
|
664
666
|
let writeOst;
|
|
@@ -669,11 +671,9 @@ function ostAnnotate(ost, astToOst, context) {
|
|
|
669
671
|
continue
|
|
670
672
|
if (letInfo.item.defType == 'ImportBinding')
|
|
671
673
|
continue
|
|
672
|
-
context.report({
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
data: { name: letInfo.item.name }
|
|
676
|
-
});
|
|
674
|
+
context.report({ node: letInfo.item.identifier,
|
|
675
|
+
messageId: 'mustInit',
|
|
676
|
+
data: { name: letInfo.item.name } });
|
|
677
677
|
}
|
|
678
678
|
|
|
679
679
|
if (ost.astNode.type == 'CallExpression' && ost.astNode.callee?.type == 'Identifier')
|
|
@@ -704,7 +704,8 @@ function ostAnnotate(ost, astToOst, context) {
|
|
|
704
704
|
}
|
|
705
705
|
}
|
|
706
706
|
|
|
707
|
-
function findFirstWrite
|
|
707
|
+
function findFirstWrite
|
|
708
|
+
(ost, letInfo) {
|
|
708
709
|
if (ost.astNode.type == 'FunctionDeclaration' || ost.astNode.type == 'ArrowFunctionExpression' || ost.astNode.type == 'FunctionExpression')
|
|
709
710
|
for (let child of ost.children)
|
|
710
711
|
if (child.astNode.type == 'BlockStatement')
|
|
@@ -712,7 +713,8 @@ function findFirstWrite(ost, letInfo) {
|
|
|
712
713
|
return findFirstWriteInSubtree(ost, letInfo)
|
|
713
714
|
}
|
|
714
715
|
|
|
715
|
-
function findFirstWriteInSubtree
|
|
716
|
+
function findFirstWriteInSubtree
|
|
717
|
+
(ost, letInfo) {
|
|
716
718
|
if (ost) {
|
|
717
719
|
if (ost.astNode.type == 'FunctionDeclaration' || ost.astNode.type == 'ArrowFunctionExpression' || ost.astNode.type == 'FunctionExpression')
|
|
718
720
|
return null
|
|
@@ -737,7 +739,8 @@ function findFirstWriteInSubtree(ost, letInfo) {
|
|
|
737
739
|
return null
|
|
738
740
|
}
|
|
739
741
|
|
|
740
|
-
function ostCheck
|
|
742
|
+
function ostCheck
|
|
743
|
+
(ost, context) {
|
|
741
744
|
if (ost) {
|
|
742
745
|
for (let letInfo of ost.lets)
|
|
743
746
|
if (letInfo.firstWrite)
|
|
@@ -748,7 +751,8 @@ function ostCheck(ost, context) {
|
|
|
748
751
|
}
|
|
749
752
|
}
|
|
750
753
|
|
|
751
|
-
function walk2Start
|
|
754
|
+
function walk2Start
|
|
755
|
+
(node, letInfo, context) {
|
|
752
756
|
if (node.astNode.type == 'FunctionDeclaration')
|
|
753
757
|
for (let child of node.children)
|
|
754
758
|
if (child.astNode.type == 'BlockStatement')
|
|
@@ -756,7 +760,8 @@ function walk2Start(node, letInfo, context) {
|
|
|
756
760
|
return walk2(node, letInfo, context, new Set())
|
|
757
761
|
}
|
|
758
762
|
|
|
759
|
-
function walk2
|
|
763
|
+
function walk2
|
|
764
|
+
(node, letInfo, context, visited) {
|
|
760
765
|
if (node) {
|
|
761
766
|
if (node.astNode.type == 'FunctionDeclaration' || node.astNode.type == 'ArrowFunctionExpression' || node.astNode.type == 'FunctionExpression')
|
|
762
767
|
return false
|
|
@@ -764,11 +769,9 @@ function walk2(node, letInfo, context, visited) {
|
|
|
764
769
|
if (node == letInfo.firstWrite) {
|
|
765
770
|
for (let readInfo of node.reads)
|
|
766
771
|
if (readInfo.item.ref.resolved == letInfo.item.variable) {
|
|
767
|
-
context.report({
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
data: { name: letInfo.item.name }
|
|
771
|
-
});
|
|
772
|
+
context.report({ node: readInfo.item.ref.identifier,
|
|
773
|
+
messageId: 'initBeforeUse',
|
|
774
|
+
data: { name: letInfo.item.name } });
|
|
772
775
|
}
|
|
773
776
|
return true
|
|
774
777
|
}
|
|
@@ -794,11 +797,9 @@ function walk2(node, letInfo, context, visited) {
|
|
|
794
797
|
|
|
795
798
|
for (let readInfo of node.reads)
|
|
796
799
|
if (readInfo.item.ref.resolved == letInfo.item.variable) {
|
|
797
|
-
context.report({
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
data: { name: letInfo.item.name }
|
|
801
|
-
});
|
|
800
|
+
context.report({ node: readInfo.item.ref.identifier,
|
|
801
|
+
messageId: 'initBeforeUse',
|
|
802
|
+
data: { name: letInfo.item.name } });
|
|
802
803
|
}
|
|
803
804
|
|
|
804
805
|
for (let child of node.children)
|
|
@@ -809,19 +810,14 @@ function walk2(node, letInfo, context, visited) {
|
|
|
809
810
|
return false
|
|
810
811
|
}
|
|
811
812
|
|
|
812
|
-
var initBeforeUsePlugin = {
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
schema: []
|
|
819
|
-
},
|
|
820
|
-
create: createInitBeforeUse
|
|
821
|
-
};
|
|
813
|
+
var initBeforeUsePlugin = { meta: { type: 'problem',
|
|
814
|
+
docs: { description: 'Warn when a variable is used before being explicitly initialized.' },
|
|
815
|
+
messages: { initBeforeUse: "'{{name}}' used before initialization.",
|
|
816
|
+
mustInit: "'{{name}}' must be initialized." },
|
|
817
|
+
schema: [] },
|
|
818
|
+
create: createInitBeforeUse };
|
|
822
819
|
|
|
823
|
-
function
|
|
824
|
-
VariableDeclaration
|
|
820
|
+
function VariableDeclaration
|
|
825
821
|
(context, node) {
|
|
826
822
|
let parent;
|
|
827
823
|
|
|
@@ -846,7 +842,8 @@ VariableDeclaration
|
|
|
846
842
|
}
|
|
847
843
|
}
|
|
848
844
|
}
|
|
849
|
-
|
|
845
|
+
|
|
846
|
+
function create$3
|
|
850
847
|
(context) {
|
|
851
848
|
return { VariableDeclaration: node => VariableDeclaration(context, node) }
|
|
852
849
|
}
|
|
@@ -855,10 +852,9 @@ var varDeclBlockStartPlugin = { meta: { type: 'suggestion',
|
|
|
855
852
|
docs: { description: 'Require variable declarations to be at the start of the block.' },
|
|
856
853
|
messages: { varDeclBlockStart: 'VarDecl must be at start of block.' },
|
|
857
854
|
schema: [] },
|
|
858
|
-
create: create$
|
|
855
|
+
create: create$3 };
|
|
859
856
|
|
|
860
|
-
function
|
|
861
|
-
FunctionDeclaration
|
|
857
|
+
function FunctionDeclaration
|
|
862
858
|
(context, node) {
|
|
863
859
|
let parent;
|
|
864
860
|
|
|
@@ -884,7 +880,7 @@ FunctionDeclaration
|
|
|
884
880
|
}
|
|
885
881
|
}
|
|
886
882
|
|
|
887
|
-
function create
|
|
883
|
+
function create$2
|
|
888
884
|
(context) {
|
|
889
885
|
return { FunctionDeclaration: node => FunctionDeclaration(context, node) }
|
|
890
886
|
}
|
|
@@ -893,7 +889,162 @@ var fnDeclBlockStartPlugin = { meta: { type: 'suggestion',
|
|
|
893
889
|
docs: { description: 'Require function declarations to be at the start of the block.' },
|
|
894
890
|
messages: { fnDeclBlockStart: 'FnDecl must be the start the block (after VarDecls).' },
|
|
895
891
|
schema: [] },
|
|
896
|
-
create };
|
|
892
|
+
create: create$2 };
|
|
893
|
+
|
|
894
|
+
function FnArgsNl
|
|
895
|
+
(node, context) {
|
|
896
|
+
let nameLine, parenLine, nameEnd, i, newlines, parent;
|
|
897
|
+
|
|
898
|
+
parent = node.parent;
|
|
899
|
+
|
|
900
|
+
if (parent?.type == 'Property' && (parent.method || parent.kind == 'get' || parent.kind == 'set')) {
|
|
901
|
+
nameLine = parent.key.loc.start.line;
|
|
902
|
+
nameEnd = parent.key.range[1];
|
|
903
|
+
}
|
|
904
|
+
else if (parent?.type == 'MethodDefinition') {
|
|
905
|
+
nameLine = parent.key.loc.start.line;
|
|
906
|
+
nameEnd = parent.key.range[1];
|
|
907
|
+
}
|
|
908
|
+
else {
|
|
909
|
+
nameLine = node.loc.start.line;
|
|
910
|
+
nameEnd = node.range[0];
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
i = nameEnd;
|
|
914
|
+
newlines = 0;
|
|
915
|
+
while (i < context.sourceCode.text.length) {
|
|
916
|
+
if (context.sourceCode.text[i] == '(')
|
|
917
|
+
break
|
|
918
|
+
if (context.sourceCode.text[i] == '\n')
|
|
919
|
+
newlines++;
|
|
920
|
+
i++;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
parenLine = nameLine + newlines;
|
|
924
|
+
|
|
925
|
+
if (parenLine - nameLine == 1)
|
|
926
|
+
return
|
|
927
|
+
context.report({ node, messageId: 'fnArgsNl' });
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
function create$1
|
|
931
|
+
(context) {
|
|
932
|
+
return { FunctionDeclaration: node => FnArgsNl(node, context),
|
|
933
|
+
FunctionExpression: node => FnArgsNl(node, context) }
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
var fnArgsNlPlugin = { meta: { type: 'suggestion',
|
|
937
|
+
docs: { description: 'Require function args on the line immediately after the function name.' },
|
|
938
|
+
messages: { fnArgsNl: 'Fn args must be on the line immediately after the function name.' },
|
|
939
|
+
schema: [] },
|
|
940
|
+
create: create$1 };
|
|
941
|
+
|
|
942
|
+
function trace
|
|
943
|
+
(...args) {
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
function unit
|
|
947
|
+
(context) {
|
|
948
|
+
return context.options[0] ?? 2
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
function checkObjectExpressionProperties
|
|
952
|
+
(properties, node, context) {
|
|
953
|
+
let firstProp, sourceCode, lastProp, lastPropEnd, closingBrace, firstPropLine, firstPropCol, afterLastProp, closingLine, lastPropValueEndLine;
|
|
954
|
+
|
|
955
|
+
sourceCode = context.sourceCode.text;
|
|
956
|
+
firstProp = properties[0];
|
|
957
|
+
lastProp = properties[properties.length - 1];
|
|
958
|
+
firstPropLine = firstProp.loc.start.line;
|
|
959
|
+
firstPropCol = firstProp.loc.start.column;
|
|
960
|
+
lastPropEnd = lastProp.range[1];
|
|
961
|
+
closingBrace = sourceCode.indexOf('}', lastPropEnd);
|
|
962
|
+
closingLine = sourceCode.slice(0, closingBrace).split('\n').length;
|
|
963
|
+
afterLastProp = sourceCode.slice(lastPropEnd, closingBrace);
|
|
964
|
+
lastPropValueEndLine = sourceCode.slice(0, lastPropEnd).split('\n').length;
|
|
965
|
+
trace('CHECK POINT 1: is single-line? firstPropLine=%d, braceLine=%d, closingLine=%d', firstPropLine, node.loc.start.line, closingLine);
|
|
966
|
+
if (firstPropLine == node.loc.start.line && closingLine == firstPropLine)
|
|
967
|
+
return
|
|
968
|
+
trace('CHECK POINT 2: is firstPropLine (%d) != braceLine (%d)?', firstPropLine, node.loc.start.line);
|
|
969
|
+
if (firstPropLine == node.loc.start.line) ;
|
|
970
|
+
else if (firstPropCol == node.loc.start.column + unit(context)) ;
|
|
971
|
+
else {
|
|
972
|
+
context.report({ node: firstProp, messageId: 'indentStruct' });
|
|
973
|
+
}
|
|
974
|
+
for (let i = 1; i < properties.length; i++) {
|
|
975
|
+
let prop;
|
|
976
|
+
|
|
977
|
+
prop = properties[i];
|
|
978
|
+
if (prop.loc.start.column == firstPropCol) ;
|
|
979
|
+
else {
|
|
980
|
+
context.report({ node: prop, messageId: 'indentStruct' });
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
if (closingLine > lastPropValueEndLine) {
|
|
984
|
+
let braceCol, closingCol;
|
|
985
|
+
|
|
986
|
+
braceCol = node.loc.start.column;
|
|
987
|
+
closingCol = node.loc.end.column - 1;
|
|
988
|
+
if (closingCol == braceCol) ;
|
|
989
|
+
else {
|
|
990
|
+
context.report({ node, messageId: 'indentStruct' });
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
if (closingLine == lastPropValueEndLine) {
|
|
994
|
+
if (afterLastProp == ' ') ;
|
|
995
|
+
else {
|
|
996
|
+
context.report({ node, messageId: 'indentStruct' });
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
for (let prop of properties)
|
|
1000
|
+
if (prop.method) {
|
|
1001
|
+
let keyLine, keyEnd, i, newlines, parenLine;
|
|
1002
|
+
|
|
1003
|
+
keyLine = prop.key.loc.start.line;
|
|
1004
|
+
keyEnd = prop.key.range[1];
|
|
1005
|
+
i = keyEnd;
|
|
1006
|
+
newlines = 0;
|
|
1007
|
+
|
|
1008
|
+
while (i < sourceCode.length) {
|
|
1009
|
+
if (sourceCode[i] == '(')
|
|
1010
|
+
break
|
|
1011
|
+
if (sourceCode[i] == '\n')
|
|
1012
|
+
newlines++;
|
|
1013
|
+
i++;
|
|
1014
|
+
}
|
|
1015
|
+
parenLine = keyLine + newlines;
|
|
1016
|
+
if (parenLine > keyLine) {
|
|
1017
|
+
let parenCol;
|
|
1018
|
+
|
|
1019
|
+
parenCol = i - sourceCode.lastIndexOf('\n', i);
|
|
1020
|
+
if (prop.value.type == 'FunctionExpression' && prop.value.async) ;
|
|
1021
|
+
else if (parenCol - 1 == prop.key.loc.start.column) ;
|
|
1022
|
+
else {
|
|
1023
|
+
context.report({ node: prop, messageId: 'indentStruct' });
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
function checkObjectExpression
|
|
1030
|
+
(node, context) {
|
|
1031
|
+
let properties;
|
|
1032
|
+
|
|
1033
|
+
properties = node.properties;
|
|
1034
|
+
if (properties.length)
|
|
1035
|
+
checkObjectExpressionProperties(properties, node, context);
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
function create
|
|
1039
|
+
(context) {
|
|
1040
|
+
return { ObjectExpression: node => checkObjectExpression(node, context) }
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
var indentStructPlugin = { meta: { type: 'suggestion',
|
|
1044
|
+
docs: { description: 'Struct alignment rules.' },
|
|
1045
|
+
messages: { indentStruct: 'Indent structure' },
|
|
1046
|
+
schema: [] },
|
|
1047
|
+
create };
|
|
897
1048
|
|
|
898
1049
|
exports.rules = void 0; exports.languageOptions = void 0; exports.plugins = void 0;
|
|
899
1050
|
|
|
@@ -903,75 +1054,69 @@ exports.plugins = { 'cookshack': { rules: { 'positive-vibes': positiveVibesPlugi
|
|
|
903
1054
|
'always-let': alwaysLetPlugin,
|
|
904
1055
|
'init-before-use': initBeforeUsePlugin,
|
|
905
1056
|
'var-decl-block-start': varDeclBlockStartPlugin,
|
|
906
|
-
'fn-decl-block-start': fnDeclBlockStartPlugin
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
};
|
|
965
|
-
|
|
966
|
-
exports.languageOptions = {
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
},
|
|
970
|
-
parserOptions: {
|
|
971
|
-
ecmaVersion: 2025,
|
|
972
|
-
sourceType: 'module'
|
|
973
|
-
}
|
|
974
|
-
};
|
|
1057
|
+
'fn-decl-block-start': fnDeclBlockStartPlugin,
|
|
1058
|
+
'fn-args-nl': fnArgsNlPlugin,
|
|
1059
|
+
'indent-struct': indentStructPlugin } } };
|
|
1060
|
+
|
|
1061
|
+
exports.rules = { 'array-bracket-newline': [ 'error', 'never' ],
|
|
1062
|
+
'array-bracket-spacing': [ 'error', 'always' ],
|
|
1063
|
+
'arrow-parens': [ 'error', 'as-needed' ],
|
|
1064
|
+
'brace-style': [ 'error', 'stroustrup' ],
|
|
1065
|
+
'comma-dangle': 'error',
|
|
1066
|
+
'curly': [ 'error', 'multi' ],
|
|
1067
|
+
'eol-last': [ 'error', 'always' ],
|
|
1068
|
+
'function-paren-newline': [ 'error', 'never' ],
|
|
1069
|
+
'indent': [ 'error', 2, { ArrayExpression: 'first',
|
|
1070
|
+
CallExpression: { arguments: 'first' },
|
|
1071
|
+
//flatTernaryExpressions: true,
|
|
1072
|
+
//offsetTernaryExpressions: true,
|
|
1073
|
+
// ternary, because overhangs strangely (eg multiline in array def)
|
|
1074
|
+
'ignoredNodes': [ 'ConditionalExpression', 'ObjectExpression *' ],
|
|
1075
|
+
FunctionDeclaration: { parameters: 'first', body: 1 },
|
|
1076
|
+
FunctionExpression: { parameters: 'first', body: 1 },
|
|
1077
|
+
ImportDeclaration: 'first',
|
|
1078
|
+
offsetTernaryExpressions: true,
|
|
1079
|
+
VariableDeclarator: 'first' } ],
|
|
1080
|
+
'init-declarations': [ 'error', 'never', { 'ignoreForLoopInit': true } ],
|
|
1081
|
+
'keyword-spacing': [ 'error', { before: true, after: true } ],
|
|
1082
|
+
'linebreak-style': [ 'error', 'unix' ],
|
|
1083
|
+
'padding-line-between-statements': [ 'error',
|
|
1084
|
+
{ blankLine: 'always', prev: 'let', next: '*' },
|
|
1085
|
+
{ blankLine: 'never', prev: 'let', next: 'let' } ],
|
|
1086
|
+
'no-case-declarations': 'error',
|
|
1087
|
+
'no-global-assign': 'error',
|
|
1088
|
+
'cookshack/positive-vibes': 'error',
|
|
1089
|
+
'cookshack/narrowest-scope': 'error',
|
|
1090
|
+
'cookshack/use-risky-equal': 'error',
|
|
1091
|
+
'cookshack/always-let': 'error',
|
|
1092
|
+
// using the implicit inititialization to undefined fits better
|
|
1093
|
+
//'cookshack/init-before-use': 'error',
|
|
1094
|
+
'cookshack/var-decl-block-start': 'error',
|
|
1095
|
+
'cookshack/fn-decl-block-start': 'error',
|
|
1096
|
+
'cookshack/fn-args-nl': 'error',
|
|
1097
|
+
'cookshack/indent-struct': 'error',
|
|
1098
|
+
'no-mixed-operators': 'error',
|
|
1099
|
+
'no-multi-spaces': 'error',
|
|
1100
|
+
'no-multiple-empty-lines': [ 'error', { max: 1, maxEOF: 0 } ],
|
|
1101
|
+
'no-negated-condition': 'error',
|
|
1102
|
+
'no-redeclare': 'error',
|
|
1103
|
+
'no-sequences': 'error',
|
|
1104
|
+
'no-shadow': [ 'error', { builtinGlobals: true } ],
|
|
1105
|
+
'no-sparse-arrays': 'error',
|
|
1106
|
+
'no-tabs': 'error',
|
|
1107
|
+
'no-trailing-spaces': 'error',
|
|
1108
|
+
'no-undef': 'error',
|
|
1109
|
+
'no-unsafe-negation': 'error',
|
|
1110
|
+
'no-unused-vars': 'error',
|
|
1111
|
+
'no-var': 'error',
|
|
1112
|
+
'object-curly-spacing': [ 'error', 'always' ],
|
|
1113
|
+
'object-shorthand': [ 'error', 'always' ],
|
|
1114
|
+
quotes: [ 'error', 'single', { avoidEscape: true } ],
|
|
1115
|
+
semi: [ 'error', 'never' ] };
|
|
1116
|
+
|
|
1117
|
+
exports.languageOptions = { globals: { ...globals.node },
|
|
1118
|
+
parserOptions: { ecmaVersion: 2025,
|
|
1119
|
+
sourceType: 'module' } };
|
|
975
1120
|
|
|
976
1121
|
var index = [ { ignores: [ 'TAGS.mjs' ] },
|
|
977
1122
|
{ languageOptions: exports.languageOptions,
|