mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[pipeline] Make logging more structured
--- Add types for logged events, including a `CompileSuccess` event which can help us record successfully compiled Forget functions and their compilation details (e.g. # memoSlots used).
This commit is contained in:
@@ -5,6 +5,8 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import * as t from "@babel/types";
|
||||
import { CompilerErrorDetailOptions } from "../CompilerError";
|
||||
import { EnvironmentConfig } from "../HIR/Environment";
|
||||
|
||||
export type ExternalFunction = {
|
||||
@@ -113,8 +115,26 @@ export type CompilationMode =
|
||||
// Compile all top-level functions
|
||||
| "all";
|
||||
|
||||
export type LoggerEvent =
|
||||
| {
|
||||
kind: "CompileError";
|
||||
fnLoc: t.SourceLocation | null;
|
||||
detail: CompilerErrorDetailOptions;
|
||||
}
|
||||
| {
|
||||
kind: "CompileSuccess";
|
||||
fnLoc: t.SourceLocation | null;
|
||||
fnName: string | null;
|
||||
memoSlots: number;
|
||||
}
|
||||
| {
|
||||
kind: "PipelineError";
|
||||
fnLoc: t.SourceLocation | null;
|
||||
data: any;
|
||||
};
|
||||
|
||||
export type Logger = {
|
||||
logEvent(name: string, data: any): void;
|
||||
logEvent: (filename: string | null, event: LoggerEvent) => void;
|
||||
};
|
||||
|
||||
export const defaultOptions: PluginOptions = {
|
||||
|
||||
@@ -50,9 +50,27 @@ function hasAnyUseNoForgetDirectives(directives: t.Directive[]): boolean {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function handleError(pass: CompilerPass, err: unknown): void {
|
||||
if (pass.opts.logger && err) {
|
||||
pass.opts.logger.logEvent("err", err);
|
||||
function handleError(
|
||||
pass: CompilerPass,
|
||||
fnLoc: t.SourceLocation | null,
|
||||
err: unknown
|
||||
): void {
|
||||
if (pass.opts.logger) {
|
||||
if (err instanceof CompilerError) {
|
||||
for (const detail of err.details) {
|
||||
pass.opts.logger.logEvent(pass.filename, {
|
||||
kind: "CompileError",
|
||||
fnLoc,
|
||||
detail: detail.options,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
pass.opts.logger.logEvent(pass.filename, {
|
||||
kind: "PipelineError",
|
||||
fnLoc,
|
||||
data: err,
|
||||
});
|
||||
}
|
||||
}
|
||||
/** Always throw if the flag is enabled, otherwise we only throw if the error is critical
|
||||
* (eg an invariant is broken, meaning the compiler may be buggy). See
|
||||
@@ -88,8 +106,14 @@ function compileAndInsertNewFunctionDeclaration(
|
||||
let compiledFn: CodegenFunction;
|
||||
try {
|
||||
compiledFn = compileFn(fnPath, pass.opts.environment);
|
||||
pass.opts.logger?.logEvent(pass.filename, {
|
||||
kind: "CompileSuccess",
|
||||
fnLoc: fnPath.node.loc ?? null,
|
||||
fnName: compiledFn.id?.name ?? null,
|
||||
memoSlots: compiledFn.memoSlotsUsed,
|
||||
});
|
||||
} catch (err) {
|
||||
handleError(pass, err);
|
||||
handleError(pass, fnPath.node.loc ?? null, err);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -266,7 +290,7 @@ export function compileProgram(
|
||||
if (!shouldVisitNode(fn, pass)) {
|
||||
return;
|
||||
} else if (lintError != null) {
|
||||
handleError(pass, lintError);
|
||||
handleError(pass, fn.node.loc ?? null, lintError);
|
||||
} else {
|
||||
const hasMutated = compileAndInsertNewFunctionDeclaration(fn, pass);
|
||||
hasForgetMutatedOriginalSource ||= hasMutated;
|
||||
@@ -280,7 +304,7 @@ export function compileProgram(
|
||||
if (!shouldVisitNode(fn, pass)) {
|
||||
return;
|
||||
} else if (lintError != null) {
|
||||
handleError(pass, lintError);
|
||||
handleError(pass, fn.node.loc ?? null, lintError);
|
||||
} else {
|
||||
const hasMutated = compileAndInsertNewFunctionDeclaration(fn, pass);
|
||||
hasForgetMutatedOriginalSource ||= hasMutated;
|
||||
@@ -294,7 +318,7 @@ export function compileProgram(
|
||||
if (!shouldVisitNode(fn, pass)) {
|
||||
return;
|
||||
} else if (lintError != null) {
|
||||
handleError(pass, lintError);
|
||||
handleError(pass, fn.node.loc ?? null, lintError);
|
||||
} else {
|
||||
const hasMutated = compileAndInsertNewFunctionDeclaration(fn, pass);
|
||||
hasForgetMutatedOriginalSource ||= hasMutated;
|
||||
|
||||
+4
@@ -43,6 +43,9 @@ export type CodegenFunction = {
|
||||
generator: boolean;
|
||||
async: boolean;
|
||||
loc: SourceLocation;
|
||||
|
||||
// Compiler info for logging and heuristics
|
||||
memoSlotsUsed: number;
|
||||
};
|
||||
|
||||
export function codegenReactiveFunction(
|
||||
@@ -89,6 +92,7 @@ export function codegenReactiveFunction(
|
||||
body,
|
||||
generator: fn.generator,
|
||||
async: fn.async,
|
||||
memoSlotsUsed: cacheCount,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user