Comments (13)
Awesome, thanks Greg! We definitely had libraries like mustache in mind. :)
from reflectable.dart.
Assuming that @mustache can be an instance of a subclass of Reflectable, class Bar is already marked for reflective use. With that, the following should be very near to working code (PS: to be implemented! -- but plausible):
var instance = mustache.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.invokeGetter(field.simpleName);
} else if ((field is MethodMirror) && (field.parameters.length == 0)) {
invocation = instance.invoke(field.simpleName, []);
}
if (invocation == null) {
return _noSuchProperty;
}
return invocation.reflectee;
The use of new Symbol(name)
is not good, this may cause problems during compilation (esp. for minification), but for the given purpose it might be possible to use const Symbol(_)
?
The names VariableMirror, MethodMirror, etc., have a different meaning, because they will be the classes defined in package:reflectable/mirrors.dart
rather than the ones from dart:mirrors (but they are by design identical, except for a couple of details that mark a desired development of dart:mirrors: for instance getField
will be renamed to invokeGetter
and getField
is @deprecated in Reflectable).
So, with the current plans for Reflectable the above should not be too hard (except for that new symbol, which is a general issue rather than a Reflectable problem).
from reflectable.dart.
Thanks for the update ;)
The use of new Symbol(name) is not good
Agreed, but this is required if the name of the symbol comes from template source code which is not statically known at compile time.
For templates which are known at compile time, I could potentially write a transformer which pulls out the symbol names ahead of time - though this would break some of the more obscure dynamic features of mustache.
I think in reality it would probably be better if the user of the mustache library was able to annotate the classes they passed to mustache to omit unneeded fields/methods. Other options to reduce compile size would be for the end-user to make a wrapper class containing only the fields accessed by the template, or passing all of the data in a map.
from reflectable.dart.
.. I'm gathering info about new Symbol(..), will return when I have it ..
from reflectable.dart.
.. I'm gathering info about new Symbol(..), will return when I have it ..
nice! Ideally, new Symbol
is fine, because the set of names that make sense to reflect on is constrained by Reflectable's capabilities. If I don't have capability to reflect on something, then dart2js can freely rename those identifiers in those classes/libraries, regardless of any new Symbol(str)
in the code. But if I have marked something @mustache
then it probably can't rename things mustache
can access.
from reflectable.dart.
If 'the set of names that make sense to reflect on is constrained by Reflectable's capabilities' then it should be possible to rely on 'const Symbol(..)' only, because Reflectable will only reflect on a class if it is statically known to require that capability, and only on names declared in that class or reachable through static analysis from there: All static information. With 'const Symbol(..)', the problem is gone.
About renaming: That sounds like minification, which was also the first thing I mentioned. But I still expect to hear more about the real issues, which may or may not be minification.
from reflectable.dart.
consider example from the start of the thread:
var template = new Template('{{ foo }}');
var output = template.renderString(new Bar()); // output = 42
@mustache
class Bar {
get foo => 42;
}
@mustache
uses new Symbol
in its implementation. However, the set of reflectable names is only "foo". I'm arguing that new Symbol
is fine to use in @mustache
implementation.
One thing that might help Reflectable is if it made the symbols itself:
var instance = mustache.reflect(object);
var field = instance.type.instanceMembers[mustache.newSymbol(name)];
if (field == null) return _noSuchProperty;
// ... code from before ...
Not sure if that helps you, but you can now tell that "name" is only one of the things the mustache
constant is reflecting on.
from reflectable.dart.
(maybe we're totally agreeing and I just misunderstood, which is common. In which case, I apologize in advance :) )
from reflectable.dart.
I think we agree pretty much. ;) But, specifically about the
predictability of the value of name
: How do you know that there won't be
assignments to innerHTML
somewhere in a polymer context, such that you
end up with new Symbol(name)
where name == "someOtherString"
? This is
probably not relevant for the mustache library in isolation, but I'm sure
it could pop up in polymer, and it's in general a very interesting problem:
Maybe there are some specific kinds of dynamism causing massive size or
speed penalties that are not actually required? In that case I would like
to be able to add some extra constraints in specific contexts, such that we
could get a good size/speed performance, and then programmers using it
would just have to avoid some excessively dynamic constructs. They might
not need them at all, at least if they make a habit of finding more static
alternatives.
By the way, I still haven't gotten a clear explanation about why new Symbol(_)
would be so expensive in a system where dart:mirrors
is not
imported, but it is obviously necessary to somehow retain the source level
name and a mapping to the "compiled name" of anything that you want to
reflect over (using any kind of reflection support, including Reflectable),
and minification is a typical example of a transformation that introduces
such "complied names".
from reflectable.dart.
Two crucial situations for new Symbol(..)
are noSuchMethod
and dart:mirrors. If a comparison is made in an implementation of noSuchMethod
using a new Symbol(..)
in order to do something specific when a specific method is called (say, methodWithLongName
), then we must be able to perform the same mapping that was done by minification. So if methodWithLongName
was minified to iA
then the Invocation
provided as an argument to noSuchMethod
will contain #iA
and a comparison with #methodWithLongName
will yield false even though it is the right method. So we need to translate the string 'methodWithLongName'
dynamically to 'iA'
before we create the new symbol and compare the two. This can only be done if we know something about the mapping done by minification, and in general we need to know the entire mapping---which will to some extent undo the effect of minification in the first place. A similar situation arises if we wish to create a new Symbol(..)
and then use that with instanceMirror.invoke
or a similar feature in dart:mirrors.
The real danger as that we "only need one dynamic symbol", but then the compiled output grows substantially because we are forced to provide a minification mapping for every symbol/identifier in the program.
from reflectable.dart.
[...] In that case I would like
to be able to add some extra constraints in specific contexts, such that we
could get a good size/speed performance, and then programmers using it
would just have to avoid some excessively dynamic constructs. They might
not need them at all, at least if they make a habit of finding more static
alternatives.
Ah, thanks for writing that. Yeah makes sense and totally agree.
The real danger as that we "only need one dynamic symbol", but then the compiled output grows substantially because we are forced to provide a minification mapping for every symbol/identifier in the program.
Interesting. Would it help if reflectable had a different kind of Symbol? Since mustache
is using new Symbol
, but they aren't going to compare it against a noSuchMethod Symbol, it would maybe be nice if there was a way to communicate that to the compiler.
from reflectable.dart.
I thought the point of Reflectable was that we would say for which classes
we need this information. So if I've said that my class is Reflectable in
the names of attributes, then creating symbols for those attributes
dynamically from the content of the HTML file shouldn't affect size. I've
told it I want exactly the names of the things in the classes I've
annotated.
It does mean that I can't reduce those names further, but that's presumably
a very small saving.
On Fri, Mar 13, 2015 at 1:01 PM John Messerly [email protected]
wrote:
[...] In that case I would like
to be able to add some extra constraints in specific contexts, such that we
could get a good size/speed performance, and then programmers using it
would just have to avoid some excessively dynamic constructs. They might
not need them at all, at least if they make a habit of finding more static
alternatives.Ah, thanks for writing that. Yeah makes sense and totally agree.
The real danger as that we "only need one dynamic symbol", but then the
compiled output grows substantially because we are forced to provide a
minification mapping for every symbol/identifier in the program.Interesting. Would it help if reflectable had a different kind of Symbol?
Since mustache is using new Symbol, but they aren't going to compare it
against a noSuchMethod Symbol, it would maybe be nice if there was a way to
communicate that to the compiler.—
Reply to this email directly or view it on GitHub
#1 (comment).
from reflectable.dart.
On Fri, Mar 13, 2015 at 9:01 PM, John Messerly [email protected]
wrote:
[...]
The real danger as that we "only need one dynamic symbol", but then the
compiled output grows substantially because we are forced to provide a
minification mapping for every symbol/identifier in the program.Interesting. Would it help if reflectable had a different kind of Symbol?
Since mustache is using new Symbol, but they aren't going to compare it
against a noSuchMethod Symbol, it would maybe be nice if there was a way to
communicate that to the compiler.We actually discussed exactly that idea recently, and we may actually end
up doing something like that, or even using strings rather than symbols (so
we'd have a String as the first argument to 'invoke', etc.). The trade-off
to consider is that canonicalized "string-like" values are cheap to
compare, but canonicalization has a similar cost as one string comparison
in the first place.
best regards,
Erik Ernst - Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 København K, Denmark
CVR no. 28866984
from reflectable.dart.
Related Issues (20)
- Depth of Reflection HOT 4
- How to check declaration value type? HOT 2
- running in web / debug causes a reflection exception before loading HOT 3
- Bug: Reflectable doesn't work with latest analyzer 4.4.0 package HOT 3
- sdk minimal version should be 2.17.0 HOT 1
- Get annotation from enum field HOT 2
- Fails when upgrading
- 【macos】Attempt to `invoke` without class mirrors. HOT 1
- [Question] is it possible build an "Angular Style DI" library using Reflectable? HOT 1
- [question] - Is it possible to have Annotations with Parameters? HOT 2
- [Question] - how to get Constructor arguments? HOT 2
- [Bug?] ERROR: This requires the 'constructor-tearoffs' language feature to be enabled. HOT 12
- [Question] - Listening to Method invocation HOT 6
- [Question] - Stats on Bundle Sizes and Performance Implications/metrics of using Reflectable ? HOT 1
- Cannot reflect ```flutter/material.dart``` URIs for ```Container``` type HOT 12
- This reflector does not match anything HOT 11
- Reflectable is not a know builder HOT 1
- Unsupported operation: location HOT 4
- Reflectable don't find "main" but im using in my library not an application HOT 5
- How to generate code according to filter rules HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from reflectable.dart.