rdl: replace class body interface list with colon-list syntax#4006
rdl: replace class body interface list with colon-list syntax#4006
Conversation
Co-authored-by: kennykerr <9845234+kennykerr@users.noreply.github.com>
crates/libs/rdl/tests/class.rdl
Outdated
| class Derived: Base, | ||
| IDerived, | ||
| IDerived2 {} |
There was a problem hiding this comment.
@copilot the line breaks here are weird. I think it should be Base, IDerived, IDerived2 all on one line.
There was a problem hiding this comment.
Fixed in a25cdff. The root cause was the formatter's Token::Comma handler always emitting a newline when outside parentheses/angles. I added an in_colon_list flag to the formatter that gets set when a : is encountered outside parens/angles and cleared on { or ;, so commas in the class header now emit a space instead of a newline. class Derived: Base, IDerived, IDerived2 {} is now all on one line.
Co-authored-by: kennykerr <9845234+kennykerr@users.noreply.github.com>
| base: super::super::Base, | ||
| a: super::AS, | ||
| } | ||
| base: super::super::Base, a: super::AS, } |
There was a problem hiding this comment.
@copilot this looks like a formatting regression.
There was a problem hiding this comment.
Fixed in cbcb3f9. The previous in_colon_list fix was too broad — it also triggered on struct field colons (base: Type), causing fields to be formatted on a single line. I added a body_stack: Vec<bool> to the formatter that records whether each { opens a struct/enum body (true) or a mod/namespace body (false). in_colon_list is now only set when the : is outside parentheses/angles and the current body is not a struct/enum body. Struct fields are back on separate lines while class header inheritance lists remain on one line.
…ggering colon-list mode Co-authored-by: kennykerr <9845234+kennykerr@users.noreply.github.com>
| }, | ||
| a2: u32, | ||
| } | ||
| b1: u16, b2: i32, }, |
There was a problem hiding this comment.
@copilot more formatting regressions - may want to consider simplifying the formatter...
There was a problem hiding this comment.
Fixed in 4ce659e. The root cause was the same as the previous regression but more pervasive: union, attribute, class, and interface are all Identifier tokens in the lexer (not keywords), so any body opened after them was incorrectly classified as a namespace/mod body, causing field colons to trigger in_colon_list.
Simplified the approach: instead of trying to track all "struct-like" keywords, I now only track last_keyword_is_mod. Only mod introduces a namespace body where : is an inheritance separator — all other bodies suppress in_colon_list. The body_stack stores false for mod bodies and true for everything else, and in_colon_list is only set when body_stack.last() == Some(&false).
This is both simpler and correct for all body types including union, attribute, anonymous inline struct/union fields, and nested unions.
…fication Co-authored-by: kennykerr <9845234+kennykerr@users.noreply.github.com>
|
@copilot fix the build |
…yntax Co-authored-by: kennykerr <9845234+kennykerr@users.noreply.github.com>
The windows-rdl class syntax listed implemented interfaces inside the class body with an explicit
#[default]attribute marker. This changes the syntax to a cleaner colon-separated inheritance list where position implies default, freeing the body for future use.Old syntax:
New syntax:
The first interface in the colon list is implicitly the default — no attribute needed. The base class (if any) must appear before interfaces and is distinguished at encode time by checking whether the resolved type is a class or interface.
Reader (
src/reader/class.rs)ClassInterfacestruct;Classnow holdscolon_list: Vec<syn::Path>class Name: Path1, Path2 {}— body is parsed but must be emptyencode_path(), uses newis_class_type()helper (checks localIndexforItem::Class, reference forTypeCategory::Class) to route each entry to eitherextendsorInterfaceImpl; first interface automatically receivesDefaultAttributeWriter (
src/writer/class.rs)interface_impls()so the default interface leads, then emits a single colon list with an empty{}bodyFormatter (
src/formatter/mod.rs)in_colon_listflag that is set when a:token is encountered inside a mod/namespace body and outside parentheses/angle-brackets, cleared on{or;in_colon_listis active, commas emit a space instead of a newline, keeping the entire inheritance list on one line (e.g.class Derived: Base, IDerived, IDerived2 {})body_stack: Vec<bool>andlast_keyword_is_modflag to correctly classify open braces: onlymodintroduces a namespace body (false) where:is an inheritance separator; all other bodies —struct,union,attribute,fn,class,interface, and anonymous inline types — are classified as field bodies (true) where:is a field-name-to-type separator and must not triggerin_colon_listSamples (
crates/samples/components/json_validator_winrt/src/sample.rdl)sample.rdlto use the new colon-list class syntax (class JsonValidator: IJsonValidator {})Tests & docs
tests/class.rdlupdated to new syntaxrdl.mdupdated with new grammar description and example🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.