Skip to content

[Bug]: Mutators are hard to use to mutate nested types in the subgraph #7003

@bterlson

Description

@bterlson

Describe the bug

In my scenario, I want to replace all enums with the equivalent union. So I implemented a mutator as follows:

export const EnumToUnion: unsafe_Mutator = {
  name: "removeEnum",
  Enum: {
    filter: (type) => {
      return unsafe_MutatorFlow.MutateAndRecur;
    },
    replace(en) {
      return $.union.create({
        variants: [...en.members.values()].map((enumMember) => {
          return $.unionVariant.create({
            type: $.literal.create(enumMember.value ?? enumMember.name),
          });
        }),
      });
    },
  },
};

It finds enums and replaces them, but this replacement is somewhat pointless because the path to the enums are not cloned with the appropriate references updated. I have to add mutators for every type for this to work.

I would have expected the original mutator to work given that the documentation says the default MutatorFlow is MutateAndRecur. If the current behavior is what we want (which is nice in that it doesn't clone a TON of stuff if a leaf type is mutated), we need some way to traverse this subgraph, and ideally it works with the current pattern used all over emitter-framework (which just uses properties to unpack the types). Perhaps a realm-aware proxy is in order.

Reproduction

.

Checklist

Metadata

Metadata

Labels

compiler:coreIssues for @typespec/compilerdesign:neededA design request has been raised that needs a proposaltriaged:core

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions