Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50850bbac6 |
@@ -0,0 +1,752 @@
|
|||||||
|
/**
|
||||||
|
* TypeScript definitions for Flow type JSON representations
|
||||||
|
* Based on the output of /data/sandcastle/boxes/fbsource/fbcode/flow/src/typing/convertTypes.ml
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Base type for all Flow types with a kind field
|
||||||
|
export interface BaseFlowType {
|
||||||
|
kind: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type for representing polarity
|
||||||
|
export type Polarity = 'positive' | 'negative' | 'neutral';
|
||||||
|
|
||||||
|
// Type for representing a name that might be null
|
||||||
|
export type OptionalName = string | null;
|
||||||
|
|
||||||
|
// Open type
|
||||||
|
export interface OpenType extends BaseFlowType {
|
||||||
|
kind: 'Open';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Def type
|
||||||
|
export interface DefType extends BaseFlowType {
|
||||||
|
kind: 'Def';
|
||||||
|
def: DefT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Eval type
|
||||||
|
export interface EvalType extends BaseFlowType {
|
||||||
|
kind: 'Eval';
|
||||||
|
type: FlowType;
|
||||||
|
destructor: Destructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generic type
|
||||||
|
export interface GenericType extends BaseFlowType {
|
||||||
|
kind: 'Generic';
|
||||||
|
name: string;
|
||||||
|
bound: FlowType;
|
||||||
|
no_infer: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ThisInstance type
|
||||||
|
export interface ThisInstanceType extends BaseFlowType {
|
||||||
|
kind: 'ThisInstance';
|
||||||
|
instance: InstanceT;
|
||||||
|
is_this: boolean;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ThisTypeApp type
|
||||||
|
export interface ThisTypeAppType extends BaseFlowType {
|
||||||
|
kind: 'ThisTypeApp';
|
||||||
|
t1: FlowType;
|
||||||
|
t2: FlowType;
|
||||||
|
t_list?: Array<FlowType>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TypeApp type
|
||||||
|
export interface TypeAppType extends BaseFlowType {
|
||||||
|
kind: 'TypeApp';
|
||||||
|
type: FlowType;
|
||||||
|
targs: Array<FlowType>;
|
||||||
|
from_value: boolean;
|
||||||
|
use_desc: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FunProto type
|
||||||
|
export interface FunProtoType extends BaseFlowType {
|
||||||
|
kind: 'FunProto';
|
||||||
|
}
|
||||||
|
|
||||||
|
// ObjProto type
|
||||||
|
export interface ObjProtoType extends BaseFlowType {
|
||||||
|
kind: 'ObjProto';
|
||||||
|
}
|
||||||
|
|
||||||
|
// NullProto type
|
||||||
|
export interface NullProtoType extends BaseFlowType {
|
||||||
|
kind: 'NullProto';
|
||||||
|
}
|
||||||
|
|
||||||
|
// FunProtoBind type
|
||||||
|
export interface FunProtoBindType extends BaseFlowType {
|
||||||
|
kind: 'FunProtoBind';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Intersection type
|
||||||
|
export interface IntersectionType extends BaseFlowType {
|
||||||
|
kind: 'Intersection';
|
||||||
|
members: Array<FlowType>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Union type
|
||||||
|
export interface UnionType extends BaseFlowType {
|
||||||
|
kind: 'Union';
|
||||||
|
members: Array<FlowType>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maybe type
|
||||||
|
export interface MaybeType extends BaseFlowType {
|
||||||
|
kind: 'Maybe';
|
||||||
|
type: FlowType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optional type
|
||||||
|
export interface OptionalType extends BaseFlowType {
|
||||||
|
kind: 'Optional';
|
||||||
|
type: FlowType;
|
||||||
|
use_desc: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keys type
|
||||||
|
export interface KeysType extends BaseFlowType {
|
||||||
|
kind: 'Keys';
|
||||||
|
type: FlowType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Annot type
|
||||||
|
export interface AnnotType extends BaseFlowType {
|
||||||
|
kind: 'Annot';
|
||||||
|
type: FlowType;
|
||||||
|
use_desc: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Opaque type
|
||||||
|
export interface OpaqueType extends BaseFlowType {
|
||||||
|
kind: 'Opaque';
|
||||||
|
opaquetype: {
|
||||||
|
opaque_id: string;
|
||||||
|
underlying_t: FlowType | null;
|
||||||
|
super_t: FlowType | null;
|
||||||
|
opaque_type_args: Array<{
|
||||||
|
name: string;
|
||||||
|
type: FlowType;
|
||||||
|
polarity: Polarity;
|
||||||
|
}>;
|
||||||
|
opaque_name: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Namespace type
|
||||||
|
export interface NamespaceType extends BaseFlowType {
|
||||||
|
kind: 'Namespace';
|
||||||
|
namespace_symbol: {
|
||||||
|
symbol: string;
|
||||||
|
};
|
||||||
|
values_type: FlowType;
|
||||||
|
types_tmap: PropertyMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any type
|
||||||
|
export interface AnyType extends BaseFlowType {
|
||||||
|
kind: 'Any';
|
||||||
|
}
|
||||||
|
|
||||||
|
// StrUtil type
|
||||||
|
export interface StrUtilType extends BaseFlowType {
|
||||||
|
kind: 'StrUtil';
|
||||||
|
op: 'StrPrefix' | 'StrSuffix';
|
||||||
|
prefix?: string;
|
||||||
|
suffix?: string;
|
||||||
|
remainder?: FlowType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TypeParam definition
|
||||||
|
export interface TypeParam {
|
||||||
|
name: string;
|
||||||
|
bound: FlowType;
|
||||||
|
polarity: Polarity;
|
||||||
|
default: FlowType | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnumInfo types
|
||||||
|
export type EnumInfo = ConcreteEnum | AbstractEnum;
|
||||||
|
|
||||||
|
export interface ConcreteEnum {
|
||||||
|
kind: 'ConcreteEnum';
|
||||||
|
enum_name: string;
|
||||||
|
enum_id: string;
|
||||||
|
members: Array<string>;
|
||||||
|
representation_t: FlowType;
|
||||||
|
has_unknown_members: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AbstractEnum {
|
||||||
|
kind: 'AbstractEnum';
|
||||||
|
representation_t: FlowType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanonicalRendersForm types
|
||||||
|
export type CanonicalRendersForm =
|
||||||
|
| InstrinsicRenders
|
||||||
|
| NominalRenders
|
||||||
|
| StructuralRenders
|
||||||
|
| DefaultRenders;
|
||||||
|
|
||||||
|
export interface InstrinsicRenders {
|
||||||
|
kind: 'InstrinsicRenders';
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NominalRenders {
|
||||||
|
kind: 'NominalRenders';
|
||||||
|
renders_id: string;
|
||||||
|
renders_name: string;
|
||||||
|
renders_super: FlowType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StructuralRenders {
|
||||||
|
kind: 'StructuralRenders';
|
||||||
|
renders_variant: 'RendersNormal' | 'RendersMaybe' | 'RendersStar';
|
||||||
|
renders_structural_type: FlowType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DefaultRenders {
|
||||||
|
kind: 'DefaultRenders';
|
||||||
|
}
|
||||||
|
|
||||||
|
// InstanceT definition
|
||||||
|
export interface InstanceT {
|
||||||
|
inst: InstType;
|
||||||
|
static: FlowType;
|
||||||
|
super: FlowType;
|
||||||
|
implements: Array<FlowType>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// InstType definition
|
||||||
|
export interface InstType {
|
||||||
|
class_name: string | null;
|
||||||
|
class_id: string;
|
||||||
|
type_args: Array<{
|
||||||
|
name: string;
|
||||||
|
type: FlowType;
|
||||||
|
polarity: Polarity;
|
||||||
|
}>;
|
||||||
|
own_props: PropertyMap;
|
||||||
|
proto_props: PropertyMap;
|
||||||
|
call_t: null | {
|
||||||
|
id: number;
|
||||||
|
call: FlowType;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefT types
|
||||||
|
export type DefT =
|
||||||
|
| NumGeneralType
|
||||||
|
| StrGeneralType
|
||||||
|
| BoolGeneralType
|
||||||
|
| BigIntGeneralType
|
||||||
|
| EmptyType
|
||||||
|
| MixedType
|
||||||
|
| NullType
|
||||||
|
| VoidType
|
||||||
|
| SymbolType
|
||||||
|
| FunType
|
||||||
|
| ObjType
|
||||||
|
| ArrType
|
||||||
|
| ClassType
|
||||||
|
| InstanceType
|
||||||
|
| SingletonStrType
|
||||||
|
| NumericStrKeyType
|
||||||
|
| SingletonNumType
|
||||||
|
| SingletonBoolType
|
||||||
|
| SingletonBigIntType
|
||||||
|
| TypeType
|
||||||
|
| PolyType
|
||||||
|
| ReactAbstractComponentType
|
||||||
|
| RendersType
|
||||||
|
| EnumValueType
|
||||||
|
| EnumObjectType;
|
||||||
|
|
||||||
|
export interface NumGeneralType extends BaseFlowType {
|
||||||
|
kind: 'NumGeneral';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StrGeneralType extends BaseFlowType {
|
||||||
|
kind: 'StrGeneral';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BoolGeneralType extends BaseFlowType {
|
||||||
|
kind: 'BoolGeneral';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BigIntGeneralType extends BaseFlowType {
|
||||||
|
kind: 'BigIntGeneral';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EmptyType extends BaseFlowType {
|
||||||
|
kind: 'Empty';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MixedType extends BaseFlowType {
|
||||||
|
kind: 'Mixed';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NullType extends BaseFlowType {
|
||||||
|
kind: 'Null';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface VoidType extends BaseFlowType {
|
||||||
|
kind: 'Void';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SymbolType extends BaseFlowType {
|
||||||
|
kind: 'Symbol';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FunType extends BaseFlowType {
|
||||||
|
kind: 'Fun';
|
||||||
|
static: FlowType;
|
||||||
|
funtype: FunTypeObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ObjType extends BaseFlowType {
|
||||||
|
kind: 'Obj';
|
||||||
|
objtype: ObjTypeObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ArrType extends BaseFlowType {
|
||||||
|
kind: 'Arr';
|
||||||
|
arrtype: ArrTypeObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ClassType extends BaseFlowType {
|
||||||
|
kind: 'Class';
|
||||||
|
type: FlowType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InstanceType extends BaseFlowType {
|
||||||
|
kind: 'Instance';
|
||||||
|
instance: InstanceT;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SingletonStrType extends BaseFlowType {
|
||||||
|
kind: 'SingletonStr';
|
||||||
|
from_annot: boolean;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NumericStrKeyType extends BaseFlowType {
|
||||||
|
kind: 'NumericStrKey';
|
||||||
|
number: string;
|
||||||
|
string: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SingletonNumType extends BaseFlowType {
|
||||||
|
kind: 'SingletonNum';
|
||||||
|
from_annot: boolean;
|
||||||
|
number: string;
|
||||||
|
string: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SingletonBoolType extends BaseFlowType {
|
||||||
|
kind: 'SingletonBool';
|
||||||
|
from_annot: boolean;
|
||||||
|
value: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SingletonBigIntType extends BaseFlowType {
|
||||||
|
kind: 'SingletonBigInt';
|
||||||
|
from_annot: boolean;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TypeType extends BaseFlowType {
|
||||||
|
kind: 'Type';
|
||||||
|
type_kind: TypeTKind;
|
||||||
|
type: FlowType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TypeTKind =
|
||||||
|
| 'TypeAliasKind'
|
||||||
|
| 'TypeParamKind'
|
||||||
|
| 'OpaqueKind'
|
||||||
|
| 'ImportTypeofKind'
|
||||||
|
| 'ImportClassKind'
|
||||||
|
| 'ImportEnumKind'
|
||||||
|
| 'InstanceKind'
|
||||||
|
| 'RenderTypeKind';
|
||||||
|
|
||||||
|
export interface PolyType extends BaseFlowType {
|
||||||
|
kind: 'Poly';
|
||||||
|
tparams: Array<TypeParam>;
|
||||||
|
t_out: FlowType;
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReactAbstractComponentType extends BaseFlowType {
|
||||||
|
kind: 'ReactAbstractComponent';
|
||||||
|
config: FlowType;
|
||||||
|
renders: FlowType;
|
||||||
|
instance: ComponentInstance;
|
||||||
|
component_kind: ComponentKind;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ComponentInstance =
|
||||||
|
| {kind: 'RefSetterProp'; type: FlowType}
|
||||||
|
| {kind: 'Omitted'};
|
||||||
|
|
||||||
|
export type ComponentKind =
|
||||||
|
| {kind: 'Structural'}
|
||||||
|
| {kind: 'Nominal'; id: string; name: string; types: Array<FlowType> | null};
|
||||||
|
|
||||||
|
export interface RendersType extends BaseFlowType {
|
||||||
|
kind: 'Renders';
|
||||||
|
form: CanonicalRendersForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EnumValueType extends BaseFlowType {
|
||||||
|
kind: 'EnumValue';
|
||||||
|
enum_info: EnumInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EnumObjectType extends BaseFlowType {
|
||||||
|
kind: 'EnumObject';
|
||||||
|
enum_value_t: FlowType;
|
||||||
|
enum_info: EnumInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ObjKind types
|
||||||
|
export type ObjKind =
|
||||||
|
| {kind: 'Exact'}
|
||||||
|
| {kind: 'Inexact'}
|
||||||
|
| {kind: 'Indexed'; dicttype: DictType};
|
||||||
|
|
||||||
|
// DictType definition
|
||||||
|
export interface DictType {
|
||||||
|
dict_name: string | null;
|
||||||
|
key: FlowType;
|
||||||
|
value: FlowType;
|
||||||
|
dict_polarity: Polarity;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ArrType types
|
||||||
|
export type ArrTypeObj = ArrayAT | TupleAT | ROArrayAT;
|
||||||
|
|
||||||
|
export interface ArrayAT {
|
||||||
|
kind: 'ArrayAT';
|
||||||
|
elem_t: FlowType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TupleAT {
|
||||||
|
kind: 'TupleAT';
|
||||||
|
elem_t: FlowType;
|
||||||
|
elements: Array<TupleElement>;
|
||||||
|
min_arity: number;
|
||||||
|
max_arity: number;
|
||||||
|
inexact: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ROArrayAT {
|
||||||
|
kind: 'ROArrayAT';
|
||||||
|
elem_t: FlowType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TupleElement definition
|
||||||
|
export interface TupleElement {
|
||||||
|
name: string | null;
|
||||||
|
t: FlowType;
|
||||||
|
polarity: Polarity;
|
||||||
|
optional: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flags definition
|
||||||
|
export interface Flags {
|
||||||
|
obj_kind: ObjKind;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Property types
|
||||||
|
export type Property =
|
||||||
|
| FieldProperty
|
||||||
|
| GetProperty
|
||||||
|
| SetProperty
|
||||||
|
| GetSetProperty
|
||||||
|
| MethodProperty;
|
||||||
|
|
||||||
|
export interface FieldProperty {
|
||||||
|
kind: 'Field';
|
||||||
|
type: FlowType;
|
||||||
|
polarity: Polarity;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GetProperty {
|
||||||
|
kind: 'Get';
|
||||||
|
type: FlowType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SetProperty {
|
||||||
|
kind: 'Set';
|
||||||
|
type: FlowType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GetSetProperty {
|
||||||
|
kind: 'GetSet';
|
||||||
|
get_type: FlowType;
|
||||||
|
set_type: FlowType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MethodProperty {
|
||||||
|
kind: 'Method';
|
||||||
|
type: FlowType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PropertyMap definition
|
||||||
|
export interface PropertyMap {
|
||||||
|
[key: string]: Property; // For other properties in the map
|
||||||
|
}
|
||||||
|
|
||||||
|
// ObjType definition
|
||||||
|
export interface ObjTypeObj {
|
||||||
|
flags: Flags;
|
||||||
|
props: PropertyMap;
|
||||||
|
proto_t: FlowType;
|
||||||
|
call_t: number | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FunType definition
|
||||||
|
export interface FunTypeObj {
|
||||||
|
this_t: {
|
||||||
|
type: FlowType;
|
||||||
|
status: ThisStatus;
|
||||||
|
};
|
||||||
|
params: Array<{
|
||||||
|
name: string | null;
|
||||||
|
type: FlowType;
|
||||||
|
}>;
|
||||||
|
rest_param: null | {
|
||||||
|
name: string | null;
|
||||||
|
type: FlowType;
|
||||||
|
};
|
||||||
|
return_t: FlowType;
|
||||||
|
type_guard: null | {
|
||||||
|
inferred: boolean;
|
||||||
|
param_name: string;
|
||||||
|
type_guard: FlowType;
|
||||||
|
one_sided: boolean;
|
||||||
|
};
|
||||||
|
effect: Effect;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ThisStatus types
|
||||||
|
export type ThisStatus =
|
||||||
|
| {kind: 'This_Method'; unbound: boolean}
|
||||||
|
| {kind: 'This_Function'};
|
||||||
|
|
||||||
|
// Effect types
|
||||||
|
export type Effect =
|
||||||
|
| {kind: 'HookDecl'; id: string}
|
||||||
|
| {kind: 'HookAnnot'}
|
||||||
|
| {kind: 'ArbitraryEffect'}
|
||||||
|
| {kind: 'AnyEffect'};
|
||||||
|
|
||||||
|
// Destructor types
|
||||||
|
export type Destructor =
|
||||||
|
| NonMaybeTypeDestructor
|
||||||
|
| PropertyTypeDestructor
|
||||||
|
| ElementTypeDestructor
|
||||||
|
| OptionalIndexedAccessNonMaybeTypeDestructor
|
||||||
|
| OptionalIndexedAccessResultTypeDestructor
|
||||||
|
| ExactTypeDestructor
|
||||||
|
| ReadOnlyTypeDestructor
|
||||||
|
| PartialTypeDestructor
|
||||||
|
| RequiredTypeDestructor
|
||||||
|
| SpreadTypeDestructor
|
||||||
|
| SpreadTupleTypeDestructor
|
||||||
|
| RestTypeDestructor
|
||||||
|
| ValuesTypeDestructor
|
||||||
|
| ConditionalTypeDestructor
|
||||||
|
| TypeMapDestructor
|
||||||
|
| ReactElementPropsTypeDestructor
|
||||||
|
| ReactElementConfigTypeDestructor
|
||||||
|
| ReactCheckComponentConfigDestructor
|
||||||
|
| ReactDRODestructor
|
||||||
|
| MakeHooklikeDestructor
|
||||||
|
| MappedTypeDestructor
|
||||||
|
| EnumTypeDestructor;
|
||||||
|
|
||||||
|
export interface NonMaybeTypeDestructor {
|
||||||
|
kind: 'NonMaybeType';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PropertyTypeDestructor {
|
||||||
|
kind: 'PropertyType';
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ElementTypeDestructor {
|
||||||
|
kind: 'ElementType';
|
||||||
|
index_type: FlowType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OptionalIndexedAccessNonMaybeTypeDestructor {
|
||||||
|
kind: 'OptionalIndexedAccessNonMaybeType';
|
||||||
|
index: OptionalIndexedAccessIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type OptionalIndexedAccessIndex =
|
||||||
|
| {kind: 'StrLitIndex'; name: string}
|
||||||
|
| {kind: 'TypeIndex'; type: FlowType};
|
||||||
|
|
||||||
|
export interface OptionalIndexedAccessResultTypeDestructor {
|
||||||
|
kind: 'OptionalIndexedAccessResultType';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ExactTypeDestructor {
|
||||||
|
kind: 'ExactType';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReadOnlyTypeDestructor {
|
||||||
|
kind: 'ReadOnlyType';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PartialTypeDestructor {
|
||||||
|
kind: 'PartialType';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RequiredTypeDestructor {
|
||||||
|
kind: 'RequiredType';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SpreadTypeDestructor {
|
||||||
|
kind: 'SpreadType';
|
||||||
|
target: SpreadTarget;
|
||||||
|
operands: Array<SpreadOperand>;
|
||||||
|
operand_slice: Slice | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SpreadTarget =
|
||||||
|
| {kind: 'Value'; make_seal: 'Sealed' | 'Frozen' | 'As_Const'}
|
||||||
|
| {kind: 'Annot'; make_exact: boolean};
|
||||||
|
|
||||||
|
export type SpreadOperand = {kind: 'Type'; type: FlowType} | Slice;
|
||||||
|
|
||||||
|
export interface Slice {
|
||||||
|
kind: 'Slice';
|
||||||
|
prop_map: PropertyMap;
|
||||||
|
generics: Array<string>;
|
||||||
|
dict: DictType | null;
|
||||||
|
reachable_targs: Array<{
|
||||||
|
type: FlowType;
|
||||||
|
polarity: Polarity;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SpreadTupleTypeDestructor {
|
||||||
|
kind: 'SpreadTupleType';
|
||||||
|
inexact: boolean;
|
||||||
|
resolved_rev: string;
|
||||||
|
unresolved: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RestTypeDestructor {
|
||||||
|
kind: 'RestType';
|
||||||
|
merge_mode: RestMergeMode;
|
||||||
|
type: FlowType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type RestMergeMode =
|
||||||
|
| {kind: 'SpreadReversal'}
|
||||||
|
| {kind: 'ReactConfigMerge'; polarity: Polarity}
|
||||||
|
| {kind: 'Omit'};
|
||||||
|
|
||||||
|
export interface ValuesTypeDestructor {
|
||||||
|
kind: 'ValuesType';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ConditionalTypeDestructor {
|
||||||
|
kind: 'ConditionalType';
|
||||||
|
distributive_tparam_name: string | null;
|
||||||
|
infer_tparams: string;
|
||||||
|
extends_t: FlowType;
|
||||||
|
true_t: FlowType;
|
||||||
|
false_t: FlowType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TypeMapDestructor {
|
||||||
|
kind: 'ObjectKeyMirror';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReactElementPropsTypeDestructor {
|
||||||
|
kind: 'ReactElementPropsType';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReactElementConfigTypeDestructor {
|
||||||
|
kind: 'ReactElementConfigType';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReactCheckComponentConfigDestructor {
|
||||||
|
kind: 'ReactCheckComponentConfig';
|
||||||
|
props: {
|
||||||
|
[key: string]: Property;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReactDRODestructor {
|
||||||
|
kind: 'ReactDRO';
|
||||||
|
dro_type:
|
||||||
|
| 'HookReturn'
|
||||||
|
| 'HookArg'
|
||||||
|
| 'Props'
|
||||||
|
| 'ImmutableAnnot'
|
||||||
|
| 'DebugAnnot';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MakeHooklikeDestructor {
|
||||||
|
kind: 'MakeHooklike';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MappedTypeDestructor {
|
||||||
|
kind: 'MappedType';
|
||||||
|
homomorphic: Homomorphic;
|
||||||
|
distributive_tparam_name: string | null;
|
||||||
|
property_type: FlowType;
|
||||||
|
mapped_type_flags: {
|
||||||
|
variance: Polarity;
|
||||||
|
optional: 'MakeOptional' | 'RemoveOptional' | 'KeepOptionality';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Homomorphic =
|
||||||
|
| {kind: 'Homomorphic'}
|
||||||
|
| {kind: 'Unspecialized'}
|
||||||
|
| {kind: 'SemiHomomorphic'; type: FlowType};
|
||||||
|
|
||||||
|
export interface EnumTypeDestructor {
|
||||||
|
kind: 'EnumType';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Union of all possible Flow types
|
||||||
|
export type FlowType =
|
||||||
|
| OpenType
|
||||||
|
| DefType
|
||||||
|
| EvalType
|
||||||
|
| GenericType
|
||||||
|
| ThisInstanceType
|
||||||
|
| ThisTypeAppType
|
||||||
|
| TypeAppType
|
||||||
|
| FunProtoType
|
||||||
|
| ObjProtoType
|
||||||
|
| NullProtoType
|
||||||
|
| FunProtoBindType
|
||||||
|
| IntersectionType
|
||||||
|
| UnionType
|
||||||
|
| MaybeType
|
||||||
|
| OptionalType
|
||||||
|
| KeysType
|
||||||
|
| AnnotType
|
||||||
|
| OpaqueType
|
||||||
|
| NamespaceType
|
||||||
|
| AnyType
|
||||||
|
| StrUtilType;
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
import {CompilerError, SourceLocation} from '..';
|
||||||
|
import {
|
||||||
|
ConcreteType,
|
||||||
|
printConcrete,
|
||||||
|
printType,
|
||||||
|
StructuralValue,
|
||||||
|
Type,
|
||||||
|
VariableId,
|
||||||
|
} from './Types';
|
||||||
|
|
||||||
|
export function unsupportedLanguageFeature(
|
||||||
|
desc: string,
|
||||||
|
loc: SourceLocation,
|
||||||
|
): never {
|
||||||
|
CompilerError.throwInvalidJS({
|
||||||
|
reason: `Typedchecker does not currently support language feature: ${desc}`,
|
||||||
|
loc,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UnificationError =
|
||||||
|
| {
|
||||||
|
kind: 'TypeUnification';
|
||||||
|
left: ConcreteType<Type>;
|
||||||
|
right: ConcreteType<Type>;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
kind: 'StructuralUnification';
|
||||||
|
left: StructuralValue;
|
||||||
|
right: ConcreteType<Type>;
|
||||||
|
};
|
||||||
|
|
||||||
|
function printUnificationError(err: UnificationError): string {
|
||||||
|
if (err.kind === 'TypeUnification') {
|
||||||
|
return `${printConcrete(err.left, printType)} is incompatible with ${printConcrete(err.right, printType)}`;
|
||||||
|
} else {
|
||||||
|
return `structural ${err.left.kind} is incompatible with ${printConcrete(err.right, printType)}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function raiseUnificationErrors(
|
||||||
|
errs: null | Array<UnificationError>,
|
||||||
|
loc: SourceLocation,
|
||||||
|
): void {
|
||||||
|
if (errs != null) {
|
||||||
|
if (errs.length === 0) {
|
||||||
|
CompilerError.invariant(false, {
|
||||||
|
reason: 'Should not have array of zero errors',
|
||||||
|
loc,
|
||||||
|
});
|
||||||
|
} else if (errs.length === 1) {
|
||||||
|
CompilerError.throwInvalidJS({
|
||||||
|
reason: `Unable to unify types because ${printUnificationError(errs[0])}`,
|
||||||
|
loc,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const messages = errs
|
||||||
|
.map(err => `\t* ${printUnificationError(err)}`)
|
||||||
|
.join('\n');
|
||||||
|
CompilerError.throwInvalidJS({
|
||||||
|
reason: `Unable to unify types because:\n${messages}`,
|
||||||
|
loc,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function unresolvableTypeVariable(
|
||||||
|
id: VariableId,
|
||||||
|
loc: SourceLocation,
|
||||||
|
): never {
|
||||||
|
CompilerError.throwInvalidJS({
|
||||||
|
reason: `Unable to resolve free variable ${id} to a concrete type`,
|
||||||
|
loc,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function cannotAddVoid(explicit: boolean, loc: SourceLocation): never {
|
||||||
|
if (explicit) {
|
||||||
|
CompilerError.throwInvalidJS({
|
||||||
|
reason: `Undefined is not a valid operand of \`+\``,
|
||||||
|
loc,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
CompilerError.throwInvalidJS({
|
||||||
|
reason: `Value may be undefined, which is not a valid operand of \`+\``,
|
||||||
|
loc,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function unsupportedTypeAnnotation(
|
||||||
|
desc: string,
|
||||||
|
loc: SourceLocation,
|
||||||
|
): never {
|
||||||
|
CompilerError.throwInvalidJS({
|
||||||
|
reason: `Typedchecker does not currently support type annotation: ${desc}`,
|
||||||
|
loc,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function checkTypeArgumentArity(
|
||||||
|
desc: string,
|
||||||
|
expected: number,
|
||||||
|
actual: number,
|
||||||
|
loc: SourceLocation,
|
||||||
|
): void {
|
||||||
|
if (expected !== actual) {
|
||||||
|
CompilerError.throwInvalidJS({
|
||||||
|
reason: `Expected ${desc} to have ${expected} type parameters, got ${actual}`,
|
||||||
|
loc,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function notAFunction(desc: string, loc: SourceLocation): void {
|
||||||
|
CompilerError.throwInvalidJS({
|
||||||
|
reason: `Cannot call ${desc} because it is not a function`,
|
||||||
|
loc,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function notAPolymorphicFunction(
|
||||||
|
desc: string,
|
||||||
|
loc: SourceLocation,
|
||||||
|
): void {
|
||||||
|
CompilerError.throwInvalidJS({
|
||||||
|
reason: `Cannot call ${desc} with type arguments because it is not a polymorphic function`,
|
||||||
|
loc,
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,312 @@
|
|||||||
|
import {GeneratedSource} from '../HIR';
|
||||||
|
import {assertExhaustive} from '../Utils/utils';
|
||||||
|
import {unsupportedLanguageFeature} from './TypeErrors';
|
||||||
|
import {
|
||||||
|
ConcreteType,
|
||||||
|
ResolvedType,
|
||||||
|
TypeParameter,
|
||||||
|
TypeParameterId,
|
||||||
|
DEBUG,
|
||||||
|
printConcrete,
|
||||||
|
printType,
|
||||||
|
} from './Types';
|
||||||
|
|
||||||
|
export function substitute(
|
||||||
|
type: ConcreteType<ResolvedType>,
|
||||||
|
typeParameters: Array<TypeParameter<ResolvedType>>,
|
||||||
|
typeArguments: Array<ResolvedType>,
|
||||||
|
): ResolvedType {
|
||||||
|
const substMap = new Map<TypeParameterId, ResolvedType>();
|
||||||
|
for (let i = 0; i < typeParameters.length; i++) {
|
||||||
|
// TODO: Length checks to make sure type params match up with args
|
||||||
|
const typeParameter = typeParameters[i];
|
||||||
|
const typeArgument = typeArguments[i];
|
||||||
|
substMap.set(typeParameter.id, typeArgument);
|
||||||
|
}
|
||||||
|
const substitutionFunction = (t: ResolvedType): ResolvedType => {
|
||||||
|
// TODO: We really want a stateful mapper or visitor here so that we can model nested polymorphic types
|
||||||
|
if (t.type.kind === 'Generic' && substMap.has(t.type.id)) {
|
||||||
|
const substitutedType = substMap.get(t.type.id)!;
|
||||||
|
return substitutedType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
kind: 'Concrete',
|
||||||
|
type: mapType(substitutionFunction, t.type),
|
||||||
|
platform: t.platform,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const substituted = mapType(substitutionFunction, type);
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
let substs = '';
|
||||||
|
for (let i = 0; i < typeParameters.length; i++) {
|
||||||
|
const typeParameter = typeParameters[i];
|
||||||
|
const typeArgument = typeArguments[i];
|
||||||
|
substs += `[${typeParameter.name}${typeParameter.id} := ${printType(typeArgument)}]`;
|
||||||
|
}
|
||||||
|
console.log(
|
||||||
|
`${printConcrete(type, printType)}${substs} = ${printConcrete(substituted, printType)}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {kind: 'Concrete', type: substituted, platform: /* TODO */ 'shared'};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapType<T, U>(
|
||||||
|
f: (t: T) => U,
|
||||||
|
type: ConcreteType<T>,
|
||||||
|
): ConcreteType<U> {
|
||||||
|
switch (type.kind) {
|
||||||
|
case 'Mixed':
|
||||||
|
case 'Number':
|
||||||
|
case 'String':
|
||||||
|
case 'Boolean':
|
||||||
|
case 'Void':
|
||||||
|
return type;
|
||||||
|
|
||||||
|
case 'Nullable':
|
||||||
|
return {
|
||||||
|
kind: 'Nullable',
|
||||||
|
type: f(type.type),
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'Array':
|
||||||
|
return {
|
||||||
|
kind: 'Array',
|
||||||
|
element: f(type.element),
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'Set':
|
||||||
|
return {
|
||||||
|
kind: 'Set',
|
||||||
|
element: f(type.element),
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'Map':
|
||||||
|
return {
|
||||||
|
kind: 'Map',
|
||||||
|
key: f(type.key),
|
||||||
|
value: f(type.value),
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'Function':
|
||||||
|
return {
|
||||||
|
kind: 'Function',
|
||||||
|
typeParameters:
|
||||||
|
type.typeParameters?.map(param => ({
|
||||||
|
id: param.id,
|
||||||
|
name: param.name,
|
||||||
|
bound: f(param.bound),
|
||||||
|
})) ?? null,
|
||||||
|
params: type.params.map(f),
|
||||||
|
returnType: f(type.returnType),
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'Component': {
|
||||||
|
return {
|
||||||
|
kind: 'Component',
|
||||||
|
children: type.children != null ? f(type.children) : null,
|
||||||
|
props: new Map([...type.props.entries()].map(([k, v]) => [k, f(v)])),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'Generic':
|
||||||
|
return {
|
||||||
|
kind: 'Generic',
|
||||||
|
id: type.id,
|
||||||
|
bound: f(type.bound),
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'Object':
|
||||||
|
return type;
|
||||||
|
|
||||||
|
case 'Tuple':
|
||||||
|
return {
|
||||||
|
kind: 'Tuple',
|
||||||
|
id: type.id,
|
||||||
|
members: type.members.map(f),
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'Structural':
|
||||||
|
return type;
|
||||||
|
|
||||||
|
case 'Enum':
|
||||||
|
case 'Union':
|
||||||
|
case 'Instance':
|
||||||
|
unsupportedLanguageFeature(type.kind, GeneratedSource);
|
||||||
|
|
||||||
|
default:
|
||||||
|
assertExhaustive(type, 'Unknown type kind');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function diff<R, T>(
|
||||||
|
a: ConcreteType<T>,
|
||||||
|
b: ConcreteType<T>,
|
||||||
|
onChild: (a: T, b: T) => R,
|
||||||
|
onChildMismatch: (child: R, cur: R) => R,
|
||||||
|
onMismatch: (a: ConcreteType<T>, b: ConcreteType<T>, cur: R) => R,
|
||||||
|
init: R,
|
||||||
|
): R {
|
||||||
|
let errors = init;
|
||||||
|
|
||||||
|
// Check if kinds match
|
||||||
|
if (a.kind !== b.kind) {
|
||||||
|
errors = onMismatch(a, b, errors);
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Based on kind, check other properties
|
||||||
|
switch (a.kind) {
|
||||||
|
case 'Mixed':
|
||||||
|
case 'Number':
|
||||||
|
case 'String':
|
||||||
|
case 'Boolean':
|
||||||
|
case 'Void':
|
||||||
|
// Simple types, no further checks needed
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'Nullable':
|
||||||
|
// Check the nested type
|
||||||
|
errors = onChildMismatch(onChild(a.type, (b as typeof a).type), errors);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'Array':
|
||||||
|
case 'Set':
|
||||||
|
// Check the element type
|
||||||
|
errors = onChildMismatch(
|
||||||
|
onChild(a.element, (b as typeof a).element),
|
||||||
|
errors,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'Map':
|
||||||
|
// Check both key and value types
|
||||||
|
errors = onChildMismatch(onChild(a.key, (b as typeof a).key), errors);
|
||||||
|
errors = onChildMismatch(onChild(a.value, (b as typeof a).value), errors);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'Function': {
|
||||||
|
const bFunc = b as typeof a;
|
||||||
|
|
||||||
|
// Check type parameters
|
||||||
|
if ((a.typeParameters == null) !== (bFunc.typeParameters == null)) {
|
||||||
|
errors = onMismatch(a, b, errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a.typeParameters != null && bFunc.typeParameters != null) {
|
||||||
|
if (a.typeParameters.length !== bFunc.typeParameters.length) {
|
||||||
|
errors = onMismatch(a, b, errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type parameters are just numbers, so we can compare them directly
|
||||||
|
for (let i = 0; i < a.typeParameters.length; i++) {
|
||||||
|
if (a.typeParameters[i] !== bFunc.typeParameters[i]) {
|
||||||
|
errors = onMismatch(a, b, errors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check parameters
|
||||||
|
if (a.params.length !== bFunc.params.length) {
|
||||||
|
errors = onMismatch(a, b, errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < a.params.length; i++) {
|
||||||
|
errors = onChildMismatch(onChild(a.params[i], bFunc.params[i]), errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check return type
|
||||||
|
errors = onChildMismatch(onChild(a.returnType, bFunc.returnType), errors);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'Component': {
|
||||||
|
const bComp = b as typeof a;
|
||||||
|
|
||||||
|
// Check children
|
||||||
|
if (a.children !== bComp.children) {
|
||||||
|
errors = onMismatch(a, b, errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check props
|
||||||
|
if (a.props.size !== bComp.props.size) {
|
||||||
|
errors = onMismatch(a, b, errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [k, v] of a.props) {
|
||||||
|
const bProp = bComp.props.get(k);
|
||||||
|
if (bProp == null) {
|
||||||
|
errors = onMismatch(a, b, errors);
|
||||||
|
} else {
|
||||||
|
errors = onChildMismatch(onChild(v, bProp), errors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'Generic': {
|
||||||
|
// Check that the type parameter IDs match
|
||||||
|
if (a.id !== (b as typeof a).id) {
|
||||||
|
errors = onMismatch(a, b, errors);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'Structural': {
|
||||||
|
const bStruct = b as typeof a;
|
||||||
|
|
||||||
|
// Check that the structural IDs match
|
||||||
|
if (a.id !== bStruct.id) {
|
||||||
|
errors = onMismatch(a, b, errors);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'Object': {
|
||||||
|
const bNom = b as typeof a;
|
||||||
|
|
||||||
|
// Check that the nominal IDs match
|
||||||
|
if (a.id !== bNom.id) {
|
||||||
|
errors = onMismatch(a, b, errors);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'Tuple': {
|
||||||
|
const bTuple = b as typeof a;
|
||||||
|
|
||||||
|
// Check that the tuple IDs match
|
||||||
|
if (a.id !== bTuple.id) {
|
||||||
|
errors = onMismatch(a, b, errors);
|
||||||
|
}
|
||||||
|
for (let i = 0; i < a.members.length; i++) {
|
||||||
|
errors = onChildMismatch(
|
||||||
|
onChild(a.members[i], bTuple.members[i]),
|
||||||
|
errors,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'Enum':
|
||||||
|
case 'Instance':
|
||||||
|
case 'Union': {
|
||||||
|
unsupportedLanguageFeature(a.kind, GeneratedSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
assertExhaustive(a, 'Unknown type kind');
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function filterOptional(t: ResolvedType): ResolvedType {
|
||||||
|
if (t.kind === 'Concrete' && t.type.kind === 'Nullable') {
|
||||||
|
return t.type.type;
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
1001
compiler/packages/babel-plugin-react-compiler/src/Flood/Types.ts
Normal file
1001
compiler/packages/babel-plugin-react-compiler/src/Flood/Types.ts
Normal file
File diff suppressed because it is too large
Load Diff
@@ -49,6 +49,7 @@ import {
|
|||||||
} from './ObjectShape';
|
} from './ObjectShape';
|
||||||
import {Scope as BabelScope, NodePath} from '@babel/traverse';
|
import {Scope as BabelScope, NodePath} from '@babel/traverse';
|
||||||
import {TypeSchema} from './TypeSchema';
|
import {TypeSchema} from './TypeSchema';
|
||||||
|
import {FlowTypeEnv} from '../Flood/Types';
|
||||||
|
|
||||||
export const ReactElementSymbolSchema = z.object({
|
export const ReactElementSymbolSchema = z.object({
|
||||||
elementSymbol: z.union([
|
elementSymbol: z.union([
|
||||||
@@ -243,6 +244,12 @@ export const EnvironmentConfigSchema = z.object({
|
|||||||
*/
|
*/
|
||||||
enableUseTypeAnnotations: z.boolean().default(false),
|
enableUseTypeAnnotations: z.boolean().default(false),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows specifying a function that can populate HIR with type information from
|
||||||
|
* Flow
|
||||||
|
*/
|
||||||
|
flowTypeProvider: z.nullable(z.function().args(z.string())).default(null),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable a new model for mutability and aliasing inference
|
* Enable a new model for mutability and aliasing inference
|
||||||
*/
|
*/
|
||||||
@@ -697,6 +704,8 @@ export class Environment {
|
|||||||
#hoistedIdentifiers: Set<t.Identifier>;
|
#hoistedIdentifiers: Set<t.Identifier>;
|
||||||
parentFunction: NodePath<t.Function>;
|
parentFunction: NodePath<t.Function>;
|
||||||
|
|
||||||
|
#flowTypeEnvironment: FlowTypeEnv | null;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
scope: BabelScope,
|
scope: BabelScope,
|
||||||
fnType: ReactFunctionType,
|
fnType: ReactFunctionType,
|
||||||
@@ -765,6 +774,26 @@ export class Environment {
|
|||||||
this.parentFunction = parentFunction;
|
this.parentFunction = parentFunction;
|
||||||
this.#contextIdentifiers = contextIdentifiers;
|
this.#contextIdentifiers = contextIdentifiers;
|
||||||
this.#hoistedIdentifiers = new Set();
|
this.#hoistedIdentifiers = new Set();
|
||||||
|
|
||||||
|
if (config.flowTypeProvider != null) {
|
||||||
|
this.#flowTypeEnvironment = new FlowTypeEnv();
|
||||||
|
CompilerError.invariant(code != null, {
|
||||||
|
reason:
|
||||||
|
'Expected Environment to be initialized with source code when a Flow type provider is specified',
|
||||||
|
loc: null,
|
||||||
|
});
|
||||||
|
this.#flowTypeEnvironment.init(this, code);
|
||||||
|
} else {
|
||||||
|
this.#flowTypeEnvironment = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get typeContext(): FlowTypeEnv {
|
||||||
|
CompilerError.invariant(this.#flowTypeEnvironment != null, {
|
||||||
|
reason: 'Flow type environment not initialized',
|
||||||
|
loc: null,
|
||||||
|
});
|
||||||
|
return this.#flowTypeEnvironment;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isInferredMemoEnabled(): boolean {
|
get isInferredMemoEnabled(): boolean {
|
||||||
|
|||||||
@@ -504,7 +504,7 @@ function canMergeScopes(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAlwaysInvalidatingType(type: Type): boolean {
|
export function isAlwaysInvalidatingType(type: Type): boolean {
|
||||||
switch (type.kind) {
|
switch (type.kind) {
|
||||||
case 'Object': {
|
case 'Object': {
|
||||||
switch (type.shapeId) {
|
switch (type.shapeId) {
|
||||||
|
|||||||
@@ -78,6 +78,10 @@ export default class DisjointSet<T> {
|
|||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
has(item: T): boolean {
|
||||||
|
return this.#entries.has(item);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Forces the set into canonical form, ie with all items pointing directly to
|
* Forces the set into canonical form, ie with all items pointing directly to
|
||||||
* their root, and returns a Map representing the mapping of items to their roots.
|
* their root, and returns a Map representing the mapping of items to their roots.
|
||||||
|
|||||||
@@ -33,12 +33,12 @@ export function assertExhaustive(_: never, errorMsg: string): never {
|
|||||||
// Modifies @param array in place, retaining only the items where the predicate returns true.
|
// Modifies @param array in place, retaining only the items where the predicate returns true.
|
||||||
export function retainWhere<T>(
|
export function retainWhere<T>(
|
||||||
array: Array<T>,
|
array: Array<T>,
|
||||||
predicate: (item: T) => boolean,
|
predicate: (item: T, index: number) => boolean,
|
||||||
): void {
|
): void {
|
||||||
let writeIndex = 0;
|
let writeIndex = 0;
|
||||||
for (let readIndex = 0; readIndex < array.length; readIndex++) {
|
for (let readIndex = 0; readIndex < array.length; readIndex++) {
|
||||||
const item = array[readIndex];
|
const item = array[readIndex];
|
||||||
if (predicate(item) === true) {
|
if (predicate(item, readIndex) === true) {
|
||||||
array[writeIndex++] = item;
|
array[writeIndex++] = item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user