Skip to content

Commit 57a0afb

Browse files
committed
feat: experimental new stuff
1 parent 111a31f commit 57a0afb

24 files changed

Lines changed: 5497 additions & 9668 deletions

.cursor/rules/display-contexts.mdc

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
description: Details and examples about how properties that affect different display contexts (such as grid, flex, and block contexts) should be handled.
3+
globs:
4+
alwaysApply: false
5+
---
6+
7+
### **CSS Context and Feature Detection**
8+
9+
#### **Primary Rule: The "Conservative (Same-Rule Only)" Approach**
10+
11+
When analyzing CSS, a property's behavior is considered within a specific layout context (like `flex`, `grid`, or `block`) **ONLY IF** the `display` property establishing that context is explicitly declared within the **SAME CSS RULE**. Implicit contexts (e.g., `div` being block by default) or contexts set on parent rules are **NOT** considered.
12+
13+
#### **Exception: Handling Item-Specific Properties (e.g., `place-self`)**
14+
15+
This "same-rule" model makes it impossible to determine a context for properties that apply to flex/grid *items* rather than the container. The `display` property is on the parent, but the item-specific property is on the child.
16+
17+
Therefore, for these specific properties, **we abandon context detection entirely**. You should generate tests that report the usage of these properties whenever they appear, regardless of context.
18+
19+
**Example for the Exception:**
20+
21+
* **`place-self` (Item Property):** This property affects a grid or flex item. We can never know its context. Therefore, it should be reported whenever it is used.
22+
23+
```css
24+
.grid-container {
25+
display: grid;
26+
}
27+
.grid-item {
28+
place-self: center start; /* <<< DETECTED (Reported without context check) */
29+
}
30+
31+
.some-other-element {
32+
place-self: end; /* <<< ALSO DETECTED (Reported without context check) */
33+
}
34+
```
35+
36+
---
37+
38+
### **Examples Illustrating the Primary Rule**
39+
40+
**1. Flex Context Detection:**
41+
42+
* **Detected:** `align-content` is detected as a flex property because `display: flex` is in the same rule.
43+
44+
```css
45+
.flex-container {
46+
display: flex;
47+
align-content: center; /* <<< DETECTED */
48+
}
49+
```
50+
51+
* **NOT Detected:** `align-content` is *NOT* detected as a flex property because `display: flex` is in a different rule.
52+
53+
```css
54+
.parent { display: flex; }
55+
.child {
56+
align-content: center; /* <<< NOT DETECTED */
57+
}
58+
```
59+
60+
**2. Block Context Detection:**
61+
62+
* **Detected:** `align-content` is detected as a block property because `display: block` is in the same rule.
63+
64+
```css
65+
.block-element {
66+
display: block;
67+
align-content: start; /* <<< DETECTED */
68+
}
69+
```
70+
71+
* **NOT Detected:** `align-content` is *NOT* detected, even on a `div`, because `display: block` is not explicitly written in the rule.
72+
73+
```css
74+
div {
75+
align-content: start; /* <<< NOT DETECTED */
76+
}
77+
```
78+
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
---
2+
description:
3+
globs:
4+
alwaysApply: true
5+
---
6+
Excellent question. As we worked through the test failures, we established several key rules and heuristics beyond just the display context. These are crucial for building a robust and predictable checker.
7+
8+
Here is a comprehensive summary of all the rules we've developed:
9+
10+
1. The Display Context Rule: "Conservative, Same-Rule Only"
11+
12+
This is the most important rule we established for container properties.
13+
14+
Primary Rule: A property is only considered to be in a flex, grid, or block context if the corresponding display property (display: flex, display: block, etc.) is explicitly declared in the exact same CSS rule.
15+
16+
Exception for Item-Specific Properties: For properties that apply to flex/grid items (like place-self or align-self), we abandon context detection entirely. We report them whenever they are used, as their context is set on a parent rule which we cannot reliably determine.
17+
18+
2. The @supports Heuristic: "Exact Match Only"
19+
20+
Because we can't build a full browser engine to evaluate complex @supports queries, we settled on a simple, predictable heuristic.
21+
22+
Rule: We only consider a feature to be "guarded" (and thus suppress a warning) if the @supports query checks for the exact property and value being used.
23+
24+
Example: align-content: stretch is only considered guarded by @supports (align-content: stretch). We would ignore a more general query like @supports (display: flex). This avoids the complexity of parsing logical operators (and, or, not) and trying to infer contextual relationships.
25+
26+
3. The Value Normalization Rule: "Always Clean the Input"
27+
28+
To handle variations in developer formatting, we apply two key normalization steps.
29+
30+
Handle Comments with .trim(): PostCSS often includes trailing whitespace in a decl.value if a comment follows it (e.g., value: 'start /* comment */'). We must always call .trim() on the value before checking it.
31+
Handle Whitespace with .replace(/\s+/g, ' '): For multi-word values (like first baseline), we first normalize all internal whitespace to a single space. This makes checks like value.includes('first baseline') reliable, regardless of whether the developer wrote one space or several.
32+
33+
4. The Special Values Rule: "Handle Keywords and Variables Conservatively"
34+
35+
CSS has special values that require specific handling because we can't know their resolved value during static analysis.
36+
37+
CSS-Wide Keywords (initial, unset, revert): We handle these on a per-property basis. For some properties (anchor-scope), these keywords effectively mean none. For others, we may need to check if they should trigger a general feature detection.
38+
39+
CSS Variables (var(...)): This is the hardest case. Our current stance is that it's impossible to know what a variable resolves to. The most conservative approach is to assume it could be an unsupported value and trigger the general feature detection for that property (e.g., if we see align-content: var(--my-align), we would report a usage of align-content).
40+
41+
5. The Architectural Rule: "Centralize Logic in approve()"
42+
43+
To keep the checker maintainable and make adding new features easy, all feature detections are funneled through a single approve(decl, featureId) function.
44+
45+
Purpose: This central function is responsible for handling all the common, repetitive logic:
46+
47+
Determining the vendor prefix.
48+
49+
Checking for @supports guards.
50+
51+
Checking for the presence of fallback properties.
52+
53+
Benefit: This keeps the main checking logic clean and focused only on identifying property: value pairs, without cluttering it with repeated checks for prefixes or @supports conditions.
54+
55+
These five rules form the complete logical foundation of our checker. They provide a clear and consistent framework for how we handle the ambiguities and complexities of static CSS analysis.

.cursor/rules/run-tests.mdc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
description:
3+
globs:
4+
alwaysApply: true
5+
---
6+
Tests can be run with `bun run test`, which will use vitest's test runner. You can also run vitest directly using `bunx vitest run`.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
description:
3+
globs:
4+
alwaysApply: true
5+
---
6+
When working with the AST, always add comments to verify your assumptions before making changes. Even though I'm very familiar with the AST, I am sometimes surprised by the structure.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,6 @@ package-lock.json
99

1010
# System files
1111
.DS_Store
12+
13+
# Secrets
14+
.env

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"editor.defaultFormatter": "esbenp.prettier-vscode"
3+
}

0 commit comments

Comments
 (0)