main
ts 1,515 lines 41.3 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 import {CompilerError} from '../CompilerError';
9 import {AliasingEffect, AliasingSignature} from '../Inference/AliasingEffects';
10 import {assertExhaustive} from '../Utils/utils';
11 import {
12 Effect,
13 GeneratedSource,
14 Hole,
15 makeDeclarationId,
16 makeIdentifierId,
17 makeInstructionId,
18 Place,
19 SourceLocation,
20 SpreadPattern,
21 ValueKind,
22 ValueReason,
23 } from './HIR';
24 import {
25 BuiltInType,
26 FunctionType,
27 makeType,
28 ObjectType,
29 PolyType,
30 PrimitiveType,
31 } from './Types';
32 import {AliasingEffectConfig, AliasingSignatureConfig} from './TypeSchema';
33
34 /*
35 * This file exports types and defaults for JavaScript object shapes. These are
36 * stored and used by a Forget `Environment`. See comments in `Types.ts`,
37 * `Globals.ts`, and `Environment.ts` for more details.
38 */
39
40 const PRIMITIVE_TYPE: PrimitiveType = {
41 kind: 'Primitive',
42 };
43
44 let nextAnonId = 0;
45 /*
46 * We currently use strings for anonymous ShapeIds since they are easily
47 * debuggable, even though `Symbol()` might be more performant
48 */
49 function createAnonId(): string {
50 return `<generated_${nextAnonId++}>`;
51 }
52
53 /*
54 * Add a non-hook function to an existing ShapeRegistry.
55 *
56 * @returns a {@link FunctionType} representing the added function.
57 */
58 export function addFunction(
59 registry: ShapeRegistry,
60 properties: Iterable<[string, BuiltInType | PolyType]>,
61 fn: Omit<FunctionSignature, 'hookKind' | 'aliasing'> & {
62 aliasing?: AliasingSignatureConfig | null | undefined;
63 },
64 id: string | null = null,
65 isConstructor: boolean = false,
66 ): FunctionType {
67 const shapeId = id ?? createAnonId();
68 const aliasing =
69 fn.aliasing != null
70 ? parseAliasingSignatureConfig(fn.aliasing, '<builtin>', GeneratedSource)
71 : null;
72 addShape(registry, shapeId, properties, {
73 ...fn,
74 aliasing,
75 hookKind: null,
76 });
77 return {
78 kind: 'Function',
79 return: fn.returnType,
80 shapeId,
81 isConstructor,
82 };
83 }
84
85 /*
86 * Add a hook to an existing ShapeRegistry.
87 *
88 * @returns a {@link FunctionType} representing the added hook function.
89 */
90 export function addHook(
91 registry: ShapeRegistry,
92 fn: Omit<FunctionSignature, 'aliasing'> & {
93 hookKind: HookKind;
94 aliasing?: AliasingSignatureConfig | null | undefined;
95 },
96 id: string | null = null,
97 ): FunctionType {
98 const shapeId = id ?? createAnonId();
99 const aliasing =
100 fn.aliasing != null
101 ? parseAliasingSignatureConfig(fn.aliasing, '<builtin>', GeneratedSource)
102 : null;
103 addShape(registry, shapeId, [], {...fn, aliasing});
104 return {
105 kind: 'Function',
106 return: fn.returnType,
107 shapeId,
108 isConstructor: false,
109 };
110 }
111
112 function parseAliasingSignatureConfig(
113 typeConfig: AliasingSignatureConfig,
114 moduleName: string,
115 loc: SourceLocation,
116 ): AliasingSignature {
117 const lifetimes = new Map<string, Place>();
118 function define(temp: string): Place {
119 CompilerError.invariant(!lifetimes.has(temp), {
120 reason: `Invalid type configuration for module`,
121 description: `Expected aliasing signature to have unique names for receiver, params, rest, returns, and temporaries in module '${moduleName}'`,
122 loc,
123 });
124 const place = signatureArgument(lifetimes.size);
125 lifetimes.set(temp, place);
126 return place;
127 }
128 function lookup(temp: string): Place {
129 const place = lifetimes.get(temp);
130 CompilerError.invariant(place != null, {
131 reason: `Invalid type configuration for module`,
132 description: `Expected aliasing signature effects to reference known names from receiver/params/rest/returns/temporaries, but '${temp}' is not a known name in '${moduleName}'`,
133 loc,
134 });
135 return place;
136 }
137 const receiver = define(typeConfig.receiver);
138 const params = typeConfig.params.map(define);
139 const rest = typeConfig.rest != null ? define(typeConfig.rest) : null;
140 const returns = define(typeConfig.returns);
141 const temporaries = typeConfig.temporaries.map(define);
142 const effects = typeConfig.effects.map(
143 (effect: AliasingEffectConfig): AliasingEffect => {
144 switch (effect.kind) {
145 case 'ImmutableCapture':
146 case 'CreateFrom':
147 case 'Capture':
148 case 'Alias':
149 case 'Assign': {
150 const from = lookup(effect.from);
151 const into = lookup(effect.into);
152 return {
153 kind: effect.kind,
154 from,
155 into,
156 };
157 }
158 case 'Mutate':
159 case 'MutateTransitiveConditionally': {
160 const value = lookup(effect.value);
161 return {kind: effect.kind, value};
162 }
163 case 'Create': {
164 const into = lookup(effect.into);
165 return {
166 kind: 'Create',
167 into,
168 reason: effect.reason,
169 value: effect.value,
170 };
171 }
172 case 'Freeze': {
173 const value = lookup(effect.value);
174 return {
175 kind: 'Freeze',
176 value,
177 reason: effect.reason,
178 };
179 }
180 case 'Impure': {
181 const place = lookup(effect.place);
182 return {
183 kind: 'Impure',
184 place,
185 error: CompilerError.throwTodo({
186 reason: 'Support impure effect declarations',
187 loc: GeneratedSource,
188 }),
189 };
190 }
191 case 'Apply': {
192 const receiver = lookup(effect.receiver);
193 const fn = lookup(effect.function);
194 const args: Array<Place | SpreadPattern | Hole> = effect.args.map(
195 arg => {
196 if (typeof arg === 'string') {
197 return lookup(arg);
198 } else if (arg.kind === 'Spread') {
199 return {kind: 'Spread', place: lookup(arg.place)};
200 } else {
201 return arg;
202 }
203 },
204 );
205 const into = lookup(effect.into);
206 return {
207 kind: 'Apply',
208 receiver,
209 function: fn,
210 mutatesFunction: effect.mutatesFunction,
211 args,
212 into,
213 loc,
214 signature: null,
215 };
216 }
217 default: {
218 assertExhaustive(
219 effect,
220 `Unexpected effect kind '${(effect as any).kind}'`,
221 );
222 }
223 }
224 },
225 );
226 return {
227 receiver: receiver.identifier.id,
228 params: params.map(p => p.identifier.id),
229 rest: rest != null ? rest.identifier.id : null,
230 returns: returns.identifier.id,
231 temporaries,
232 effects,
233 };
234 }
235
236 /*
237 * Add an object to an existing ShapeRegistry.
238 *
239 * @returns an {@link ObjectType} representing the added object.
240 */
241 export function addObject(
242 registry: ShapeRegistry,
243 id: string | null,
244 properties: Iterable<[string, BuiltInType | PolyType]>,
245 ): ObjectType {
246 const shapeId = id ?? createAnonId();
247 addShape(registry, shapeId, properties, null);
248 return {
249 kind: 'Object',
250 shapeId,
251 };
252 }
253
254 function addShape(
255 registry: ShapeRegistry,
256 id: string,
257 properties: Iterable<[string, BuiltInType | PolyType]>,
258 functionType: FunctionSignature | null,
259 ): ObjectShape {
260 const shape: ObjectShape = {
261 properties: new Map(properties),
262 functionType,
263 };
264
265 CompilerError.invariant(!registry.has(id), {
266 reason: `[ObjectShape] Could not add shape to registry: name ${id} already exists.`,
267 loc: GeneratedSource,
268 });
269 registry.set(id, shape);
270 return shape;
271 }
272
273 export type HookKind =
274 | 'useContext'
275 | 'useState'
276 | 'useActionState'
277 | 'useReducer'
278 | 'useRef'
279 | 'useEffect'
280 | 'useLayoutEffect'
281 | 'useInsertionEffect'
282 | 'useMemo'
283 | 'useCallback'
284 | 'useTransition'
285 | 'useImperativeHandle'
286 | 'useEffectEvent'
287 | 'useOptimistic'
288 | 'Custom';
289
290 /*
291 * Call signature of a function, used for type and effect inference.
292 *
293 * Note: Param type is not recorded since it currently does not affect inference.
294 * Specifically, we currently do not:
295 * - infer types based on their usage in argument position
296 * - handle inference for overloaded / generic functions
297 */
298 export type FunctionSignature = {
299 positionalParams: Array<Effect>;
300 restParam: Effect | null;
301 returnType: BuiltInType | PolyType;
302 returnValueKind: ValueKind;
303
304 /**
305 * For functions that return frozen/immutable values, the reason provides a more
306 * precise error message for any (invalid) mutations of the value.
307 */
308 returnValueReason?: ValueReason;
309
310 calleeEffect: Effect;
311 hookKind: HookKind | null;
312 /*
313 * Whether any of the parameters may be aliased by each other or the return
314 * value. Defaults to false (parameters may alias). When true, the compiler
315 * may choose not to memoize arguments if they do not otherwise escape.
316 */
317 noAlias?: boolean;
318
319 /**
320 * Supported only for methods (no-op when used on functions in CallExpression.callee position).
321 *
322 * Indicates that the method can only modify its receiver if any of the arguments
323 * are mutable or are function expressions which mutate their arguments. This is designed
324 * for methods such as Array.prototype.map(), which only mutate the receiver array if they are
325 * passed a callback which has mutable side-effects (including mutating its inputs).
326 *
327 * MethodCalls to such functions will use a different behavior depending on their arguments:
328 * - If arguments are all non-mutable, the arguments get the Read effect and the receiver is Capture.
329 * - Else uses the effects specified by this signature.
330 */
331 mutableOnlyIfOperandsAreMutable?: boolean;
332
333 impure?: boolean;
334 knownIncompatible?: string | null | undefined;
335
336 canonicalName?: string;
337
338 aliasing?: AliasingSignature | null | undefined;
339 };
340
341 /*
342 * Shape of an {@link FunctionType} if {@link ObjectShape.functionType} is present,
343 * or {@link ObjectType} otherwise.
344 *
345 * Constructors (e.g. the global `Array` object) and other functions (e.g. `Math.min`)
346 * are both represented by {@link ObjectShape.functionType}.
347 */
348 export type ObjectShape = {
349 properties: Map<string, BuiltInType | PolyType>;
350 functionType: FunctionSignature | null;
351 };
352
353 /*
354 * Every valid ShapeRegistry must contain ObjectShape definitions for
355 * {@link BuiltInArrayId} and {@link BuiltInObjectId}, since these are the
356 * the inferred types for [] and {}.
357 */
358 export type ShapeRegistry = Map<string, ObjectShape>;
359 export const BuiltInPropsId = 'BuiltInProps';
360 export const BuiltInArrayId = 'BuiltInArray';
361 export const BuiltInSetId = 'BuiltInSet';
362 export const BuiltInMapId = 'BuiltInMap';
363 export const BuiltInWeakSetId = 'BuiltInWeakSet';
364 export const BuiltInWeakMapId = 'BuiltInWeakMap';
365 export const BuiltInFunctionId = 'BuiltInFunction';
366 export const BuiltInJsxId = 'BuiltInJsx';
367 export const BuiltInObjectId = 'BuiltInObject';
368 export const BuiltInUseStateId = 'BuiltInUseState';
369 export const BuiltInSetStateId = 'BuiltInSetState';
370 export const BuiltInUseActionStateId = 'BuiltInUseActionState';
371 export const BuiltInSetActionStateId = 'BuiltInSetActionState';
372 export const BuiltInUseRefId = 'BuiltInUseRefId';
373 export const BuiltInRefValueId = 'BuiltInRefValue';
374 export const BuiltInMixedReadonlyId = 'BuiltInMixedReadonly';
375 export const BuiltInUseEffectHookId = 'BuiltInUseEffectHook';
376 export const BuiltInUseLayoutEffectHookId = 'BuiltInUseLayoutEffectHook';
377 export const BuiltInUseInsertionEffectHookId = 'BuiltInUseInsertionEffectHook';
378 export const BuiltInUseOperatorId = 'BuiltInUseOperator';
379 export const BuiltInUseReducerId = 'BuiltInUseReducer';
380 export const BuiltInDispatchId = 'BuiltInDispatch';
381 export const BuiltInUseContextHookId = 'BuiltInUseContextHook';
382 export const BuiltInUseTransitionId = 'BuiltInUseTransition';
383 export const BuiltInUseOptimisticId = 'BuiltInUseOptimistic';
384 export const BuiltInSetOptimisticId = 'BuiltInSetOptimistic';
385 export const BuiltInStartTransitionId = 'BuiltInStartTransition';
386 export const BuiltInUseEffectEventId = 'BuiltInUseEffectEvent';
387 export const BuiltInEffectEventId = 'BuiltInEffectEventFunction';
388
389 // See getReanimatedModuleType() in Globals.ts — this is part of supporting Reanimated's ref-like types
390 export const ReanimatedSharedValueId = 'ReanimatedSharedValueId';
391
392 // ShapeRegistry with default definitions for built-ins.
393 export const BUILTIN_SHAPES: ShapeRegistry = new Map();
394
395 // If the `ref` prop exists, it has the ref type
396 addObject(BUILTIN_SHAPES, BuiltInPropsId, [
397 ['ref', {kind: 'Object', shapeId: BuiltInUseRefId}],
398 ]);
399
400 /* Built-in array shape */
401 addObject(BUILTIN_SHAPES, BuiltInArrayId, [
402 [
403 'indexOf',
404 addFunction(BUILTIN_SHAPES, [], {
405 positionalParams: [],
406 restParam: Effect.Read,
407 returnType: {kind: 'Primitive'},
408 calleeEffect: Effect.Read,
409 returnValueKind: ValueKind.Primitive,
410 }),
411 ],
412 [
413 'includes',
414 addFunction(BUILTIN_SHAPES, [], {
415 positionalParams: [],
416 restParam: Effect.Read,
417 returnType: {kind: 'Primitive'},
418 calleeEffect: Effect.Read,
419 returnValueKind: ValueKind.Primitive,
420 }),
421 ],
422 [
423 'pop',
424 addFunction(BUILTIN_SHAPES, [], {
425 positionalParams: [],
426 restParam: null,
427 returnType: {kind: 'Poly'},
428 calleeEffect: Effect.Store,
429 returnValueKind: ValueKind.Mutable,
430 }),
431 ],
432 [
433 'at',
434 addFunction(BUILTIN_SHAPES, [], {
435 positionalParams: [Effect.Read],
436 restParam: null,
437 returnType: {kind: 'Poly'},
438 calleeEffect: Effect.Capture,
439 returnValueKind: ValueKind.Mutable,
440 }),
441 ],
442 [
443 'concat',
444 addFunction(BUILTIN_SHAPES, [], {
445 positionalParams: [],
446 restParam: Effect.Capture,
447 returnType: {
448 kind: 'Object',
449 shapeId: BuiltInArrayId,
450 },
451 calleeEffect: Effect.Capture,
452 returnValueKind: ValueKind.Mutable,
453 }),
454 ],
455 ['length', PRIMITIVE_TYPE],
456 [
457 'push',
458 addFunction(BUILTIN_SHAPES, [], {
459 positionalParams: [],
460 restParam: Effect.Capture,
461 returnType: PRIMITIVE_TYPE,
462 calleeEffect: Effect.Store,
463 returnValueKind: ValueKind.Primitive,
464 aliasing: {
465 receiver: '@receiver',
466 params: [],
467 rest: '@rest',
468 returns: '@returns',
469 temporaries: [],
470 effects: [
471 // Push directly mutates the array itself
472 {kind: 'Mutate', value: '@receiver'},
473 // The arguments are captured into the array
474 {
475 kind: 'Capture',
476 from: '@rest',
477 into: '@receiver',
478 },
479 // Returns the new length, a primitive
480 {
481 kind: 'Create',
482 into: '@returns',
483 value: ValueKind.Primitive,
484 reason: ValueReason.KnownReturnSignature,
485 },
486 ],
487 },
488 }),
489 ],
490 [
491 'slice',
492 addFunction(BUILTIN_SHAPES, [], {
493 positionalParams: [],
494 restParam: Effect.Read,
495 returnType: {
496 kind: 'Object',
497 shapeId: BuiltInArrayId,
498 },
499 calleeEffect: Effect.Capture,
500 returnValueKind: ValueKind.Mutable,
501 }),
502 ],
503 [
504 'map',
505 addFunction(BUILTIN_SHAPES, [], {
506 positionalParams: [],
507 restParam: Effect.ConditionallyMutate,
508 returnType: {kind: 'Object', shapeId: BuiltInArrayId},
509 /*
510 * callee is ConditionallyMutate because items of the array
511 * flow into the lambda and may be mutated there, even though
512 * the array object itself is not modified
513 */
514 calleeEffect: Effect.ConditionallyMutate,
515 returnValueKind: ValueKind.Mutable,
516 noAlias: true,
517 mutableOnlyIfOperandsAreMutable: true,
518 aliasing: {
519 receiver: '@receiver',
520 params: ['@callback'],
521 rest: null,
522 returns: '@returns',
523 temporaries: [
524 // Temporary representing captured items of the receiver
525 '@item',
526 // Temporary representing the result of the callback
527 '@callbackReturn',
528 /*
529 * Undefined `this` arg to the callback. Note the signature does not
530 * support passing an explicit thisArg second param
531 */
532 '@thisArg',
533 ],
534 effects: [
535 // Map creates a new mutable array
536 {
537 kind: 'Create',
538 into: '@returns',
539 value: ValueKind.Mutable,
540 reason: ValueReason.KnownReturnSignature,
541 },
542 // The first arg to the callback is an item extracted from the receiver array
543 {
544 kind: 'CreateFrom',
545 from: '@receiver',
546 into: '@item',
547 },
548 // The undefined this for the callback
549 {
550 kind: 'Create',
551 into: '@thisArg',
552 value: ValueKind.Primitive,
553 reason: ValueReason.KnownReturnSignature,
554 },
555 // calls the callback, returning the result into a temporary
556 {
557 kind: 'Apply',
558 receiver: '@thisArg',
559 args: ['@item', {kind: 'Hole'}, '@receiver'],
560 function: '@callback',
561 into: '@callbackReturn',
562 mutatesFunction: false,
563 },
564 // captures the result of the callback into the return array
565 {
566 kind: 'Capture',
567 from: '@callbackReturn',
568 into: '@returns',
569 },
570 ],
571 },
572 }),
573 ],
574 [
575 'flatMap',
576 addFunction(BUILTIN_SHAPES, [], {
577 positionalParams: [],
578 restParam: Effect.ConditionallyMutate,
579 returnType: {kind: 'Object', shapeId: BuiltInArrayId},
580 /*
581 * callee is ConditionallyMutate because items of the array
582 * flow into the lambda and may be mutated there, even though
583 * the array object itself is not modified
584 */
585 calleeEffect: Effect.ConditionallyMutate,
586 returnValueKind: ValueKind.Mutable,
587 noAlias: true,
588 mutableOnlyIfOperandsAreMutable: true,
589 }),
590 ],
591 [
592 'filter',
593 addFunction(BUILTIN_SHAPES, [], {
594 positionalParams: [],
595 restParam: Effect.ConditionallyMutate,
596 returnType: {kind: 'Object', shapeId: BuiltInArrayId},
597 /*
598 * callee is ConditionallyMutate because items of the array
599 * flow into the lambda and may be mutated there, even though
600 * the array object itself is not modified
601 */
602 calleeEffect: Effect.ConditionallyMutate,
603 returnValueKind: ValueKind.Mutable,
604 noAlias: true,
605 mutableOnlyIfOperandsAreMutable: true,
606 }),
607 ],
608 [
609 'every',
610 addFunction(BUILTIN_SHAPES, [], {
611 positionalParams: [],
612 restParam: Effect.ConditionallyMutate,
613 returnType: {kind: 'Primitive'},
614 /*
615 * callee is ConditionallyMutate because items of the array
616 * flow into the lambda and may be mutated there, even though
617 * the array object itself is not modified
618 */
619 calleeEffect: Effect.ConditionallyMutate,
620 returnValueKind: ValueKind.Primitive,
621 noAlias: true,
622 mutableOnlyIfOperandsAreMutable: true,
623 }),
624 ],
625 [
626 'some',
627 addFunction(BUILTIN_SHAPES, [], {
628 positionalParams: [],
629 restParam: Effect.ConditionallyMutate,
630 returnType: {kind: 'Primitive'},
631 /*
632 * callee is ConditionallyMutate because items of the array
633 * flow into the lambda and may be mutated there, even though
634 * the array object itself is not modified
635 */
636 calleeEffect: Effect.ConditionallyMutate,
637 returnValueKind: ValueKind.Primitive,
638 noAlias: true,
639 mutableOnlyIfOperandsAreMutable: true,
640 }),
641 ],
642 [
643 'find',
644 addFunction(BUILTIN_SHAPES, [], {
645 positionalParams: [],
646 restParam: Effect.ConditionallyMutate,
647 returnType: {kind: 'Poly'},
648 calleeEffect: Effect.ConditionallyMutate,
649 returnValueKind: ValueKind.Mutable,
650 noAlias: true,
651 mutableOnlyIfOperandsAreMutable: true,
652 }),
653 ],
654 [
655 'findIndex',
656 addFunction(BUILTIN_SHAPES, [], {
657 positionalParams: [],
658 restParam: Effect.ConditionallyMutate,
659 returnType: {kind: 'Primitive'},
660 /*
661 * callee is ConditionallyMutate because items of the array
662 * flow into the lambda and may be mutated there, even though
663 * the array object itself is not modified
664 */
665 calleeEffect: Effect.ConditionallyMutate,
666 returnValueKind: ValueKind.Primitive,
667 noAlias: true,
668 mutableOnlyIfOperandsAreMutable: true,
669 }),
670 ],
671 [
672 'join',
673 addFunction(BUILTIN_SHAPES, [], {
674 positionalParams: [],
675 restParam: Effect.Read,
676 returnType: PRIMITIVE_TYPE,
677 calleeEffect: Effect.Read,
678 returnValueKind: ValueKind.Primitive,
679 }),
680 ],
681 // TODO: rest of Array properties
682 ]);
683
684 /* Built-in Object shape */
685 addObject(BUILTIN_SHAPES, BuiltInObjectId, [
686 [
687 'toString',
688 addFunction(BUILTIN_SHAPES, [], {
689 positionalParams: [],
690 restParam: null,
691 returnType: PRIMITIVE_TYPE,
692 calleeEffect: Effect.Read,
693 returnValueKind: ValueKind.Primitive,
694 }),
695 ],
696 /*
697 * TODO:
698 * hasOwnProperty, isPrototypeOf, propertyIsEnumerable, toLocaleString, valueOf
699 */
700 ]);
701
702 /* Built-in Set shape */
703 addObject(BUILTIN_SHAPES, BuiltInSetId, [
704 [
705 /**
706 * add(value)
707 * Parameters
708 * value: the value of the element to add to the Set object.
709 * Returns the Set object with added value.
710 */
711 'add',
712 addFunction(BUILTIN_SHAPES, [], {
713 positionalParams: [Effect.Capture],
714 restParam: null,
715 returnType: {kind: 'Object', shapeId: BuiltInSetId},
716 calleeEffect: Effect.Store,
717 // returnValueKind is technically dependent on the ValueKind of the set itself
718 returnValueKind: ValueKind.Mutable,
719 aliasing: {
720 receiver: '@receiver',
721 params: [],
722 rest: '@rest',
723 returns: '@returns',
724 temporaries: [],
725 effects: [
726 // Set.add returns the receiver Set
727 {
728 kind: 'Assign',
729 from: '@receiver',
730 into: '@returns',
731 },
732 // Set.add mutates the set itself
733 {
734 kind: 'Mutate',
735 value: '@receiver',
736 },
737 // Captures the rest params into the set
738 {
739 kind: 'Capture',
740 from: '@rest',
741 into: '@receiver',
742 },
743 ],
744 },
745 }),
746 ],
747 [
748 /**
749 * clear()
750 * Parameters none
751 * Returns undefined
752 */
753 'clear',
754 addFunction(BUILTIN_SHAPES, [], {
755 positionalParams: [],
756 restParam: null,
757 returnType: PRIMITIVE_TYPE,
758 calleeEffect: Effect.Store,
759 returnValueKind: ValueKind.Primitive,
760 }),
761 ],
762 [
763 /**
764 * setInstance.delete(value)
765 * Returns true if value was already in Set; otherwise false.
766 */
767 'delete',
768 addFunction(BUILTIN_SHAPES, [], {
769 positionalParams: [Effect.Read],
770 restParam: null,
771 returnType: PRIMITIVE_TYPE,
772 calleeEffect: Effect.Store,
773 returnValueKind: ValueKind.Primitive,
774 }),
775 ],
776 [
777 'has',
778 addFunction(BUILTIN_SHAPES, [], {
779 positionalParams: [Effect.Read],
780 restParam: null,
781 returnType: PRIMITIVE_TYPE,
782 calleeEffect: Effect.Read,
783 returnValueKind: ValueKind.Primitive,
784 }),
785 ],
786 ['size', PRIMITIVE_TYPE],
787 [
788 /**
789 * difference(other)
790 * Parameters
791 * other: A Set object, or set-like object.
792 * Returns a new Set object containing elements in this set but not in the other set.
793 */
794 'difference',
795 addFunction(BUILTIN_SHAPES, [], {
796 positionalParams: [Effect.Capture],
797 restParam: null,
798 returnType: {kind: 'Object', shapeId: BuiltInSetId},
799 calleeEffect: Effect.Capture,
800 returnValueKind: ValueKind.Mutable,
801 }),
802 ],
803 [
804 /**
805 * union(other)
806 * Parameters
807 * other: A Set object, or set-like object.
808 * Returns a new Set object containing elements in either this set or the other set.
809 */
810 'union',
811 addFunction(BUILTIN_SHAPES, [], {
812 positionalParams: [Effect.Capture],
813 restParam: null,
814 returnType: {kind: 'Object', shapeId: BuiltInSetId},
815 calleeEffect: Effect.Capture,
816 returnValueKind: ValueKind.Mutable,
817 }),
818 ],
819 [
820 /**
821 * symmetricalDifference(other)
822 * Parameters
823 * other: A Set object, or set-like object.
824 * A new Set object containing elements which are in either this set or the other set, but not in both.
825 */
826 'symmetricalDifference',
827 addFunction(BUILTIN_SHAPES, [], {
828 positionalParams: [Effect.Capture],
829 restParam: null,
830 returnType: {kind: 'Object', shapeId: BuiltInSetId},
831 calleeEffect: Effect.Capture,
832 returnValueKind: ValueKind.Mutable,
833 }),
834 ],
835 [
836 /**
837 * isSubsetOf(other)
838 * Parameters
839 * other: A Set object, or set-like object.
840 * Returns true if all elements in this set are also in the other set, and false otherwise.
841 */
842 'isSubsetOf',
843 addFunction(BUILTIN_SHAPES, [], {
844 positionalParams: [Effect.Read],
845 restParam: null,
846 returnType: PRIMITIVE_TYPE,
847 calleeEffect: Effect.Read,
848 returnValueKind: ValueKind.Primitive,
849 }),
850 ],
851 [
852 /**
853 * isSupersetOf(other)
854 * Parameters
855 * other: A Set object, or set-like object.
856 * Returns true if all elements in the other set are also in this set, and false otherwise.
857 */
858 'isSupersetOf',
859 addFunction(BUILTIN_SHAPES, [], {
860 positionalParams: [Effect.Read],
861 restParam: null,
862 returnType: PRIMITIVE_TYPE,
863 calleeEffect: Effect.Read,
864 returnValueKind: ValueKind.Primitive,
865 }),
866 ],
867 [
868 /**
869 * forEach(callbackFn)
870 * forEach(callbackFn, thisArg)
871 */
872 'forEach',
873 addFunction(BUILTIN_SHAPES, [], {
874 /**
875 * see Array.map explanation for why arguments are marked `ConditionallyMutate`
876 */
877 positionalParams: [],
878 restParam: Effect.ConditionallyMutate,
879 returnType: PRIMITIVE_TYPE,
880 calleeEffect: Effect.ConditionallyMutate,
881 returnValueKind: ValueKind.Primitive,
882 noAlias: true,
883 mutableOnlyIfOperandsAreMutable: true,
884 }),
885 ],
886 /**
887 * Iterators
888 */
889 [
890 'entries',
891 addFunction(BUILTIN_SHAPES, [], {
892 positionalParams: [],
893 restParam: null,
894 returnType: {kind: 'Poly'},
895 calleeEffect: Effect.Capture,
896 returnValueKind: ValueKind.Mutable,
897 }),
898 ],
899 [
900 'keys',
901 addFunction(BUILTIN_SHAPES, [], {
902 positionalParams: [],
903 restParam: null,
904 returnType: {kind: 'Poly'},
905 calleeEffect: Effect.Capture,
906 returnValueKind: ValueKind.Mutable,
907 }),
908 ],
909 [
910 'values',
911 addFunction(BUILTIN_SHAPES, [], {
912 positionalParams: [],
913 restParam: null,
914 returnType: {kind: 'Poly'},
915 calleeEffect: Effect.Capture,
916 returnValueKind: ValueKind.Mutable,
917 }),
918 ],
919 ]);
920 addObject(BUILTIN_SHAPES, BuiltInMapId, [
921 [
922 /**
923 * clear()
924 * Parameters none
925 * Returns undefined
926 */
927 'clear',
928 addFunction(BUILTIN_SHAPES, [], {
929 positionalParams: [],
930 restParam: null,
931 returnType: PRIMITIVE_TYPE,
932 calleeEffect: Effect.Store,
933 returnValueKind: ValueKind.Primitive,
934 }),
935 ],
936 [
937 'delete',
938 addFunction(BUILTIN_SHAPES, [], {
939 positionalParams: [Effect.Read],
940 restParam: null,
941 returnType: PRIMITIVE_TYPE,
942 calleeEffect: Effect.Store,
943 returnValueKind: ValueKind.Primitive,
944 }),
945 ],
946 [
947 'get',
948 addFunction(BUILTIN_SHAPES, [], {
949 positionalParams: [Effect.Read],
950 restParam: null,
951 returnType: {kind: 'Poly'},
952 calleeEffect: Effect.Capture,
953 returnValueKind: ValueKind.Mutable,
954 }),
955 ],
956 [
957 'has',
958 addFunction(BUILTIN_SHAPES, [], {
959 positionalParams: [Effect.Read],
960 restParam: null,
961 returnType: PRIMITIVE_TYPE,
962 calleeEffect: Effect.Read,
963 returnValueKind: ValueKind.Primitive,
964 }),
965 ],
966 [
967 /**
968 * Params
969 * key: the key of the element to add to the Map object. The key may be
970 * any JavaScript type (any primitive value or any type of JavaScript
971 * object).
972 * value: the value of the element to add to the Map object.
973 * Returns the Map object.
974 */
975 'set',
976 addFunction(BUILTIN_SHAPES, [], {
977 positionalParams: [Effect.Capture, Effect.Capture],
978 restParam: null,
979 returnType: {kind: 'Object', shapeId: BuiltInMapId},
980 calleeEffect: Effect.Store,
981 returnValueKind: ValueKind.Mutable,
982 }),
983 ],
984 ['size', PRIMITIVE_TYPE],
985 [
986 'forEach',
987 addFunction(BUILTIN_SHAPES, [], {
988 /**
989 * see Array.map explanation for why arguments are marked `ConditionallyMutate`
990 */
991 positionalParams: [],
992 restParam: Effect.ConditionallyMutate,
993 returnType: PRIMITIVE_TYPE,
994 calleeEffect: Effect.ConditionallyMutate,
995 returnValueKind: ValueKind.Primitive,
996 noAlias: true,
997 mutableOnlyIfOperandsAreMutable: true,
998 }),
999 ],
1000 /**
1001 * Iterators
1002 */
1003 [
1004 'entries',
1005 addFunction(BUILTIN_SHAPES, [], {
1006 positionalParams: [],
1007 restParam: null,
1008 returnType: {kind: 'Poly'},
1009 calleeEffect: Effect.Capture,
1010 returnValueKind: ValueKind.Mutable,
1011 }),
1012 ],
1013 [
1014 'keys',
1015 addFunction(BUILTIN_SHAPES, [], {
1016 positionalParams: [],
1017 restParam: null,
1018 returnType: {kind: 'Poly'},
1019 calleeEffect: Effect.Capture,
1020 returnValueKind: ValueKind.Mutable,
1021 }),
1022 ],
1023 [
1024 'values',
1025 addFunction(BUILTIN_SHAPES, [], {
1026 positionalParams: [],
1027 restParam: null,
1028 returnType: {kind: 'Poly'},
1029 calleeEffect: Effect.Capture,
1030 returnValueKind: ValueKind.Mutable,
1031 }),
1032 ],
1033 ]);
1034
1035 addObject(BUILTIN_SHAPES, BuiltInWeakSetId, [
1036 [
1037 /**
1038 * add(value)
1039 * Parameters
1040 * value: the value of the element to add to the Set object.
1041 * Returns the Set object with added value.
1042 */
1043 'add',
1044 addFunction(BUILTIN_SHAPES, [], {
1045 positionalParams: [Effect.Capture],
1046 restParam: null,
1047 returnType: {kind: 'Object', shapeId: BuiltInWeakSetId},
1048 calleeEffect: Effect.Store,
1049 // returnValueKind is technically dependent on the ValueKind of the set itself
1050 returnValueKind: ValueKind.Mutable,
1051 }),
1052 ],
1053 [
1054 /**
1055 * setInstance.delete(value)
1056 * Returns true if value was already in Set; otherwise false.
1057 */
1058 'delete',
1059 addFunction(BUILTIN_SHAPES, [], {
1060 positionalParams: [Effect.Read],
1061 restParam: null,
1062 returnType: PRIMITIVE_TYPE,
1063 calleeEffect: Effect.Store,
1064 returnValueKind: ValueKind.Primitive,
1065 }),
1066 ],
1067 [
1068 'has',
1069 addFunction(BUILTIN_SHAPES, [], {
1070 positionalParams: [Effect.Read],
1071 restParam: null,
1072 returnType: PRIMITIVE_TYPE,
1073 calleeEffect: Effect.Read,
1074 returnValueKind: ValueKind.Primitive,
1075 }),
1076 ],
1077 ]);
1078
1079 addObject(BUILTIN_SHAPES, BuiltInWeakMapId, [
1080 [
1081 'delete',
1082 addFunction(BUILTIN_SHAPES, [], {
1083 positionalParams: [Effect.Read],
1084 restParam: null,
1085 returnType: PRIMITIVE_TYPE,
1086 calleeEffect: Effect.Store,
1087 returnValueKind: ValueKind.Primitive,
1088 }),
1089 ],
1090 [
1091 'get',
1092 addFunction(BUILTIN_SHAPES, [], {
1093 positionalParams: [Effect.Read],
1094 restParam: null,
1095 returnType: {kind: 'Poly'},
1096 calleeEffect: Effect.Capture,
1097 returnValueKind: ValueKind.Mutable,
1098 }),
1099 ],
1100 [
1101 'has',
1102 addFunction(BUILTIN_SHAPES, [], {
1103 positionalParams: [Effect.Read],
1104 restParam: null,
1105 returnType: PRIMITIVE_TYPE,
1106 calleeEffect: Effect.Read,
1107 returnValueKind: ValueKind.Primitive,
1108 }),
1109 ],
1110 [
1111 /**
1112 * Params
1113 * key: the key of the element to add to the Map object. The key may be
1114 * any JavaScript type (any primitive value or any type of JavaScript
1115 * object).
1116 * value: the value of the element to add to the Map object.
1117 * Returns the Map object.
1118 */
1119 'set',
1120 addFunction(BUILTIN_SHAPES, [], {
1121 positionalParams: [Effect.Capture, Effect.Capture],
1122 restParam: null,
1123 returnType: {kind: 'Object', shapeId: BuiltInWeakMapId},
1124 calleeEffect: Effect.Store,
1125 returnValueKind: ValueKind.Mutable,
1126 }),
1127 ],
1128 ]);
1129
1130 addObject(BUILTIN_SHAPES, BuiltInUseStateId, [
1131 ['0', {kind: 'Poly'}],
1132 [
1133 '1',
1134 addFunction(
1135 BUILTIN_SHAPES,
1136 [],
1137 {
1138 positionalParams: [],
1139 restParam: Effect.Freeze,
1140 returnType: PRIMITIVE_TYPE,
1141 calleeEffect: Effect.Read,
1142 returnValueKind: ValueKind.Primitive,
1143 },
1144 BuiltInSetStateId,
1145 ),
1146 ],
1147 ]);
1148
1149 addObject(BUILTIN_SHAPES, BuiltInUseTransitionId, [
1150 ['0', {kind: 'Primitive'}],
1151 [
1152 '1',
1153 addFunction(
1154 BUILTIN_SHAPES,
1155 [],
1156 {
1157 positionalParams: [],
1158 restParam: null,
1159 returnType: PRIMITIVE_TYPE,
1160 calleeEffect: Effect.Read,
1161 returnValueKind: ValueKind.Primitive,
1162 },
1163 BuiltInStartTransitionId,
1164 ),
1165 ],
1166 ]);
1167
1168 addObject(BUILTIN_SHAPES, BuiltInUseOptimisticId, [
1169 ['0', {kind: 'Poly'}],
1170 [
1171 '1',
1172 addFunction(
1173 BUILTIN_SHAPES,
1174 [],
1175 {
1176 positionalParams: [],
1177 restParam: Effect.Freeze,
1178 returnType: PRIMITIVE_TYPE,
1179 calleeEffect: Effect.Read,
1180 returnValueKind: ValueKind.Primitive,
1181 },
1182 BuiltInSetOptimisticId,
1183 ),
1184 ],
1185 ]);
1186
1187 addObject(BUILTIN_SHAPES, BuiltInUseActionStateId, [
1188 ['0', {kind: 'Poly'}],
1189 [
1190 '1',
1191 addFunction(
1192 BUILTIN_SHAPES,
1193 [],
1194 {
1195 positionalParams: [],
1196 restParam: Effect.Freeze,
1197 returnType: PRIMITIVE_TYPE,
1198 calleeEffect: Effect.Read,
1199 returnValueKind: ValueKind.Primitive,
1200 },
1201 BuiltInSetActionStateId,
1202 ),
1203 ],
1204 ]);
1205
1206 addObject(BUILTIN_SHAPES, BuiltInUseReducerId, [
1207 ['0', {kind: 'Poly'}],
1208 [
1209 '1',
1210 addFunction(
1211 BUILTIN_SHAPES,
1212 [],
1213 {
1214 positionalParams: [],
1215 restParam: Effect.Freeze,
1216 returnType: PRIMITIVE_TYPE,
1217 calleeEffect: Effect.Read,
1218 returnValueKind: ValueKind.Primitive,
1219 },
1220 BuiltInDispatchId,
1221 ),
1222 ],
1223 ]);
1224
1225 addObject(BUILTIN_SHAPES, BuiltInUseRefId, [
1226 ['current', {kind: 'Object', shapeId: BuiltInRefValueId}],
1227 ]);
1228
1229 addObject(BUILTIN_SHAPES, BuiltInRefValueId, [
1230 ['*', {kind: 'Object', shapeId: BuiltInRefValueId}],
1231 ]);
1232
1233 addObject(BUILTIN_SHAPES, ReanimatedSharedValueId, []);
1234
1235 addFunction(
1236 BUILTIN_SHAPES,
1237 [],
1238 {
1239 positionalParams: [],
1240 restParam: Effect.ConditionallyMutate,
1241 returnType: {kind: 'Poly'},
1242 calleeEffect: Effect.ConditionallyMutate,
1243 returnValueKind: ValueKind.Mutable,
1244 },
1245 BuiltInEffectEventId,
1246 );
1247
1248 /**
1249 * MixedReadOnly =
1250 * | primitive
1251 * | simple objects (Record<string, MixedReadOnly>)
1252 * | Array<MixedReadOnly>
1253 *
1254 * APIs such as Relay — but also Flux and other data stores — often return a
1255 * union of types with some interesting properties in terms of analysis.
1256 *
1257 * Given this constraint, if data came from Relay, then we should be able to
1258 * infer things like `data.items.map(): Array`. That may seem like a leap at
1259 * first but remember, we assume you're not patching builtins. Thus the only way
1260 * data.items.map can exist and be a function, given the above set of data types
1261 * and builtin JS methods, is if `data.items` was an Array, and `data.items.map`
1262 * is therefore calling Array.prototype.map. Then we know that function returns
1263 * an Array as well. This relies on the fact that map() is being called, so if
1264 * data.items was some other type it would error at runtime - so it's sound.
1265 *
1266 * Note that this shape is currently only used for hook return values, which
1267 * means that it's safe to type aliasing method-call return kinds as `Frozen`.
1268 *
1269 * Also note that all newly created arrays from method-calls (e.g. `.map`)
1270 * have the appropriate mutable `BuiltInArray` shape
1271 */
1272 addObject(BUILTIN_SHAPES, BuiltInMixedReadonlyId, [
1273 [
1274 'toString',
1275 addFunction(BUILTIN_SHAPES, [], {
1276 positionalParams: [],
1277 restParam: Effect.Read,
1278 returnType: PRIMITIVE_TYPE,
1279 calleeEffect: Effect.Read,
1280 returnValueKind: ValueKind.Primitive,
1281 }),
1282 ],
1283 [
1284 'indexOf',
1285 addFunction(BUILTIN_SHAPES, [], {
1286 positionalParams: [],
1287 restParam: Effect.Read,
1288 returnType: {kind: 'Primitive'},
1289 calleeEffect: Effect.Read,
1290 returnValueKind: ValueKind.Primitive,
1291 }),
1292 ],
1293 [
1294 'includes',
1295 addFunction(BUILTIN_SHAPES, [], {
1296 positionalParams: [],
1297 restParam: Effect.Read,
1298 returnType: {kind: 'Primitive'},
1299 calleeEffect: Effect.Read,
1300 returnValueKind: ValueKind.Primitive,
1301 }),
1302 ],
1303 [
1304 'at',
1305 addFunction(BUILTIN_SHAPES, [], {
1306 positionalParams: [Effect.Read],
1307 restParam: null,
1308 returnType: {kind: 'Object', shapeId: BuiltInMixedReadonlyId},
1309 calleeEffect: Effect.Capture,
1310 returnValueKind: ValueKind.Frozen,
1311 }),
1312 ],
1313 [
1314 'map',
1315 addFunction(BUILTIN_SHAPES, [], {
1316 /**
1317 * Note `map`'s arguments are annotated as Effect.ConditionallyMutate as
1318 * calling `<array>.map(fn)` might invoke `fn`, which means replaying its
1319 * effects.
1320 *
1321 * (Note that Effect.Read / Effect.Capture on a function type means
1322 * potential data dependency or aliasing respectively.)
1323 */
1324 positionalParams: [],
1325 restParam: Effect.ConditionallyMutate,
1326 returnType: {kind: 'Object', shapeId: BuiltInArrayId},
1327 calleeEffect: Effect.ConditionallyMutate,
1328 returnValueKind: ValueKind.Mutable,
1329 noAlias: true,
1330 }),
1331 ],
1332 [
1333 'flatMap',
1334 addFunction(BUILTIN_SHAPES, [], {
1335 positionalParams: [],
1336 restParam: Effect.ConditionallyMutate,
1337 returnType: {kind: 'Object', shapeId: BuiltInArrayId},
1338 calleeEffect: Effect.ConditionallyMutate,
1339 returnValueKind: ValueKind.Mutable,
1340 noAlias: true,
1341 }),
1342 ],
1343 [
1344 'filter',
1345 addFunction(BUILTIN_SHAPES, [], {
1346 positionalParams: [],
1347 restParam: Effect.ConditionallyMutate,
1348 returnType: {kind: 'Object', shapeId: BuiltInArrayId},
1349 calleeEffect: Effect.ConditionallyMutate,
1350 returnValueKind: ValueKind.Mutable,
1351 noAlias: true,
1352 }),
1353 ],
1354 [
1355 'concat',
1356 addFunction(BUILTIN_SHAPES, [], {
1357 positionalParams: [],
1358 restParam: Effect.Capture,
1359 returnType: {
1360 kind: 'Object',
1361 shapeId: BuiltInArrayId,
1362 },
1363 calleeEffect: Effect.Capture,
1364 returnValueKind: ValueKind.Mutable,
1365 }),
1366 ],
1367 [
1368 'slice',
1369 addFunction(BUILTIN_SHAPES, [], {
1370 positionalParams: [],
1371 restParam: Effect.Read,
1372 returnType: {
1373 kind: 'Object',
1374 shapeId: BuiltInArrayId,
1375 },
1376 calleeEffect: Effect.Capture,
1377 returnValueKind: ValueKind.Mutable,
1378 }),
1379 ],
1380 [
1381 'every',
1382 addFunction(BUILTIN_SHAPES, [], {
1383 positionalParams: [],
1384 restParam: Effect.ConditionallyMutate,
1385 returnType: {kind: 'Primitive'},
1386 calleeEffect: Effect.ConditionallyMutate,
1387 returnValueKind: ValueKind.Primitive,
1388 noAlias: true,
1389 mutableOnlyIfOperandsAreMutable: true,
1390 }),
1391 ],
1392 [
1393 'some',
1394 addFunction(BUILTIN_SHAPES, [], {
1395 positionalParams: [],
1396 restParam: Effect.ConditionallyMutate,
1397 returnType: {kind: 'Primitive'},
1398 calleeEffect: Effect.ConditionallyMutate,
1399 returnValueKind: ValueKind.Primitive,
1400 noAlias: true,
1401 mutableOnlyIfOperandsAreMutable: true,
1402 }),
1403 ],
1404 [
1405 'find',
1406 addFunction(BUILTIN_SHAPES, [], {
1407 positionalParams: [],
1408 restParam: Effect.ConditionallyMutate,
1409 returnType: {kind: 'Object', shapeId: BuiltInMixedReadonlyId},
1410 calleeEffect: Effect.ConditionallyMutate,
1411 returnValueKind: ValueKind.Frozen,
1412 noAlias: true,
1413 mutableOnlyIfOperandsAreMutable: true,
1414 }),
1415 ],
1416 [
1417 'findIndex',
1418 addFunction(BUILTIN_SHAPES, [], {
1419 positionalParams: [],
1420 restParam: Effect.ConditionallyMutate,
1421 returnType: {kind: 'Primitive'},
1422 calleeEffect: Effect.ConditionallyMutate,
1423 returnValueKind: ValueKind.Primitive,
1424 noAlias: true,
1425 mutableOnlyIfOperandsAreMutable: true,
1426 }),
1427 ],
1428 [
1429 'join',
1430 addFunction(BUILTIN_SHAPES, [], {
1431 positionalParams: [],
1432 restParam: Effect.Read,
1433 returnType: PRIMITIVE_TYPE,
1434 calleeEffect: Effect.Read,
1435 returnValueKind: ValueKind.Primitive,
1436 }),
1437 ],
1438 ['*', {kind: 'Object', shapeId: BuiltInMixedReadonlyId}],
1439 ]);
1440
1441 addObject(BUILTIN_SHAPES, BuiltInJsxId, []);
1442 addObject(BUILTIN_SHAPES, BuiltInFunctionId, []);
1443
1444 export const DefaultMutatingHook = addHook(
1445 BUILTIN_SHAPES,
1446 {
1447 positionalParams: [],
1448 restParam: Effect.ConditionallyMutate,
1449 returnType: {kind: 'Poly'},
1450 calleeEffect: Effect.Read,
1451 hookKind: 'Custom',
1452 returnValueKind: ValueKind.Mutable,
1453 },
1454 'DefaultMutatingHook',
1455 );
1456
1457 export const DefaultNonmutatingHook = addHook(
1458 BUILTIN_SHAPES,
1459 {
1460 positionalParams: [],
1461 restParam: Effect.Freeze,
1462 returnType: {kind: 'Poly'},
1463 calleeEffect: Effect.Read,
1464 hookKind: 'Custom',
1465 returnValueKind: ValueKind.Frozen,
1466 aliasing: {
1467 receiver: '@receiver',
1468 params: [],
1469 rest: '@rest',
1470 returns: '@returns',
1471 temporaries: [],
1472 effects: [
1473 // Freeze the arguments
1474 {
1475 kind: 'Freeze',
1476 value: '@rest',
1477 reason: ValueReason.HookCaptured,
1478 },
1479 // Returns a frozen value
1480 {
1481 kind: 'Create',
1482 into: '@returns',
1483 value: ValueKind.Frozen,
1484 reason: ValueReason.HookReturn,
1485 },
1486 // May alias any arguments into the return
1487 {
1488 kind: 'Alias',
1489 from: '@rest',
1490 into: '@returns',
1491 },
1492 ],
1493 },
1494 },
1495 'DefaultNonmutatingHook',
1496 );
1497
1498 export function signatureArgument(id: number): Place {
1499 const place: Place = {
1500 kind: 'Identifier',
1501 effect: Effect.Unknown,
1502 loc: GeneratedSource,
1503 reactive: false,
1504 identifier: {
1505 declarationId: makeDeclarationId(id),
1506 id: makeIdentifierId(id),
1507 loc: GeneratedSource,
1508 mutableRange: {start: makeInstructionId(0), end: makeInstructionId(0)},
1509 name: null,
1510 scope: null,
1511 type: makeType(),
1512 },
1513 };
1514 return place;
1515 }