Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support bitflag enums (closes #158) #163

Merged
merged 12 commits into from
Dec 9, 2021
Merged

Support bitflag enums (closes #158) #163

merged 12 commits into from
Dec 9, 2021

Conversation

lynn
Copy link
Contributor

@lynn lynn commented Dec 8, 2021

Now you can write

[flags]
enum MyFlags {
    Red = 1 << 0;
    Green = 1 << 1;
    Blue = 1 << 2;
    Yellow = Red | Green;
}

and this yields special codegen in Rust, specifically, where ordinary enums do not already allow bitflag-like behavior:

::bitflags::bitflags! {
    pub struct MyFlags: u32 {
        const RED = 1;
        const GREEN = 2;
        const BLUE = 4;
        const YELLOW = 3;
    }
}

At last, you can write let magenta = MyFlags::RED | MyFlags::BLUE and decode/encode values like that.

For now, I won't preserve the arithmetic expressions in codegen (sorry Andrew) and I won't hide the bitflags dependency behind a feature flag (sorry Matthew). Neither of those things seem worth the added complexity for right now.

Note to self: after this is merged, I need to go doc it on the wiki.

Core/Generators/Rust/RustGenerator.cs Outdated Show resolved Hide resolved
Core/Generators/Rust/RustGenerator.cs Outdated Show resolved Hide resolved
/// The 'deprecated' keyword which is reserved by the compiler
/// </summary>
[Keyword("deprecated")]
Deprecated,
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are these tokens being removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I changed the way attributes are parsed so that the "attribute name" after the opening [ is simply parsed as an identifier. This way we don't have to introduce a new keyword TokenKind for each new attribute that we want to introduce.

Laboratory/Rust/auto-testing/Cargo.toml Outdated Show resolved Hide resolved
Laboratory/Rust/benchmarking/Cargo.toml Outdated Show resolved Hide resolved
Laboratory/Rust/functionality-testing/Cargo.toml Outdated Show resolved Hide resolved
Laboratory/Rust/manual-testing/Cargo.toml Outdated Show resolved Hide resolved
@@ -0,0 +1,7 @@
import * as G from './generated/gen';

it("Supports flag enums", () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe it would be good to add a const "isFlagsEnum: bool" to the enum definitions

Something like

export enum MyEnum {
 // ...
}

export const $MyEnumIsFlags = true;

Or maybe injecting it into the enum object and updating the typing to reflect? This seems a little harder though.

enum _MyEnum {...}
(_MyEnum as any).isFlags = true;
type MyEnumType = typeof _MyEnum & { isFlags: true }
export const MyEnum = _MyEnum as unknown as MyEnumType

I think that would work?

@lynn lynn merged commit 6833543 into master Dec 9, 2021
@andrewmd5 andrewmd5 deleted the bitmask branch July 18, 2022 15:38
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.

None yet

2 participants