@composita/symbols
Version:
Composita language symbols.
48 lines • 2.11 kB
JavaScript
export class InterfaceDeclarationSymbol {
constructor(interfaceSymbol, cardinality) {
this.interfaceSymbol = interfaceSymbol;
this.cardinality = cardinality;
}
}
export class CardinalitySymbol {
constructor(min, max = min) {
this.min = min;
this.max = max;
if (min < 1) {
throw new Error('cardinality must be greater 0');
}
if (max !== undefined && max < min) {
throw new Error(`min ${min} must be greater than max ${max}`);
}
}
unlimited() {
return this.max === Infinity;
}
}
export class GenericSymbol {
constructor(offered, required) {
this.offered = offered;
this.required = required;
GenericSymbol.validate(this.offered, 'Offered interface defined multiple times.');
GenericSymbol.validate(this.required, 'Required interface defined multiple times.');
}
static validate(data, msg) {
const uniqueNames = new Array(...new Set(data.map((offer) => offer.interfaceSymbol.identifier)));
if (uniqueNames.length !== data.length) {
throw new Error(msg);
}
}
static matchInterfaceDeclarations(genericAInterfaces, genericBInterfaces, minCompare, maxCompare) {
return (genericAInterfaces.filter((genericAInterface) => genericBInterfaces.find((genericBInterface) => genericAInterface.interfaceSymbol === genericBInterface.interfaceSymbol &&
maxCompare(genericAInterface.cardinality.max, genericBInterface.cardinality.max) &&
minCompare(genericAInterface.cardinality.min, genericBInterface.cardinality.min)) !== undefined).length === genericAInterfaces.length);
}
canBeSubstitutedBy(other) {
return (GenericSymbol.matchInterfaceDeclarations(this.offered, other.offered, (a, b) => a >= b, (a, b) => a >= b) &&
GenericSymbol.matchInterfaceDeclarations(this.required, other.required, (a, b) => a <= b, (a, b) => a <= b));
}
canSubstitute(other) {
return other.canBeSubstitutedBy(this);
}
}
//# sourceMappingURL=generic-symbols.js.map