Skip to content

Allow functions to be used directly as metadata annotations #3210

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

Open
GregoryConrad opened this issue Jul 10, 2023 · 5 comments
Open

Allow functions to be used directly as metadata annotations #3210

GregoryConrad opened this issue Jul 10, 2023 · 5 comments
Labels
request Requests to resolve a particular developer problem

Comments

@GregoryConrad
Copy link

GregoryConrad commented Jul 10, 2023

I haven't actually looked at the language spec to know for sure whether this is considered a bug or not, but this definitely seems like some unwanted behavior. Filing here instead of sdk since I'm guessing it is due to the language specification.

void foo() {}
const bar = foo;

class Metadata {
  const Metadata(this.f);
  final void Function() f;
}

// @foo        // fails to compile, but this seems like it should
@bar           // ok, despite just being = foo
@Metadata(foo) // ok
void foobar() {}

Using functions as metadata annotations will be useful for when static metaprogramming roles around.

@GregoryConrad GregoryConrad added the request Requests to resolve a particular developer problem label Jul 10, 2023
@eernstg
Copy link
Member

eernstg commented Jul 10, 2023

Metadata is specified to be a reference to a constant variable, or an invocation of a constant constructor, and everything else is a compile-time error.

I'm not quite sure why the rules are so strict (these rules haven't been changed recently, if ever), and you have already mentioned that the function object foo can be used as metadata by declaring a constant variable bar and using that.

Syntactically, an expression that denotes a statically resolved function is already covered by the grammar rule about metadata.

So we should be able to introduce this generalization without breaking anything.

@lrhn
Copy link
Member

lrhn commented Jul 10, 2023

(these rules haven't been changed recently, if ever)

Only change I remember was to allow type arguments to constructor invocations.
Don't remember if we added "qualified identifier" at some much earlier point, but I think named constructors predate metadata, so it was probably there since the start.

If we allow constant function tear-offs, we should consider whether to allow instantiated function tear-offs (with constant type arguments).

That won't actually complicate the grammar much, since we already accounted for all the problems when introducing record types:

... since @metadata<T> appears to be a generic instantiation and could potentially be valid syntax in the future.

It should just work.

We already allow <qualifiedIdentifier>, which is enough to denote any static function, even if it requires three steps like prefix.ClassName.methodName.

If we allow static functions, we can also allow constructor tear-offs, which would mean allowing new as final "identifier", and generics after the next-to-last name in the chain.

So, something like:

<metadatum> ::= 
     <identifier> <typeArguments>? 
   | (<typeIdentifier> '.')? <typeIdentifier> <typeArguments>? ('.' <constructorName>)? (NO_SP <arguments>)?

<constructorName> ::= <identifier> | 'new'

@jtkeyva
Copy link

jtkeyva commented Feb 5, 2024

+1

@munificent
Copy link
Member

I think named constructors predate metadata

I believe you're correct.

@m-sadegh-sh

This comment was marked as off-topic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
request Requests to resolve a particular developer problem
Projects
None yet
Development

No branches or pull requests

6 participants