-
Notifications
You must be signed in to change notification settings - Fork 163
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add [LegacyNamespace] to allow defining an interface in a namespace #425
Conversation
This is just a first pass; I'd be interested in any feedback you might have. cc @domenic . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A number of nits, but overall this seems good.
I'm on the fence as to whether we should add some sort of usage note, along the lines of "most places in the platform don't do this; maybe check first, and don't go crazy using it everywhere."
index.bs
Outdated
|
||
If the [{{InNamespace}}] [=extended attribute=] appears on an [=interface=], it indicates that | ||
the [=interface object=] for this interface will not be created as a property of the global | ||
object, but rather the namespace which is the argument to the extended attribute. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"but rather as a property of" is clearer, I think
"namespace identified by the argument", I think
[=namespace=]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
index.bs
Outdated
The [=class string=] of an interface with the [{{InNamespace}}] extended | ||
attribute is the concatenation of the class string of the namespace, <code>"."</code>, | ||
and the class string that the interface would otherwise have without this | ||
extended attribute. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should not be located here but instead be a modification to
The class string of a platform object that implements one or more interfaces must be the identifier of the primary interface of the platform object.
Also, no <code>
around strings in Web IDL, it appears.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
index.bs
Outdated
@@ -12516,6 +12558,10 @@ The characteristics of a namespace object are described in [[#namespace-object]] | |||
1. Let |F| be the result of [=creating an operation function|creating an operation function=] | |||
given |op|, |namespace|, and |realm|. | |||
1. Perform [=!=] [=CreateDataProperty=](|namespaceObject|, |op|'s [=identifier=], |F|). | |||
1. For each [=exposed=] [=interface=] |intr| which has the [{{InNamespace}}] extended attribute, with the identifier of this namespace as its argument, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrap to 100 chars here too
[=identifier=]
Just interface instead of intr is nicer, I think.
No comma before "with", I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
index.bs
Outdated
@@ -12516,6 +12558,10 @@ The characteristics of a namespace object are described in [[#namespace-object]] | |||
1. Let |F| be the result of [=creating an operation function|creating an operation function=] | |||
given |op|, |namespace|, and |realm|. | |||
1. Perform [=!=] [=CreateDataProperty=](|namespaceObject|, |op|'s [=identifier=], |F|). | |||
1. For each [=exposed=] [=interface=] |intr| which has the [{{InNamespace}}] extended attribute, with the identifier of this namespace as its argument, | |||
1. Let |I| be the [=interface object=] for |intr|. | |||
1. Let |newDesc| be the PropertyDescriptor{ \[[Writable]]: <emu-val>true</emu-val>, \[[Enumerable]]: <emu-val>false</emu-val>, \[[Configurable]]: <emu-val>true</emu-val>, \[[Value]]: |I| }. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like at this point we don't put spaces after { and before } in Web IDL.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Thanks for the PR! A comment and some bikeshedding. My understanding was the wanted to avoid such constructs in favor of waiting for modules instead, but maybe things have changed? If we do go this route though, shouldn't we go for dedicated syntax here instead of (ab)using extended attributes? E.g.: something like: namespace Foo { };
interface Foo.Bar {
};
interface Foo.Baz : Foo.Bar {
}; And if we do choose extended attributes, maybe |
I know @rwaldron is going to jump on this. |
I would definitely prefer @tobie's syntax. |
My thinking for advising @littledan to go with this instead of new syntax is that we already use extended attributes to control what gets exposed for a given interface (viz. [NamedConstructor], [NoInterfaceObject], and [Exposed]). Plus, it's always a bonus when we don't need to update every IDL toolchain to add a new feature. |
The main issue for me is that this would disallow the following fragment since the interface name is the same (or at least I think, I cannot find the clause that disallows this but it seems reasonably logical): [Exposed=Window]
interface Foo {};
[Exposed=Window]
namespace bar {};
[InNamespace=bar]
interface Foo {}; ... and namespacing was kind of the point of namespaces. On the other hand, even if we do allow that, it can be difficult (for a human) to immediately recognize I agree that a syntax change can cause churn, no doubt about that, but I still believe it's the best way forward. |
Whether more dedicated syntax makes sense very much depends on whether we want this kind of namespacing going forward or use some kind of builtin modules. Does Wasm really need this? |
If we could end-up in a situation where those extended attributes are mostly there for legacy purposes, I think that would be better. We're adding new syntax for mixins soon, so [NoInterfaceObject] will be a legacy construct.
Well, for namespaces to be at all useful, we'd be breaking the invariant that identifiers are unique, so we're in for a world of pain anyway (e.g. idlharness assumes interface identifiers are unique). |
I agree with @annevk's sentiment here. It seems weird to suddenly allow this for a part of the platform for implementor/editor convenience when we've been refusing it for the rest of the platform despite developers requiring it for a long time (e.g. for grouping all sensors under a single namespace, see w3c/sensors#127). |
Historically, WebAssembly seems to have somehow skipped the WebIDL formalization and TAG review before shipping (blink-dev Intent to Ship thread), so it recently got out of the door with these namespaces. It has now be shipping in Chrome for around six months, and has also shipped in Firefox. At this point, it could be a risk to web compatibility to change the API to be anything but namespaced.
|
HTML doesn't define an interface called |
Sorry, not sure why I got confused about that; I believe in some past version there were some funny cross-references generated, but I don't see them now. |
So if we agree this was a design mistake and that we keep it for Web compat reasons, we can restrict it to the existing set of interfaces defined by WebAssembly and keep the interface identifier uniqueness invariant as a requirement. In that case, we should call it [LegacyNamespace] and add an advisement to it such as we do for [LegacyArrayClass]. |
OK, LegacyNamespace seems to be the way to go for now, though I won't be surprised if, in the future, others come in wanting interfaces in namespaces ("WebAssembly has it, so why can't my API?"). |
I won't either. Which is why I suggested dedicated syntax. If this opens up to other use cases, the unique identifier invariant won't hold long, and we'll need to address this in the spec. |
Would it be reasonable to start with the LegacyNamespace form, and consider adding dedicated syntax later (and going back and updating the WebAssembly spec) if it turns out to be needed for other specifications? |
I'm fine with that. Can you add an advisement in the same style as those I just added for all the [LegacyX] stuff? |
@tobie I believe this PR should be in that same style. |
I just merged some more consistent text earlier for all of these advisement (always at the top, with a link to a file an "intent to use" GH issue before using it, etc. ), think you could follow that format? |
This is necessary to specify certain APIs such as WebAssembly, which includes several constructors as properties of the root WebAssembly object. See a WebAssembly draft specification where this is in use at https://github.com/littledan/spec/blob/new-js.bs/document/JS.bs
2d01439
to
6ecbbc9
Compare
Done |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few other nits (sorry for the back-and-forth, I've been mostly OoO today, and looking at this stuff on a phone isn't ideal). Would like to get @bzbarsky to have a look before this is merged. Think he's back next week.
index.bs
Outdated
<h4 id="LegacyNamespace" extended-attribute lt="LegacyNamespace">[LegacyNamespace]</h4> | ||
|
||
<p class="advisement"> | ||
The [{{LegacyArrayClass}}] [=extended attribute=] is an undesirable feature. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/LegacyArrayClass/LegacyNamespace/
index.bs
Outdated
@@ -10135,7 +10186,7 @@ Note: The HTML Standard defines how a security check is performed. [[!HTML]] | |||
|
|||
For every non-callback [=interface=] that is [=exposed=] in | |||
a given ECMAScript global environment and that is not declared with | |||
the [{{NoInterfaceObject}}] [=extended attribute=], | |||
the [{{NoInterfaceObject}}] or [{{LegacyNamespace}}] [=extended attribute|extended attributes=], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/[=extended attribute|extended attributes=]/[=extended attributes=]/ (Bikeshed should recognize the plurals.
Fixed those nits. |
Just discussed this with @bzbarsky. He pointed out that Mozilla's Wasm implementation wasn't relying on WebIDL at all so far, which creates significant differences with what a WebIDL-based implementation would look like. Is Chrome's implementation WebIDL-based? @lukewagner, what's Mozilla's plan here? Are implementations going to converge on a WebIDL-based spec? |
Yes, we currently hand-code our wasm JS API bindings in the JS engine. However, we should be able to precisely match the order of coercions and property descriptor values to match a Web IDL spec without much trouble. The plan is also to write plentiful wpts for all the observable differences. |
Thanks, @lukewagner. So if the plan is for all to move to WebIDL semantics, we should just go-ahead with this. |
That said, are we sure that the backwards compatibility issues that will be created by moving to a WebIDL-based specification aren't the occasion to eschew [LegacyNamespace] altogether and move to the more standard |
From the changes I anticipate (order of coercions, enumerability of properties), I don't think breakage will actually occur in the wild at this point by simply moving to WebIDL (and there's probably already divergence between browsers in these minute details). |
V8's implementation is not WebIDL-based either, but I plan to work on those wpts. Thanks for the merge! |
As far as I know the differences are fairly minor: #226. But they are a source of annoyance. I still wonder whether we should offer some kind of opt-in mechanism to get JavaScript-style classes rather than IDL-style classes. Then we could also potentially describe other things with IDL, such as Promise and ReadableStream, if we wanted to. |
@annevk That sounds even better :) |
This is necessary to specify certain APIs such as WebAssembly,
which includes several constructors as properties of the root
WebAssembly object. See a WebAssembly draft specification where
this is in use at https://github.com/littledan/spec/blob/new-js.bs/document/JS.bs
Preview | Diff