Skip to content
This repository has been archived by the owner on Nov 13, 2023. It is now read-only.

[Design] Allow renaming of exported component props. #75

Closed
cristianoc opened this issue Oct 27, 2018 · 8 comments
Closed

[Design] Allow renaming of exported component props. #75

cristianoc opened this issue Oct 27, 2018 · 8 comments
Labels
enhancement New feature or request

Comments

@cristianoc
Copy link
Collaborator

cristianoc commented Oct 27, 2018

Renaming in type definitions is already supported with @genType.as, for example:

[@genType]
type t  = { [@genType.as "type"] type_: string, number:int };

One would like to do the same when exporting components:

[@genType]
let make = (~type_, ~number, _children) => {
...

however it's not possible to add annotations next to named arguments above.

@cristianoc
Copy link
Collaborator Author

One possibility is to write the explicitly curried version and add annotations to the function type, like this:

[@genType]
let make =
  [@genType.as "type"]
  (
    (~type_) =>
      [@genType.as "$number"]
      (
        (~number, _children) => {
          ...component,
          render: _self => {
            Js.log2("type", type_);
            Js.log2("$number", number);
            <div />;
          },
        }
      )
  );

@cristianoc
Copy link
Collaborator Author

Another possibility is to use a map-style annotation:

module Design2 = {
  [@genType.as [("type_", "type"), ("number", "$number")]]
  let make = (~type_, ~number, _children) => {
    ...component,
    render: _self => {
      Js.log2("type", type_);
      Js.log2("$number", number);
      <div />;
    },
  };
};

One downside here is that it's possible to misspell the matching between ~type_ and "type_".

One downside of the annotation on the uncurried function is that first, the uncurried version needs to be used, and second, there's the convention that the annotation refers to the first named argument in the rest of the type. These are all extra details that one would need to learn.

@cristianoc
Copy link
Collaborator Author

One advantage of the map notation [@genType.as [("type_", "type"), ("number", "$number")]] is that is could be used everywhere, so it needs to be learned only once. It could be used for record/object types as well. Except... it might not work well with nested object types, where the label being renamed might end up quite far from the annotation.

@cristianoc
Copy link
Collaborator Author

@IwanKaramazow @jchavarri is there a reason why annotations are not allowed inside here: (~type_, ~number, _children) => ?
That would be the simplest solution.

@cristianoc cristianoc added the enhancement New feature or request label Oct 27, 2018
@cristianoc cristianoc changed the title Allow renaming of exported component props. [Design] Allow renaming of exported component props. Oct 27, 2018
cristianoc added a commit that referenced this issue Oct 27, 2018
Defining directly a type with annotated labeled arguments works.

But defining a function does not seem to work. The AST seems to only have empty strings corresponding to named argument types.

See: #75.
@cristianoc
Copy link
Collaborator Author

There's something strange going on.
Annotating directly a type declaration like this works:

  [@genType]
  type functionTypeWithGenTypeAs =
    [@genType.as "type"] (
      (~type_: string) => [@genType.as "$number"] ((~number: int) => int)
    );

But if a function is annotated as below, only empty strings are picked up associated to the @genType.as annotations in the AST:

  /* These genType.as annotation are currently not picked up in the AST */
  [@genType]
  let make =
    [@genType.as "type"]
    (
      (~type_) =>
        [@genType.as "$number"]
        (
          (~number, _children) => {
            ...component,
            render: _self => {
              Js.log2("type", type_);
              Js.log2("$number", number);
              <div />;
            },
          }
        )
    );
};

See 732bc24.

cristianoc added a commit that referenced this issue Oct 28, 2018
Support renaming of the form `[@genType.as “xRenamed”] (~x) => …`.

There’s a bug in ocaml 4.03.2 where the first annotation is lost.
So it’s not possible to rename the first named argument.
This limitation will go away once the compiler version is upgraded.

See #75.
@cristianoc
Copy link
Collaborator Author

Added support for the annotation on the uncurried form in 732bc24.

There's a bug in ocaml 4.03.2 where the first argument of the function can't be renamed. This will go away after the compiler upgrade.

In future, refmt could make this look nicer. Already now, this is supported:

[@genType]
let renameABunch = ~pad =>
  [@genType.as "xRenamed"] (~x) => [@genType.as "yRenamed"] (~y) => pad+x+y;

and is currently formatted to:

let renameABunch = ~pad =>
  [@genType.as "xRenamed"]
  ((~x) => [@genType.as "yRenamed"] ((~y) => pad + x + y));

Ideally, it could look like this:

[@genType]
let renameABunch = (~pad, [@genType.as "xRenamed"] ~x, [@genType.as "yRenamed"] ~y) => pad + x + y;

@cristianoc
Copy link
Collaborator Author

The first solution is now in master.
The issue about not being able to rename the first argument will need to be documented.
The feature request for better refmt moved to reasonml/reason#2251.
This can be closed now.

@jchavarri
Copy link
Contributor

This is awesome!! 👏 🎉

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants