UNPKG

typir

Version:

General purpose type checking library

85 lines 3.47 kB
/****************************************************************************** * Copyright 2024 TypeFox GmbH * This program and the accompanying materials are made available under the * terms of the MIT License, which is available in the project root. ******************************************************************************/ import { assertTrue } from '../../utils/utils.js'; import { MultiplicityType } from './multiplicity-type.js'; export const MULTIPLICITY_UNLIMITED = -1; export const MultiplicityKindName = 'MultiplicityTypeKind'; /** * Types of this kind constrain a type with lower bound and upper bound, * e.g. ConstrainedType[1..*] or ConstrainedType[2..4]. */ export class MultiplicityKind { constructor(services, options) { this.options = this.collectOptions(options); this.$name = this.options.$name; this.services = services; this.services.infrastructure.Kinds.register(this); } collectOptions(options) { return Object.assign({ // the default values: $name: MultiplicityKindName, symbolForUnlimited: '*' }, options); } getMultiplicityType(typeDetails) { const key = this.calculateIdentifier(typeDetails); return this.services.infrastructure.Graph.getType(key); } createMultiplicityType(typeDetails) { // check input assertTrue(this.getMultiplicityType(typeDetails) === undefined); if (!this.checkBounds(typeDetails.lowerBound, typeDetails.upperBound)) { throw new Error(); } // create the type with multiplicities const typeWithMultiplicity = new MultiplicityType(this, this.calculateIdentifier(typeDetails), typeDetails); this.services.infrastructure.Graph.addNode(typeWithMultiplicity); this.registerInferenceRules(typeDetails, typeWithMultiplicity); return typeWithMultiplicity; } registerInferenceRules(_typeDetails, _typeWithMultiplicity) { // TODO } calculateIdentifier(typeDetails) { return `${typeDetails.constrainedType.getIdentifier()}${this.printRange(typeDetails.lowerBound, typeDetails.upperBound)}`; } checkBounds(lowerBound, upperBound) { // check range if (lowerBound < 0 || upperBound < -1) { return false; } // upper bound must not be lower than the lower bound if (0 <= lowerBound && 0 <= upperBound && lowerBound > upperBound) { return false; } return true; } printRange(lowerBound, upperBound) { if (lowerBound === upperBound || (lowerBound === 0 && upperBound === MULTIPLICITY_UNLIMITED)) { // [2..2] => [2], [0..*] => [*] return `[${this.printBound(upperBound)}]`; } else { // e.g. [1..3], [1..*] return `[${this.printBound(lowerBound)}..${this.printBound(upperBound)}]`; } } printBound(bound) { return bound === MULTIPLICITY_UNLIMITED ? this.options.symbolForUnlimited : `${bound}`; } isBoundGreaterEquals(leftBound, rightBound) { if (leftBound === MULTIPLICITY_UNLIMITED) { return true; } if (rightBound === MULTIPLICITY_UNLIMITED) { return false; } return leftBound >= rightBound; } } export function isMultiplicityKind(kind) { return kind instanceof MultiplicityKind; } //# sourceMappingURL=multiplicity-kind.js.map