From 9465cb2100bedcb45cab56f6c45c4977bc68b3e4 Mon Sep 17 00:00:00 2001 From: Mofei Zhang Date: Mon, 13 Mar 2023 14:52:15 -0400 Subject: [PATCH] [hir] Move Types to a separate file --- Move types around in preparation for next PR #1335. No changes in impl, types, or functions. --- compiler/forget/src/HIR/HIR.ts | 119 +----------------------------- compiler/forget/src/HIR/Types.ts | 123 +++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 116 deletions(-) create mode 100644 compiler/forget/src/HIR/Types.ts diff --git a/compiler/forget/src/HIR/HIR.ts b/compiler/forget/src/HIR/HIR.ts index 763695da43..8ed931c45b 100644 --- a/compiler/forget/src/HIR/HIR.ts +++ b/compiler/forget/src/HIR/HIR.ts @@ -8,7 +8,7 @@ import * as t from "@babel/types"; import invariant from "invariant"; import { Environment } from "./Environment"; -import { Hook } from "./Hooks"; +import { Type } from "./Types"; // ******************************************************************************************* // ******************************************************************************************* @@ -763,121 +763,6 @@ export function makeInstructionId(id: number): InstructionId { return id as InstructionId; } -export type Type = - | PrimitiveType - | HookType - | FunctionType - | ObjectType - | PhiType - | PolyType - | TypeVar; -export type PrimitiveType = { kind: "Primitive" }; -export type FunctionType = { - kind: "Function"; -}; -export type HookType = { - kind: "Hook"; - definition: Hook; -}; -export type ObjectType = { kind: "Object" }; -export type TypeVar = { - kind: "Type"; - id: TypeId; -}; -export type PolyType = { - kind: "Poly"; -}; -export type PhiType = { - kind: "Phi"; - operands: Array; -}; - -/** - * Simulated opaque type for TypeId to prevent using normal numbers as ids - * accidentally. - */ -const opaqueTypeId = Symbol(); -export type TypeId = number & { [opaqueTypeId]: "IdentifierId" }; - -export function makeTypeId(id: number): TypeId { - invariant( - id >= 0 && Number.isInteger(id), - "Expected instruction id to be a non-negative integer" - ); - return id as TypeId; -} - -let typeCounter = 0; -export function makeType(): TypeVar { - return { - kind: "Type", - id: makeTypeId(typeCounter++), - }; -} - -export function typeEquals(tA: Type, tB: Type): boolean { - if (tA.kind !== tB.kind) return false; - return ( - typeVarEquals(tA, tB) || - funcTypeEquals(tA, tB) || - hookTypeEquals(tA, tB) || - objectTypeEquals(tA, tB) || - primitiveTypeEquals(tA, tB) || - polyTypeEquals(tA, tB) || - phiTypeEquals(tA, tB) - ); -} - -function typeVarEquals(tA: Type, tB: Type): boolean { - if (tA.kind === "Type" && tB.kind === "Type") { - return tA.id === tB.id; - } - return false; -} - -function typeKindCheck(tA: Type, tb: Type, type: string): boolean { - return tA.kind === type && tb.kind === type; -} - -function primitiveTypeEquals(tA: Type, tB: Type): boolean { - return typeKindCheck(tA, tB, "Primitive"); -} - -function polyTypeEquals(tA: Type, tB: Type): boolean { - return typeKindCheck(tA, tB, "Poly"); -} - -function objectTypeEquals(tA: Type, tB: Type): boolean { - return typeKindCheck(tA, tB, "Object"); -} - -function funcTypeEquals(tA: Type, tB: Type): boolean { - return typeKindCheck(tA, tB, "Function"); -} - -function hookTypeEquals(tA: Type, tB: Type): boolean { - return ( - tA.kind === "Hook" && tB.kind === "Hook" && tA.definition === tB.definition - ); -} - -function phiTypeEquals(tA: Type, tB: Type): boolean { - if (tA.kind === "Phi" && tB.kind === "Phi") { - if (tA.operands.length !== tB.operands.length) { - return false; - } - - let operands = new Set(tA.operands); - for (let i = 0; i < tB.operands.length; i++) { - if (!operands.has(tB.operands[i])) { - return false; - } - } - } - - return false; -} - export function isObjectType(id: Identifier): boolean { return id.type.kind === "Object"; } @@ -889,3 +774,5 @@ export function isPrimitiveType(id: Identifier): boolean { export function isHookType(id: Identifier): boolean { return id.type.kind === "Hook"; } + +export * from "./Types"; diff --git a/compiler/forget/src/HIR/Types.ts b/compiler/forget/src/HIR/Types.ts new file mode 100644 index 0000000000..959bb52751 --- /dev/null +++ b/compiler/forget/src/HIR/Types.ts @@ -0,0 +1,123 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import invariant from "invariant"; +import { Hook } from "./Hooks"; + +export type Type = + | PrimitiveType + | HookType + | FunctionType + | ObjectType + | PhiType + | PolyType + | TypeVar; +export type PrimitiveType = { kind: "Primitive" }; +export type FunctionType = { + kind: "Function"; +}; +export type HookType = { + kind: "Hook"; + definition: Hook; +}; +export type ObjectType = { kind: "Object" }; +export type TypeVar = { + kind: "Type"; + id: TypeId; +}; +export type PolyType = { + kind: "Poly"; +}; +export type PhiType = { + kind: "Phi"; + operands: Array; +}; + +/** + * Simulated opaque type for TypeId to prevent using normal numbers as ids + * accidentally. + */ +const opaqueTypeId = Symbol(); +export type TypeId = number & { [opaqueTypeId]: "IdentifierId" }; + +export function makeTypeId(id: number): TypeId { + invariant( + id >= 0 && Number.isInteger(id), + "Expected instruction id to be a non-negative integer" + ); + return id as TypeId; +} + +let typeCounter = 0; +export function makeType(): TypeVar { + return { + kind: "Type", + id: makeTypeId(typeCounter++), + }; +} + +export function typeEquals(tA: Type, tB: Type): boolean { + if (tA.kind !== tB.kind) return false; + return ( + typeVarEquals(tA, tB) || + funcTypeEquals(tA, tB) || + hookTypeEquals(tA, tB) || + objectTypeEquals(tA, tB) || + primitiveTypeEquals(tA, tB) || + polyTypeEquals(tA, tB) || + phiTypeEquals(tA, tB) + ); +} + +function typeVarEquals(tA: Type, tB: Type): boolean { + if (tA.kind === "Type" && tB.kind === "Type") { + return tA.id === tB.id; + } + return false; +} + +function typeKindCheck(tA: Type, tb: Type, type: string): boolean { + return tA.kind === type && tb.kind === type; +} + +function primitiveTypeEquals(tA: Type, tB: Type): boolean { + return typeKindCheck(tA, tB, "Primitive"); +} + +function polyTypeEquals(tA: Type, tB: Type): boolean { + return typeKindCheck(tA, tB, "Poly"); +} + +function objectTypeEquals(tA: Type, tB: Type): boolean { + return typeKindCheck(tA, tB, "Object"); +} + +function funcTypeEquals(tA: Type, tB: Type): boolean { + return typeKindCheck(tA, tB, "Function"); +} + +function hookTypeEquals(tA: Type, tB: Type): boolean { + return ( + tA.kind === "Hook" && tB.kind === "Hook" && tA.definition === tB.definition + ); +} + +function phiTypeEquals(tA: Type, tB: Type): boolean { + if (tA.kind === "Phi" && tB.kind === "Phi") { + if (tA.operands.length !== tB.operands.length) { + return false; + } + + let operands = new Set(tA.operands); + for (let i = 0; i < tB.operands.length; i++) { + if (!operands.has(tB.operands[i])) { + return false; + } + } + } + + return false; +}