Skip to content

Commit 4a4be1f

Browse files
authored
Allow same named static and nonstatic operations (#673)
Fixes #672
1 parent 33dc010 commit 4a4be1f

File tree

3 files changed

+57
-7
lines changed

3 files changed

+57
-7
lines changed

lib/validators/interface.js

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,35 @@
11
import { validationError } from "../error.js";
22

3+
/**
4+
* @param {import("../validator.js").Definitions} defs
5+
* @param {import("../productions/container.js").Container} i
6+
*/
37
export function* checkInterfaceMemberDuplication(defs, i) {
4-
const opNames = new Set(getOperations(i).map((op) => op.name));
8+
const opNames = groupOperationNames(i);
59
const partials = defs.partials.get(i.name) || [];
610
const mixins = defs.mixinMap.get(i.name) || [];
711
for (const ext of [...partials, ...mixins]) {
812
const additions = getOperations(ext);
9-
yield* forEachExtension(additions, opNames, ext, i);
10-
for (const addition of additions) {
11-
opNames.add(addition.name);
12-
}
13+
const statics = additions.filter((a) => a.special === "static");
14+
const nonstatics = additions.filter((a) => a.special !== "static");
15+
yield* checkAdditions(statics, opNames.statics, ext, i);
16+
yield* checkAdditions(nonstatics, opNames.nonstatics, ext, i);
17+
statics.forEach((op) => opNames.statics.add(op.name));
18+
nonstatics.forEach((op) => opNames.nonstatics.add(op.name));
1319
}
1420

15-
function* forEachExtension(additions, existings, ext, base) {
21+
/**
22+
* @param {import("../productions/operation.js").Operation[]} additions
23+
* @param {Set<string>} existings
24+
* @param {import("../productions/container.js").Container} ext
25+
* @param {import("../productions/container.js").Container} base
26+
*/
27+
function* checkAdditions(additions, existings, ext, base) {
1628
for (const addition of additions) {
1729
const { name } = addition;
1830
if (name && existings.has(name)) {
19-
const message = `The operation "${name}" has already been defined for the base interface "${base.name}" either in itself or in a mixin`;
31+
const isStatic = addition.special === "static" ? "static " : "";
32+
const message = `The ${isStatic}operation "${name}" has already been defined for the base interface "${base.name}" either in itself or in a mixin`;
2033
yield validationError(
2134
addition.tokens.name,
2235
ext,
@@ -27,7 +40,26 @@ export function* checkInterfaceMemberDuplication(defs, i) {
2740
}
2841
}
2942

43+
/**
44+
* @param {import("../productions/container.js").Container} i
45+
* @returns {import("../productions/operation.js").Operation[]}
46+
*/
3047
function getOperations(i) {
3148
return i.members.filter(({ type }) => type === "operation");
3249
}
50+
51+
/**
52+
* @param {import("../productions/container.js").Container} i
53+
*/
54+
function groupOperationNames(i) {
55+
const ops = getOperations(i);
56+
return {
57+
statics: new Set(
58+
ops.filter((op) => op.special === "static").map((op) => op.name)
59+
),
60+
nonstatics: new Set(
61+
ops.filter((op) => op.special !== "static").map((op) => op.name)
62+
),
63+
};
64+
}
3365
}

test/invalid/baseline/overloads.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@
1616
(no-cross-overload) Validation error at line 26 in overloads.webidl, inside `interface mixin WebGL2RenderingContextBase`:
1717
undefined bufferData(GLenum target,
1818
^ The operation "bufferData" has already been defined for the base interface "WebGL2RenderingContext" either in itself or in a mixin
19+
(no-cross-overload) Validation error at line 56 in overloads.webidl, inside `partial interface Test`:
20+
static undefined invalid();
21+
^ The static operation "invalid" has already been defined for the base interface "Test" either in itself or in a mixin

test/invalid/idl/overloads.webidl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,18 @@ interface WebGL2RenderingContext
4040
};
4141
WebGL2RenderingContext includes WebGLRenderingContextBase;
4242
WebGL2RenderingContext includes WebGL2RenderingContextBase;
43+
44+
[Exposed=*]
45+
interface Test {
46+
undefined valid();
47+
};
48+
49+
partial interface Test {
50+
static undefined valid();
51+
52+
static undefined invalid();
53+
};
54+
55+
partial interface Test {
56+
static undefined invalid();
57+
};

0 commit comments

Comments
 (0)