@@ -14,8 +14,15 @@ import {
14
14
} from "../HIR" ;
15
15
import { eachReactiveValueOperand } from "./visitors" ;
16
16
17
- /*
18
- * This pass supports the `fbt` translation system (https://facebook.github.io/fbt/).
17
+ /**
18
+ * This pass supports the
19
+ * This pass supports the `fbt` translation system (https://facebook.github.io/fbt/)
20
+ * as well as similar user-configurable macro-like APIs where it's important that
21
+ * the name of the function not be changed, and it's literal arguments not be turned
22
+ * into temporaries.
23
+ *
24
+ * ## FBT
25
+ *
19
26
* FBT provides the `<fbt>` JSX element and `fbt()` calls (which take params in the
20
27
* form of `<fbt:param>` children or `fbt.param()` arguments, respectively). These
21
28
* tags/functions have restrictions on what types of syntax may appear as props/children/
@@ -26,13 +33,22 @@ import { eachReactiveValueOperand } from "./visitors";
26
33
* operands to fbt tags/calls have the same scope as the tag/call itself.
27
34
*
28
35
* Note that this still allows the props/arguments of `<fbt:param>`/`fbt.param()`
29
- * to be independently memoized
36
+ * to be independently memoized.
37
+ *
38
+ * ## User-defined macro-like function
39
+ *
40
+ * Users can also specify their own functions to be treated similarly to fbt via the
41
+ * `customMacros` environment configuration.
30
42
*/
31
- export function memoizeFbtOperandsInSameScope ( fn : HIRFunction ) : void {
43
+ export function memoizeFbtAndMacroOperandsInSameScope ( fn : HIRFunction ) : void {
44
+ const fbtMacroTags = new Set ( [
45
+ ...FBT_TAGS ,
46
+ ...( fn . env . config . customMacros ?? [ ] ) ,
47
+ ] ) ;
32
48
const fbtValues : Set < IdentifierId > = new Set ( ) ;
33
49
while ( true ) {
34
50
let size = fbtValues . size ;
35
- visit ( fn , fbtValues ) ;
51
+ visit ( fn , fbtMacroTags , fbtValues ) ;
36
52
if ( size === fbtValues . size ) {
37
53
break ;
38
54
}
@@ -50,7 +66,11 @@ export const SINGLE_CHILD_FBT_TAGS: Set<string> = new Set([
50
66
"fbs:param" ,
51
67
] ) ;
52
68
53
- function visit ( fn : HIRFunction , fbtValues : Set < IdentifierId > ) : void {
69
+ function visit (
70
+ fn : HIRFunction ,
71
+ fbtMacroTags : Set < string > ,
72
+ fbtValues : Set < IdentifierId >
73
+ ) : void {
54
74
for ( const [ , block ] of fn . body . blocks ) {
55
75
for ( const instruction of block . instructions ) {
56
76
const { lvalue, value } = instruction ;
@@ -60,7 +80,7 @@ function visit(fn: HIRFunction, fbtValues: Set<IdentifierId>): void {
60
80
if (
61
81
value . kind === "Primitive" &&
62
82
typeof value . value === "string" &&
63
- FBT_TAGS . has ( value . value )
83
+ fbtMacroTags . has ( value . value )
64
84
) {
65
85
/*
66
86
* We don't distinguish between tag names and strings, so record
@@ -69,7 +89,7 @@ function visit(fn: HIRFunction, fbtValues: Set<IdentifierId>): void {
69
89
fbtValues . add ( lvalue . identifier . id ) ;
70
90
} else if (
71
91
value . kind === "LoadGlobal" &&
72
- FBT_TAGS . has ( value . binding . name )
92
+ fbtMacroTags . has ( value . binding . name )
73
93
) {
74
94
// Record references to `fbt` as a global
75
95
fbtValues . add ( lvalue . identifier . id ) ;
@@ -96,7 +116,7 @@ function visit(fn: HIRFunction, fbtValues: Set<IdentifierId>): void {
96
116
) ;
97
117
}
98
118
} else if (
99
- isFbtJsxExpression ( fbtValues , value ) ||
119
+ isFbtJsxExpression ( fbtMacroTags , fbtValues , value ) ||
100
120
isFbtJsxChild ( fbtValues , lvalue , value )
101
121
) {
102
122
const fbtScope = lvalue . identifier . scope ;
@@ -141,14 +161,15 @@ function isFbtCallExpression(
141
161
}
142
162
143
163
function isFbtJsxExpression (
164
+ fbtMacroTags : Set < string > ,
144
165
fbtValues : Set < IdentifierId > ,
145
166
value : ReactiveValue
146
167
) : boolean {
147
168
return (
148
169
value . kind === "JsxExpression" &&
149
170
( ( value . tag . kind === "Identifier" &&
150
171
fbtValues . has ( value . tag . identifier . id ) ) ||
151
- ( value . tag . kind === "BuiltinTag" && FBT_TAGS . has ( value . tag . name ) ) )
172
+ ( value . tag . kind === "BuiltinTag" && fbtMacroTags . has ( value . tag . name ) ) )
152
173
) ;
153
174
}
154
175
0 commit comments