Dart2js brackets Symbol in metadata annotation - dart

I can run this code on Dart VM:
#MirrorsUsed(metaTargets: Tag)
import 'dart:mirrors';
class Tag {
final Symbol name;
const Tag(this.name);
}
#proxy
#Tag(#[])
class Tagged {
noSuchMethod(Invocation invocation) {
InstanceMirror instanceMirror = reflect(this);
ClassMirror classMirror = instanceMirror.type;
classMirror.metadata.forEach((em) {
if (em.reflectee is Tag && em.reflectee.name == invocation.memberName)
print(invocation.positionalArguments);
});
}
}
void main() {
var tagged = new Tagged();
tagged[42];
tagged.foo();
tagged["Dart"];
}
output:
[42]
[Dart]
But when i try to compile it with dart2js it fails with this error:
[Error from Dart2JS]:
bin\dart2jswithbracketanotation.dart:9:7:
Expected identifier, but got '['.
#Tag(#[])
So which one has the bug?:
(Dart VM) because I can run it at all.
(dart2js) because it doesn't compile to js.
update: I reported this bug

I think it's a bug in Dart2JS because an operator should be allowed at this position.

Related

How do you stub a method in mockito for dart?

import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
class Cat {
bool meow() {
return true;
}
}
class MockCat extends Mock implements Cat {}
void main() {
Cat mockCat = MockCat();
test('Mockito', () {
when(mockCat.meow()).thenReturn(true);
expect(mockCat.meow(), true);
});
}
Hi,
I am learning how to use mockito ^5.0.2 in Dart.
But anything I seem to do, doesn't work.
Here is the debug output for the above line codes :
type 'Null' is not a subtype of type 'bool'
MockCat.meow
test\…\use_cases\mockito_test.dart:5
main.<fn>
test\…\use_cases\mockito_test.dart:15
2
✖ Mockito
Exited (1)
Do you get the same output with the same code ?
What am I doing wrong here ?

Why is this basic Dart mirror usage not working

