rbi icon indicating copy to clipboard operation
rbi copied to clipboard

Make TEnumBlock behave as a scope

Open Morriar opened this issue 1 year ago • 1 comments

To represent T::Enum subclasses like this one:

class MyEnum < T::Enum
  enums do
    # Some comments
    A = new
    B = new
  end
end

We currently use a special node called TEnumBlock that only accepts an array of names representing the constants like A, B. On top of being unnecessarily restrictive and complex, it doesn't allow storing the comments attached to each enum constant.

In reality, enums do .. end is nothing more than a block that can accept constants but also other types of nodes. This PR changes the superclass of TEnumBlock to be a Tree that can contain any kind of nodes including Const to represent the A, B etc. This means we can now attach comments to the constants and parse the TEnum properly.

This is a breaking change as we change the API to build TEnum which may break some clients.

Morriar avatar Aug 06 '24 20:08 Morriar

The changes look fine to me, but I can't understand how one is supposed to extract all enum members from the resulting TEnumBlock object? Do you need to find all the constants defined in that scope with the value new?

Good point, I added a TEnum#members method to make gathering the enum constants super easily:

enum = TEnum.new("Enum") do |enum|
  enum << TEnumBlock.new do |block|
    block << Const.new("A", "new")
    block << Const.new("B", "new")
  end
end

assert_equal(["A", "B"], enum.members)

Morriar avatar Aug 07 '24 16:08 Morriar

Following our conversation earlier I removed the members helper as we don't have a clean way to ensure the RBI::Const is actually a valid T::Enum member.

Let's revisit this once we need it 👍

Morriar avatar Aug 21 '24 19:08 Morriar