Coder Social home page Coder Social logo

google / reflectable.dart Goto Github PK

View Code? Open in Web Editor NEW
369.0 38.0 65.0 2.57 MB

Reflectable is a Dart library that allows programmers to eliminate certain usages of dynamic reflection by specialization of reflective code to an equivalent implementation using only static techniques. The use of dynamic reflection is constrained in order to ensure that the specialized code can be generated and will have a reasonable size.

Home Page: https://pub.dev/packages/reflectable

License: BSD 3-Clause "New" or "Revised" License

Dart 99.46% Makefile 0.25% Shell 0.28%

reflectable.dart's Introduction

This repository provides the Dart package reflectable along with a set of test cases, test_reflectable.

Support for generating code that implements a large subset of the features offered by 'dart:mirrors' without relying on 'dart:mirrors' itself. Provides a system based on capabilities to control the amount of reflection support.

Used to test package reflectable. Also serves as a set of examples of how reflectable can be used.

reflectable.dart's People

Contributors

anders-sandholm avatar ashutosh2014 avatar bwilkerson avatar dimibe avatar eernstg avatar jakemac53 avatar jcowgar avatar julientd avatar kevmoo avatar luisvt avatar mit-mit avatar ricowind avatar sigurdm avatar sten435 avatar zoechi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

reflectable.dart's Issues

Super classes and interfaces of annotated classes should also be reflectable.

This is needed in order to walk the super chain to get all members of a class. It is not possible to add an annotation to all super classes since many of them live in the sdk (Object for example).

For example, currently this will fail:

class MyReflectable extends Reflectable {
  const MyReflectable() : super(instanceInvokeCapability);
}
const myReflectable = const MyReflectable()

@myReflectable
class MyClass {}

main() {
  var typeMirror = myReflectable.reflectType(MyClass);

  // Throws exception because `Object` is not reflectable.
  var superclass = typeMirror.superclass;
}

This could be hidden possibly under a capability, such as superclassCapability or something along those lines to avoid code bloat in cases that don't need it?

instanceMembers fails after transform in some cases

I have a Reflector with InstanceInvokeMetaCapability, and in Dart (vm,dartium,content-shell) it works as expected. However after transform I get a weird error.

When I do this: reflector.reflect(this).type.instanceMembers

This part:

// src/reflectable_transformer_based.dart:183

  ReflectorData get _data {
    if (_dataCache == null) {
      _dataCache = data[_reflector];
    }
    return _dataCache;
  }

Fails in some way in Dart2JS, because the data[_reflector] throws the following error in JS:

  NullError: method not found: '$index' on null
  package:reflectable/src/reflectable_transformer_based.dart 185:20   _data
  package:reflectable/src/reflectable_transformer_based.dart 196:13   _InstanceMirrorImpl
  package:reflectable/src/reflectable_transformer_based.dart 195:3
  package:reflectable/src/reflectable_transformer_based.dart 2166:12  myProjectsFunctionName
  package:my_project/my_file.dart

I haven't encountered this error before, and I suspect it has something to do with encapsulation, maybe?
Both the metadata class and the reflectee class are public.

Transformer throws on admitSubtypeCapability

Not sure if this capability is supposed to work in js, if not a better error message/guard should be provided.

This is the capability spec:

