Bug 1577126 [wpt PR 18722] - Update idlharness to support constructor operations., a=testonly

Automatic update from web-platform-tests
Update webidl2 to 23.6.0.

--
Update idlharness to support constructor operations.

--
Add a test.

--

wpt-commits: ae8cc6c08076ef5071e5e4d35cc2d4e92c2e8e4a, 5c67f16d023a23177da4fc6457cffa8905c66985, 41a14253769e09c10a40a4612be7e51ef0fac46f
wpt-pr: 18722
This commit is contained in:
Ms2ger 2019-09-02 13:44:25 +00:00 коммит произвёл moz-wptsync-bot
Родитель ac2a1d371c
Коммит 9ab6450440
3 изменённых файлов: 163 добавлений и 48 удалений

Просмотреть файл

@ -1507,6 +1507,17 @@ IdlInterface.prototype.test = function()
this.test_members();
};
// This supports both Constructor extended attributes and constructor
// operations until all idl fragments have been updated.
IdlInterface.prototype.constructors = function()
{
var extendedAttributes = this.extAttrs
.filter(function(attr) { return attr.name == "Constructor"; });
var operations = this.members
.filter(function(m) { return m.type == "constructor"; });
return extendedAttributes.concat(operations);
}
IdlInterface.prototype.test_self = function()
{
subsetTestByKey(this.name, test, function()
@ -1594,7 +1605,7 @@ IdlInterface.prototype.test_self = function()
"prototype of self's property " + format_value(this.name) + " is not Function.prototype");
}
if (!this.has_extended_attribute("Constructor")) {
if (!this.constructors().length) {
// "The internal [[Call]] method of the interface object behaves as
// follows . . .
//
@ -1629,8 +1640,7 @@ IdlInterface.prototype.test_self = function()
assert_false(desc.enumerable, this.name + ".length should not be enumerable");
assert_true(desc.configurable, this.name + ".length should be configurable");
var constructors = this.extAttrs
.filter(function(attr) { return attr.name == "Constructor"; });
var constructors = this.constructors();
var expected_length = minOverloadLength(constructors);
assert_equals(this.get_interface_object().length, expected_length, "wrong value for " + this.name + ".length");
}.bind(this), this.name + " interface object length");

Просмотреть файл

@ -0,0 +1,25 @@
<!DOCTYPE HTML>
<title>IdlInterface.prototype.constructors()</title>
<div id="log"></div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/WebIDLParser.js"></script>
<script src="/resources/idlharness.js"></script>
<script src="../../../idl-helper.js"></script>
<script>
"use strict";
test(function() {
var i = interfaceFrom('[Constructor] interface A { };');
assert_equals(i.constructors().length, 1);
}, 'Interface with Constructor extended attribute.');
test(function() {
var i = interfaceFrom('interface A { constructor(); };');
assert_equals(i.constructors().length, 1);
}, 'Interface with constructor method');
test(function() {
var i = interfaceFrom('[Constructor] interface A { constructor(); };');
assert_equals(i.constructors().length, 2);
}, 'Interface with both');
</script>

Просмотреть файл

