1

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?

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
tusj
  • 287
  • 2
  • 11
  • you're reflecting on an instance of a string, so you will get an InstanceMirror – Daniel Robinson May 28 '14 at 06:37
  • That is true. But why is not `var a = ""` a declaration? – tusj May 28 '14 at 06:38
  • 1
    well the api docs say "A DeclarationMirror reflects some entity declared in a Dart program" which to me sounds like it is usable on declerations within a library, I have had a brief look through the api and found it to be returned by using a LibraryMirrors declarations getter. All I can say for certain that calling reflect(a) is definately not reflecting on a declaration, it's just reflecting on the string instance, you want to use reflectClass() or reflectType() as they do return DeclarationMirrors. – Daniel Robinson May 28 '14 at 06:53
  • That's the examples we already have, and that works fine. I am just curious to see how to obtain that `DeclarationMirror` without going through the members of a class. And the notation posted is not bound to the type, but to the instance of the variable, so I wanted to see how I could find that annotation by going through the reflection of its instance. I will play around a little with LibraryMirror and see what I get. – tusj May 28 '14 at 07:19

4 Answers4

2

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.

Community
  • 1
  • 1
Vink
  • 1,267
  • 9
  • 13
  • What I have read any constant value can be used as annotation. Do you think that's not so? – Günter Zöchbauer May 28 '14 at 08:33
  • Yes, i agree and here i use a constant constructor as an annotation. The issue here is that for a variable annotation, i don't know exactly why, but the constructor of the annotation is never called. But if i remove the const qualifier in my constructor, the dart analyzer will warn me that the annotation is not valid. – Vink May 28 '14 at 08:37
  • Thanks, I think I understand now what you tried to show. – Günter Zöchbauer May 28 '14 at 08:39
  • Yeah, sorry if my explanation are not totally clear ^^" – Vink May 28 '14 at 08:40
  • But is it not so that `annotation.inst` is acutally never set because `inst` is not referring to `this.inst` but just the argument? I tried changing the constructor call to `this.inst` but then it complains that the class is not constant any more. By setting `this.inst` in the constructor, you get: 'inst' is a static variable in the enclosing class, variables initialized in a constructor cannot be static – tusj May 28 '14 at 08:48
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).

lrn
  • 64,680
  • 7
  • 105
  • 121
1

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.

tusj
  • 287
  • 2
  • 11
1

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.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567