@composita/symbols
Version: 
Composita language symbols.
54 lines • 2.41 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.GenericSymbol = exports.CardinalitySymbol = exports.InterfaceDeclarationSymbol = void 0;
class InterfaceDeclarationSymbol {
    constructor(interfaceSymbol, cardinality) {
        this.interfaceSymbol = interfaceSymbol;
        this.cardinality = cardinality;
    }
}
exports.InterfaceDeclarationSymbol = InterfaceDeclarationSymbol;
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;
    }
}
exports.CardinalitySymbol = CardinalitySymbol;
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);
    }
}
exports.GenericSymbol = GenericSymbol;
//# sourceMappingURL=generic-symbols.js.map