Crystal: Return array of annotations of T on a type

Created on 17 Jan 2019  路  2Comments  路  Source: crystal-lang/crystal

class Klass

  annotation Test; end

  @[Test(val: 1)]
  @[Test(val: 2)]
  property test : Int32?

  def get
    {% for ivar in @type.instance_vars %}
      pp {{ivar.annotation(Test).stringify}} #= => "@[Test(val: 2)]"
    {% end %}
  end
end


Klass.new.get

Currently the .annotation method returns the last defined annotation of that type. However there are cases where there could be multiple annotations of the same type on a property/method, but with different values. For example:

  @[Athena::Routing::Get(path: "users/:id/posts/:post_id")]
  @[Athena::Routing::ParamConverter(param: "user", type: User, converter: Exists)]
  @[Athena::Routing::ParamConverter(param: "post", type: Post, converter: Exists)]
  def self.get_user(user : User, post : Post) : String
    "User_id: #{user.id}....Post_id: #{post.id}"
  end

Currently this isn't possible since the last ParamConverter would override the first.

I propose a new method be added annotations(Type) which would return all of the annotations defined, not just the last. The current annotation method could be altered to just return the last annotation from the array to maintain current behavior.

I'd be happy to give this a shot, but some hints of what would need to be done would be nice :)

Most helpful comment

Also in C# annotations are annotated with expected target and multiplicity. And give compiler time errors if are wrongly applied.

GetCustomAttribute,GetCustomAttributes is the API used there, so I think annotation/annotations is a good design.

All 2 comments

I think it's a good idea. In C# annotations can have multiplicity. In Crystal we could always store all of them and have annotation(...) return the last one, and annotations(...) return all of them.

Also in C# annotations are annotated with expected target and multiplicity. And give compiler time errors if are wrongly applied.

GetCustomAttribute,GetCustomAttributes is the API used there, so I think annotation/annotations is a good design.

Was this page helpful?
0 / 5 - 0 ratings