Skip to content

Implement initial transform#6

Merged
skovhus merged 36 commits intomainfrom
implement-gpt5.2
Jan 5, 2026
Merged

Implement initial transform#6
skovhus merged 36 commits intomainfrom
implement-gpt5.2

Conversation

@skovhus
Copy link
Copy Markdown
Owner

@skovhus skovhus commented Jan 1, 2026

GPT5.2 version


Note

Implements a production-ready transform from styled-components to StyleX with a minimal public API.

  • Core: New transformation pipeline (internal/*) with rule lowering, JSX rewrites, wrappers, keyframes parsing, CSS var rewriting, and output formatting/safety
  • Adapter API: Replaces legacy adapter with defineAdapter + unified resolveValue and optional custom handlers; adds built-in dynamic handlers
  • Public API: Narrows to defineAdapter and runTransform; updates exports and README with usage, options, and advanced customization
  • Tests: Moves tests to src/__tests__, adds e2e (run.e2e.test.ts) and fixture adapters; normalizes comparisons via oxfmt
  • Tooling: Stricter linting (oxlint errors, type-aware), VSCode formatter settings, added deps (stylis, coverage plugin) and lockfile updates

Written by Cursor Bugbot for commit d3d4edd. This will update automatically on new commits. Configure here.

@skovhus skovhus marked this pull request as ready for review January 5, 2026 09:39
@skovhus skovhus changed the title Transform GPT5.2 version Implement initial transform Jan 5, 2026
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is being reviewed by Cursor Bugbot

Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

Comment thread src/__tests__/fixture-adapters.ts Outdated
@skovhus skovhus merged commit e8e7864 into main Jan 5, 2026
2 checks passed
@skovhus skovhus deleted the implement-gpt5.2 branch January 5, 2026 09:51
style: styleFromSingleDeclaration(node.css.property, alt),
},
],
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handler returns malformed variant data instead of null

The conditionalValueHandler has a fallback return at lines 100-114 that produces malformed splitVariants results instead of returning null. When testPath is null (test expression isn't a MemberExpression), both variants get when: "" (empty string). When testPath has length > 1 (nested access like props.foo.bar), only the first segment is used, producing semantically incorrect conditions. Downstream in emit-wrappers.ts, this causes j.identifier("") to be called with an empty string, producing invalid JavaScript AST. The fallback block should return null to indicate the handler cannot process this pattern.

Fix in Cursor Fix in Web

const defaultMarkerCall = j.callExpression(
j.memberExpression(j.identifier("stylex"), j.identifier("defaultMarker")),
[],
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same AST node reused across multiple locations in tree

The defaultMarkerCall AST node is created once at line 25-28, then the same node instance is pushed into call.arguments for every matching JSX element at line 83. Sharing AST node references across multiple locations in the tree violates AST invariants and can cause recast/jscodeshift to produce corrupted output or throw errors during printing. Each insertion point needs a fresh AST node, which can be created by calling j.callExpression(...) inside the loop or by cloning the node.

Additional Locations (1)

Fix in Cursor Fix in Web

cursor Bot pushed a commit that referenced this pull request Feb 27, 2026
Finding #1 (MODERATE): canSafelyInline and resolvePerSiteProps missed
JSXSelfClosingElement nodes (<Foo />) — consumed props on self-closing
elements were not checked for safety or variant creation. Fixed by
extracting findAllJsxSites() helper that searches both JSXElement and
JSXSelfClosingElement, used by all JSX scanning functions.

Finding #2 (MODERATE): attrsAsTag (.attrs({ as: SomeComponent })) was
not checked — component-ref overrides were silently ignored. Fixed by
bailing extractStaticPropsFromAttrs when attrsAsTag is set.

Finding #3 (MODERATE): $-prefixed non-consumed transient props would
leak to the DOM in the wrapper path for inlined intrinsic elements.
Fixed by setting shouldForwardProp.dropPrefix to "$" in applyResolution.

Finding #4 (LOW): findVaryingProps had an always-true condition
(!allSame || hasAnyValue where hasAnyValue was guaranteed true).
Simplified: track all consumed props present at any JSX site.

Finding #5 (LOW): Covered by Finding #3's dropPrefix fix.

Finding #6 (LOW): Inaccurate comment in applyResolution. Updated.

Finding #7 (LOW): Static property inheritance lost for resolved
components. Fixed by saving originalBaseIdent before overwriting base.

Added 3 regression tests:
- attrsAsTag component ref bail
- self-closing element with dynamic consumed prop (canSafelyInline)
- self-closing element with static consumed prop (variant creation)

Co-authored-by: Kenneth Skovhus <skovhus@users.noreply.github.com>
@skovhus skovhus mentioned this pull request Feb 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant