Symbol with private identifier argument
Asked Answered
D

2

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

Dentiform answered 18/3, 2015 at 3:3 Comment(0)
F
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.

Fannie answered 18/3, 2015 at 6:11 Comment(2)
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, =].Dentiform
A setter Symbol can't be created using a symbol literal, but it can be created using const Symbol("x="). That's issue 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.Fannie
E
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");
Ephor answered 19/3, 2015 at 16:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.