compiler/packages/babel-plugin-react-compiler/src/HIR/Globals.ts TYPESCRIPT 1,127 lines View on github.com → Search inside
1/**2 * Copyright (c) Meta Platforms, Inc. and affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 */78import {Effect, ValueKind, ValueReason} from './HIR';9import {10  BUILTIN_SHAPES,11  BuiltInArrayId,12  BuiltInMapId,13  BuiltInMixedReadonlyId,14  BuiltInObjectId,15  BuiltInSetId,16  BuiltInUseActionStateId,17  BuiltInUseContextHookId,18  BuiltInUseEffectEventId,19  BuiltInUseEffectHookId,20  BuiltInUseInsertionEffectHookId,21  BuiltInUseLayoutEffectHookId,22  BuiltInUseOperatorId,23  BuiltInUseOptimisticId,24  BuiltInUseReducerId,25  BuiltInUseRefId,26  BuiltInUseStateId,27  BuiltInUseTransitionId,28  BuiltInWeakMapId,29  BuiltInWeakSetId,30  BuiltInEffectEventId,31  ReanimatedSharedValueId,32  ShapeRegistry,33  addFunction,34  addHook,35  addObject,36} from './ObjectShape';37import {BuiltInType, ObjectType, PolyType} from './Types';38import {TypeConfig} from './TypeSchema';39import {assertExhaustive} from '../Utils/utils';40import {isHookName} from './Environment';41import {CompilerError, SourceLocation} from '..';4243/*44 * This file exports types and defaults for JavaScript global objects.45 * A Forget `Environment` stores the GlobalRegistry and ShapeRegistry46 * used for the current project. These ultimately help Forget refine47 * its inference of types (i.e. Object vs Primitive) and effects48 * (i.e. read vs mutate) in source programs.49 */5051// ShapeRegistry with default definitions for builtins and global objects.52export const DEFAULT_SHAPES: ShapeRegistry = new Map(BUILTIN_SHAPES);5354// Hack until we add ObjectShapes for all globals55const UNTYPED_GLOBALS: Set<string> = new Set([56  'Object',57  'Function',58  'RegExp',59  'Date',60  'Error',61  'TypeError',62  'RangeError',63  'ReferenceError',64  'SyntaxError',65  'URIError',66  'EvalError',67  'DataView',68  'Float32Array',69  'Float64Array',70  'Int8Array',71  'Int16Array',72  'Int32Array',73  'WeakMap',74  'Uint8Array',75  'Uint8ClampedArray',76  'Uint16Array',77  'Uint32Array',78  'ArrayBuffer',79  'JSON',80  'console',81  'eval',82]);8384const TYPED_GLOBALS: Array<[string, BuiltInType]> = [85  [86    'Object',87    addObject(DEFAULT_SHAPES, 'Object', [88      [89        'keys',90        addFunction(DEFAULT_SHAPES, [], {91          positionalParams: [Effect.Read],92          restParam: null,93          returnType: {kind: 'Object', shapeId: BuiltInArrayId},94          calleeEffect: Effect.Read,95          returnValueKind: ValueKind.Mutable,96        }),97      ],98      [99        /**100         * Object.fromEntries(iterable)101         * iterable: An iterable, such as an Array or Map, containing a list of102         *           objects. Each object should have two properties.103         * Returns a new object whose properties are given by the entries of the104         * iterable.105         */106        'fromEntries',107        addFunction(DEFAULT_SHAPES, [], {108          positionalParams: [Effect.ConditionallyMutate],109          restParam: null,110          returnType: {kind: 'Object', shapeId: BuiltInObjectId},111          calleeEffect: Effect.Read,112          returnValueKind: ValueKind.Mutable,113        }),114      ],115      [116        'entries',117        addFunction(DEFAULT_SHAPES, [], {118          positionalParams: [Effect.Capture],119          restParam: null,120          returnType: {kind: 'Object', shapeId: BuiltInArrayId},121          calleeEffect: Effect.Read,122          returnValueKind: ValueKind.Mutable,123          aliasing: {124            receiver: '@receiver',125            params: ['@object'],126            rest: null,127            returns: '@returns',128            temporaries: [],129            effects: [130              {131                kind: 'Create',132                into: '@returns',133                reason: ValueReason.KnownReturnSignature,134                value: ValueKind.Mutable,135              },136              // Object values are captured into the return137              {138                kind: 'Capture',139                from: '@object',140                into: '@returns',141              },142            ],143          },144        }),145      ],146      [147        'keys',148        addFunction(DEFAULT_SHAPES, [], {149          positionalParams: [Effect.Read],150          restParam: null,151          returnType: {kind: 'Object', shapeId: BuiltInArrayId},152          calleeEffect: Effect.Read,153          returnValueKind: ValueKind.Mutable,154          aliasing: {155            receiver: '@receiver',156            params: ['@object'],157            rest: null,158            returns: '@returns',159            temporaries: [],160            effects: [161              {162                kind: 'Create',163                into: '@returns',164                reason: ValueReason.KnownReturnSignature,165                value: ValueKind.Mutable,166              },167              // Only keys are captured, and keys are immutable168              {169                kind: 'ImmutableCapture',170                from: '@object',171                into: '@returns',172              },173            ],174          },175        }),176      ],177      [178        'values',179        addFunction(DEFAULT_SHAPES, [], {180          positionalParams: [Effect.Capture],181          restParam: null,182          returnType: {kind: 'Object', shapeId: BuiltInArrayId},183          calleeEffect: Effect.Read,184          returnValueKind: ValueKind.Mutable,185          aliasing: {186            receiver: '@receiver',187            params: ['@object'],188            rest: null,189            returns: '@returns',190            temporaries: [],191            effects: [192              {193                kind: 'Create',194                into: '@returns',195                reason: ValueReason.KnownReturnSignature,196                value: ValueKind.Mutable,197              },198              // Object values are captured into the return199              {200                kind: 'Capture',201                from: '@object',202                into: '@returns',203              },204            ],205          },206        }),207      ],208    ]),209  ],210  [211    'Array',212    addObject(DEFAULT_SHAPES, 'Array', [213      [214        'isArray',215        // Array.isArray(value)216        addFunction(DEFAULT_SHAPES, [], {217          positionalParams: [Effect.Read],218          restParam: null,219          returnType: {kind: 'Primitive'},220          calleeEffect: Effect.Read,221          returnValueKind: ValueKind.Primitive,222        }),223      ],224      /*225       * https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.from226       * Array.from(arrayLike, optionalFn, optionalThis)227       * Note that the Effect of `arrayLike` is polymorphic i.e.228       *  - Effect.read if229       *     - it does not have an @iterator property and is array-like230       *       (i.e. has a length property)231       *    - it is an iterable object whose iterator does not mutate itself232       *  - Effect.mutate if it is a self-mutative iterator (e.g. a generator233       *    function)234       */235      [236        'from',237        addFunction(DEFAULT_SHAPES, [], {238          positionalParams: [239            Effect.ConditionallyMutateIterator,240            Effect.ConditionallyMutate,241            Effect.ConditionallyMutate,242          ],243          restParam: Effect.Read,244          returnType: {kind: 'Object', shapeId: BuiltInArrayId},245          calleeEffect: Effect.Read,246          returnValueKind: ValueKind.Mutable,247        }),248      ],249      [250        'of',251        // Array.of(element0, ..., elementN)252        addFunction(DEFAULT_SHAPES, [], {253          positionalParams: [],254          restParam: Effect.Read,255          returnType: {kind: 'Object', shapeId: BuiltInArrayId},256          calleeEffect: Effect.Read,257          returnValueKind: ValueKind.Mutable,258        }),259      ],260    ]),261  ],262  [263    'performance',264    addObject(DEFAULT_SHAPES, 'performance', [265      // Static methods (TODO)266      [267        'now',268        // Date.now()269        addFunction(DEFAULT_SHAPES, [], {270          positionalParams: [],271          restParam: Effect.Read,272          returnType: {kind: 'Poly'}, // TODO: could be Primitive, but that would change existing compilation273          calleeEffect: Effect.Read,274          returnValueKind: ValueKind.Mutable, // same here275          impure: true,276          canonicalName: 'performance.now',277        }),278      ],279    ]),280  ],281  [282    'Date',283    addObject(DEFAULT_SHAPES, 'Date', [284      // Static methods (TODO)285      [286        'now',287        // Date.now()288        addFunction(DEFAULT_SHAPES, [], {289          positionalParams: [],290          restParam: Effect.Read,291          returnType: {kind: 'Poly'}, // TODO: could be Primitive, but that would change existing compilation292          calleeEffect: Effect.Read,293          returnValueKind: ValueKind.Mutable, // same here294          impure: true,295          canonicalName: 'Date.now',296        }),297      ],298    ]),299  ],300  [301    'Math',302    addObject(DEFAULT_SHAPES, 'Math', [303      // Static properties (TODO)304      ['PI', {kind: 'Primitive'}],305      // Static methods (TODO)306      [307        'max',308        // Math.max(value0, ..., valueN)309        addFunction(DEFAULT_SHAPES, [], {310          positionalParams: [],311          restParam: Effect.Read,312          returnType: {kind: 'Primitive'},313          calleeEffect: Effect.Read,314          returnValueKind: ValueKind.Primitive,315        }),316      ],317      [318        'min',319        // Math.min(value0, ..., valueN)320        addFunction(DEFAULT_SHAPES, [], {321          positionalParams: [],322          restParam: Effect.Read,323          returnType: {kind: 'Primitive'},324          calleeEffect: Effect.Read,325          returnValueKind: ValueKind.Primitive,326        }),327      ],328      [329        'trunc',330        addFunction(DEFAULT_SHAPES, [], {331          positionalParams: [],332          restParam: Effect.Read,333          returnType: {kind: 'Primitive'},334          calleeEffect: Effect.Read,335          returnValueKind: ValueKind.Primitive,336        }),337      ],338      [339        'ceil',340        addFunction(DEFAULT_SHAPES, [], {341          positionalParams: [],342          restParam: Effect.Read,343          returnType: {kind: 'Primitive'},344          calleeEffect: Effect.Read,345          returnValueKind: ValueKind.Primitive,346        }),347      ],348      [349        'floor',350        addFunction(DEFAULT_SHAPES, [], {351          positionalParams: [],352          restParam: Effect.Read,353          returnType: {kind: 'Primitive'},354          calleeEffect: Effect.Read,355          returnValueKind: ValueKind.Primitive,356        }),357      ],358      [359        'pow',360        addFunction(DEFAULT_SHAPES, [], {361          positionalParams: [],362          restParam: Effect.Read,363          returnType: {kind: 'Primitive'},364          calleeEffect: Effect.Read,365          returnValueKind: ValueKind.Primitive,366        }),367      ],368      [369        'random',370        addFunction(DEFAULT_SHAPES, [], {371          positionalParams: [],372          restParam: Effect.Read,373          returnType: {kind: 'Poly'}, // TODO: could be Primitive, but that would change existing compilation374          calleeEffect: Effect.Read,375          returnValueKind: ValueKind.Mutable, // same here376          impure: true,377          canonicalName: 'Math.random',378        }),379      ],380    ]),381  ],382  ['Infinity', {kind: 'Primitive'}],383  ['NaN', {kind: 'Primitive'}],384  [385    'console',386    addObject(DEFAULT_SHAPES, 'console', [387      [388        'error',389        addFunction(DEFAULT_SHAPES, [], {390          positionalParams: [],391          restParam: Effect.Read,392          returnType: {kind: 'Primitive'},393          calleeEffect: Effect.Read,394          returnValueKind: ValueKind.Primitive,395        }),396      ],397      [398        'info',399        addFunction(DEFAULT_SHAPES, [], {400          positionalParams: [],401          restParam: Effect.Read,402          returnType: {kind: 'Primitive'},403          calleeEffect: Effect.Read,404          returnValueKind: ValueKind.Primitive,405        }),406      ],407      [408        'log',409        addFunction(DEFAULT_SHAPES, [], {410          positionalParams: [],411          restParam: Effect.Read,412          returnType: {kind: 'Primitive'},413          calleeEffect: Effect.Read,414          returnValueKind: ValueKind.Primitive,415        }),416      ],417      [418        'table',419        addFunction(DEFAULT_SHAPES, [], {420          positionalParams: [],421          restParam: Effect.Read,422          returnType: {kind: 'Primitive'},423          calleeEffect: Effect.Read,424          returnValueKind: ValueKind.Primitive,425        }),426      ],427      [428        'trace',429        addFunction(DEFAULT_SHAPES, [], {430          positionalParams: [],431          restParam: Effect.Read,432          returnType: {kind: 'Primitive'},433          calleeEffect: Effect.Read,434          returnValueKind: ValueKind.Primitive,435        }),436      ],437      [438        'warn',439        addFunction(DEFAULT_SHAPES, [], {440          positionalParams: [],441          restParam: Effect.Read,442          returnType: {kind: 'Primitive'},443          calleeEffect: Effect.Read,444          returnValueKind: ValueKind.Primitive,445        }),446      ],447    ]),448  ],449  [450    'Boolean',451    addFunction(DEFAULT_SHAPES, [], {452      positionalParams: [],453      restParam: Effect.Read,454      returnType: {kind: 'Primitive'},455      calleeEffect: Effect.Read,456      returnValueKind: ValueKind.Primitive,457    }),458  ],459  [460    'Number',461    addFunction(DEFAULT_SHAPES, [], {462      positionalParams: [],463      restParam: Effect.Read,464      returnType: {kind: 'Primitive'},465      calleeEffect: Effect.Read,466      returnValueKind: ValueKind.Primitive,467    }),468  ],469  [470    'String',471    addFunction(DEFAULT_SHAPES, [], {472      positionalParams: [],473      restParam: Effect.Read,474      returnType: {kind: 'Primitive'},475      calleeEffect: Effect.Read,476      returnValueKind: ValueKind.Primitive,477    }),478  ],479  [480    'parseInt',481    addFunction(DEFAULT_SHAPES, [], {482      positionalParams: [],483      restParam: Effect.Read,484      returnType: {kind: 'Primitive'},485      calleeEffect: Effect.Read,486      returnValueKind: ValueKind.Primitive,487    }),488  ],489  [490    'parseFloat',491    addFunction(DEFAULT_SHAPES, [], {492      positionalParams: [],493      restParam: Effect.Read,494      returnType: {kind: 'Primitive'},495      calleeEffect: Effect.Read,496      returnValueKind: ValueKind.Primitive,497    }),498  ],499  [500    'isNaN',501    addFunction(DEFAULT_SHAPES, [], {502      positionalParams: [],503      restParam: Effect.Read,504      returnType: {kind: 'Primitive'},505      calleeEffect: Effect.Read,506      returnValueKind: ValueKind.Primitive,507    }),508  ],509  [510    'isFinite',511    addFunction(DEFAULT_SHAPES, [], {512      positionalParams: [],513      restParam: Effect.Read,514      returnType: {kind: 'Primitive'},515      calleeEffect: Effect.Read,516      returnValueKind: ValueKind.Primitive,517    }),518  ],519  [520    'encodeURI',521    addFunction(DEFAULT_SHAPES, [], {522      positionalParams: [],523      restParam: Effect.Read,524      returnType: {kind: 'Primitive'},525      calleeEffect: Effect.Read,526      returnValueKind: ValueKind.Primitive,527    }),528  ],529  [530    'encodeURIComponent',531    addFunction(DEFAULT_SHAPES, [], {532      positionalParams: [],533      restParam: Effect.Read,534      returnType: {kind: 'Primitive'},535      calleeEffect: Effect.Read,536      returnValueKind: ValueKind.Primitive,537    }),538  ],539  [540    'decodeURI',541    addFunction(DEFAULT_SHAPES, [], {542      positionalParams: [],543      restParam: Effect.Read,544      returnType: {kind: 'Primitive'},545      calleeEffect: Effect.Read,546      returnValueKind: ValueKind.Primitive,547    }),548  ],549  [550    'decodeURIComponent',551    addFunction(DEFAULT_SHAPES, [], {552      positionalParams: [],553      restParam: Effect.Read,554      returnType: {kind: 'Primitive'},555      calleeEffect: Effect.Read,556      returnValueKind: ValueKind.Primitive,557    }),558  ],559  [560    'Map',561    addFunction(562      DEFAULT_SHAPES,563      [],564      {565        positionalParams: [Effect.ConditionallyMutateIterator],566        restParam: null,567        returnType: {kind: 'Object', shapeId: BuiltInMapId},568        calleeEffect: Effect.Read,569        returnValueKind: ValueKind.Mutable,570      },571      null,572      true,573    ),574  ],575  [576    'Set',577    addFunction(578      DEFAULT_SHAPES,579      [],580      {581        positionalParams: [Effect.ConditionallyMutateIterator],582        restParam: null,583        returnType: {kind: 'Object', shapeId: BuiltInSetId},584        calleeEffect: Effect.Read,585        returnValueKind: ValueKind.Mutable,586      },587      null,588      true,589    ),590  ],591  [592    'WeakMap',593    addFunction(594      DEFAULT_SHAPES,595      [],596      {597        positionalParams: [Effect.ConditionallyMutateIterator],598        restParam: null,599        returnType: {kind: 'Object', shapeId: BuiltInWeakMapId},600        calleeEffect: Effect.Read,601        returnValueKind: ValueKind.Mutable,602      },603      null,604      true,605    ),606  ],607  [608    'WeakSet',609    addFunction(610      DEFAULT_SHAPES,611      [],612      {613        positionalParams: [Effect.ConditionallyMutateIterator],614        restParam: null,615        returnType: {kind: 'Object', shapeId: BuiltInWeakSetId},616        calleeEffect: Effect.Read,617        returnValueKind: ValueKind.Mutable,618      },619      null,620      true,621    ),622  ],623  // TODO: rest of Global objects624];625626/*627 * TODO(mofeiZ): We currently only store rest param effects for hooks.628 * now that FeatureFlag `enableTreatHooksAsFunctions` is removed we can629 * use positional params too (?)630 */631const REACT_APIS: Array<[string, BuiltInType]> = [632  [633    'useContext',634    addHook(635      DEFAULT_SHAPES,636      {637        positionalParams: [],638        restParam: Effect.Read,639        returnType: {kind: 'Poly'},640        calleeEffect: Effect.Read,641        hookKind: 'useContext',642        returnValueKind: ValueKind.Frozen,643        returnValueReason: ValueReason.Context,644      },645      BuiltInUseContextHookId,646    ),647  ],648  [649    'useState',650    addHook(DEFAULT_SHAPES, {651      positionalParams: [],652      restParam: Effect.Freeze,653      returnType: {kind: 'Object', shapeId: BuiltInUseStateId},654      calleeEffect: Effect.Read,655      hookKind: 'useState',656      returnValueKind: ValueKind.Frozen,657      returnValueReason: ValueReason.State,658    }),659  ],660  [661    'useActionState',662    addHook(DEFAULT_SHAPES, {663      positionalParams: [],664      restParam: Effect.Freeze,665      returnType: {kind: 'Object', shapeId: BuiltInUseActionStateId},666      calleeEffect: Effect.Read,667      hookKind: 'useActionState',668      returnValueKind: ValueKind.Frozen,669      returnValueReason: ValueReason.State,670    }),671  ],672  [673    'useReducer',674    addHook(DEFAULT_SHAPES, {675      positionalParams: [],676      restParam: Effect.Freeze,677      returnType: {kind: 'Object', shapeId: BuiltInUseReducerId},678      calleeEffect: Effect.Read,679      hookKind: 'useReducer',680      returnValueKind: ValueKind.Frozen,681      returnValueReason: ValueReason.ReducerState,682    }),683  ],684  [685    'useRef',686    addHook(DEFAULT_SHAPES, {687      positionalParams: [],688      restParam: Effect.Capture,689      returnType: {kind: 'Object', shapeId: BuiltInUseRefId},690      calleeEffect: Effect.Read,691      hookKind: 'useRef',692      returnValueKind: ValueKind.Mutable,693    }),694  ],695  [696    'useImperativeHandle',697    addHook(DEFAULT_SHAPES, {698      positionalParams: [],699      restParam: Effect.Freeze,700      returnType: {kind: 'Primitive'},701      calleeEffect: Effect.Read,702      hookKind: 'useImperativeHandle',703      returnValueKind: ValueKind.Frozen,704    }),705  ],706  [707    'useMemo',708    addHook(DEFAULT_SHAPES, {709      positionalParams: [],710      restParam: Effect.Freeze,711      returnType: {kind: 'Poly'},712      calleeEffect: Effect.Read,713      hookKind: 'useMemo',714      returnValueKind: ValueKind.Frozen,715    }),716  ],717  [718    'useCallback',719    addHook(DEFAULT_SHAPES, {720      positionalParams: [],721      restParam: Effect.Freeze,722      returnType: {kind: 'Poly'},723      calleeEffect: Effect.Read,724      hookKind: 'useCallback',725      returnValueKind: ValueKind.Frozen,726    }),727  ],728  [729    'useEffect',730    addHook(731      DEFAULT_SHAPES,732      {733        positionalParams: [],734        restParam: Effect.Freeze,735        returnType: {kind: 'Primitive'},736        calleeEffect: Effect.Read,737        hookKind: 'useEffect',738        returnValueKind: ValueKind.Frozen,739        aliasing: {740          receiver: '@receiver',741          params: [],742          rest: '@rest',743          returns: '@returns',744          temporaries: ['@effect'],745          effects: [746            // Freezes the function and deps747            {748              kind: 'Freeze',749              value: '@rest',750              reason: ValueReason.Effect,751            },752            // Internally creates an effect object that captures the function and deps753            {754              kind: 'Create',755              into: '@effect',756              value: ValueKind.Frozen,757              reason: ValueReason.KnownReturnSignature,758            },759            // The effect stores the function and dependencies760            {761              kind: 'Capture',762              from: '@rest',763              into: '@effect',764            },765            // Returns undefined766            {767              kind: 'Create',768              into: '@returns',769              value: ValueKind.Primitive,770              reason: ValueReason.KnownReturnSignature,771            },772          ],773        },774      },775      BuiltInUseEffectHookId,776    ),777  ],778  [779    'useLayoutEffect',780    addHook(781      DEFAULT_SHAPES,782      {783        positionalParams: [],784        restParam: Effect.Freeze,785        returnType: {kind: 'Poly'},786        calleeEffect: Effect.Read,787        hookKind: 'useLayoutEffect',788        returnValueKind: ValueKind.Frozen,789      },790      BuiltInUseLayoutEffectHookId,791    ),792  ],793  [794    'useInsertionEffect',795    addHook(796      DEFAULT_SHAPES,797      {798        positionalParams: [],799        restParam: Effect.Freeze,800        returnType: {kind: 'Poly'},801        calleeEffect: Effect.Read,802        hookKind: 'useInsertionEffect',803        returnValueKind: ValueKind.Frozen,804      },805      BuiltInUseInsertionEffectHookId,806    ),807  ],808  [809    'useTransition',810    addHook(DEFAULT_SHAPES, {811      positionalParams: [],812      restParam: null,813      returnType: {kind: 'Object', shapeId: BuiltInUseTransitionId},814      calleeEffect: Effect.Read,815      hookKind: 'useTransition',816      returnValueKind: ValueKind.Frozen,817    }),818  ],819  [820    'useOptimistic',821    addHook(DEFAULT_SHAPES, {822      positionalParams: [],823      restParam: Effect.Freeze,824      returnType: {kind: 'Object', shapeId: BuiltInUseOptimisticId},825      calleeEffect: Effect.Read,826      hookKind: 'useOptimistic',827      returnValueKind: ValueKind.Frozen,828      returnValueReason: ValueReason.State,829    }),830  ],831  [832    'use',833    addFunction(834      DEFAULT_SHAPES,835      [],836      {837        positionalParams: [],838        restParam: Effect.Freeze,839        returnType: {kind: 'Poly'},840        calleeEffect: Effect.Read,841        returnValueKind: ValueKind.Frozen,842      },843      BuiltInUseOperatorId,844    ),845  ],846  [847    'useEffectEvent',848    addHook(849      DEFAULT_SHAPES,850      {851        positionalParams: [],852        restParam: Effect.Freeze,853        returnType: {854          kind: 'Function',855          return: {kind: 'Poly'},856          shapeId: BuiltInEffectEventId,857          isConstructor: false,858        },859        calleeEffect: Effect.Read,860        hookKind: 'useEffectEvent',861        // Frozen because it should not mutate any locally-bound values862        returnValueKind: ValueKind.Frozen,863      },864      BuiltInUseEffectEventId,865    ),866  ],867];868869TYPED_GLOBALS.push(870  [871    'React',872    addObject(DEFAULT_SHAPES, null, [873      ...REACT_APIS,874      [875        'createElement',876        addFunction(DEFAULT_SHAPES, [], {877          positionalParams: [],878          restParam: Effect.Freeze,879          returnType: {kind: 'Poly'},880          calleeEffect: Effect.Read,881          returnValueKind: ValueKind.Frozen,882        }),883      ],884      [885        'cloneElement',886        addFunction(DEFAULT_SHAPES, [], {887          positionalParams: [],888          restParam: Effect.Freeze,889          returnType: {kind: 'Poly'},890          calleeEffect: Effect.Read,891          returnValueKind: ValueKind.Frozen,892        }),893      ],894      [895        'createRef',896        addFunction(DEFAULT_SHAPES, [], {897          positionalParams: [],898          restParam: Effect.Capture, // createRef takes no paramters899          returnType: {kind: 'Object', shapeId: BuiltInUseRefId},900          calleeEffect: Effect.Read,901          returnValueKind: ValueKind.Mutable,902        }),903      ],904    ]),905  ],906  [907    '_jsx',908    addFunction(DEFAULT_SHAPES, [], {909      positionalParams: [],910      restParam: Effect.Freeze,911      returnType: {kind: 'Poly'},912      calleeEffect: Effect.Read,913      returnValueKind: ValueKind.Frozen,914    }),915  ],916);917918export type Global = BuiltInType | PolyType;919export type GlobalRegistry = Map<string, Global>;920export const DEFAULT_GLOBALS: GlobalRegistry = new Map(REACT_APIS);921922// Hack until we add ObjectShapes for all globals923for (const name of UNTYPED_GLOBALS) {924  DEFAULT_GLOBALS.set(name, {925    kind: 'Poly',926  });927}928929for (const [name, type_] of TYPED_GLOBALS) {930  DEFAULT_GLOBALS.set(name, type_);931}932933// Recursive global types934DEFAULT_GLOBALS.set(935  'globalThis',936  addObject(DEFAULT_SHAPES, 'globalThis', TYPED_GLOBALS),937);938DEFAULT_GLOBALS.set(939  'global',940  addObject(DEFAULT_SHAPES, 'global', TYPED_GLOBALS),941);942943export function installTypeConfig(944  globals: GlobalRegistry,945  shapes: ShapeRegistry,946  typeConfig: TypeConfig,947  moduleName: string,948  loc: SourceLocation,949): Global {950  switch (typeConfig.kind) {951    case 'type': {952      switch (typeConfig.name) {953        case 'Array': {954          return {kind: 'Object', shapeId: BuiltInArrayId};955        }956        case 'MixedReadonly': {957          return {kind: 'Object', shapeId: BuiltInMixedReadonlyId};958        }959        case 'Primitive': {960          return {kind: 'Primitive'};961        }962        case 'Ref': {963          return {kind: 'Object', shapeId: BuiltInUseRefId};964        }965        case 'Any': {966          return {kind: 'Poly'};967        }968        default: {969          assertExhaustive(970            typeConfig.name,971            `Unexpected type '${(typeConfig as any).name}'`,972          );973        }974      }975    }976    case 'function': {977      return addFunction(shapes, [], {978        positionalParams: typeConfig.positionalParams,979        restParam: typeConfig.restParam,980        calleeEffect: typeConfig.calleeEffect,981        returnType: installTypeConfig(982          globals,983          shapes,984          typeConfig.returnType,985          moduleName,986          loc,987        ),988        returnValueKind: typeConfig.returnValueKind,989        noAlias: typeConfig.noAlias === true,990        mutableOnlyIfOperandsAreMutable:991          typeConfig.mutableOnlyIfOperandsAreMutable === true,992        aliasing: typeConfig.aliasing,993        knownIncompatible: typeConfig.knownIncompatible ?? null,994      });995    }996    case 'hook': {997      return addHook(shapes, {998        hookKind: 'Custom',999        positionalParams: typeConfig.positionalParams ?? [],1000        restParam: typeConfig.restParam ?? Effect.Freeze,1001        calleeEffect: Effect.Read,1002        returnType: installTypeConfig(1003          globals,1004          shapes,1005          typeConfig.returnType,1006          moduleName,1007          loc,1008        ),1009        returnValueKind: typeConfig.returnValueKind ?? ValueKind.Frozen,1010        noAlias: typeConfig.noAlias === true,1011        aliasing: typeConfig.aliasing,1012        knownIncompatible: typeConfig.knownIncompatible ?? null,1013      });1014    }1015    case 'object': {1016      return addObject(1017        shapes,1018        null,1019        Object.entries(typeConfig.properties ?? {}).map(([key, value]) => {1020          const type = installTypeConfig(1021            globals,1022            shapes,1023            value,1024            moduleName,1025            loc,1026          );1027          const expectHook = isHookName(key);1028          let isHook = false;1029          if (type.kind === 'Function' && type.shapeId !== null) {1030            const functionType = shapes.get(type.shapeId);1031            if (functionType?.functionType?.hookKind !== null) {1032              isHook = true;1033            }1034          }1035          if (expectHook !== isHook) {1036            CompilerError.throwInvalidConfig({1037              reason: `Invalid type configuration for module`,1038              description: `Expected type for object property '${key}' from module '${moduleName}' ${expectHook ? 'to be a hook' : 'not to be a hook'} based on the property name`,1039              loc,1040            });1041          }1042          return [key, type];1043        }),1044      );1045    }1046    default: {1047      assertExhaustive(1048        typeConfig,1049        `Unexpected type kind '${(typeConfig as any).kind}'`,1050      );1051    }1052  }1053}10541055export function getReanimatedModuleType(registry: ShapeRegistry): ObjectType {1056  // hooks that freeze args and return frozen value1057  const frozenHooks = [1058    'useFrameCallback',1059    'useAnimatedStyle',1060    'useAnimatedProps',1061    'useAnimatedScrollHandler',1062    'useAnimatedReaction',1063    'useWorkletCallback',1064  ];1065  const reanimatedType: Array<[string, BuiltInType]> = [];1066  for (const hook of frozenHooks) {1067    reanimatedType.push([1068      hook,1069      addHook(registry, {1070        positionalParams: [],1071        restParam: Effect.Freeze,1072        returnType: {kind: 'Poly'},1073        returnValueKind: ValueKind.Frozen,1074        noAlias: true,1075        calleeEffect: Effect.Read,1076        hookKind: 'Custom',1077      }),1078    ]);1079  }10801081  /**1082   * hooks that return a mutable value. ideally these should be modelled as a1083   * ref, but this works for now.1084   */1085  const mutableHooks = ['useSharedValue', 'useDerivedValue'];1086  for (const hook of mutableHooks) {1087    reanimatedType.push([1088      hook,1089      addHook(registry, {1090        positionalParams: [],1091        restParam: Effect.Freeze,1092        returnType: {kind: 'Object', shapeId: ReanimatedSharedValueId},1093        returnValueKind: ValueKind.Mutable,1094        noAlias: true,1095        calleeEffect: Effect.Read,1096        hookKind: 'Custom',1097      }),1098    ]);1099  }11001101  // functions that return mutable value1102  const funcs = [1103    'withTiming',1104    'withSpring',1105    'createAnimatedPropAdapter',1106    'withDecay',1107    'withRepeat',1108    'runOnUI',1109    'executeOnUIRuntimeSync',1110  ];1111  for (const fn of funcs) {1112    reanimatedType.push([1113      fn,1114      addFunction(registry, [], {1115        positionalParams: [],1116        restParam: Effect.Read,1117        returnType: {kind: 'Poly'},1118        calleeEffect: Effect.Read,1119        returnValueKind: ValueKind.Mutable,1120        noAlias: true,1121      }),1122    ]);1123  }11241125  return addObject(registry, null, reanimatedType);1126}

Findings

✓ No findings reported for this file.

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.