Skip to content

Commit

Permalink
Allow same named static and nonstatic operations (#673)
Browse files Browse the repository at this point in the history
Fixes #672
  • Loading branch information
saschanaz authored May 20, 2022
1 parent 33dc010 commit 4a4be1f
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 7 deletions.
46 changes: 39 additions & 7 deletions lib/validators/interface.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,35 @@
import { validationError } from "../error.js";

/**
* @param {import("../validator.js").Definitions} defs
* @param {import("../productions/container.js").Container} i
*/
export function* checkInterfaceMemberDuplication(defs, i) {
const opNames = new Set(getOperations(i).map((op) => op.name));
const opNames = groupOperationNames(i);
const partials = defs.partials.get(i.name) || [];
const mixins = defs.mixinMap.get(i.name) || [];
for (const ext of [...partials, ...mixins]) {
const additions = getOperations(ext);
yield* forEachExtension(additions, opNames, ext, i);
for (const addition of additions) {
opNames.add(addition.name);
}
const statics = additions.filter((a) => a.special === "static");
const nonstatics = additions.filter((a) => a.special !== "static");
yield* checkAdditions(statics, opNames.statics, ext, i);
yield* checkAdditions(nonstatics, opNames.nonstatics, ext, i);
statics.forEach((op) => opNames.statics.add(op.name));
nonstatics.forEach((op) => opNames.nonstatics.add(op.name));
}

function* forEachExtension(additions, existings, ext, base) {
/**
* @param {import("../productions/operation.js").Operation[]} additions
* @param {Set<string>} existings
* @param {import("../productions/container.js").Container} ext
* @param {import("../productions/container.js").Container} base
*/
function* checkAdditions(additions, existings, ext, base) {
for (const addition of additions) {
const { name } = addition;
if (name && existings.has(name)) {
const message = `The operation "${name}" has already been defined for the base interface "${base.name}" either in itself or in a mixin`;
const isStatic = addition.special === "static" ? "static " : "";
const message = `The ${isStatic}operation "${name}" has already been defined for the base interface "${base.name}" either in itself or in a mixin`;
yield validationError(
addition.tokens.name,
ext,
Expand All @@ -27,7 +40,26 @@ export function* checkInterfaceMemberDuplication(defs, i) {
}
}

/**
* @param {import("../productions/container.js").Container} i
* @returns {import("../productions/operation.js").Operation[]}
*/
function getOperations(i) {
return i.members.filter(({ type }) => type === "operation");
}

/**
* @param {import("../productions/container.js").Container} i
*/
function groupOperationNames(i) {
const ops = getOperations(i);
return {
statics: new Set(
ops.filter((op) => op.special === "static").map((op) => op.name)
),
nonstatics: new Set(
ops.filter((op) => op.special !== "static").map((op) => op.name)
),
};
}
}
3 changes: 3 additions & 0 deletions test/invalid/baseline/overloads.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@
(no-cross-overload) Validation error at line 26 in overloads.webidl, inside `interface mixin WebGL2RenderingContextBase`:
undefined bufferData(GLenum target,
^ The operation "bufferData" has already been defined for the base interface "WebGL2RenderingContext" either in itself or in a mixin
(no-cross-overload) Validation error at line 56 in overloads.webidl, inside `partial interface Test`:
static undefined invalid();
^ The static operation "invalid" has already been defined for the base interface "Test" either in itself or in a mixin
15 changes: 15 additions & 0 deletions test/invalid/idl/overloads.webidl
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,18 @@ interface WebGL2RenderingContext
};
WebGL2RenderingContext includes WebGLRenderingContextBase;
WebGL2RenderingContext includes WebGL2RenderingContextBase;

[Exposed=*]
interface Test {
undefined valid();
};

partial interface Test {
static undefined valid();

static undefined invalid();
};

partial interface Test {
static undefined invalid();
};

0 comments on commit 4a4be1f

Please sign in to comment.