UNPKG

typir

Version:

General purpose type checking library

108 lines 6.48 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 { Type } from '../graph/type-node.js'; import { TypeInitializer } from '../initialization/type-initializer.js'; import { FunctionType } from '../kinds/function/function-type.js'; import { TypirSpecifics, TypirServices } from '../typir.js'; import { NameTypePair } from '../utils/utils-definitions.js'; import { ValidationProblemAcceptor } from './validation.js'; export interface InferOperatorWithSingleOperand<Specifics extends TypirSpecifics, T extends Specifics['LanguageType'] = Specifics['LanguageType']> { languageKey?: string | string[]; filter?: (languageNode: Specifics['LanguageType'], operatorName: string) => languageNode is T; matching: (languageNode: T, operatorName: string) => boolean; operand: (languageNode: T, operatorName: string) => Specifics['LanguageType']; validation?: OperatorValidationRule<FunctionType, Specifics, T> | Array<OperatorValidationRule<FunctionType, Specifics, T>>; validateArgumentsOfCalls?: boolean | ((languageNode: T) => boolean); } export interface InferOperatorWithMultipleOperands<Specifics extends TypirSpecifics, T extends Specifics['LanguageType'] = Specifics['LanguageType']> { languageKey?: string | string[]; filter?: (languageNode: Specifics['LanguageType'], operatorName: string) => languageNode is T; matching: (languageNode: T, operatorName: string) => boolean; operands: (languageNode: T, operatorName: string) => Array<Specifics['LanguageType']>; validation?: OperatorValidationRule<FunctionType, Specifics, T> | Array<OperatorValidationRule<FunctionType, Specifics, T>>; validateArgumentsOfCalls?: boolean | ((languageNode: T) => boolean); } export type OperatorValidationRule<TypeType extends Type, Specifics extends TypirSpecifics, T extends Specifics['LanguageType'] = Specifics['LanguageType']> = (operatorCall: T, operatorName: string, operatorType: TypeType, accept: ValidationProblemAcceptor<Specifics>, typir: TypirServices<Specifics>) => void; export interface AnyOperatorDetails { name: string; } export interface UnaryOperatorDetails extends AnyOperatorDetails { signature?: UnaryOperatorSignature; signatures?: UnaryOperatorSignature[]; } export interface UnaryOperatorSignature { operand: Type; return: Type; } export interface BinaryOperatorDetails extends AnyOperatorDetails { signature?: BinaryOperatorSignature; signatures?: BinaryOperatorSignature[]; } export interface BinaryOperatorSignature { left: Type; right: Type; return: Type; } export interface TernaryOperatorDetails extends AnyOperatorDetails { signature?: TernaryOperatorSignature; signatures?: TernaryOperatorSignature[]; } export interface TernaryOperatorSignature { first: Type; second: Type; third: Type; return: Type; } export interface GenericOperatorDetails extends AnyOperatorDetails { outputType: Type; inputParameter: NameTypePair[]; } export interface OperatorFactoryService<Specifics extends TypirSpecifics> { createUnary(typeDetails: UnaryOperatorDetails): OperatorConfigurationUnaryChain<Specifics>; createBinary(typeDetails: BinaryOperatorDetails): OperatorConfigurationBinaryChain<Specifics>; createTernary(typeDetails: TernaryOperatorDetails): OperatorConfigurationTernaryChain<Specifics>; /** This function allows to create a single operator with arbitrary input operands. */ createGeneric(typeDetails: GenericOperatorDetails): OperatorConfigurationGenericChain<Specifics>; } export interface OperatorConfigurationUnaryChain<Specifics extends TypirSpecifics> { inferenceRule<T extends Specifics['LanguageType']>(rule: InferOperatorWithSingleOperand<Specifics, T>): OperatorConfigurationUnaryChain<Specifics>; finish(): Array<TypeInitializer<Type, Specifics>>; } export interface OperatorConfigurationBinaryChain<Specifics extends TypirSpecifics> { inferenceRule<T extends Specifics['LanguageType']>(rule: InferOperatorWithMultipleOperands<Specifics, T>): OperatorConfigurationBinaryChain<Specifics>; finish(): Array<TypeInitializer<Type, Specifics>>; } export interface OperatorConfigurationTernaryChain<Specifics extends TypirSpecifics> { inferenceRule<T extends Specifics['LanguageType']>(rule: InferOperatorWithMultipleOperands<Specifics, T>): OperatorConfigurationTernaryChain<Specifics>; finish(): Array<TypeInitializer<Type, Specifics>>; } export interface OperatorConfigurationGenericChain<Specifics extends TypirSpecifics> { inferenceRule<T extends Specifics['LanguageType']>(rule: InferOperatorWithSingleOperand<Specifics, T> | InferOperatorWithMultipleOperands<Specifics, T>): OperatorConfigurationGenericChain<Specifics>; finish(): TypeInitializer<Type, Specifics>; } /** * This implementation realizes operators as functions and creates types of kind 'function'. * If Typir does not use the function kind so far, it will be automatically added. * (Alternative implementation strategies for operators would be a dedicated kind for operators, which might extend the 'function' kind) * * Nevertheless, there are some differences between operators and functions: * - Operators have no declaration. * - It is not possible to have references to operators. * * The same operator (i.e. same operator name, e.g. "+" or "XOR") with different types for its operands will be realized as different function types, * e.g. there are two functions for "+" for numbers and for strings. * * All operands are mandatory. */ export declare class DefaultOperatorFactory<Specifics extends TypirSpecifics> implements OperatorFactoryService<Specifics> { protected readonly services: TypirServices<Specifics>; constructor(services: TypirServices<Specifics>); createUnary(typeDetails: UnaryOperatorDetails): OperatorConfigurationUnaryChain<Specifics>; createBinary(typeDetails: BinaryOperatorDetails): OperatorConfigurationBinaryChain<Specifics>; createTernary(typeDetails: TernaryOperatorDetails): OperatorConfigurationTernaryChain<Specifics>; createGeneric(typeDetails: GenericOperatorDetails): OperatorConfigurationGenericChain<Specifics>; } //# sourceMappingURL=operator.d.ts.map