class Foo extends Reflectable {
  const Foo() : super(admitSubtypeCapability);
Build error:
Transform Reflectable on foobar|ReflectableTransformed threw error: *** Unexpected situation encountered!
Please report a bug on github.com/dart-lang/reflectable: Unexpected capability _AdmitSubtypeCapability.
package:reflectable/src/incompleteness.dart 28                unreachableError
package:reflectable/src/transformer_implementation.dart 3136  TransformerImplementation._capabilityOfExpression
package:reflectable/src/transformer_implementation.dart 3179  TransformerImplementation._capabilitiesOf.capabilityOfExpression
dart:_internal/iterable.dart 413                              MappedListIterable.elementAt
dart:_internal/iterable.dart 219                              ListIterable.toList
package:reflectable/src/transformer_implementation.dart 3187  TransformerImplementation._capabilitiesOf
package:reflectable/src/transformer_implementation.dart 2840  TransformerImplementation._computeWorld.getReflectorDomain.<fn>
dart:collection-patch/compact_hash.dart 254                   _HashVMBase&MapMixin&&_LinkedHashMapMixin.putIfAbsent
package:reflectable/src/transformer_implementation.dart 2838  TransformerImplementation._computeWorld.getReflectorDomain
package:reflectable/src/transformer_implementation.dart 2866  TransformerImplementation._computeWorld.addClassDomain
package:reflectable/src/transformer_implementation.dart 2962  TransformerImplementation._computeWorld
package:reflectable/src/transformer_implementation.dart 3327  TransformerImplementation.apply.<async>
dart:async/zone.dart 1149                                     _RootZone.runUnary
dart:async/future_impl.dart 502                               _Future._propagateToListeners.handleValueCallback
dart:async/future_impl.dart 585                               _Future._propagateToListeners
dart:async/future_impl.dart 568                               _Future._propagateToListeners.handleWhenCompleteCallback.<fn>
dart:async/zone.dart 1149                                     _RootZone.runUnary
dart:async/future_impl.dart 502                               _Future._propagateToListeners.handleValueCallback
dart:async/future_impl.dart 585                               _Future._propagateToListeners
dart:async/future_impl.dart 376                               _Future._completeWithValue
dart:async/future_impl.dart 430                               _Future._asyncComplete.<fn>
dart:async/schedule_microtask.dart 43                         _microtaskLoop
dart:async/schedule_microtask.dart 52                         _microtaskLoopEntry
dart:isolate-patch/isolate_patch.dart 96                      _runPendingImmediateCallback
dart:isolate-patch/isolate_patch.dart 151                     _RawReceivePortImpl._handleMessage

package:reflectable/src/incompleteness.dart 28                unreachableError
package:reflectable/src/transformer_implementation.dart 3136  TransformerImplementation._capabilityOfExpression
package:reflectable/src/transformer_implementation.dart 3179  TransformerImplementation._capabilitiesOf.capabilityOfExpression
dart:_internal                                                ListIterable.toList
package:reflectable/src/transformer_implementation.dart 3187  TransformerImplementation._capabilitiesOf
package:reflectable/src/transformer_implementation.dart 2840  TransformerImplementation._computeWorld.getReflectorDomain.<fn>
dart:collection                                               _HashVMBase&MapMixin&&_LinkedHashMapMixin.putIfAbsent
package:reflectable/src/transformer_implementation.dart 2838  TransformerImplementation._computeWorld.getReflectorDomain
package:reflectable/src/transformer_implementation.dart 2866  TransformerImplementation._computeWorld.addClassDomain
package:reflectable/src/transformer_implementation.dart 2962  TransformerImplementation._computeWorld
package:reflectable/src/transformer_implementation.dart 3327  TransformerImplementation.apply.<async>

The transformer makes an attempt to invoke `null.parent`.

I got this exception on one of the entry-points

Serving polymer_elements_demo web on http://localhost:45700
Build error:
Transform Reflectable on polymer_elements_demo|ReflectableTransformed threw error: The null object does not have a getter 'parent'.

NoSuchMethodError: method not found: 'parent'
Receiver: null
Arguments: []
dart:core-patch/object_patch.dart 42 Object._noSuchMethod
dart:core-patch/object_patch.dart 45 Object.noSuchMethod
package:reflectable/src/transformer_implementation.dart 2326 _extractMetadataCode
package:reflectable/src/transformer_implementation.dart 739 _ReflectorDomain._generateCode.
dart:_internal/iterable.dart 390 MappedIterator.moveNext
dart:core-patch/growable_array.dart 188 List.addAll
package:reflectable/src/transformer_implementation.dart 752 _ReflectorDomain._generateCode
package:reflectable/src/transformer_implementation.dart 50 ReflectionWorld.generateCode.
dart:_internal/iterable.dart 413 MappedListIterable.elementAt
dart:_internal/iterable.dart 148 ListIterable.join
package:reflectable/src/transformer_implementation.dart 2145 _formatAsMap
package:reflectable/src/transformer_implementation.dart 48 ReflectionWorld.generateCode
package:reflectable/src/transformer_implementation.dart 1872 TransformerImplementation._generateNewEntryPoint
package:reflectable/src/transformer_implementation.dart 1996 TransformerImplementation.apply.
dart:async/zone.dart 1165 _RootZone.runUnary
dart:async/future_impl.dart 502 _Future._propagateToListeners.handleValueCallback
dart:async/future_impl.dart 585 _Future._propagateToListeners
dart:async/future_impl.dart 376 _Future._completeWithValue
dart:async/future_impl.dart 430 _Future._asyncComplete.
dart:async/schedule_microtask.dart 43 _microtaskLoop
dart:async/schedule_microtask.dart 52 _microtaskLoopEntry
dart:isolate-patch/isolate_patch.dart 96 _runPendingImmediateCallback
dart:isolate-patch/isolate_patch.dart 151 _RawReceivePortImpl._handleMessage

dart:core Object.noSuchMethod
package:reflectable/src/transformer_implementation.dart 2326 _extractMetadataCode
package:reflectable/src/transformer_implementation.dart 739 _ReflectorDomain._generateCode.
dart:core List.addAll
package:reflectable/src/transformer_implementation.dart 752 _ReflectorDomain._generateCode
package:reflectable/src/transformer_implementation.dart 50 ReflectionWorld.generateCode.
dart:_internal ListIterable.join
package:reflectable/src/transformer_implementation.dart 2145 _formatAsMap
package:reflectable/src/transformer_implementation.dart 48 ReflectionWorld.generateCode
package:reflectable/src/transformer_implementation.dart 1872 TransformerImplementation._generateNewEntryPoint
package:reflectable/src/transformer_implementation.dart 1996 TransformerImplementation.apply.
Build completed with 1 errors.

when loading a Polymer entry page but the error wasn't even related to the page I was loading.
There is also no information about which entry-point caused the exception.

Request to refactor to add option to not overwrite the entry-point file

Hi,

We'd like to try to use reflectable with Flutter, but don't want to pull in barback or transformers. Would it be possible to refactor reflectable to not require/mandate a dep on barback?

(We'd then take responsibility for wiring reflectable into our build system.)

Flutter doesn't have any reflection capabilities, so we'd love to experiment with reflectable.

Thanks very much!

Use case from mustache library

In case it helps - here's how mirrors are currently used in the mustache library. It would be great if the reflectable library also handles this use case.

   var template = new Template('{{ foo }}');
   var output = template.renderString(new Bar());  // output = 42

   @mustache
   class Bar {
      get foo => 42;
   }

Here's the part of the implementation which uses mirrors:

https://github.com/xxgreg/mustache/blob/master/lib/src/renderer.dart#L192

    var instance = reflect(object);
    var field = instance.type.instanceMembers[new Symbol(name)];
    if (field == null) return _noSuchProperty;

    var invocation = null;
    if ((field is VariableMirror) || ((field is MethodMirror) && (field.isGetter))) {
      invocation = instance.getField(field.simpleName);
    } else if ((field is MethodMirror) && (field.parameters.length == 0)) {
      invocation = instance.invoke(field.simpleName, []);
    }
    if (invocation == null) {
      return _noSuchProperty;
    }
    return invocation.reflectee;

Unable to point Pub to git repo

I wanted to play around with the reflectable package a little bit but, due to the repo's folder structure, I'm unable to point my project at it. Pub does not appear to support specifying a subpath within a git repo based dependency entry. So the best I can do is point to the top-level directory which causes pub to complain that there's no pubspec.yaml file present. Could you please consider either splitting the repo into two, or restructure the repo to be a valid dependency target for pub?

Allow access to both getter and setter of a property when either is annotated according to InstanceInvokeMetaCapability

It would be very nice if you could use InstanceInvokeMetaCapability to reflect on properties without requiring that both getter and setter be annotated with the specified type, either as the default behavior of through additional config. It's less ideal that users of my library have to annotate both getter and setter of every property that they want to have processed when the thing it does always involves both reading and modifying the property value. Currently I have to resort to InstanceInvokeCapability without a name pattern.

On a more general note, as a user of Reflectable it would just feel more natural if properties were given at least partially first-class treatment instead of them just being linked by name.

Transformer error: The null object does not have a getter 'supertype'.

I'm currently getting an error message when trying to compile my polymer-dart project (behaviors-branch). Reflectable is at 0.1.5.

ReflectableTransformed threw error: The null object does not have a getter 'supertype'.             

NoSuchMethodError: method not found: 'supertype'                                                                                     
Receiver: null                                                                                                                       
Arguments: []                                                                                                                        
dart:core-patch/object_patch.dart 42                             Object._noSuchMethod                                                
dart:core-patch/object_patch.dart 45                             Object.noSuchMethod                                                 
package:reflectable/src/transformer_implementation.dart 947:47   _ClassDomain._instanceMembers.helper                                
package:reflectable/src/transformer_implementation.dart 936:15   _ClassDomain._instanceMembers.helper                                
package:reflectable/src/transformer_implementation.dart 971:18   _ClassDomain._instanceMembers                                       
package:reflectable/src/transformer_implementation.dart 405:19   _ReflectorDomain._generateCode                                      
package:reflectable/src/transformer_implementation.dart 47:24    ReflectionWorld.generateCode.<fn>
dart:_internal/iterable.dart 413                                 MappedListIterable.elementAt
dart:_internal/iterable.dart 148                                 ListIterable.join
package:reflectable/src/transformer_implementation.dart 2104:50  _formatAsMap
package:reflectable/src/transformer_implementation.dart 45:12    ReflectionWorld.generateCode
package:reflectable/src/transformer_implementation.dart 1837:25  TransformerImplementation._generateNewEntryPoint
package:reflectable/src/transformer_implementation.dart 1955:11  TransformerImplementation.apply.<async>
dart:async/zone.dart 1166                                        _RootZone.runUnary
dart:async/future_impl.dart 494                                  _Future._propagateToListeners.handleValueCallback
dart:async/future_impl.dart 577                                  _Future._propagateToListeners
dart:async/future_impl.dart 368                                  _Future._completeWithValue
dart:async/future_impl.dart 422                                  _Future._asyncComplete.<fn>
dart:async/schedule_microtask.dart 43                            _microtaskLoop
dart:async/schedule_microtask.dart 52                            _microtaskLoopEntry
dart:isolate-patch/isolate_patch.dart 96                         _runPendingImmediateCallback
dart:isolate-patch/isolate_patch.dart 149                        _RawReceivePortImpl._handleMessage

dart:core                                                        Object.noSuchMethod
package:reflectable/src/transformer_implementation.dart 947:47   _ClassDomain._instanceMembers.helper
package:reflectable/src/transformer_implementation.dart 936:15   _ClassDomain._instanceMembers.helper
package:reflectable/src/transformer_implementation.dart 971:18   _ClassDomain._instanceMembers
package:reflectable/src/transformer_implementation.dart 405:19   _ReflectorDomain._generateCode
package:reflectable/src/transformer_implementation.dart 47:24    ReflectionWorld.generateCode.<fn>
dart:_internal                                                   ListIterable.join
package:reflectable/src/transformer_implementation.dart 2104:50  _formatAsMap
package:reflectable/src/transformer_implementation.dart 45:12    ReflectionWorld.generateCode
package:reflectable/src/transformer_implementation.dart 1837:25  TransformerImplementation._generateNewEntryPoint
package:reflectable/src/transformer_implementation.dart 1955:11  TransformerImplementation.apply.<async>

As far as I understand the code in transformer_implementation.dart the code in lines 947 up to 949 should check classElement for null:

ClassElement superclass = (classElement != null && classElement.supertype != null)
          ? classElement.supertype.element
          : null;

Is there something I can do to prevent this kind of exceptions? What is causing classElement to be null in the first place?

Update to use analyzer `^0.27.0`

Last I heard there were some issues, but we need to get those resolved and update. This is the final dependency of polymer which needs to be updated.

Transformer gives invalid warnings about missing entry points

This is partly related to this bug dart-lang/pub#1308, and partly the transformers fault. If the user does pub serve or pub build on a specific directory (usually web or test) then the transformer will only be supplied the files from that directory and the files from lib, not all files in the package. Therefore if you have entry points inside of web and test, then you will always get a warning about entry points not existing if you pub serve|build web|test. I don't know if there is a good solution to this, the warning may need to just be removed.

Multi field declaration fails

should this work?

class Name extends JsProxy {
  @reflectable String first, last;
  // also not possible
  // @reflectable String first, @reflectable last;
  Name(this.first, this.last);
}

I didn't get an error message, just launching the Polymer app failed.

I don't especially need or want this, just encountered it while working on some Polymer examples.

Bad formatting in design document

The choice of code/non-code font is wrong at the beginning of the 'Considerations around Admitting Subtypes' section in the reflectable capability design document.

Example of a simple JSON system using reflectable

Users have been asking for an easy way to do simple JSON decoding for years. Hopefully reflectable can deliver this.

Here is the use case:

class Person {
  int age;
  String name;
  List<Address> addresses;
}

class Address {
  String street;
  String zip;
}

// Assumptions: no key is used for each top-level object (map), the developer knows what the top-level
// maps are. The structure of the maps is expected to match the structure of the class.
final data = '''
[
  {"age":21, "name":"Bob", "addresses":[{"street":"123 main", "zip":"88443"}, {"street":"555 second", "zip":"99999"}]},
  {"age":3, "name":"Alice", "addresses":[{"street":"222 cedar", "zip":"23456"}]}
]
''';

We should really make it simple to get a List<Person> from the data string, without code bloat when compiled to JavaScript, and without a source-gen step.

InstanceInvokeMetaCapability doesn't let you invoke methods on super classes/mixins

For example the following throws when it shouldn't.

import 'package:reflectable/reflectable.dart';

class MyReflectable extends Reflectable {
  const MyReflectable()
      : super(const InstanceInvokeMetaCapability(IsReflectable));
}

const myReflectable = const MyReflectable();

class IsReflectable {
  const IsReflectable();
}

@myReflectable
class A {
  @IsReflectable()
  String get hello => 'world';
}

@myReflectable
class B extends A {}

main() {
  var instance = new B();
  var instanceMirror = myReflectable.reflect(instance);
  print(instanceMirror.invokeGetter('hello'));
}

Type arguments are not covered by a capability

Programs using reflectable may use a capability (TypeAnnotationQuantifyCapability) to request that the classes used as type annotations in covered declarations are covered as well. For instance, consider the situation where we have a class C which is covered by reflector, and which uses a non-covered class D in one or more type annotations:

@reflector
abstract class C {
  D foo(D d);
}

class D {}

Assuming that reflector provides support for obtaining a class mirror for C, a method mirror for foo, and a class mirror for the return type or argument type D, then a typeAnnotationQuantifyCapability in reflector can be used to automatically ensure that D is covered because it can be reached in this manner.

It is tempting to request a similar capability, say typeArgumentQuantifyCapability, which would ensure that we get coverage of all the types used as type arguments. However, it is not easy to implement support for such a capability (apart from the trivial solution which is to support the entire universe).

The problem is that the set of type arguments used in instantiations of generic classes is not a statically known property. For instance, it is possible to use runtime values (of an int, say) to select an arbitrary depth in the construction of a value of type List<List<List<...>>>, which means that the dynamic set of type arguments is undecidable.

For this reason, no attempt is made to automatically obtain coverage of the types used as type arguments, and there will never be a typeArgumentQuantifyCapability.

This is particularly inconvenient for the method typeArguments, which may fail with a NoSuchCapabilityError because it attempts to create a TypeMirror for a class which is not covered. Unfortunately, the only available remedy is a manual extension of the set of covered classes. If the classes which are actually used as type arguments are covered then typeArguments will succeed, and no further issues arise. But, in general, invocations of typeArguments must be considered to be dangerous in this respect.

This issue is marked as blocked because a solution is out of reach, and it exists because it is useful to be able to point to this explanation, in case the issue arises in practice.

Range error when a class contains a static final list field

@PolymerRegister('my-element')
class MyElement extends PolymerElement {
  static const List<String> hardCodedListOfWords = const [
    "apple"];
  MyElement.created() : super.created() {}
}

When I rename it to make it private it works fine.
Full project https://github.com/bwu-dart-contributing/polymer-dart-patterns/blob/0.17.0/web/forms/implementing_simple_autocompletion/my_element.dart#L17

Exception: Uncaught Error: RangeError (index): Invalid value: Not in range 0..2523, inclusive: -1
Stack Trace:

0 List.

1 ClassMirrorImpl.staticMembers (package:reflectable/src/reflectable_transformer_based.dart:352:32)

2 _setupHostAttributes (package:polymer/src/common/polymer_descriptor.dart:160:18)

3 createPolymerDescriptor (package:polymer/src/common/polymer_descriptor.dart:32:3)

4 PolymerRegister.initialize (package:polymer/src/common/polymer_register.dart:19:36)

5 loadInitializers.. (package:initialize/src/static_loader.dart:46:32)

6 _runInitQueue (package:initialize/initialize.dart:35:24)

7 _runInitQueue. (package:initialize/initialize.dart:38:26)

8 _RootZone.runUnary (dart:async/zone.dart:1165)

9 _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:502)

10 _Future._propagateToListeners (dart:async/future_impl.dart:585)

11 _Future._completeWithValue (dart:async/future_impl.dart:376)

12 _Future._asyncComplete. (dart:async/future_impl.dart:430)

13 _microtaskLoop (dart:async/schedule_microtask.dart:43)

14 _microtaskLoopEntry (dart:async/schedule_microtask.dart:52)

15 _ScheduleImmediateHelper._handleMutation (dart:html:42565)

Memoryleak using Transformer when running pub serve

I'm currently running into a memory leak using pub serve.

The pubspec looks like this:

name: myapp
version: 0.0.1
description: Myapp.
dependencies:
  polymer: ^1.0.0
  polymer_elements: any
  web_components: ^0.12.0
  browser: any
  route_hierarchical: any
  protobuf: any
  uuid: any
  lawndart: any
  quiver: any
  reflectable: 0.2.0
transformers:
- web_components:
    entry_points:
    - web/index.html
#    - test/app_test.html
- reflectable:
    entry_points:
    - web/index.dart
#    - test/app_test.dart
- test/pub_serve:
    $include: test/**_test{.*,}.dart
- $dart2js:
    minify: false
    sourceMaps: true
    verbose: true
dev_dependencies:
  test: ^0.12.3
environment:
  sdk: ">=1.2.0 <2.0.0"
dependency_overrides:
  polymer:
    git:
      ref: behaviors
      url: https://github.com/dart-lang/polymer-dart.git
  polymer_interop:
    git:
      ref: 0.2.0-dev
      url: https://github.com/dart-lang/polymer_interop.git
  polymer_elements:
    git:
      ref: master
      url: https://github.com/dart-lang/polymer_elements.git
  reflectable:
    path: ../reflectable/reflectable

Im running this to prevent pub from taking all the memory available.

export DART_VM_OPTIONS=--observe
ulimit -Sv 4000000
pub serve --mode debug --hostname 0.0.0.0 --port 7080

I tried to find the reason using Observatory. The top classes from the allocation profile are

  • LinkEntry
  • _List
  • Context.

InstanceInvokeMetaCapability doesn't match meta which extends/implements specified classes

The implementation of metadataSupported doesn't match metadata which extends or implements the supported metadata, it only matches if the runtimeType exactly matches the type of the metadata:

/// Returns true iff an element of the [metadata] is supported by the
/// [capability].
bool metadataSupported(
    List<dm.InstanceMirror> metadata, MetadataQuantifiedCapability capability) {
  return metadata
      .map((dm.InstanceMirror x) => x.reflectee.runtimeType)
      .contains(capability.metadataType);
}

Transformer fails on polymer tests

I have a pull request here dart-archive/polymer-dart#540 which migrates polymer to the reflectable package. The transformer gets some errors though, so I won't be able to submit until those are resolved. The issue seems to happen when the transformer tried to get the metadata on fields in a class, stack trace below:

Build error:
Transform Reflectable on polymer|ReflectableTransformed threw error: The null object does not have a getter 'metadata'.

NoSuchMethodError: method not found: 'metadata'
Receiver: null
Arguments: []
dart:core-patch/object_patch.dart 42                             Object._noSuchMethod
dart:core-patch/object_patch.dart 45                             Object.noSuchMethod
package:reflectable/src/transformer_implementation.dart 1698:69  extractMetadataCode
package:reflectable/src/transformer_implementation.dart 372:24   ReflectorDomain.generateCode.<fn>
dart:_internal/iterable.dart 390                                 MappedIterator.moveNext
dart:core-patch/growable_array.dart 189                          List.addAll
package:reflectable/src/transformer_implementation.dart 397:9    ReflectorDomain.generateCode
package:reflectable/src/transformer_implementation.dart 45:24    ReflectionWorld.generateCode.<fn>
dart:_internal/iterable.dart 413                                 MappedListIterable.elementAt
dart:_internal/iterable.dart 148                                 ListIterable.join
package:reflectable/src/transformer_implementation.dart 1595:49  formatAsMap
package:reflectable/src/transformer_implementation.dart 43:12    ReflectionWorld.generateCode
package:reflectable/src/transformer_implementation.dart 1400:25  TransformerImplementation.reflectionWorldSource
package:reflectable/src/transformer_implementation.dart 1505:40  TransformerImplementation.apply.<async>
dart:async/zone.dart 1166                                        _RootZone.runUnary
dart:async/future_impl.dart 494                                  _Future._propagateToListeners.handleValueCallback
dart:async/future_impl.dart 577                                  _Future._propagateToListeners
dart:async/future_impl.dart 368                                  _Future._completeWithValue
dart:async/future_impl.dart 422                                  _Future._asyncComplete.<fn>
dart:async/schedule_microtask.dart 43                            _microtaskLoop
dart:async/schedule_microtask.dart 52                            _microtaskLoopEntry
dart:isolate-patch/isolate_patch.dart 96                         _runPendingImmediateCallback
dart:isolate-patch/isolate_patch.dart 149                        _RawReceivePortImpl._handleMessage

dart:core                                                        Object.noSuchMethod
package:reflectable/src/transformer_implementation.dart 1698:69  extractMetadataCode
package:reflectable/src/transformer_implementation.dart 372:24   ReflectorDomain.generateCode.<fn>
dart:core                                                        List.addAll
package:reflectable/src/transformer_implementation.dart 397:9    ReflectorDomain.generateCode
package:reflectable/src/transformer_implementation.dart 45:24    ReflectionWorld.generateCode.<fn>
dart:_internal                                                   ListIterable.join
package:reflectable/src/transformer_implementation.dart 1595:49  formatAsMap
package:reflectable/src/transformer_implementation.dart 43:12    ReflectionWorld.generateCode
package:reflectable/src/transformer_implementation.dart 1400:25  TransformerImplementation.reflectionWorldSource
package:reflectable/src/transformer_implementation.dart 1505:40  TransformerImplementation.apply.<async>
dart:isolate 

Suppress "unused import" warning when only using an import reflectively

Similar to:

@MirrorsUsed(...)
import 'dart:mirrors

I want to be able to do something like:

@myReflectable
import 'package:reflected_upon/reflected_upon.dart';

to avoid an "unused import" warning, when I only use package:reflected_upon/reflected_upon.dart reflectively. Is/will that be possible?

Update bootstrap logic to have `test` package support.

In order to write tests which are defined asynchronously, you need to return a future from main which doesn't complete until all tests have been set up. The current bootstrap logic for reflectable overwrites your main with a new one that has no return value here. The return type on main should be removed, and the original mains value should be returned, so roughly:

void main() {
  initializeReflectable();
  _main();
}

should become:

main() {
  initializeReflectable();
  return _main();
}

Cannot re-create default values.

With the interface the analyzer currently present us it is very difficult to reproduce a constant from the default value to a function parameter in generated code.

For a simplified example, given:

class A {
  A([a = XXXX]);
}

We would like to be able to produce:

newInstance(List arguments) {
  Function x = ([a = YYYY]) => new A(a);
  Function.apply(x, arguments);
}

Such that YYYY has the same value as XXXX.
For example if we have:

class A {
  static const c = 10;
  A([a = c]);
}

then letting YYYY = XXXX will fail.
This might be possible after a resolution of: dart-lang/sdk#17307.
When we have generalized tearoffs: dart-archive/dart_enhancement_proposals#3 this issue might disappear.

Transformer should process multiple entry-points even when it encounters errors

This issue was extracted from issue #37, submitted by @zoechi.

The issue is that the transformer stops with an error message whenever it encounters a program that contains constructs which prevent the transformation from being completed (e.g., if the super initializer in a subclass of class Reflectable passes a non-const argument), but it would be more useful if it were to emit the error message such that the programmer knows that one of the entry points could not be transformed (the error message should of course contain information about the location in the code that causes the transformation to stop), and then proceed to transform the remaining entry points.

Consider propertymirror type that wraps getter and setter methods

This is a follow up to #52 (comment)

When dealing with properties I find it quite awkward that getters and setters are only connected by name with setters being suffixed =. This naming link also appears - from a naive users POV - slightly inconsistent because I can set a property value using the name of the getter.

I know this is not a property of reflectable but since it wraps mirrors perhaps a nicer interface could be provided.

For instance if I want to find all read/write properties of an object I currently have to do something like this:

  Set<String> getReadWritePropertiesUsingInstanceMembers(Object object) {
    final members = reflector.reflect(object).type.instanceMembers;
    return members.values
        .where((MethodMirror method) => method.isGetter)
        .map((DeclarationMirror getter) => getter.simpleName)
        .where((simpleName) => members.containsKey('$simpleName='))
        .toSet();
  }

It would be nifty if a PropertyMirror subtype of MethodMirror existed and wrapped access to both getter and setter. With this I could do something like:

  Set<String> getReadWritePropertiesUsingInstanceProperties(Object object) {
    final properties = reflector.reflect(object).type.instanceProperties;
    return properties.values
        .where((PropertyMirror property) =>
            property.canRead && property.canWrite)
        .map((DeclarationMirror property) => property.simpleName)
        .toSet();
  }

Empty `staticMembers`

We got reports about staticMembers returning the empty list in a case where there are actually several static members; apparently, the expected mirrors are available if an instanceInvokeCapability is included, which would be a bug because that area is covered by various kinds of StaticInvokeCapability. Details are currently being exchanged via email.

Private members no way to implement, or is there

I am looking at doing this in a library I maintain. The solution I was thinking of using was adding accessor proxys to the library files that contain the private members there for making them usable. Would this be appropriate for this package.

Obviously this would be done using a transformer.

Make names of generated classes unique.

Currently if we have

@MyReflectable
@MyReflectable2
class A{}

We will generate two classes called Static_A_InstanceMirror and 2 called Static_A_ClassMirror.
Also two classes with the same name in different libraries give rise to a clash.
They should have globally unique names.
Perhaps something like MyReflectable2_liba_A_InstanceMirror.

Exception on method when name is "registered"

I'm not sure if this is a Polymer or Reflectable issue.

When an event handler is named registered

@PolymerRegister('some-element')
class SomeElement extends PolymerElement {
  SomeElement.created() : super.created();

  @reflectable
  void registered(dom.CustomEvent event, [_]) {...}
  // any other name than registered works just fine
}

See also http://stackoverflow.com/questions/33342798/how-do-you-listen-for-custom-events-in-polymer-dart-1-0/33342934#33342798

Observatory listening at http://127.0.0.1:46104/
Exception: Uncaught Error: Unhandled exception:
Reflecting on un-marked type 'JsObjectImpl'

0 _InstanceMirrorImpl._InstanceMirrorImpl (package:reflectable/src/reflectable_transformer_based.dart:150:9)

1 ReflectableImpl.reflect (package:reflectable/src/reflectable_transformer_based.dart:1216:16)

2 _setupReflectableMethods.. (package:polymer/src/common/polymer_descriptor.dart:151:49)

3 JsObject._callMethod (dart:js:678)

4 JsObject.callMethod (dart:js:618)

5 PolymerRegister.initialize (package:polymer/src/common/polymer_register.dart:19:13)

6 loadInitializers.. (package:initialize/src/static_loader.dart:46:32)

7 _runInitQueue (package:initialize/initialize.dart:35:24)

8 _runInitQueue. (package:initialize/initialize.dart:38:26)

9 _RootZone.runUnary (dart:async/zone.dart:1165)

10 _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:502)

11 _Future._propagateToListeners (dart:async/future_impl.dart:585)

12 _Future._completeWithValue (dart:async/future_impl.dart:376)

13 _Future._asyncComplete. (dart:async/future_impl.dart:430)

14 _microtaskLoop (dart:async/schedule_microtask.dart:43)

15 _microtaskLoopEntry (dart:async/schedule_microtask.dart:52)

16 _ScheduleImmediateHelper._handleMutation (dart:html:42565)

Stack Trace:

0 JsObject._callMethod (dart:js:678)

1 JsObject.callMethod (dart:js:618)

2 PolymerRegister.initialize (package:polymer/src/common/polymer_register.dart:19:13)

3 loadInitializers.. (package:initialize/src/static_loader.dart:46:32)

4 _runInitQueue (package:initialize/initialize.dart:35:24)

5 _runInitQueue. (package:initialize/initialize.dart:38:26)

6 _RootZone.runUnary (dart:async/zone.dart:1165)

7 _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:502)

8 _Future._propagateToListeners (dart:async/future_impl.dart:585)

9 _Future._completeWithValue (dart:async/future_impl.dart:376)

10 _Future._asyncComplete. (dart:async/future_impl.dart:430)

11 _microtaskLoop (dart:async/schedule_microtask.dart:43)

12 _microtaskLoopEntry (dart:async/schedule_microtask.dart:52)

13 _ScheduleImmediateHelper._handleMutation (dart:html:42565)

NPE in ClassMirror.instanceMembers unless every immediate subclass is marked for reflection or superclassQuantifyCapability is specified

This one had me scratching my head for a while.

Given the capabilities instanceInvokeCapability, metadataCapability, nameCapability and the class C extending class B that extends class A where class C is annotated with my capability spec I get an NPE in javascript when I do:

final members = myReflectionCapability.reflect(instanceOfClassC).type.instanceMembers;

The error occurs in the _variableMirror getter here because _variableMirrorIndex is null.

abstract class ImplicitAccessorMirrorImpl extends _DataCaching
    implements MethodMirror {
  final ReflectableImpl _reflector;
  final int _variableMirrorIndex;
  final int _reflectedTypeIndex;
  final int _dynamicReflectedTypeIndex;

  /// Index of this [ImplicitAccessorMirrorImpl] in `_data.memberMirrors`.
  final int _selfIndex;

  VariableMirrorImpl get _variableMirror =>
      _data.memberMirrors[_variableMirrorIndex];

  ImplicitAccessorMirrorImpl(
      this._reflector,
      this._variableMirrorIndex,
      this._reflectedTypeIndex,
      this._dynamicReflectedTypeIndex,
      this._selfIndex);

  int get kind => constants.kindFromEncoding(_variableMirror._descriptor);

This is the stacktrace from Chrome

2015-12-04 14:01:17.320 [FINER]  [HistoryManager] Reflecting on ServiceList
js_primitives.dart:31 Invalid argument (index): null

STACKTRACE:
Invalid argument (index): null
    at dart.wrapException (http://localhost:2001/main.dart.js:3414:17)
    at dart.ioore (http://localhost:2001/main.dart.js:3362:15)
    at ImplicitGetterMirrorImpl.dart.ImplicitGetterMirrorImpl.get$simpleName (http://localhost:2001/main.dart.js:49701:20)
    at NonGenericClassMirrorImpl.dart.ClassMirrorBase.get$instanceMembers (http://localhost:2001/main.dart.js:49446:51)
    at _ComponentReflector.dart._ComponentReflector.getStatefulProperties$1 (http://localhost:2001/main.dart.js:70686:101)
    at HistoryManager.dart.HistoryManager._handleComponentAttach$1 (http://localhost:2001/main.dart.js:70483:47)
    at HistoryManager__addEventListeners_closure.dart.HistoryManager__addEventListeners_closure.call$1 (http://localhost:2001/main.dart.js:70535:55)
    at ScopeStreamSubscription.dart.ScopeStreamSubscription._core_internal$_onData$1 (http://localhost:2001/main.dart.js:13733:44)
    at ScopeStream.dart.ScopeStream._fire$1 (http://localhost:2001/main.dart.js:13659:28)
    at dart._Streams.static._Streams_emit (http://localhost:2001/main.dart.js:13527:24)

If I add superclassQuantifyCapability it works but this seems like a bug because I actually only want to reflect on C.

The error also does not occur or cause any warning in the VM. Also it doesn't occur if I leave out class A, meaning that it's just C extending B or if I add my reflection annotation to B.

Reflecting on fields in a space efficient way

Is there a way to reflect on the fields of an instance without ballooning the size of the app? I'm using the declarationsCapability and instanceInvokeCapability and I'm seeing about 30kb increase of minified JS for a single reflected class.

Looking through the generated JS, it seems like it includes the type info for the instance's fields, those type's fields, and so on. I really don't care about the type info. I just want to iterate over the instance's fields and query their values.

Public fixnum field on PolymerElement causes reflectable to fail.

If you have a PolymerElement that contains a field with a type from the fixnum package like:

Int64 lastMessageId = Int64.ZERO;

the reflectable transformation fails with a message like

[Warning from Dart2JS]:
web/index.dart:34:3:
Cannot resolve getter.
  _initializeReflectable();
  ^^^^^^^^^^^^^^^^^^^^^^

If you "hide" the field from the outside like this:

Int64 _lastMessageId = Int64.ZERO;

it works. ;)

I could reproduce this by adding the above field to TodoList class of https://github.com/dart-lang/sample-todomvc-polymer/tree/polymer-0.17-behaviors and run pub build

Im using the latest reflectable, polymer and Dart VM version: 1.12.0 (Mon Aug 31 03:24:52 2015) on "linux_x64"

The null object does not have a getter 'parameters'

When running the latest reflectable transformer on my project I got this exception:

Build error:
Transform Reflectable on test|ReflectableTransformed threw error: The null object does not have a getter 'parameters'.

NoSuchMethodError: method not found: 'parameters'
Receiver: null
Arguments: []
dart:core-patch/object_patch.dart 42                             Object._noSuchMethod
dart:core-patch/object_patch.dart 45                             Object.noSuchMethod
package:reflectable/src/transformer_implementation.dart 1776:39  TransformerImplementation._generateNewEntryPoint
package:reflectable/src/transformer_implementation.dart 1877:11  TransformerImplementation.apply.<async>
dart:async/zone.dart 1166                                        _RootZone.runUnary
dart:async/future_impl.dart 494                                  _Future._propagateToListeners.handleValueCallback
dart:async/future_impl.dart 577                                  _Future._propagateToListeners
dart:async/future_impl.dart 368                                  _Future._completeWithValue
dart:async/future_impl.dart 422                                  _Future._asyncComplete.<fn>
dart:async/schedule_microtask.dart 43                            _microtaskLoop
dart:async/schedule_microtask.dart 52                            _microtaskLoopEntry
dart:isolate-patch/isolate_patch.dart 96                         _runPendingImmediateCallback
dart:isolate-patch/isolate_patch.dart 149                        _RawReceivePortImpl._handleMessage

dart:core                                                        Object.noSuchMethod
package:reflectable/src/transformer_implementation.dart 1776:39  TransformerImplementation._generateNewEntryPoint
package:reflectable/src/transformer_implementation.dart 1877:11  TransformerImplementation.apply.<async>

I'm using the latest git commit #f130cb6486f221e7a1907d9d3e5a642095b1e671 and Dart VM version: 1.12.0 (Mon Aug 31 03:24:52 2015) on "linux_x64"

transformer implementation of invokeSetter throws NoSuchCapability error instead of NoSuchMethod error

For instance, given the following app:

import 'package:reflectable/reflectable.dart';

class MyReflectable extends Reflectable {
  const MyReflectable()
      : super(instanceInvokeCapability);
}

@MyReflectable()
class MySimpleClass {
  String get message => 'hello';
}

main() {
  var instance = new MySimpleClass();
  var instanceMirror = myReflectable.reflect(instance);
  instanceMirror.invokeSetter(r'message', 'world');
}

The mirrors based implementation will correctly throw a NoSuchMethod error, but the transformer based implementation will incorrectly throw a NoSuchCapability error.

Cannot reflect upon closures

The Dart language provides no support for identifying closures with a statically known type using standard reflection-free constructs. This means that we cannot create and return a suitable mirror for any given closure in transformed code, i.e., reflect cannot return a ClosureMirror in transformed code.

Similarly, we have not implemented support for FunctionTypeMirror in transformed code. We could implement some level of support , but function type mirrors would not be very useful when there are no closure mirrors.

This issue has existed from the beginning of the development of this package, and we will need extra support from the underlying platforms in order to resolve it. Hence, it is not expected that this issue will go away soon.

Support use of reflectable in packages.

If we have a package e.g. serialize defining class Serializable extends Reflectable
And another package imports this package and annotating its own classes @Serializable() class A {}. The transformer needs to know about class A when it transforms serializable.
This is currently very hard given the way transformers work.

Support annotation on imports or library deffinition

It would be great if it was possible to add an annotation to an import or library definition to make it possible to serialize all classes in that library.

I tend to stuff all my entity classes into a single library and it's unnecessary tedious to place an annotation over all classes in that library.

Github URL invalid?

Hi,

Seems like the github URL specified on the pub page is invalid (https://www.github.com/dart-lang/reflectable/reflectable). It gives me a 404 right now. Also the pubspec.yaml file in reflectable refers to this URL.

When I try running pub get with reflectable: "^0.1.4" in my pubspec.yaml, I get this error:

Package reflectable has no versions that match >=0.1.4 <0.2.0 derived from:

  • myproject depends on version ^0.1.4

I'm using version 1.12.1. These issues are maybe related?

Best regards,
Adam

Capability: Access metadata

For dart2js there will be the desire to control which metadata is retained. The most useful way to filter is probably by the Type of the metadata items.

I am particularly hoping that doc-comments can be encoded as metadata as well, see:

http://dartbug.com/15704

So I could specify I want to retain Comments for example.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.