- From: Boris Zbarsky <notifications@github.com>
- Date: Thu, 22 Dec 2016 10:25:09 -0800
- To: heycam/webidl <webidl@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <heycam/webidl/issues/188/268860016@github.com>
> How does it deal with circular references, if at all? However JSON.stringify normally does. All the "jsonifier" thing does is expose a toJSON function that gets called from that algorithm. In practice, circular references throw. > What's the precise inheritance story? Fwiw, I think I covered this in the description of the algorithm.... ;) > Which of the following would JSON.stringify(new B()); return? {"foo": "..."} Well it would if you put a [Constructor] on `B` . As things stand, it throws on `new B()`. > Which of the following would JSON.stringify(new C()); return? {"foo": "..."} A more interesting example is this: [Constructor] interface A { attribute DOMString foo; jsonifier; } [Constructor] interface B : A { attribute DOMString foo; jsonifier; } In this case, the value for "foo" would be the one from B, not from A. > What would be the interaction with actual toJSON operations found in the inheritance tree? That's a good question. I don't see any way to make these play nice together: toJSON can return primitives, but `jsonifier` really needs an object to define properties on. In practice, if you want custom serialization behavior on an interface, it doesn't make much sense to define "default" serialization behavior on descendant interfaces. We could just make that invalid IDL. > Could we instead imagine having a default algorithm for toJSON operations > (that would return all own and inherited serializable attributes) but that > could be overridden in prose? We could imagine it, but it's a bit less useful to me as a UA implementor, because "overridden in prose" is not expressed in IDL, so I have no way to know whether my binding generator should generate and use the default algorithm or not, short of annotating the IDL with that information. At which point we've basically pushed the problem over to one of having `[DefaultBehavior] object toJSON()` instead of `jsonifier` or whatnot. Apart from not having the cognitive overhead of extra syntax, what is the win? > JSON.stringify(new C()); would return: Why would it do any such thing? Why should the toJSON method on A know anything about attributes of descendant interfaces? > Is this actually useful? Probably not; it's not used in practice in Gecko. It happened to be simple to implement in Gecko: the binding generator for an interface with a jsonifier generates a method to stick the properties on an object, and descendant interfaces can call that method if they want. Your approach means that the binding generator for an interface has to check whether any descendants have a jsonifier and generate the method based on that more-global information. It's doable, but quite a bit more annoying to implement (e.g. in terms of getting build-system dependencies right, etc), which is why I didn't do it that way. Alternately, we could just forbid interfaces with a jsonifier from having a parent with no jsonifier or something. That adds more coupling between specs if spec X extends an interface from spec Y and wants X to be serializable, but maybe that's ok... Then again, given how W3C specs work maybe this is a terrible idea. > or you can call some helper abstract op we define in Web IDL that gives you some kind of "serialize all attributes" behavior As I said above, that's probably fine in terms of spec factoring, but may complicate implementation, because that helper may be quite hard to implement generically in an automated way (and half the point here is to have this be automated, so people don't screw up things like adding a new attribute but not adding it to the serializer). Certainly I'd want a way to express the "use the helper" bit in IDL for Gecko's purposes, but I can just use an extended attribute for that. > I don't think we need the ability for each link in the inheritance chain to opt-in I agree. > the spec doesn't currently seem clear on whether the default serializer observably does a Get(this, "attributeName") or not Indeed. Fwiw, in Gecko we call the default getter directly. -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/heycam/webidl/issues/188#issuecomment-268860016
Received on Thursday, 22 December 2016 18:25:36 UTC