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

Stop removing underscores from CodingKey names in InputKey #548

Merged
merged 1 commit into from
Feb 2, 2023

Conversation

natecook1000
Copy link
Member

When a property wrapper is applied to a property, the property's storage is given a name with a prefixed underscore. That is, for a property named x, the actual storage is named _x.

That prefixed storage is what is visible through reflection, so when building an ArgumentSet from a command type's mirror, we need to remove the leading underscore. This is done when creating an InputKey for each property.

However, InputKeys are also created from CodingKeys during decoding of a command. These CodingKeys do not have the leading underscore that is added by the property wrapper, so any underscores that appear are actually from the declaration of the property with an underscored name. Removing leading underscores from CodingKey names results in a mismatch when trying to find the decoded value. For example, for a simple command declared like this:

@main
struct Repro: ParsableCommand {
    @Option(name: .customLong("arg"))
    var _arg: String?

    func run() throws {
        print(self._arg ?? "nil")
    }
}

Running: repro --arg foo fails to parse with the error:

Error: Unknown option '--arg'. Did you mean '--arg'?
Usage: repro [--arg <arg>]
  See 'repro --help' for more information.

This change simplifies the InputKey type to use an array path instead of an indirect enum and removes the leading underscore dropping when creating an InputKey from a CodingKey.

rdar://104928743

Checklist

  • I've added at least one test that validates that my change is working, if appropriate
  • I've followed the code style of the rest of the project
  • I've read the Contribution Guidelines
  • I've updated the documentation if necessary

When a property wrapper is applied to a property, the property's
storage is given a name with a prefixed underscore. That is,
for a property named `x`, the actual storage is named `_x`.

That prefixed storage is what is visible through reflection, so
when building an ArgumentSet from a command type's Mirror, we
need to remove the leading underscore. This is done when creating
an InputKey for each property.

However, InputKeys are also created from CodingKeys during
decoding of a ParsableCommand. These CodingKeys _do not_ have
the leading underscore that is visible, so any underscores
that appear are actually from the declaration of the property
with an underscored name. Removing leading underscores from
CodingKey names results in a mismatch when trying to find
the decoded value.

This change simplifies the InputKey type to use an array
path instead of an indirect enum and removes the leading
underscore dropping when creating an InputKey from a CodingKey.

rdar://104928743
@natecook1000
Copy link
Member Author

@swift-ci Please test

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.

1 participant