fix(hir): error on widget method-chain modifier syntax (closes #195)#201
Merged
Merged
Conversation
Method-chain modifier calls like `Text("hi").font("title")` previously
compiled fine but silently dropped every modifier. Option B: reject them
at HIR lowering time with a clear diagnostic so users discover the
supported options-object form.
Adds `is_widget_modifier_name` helper and a detection block in
`lower_expr` (inside the `ast::Expr::Member` handler). When a call's
receiver is a direct `perry/ui` widget constructor call AND the method
name is a known modifier, `Err` is returned:
modifier 'font' must be passed as an option-object on the widget
constructor; use: Text("...", { font: ... })
Chained chains (`.font().color()`) fail on the first modifier via
natural recursion — the outer `.color()` processing tries to lower the
inner `Text(...).font(...)`, which fails, and the error propagates.
Modifiers recognised: font, fontWeight, weight, foregroundColor, color,
foreground, padding, cornerRadius, background, backgroundColor, opacity,
lineLimit, frame, minimumScaleFactor, containerBackground, maxWidth, url,
bold, italic, underline, fontSize, strikethrough, multilineTextAlignment,
lineSpacing.
Note: method-chain modifiers inside `Widget({...})` render bodies
(perry/widget, not perry/ui) travel a separate AST-only path
(parse_widget_node) that never calls lower_expr, so they still silently
drop rather than error. Fixing that path would require changing
parse_render_body_stmts to return Result — deferred as a follow-up.
Option A (fold chain into constructor options-object) was deliberately
deferred per the issue guidance.
https://claude.ai/code/session_01Q6AhxeUKokdecgMWrqyzkB
9625268 to
2a6411b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
is_widget_modifier_namehelper + a ~28-line detection block insidelower_expr'sast::Expr::Memberhandler.crates/perry-hir/tests/widget_modifier_diagnostic.rs.docs/src/widgets/components.mdto use the options-object form and adds a one-line note. The larger "Modifiers" section (lines 116–175) examples still show the chained form; updating all of them would exceed ~30 lines — left for a follow-up.Modifiers recognised
font,fontWeight,weight,foregroundColor,color,foreground,padding,cornerRadius,background,backgroundColor,opacity,lineLimit,frame,minimumScaleFactor,containerBackground,maxWidth,url,bold,italic,underline,fontSize,strikethrough,multilineTextAlignment,lineSpacingExample error output
Chained calls fail on the first modifier via natural recursion — processing
.color(...)tries to lower the innerText(...).font(...), which fails, and the error propagates.Scope / known limitation
The check lives in
lower_expr, which is the path for standaloneperry/uicode. Method-chain modifiers insideWidget({...})render bodies (fromperry/widget) travel a separate AST-only path (parse_widget_node) that never callslower_expr, so they still silently drop rather than error there. Fixing that path requires changingparse_render_body_stmtsto returnResult— deferred as a follow-up.Test plan
cargo test -p perry-hir --test widget_modifier_diagnostic— 6 new tests passcargo build --release -p perry-runtime -p perry-stdlib -p perry— clean buildhttps://claude.ai/code/session_01Q6AhxeUKokdecgMWrqyzkB
Generated by Claude Code