@ -103,10 +103,10 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var _lib_webidl2_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "parse", function() { return _lib_webidl2_js__WEBPACK_IMPORTED_MODULE_0__["parse"]; });
/* harmony import */ var _lib_writer_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(29);
/* harmony import */ var _lib_writer_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "write", function() { return _lib_writer_js__WEBPACK_IMPORTED_MODULE_1__["write"]; });
/* harmony import */ var _lib_validator_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(30);
/* harmony import */ var _lib_validator_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(31);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "validate", function() { return _lib_validator_js__WEBPACK_IMPORTED_MODULE_2__["validate"]; });
@ -128,10 +128,10 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var _productions_typedef_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(17);
/* harmony import */ var _productions_callback_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(18);
/* harmony import */ var _productions_interface_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(19);
/* harmony import */ var _productions_mixin_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(24);
/* harmony import */ var _productions_dictionary_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(25);
/* harmony import */ var _productions_namespace_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(27);
/* harmony import */ var _productions_callback_interface_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(28);
/* harmony import */ var _productions_mixin_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(25);
/* harmony import */ var _productions_dictionary_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(26);
/* harmony import */ var _productions_namespace_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(28);
/* harmony import */ var _productions_callback_interface_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(29);
@ -299,6 +299,7 @@ const nonRegexTerminals = [
"async",
"boolean",
"byte",
"constructor",
"double",
"false",
"float",
@ -501,12 +502,13 @@ function lastLine(text) {
/**
* @typedef {object} WebIDL2ErrorOptions
* @property {"error" | "warning"} level
* @property {Function} autofix
*
* @param {string} message error message
* @param {"Syntax" | "Validation"} kind error type
* @param {WebIDL2ErrorOptions} [options]
*/
function error(source, position, current, message, kind, { level = "error" } = {}) {
function error(source, position, current, message, kind, { level = "error", autofix } = {}) {
/**
* @param {number} count
*/
@ -556,6 +558,7 @@ function error(source, position, current, message, kind, { level = "error" } = {
line,
sourceName: source.name,
level,
autofix,
input: subsequentText,
tokens: subsequentTokens
};
@ -664,12 +667,15 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "type_with_extended_attributes", function() { return type_with_extended_attributes; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "return_type", function() { return return_type; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "stringifier", function() { return stringifier; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "autofixAddExposedWindow", function() { return autofixAddExposedWindow; });
/* harmony import */ var _type_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6);
/* harmony import */ var _argument_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9);
/* harmony import */ var _token_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(13);
/* harmony import */ var _extended_attributes_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(11);
/* harmony import */ var _operation_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(14);
/* harmony import */ var _attribute_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(15);
/* harmony import */ var _tokeniser_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(2);
@ -838,6 +844,29 @@ function stringifier(tokeniser) {
return member;
}
/**
* @param {object} def
* @param {import("./extended-attributes.js").ExtendedAttributes} def.extAttrs
*/
function autofixAddExposedWindow(def) {
return () => {
if (def.extAttrs.length){
const tokeniser = new _tokeniser_js__WEBPACK_IMPORTED_MODULE_6__["Tokeniser"]("Exposed=Window,");
const exposed = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_3__["SimpleExtendedAttribute"].parse(tokeniser);
exposed.tokens.separator = tokeniser.consume(",");
const existing = def.extAttrs[0];
if (!/^\s/.test(existing.tokens.name.trivia)) {
existing.tokens.name.trivia = ` ${existing.tokens.name.trivia}`;
}
def.extAttrs.unshift(exposed);
} else {
def.extAttrs = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_3__["ExtendedAttributes"].parse(new _tokeniser_js__WEBPACK_IMPORTED_MODULE_6__["Tokeniser"]("[Exposed=Window]"));
def.extAttrs.tokens.open.trivia = def.tokens.base.trivia;
def.tokens.base.trivia = " ";
}
};
}
/***/ }),
/* 6 */
@ -1065,25 +1094,15 @@ class Base {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "dictionaryWithinUnion", function() { return dictionaryWithinUnion; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "idlTypeIncludesDictionary", function() { return idlTypeIncludesDictionary; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "referencesTypedef", function() { return referencesTypedef; });
/**
* Yields direct references to dictionary within union.
*/
function* dictionaryWithinUnion(subtypes, defs) {
for (const subtype of subtypes) {
const def = defs.unique.get(subtype.idlType);
if (def && def.type === "dictionary") {
yield subtype;
}
}
}
/**
* @param {*} idlType
* @param {*[]} defs
* @param {object} [options]
* @param {boolean} [options.useNullableInner] use when the input idlType is nullable and you want to use its inner type
* @return the type reference that ultimately includes dictionary.
*/
function idlTypeIncludesDictionary(idlType, defs) {
function idlTypeIncludesDictionary(idlType, defs, { useNullableInner } = {}) {
if (!idlType.union) {
const def = defs.unique.get(idlType.idlType);
if (!def) {
@ -1103,7 +1122,7 @@ function idlTypeIncludesDictionary(idlType, defs) {
return idlType;
}
}
if (def.type === "dictionary") {
if (def.type === "dictionary" && (useNullableInner || !idlType.nullable)) {
return idlType;
}
}
@ -1118,14 +1137,6 @@ function idlTypeIncludesDictionary(idlType, defs) {
}
}
/**
* @return true if the idlType directly references a typedef.
*/
function referencesTypedef(idlType, defs) {
const result = defs.unique.get(idlType.idlType);
return result && result.type === "typedef";
}
/***/ }),
/* 9 */
@ -1189,19 +1200,29 @@ class Argument extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
*validate(defs) {
yield* this.idlType.validate(defs);
if (Object(_validators_helpers_js__WEBPACK_IMPORTED_MODULE_6__["idlTypeIncludesDictionary"])(this.idlType, defs)) {
if (this.optional && !this.default) {
const message = `Optional dictionary arguments must have a default value of \`{}\`.`;
yield Object(_error_js__WEBPACK_IMPORTED_MODULE_5__["validationError"])(this.source, this.tokens.name, this, message);
}
if (Object(_validators_helpers_js__WEBPACK_IMPORTED_MODULE_6__["idlTypeIncludesDictionary"])(this.idlType, defs, { useNullableInner: true })) {
if (this.idlType.nullable) {
const message = `Dictionary arguments cannot be nullable.`;
yield Object(_error_js__WEBPACK_IMPORTED_MODULE_5__["validationError"])(this.source, this.tokens.name, this, message);
} else if (this.optional && !this.default) {
const message = `Optional dictionary arguments must have a default value of \`{}\`.`;
yield Object(_error_js__WEBPACK_IMPORTED_MODULE_5__["validationError"])(this.source, this.tokens.name, this, message, {
autofix: autofixOptionalDictionaryDefaultValue(this)
});
}
}
}
}
/**
* @param {Argument} arg
*/
function autofixOptionalDictionaryDefaultValue(arg) {
return () => {
arg.default = _default_js__WEBPACK_IMPORTED_MODULE_1__["Default"].parse(new _tokeniser_js__WEBPACK_IMPORTED_MODULE_4__["Tokeniser"](" = {}"));
};
}
/***/ }),
/* 10 */
@ -1259,6 +1280,7 @@ class Default extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SimpleExtendedAttribute", function() { return SimpleExtendedAttribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ExtendedAttributes", function() { return ExtendedAttributes; });
/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7);
/* harmony import */ var _array_base_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(12);
@ -1715,6 +1737,8 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(5);
/* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(3);
/* harmony import */ var _validators_interface_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(23);
/* harmony import */ var _constructor_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(24);
@ -1747,6 +1771,7 @@ class Interface extends _container_js__WEBPACK_IMPORTED_MODULE_0__["Container"]
inheritable: !partial,
allowedMembers: [
[_constant_js__WEBPACK_IMPORTED_MODULE_3__["Constant"].parse],
[_constructor_js__WEBPACK_IMPORTED_MODULE_8__["Constructor"].parse],
[static_member],
[_helpers_js__WEBPACK_IMPORTED_MODULE_5__["stringifier"]],
[_iterable_js__WEBPACK_IMPORTED_MODULE_4__["IterableLike"].parse],
@ -1772,7 +1797,9 @@ To fix, add, for example, \`[Exposed=Window]\`. Please also consider carefully \
if your interface should also be exposed in a Worker scope. Refer to the \
[WebIDL spec section on Exposed](https://heycam.github.io/webidl/#Exposed) \
for more information.`;
yield Object(_error_js__WEBPACK_IMPORTED_MODULE_6__["validationError"])(this.source, this.tokens.name, this, message);
yield Object(_error_js__WEBPACK_IMPORTED_MODULE_6__["validationError"])(this.source, this.tokens.name, this, message, {
autofix: Object(_helpers_js__WEBPACK_IMPORTED_MODULE_5__["autofixAddExposedWindow"])(this)
});
}
yield* super.validate(defs);
@ -2033,6 +2060,43 @@ function* checkInterfaceMemberDuplication(defs, i) {
/* 24 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Constructor", function() { return Constructor; });
/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7);
/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5);
class Constructor extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
/**
* @param {import("../tokeniser").Tokeniser} tokeniser
*/
static parse(tokeniser) {
const base = tokeniser.consume("constructor");
if (!base) {
return;
}
const tokens = { base };
tokens.open = tokeniser.consume("(") || tokeniser.error("No argument list in constructor");
const args = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["argument_list"])(tokeniser);
tokens.close = tokeniser.consume(")") || tokeniser.error("Unterminated constructor");
tokens.termination = tokeniser.consume(";") || tokeniser.error("No semicolon after constructor");
const ret = new Constructor({ tokens });
ret.arguments = args;
return ret;
}
get type() {
return "constructor";
}
}
/***/ }),
/* 25 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Mixin", function() { return Mixin; });
@ -2075,14 +2139,14 @@ class Mixin extends _container_js__WEBPACK_IMPORTED_MODULE_0__["Container"] {
/***/ }),
/* 25 */
/* 26 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Dictionary", function() { return Dictionary; });
/* harmony import */ var _container_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(20);
/* harmony import */ var _field_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(26);
/* harmony import */ var _field_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27);
@ -2112,7 +2176,7 @@ class Dictionary extends _container_js__WEBPACK_IMPORTED_MODULE_0__["Container"]
/***/ }),
/* 26 */
/* 27 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@ -2161,7 +2225,7 @@ class Field extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
/***/ }),
/* 27 */
/* 28 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@ -2171,6 +2235,8 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var _attribute_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(15);
/* harmony import */ var _operation_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(14);
/* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3);
/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(5);
@ -2206,7 +2272,9 @@ To fix, add, for example, [Exposed=Window]. Please also consider carefully \
if your namespace should also be exposed in a Worker scope. Refer to the \
[WebIDL spec section on Exposed](https://heycam.github.io/webidl/#Exposed) \
for more information.`;
yield Object(_error_js__WEBPACK_IMPORTED_MODULE_3__["validationError"])(this.source, this.tokens.name, this, message);
yield Object(_error_js__WEBPACK_IMPORTED_MODULE_3__["validationError"])(this.source, this.tokens.name, this, message, {
autofix: Object(_helpers_js__WEBPACK_IMPORTED_MODULE_4__["autofixAddExposedWindow"])(this)
});
}
yield* super.validate(defs);
}
@ -2214,7 +2282,7 @@ for more information.`;
/***/ }),
/* 28 */
/* 29 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@ -2255,7 +2323,7 @@ class CallbackInterface extends _container_js__WEBPACK_IMPORTED_MODULE_0__["Cont
/***/ }),
/* 29 */
/* 30 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@ -2416,6 +2484,17 @@ function write(ast, { templates: ts = templates } = {}) {
]), { data: it, parent });
}
function constructor(it, parent) {
return ts.definition(ts.wrap([
extended_attributes(it.extAttrs),
token(it.tokens.base),
token(it.tokens.open),
ts.wrap(it.arguments.map(argument)),
token(it.tokens.close),
token(it.tokens.termination)
]), { data: it, parent });
}
function inheritance(inh) {
if (!inh.tokens.inheritance) {
return "";
@ -2538,6 +2617,7 @@ function write(ast, { templates: ts = templates } = {}) {
namespace: container,
operation,
attribute,
constructor,
dictionary: container,
field,
const: const_,
@ -2570,7 +2650,7 @@ function write(ast, { templates: ts = templates } = {}) {
/***/ }),
/* 30 */
/* 31 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";