typir
Version:
General purpose type checking library
108 lines • 6.48 kB
TypeScript
/******************************************************************************
* 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