Accessing library internal fields with mirror

Issue

Trying to access a private (package internal) field got me in a strange situation.
My Class “Properties” has a internal field named ‘_forceAccum’.
Trying to get the value of it fails for me using this code:

InstanceMirror bodyMirror = reflect(props);
var value = propsMirror.getField(new Symbol('_forceAccum'));

but if I use this instead:

InstanceMirror bodyMirror = reflect(props);
var value = propsMirror.getField(new Symbol('_forceAccum@434525364'));

it works. (I got the “@…” from iterating through the symbols (.toString()) from the class mirror).

Is it supposed to work this way? Is it safe or will it change in the next version? (I’m using 1.7.2)
or does it just work by pure happenstance?

Solution

Your problem is that you have a library private name. It’s name isn’t just _forceAccum, it’s a special symbol related to _forceAccum that is unique to the library, but different from a _forceAccum in another library.

To create the private symbol using mirrors, you must use MirrorSystem.getSymbol as: MirrorSystem.getSymbol("_forceAccum", libraryMirrorOfLibrary). This creates a library-private symbol for that particular library. You can’t create a private symbol without either specifying the library that it’s private to, or by being in the library (#_forceAccum will create the correct symbol for the library that it occurs in).

The other alternative, which you used, is to look through the library and find the already existing symbol there:

var forceAccumSymbol = 
    libraryMirrorOfLibrary.declarations.keys
                          .where((n) => MirrorSystem.getName(n) == "_forceAccum")
                          .first;

(if the declaration is a top-level declaration).

The _forceAccum@something name that you are seeing is the VM’s way of making a name library private. It’s not going to work if compiled with dart2js, and it’s probably not going to have the same something on each run, so you can’t can’t put it into your code.

Answered By – lrn

Answer Checked By – Timothy Miller (FlutterFixes Admin)

Leave a Reply

Your email address will not be published.