Philipp Spiess db405304f4
Don't swallow @utility declarations when @apply is used in nested rules (#16940)
Fixes #16935

This PR fixes an issue where the order of how `@apply` was resolved was
incorrect for nested rules. Consider this example:

```css
.rule {
  @apply underline;
  .nested-rule {
    @apply custom-utility;
  }
}

@utility custom-utility {
  @apply flex;
}
```

The way we topologically sort these, we end up with a list that looks
roughly like this:

```css
.rule {
  @apply underline;
  .nested-rule {
    @apply custom-utility;
  }
}

@utility custom-utility {
  @apply flex;
}

.nested-rule {
  @apply custom-utility;
}
```

As you can see here the nested rule is now part of the top-level list.
This is correct because we first have to substitute the `@apply` inside
the `@utility custom-utility` before we can apply the `custom-utility`
inside `.nested-rule`. However, because we were using a regular AST walk
and because the initial `.rule` also contains the `.nested-rule` as
child, we would first substitute the `@apply` inside the `.nested-rule`,
causing the design-system to force resolve (and cache) the wrong value
for `custom-utility`.

Because the list is already flattened, we do not need to recursively
look into child declarations when we traverse the sorted list. This PR
changes it to use a regular `for` loop instead of the `walk`.

## Test plan

- Added a regression test
- Rest of tests still green
2025-03-04 16:54:05 +01:00
..
2024-12-11 15:27:20 +01:00