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

Expose a base Annotation type #12655

Open
Blacksmoke16 opened this issue Oct 24, 2022 · 2 comments
Open

Expose a base Annotation type #12655

Blacksmoke16 opened this issue Oct 24, 2022 · 2 comments

Comments

@Blacksmoke16
Copy link
Member

Blacksmoke16 commented Oct 24, 2022

Feature Request

  • Is your feature request related to a problem? Please describe clearly and concisely what is it.

With #9326 being merged, I got to revisiting my use case for that and what a potential implementation would look like. Using a stringified version of the annotation type works, but comes with some drawbacks.

The primary one being it can lead to issues if the same annotation exists within multiple namespaces, which can be solved but leads to more typing. Another problem is that you get a bit less type safety and have less options when it comes to making use of the type system itself.

Unlike the vast majority of the other types, annotations themselves seem to be outside of the normal AST tree. They have no ancestors nor children. There also is no Annotation type itself outside of macros. Because of this, code like this currently gets typed as a union between the two annotation:

annotation Foo; end
annotation Bar; end

hash = {
  Foo => 10,
  Bar => 20,
}

typeof(hash) # : Hash(Bar.class | Foo.class, Int32)
  • Describe the feature you would like, optionally illustrated by examples, and how it will solve the above problem.

I propose that all annotation type inherit from a base Annotation type, such that you could represent the hash as Hash(Annotation.class, Int32). This would allow more flexibility in adding/interacting with annotation types themselves. E.g. allowing for the creation of general purpose aliases/type restrictions of any annotation.

My main use case for this is to support the https://athenaframework.org/components/config/#custom-annotations feature of Athena. I.e. making overloads based on the annotation type such that the compiler knows it should return a specific struct based on what annotation was provided. Being able to type the internal hash as Annotation.class, or even iterate over all annotation children, would make that logic quite a bit cleaner.

EDIT: This would also be helpful for #9802. As if that ever gets implemented then i would make some things easier, but would still need to be able to store a hash of any annotation type.

  • Describe considered alternative solutions, and the reasons why you have not proposed them as a solution here.

Not super familiar with what the implementation of this would look like, but if so desired this could maybe be done at the macro AST level such that you could do like Annotation.all_subclasses, which would satisfy my use case as well I think given it would be easier to create the union of annotation types/generate the overloads.

  • Does it break backward compatibility, if yes then what's the migration path?

Probably not given its a new type? Tho not sure if this would have any other consequences.

@Blacksmoke16
Copy link
Member Author

Blacksmoke16 commented Oct 25, 2022

Looked into this a bit and here are my notes:

  • Currently annotations are of type AnnotationType which is currently just a NamedType
    • They have no parents, nor the ability to define a superclass/parents/subclasses
    • Given this type already exists, we'll need to either rename it to make room for the parent type, or use a diff name for the parent
  • Seems like we could follow some of what was done for UnionType in c628fbb as that also represents a more meta type you cant really instantiate/use directly
    • The parent annotation type probably also needs to be a child of struct such that we can define struct Annotation; end similar to struct Union; end?
      • Was running into an issue related to Error: Annotation is not a struct, it's a annotation because the type isnt a ClassDef? Not sure how ClassType struct avoids this...

@HertzDevil
Copy link
Contributor

Annotation could be a metaclass of itself, just like Class and all lib types. And the instance type of Annotation would be just NoReturn.

Related: #1150 for modules

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants