[logger] Log todo when encountering "use no forget"

--- 

This change simply logs on every function we encounter with a `use no forget` 
directive. A few nuances -- `compilationMode: "infer"` only compiles functions 
we infer to be 'react functions'. 

```js 

// `add` would not be compiled, as it has no jsx, no hook calls, 

// and is not named as a component or hook 

function add(a, b) { 

return a + b; 

} 

``` 

With this PR, we would report todos for functions that Forget wouldn't 
ordinarily try to compile. 

```js 

// Todo: Skipped due to "use no forget" directive. 

function add(a, b) { 

"use no forget"; 

return a + b; 

} 

``` 

This seems fine to me as (1) it's a bit nonsensical to have a `use no forget` 
direction on a non-react function, and (2) we're goalling on getting `use no 
forget`s down to 0.
This commit is contained in:
Mofei Zhang
2024-02-05 16:05:09 -05:00
parent 195b5e5a24
commit 707d9643dd
@@ -36,22 +36,24 @@ export type CompilerPass = {
comments: (t.CommentBlock | t.CommentLine)[];
};
function hasAnyUseForgetDirectives(directives: t.Directive[]): boolean {
function findUseForgetDirective(directives: t.Directive[]): t.Directive | null {
for (const directive of directives) {
if (directive.value.value === "use forget") {
return true;
return directive;
}
}
return false;
return null;
}
function hasAnyUseNoForgetDirectives(directives: t.Directive[]): boolean {
function findUseNoForgetDirective(
directives: t.Directive[]
): t.Directive | null {
for (const directive of directives) {
if (directive.value.value === "use no forget") {
return true;
return directive;
}
}
return false;
return null;
}
function isCriticalError(err: unknown): boolean {
@@ -362,11 +364,22 @@ function shouldVisitNode(fn: BabelFn, pass: CompilerPass): boolean {
}
if (fn.node.body.type === "BlockStatement") {
// Opt-outs disable compilation regardless of mode
if (hasAnyUseNoForgetDirectives(fn.node.body.directives)) {
const useNoForget = findUseNoForgetDirective(fn.node.body.directives);
if (useNoForget != null) {
pass.opts.logger?.logEvent(pass.filename, {
kind: "CompileError",
fnLoc: fn.node.body.loc ?? null,
detail: {
severity: ErrorSeverity.Todo,
reason: 'Skipped due to "use no forget" directive.',
loc: useNoForget.loc ?? null,
suggestions: null,
},
});
return false;
}
// Otherwise opt-ins enable compilation regardless of mode
if (hasAnyUseForgetDirectives(fn.node.body.directives)) {
if (findUseForgetDirective(fn.node.body.directives) != null) {
return true;
}
}