Skip to content

Commit 0eabdf6

Browse files
committed
[compiler] Add Intl formatter types and fix moduleTypeProvider fallback
Add type definitions for all Intl formatter objects (DateTimeFormat, NumberFormat, Collator, PluralRules, ListFormat, RelativeTimeFormat, Segmenter, DisplayNames) so the compiler understands that formatter instances are immutable and their methods only read arguments. Without these types, `new Intl.DateTimeFormat().format(date)` would conservatively assume the format call captures `date` into the formatter, creating an unnecessary dependency. Also fix `#resolveModuleType` to always fall back to `defaultModuleTypeProvider` when a custom `moduleTypeProvider` returns null, so that tools like the snap runner that set their own provider still get the default module types (react-hook-form, tanstack, etc.).
1 parent 074d96b commit 0eabdf6

5 files changed

Lines changed: 537 additions & 7 deletions

File tree

compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -792,18 +792,20 @@ export class Environment {
792792
* NOTE: Zod doesn't work when specifying a function as a default, so we have to
793793
* fallback to the default value here
794794
*/
795-
const moduleTypeProvider =
796-
this.config.moduleTypeProvider ?? defaultModuleTypeProvider;
797-
if (moduleTypeProvider == null) {
798-
return null;
799-
}
800-
if (typeof moduleTypeProvider !== 'function') {
795+
const moduleTypeProvider = this.config.moduleTypeProvider;
796+
if (
797+
moduleTypeProvider != null &&
798+
typeof moduleTypeProvider !== 'function'
799+
) {
801800
CompilerError.throwInvalidConfig({
802801
reason: `Expected a function for \`moduleTypeProvider\``,
803802
loc,
804803
});
805804
}
806-
const unparsedModuleConfig = moduleTypeProvider(moduleName);
805+
const unparsedModuleConfig =
806+
(typeof moduleTypeProvider === 'function'
807+
? moduleTypeProvider(moduleName)
808+
: null) ?? defaultModuleTypeProvider(moduleName);
807809
if (unparsedModuleConfig != null) {
808810
const parsedModuleConfig = TypeSchema.safeParse(unparsedModuleConfig);
809811
if (!parsedModuleConfig.success) {

compiler/packages/babel-plugin-react-compiler/src/HIR/Globals.ts

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ import {
2828
BuiltInWeakMapId,
2929
BuiltInWeakSetId,
3030
BuiltInEffectEventId,
31+
BuiltInIntlDateTimeFormatId,
32+
BuiltInIntlNumberFormatId,
33+
BuiltInIntlCollatorId,
34+
BuiltInIntlPluralRulesId,
35+
BuiltInIntlListFormatId,
36+
BuiltInIntlRelativeTimeFormatId,
37+
BuiltInIntlSegmenterId,
38+
BuiltInIntlDisplayNamesId,
3139
ReanimatedSharedValueId,
3240
ShapeRegistry,
3341
addFunction,
@@ -620,6 +628,145 @@ const TYPED_GLOBALS: Array<[string, BuiltInType]> = [
620628
true,
621629
),
622630
],
631+
[
632+
'Intl',
633+
addObject(DEFAULT_SHAPES, 'Intl', [
634+
[
635+
'DateTimeFormat',
636+
addFunction(
637+
DEFAULT_SHAPES,
638+
[],
639+
{
640+
positionalParams: [Effect.Read, Effect.Read],
641+
restParam: null,
642+
returnType: {
643+
kind: 'Object',
644+
shapeId: BuiltInIntlDateTimeFormatId,
645+
},
646+
calleeEffect: Effect.Read,
647+
returnValueKind: ValueKind.Frozen,
648+
},
649+
null,
650+
true,
651+
),
652+
],
653+
[
654+
'NumberFormat',
655+
addFunction(
656+
DEFAULT_SHAPES,
657+
[],
658+
{
659+
positionalParams: [Effect.Read, Effect.Read],
660+
restParam: null,
661+
returnType: {kind: 'Object', shapeId: BuiltInIntlNumberFormatId},
662+
calleeEffect: Effect.Read,
663+
returnValueKind: ValueKind.Frozen,
664+
},
665+
null,
666+
true,
667+
),
668+
],
669+
[
670+
'Collator',
671+
addFunction(
672+
DEFAULT_SHAPES,
673+
[],
674+
{
675+
positionalParams: [Effect.Read, Effect.Read],
676+
restParam: null,
677+
returnType: {kind: 'Object', shapeId: BuiltInIntlCollatorId},
678+
calleeEffect: Effect.Read,
679+
returnValueKind: ValueKind.Frozen,
680+
},
681+
null,
682+
true,
683+
),
684+
],
685+
[
686+
'PluralRules',
687+
addFunction(
688+
DEFAULT_SHAPES,
689+
[],
690+
{
691+
positionalParams: [Effect.Read, Effect.Read],
692+
restParam: null,
693+
returnType: {kind: 'Object', shapeId: BuiltInIntlPluralRulesId},
694+
calleeEffect: Effect.Read,
695+
returnValueKind: ValueKind.Frozen,
696+
},
697+
null,
698+
true,
699+
),
700+
],
701+
[
702+
'ListFormat',
703+
addFunction(
704+
DEFAULT_SHAPES,
705+
[],
706+
{
707+
positionalParams: [Effect.Read, Effect.Read],
708+
restParam: null,
709+
returnType: {kind: 'Object', shapeId: BuiltInIntlListFormatId},
710+
calleeEffect: Effect.Read,
711+
returnValueKind: ValueKind.Frozen,
712+
},
713+
null,
714+
true,
715+
),
716+
],
717+
[
718+
'RelativeTimeFormat',
719+
addFunction(
720+
DEFAULT_SHAPES,
721+
[],
722+
{
723+
positionalParams: [Effect.Read, Effect.Read],
724+
restParam: null,
725+
returnType: {
726+
kind: 'Object',
727+
shapeId: BuiltInIntlRelativeTimeFormatId,
728+
},
729+
calleeEffect: Effect.Read,
730+
returnValueKind: ValueKind.Frozen,
731+
},
732+
null,
733+
true,
734+
),
735+
],
736+
[
737+
'Segmenter',
738+
addFunction(
739+
DEFAULT_SHAPES,
740+
[],
741+
{
742+
positionalParams: [Effect.Read, Effect.Read],
743+
restParam: null,
744+
returnType: {kind: 'Object', shapeId: BuiltInIntlSegmenterId},
745+
calleeEffect: Effect.Read,
746+
returnValueKind: ValueKind.Frozen,
747+
},
748+
null,
749+
true,
750+
),
751+
],
752+
[
753+
'DisplayNames',
754+
addFunction(
755+
DEFAULT_SHAPES,
756+
[],
757+
{
758+
positionalParams: [Effect.Read, Effect.Read],
759+
restParam: null,
760+
returnType: {kind: 'Object', shapeId: BuiltInIntlDisplayNamesId},
761+
calleeEffect: Effect.Read,
762+
returnValueKind: ValueKind.Frozen,
763+
},
764+
null,
765+
true,
766+
),
767+
],
768+
]),
769+
],
623770
// TODO: rest of Global objects
624771
];
625772

0 commit comments

Comments
 (0)