Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(interface): Remove dead code #171

Merged
merged 2 commits into from
Feb 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,24 +188,18 @@ The example above showed a simplified generated wrapper file with only three exp

### For interfaces

Note that all of the below are still exported for "mixin" interfaces, but only `isImpl()` and `is()` make sense ([#55](https://github.com/jsdom/webidl2js/issues/55)).

#### `isImpl(value)`

Returns a boolean indicating whether _value_ is an instance of the corresponding implementation class.

This is especially useful inside implementation class files, where incoming wrappers will be _unwrapped_, so that you only ever see implementation class instances ("impls").

This also works when used with mixin implementation classes: that is, `generatedModuleForMixin.isImpl(implForMixinTarget)` will be true.

#### `is(value)`

Returns a boolean indicating whether _value_ is an instance of the wrapper class.

This is useful in other parts of your program that are not implementation class files, but instead receive wrapper classes from client code.

This also works when used with mixin wrapper classes: that is, `generatedModuleForMixin.is(wrapperForMixinTarget)` will be true.

#### `convert(value, { context })`

Performs the Web IDL conversion algorithm for this interface, converting _value_ into the correct representation of the interface type suitable for consumption by implementation classes: the corresponding impl.
Expand Down Expand Up @@ -259,8 +253,6 @@ A constructor for your implementation class, with signature `(globalObject, cons

If you don't need to do any of these things, the constructor is entirely optional.

Additionally, the constructor should not be provided for mixin classes; it will never be called.

### Methods implementing IDL operations

IDL operations that you wish to implement need to have corresponding methods on the implementation class.
Expand Down
74 changes: 8 additions & 66 deletions lib/constructs/interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ class Interface {
this.str = null;
this.opts = opts;
this.requires = new utils.RequiresMap(ctx);
this.implemented = [];
this.included = [];

this.constructorOperations = [];
Expand Down Expand Up @@ -270,8 +269,7 @@ class Interface {
}
};

const seen = new Set([this.name]);
for (const member of this.members(seen)) {
for (const member of this.members()) {
let key;
switch (member.type) {
case "constructor":
Expand Down Expand Up @@ -348,7 +346,7 @@ class Interface {
this.stringifier = member;
}
}
for (const member of this.inheritedMembers(seen)) {
for (const member of this.inheritedMembers()) {
TimothyGu marked this conversation as resolved.
Show resolved Hide resolved
if (this.iterable && member.type === "iterable") {
throw new Error(`Iterable interface ${this.name} inherits from another iterable interface ` +
`${member.definingInterface}`);
Expand Down Expand Up @@ -452,21 +450,9 @@ class Interface {
}
}

// https://heycam.github.io/webidl/#dfn-consequential-interfaces
* consequentialInterfaces(seen = new Set([this.name]), root = this.name) {
for (const iface of this.implemented) {
if (seen.has(iface)) {
throw new Error(`${root} has a dependency cycle`);
}
seen.add(iface);
yield* this.ctx.interfaces.get(iface).allInterfaces(seen);
}
}

// All interfaces an object of this interface implements.
* allInterfaces(seen = new Set([this.name]), root = this.name) {
yield this.name;
yield* this.consequentialInterfaces(seen, root);
if (this.idl.inheritance && this.ctx.interfaces.has(this.idl.inheritance)) {
if (seen.has(this.idl.inheritance)) {
throw new Error(`${root} has an inheritance cycle`);
Expand All @@ -476,19 +462,16 @@ class Interface {
}
}

// Members that will be visible on this interface's prototype object, i.e. members from this
// interface and its consequential interfaces.
* members(seen = new Set([this.name]), root = this.name) {
// Members that will be own properties of this interface's prototype object,
// i.e. members from this interface and its mixins.
* members() {
yield* this.idl.members;
for (const mixin of this.included) {
yield* this.ctx.interfaceMixins.get(mixin).idl.members;
}
for (const iface of this.consequentialInterfaces(seen, root)) {
yield* this.ctx.interfaces.get(iface).idl.members;
}
}

// Members from this interface's inherited interfaces and their consequential interfaces.
// Members inherited from this interface's prototype chain.
* inheritedMembers(seen = new Set([this.name]), root = this.name) {
if (this.idl.inheritance && this.ctx.interfaces.has(this.idl.inheritance)) {
if (seen.has(this.idl.inheritance)) {
Expand Down Expand Up @@ -516,60 +499,20 @@ class Interface {
this.requires.add(this.idl.inheritance);
}

for (const iface of this.consequentialInterfaces()) {
this.requires.add(iface);
}

this.str = `
${this.requires.generate()}

${this.str}
`;
}

generateMixins() {
for (const iface of this.consequentialInterfaces()) {
this.str += `
${iface}._mixedIntoPredicates.push(exports.is);
`;
}
}

generateExport() {
this.str += `
/**
* When an interface-module that implements this interface as a mixin is loaded, it will append its own \`.is()\`
* method into this array. It allows objects that directly implements *those* interfaces to be recognized as
* implementing this mixin interface.
*/
exports._mixedIntoPredicates = [];
exports.is = function is(obj) {
if (obj) {
if (utils.hasOwn(obj, impl) && obj[impl] instanceof Impl.implementation) {
return true;
}
for (const isMixedInto of exports._mixedIntoPredicates) {
if (isMixedInto(obj)) {
return true;
}
}
}
return false;
return utils.isObject(obj) && utils.hasOwn(obj, impl) && obj[impl] instanceof Impl.implementation;
};
exports.isImpl = function isImpl(obj) {
if (obj) {
if (obj instanceof Impl.implementation) {
return true;
}

const wrapper = utils.wrapperForImpl(obj);
for (const isMixedInto of exports._mixedIntoPredicates) {
if (isMixedInto(wrapper)) {
return true;
}
}
}
return false;
return utils.isObject(obj) && obj instanceof Impl.implementation;
};
exports.convert = function convert(obj, { context = "The provided value" } = {}) {
if (exports.is(obj)) {
Expand Down Expand Up @@ -1551,7 +1494,6 @@ class Interface {
this.generateLegacyProxyHandler();
}

this.generateMixins();
this.generateRequires();
}

Expand Down
Loading