Skip to content

RDL property syntax issues #4163

@kennykerr

Description

@kennykerr

thoughts?

That looked good until it was brought to my attention that I had overlooked the opportunity for a collision with the RDL event keyword. The prospect of two competing syntaxes for describing properties in WinRT and COM isn't quite enticing. Going forward, either of these options is probably better:

  • Find a way to support the property shorthand syntax for COM interfaces, or
  • roll back to the more verbose, keyword-prefixed syntax.

Regardless of the approach taken, there are a few rough edges that should be addressed:

Canonical representation (QoL)

Enforcing canonical representations is a good thing, and I was delighted to see the RDL parser rejecting #[get] #[set] foo: u32; as a needlessly verbose version of foo: u32;. The following RDL is equally redundant, yet accepted:

#[winrt]
mod Test {
    interface ITest {
        #[get]
        foo: u32;
        #[set]
        foo: u32;
    }
}

This should be rejected for the same reason that #[get] #[set] ... is. This is purely a QoL improvement; the RDL round-trips with full semantic fidelity, just not lexically. Here's the relevant portion of what the Reader/Writer makes of it:

    interface ITest {
        foo: u32;
    }

Type loss (bug)

A similarly structured RDL surfaces a genuine bug:

#[winrt]
mod Test {
    interface ITest {
        #[get]
        foo: u32;
        #[set]
        foo: String; // <-- foo is of type String, not u32
    }
}

Running this RDL through the same Reader/Writer-cycle produces the same RDL output as the previous test (foo: u32;), dropping the type information for the #[set]-attributed property of the same symbol foo. This needs to be addressed.

V-table ordering (bug)

Toying about with this, I discovered another, more realistic bug: Interleaving disparate #[get] and #[set] property descriptions with unrelated entities coerces the getter/setter into consecutive v-table slots. As an example:

#[winrt]
mod Test {
    interface ITest {
        #[get]
        foo: u32;
        bar: u32;
        #[set]
        foo: u32;
    }
}

gets round-tripped into:

#[winrt]
mod Test {
    interface ITest {
        foo: u32;
        bar: u32;
    }
}

This effectively moves put_foo() in v-table-order ahead of get_bar(), breaking the ABI contract. The v-table entries should instead be: get_foo(), get_bar(), put_bar(), put_foo().

Symbol duplication (QoL/bug?)

There's another unrelated yet prevalent issue that's probably not exclusive to properties: Symbols can be repeated within the same scope. Consider the following RDL

#[winrt]
mod Test {
    interface ITest {
        foo: u32;
        foo: u32;
    }
}

This round-trips perfectly and makes for a valid interface description in terms of the ABI. This interface description, however, cannot be directly/easily projected into any programming language I'm familiar with. This is an issue that needs to be addressed.

Originally posted by @tim-weis in #4143 (comment)

Metadata

Metadata

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions