UNPKG

webidl2

Version:
95 lines (88 loc) 2.18 kB
import { validationError as error } from "./error.js"; function getMixinMap(all, unique) { const map = new Map(); const includes = all.filter((def) => def.type === "includes"); for (const include of includes) { const mixin = unique.get(include.includes); if (!mixin) { continue; } const array = map.get(include.target); if (array) { array.push(mixin); } else { map.set(include.target, [mixin]); } } return map; } /** * @typedef {ReturnType<typeof groupDefinitions>} Definitions */ function groupDefinitions(all) { const unique = new Map(); const duplicates = new Set(); const partials = new Map(); for (const def of all) { if (def.partial) { const array = partials.get(def.name); if (array) { array.push(def); } else { partials.set(def.name, [def]); } continue; } if (!def.name) { continue; } if (!unique.has(def.name)) { unique.set(def.name, def); } else { duplicates.add(def); } } return { all, unique, partials, duplicates, mixinMap: getMixinMap(all, unique), cache: { typedefIncludesDictionary: new WeakMap(), dictionaryIncludesRequiredField: new WeakMap(), }, }; } function* checkDuplicatedNames({ unique, duplicates }) { for (const dup of duplicates) { const { name } = dup; const message = `The name "${name}" of type "${ unique.get(name).type }" was already seen`; yield error(dup.tokens.name, dup, "no-duplicate", message); } } function* validateIterable(ast) { const defs = groupDefinitions(ast); for (const def of defs.all) { if (def.validate) { yield* def.validate(defs); } } yield* checkDuplicatedNames(defs); } // Remove this once all of our support targets expose `.flat()` by default function flatten(array) { if (array.flat) { return array.flat(); } return [].concat(...array); } /** * @param {import("./productions/base.js").Base[]} ast * @return {import("./error.js").WebIDLErrorData[]} validation errors */ export function validate(ast) { return [...validateIterable(flatten(ast))]; }