import { Observable } from "../../util/observe"; import type { RuntimeConstruct } from "../constructs/CPPConstruct"; import type { ClassDeclaration } from "../constructs/declarations/class/ClassDeclaration"; import type { ClassDefinition } from "../constructs/declarations/class/ClassDefinition"; import type { MemberVariableDeclaration } from "../constructs/declarations/class/MemberVariableDeclaration"; import type { FunctionDefinitionGroup } from "../constructs/declarations/declarations"; import type { FunctionDeclaration } from "../constructs/declarations/function/FunctionDeclaration"; import type { FunctionDefinition } from "../constructs/declarations/function/FunctionDefinition"; import type { ParameterDefinition } from "../constructs/declarations/function/ParameterDefinition"; import type { GlobalVariableDefinition } from "../constructs/declarations/variable/GlobalVariableDefinition"; import type { LocalVariableDefinition } from "../constructs/declarations/variable/LocalVariableDefinition"; import type { CompilerNote } from "./errors"; import type { FunctionCall } from "../constructs/FunctionCall"; import type { QualifiedName } from "./lexical"; import type { NewObjectType } from "../constructs/expressions/NewExpression"; import type { AutoObject, CPPObject, StaticObject, TemporaryObject } from "../runtime/objects"; import type { PotentialFullExpression } from "../constructs/PotentialFullExpression"; import { RuntimePotentialFullExpression } from "../constructs/RuntimePotentialFullExpression"; import type { ArrayElemType, ArrayOfUnknownBoundType, BoundedArrayType, CompleteClassType, CompleteObjectType, CompleteReturnType, FunctionType, PotentiallyCompleteArrayType, PotentiallyCompleteClassType, PotentiallyCompleteObjectType, ReferenceType, Type, VoidType } from "./types"; import type { SemanticContext } from "./contexts"; export interface EntityDescription { name: string; message: string; } export declare type EntityID = number; export declare abstract class CPPEntity { private static _nextEntityId; readonly observable: Observable; readonly entityId: number; readonly type: T; /** * Most entities will have a natural type, but a few will not (e.g. namespaces). In this case, * I haven't decided what to do. * TODO: fix this - there should probably be a subtype or interface for a TypedEntity */ constructor(type: T); abstract isTyped(this: ObjectEntity, predicate: (t: Type) => t is NarrowedT): this is ObjectEntity; abstract isTyped(predicate: (t: Type) => t is NarrowedT): this is CPPEntity; abstract describe(): EntityDescription; abstract isSemanticallyEquivalent(other: CPPEntity, equivalenceContext: SemanticContext): boolean; } export declare function areEntitiesSemanticallyEquivalent(entity: CPPEntity | undefined, other: CPPEntity | undefined, equivalenceContext: SemanticContext): boolean; export declare abstract class NamedEntity extends CPPEntity { readonly name: string; /** * All NamedEntitys will have a name, but in some cases this might be "". e.g. an unnamed namespace. */ constructor(type: T, name: string); } export declare type DeclarationKind = "variable" | "function" | "class"; declare abstract class DeclaredEntityBase extends NamedEntity { abstract readonly declarationKind: DeclarationKind; constructor(type: T, name: string); } export declare class FunctionOverloadGroup { readonly declarationKind = "function"; readonly name: string; private readonly _overloads; readonly overloads: readonly FunctionEntity[]; constructor(overloads: readonly FunctionEntity[]); addOverload(overload: FunctionEntity): void; /** * Selects a function from the given overload group based on the signature of * the provided function type. (Note there's no consideration of function names here.) * WARNING: This function does NOT perform overload resolution. For example, it does * not consider the possibility of implicit conversions, which is a part of full overload * resolution. It simply looks for an overload with a matching signature. */ selectOverloadBySignature(type: FunctionType): FunctionEntity | undefined; } export declare type ObjectEntityType = CompleteObjectType | ReferenceType; export interface ObjectEntity extends CPPEntity { runtimeLookup(rtConstruct: RuntimeConstruct): CPPObject; readonly variableKind: "object"; } export interface BoundReferenceEntity extends CPPEntity { name?: string; runtimeLookup(this: BoundReferenceEntity>, rtConstruct: RuntimeConstruct): CPPObject | undefined; readonly variableKind: "reference"; } export interface UnboundReferenceEntity extends CPPEntity { name?: string; bindTo(this: UnboundReferenceEntity>, rtConstruct: RuntimeConstruct, obj: CPPObject): void; } export declare function runtimeObjectLookup(entity: ObjectEntity | BoundReferenceEntity>, rtConstruct: RuntimeConstruct): CPPObject; declare abstract class VariableEntityBase extends DeclaredEntityBase { readonly declarationKind = "variable"; abstract readonly variableKind: "reference" | "object"; abstract readonly variableLocation: "local" | "global" | "member"; } export declare class LocalObjectEntity extends VariableEntityBase implements ObjectEntity { readonly variableKind = "object"; readonly variableLocation = "local"; readonly firstDeclaration: LocalVariableDefinition | ParameterDefinition; readonly declarations: readonly LocalVariableDefinition[] | readonly ParameterDefinition[]; readonly definition: LocalVariableDefinition | ParameterDefinition; private readonly _isParameter; constructor(type: T, def: LocalVariableDefinition | ParameterDefinition, isParameter?: boolean); toString(): string; mergeInto(existingEntity: VariableEntity): CompilerNote; runtimeLookup(rtConstruct: RuntimeConstruct): AutoObject; isParameter(): this is LocalObjectParameterEntity; isTyped(predicate: (t: CompleteObjectType) => t is NarrowedT): this is LocalObjectEntity; isTyped(predicate: (t: Type) => t is NarrowedT): this is never; describe(): { name: string; message: string; }; isSemanticallyEquivalent(other: CPPEntity, equivalenceContext: SemanticContext): boolean; } export interface LocalObjectParameterEntity extends LocalObjectEntity { readonly firstDeclaration: ParameterDefinition; readonly declarations: readonly ParameterDefinition[]; readonly definition: ParameterDefinition; } export declare class LocalReferenceEntity extends VariableEntityBase implements BoundReferenceEntity, UnboundReferenceEntity { readonly variableKind = "reference"; readonly variableLocation = "local"; readonly firstDeclaration: LocalVariableDefinition | ParameterDefinition; readonly declarations: readonly LocalVariableDefinition[] | readonly ParameterDefinition[]; readonly definition: LocalVariableDefinition | ParameterDefinition; readonly name: string; private readonly _isParameter; constructor(type: T, def: LocalVariableDefinition | ParameterDefinition, isParameter?: boolean); mergeInto(existingEntity: VariableEntity): CompilerNote; bindTo(this: LocalReferenceEntity>, rtConstruct: RuntimeConstruct, obj: CPPObject): void; runtimeLookup(this: LocalReferenceEntity>, rtConstruct: RuntimeConstruct): CPPObject | undefined; isParameter(): this is LocalReferenceParameterEntity; isTyped(predicate: (t: ReferenceType) => t is NarrowedT): this is LocalReferenceEntity; isTyped(predicate: (t: Type) => t is NarrowedT): this is never; describe(): { name: string; message: string; }; isSemanticallyEquivalent(other: CPPEntity, equivalenceContext: SemanticContext): boolean; } export interface LocalReferenceParameterEntity extends LocalReferenceEntity { readonly firstDeclaration: ParameterDefinition; readonly declarations: readonly ParameterDefinition[]; readonly definition: ParameterDefinition; } export declare class GlobalObjectEntity extends VariableEntityBase { readonly variableKind = "object"; readonly variableLocation = "global"; readonly qualifiedName: QualifiedName; readonly firstDeclaration: GlobalVariableDefinition; readonly declarations: readonly GlobalVariableDefinition[]; readonly definition?: GlobalVariableDefinition; constructor(type: T, decl: GlobalVariableDefinition); toString(): string; mergeInto(existingEntity: VariableEntity): VariableEntity | CompilerNote; registerWithLinker(): void; link(def: GlobalVariableDefinition | undefined): void; runtimeLookup(rtConstruct: RuntimeConstruct): StaticObject; isTyped(predicate: (t: CompleteObjectType) => t is NarrowedT): this is GlobalObjectEntity; isTyped(predicate: (t: Type) => t is NarrowedT): this is never; describe(): { name: string; message: string; }; isSemanticallyEquivalent(other: CPPEntity, equivalenceContext: SemanticContext): boolean; } export declare type VariableEntity = LocalVariableEntity | GlobalVariableEntity | MemberVariableEntity; export declare type LocalVariableEntity = LocalObjectEntity> | LocalReferenceEntity>; export declare type GlobalVariableEntity = GlobalObjectEntity> | never; export declare type MemberVariableEntity = MemberObjectEntity> | MemberReferenceEntity>; /** * Looking this entity up at runtime yields the return object of the containing runtime function. * Note this is generally only something you would want in the context of a return-by-value * function, in which case the return object is a temporary object created to eventually be initialized * with the returned value. In a pass-by-reference function, the return object will only exist once the * return has been processed and it is set to the returned object. In void function, there is no return * object. * @throws Throws an exception if the return object does not exist. */ export declare class ReturnObjectEntity extends CPPEntity implements ObjectEntity { readonly variableKind = "object"; runtimeLookup(rtConstruct: RuntimeConstruct): CPPObject; isTyped(predicate: (t: CompleteObjectType) => t is NarrowedT): this is ReturnObjectEntity; isTyped(predicate: (t: Type) => t is NarrowedT): this is never; describe(): { name: string; message: string; }; isSemanticallyEquivalent(other: CPPEntity, equivalenceContext: SemanticContext): boolean; } export declare class ReturnByReferenceEntity extends CPPEntity implements UnboundReferenceEntity { bindTo(this: ReturnByReferenceEntity>, rtConstruct: RuntimeConstruct, obj: CPPObject): void; isTyped(predicate: (t: ReferenceType) => t is NarrowedT): this is ReturnByReferenceEntity; isTyped(predicate: (t: Type) => t is NarrowedT): this is never; describe(): { name: string; message: string; }; isSemanticallyEquivalent(other: CPPEntity, equivalenceContext: SemanticContext): boolean; } export declare class PassByValueParameterEntity extends CPPEntity implements ObjectEntity { readonly variableKind = "object"; readonly calledFunction: FunctionEntity; readonly type: T; readonly num: number; constructor(calledFunction: FunctionEntity, type: T, num: number); runtimeLookup(rtConstruct: RuntimeConstruct): AutoObject; isTyped(predicate: (t: CompleteObjectType) => t is NarrowedT): this is PassByValueParameterEntity; isTyped(predicate: (t: Type) => t is NarrowedT): this is never; describe(): { name: string; message: string; }; isSemanticallyEquivalent(other: CPPEntity, equivalenceContext: SemanticContext): boolean; } export declare class PassByReferenceParameterEntity extends CPPEntity implements UnboundReferenceEntity { readonly calledFunction: FunctionEntity; readonly num: number; constructor(calledFunction: FunctionEntity, type: T, num: number); bindTo(this: PassByReferenceParameterEntity>, rtConstruct: RuntimeConstruct, obj: CPPObject): void; isTyped(predicate: (t: ReferenceType) => t is NarrowedT): this is PassByReferenceParameterEntity; isTyped(predicate: (t: Type) => t is NarrowedT): this is never; describe(): { name: string; message: string; }; isSemanticallyEquivalent(other: CPPEntity, equivalenceContext: SemanticContext): boolean; } export declare class ReceiverEntity extends CPPEntity implements ObjectEntity { readonly variableKind = "object"; constructor(type: CompleteClassType); toString(): string; runtimeLookup(rtConstruct: RuntimeConstruct): CPPObject; isTyped(predicate: (t: CompleteClassType) => t is NarrowedT): this is ReceiverEntity; isTyped(predicate: (t: Type) => t is NarrowedT): this is never; describe(): { name: string; message: string; }; isSemanticallyEquivalent(other: CPPEntity, equivalenceContext: SemanticContext): boolean; } export declare class NewObjectEntity extends CPPEntity implements ObjectEntity { readonly variableKind = "object"; runtimeLookup(rtConstruct: RuntimeConstruct): import("../runtime/objects").DynamicObject; isTyped(predicate: (t: NewObjectType) => t is NarrowedT): this is NewObjectEntity; isTyped(predicate: (t: Type) => t is NarrowedT): this is never; describe(): { name: string; message: string; }; isSemanticallyEquivalent(other: CPPEntity, equivalenceContext: SemanticContext): boolean; } export declare class NewArrayEntity extends CPPEntity { readonly variableKind = "object"; runtimeLookup(rtConstruct: RuntimeConstruct): import("../runtime/objects").DynamicObject> | undefined; isTyped(predicate: (t: PotentiallyCompleteArrayType) => t is NarrowedT): this is NewArrayEntity; isTyped(predicate: (t: Type) => t is NarrowedT): this is never; describe(): { name: string; message: string; }; isSemanticallyEquivalent(other: CPPEntity, equivalenceContext: SemanticContext): boolean; } export declare class ArraySubobjectEntity extends CPPEntity implements ObjectEntity { readonly variableKind = "object"; readonly arrayEntity: ObjectEntity>; readonly index: number; constructor(arrayEntity: ObjectEntity>, index: number); runtimeLookup(rtConstruct: RuntimeConstruct): import("../runtime/objects").ArraySubobject; isTyped(predicate: (t: ArrayElemType) => t is NarrowedT): this is ArraySubobjectEntity; isTyped(predicate: (t: Type) => t is NarrowedT): this is never; describe(): { name: string; message: string; }; isSemanticallyEquivalent(other: CPPEntity, equivalenceContext: SemanticContext): boolean; } export declare class DynamicLengthArrayNextElementEntity extends CPPEntity implements ObjectEntity { readonly variableKind = "object"; readonly arrayEntity: NewArrayEntity>; constructor(arrayEntity: NewArrayEntity>); runtimeLookup(rtConstruct: RuntimeConstruct): import("../runtime/objects").ArraySubobject; isTyped(predicate: (t: ArrayElemType) => t is NarrowedT): this is ArraySubobjectEntity; isTyped(predicate: (t: Type) => t is NarrowedT): this is never; describe(): { name: string; message: string; }; isSemanticallyEquivalent(other: CPPEntity, equivalenceContext: SemanticContext): boolean; } export declare class BaseSubobjectEntity extends CPPEntity implements ObjectEntity { readonly variableKind = "object"; readonly containingEntity: ObjectEntity; constructor(containingEntity: ObjectEntity, type: CompleteClassType); runtimeLookup(rtConstruct: RuntimeConstruct): import("../runtime/objects").BaseSubobject; isTyped(predicate: (t: CompleteClassType) => t is NarrowedT): this is BaseSubobjectEntity; isTyped(predicate: (t: Type) => t is NarrowedT): this is never; describe(): { name: string; message: string; }; isSemanticallyEquivalent(other: CPPEntity, equivalenceContext: SemanticContext): boolean; } declare abstract class MemberVariableEntityBase extends VariableEntityBase { readonly variableLocation = "member"; readonly firstDeclaration: MemberVariableDeclaration; readonly declarations: readonly MemberVariableDeclaration[]; readonly definition: undefined; constructor(type: T, decl: MemberVariableDeclaration); toString(): string; mergeInto(existingEntity: VariableEntity): CompilerNote; describe(): { name: string; message: string; }; } export declare class MemberObjectEntity extends MemberVariableEntityBase { readonly variableKind = "object"; runtimeLookup(rtConstruct: RuntimeConstruct): CPPObject; isTyped(predicate: (t: CompleteObjectType) => t is NarrowedT): this is MemberObjectEntity; isTyped(predicate: (t: Type) => t is NarrowedT): this is never; isSemanticallyEquivalent(other: CPPEntity, equivalenceContext: SemanticContext): boolean; } export declare class MemberReferenceEntity extends MemberVariableEntityBase implements BoundReferenceEntity, UnboundReferenceEntity { readonly variableKind = "reference"; runtimeLookup(this: MemberReferenceEntity>, rtConstruct: RuntimeConstruct): CPPObject; bindTo(this: MemberReferenceEntity>, rtConstruct: RuntimeConstruct, obj: CPPObject): void; isTyped(predicate: (t: ReferenceType) => t is NarrowedT): this is MemberReferenceEntity; isTyped(predicate: (t: Type) => t is NarrowedT): this is never; isSemanticallyEquivalent(other: CPPEntity, equivalenceContext: SemanticContext): boolean; } export declare class TemporaryObjectEntity extends CPPEntity implements ObjectEntity { readonly variableKind = "object"; protected static readonly _name = "TemporaryObjectEntity"; readonly creator: PotentialFullExpression | FunctionCall; readonly owner: PotentialFullExpression | FunctionCall; readonly name: string; constructor(type: T, creator: PotentialFullExpression | FunctionCall, owner: PotentialFullExpression | FunctionCall, name: string); setOwner(newOwner: PotentialFullExpression | FunctionCall): void; objectInstance(creatorRt: RuntimePotentialFullExpression): TemporaryObject; runtimeLookup(rtConstruct: RuntimeConstruct): TemporaryObject; isTyped(predicate: (t: CompleteObjectType) => t is NarrowedT): this is TemporaryObjectEntity; isTyped(predicate: (t: Type) => t is NarrowedT): this is never; describe(): { name: string; message: string; }; isSemanticallyEquivalent(other: CPPEntity, equivalenceContext: SemanticContext): boolean; } export declare class FunctionEntity extends DeclaredEntityBase { readonly declarationKind = "function"; readonly qualifiedName: QualifiedName; readonly firstDeclaration: FunctionDeclaration; readonly declarations: readonly FunctionDeclaration[]; readonly definition?: FunctionDefinition; readonly isMemberFunction: boolean; readonly isVirtual: boolean; readonly isPureVirtual: boolean; readonly isConstructor: boolean; readonly isDestructor: boolean; readonly isOdrUsed: boolean; readonly isImplicit: boolean; readonly isUserDefined: boolean; readonly overrideID: number; readonly overriders: { [index: string]: FunctionEntity; }; readonly overrideTarget?: FunctionEntity; constructor(type: T, decl: FunctionDeclaration); addDeclaration(decl: FunctionDeclaration): void; addDeclarations(decls: readonly FunctionDeclaration[]): void; toString(): string; registerOverrider(containingClass: ClassEntity, overrider: FunctionEntity): void; setOverrideTarget(target: FunctionEntity): void; mergeInto(overloadGroup: FunctionOverloadGroup): FunctionEntity | CompilerNote; setDefinition(def: FunctionDefinition): void; registerWithLinker(): void; link(def: FunctionDefinitionGroup | undefined): void; isMain(): boolean; getDynamicallyBoundFunction(receiver: CPPObject | undefined): FunctionDefinition | undefined; registerCall(call: FunctionCall): void; returnsVoid(): this is FunctionEntity>; returnsCompleteType(): this is FunctionEntity>; isTyped(predicate: (t: FunctionType) => t is NarrowedT): this is FunctionEntity; isTyped(predicate: (t: Type) => t is NarrowedT): this is never; describe(): EntityDescription; isSemanticallyEquivalent(other: CPPEntity, equivalenceContext: SemanticContext): boolean; } export declare class ClassEntity extends DeclaredEntityBase { readonly declarationKind = "class"; readonly qualifiedName: QualifiedName; readonly firstDeclaration: ClassDeclaration; readonly declarations: readonly ClassDeclaration[]; readonly definition?: ClassDefinition; constructor(decl: ClassDeclaration); isComplete(): this is CompleteClassEntity; toString(): string; addDeclaration(decl: ClassDeclaration): void; addDeclarations(decls: readonly ClassDeclaration[]): void; /** * Merge this class entity into a previous existing class entity. * If exactly one of the entities has a definition, the other one assumes * that definition as well. If both have a definition, an error is returned * unless the two are literally the same definition. (Note that an error * is thrown in the case of separate definitions with the same exact source * tokens, because the use of `mergeInto` means these definitions occur in the * same translation unit, which is prohibited.) * @param existingEntity */ mergeInto(existingEntity: ClassEntity): CompilerNote | ClassEntity; setDefinition(def: ClassDefinition): void; registerWithLinker(): void; link(def: ClassDefinition | undefined): void; isTyped(predicate: (t: PotentiallyCompleteClassType) => t is NarrowedT): this is ClassEntity; isTyped(predicate: (t: Type) => t is NarrowedT): this is never; describe(): EntityDescription; isSemanticallyEquivalent(other: CPPEntity, equivalenceContext: SemanticContext): boolean; } export interface CompleteClassEntity extends ClassEntity { readonly type: CompleteClassType; readonly definition: ClassDefinition; } /** * Selects a function from the given overload group based on the signature of * the provided function type. (Note there's no consideration of function names here.) */ export declare function selectOverloadedDefinition(overloadGroup: readonly FunctionDefinition[], type: FunctionType): FunctionDefinition | undefined; export {};