UNPKG

typir

Version:

General purpose type checking library

129 lines 6.57 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 { GraphAlgorithms } from '../graph/graph-algorithms.js'; import { TypeEdge } from '../graph/type-edge.js'; import { TypeGraph } from '../graph/type-graph.js'; import { Type } from '../graph/type-node.js'; import { TypirSpecifics, TypirServices } from '../typir.js'; import { TypeEquality } from './equality.js'; /** * Describes the possible conversion modes. * * IMPLICIT means coercion, * e.g. in "3 + 'three'" the int value 3 is implicitly converted to the string value '3'. * By default, this relation is transitive (this could be configured). * Cycles are not allowed for this relation. * * EXPLICIT means casting, * e.g. in "myValue as MyType" the value stored in the variable myValue is explicitly casted to MyType. * By default, this relation is not transitive (this could be configured). * Cycles are allowed for this relation. */ export type ConversionModeForSpecification = /** The conversion is implicitly possible. In this case, the explicit conversion is possible as well (IMPLICIT => EXPLICIT). */ 'IMPLICIT_EXPLICIT' | /** The conversion is only explicitly possible */ 'EXPLICIT'; export type ConversionMode = ConversionModeForSpecification | /** no conversion possible at all (this is the default mode) */ 'NONE' | /** a type is always self-convertible to itself (implicitly or explicitly), in this case no conversion is necessary */ 'SELF'; /** * Manages conversions between different types. * A conversion is a directed relationship between two types. * If a source type can be converted to a target type, the source type could be assignable to the target type (depending on the conversion mode: target := source). */ export interface TypeConversion { /** * Defines the conversion relationship between two types. * @param from the from/source type * @param to the to/target type * @param mode the desired conversion relationship between the two given types * @throws an error, if a cycle was introduced */ markAsConvertible(from: Type, to: Type, mode: ConversionModeForSpecification): void; /** * Identifies the existing conversion relationship between two given types. * @param from the from/source type * @param to the to/target type * @returns the existing conversion relationship between the two given types */ getConversion(from: Type, to: Type): ConversionMode; /** * Checks whether the given two types are implicitly (or explicitly) convertible. * @param from the from/source type * @param to the to/target type * @returns true if the conversion is possible, false otherwise */ isImplicitExplicitConvertible(from: Type, to: Type): boolean; /** * Checks whether the given two types are (only) explicitly convertible. * @param from the from/source type * @param to the to/target type * @returns true if the conversion is possible, false otherwise */ isExplicitConvertible(from: Type, to: Type): boolean; /** * Checks whether the given two types are not convertible (and are not equals). * @param from the from/source type * @param to the to/target type * @returns true if the conversion is not possible, false otherwise */ isNoneConvertible(from: Type, to: Type): boolean; /** * Checks whether the given two types are (implicitly or explicitly) convertible, since they are equal. * @param from the from/source type * @param to the to/target type * @returns true if the types are equal, false otherwise */ isSelfConvertible(from: Type, to: Type): boolean; /** * Checks whether the given two types are convertible (EXPLICIT or IMPLICIT or SELF). * @param from the from/source type * @param to the to/target type * @returns true if the implicit or explicit conversion is possible or the types are equal, false otherwise */ isConvertible(from: Type, to: Type): boolean; /** * Returns all other types to which the given type can be recursively converted. * @param from the source type, which is convertible to the returned types * @param mode only conversion rules with the given conversion mode are considered * @returns the set of recursively reachable types for conversion ("conversion targets") */ getConvertibleTo(from: Type, mode: ConversionModeForSpecification): Set<Type>; } /** * Design decisions: * - Do not store transitive relationships, since they must be removed, when types of the corresponding path are removed! * - Store only EXPLICIT and IMPLICIT relationships, since this is not required, missing edges means NONE/SELF. */ export declare class DefaultTypeConversion<Specifics extends TypirSpecifics> implements TypeConversion { protected readonly equality: TypeEquality; protected readonly graph: TypeGraph; protected readonly algorithms: GraphAlgorithms; constructor(services: TypirServices<Specifics>); markAsConvertible(from: Type, to: Type, mode: ConversionModeForSpecification): void; protected isTransitive(mode: ConversionModeForSpecification): boolean; getConversion(from: Type, to: Type): ConversionMode; protected collectReachableTypes(from: Type, mode: ConversionModeForSpecification): Set<Type>; protected existsEdgePath(from: Type, to: Type, mode: ConversionModeForSpecification): boolean; protected isTransitivelyConvertable(from: Type, to: Type, mode: ConversionModeForSpecification): boolean; isImplicitExplicitConvertible(from: Type, to: Type): boolean; isExplicitConvertible(from: Type, to: Type): boolean; isNoneConvertible(from: Type, to: Type): boolean; isSelfConvertible(from: Type, to: Type): boolean; isConvertible(from: Type, to: Type): boolean; protected getConversionEdge(from: Type, to: Type): ConversionEdge | undefined; getConvertibleTo(from: Type, mode: ConversionModeForSpecification): Set<Type>; } export interface ConversionEdge extends TypeEdge { readonly $relation: 'ConversionEdge'; mode: ConversionMode; } export declare const ConversionEdge = "ConversionEdge"; export declare function isConversionEdge(edge: unknown): edge is ConversionEdge; //# sourceMappingURL=conversion.d.ts.map