How to retrieve annotations on declarations

2019-08-08 02:14发布

问题:

According to the spec, metadata can appear before a variable declaration.

However, it does not say anything about if this is possible to retrieve.

const annotation = null;

main() {

  @annotation
  var a = "";
  print(reflect(a) is DeclarationMirror);
}

Outputs false;

Is the retrieval of such usage of annotations possible?

回答1:

Sorry for the anwser, but actually, it's not possible to do what you want. For a simple reason : Your code is syntaxicly correct, but no instance of the annotation is created.

example :

class Testing {
  Testing(String toPrint) {
    print(toPrint);
  }
}

class annotation {
  final Testing test;
  const annotation(this.test);
}

void main() {
   @annotation(new Testing("Annotation instanciation"))  var a = "hello";

   print(a);
   var annot = new annotation(new Testing("Local instanciation"));
   print(a);
}

This code result :

$ hello

$ Local instanciation

$ hello

So the annotation constructor has never been called.

May be this features will be add in the future

Information : Actually, it doesn't work in this case because it's a local variable declaration. for a function, class or others, it will work.



回答2:

No, it's not possible.

You are correct that you need to use mirrors to retrieve metadata. The spec says:

"Metadata can be retrieved at runtime via a reflective call, provided the annotated
 program construct p is accessible via reflection."

However, there are no mirrors for local variables (variables declared inside function bodies), so it is exactly not accessible via reflection.

You can only find mirrors for declarations that are either top-level, members of a class, or parameters of a function (and, technically, a local function declaration, but that doesn't work very well).



回答3:

By using currentMirrorSystem().findLibrary I could retrieve the list of declarations in the library. By using new Symbol('') to denote the current unnamed library, and the global identifiers were accessible. I could also get the main method, but I could not access the inner variables in main. So the answer is a partial yes.

However, I wonder if ClosureMirror could be worth looking at.



回答4:

As far as I know this is currently only supported for fields of a class or top level fields but not for local variables inside a method/function when reflecting at runtime. Maybe source mirrors has more capabilities (I haven't used it yet) but I think this can only be used at compile time.