diff --git a/.gitattributes b/.gitattributes index 9b5bbd2f..5a0d5e48 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,2 @@ # Auto detect text files and perform LF normalization -* text=auto -/test/*/** text eol=lf +* text=auto eol=lf diff --git a/README.md b/README.md index 3e2bd993..f45ee123 100644 --- a/README.md +++ b/README.md @@ -199,6 +199,7 @@ properties: * `no-constructible-global`: Interfaces with `[Global]` cannot have constructors. * `renamed-legacy`: Legacy extended attributes must use their new names. * `replace-void`: `void` type is replaced by `undefined` type. + * `migrate-allowshared`: `[AllowShared] BufferSource` is replaced by `AllowSharedBufferSource`. * `input`: a short peek at the text at the point where the error happened * `tokens`: the five tokens at the point of error, as understood by the tokeniser (this is the same content as `input`, but seen from the tokeniser's point of view) diff --git a/lib/productions/type.js b/lib/productions/type.js index 654a52cf..728fe6f0 100644 --- a/lib/productions/type.js +++ b/lib/productions/type.js @@ -194,6 +194,26 @@ export class Type extends Base { *validate(defs) { yield* this.extAttrs.validate(defs); + if (this.idlType === "BufferSource") { + // XXX: For now this is a hack. Consider moving parents' extAttrs into types as the spec says: + // https://webidl.spec.whatwg.org/#idl-annotated-types + for (const extAttrs of [this.extAttrs, this.parent?.extAttrs]) { + for (const extAttr of extAttrs) { + if (extAttr.name !== "AllowShared") { + continue; + } + const message = `\`[AllowShared] BufferSource\` is now replaced with AllowSharedBufferSource.`; + yield validationError( + this.tokens.base, + this, + "migrate-allowshared", + message, + { autofix: replaceAllowShared(this, extAttr, extAttrs) } + ); + } + } + } + if (this.idlType === "void") { const message = `\`void\` is now replaced by \`undefined\`. Refer to the \ [relevant GitHub issue](https://github.com/whatwg/webidl/issues/60) \ @@ -273,6 +293,23 @@ for more information.`; } } +/** + * @param {Type} type + * @param {import("./extended-attributes.js").SimpleExtendedAttribute} extAttr + * @param {ExtendedAttributes} extAttrs + */ +function replaceAllowShared(type, extAttr, extAttrs) { + return () => { + const index = extAttrs.indexOf(extAttr); + extAttrs.splice(index, 1); + if (!extAttrs.length && type.tokens.base.trivia.match(/^\s$/)) { + type.tokens.base.trivia = ""; // (let's not remove comments) + } + + type.tokens.base.value = "AllowSharedBufferSource"; + }; +} + /** * @param {Type} type */ diff --git a/lib/tokeniser.js b/lib/tokeniser.js index 21b13e0c..77498394 100644 --- a/lib/tokeniser.js +++ b/lib/tokeniser.js @@ -18,6 +18,7 @@ const tokenRe = { export const typeNameKeywords = [ "ArrayBuffer", + "SharedArrayBuffer", "DataView", "Int8Array", "Int16Array", diff --git a/test/autofix.js b/test/autofix.js index 5056e724..d61f6a66 100644 --- a/test/autofix.js +++ b/test/autofix.js @@ -342,4 +342,22 @@ describe("Writer template functions", () => { `; expect(autofix(input)).toBe(output); }); + + it("should replace [AllowShared] BufferSource into undefined", () => { + const input = ` + [Exposed=Window] + interface Foo { + undefined foo([AllowShared] /* Accept SharedArrayBuffer */ BufferSource source); + undefined foo(optional [AllowShared] /* Accept SharedArrayBuffer */ BufferSource source); + }; + `; + const output = ` + [Exposed=Window] + interface Foo { + undefined foo( /* Accept SharedArrayBuffer */ AllowSharedBufferSource source); + undefined foo(optional /* Accept SharedArrayBuffer */ AllowSharedBufferSource source); + }; + `; + expect(autofix(input)).toBe(output); + }); }); diff --git a/test/invalid/baseline/invalid-allowshared.txt b/test/invalid/baseline/invalid-allowshared.txt new file mode 100644 index 00000000..8623d5f0 --- /dev/null +++ b/test/invalid/baseline/invalid-allowshared.txt @@ -0,0 +1,3 @@ +(migrate-allowshared) Validation error at line 3 in invalid-allowshared.webidl: + foo([AllowShared] BufferSource source); + ^ `[AllowShared] BufferSource` is now replaced with AllowSharedBufferSource. diff --git a/test/invalid/baseline/sharedarraybuffer.txt b/test/invalid/baseline/sharedarraybuffer.txt new file mode 100644 index 00000000..605503c3 --- /dev/null +++ b/test/invalid/baseline/sharedarraybuffer.txt @@ -0,0 +1,3 @@ +Syntax error at line 1 in sharedarraybuffer.webidl: +interface SharedArrayBuffer {}; + ^ Missing name in interface diff --git a/test/invalid/idl/invalid-allowshared.webidl b/test/invalid/idl/invalid-allowshared.webidl new file mode 100644 index 00000000..d207cea3 --- /dev/null +++ b/test/invalid/idl/invalid-allowshared.webidl @@ -0,0 +1,4 @@ +[Exposed=Window] +interface Foo { + undefined foo([AllowShared] BufferSource source); +}; diff --git a/test/invalid/idl/sharedarraybuffer.webidl b/test/invalid/idl/sharedarraybuffer.webidl new file mode 100644 index 00000000..24be99e0 --- /dev/null +++ b/test/invalid/idl/sharedarraybuffer.webidl @@ -0,0 +1 @@ +interface SharedArrayBuffer {}; diff --git a/test/syntax/baseline/sharedarraybuffer.json b/test/syntax/baseline/sharedarraybuffer.json new file mode 100644 index 00000000..1bd00f5b --- /dev/null +++ b/test/syntax/baseline/sharedarraybuffer.json @@ -0,0 +1,89 @@ +[ + { + "type": "interface", + "name": "Foo", + "inheritance": null, + "members": [ + { + "type": "operation", + "name": "foo", + "idlType": { + "type": "return-type", + "extAttrs": [], + "generic": "", + "nullable": false, + "union": false, + "idlType": "undefined" + }, + "arguments": [ + { + "type": "argument", + "name": "buffer", + "extAttrs": [], + "idlType": { + "type": "argument-type", + "extAttrs": [], + "generic": "", + "nullable": false, + "union": false, + "idlType": "SharedArrayBuffer" + }, + "default": null, + "optional": false, + "variadic": false + } + ], + "extAttrs": [], + "special": "" + }, + { + "type": "operation", + "name": "foo", + "idlType": { + "type": "return-type", + "extAttrs": [], + "generic": "", + "nullable": false, + "union": false, + "idlType": "undefined" + }, + "arguments": [ + { + "type": "argument", + "name": "source", + "extAttrs": [], + "idlType": { + "type": "argument-type", + "extAttrs": [], + "generic": "", + "nullable": false, + "union": false, + "idlType": "AllowSharedBufferSource" + }, + "default": null, + "optional": false, + "variadic": false + } + ], + "extAttrs": [], + "special": "" + } + ], + "extAttrs": [ + { + "type": "extended-attribute", + "name": "Exposed", + "rhs": { + "type": "identifier", + "value": "Window" + }, + "arguments": [] + } + ], + "partial": false + }, + { + "type": "eof", + "value": "" + } +] diff --git a/test/syntax/idl/sharedarraybuffer.webidl b/test/syntax/idl/sharedarraybuffer.webidl new file mode 100644 index 00000000..e314559b --- /dev/null +++ b/test/syntax/idl/sharedarraybuffer.webidl @@ -0,0 +1,5 @@ +[Exposed=Window] +interface Foo { + undefined foo(SharedArrayBuffer buffer); + undefined foo(AllowSharedBufferSource source); +};