dart-archive / smoke

Smoke is a Dart package that exposes a reduced reflective system API. This API includes accessing objects in a dynamic fashion (read properties, write properties, and call methods), inspecting types (for example, whether a method exists), and symbol/string convention.
https://pub.dartlang.org/packages/smoke
BSD 3-Clause "New" or "Revised" License
12 stars 3 forks source link

allow to add extra information from code or as a separate transformer #10

Open DartBot opened 9 years ago

DartBot commented 9 years ago

Issue by jolleekin Originally opened as dart-lang/sdk#19875


I was trying to bind the text of a button to a resource string. nodeBind(button.firstChild).bind('text', 'resources.commands.save');

This in turn creates a PathObserver, which then creates a PropertyPath. PropertyPath uses smoke.nameToSymbol to convert each path segment into a Symbol.

The created PropertyPath was expected to have 3 symbols: #resources, #commands, and #save, but it actually contained #resources, null, and null.

Before transformation, smoke.nameToSymbol uses new Symbol(name); however, after transformation, smoke.nameToSymbol calls GeneratedSymbolConverterService.nameToSymbol, which uses a symbol cache. The cache didn't contain #commands and #save, so nodeBind failed.

/// Implements [SymbolConverterService] using a static configuration. class GeneratedSymbolConverterService implements SymbolConverterService {   Map<Symbol, String> _names;

  /// A map from strings to symbols (the reverse of [names]).   final Map<String, Symbol> _symbols;

  GeneratedSymbolConverterService(StaticConfiguration configuration)       : _names = configuration.names,         _symbols = {} {     _names.forEach((k, v) { _symbols[v] = k; });   }

  String symbolToName(Symbol symbol) => _names[symbol];   Symbol nameToSymbol(String name) => _symbols[name]; }

DartBot commented 9 years ago

Comment by sigmundch


The problem is that all these bindings and PathObservers are actually reflective. We use smoke as a library that implements the reflective API. When you run in Dartium, this API is implemented with dart:mirrors, but when you build the app with the polymer transformers, we replace the use of mirrors with generated code to help dart2js optimize your app.

To generate the code we need, the polymer transformers parse your app and discover every expression in a template, among other things. Expressions within Dart code, like your example above, are not discovered so we don't know how to generate code for them. That's basically why there is no entry for #commands or #save.

In the future I'd like to add the option of adding your own transformer phase that tells smoke to generate some extra symbols and such, but this is not available today. I'll keep this bug open to track this.

Meanwhile, the best way to work around this issue is to make sure those symbols are mentioned in your HTML templates somewhere. It should be enough to define a polymer-element element whose template uses those symbols (even if the element is not used anywhere).


Removed Priority-Unassigned label. Added Priority-Medium, Pkg-Smoke, Area-Pkg, Polymer-P-1, Triaged labels.

DartBot commented 9 years ago

Comment by sigmundch


This might need the same changes we need to fix issue #8, though.


Marked this as being blocked by #8. Changed the title to: "allow to add extra information from code or as a separate transformer".

DartBot commented 9 years ago

Comment by sigmundch


Removed Polymer-P-1 label. Added Polymer-Milestone-Next label.