Comments (9)
Unfortunately it doesn't seem possible to change the .constructor
property of a function or the .name
property of a constructor, so we might be out of luck here. Where have you seen this test in the wild?
from regenerator.
Unfortunately it doesn't seem possible to change the
.constructor
property of a function or the.name
property of a constructor, so we might be out of luck here.
While we can't update name
on a function, we can luckily definitely set the constructor
on a function object. To wit:
$ node
> function test () {}
// original constructor is Function
> test.constructor
[Function: Function]
// create a polyfill faux GeneratorFunction constructor
> function GeneratorFunction () {}
// set constructor to polyfill
> test.constructor = GeneratorFunction
[Function: GeneratorFunction]
// test.constructor.name is now the expected value, and will pass isGeneratorFunction()
> test.constructor.name
'GeneratorFunction'
Where have you seen this test in the wild?
The generator flow control library co
: https://github.com/visionmedia/co/blob/c247a120e34c147b28119c732e550836e3477660/index.js#L201-L211
You can see above that the same technique is used to detect Generator instances, and that works great with regenerator at the moment. The fact that the isGeneratorFunction
is failing is causing 4 of the co tests to fail, whereas they pass using the --harmony_generators
flag in node.
from regenerator.
That said, my proposal (and I know the extra boilerplate here kinda sucks), is to wrap the function in an immediately invoked function, so that we can have a closure around the transpiled function, and then set the constructor
property before returning.
So some ES6 code like this:
co(function *() {
})();
Would turn into this (extra whitespace added for readability):
co( (function() {
var fg = function() {
return wrapGenerator(function($ctx) {
while (1) switch ($ctx.next) {
case 0:
return $ctx.stop();
}
}, this);
};
// here's the crucial part: we overwrite the original `constructor` property with
// one defined in the runtime, perhaps exposed as `wrapGenerator.GeneratorFunction`…
fg.constructor = wrapGenerator.GeneratorFunction;
return fg;
})() )();
Thoughts?
edit: fixed syntax errors in example output
from regenerator.
I agree that the boilerplate is less than ideal, but I also think it would be worth it.
The part I'm struggling with right now is what to do about named function declarations. Right now, their behavior is pretty simple because a generator function declaration just becomes a normal function declaration with the same name. That seems more tricky when the function is created inside a closure, because you'd have to assign the function to a variable of the same name in the outer scope before any other statements, in case those earlier statements refer to the declared function by name.
I'm going to keep thinking about it. Maybe there's a way to implement isGeneratorFunction
that's easier to cooperate with, and we could persuade @visionmedia to adopt that instead.
from regenerator.
I have come up with a hacky, regenerator-aware isGeneratorFunction()
, but I can almost promise that TJ would never merge it upstream ;) Essentially it's toString()
ing the argument and checking the function source for the "wrapGenerator" function.
function isGeneratorFunction(obj) {
// the "function" typeof test is required to filter out false-positives from
// the toString() hack below, when obj is an Array
if ('function' != typeof obj) return false;
// "offically" sanctioned check...
if (obj.constructor && 'GeneratorFunction' == obj.constructor.name) return true;
// hacky check for facebook/regenerator
if ((String(obj).indexOf('wrapGenerator(') != -1) return true;
return false;
}
This makes the co
test cases pass 100% for me using node v0.10.21 which is using regenerator under the hood.
from regenerator.
What if the runtime added
Function.prototype.markGenerator = function() {
this.constructor = GeneratorFunction;
return this;
};
And then generator function expressions like function *gen() {}
became the expression function gen() { ... }.markGenerator()
and function declarations of the same form became
gen.markGenerator(); // At beginning of scope where gen is defined.
...
function gen() { ... }
That saves some boilerplate, at least (and we could use an even shorter name than markGenerator
).
from regenerator.
If that's possible then I think it would be awesome!
I'd recommend prefixing the name of the function though, since augmenting the Function.prototype
could upset some people. Perhaps _regenMark()
or something less likely to ever collide.
I would love to see this happen!
from regenerator.
Please don't add stuff to Function.prototype
for making generated code pretty. Just use wrapGenerator.markGenerator(gen)
// function declarations
wrapGenerator.markGenerator(gen); // At beginning of scope where gen is defined.
...
function gen() { ... }
// function expressions
wrapGenerator.markGenerator(function gen() { ... })
from regenerator.
@Raynos +1
from regenerator.
Related Issues (20)
- Runtime - Transformation of async/await try...catch prevents inspecting variable defined in catch statement
- Is the copyright @ 2013 kept knowingly or it should be changed every year like other Open Source projects of Facebook?
- "The Function constructor is eval" warning from Mozilla Addons Linter HOT 2
- regeneratorRuntime is not defined on cli
- Minified Error, do you have minified version of it?
- Problem on both using Babel babel/plugin-transform-classes and regenerator for async class methods
- Question: why isn't the minified version of regenerator runtime published?
- docs: NPM package `regenerator-runtime` registry repository link broken
- runtime.js should read Symbol values dynamically HOT 1
- Not able to update the chrome version to 58.
- Latest version error HOT 5
- Crashes when processing sparse array with `await`
- regenerator-runtime new version 0.13.11 not tagged as latest HOT 1
- I need to delete this issue
- Sandbox bug report
- Sandbox bug report
- Compile to pure function
- What changed in version 0.14.0? HOT 2
- `npm deprecate` regenerator-runtmie@<0.13.8 HOT 2
- Generator spec reference link is outdated in `runtime.js` file
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 regenerator.