2

I want to create a symbol equal to that of a private MethodMirror's simplename. However, Symbol's documentation states the argument of new Symbol must be a valid public identifier. If I try and create a const Symbol('_privateIdentifier') dart editor informs me that evaluation of this constant expression will throw an exception - though the program runs fine, and I am able to use it without any issues.

void main(){
  //error flagged in dart editor, though runs fine.
  const s = const Symbol('_s');
  print(s); //Symbol("_s");
}

It seems the mirror system uses symbols.

import 'dart:mirrors';
class ClassA{
  _privateMethod(){}
}

void main(){
  var classMirror = reflect(new ClassA()).type;
  classMirror.declarations.keys.forEach(print);
  //Symbol("_privateMethod"), Symbol("ClassA")
}

Is the documentation/error flagging in dart editor a legacy bug due to an outdated dart analyzer? Or are there plans to enforce this public requirement in future? Is there another way to create a unique identifying symbol that will be minified to the same symbol as the declaration's simple name

jww
  • 97,681
  • 90
  • 411
  • 885
DomJack
  • 4,098
  • 1
  • 17
  • 32

2 Answers2

3

If it doesn't throw then the VM has a bug in the const Symbol constructor.

The problem is that "_s" does not identify a private variable without also saying which library it belongs to. The symbol constructor has a second argument taking a LibraryMirror for that reason, and passing in a private name without also passing in a mirror should throw. That's hard to do in a const constructor without side-stepping the requirements of a const constructor (no executing code!), which is likely why the VM doesn't handle it. It needs to be special-cased at the compiler level.

You will also find that const Symbol('_s') is not the same as #_s. The latter creates a private symbol for the current library, the former (if it runs) creates a non-private symbol with the name '_s', which is not really useful. For example print(identical(#_s, const Symbol('_s'))); prints false.

lrn
  • 64,680
  • 7
  • 105
  • 121
  • Is it possible to have a symbol literal that is identical to a top-level setter-method? From what I understand, setter symbols always end in "=", but it looks like #x= gets tokenized into [#x, =]. – DomJack Mar 19 '15 at 01:54
  • A setter `Symbol` can't be created using a symbol literal, but it can be created using `const Symbol("x=")`. That's issue http://dartbug.com/13640. It makes it somewhat harder to create a private setter symbol, and if it doesn't have to be a constant, the easiest way is likely to create an object with a `noSuchMethod` that leaks the `Invocation.memberName` symbol. – lrn Mar 19 '15 at 13:28
1

The To get hold of the symbol I think you would need to get it from the object. e.g.

  reflect(thing).type.declarations.keys.firstWhere(
    (x) => MirrorSystem.getName(x) == "_privateThingIWant");
Alan Knight
  • 2,759
  • 1
  • 15
  • 13