I've got the following code in a console application:
import 'dart:mirrors';
void main() {
final foo = Foo();
final mirror = reflect(foo);
final instanceMirror = mirror.invoke(#test, []);
print(instanceMirror);
}
class Foo {
int get test {return 42;}
}
When I run it I get an exception:
Exception has occurred.
NoSuchMethodError (NoSuchMethodError: Class 'int' has no instance method 'call'.
Receiver: 42
Tried calling: call())
If I set a breakpoint on test then it is hit before the exception, so it's definitely invoking the property.
Why is an exception being thrown?
UPDATE: ultimately what I am trying to achieve is to grab the values of all properties in an object. Per #mezoni's answer, it seems I need to treat properties as fields rather than methods (the opposite of C#, incidentally). However, it's still not entirely clear why or how to enumerate all fields. The best I've gotten is this:
import 'dart:mirrors';
void main() {
final foo = Foo();
final mirror = reflect(foo);
for (var k in mirror.type.instanceMembers.keys) {
final i = mirror.type.instanceMembers[k];
if (i.isGetter && i.simpleName != #hashCode && i.simpleName != #runtimeType) {
final instanceMirror = mirror.getField(i.simpleName);
print("${MirrorSystem.getName(i.simpleName)}: ${instanceMirror.reflectee}");
}
}
}
class Foo {
int get someOther {
return 42;
}
int get test {
return someOther + 13;
}
}
Please try this code:
import 'dart:mirrors';
void main() {
final foo = Foo();
final mirror = reflect(foo);
final instanceMirror = mirror.getField(#test);
print(instanceMirror.reflectee);
}
class Foo {
int get test {
return 42;
}
}

Getting ClassMirror instances for all classes that have an annotation

I have this annotation
class Target{
final String value;
const Target(this.value);
}
and 2 classes that are annotated with it
#Target("/313")
class c1{
}
#Target("/314")
class c2{
}
how can i get a List of ClassMirror instances for the classes that have the Target annotation?
based on the selected answer that is if i knew what library my calsses exist in
var mirrorSystem = currentMirrorSystem();
var libraryMirror = mirrorSystem.findLibrary(#testlib);
for(ClassMirror classMirror in libraryMirror.declarations.values){
if(classMirror.metadata!=null){
for(var meta in classMirror.metadata){
if(meta.type == reflectClass(Path)){
print(classMirror.simpleName);
print(meta.getField(#value));
}
}
}
}
This searches all libraries in the current isolate for classes that are annotated with #Target('/313')
#MirrorsUsed(metaTargets: Target) // might be necessary when you build this code to JavaScript
import 'dart:mirrors';
class Target {
final String id;
const Target(this.id);
}
#Target('/313')
class c1{
}
#Target('/314')
class c2{
}
#Target('/313')
#Target('/314')
class c3{
}
void main() {
MirrorSystem mirrorSystem = currentMirrorSystem();
mirrorSystem.libraries.forEach((lk, l) {
l.declarations.forEach((dk, d) {
if(d is ClassMirror) {
ClassMirror cm = d as ClassMirror;
cm.metadata.forEach((md) {
InstanceMirror metadata = md as InstanceMirror;
if(metadata.type == reflectClass(Target) && metadata.getField(#id).reflectee == '/313') {
print('found: ${cm.simpleName}');
}
});
}
});
});
}
found: Symbol("c3")
found: Symbol("c1")

in Dart, given a Type name, how do you get the Type (class) itself? [duplicate]

This question already has answers here:
Create an instance of an object from a String in Dart?
(3 answers)
Closed 8 years ago.
if have a Type, using Mirrors can get the Type name. inversely, given a Type's name, how do you get the Type?
for example, from a Dart-centric version of Angular:
index.html
<form ng-controller='word?reset=true' >
...
</form>
mylib.dart
class Controller {
Controller( Brando brando, Element elem, Map args ) { ... }
}
class Word extends Controller { ... }
class LangList extends Controller { ... }
// Brando, the godfather
class Brando {
...
void compile( Element el ) {
...
// add controller
if( el.attributes.contains( 'ng-controller' ) {
var name = el.attributes.getTypeName(); <== "Word"
var args = el.attributes.getTypeArgs(); <== { 'reset': 'true' }
var type = <get type from camelized Type name> <=== how??
this.controllers.add( reflectClass(type).newInstance(
const Symbol(''), [this,el,args]).reflectee ); <=== instance from type
}
...
}
}
know how to get name of Type, how to get Type from class and Object, and know how to instantiate a Type. missing final piece - how do you derive the Type from its name?
Note: The mirror API is `unstable', so this answer may change over time.
*Note: This may (will) bloat your generated javascript see: https://api.dartlang.org/docs/channels/stable/latest/dart_mirrors/MirrorSystem.html#getSymbol*
import 'dart:mirrors';
class Bar {
}
ClassMirror findClassMirror(String name) {
for (var lib in currentMirrorSystem().libraries.values) {
var mirror = lib.declarations[MirrorSystem.getSymbol(name)];
if (mirror != null) return mirror;
}
throw new ArgumentError("Class $name does not exist");
}
void main() {
ClassMirror mirror = findClassMirror("Bar");
print("mirror: $mirror");
}
output:
mirror: ClassMirror on 'Bar'

Retrieving getter values with dart:mirrors reflection

I have the following code (simplified), that uses reflection to iterate a class's fields and getters and output the values. The ContainsGetter class contains a getter, and the ContainsField class contains a simple field.
Using dart:mirrors library, I can get the value of the field by using instanceMirror.getField(fieldName)), but not the getter by using instanceMirror.invoke(fieldName,[]).
The following Dart script (using the build 17463) gives the output below:
app script
import 'dart:mirrors';
class ContainsGetter { // raises an error
String get aGetter => "I am a getter";
}
class ContainsField { // works fine
String aField = "I am a field";
}
void main() {
printFieldValues(reflect(new ContainsField()));
printGetterValues(reflect(new ContainsGetter()));
}
void printFieldValues(instanceMirror) {
var classMirror = instanceMirror.type;
classMirror.variables.keys.forEach((key) {
var futureField = instanceMirror.getField(key); // <-- works ok
futureField.then((imField) => print("Field: $key=${imField.reflectee}"));
});
}
void printGetterValues(instanceMirror) {
var classMirror = instanceMirror.type;
classMirror.getters.keys.forEach((key) {
var futureValue = instanceMirror.invoke(key,[]); // <-- fails
futureValue.then((imValue) => print("Field: $key=${imValue.reflectee}"));
});
}
output
Field: aField=I am a field
Uncaught Error: Compile-time error during mirrored execution: <Dart_Invoke: did not find instance method 'ContainsGetter.aGetter'.>
Stack Trace:
#0 _LocalObjectMirrorImpl._invoke (dart:mirrors-patch:163:3)
#1 _LocalObjectMirrorImpl.invoke (dart:mirrors-patch:125:33)
(An acceptable could be that "this bit just hasn't been written yet!")
Aah, I've just worked it out. Although aGetter is like a method in its implementation, you use the getField() rather than invoke to retrieve its value.
void printGetterValues(instanceMirror) {
var classMirror = instanceMirror.type;
classMirror.getters.keys.forEach((key) {
var futureValue = instanceMirror.getField(key); // <-- now works ok
futureValue.then((imValue) => print("Field: $key=${imValue.reflectee}"));
});
}

Resources