flatlint 1.12.0 β†’ 1.13.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/ChangeLog CHANGED
@@ -1,3 +1,9 @@
1
+ 2025.01.01, v1.13.0
2
+
3
+ feature:
4
+ - f24e4d3 flatlint: add support of __array
5
+ - 0b2d275 flatlint: compare: __array: add support
6
+
1
7
  2024.12.31, v1.12.0
2
8
 
3
9
  feature:
package/README.md CHANGED
@@ -90,6 +90,24 @@ npm i flatlint
90
90
 
91
91
  </details>
92
92
 
93
+ ## Template literals
94
+
95
+ **FlatLint** uses language similar to 🐊[**PutoutScript**](https://github.com/coderaiser/putout/blob/master/docs/putout-script.md#-putoutscript).
96
+
97
+ It can look similar, but has a couple differences:
98
+ - βœ…it may not be valid **JavaScript**, it can be couple tokens that can be fixed;
99
+ - βœ…it counts each symbol as a token;
100
+
101
+ ### `__a`
102
+
103
+ From `__a` to `__z` is usually identifiers, but can also be strings if used with quotes `'__a'` they can be single or double,
104
+ it can be only one quote `'__a` - this is valid, since **FlatLint** is tokens based.
105
+
106
+ ### `__array`
107
+
108
+ Collects everything that looks like array elements, it can start from squire brace `[__array;`, but that's not important
109
+ to end with it, since it used to fix error patterns.
110
+
93
111
  ## API
94
112
 
95
113
  ```js
@@ -0,0 +1,21 @@
1
+ import {Punctuator} from '#types';
2
+ import {equal} from './equal.js';
3
+
4
+ export const collectArray = ({currentTokenIndex, tokens, nextTemplateToken}) => {
5
+ const n = tokens.length;
6
+ const brace = Punctuator(']');
7
+ let index = currentTokenIndex;
8
+
9
+ for (; index < n; index++) {
10
+ const token = tokens[index];
11
+
12
+ if (equal(token, nextTemplateToken))
13
+ break;
14
+
15
+ if (equal(token, brace))
16
+ break;
17
+ }
18
+
19
+ return --index;
20
+ };
21
+
@@ -1,11 +1,13 @@
1
1
  import {prepare} from '#parser';
2
+ import {isTemplateArrayToken} from '#types';
3
+ import {collectArray} from './collect-array.js';
2
4
  import {
3
- isId,
4
- isIdentifier,
5
- isPunctuator,
6
- isQuote,
7
- isStringLiteral,
8
- } from '#types';
5
+ equal,
6
+ equalAny,
7
+ equalId,
8
+ equalQuote,
9
+ equalStr,
10
+ } from './equal.js';
9
11
 
10
12
  export const compare = (source, template) => {
11
13
  const templateTokens = prepare(template);
@@ -16,26 +18,31 @@ export const compare = (source, template) => {
16
18
  let isEqual = false;
17
19
  let start = 0;
18
20
  let end = 0;
21
+ let delta = 0;
19
22
 
20
23
  for (let index = 0; index < n; index++) {
21
24
  for (let templateIndex = 0; templateIndex < templateTokensLength; templateIndex++) {
22
25
  const currentTokenIndex = index + templateIndex;
23
-
24
- if (currentTokenIndex > n) {
25
- isEqual = false;
26
- break;
27
- }
28
-
29
26
  const templateToken = templateTokens[templateIndex];
30
27
  const currentToken = tokens[currentTokenIndex];
31
28
 
32
- if (!compareAll(currentToken, templateToken)) {
29
+ if (isTemplateArrayToken(templateToken)) {
30
+ const indexOfArrayEnd = collectArray({
31
+ currentTokenIndex,
32
+ tokens,
33
+ templateToken,
34
+ nextTemplateToken: templateTokens[templateIndex + 1],
35
+ });
36
+
37
+ delta = indexOfArrayEnd - currentTokenIndex;
38
+ index = indexOfArrayEnd - templateIndex;
39
+ } else if (!compareAll(currentToken, templateToken)) {
33
40
  isEqual = false;
34
41
  break;
35
42
  }
36
43
 
37
44
  isEqual = true;
38
- start = index;
45
+ start = index - delta;
39
46
  end = currentTokenIndex;
40
47
  }
41
48
 
@@ -62,41 +69,3 @@ function compareAll(a, b) {
62
69
 
63
70
  return false;
64
71
  }
65
-
66
- function equal(a, b) {
67
- return a.type === b.type && a.value === b.value;
68
- }
69
-
70
- function equalAny(a, b) {
71
- if (!isIdentifier(b))
72
- return false;
73
-
74
- if (isPunctuator(a))
75
- return false;
76
-
77
- return b.value === '__';
78
- }
79
-
80
- function equalQuote(a, b) {
81
- if (!isPunctuator(a))
82
- return false;
83
-
84
- return isQuote(b.value);
85
- }
86
-
87
- function equalStr(a, b) {
88
- if (!isStringLiteral(a))
89
- return false;
90
-
91
- return isId(b.value);
92
- }
93
-
94
- function equalId(a, b) {
95
- if (!isIdentifier(b))
96
- return false;
97
-
98
- if (isPunctuator(a))
99
- return false;
100
-
101
- return isId(b.value);
102
- }
@@ -0,0 +1,45 @@
1
+ import {
2
+ isId,
3
+ isIdentifier,
4
+ isPunctuator,
5
+ isQuote,
6
+ isStringLiteral,
7
+ } from '#types';
8
+
9
+ export function equal(a, b) {
10
+ return a.type === b.type && a.value === b.value;
11
+ }
12
+
13
+ export function equalAny(a, b) {
14
+ if (!isIdentifier(b))
15
+ return false;
16
+
17
+ if (isPunctuator(a))
18
+ return false;
19
+
20
+ return b.value === '__';
21
+ }
22
+
23
+ export function equalQuote(a, b) {
24
+ if (!isPunctuator(a))
25
+ return false;
26
+
27
+ return isQuote(b.value);
28
+ }
29
+
30
+ export function equalStr(a, b) {
31
+ if (!isStringLiteral(a))
32
+ return false;
33
+
34
+ return isId(b.value);
35
+ }
36
+
37
+ export function equalId(a, b) {
38
+ if (!isIdentifier(b))
39
+ return false;
40
+
41
+ if (isPunctuator(a))
42
+ return false;
43
+
44
+ return isId(b.value);
45
+ }
@@ -4,9 +4,6 @@ export function report() {
4
4
 
5
5
  export function replace() {
6
6
  return {
7
- '["__a";': '["__a"];',
8
- '[__a;': '[__a];',
9
- '["__a", "__b";': '["__a", "__b"];',
10
- '[__a, __b;': '[__a, __b];',
7
+ '[__array;': '[__array];',
11
8
  };
12
9
  }
@@ -1,8 +1,14 @@
1
- import {is} from '#types';
1
+ import {
2
+ is,
3
+ isTemplateArray,
4
+ Punctuator,
5
+ } from '#types';
2
6
  import {prepare} from '#parser';
3
7
  import {compare} from '#compare';
4
8
  import {traverse} from '#traverser';
9
+ import {collectArray} from '../compare/collect-array.js';
5
10
 
11
+ const {isArray} = Array;
6
12
  const {entries} = Object;
7
13
 
8
14
  export const replace = (tokens, {fix, rule, plugin}) => {
@@ -79,6 +85,23 @@ function getValues(tokens, waysFrom) {
79
85
  const values = {};
80
86
 
81
87
  for (const [name, index] of entries(waysFrom)) {
88
+ if (isTemplateArray(name)) {
89
+ debugger;
90
+ const endOfArray = collectArray({
91
+ currentTokenIndex: index,
92
+ tokens,
93
+ nextTemplateToken: Punctuator(';'),
94
+ });
95
+
96
+ if (index === endOfArray) {
97
+ values[name] = tokens[index];
98
+ continue;
99
+ }
100
+
101
+ values[name] = tokens.slice(index, endOfArray + 1);
102
+ continue;
103
+ }
104
+
82
105
  values[name] = tokens[index];
83
106
  }
84
107
 
@@ -87,6 +110,14 @@ function getValues(tokens, waysFrom) {
87
110
 
88
111
  function setValues({to, waysTo, values}) {
89
112
  for (const [name, index] of entries(waysTo)) {
90
- to[index] = values[name];
113
+ const current = values[name];
114
+
115
+ if (!isArray(current)) {
116
+ to[index] = values[name];
117
+ continue;
118
+ }
119
+
120
+ to.splice(index, 1, ...values[name]);
91
121
  }
92
122
  }
123
+
@@ -1,9 +1,10 @@
1
1
  import {replace} from './replacer.js';
2
2
 
3
3
  export const run = (tokens, {fix, fixCount = 10, plugins}) => {
4
+ debugger;
4
5
  const places = [];
5
6
 
6
- while (--fixCount) {
7
+ while (--fixCount >= 0) {
7
8
  for (const {rule, plugin} of plugins) {
8
9
  places.push(...replace(tokens, {
9
10
  fix,
@@ -11,8 +12,10 @@ export const run = (tokens, {fix, fixCount = 10, plugins}) => {
11
12
  plugin,
12
13
  }));
13
14
 
14
- if (places.length)
15
- return [places];
15
+ if (!fix || places.length) {
16
+ fixCount = 0;
17
+ break;
18
+ }
16
19
  }
17
20
  }
18
21
 
@@ -30,8 +30,13 @@ export const is = (str, array = ALL) => {
30
30
  const LINKED_NODE = /^__[a-z]$/;
31
31
  const ANY = '__';
32
32
  const QUOTE = /^['"]$/;
33
+ const ARRAY = '__array';
33
34
 
34
- const ALL = [ANY, LINKED_NODE];
35
+ const ALL = [
36
+ ANY,
37
+ LINKED_NODE,
38
+ ARRAY,
39
+ ];
35
40
 
36
41
  function check(str, item) {
37
42
  if (isString(item))
@@ -42,3 +47,5 @@ function check(str, item) {
42
47
 
43
48
  export const isId = (a) => LINKED_NODE.test(a);
44
49
  export const isQuote = (a) => QUOTE.test(a);
50
+ export const isTemplateArray = (a) => a === ARRAY;
51
+ export const isTemplateArrayToken = (a) => isIdentifier(a) && isTemplateArray(a.value);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flatlint",
3
- "version": "1.12.0",
3
+ "version": "1.13.0",
4
4
  "description": "JavaScript tokens-based linter",
5
5
  "main": "lib/flatlint.js",
6
6
  "type": "module",