@samitouri / QOS-React-1 / commits / 707d9643dd

[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.

Mofei Zhang committed Feb 5, 2024 at 16:05 UTC 707d9643dd810f7c6bf7c4ef1e855cb80ec7c72e
1 file changed +21 -8
compiler/packages/babel-plugin-react-forget/src/Entrypoint/Program.ts
+21 -8
@@ -36,22 +36,24 @@ export type CompilerPass = {
36 comments: (t.CommentBlock | t.CommentLine)[];
37 };
38
39 -function hasAnyUseForgetDirectives(directives: t.Directive[]): boolean {
39 +function findUseForgetDirective(directives: t.Directive[]): t.Directive | null {
40 for (const directive of directives) {
41 if (directive.value.value === "use forget") {
42 - return true;
42 + return directive;
43 }
44 }
45 - return false;
45 + return null;
46 }
47
48 -function hasAnyUseNoForgetDirectives(directives: t.Directive[]): boolean {
48 +function findUseNoForgetDirective(
49 + directives: t.Directive[]
50 +): t.Directive | null {
51 for (const directive of directives) {
52 if (directive.value.value === "use no forget") {
51 - return true;
53 + return directive;
54 }
55 }
54 - return false;
56 + return null;
57 }
58
59 function isCriticalError(err: unknown): boolean {
@@ -362,11 +364,22 @@ function shouldVisitNode(fn: BabelFn, pass: CompilerPass): boolean {
364 }
365 if (fn.node.body.type === "BlockStatement") {
366 // Opt-outs disable compilation regardless of mode
365 - if (hasAnyUseNoForgetDirectives(fn.node.body.directives)) {
367 + const useNoForget = findUseNoForgetDirective(fn.node.body.directives);
368 + if (useNoForget != null) {
369 + pass.opts.logger?.logEvent(pass.filename, {
370 + kind: "CompileError",
371 + fnLoc: fn.node.body.loc ?? null,
372 + detail: {
373 + severity: ErrorSeverity.Todo,
374 + reason: 'Skipped due to "use no forget" directive.',
375 + loc: useNoForget.loc ?? null,
376 + suggestions: null,
377 + },
378 + });
379 return false;
380 }
381 // Otherwise opt-ins enable compilation regardless of mode
369 - if (hasAnyUseForgetDirectives(fn.node.body.directives)) {
382 + if (findUseForgetDirective(fn.node.body.directives) != null) {
383 return true;
384 }
385 }