Robin Malfait 527031d5f6
Improve data type analyses for arbitrary values (#9320)
* improve split logic by delimiter

The original RegEx did mostly what we want, the idea is that we wanted
to split by a `,` but one that was not within `()`. This is useful when
you define multiple background colors for example:
```html
<div class="bg-[rgb(0,0,0),rgb(255,255,255)]"></div>
```

In this case splitting by the regex would result in the proper result:
```js
let result = [
  'rgb(0,0,0)',
  'rgb(255,255,255)'
]
```

Visually, you can think of it like:
```
    ┌─[./example.html]
    │
∙ 1 │   <div class="bg-[rgb(0,0,0),rgb(255,255,255)]"></div>
    ·                       ──┬── ┬    ─────┬─────
    ·                         │   │         ╰─────── Guarded by parens
    ·                         │   ╰───────────────── We will split here
    ·                         ╰───────────────────── Guarded by parens
    │
    └─
```

We properly split by `,` not inside a `()`. However, this RegEx fails
the moment you have deeply nested RegEx values.

Visually, this is what's happening:
```
    ┌─[./example.html]
    │
∙ 1 │   <div class="bg-[rgba(0,0,0,var(--alpha))]"></div>
    ·                         ┬ ┬ ┬
    ·                         ╰─┴─┴── We accidentally split here
    │
    └─
```
This is because on the right of the `,`, the first paren is an opening
paren `(` instead of a closing one `)`.

I'm not 100% sure how we can improve the RegEx to handle that case as
well, instead I wrote a small `splitBy` function that allows you to
split the string by a character (just like you could do before) but
ignores the ones inside the given exceptions. This keeps track of a
stack to know whether we are within parens or not.

Visually, the fix looks like this:
```
    ┌─[./example.html]
    │
∙ 1 │   <div class="bg-[rgba(0,0,0,var(--alpha)),rgb(255,255,255,var(--alpha))]"></div>
    ·                         ┬ ┬ ┬             ┬       ┬   ┬   ┬
    ·                         │ │ │             │       ╰───┴───┴── Guarded by parens
    ·                         │ │ │             ╰────────────────── We will split here
    ·                         ╰─┴─┴──────────────────────────────── Guarded by parens
    │
    └─
```

* use already existing `splitAtTopLevelOnly` function

* add faster implemetation for `splitAtTopLevelOnly`

However, the faster version can't handle separators with multiple
characters right now. So instead of using buggy code or only using the
"slower" code, we've added a fast path where we use the faster code
wherever we can.

* use `splitAtTopLevelOnly` directly

* make split go brrrrrrr

* update changelog

* remove unncessary array.from call

Co-authored-by: Jordan Pittman <jordan@cryptica.me>
2022-09-14 14:08:56 +02:00
..
2021-12-15 18:13:09 +01:00
2022-07-18 09:31:45 -04:00
2022-04-12 14:13:04 -04:00
2021-09-21 12:43:44 -04:00
2021-09-21 12:37:49 -04:00