webidl
webidl copied to clipboard
Suggestion: forbid ECMA-262/402-defined global names for some named constructs
There are two reasons I think it’d be good for Web IDL to specify something like the following rough attempt:
A Web IDL construct which would imply defining properties of global objects in the ES binding whose property names are among those defined by ECMA-262 and ECMA-402 in SetDefaultGlobalBindings is not valid.
-
The first reason is the obvious one —
interface Array {}
would be a bad time for everybody. But since that is so obvious, it might seem weird to bother spilling ink on specifying that it shouldn’t be done. -
The second reason is that the absence of the requirement means every time define the global property references calls CreateMethodProperty, because some ES-defined global properties are unconfigurable, we hit undefined behavior*. Given
interface _Infinity {}
, CreateMethodProperty’s! DefinePropertyOrThrow
turns into a? DefinePropertyOrThrow
.
* The assertion in CreateMethodProperty is that “O is an ordinary, extensible object with no non-configurable properties,” so it’s actually always violated when called in this algorthm no matter what the property name is. “Uh oh what now” chaos only really ensues when the property name is "Infinity", "NaN", or "undefined", though.
I’m sure the requirement could be expressed other ways / better ways than my attempt above. I figured the abstract phrasing might be preferred for brevity, but here’s an attempt at explicitly enumerating the set of identifiers which I meant to cover there:
- identifiers of namespaces
- identifiers of interfaces not annotated by the [LegacyNoInterfaceObject] or [LegacyNamespace] extended attributes
- identifiers of callback interfaces which have const members
- identifiers of legacy factory function operations declared by [LegacyFactoryFunction] extended attributes
- identifiers declared as interface aliases by [LegacyWindowAlias] extended attributes
- identifiers of regular attributes of interfaces annotated by the [Global] extended attribute
- identifiers of regular operations of interfaces annotated by the [Global] extended attribute
Relatedly — though for pretty different reasons — I think it would be pretty reasonable to add "hasOwnProperty", "isPrototypeOf", and "propertyIsEnumerable" to the list of reserved identifiers so that they’re forbidden across the board. Unlike "toLocaleString", "toString", and "valueOf", the corresponding %Object.prototype% methods aren’t logical extension points suitable for custom shadowing. Ideally they’d never have existed, of course ... but they do.
It seems bad that we'd always violate the CreateMethodProperty
assertion. We should figure out how to not do that or remove the assertion, but perhaps we should track that separately?
CreateMethodProperty(O, P, V) used to just be:
- Let newDesc be the PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }.
- Return ? O.[[DefineOwnProperty]](P, newDesc).
But this was changed as part of the completion record rework in https://github.com/tc39/ecma262/pull/2547.