mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Distinguish internal invariant passes from user code validation
Distinguishes between two types of "validation" passes: - Passes which assert the validity of the HIR. These remain in HIR/ but are renamed "assertFoo". - Passes which validate that the user code is correct. These move to Validation/.
This commit is contained in:
@@ -9,15 +9,11 @@ import { NodePath } from "@babel/traverse";
|
||||
import * as t from "@babel/types";
|
||||
import {
|
||||
HIRFunction,
|
||||
ReactiveFunction,
|
||||
assertConsistentIdentifiers,
|
||||
assertTerminalSuccessorsExist,
|
||||
lower,
|
||||
mergeConsecutiveBlocks,
|
||||
ReactiveFunction,
|
||||
validateConsistentIdentifiers,
|
||||
validateFrozenLambdas,
|
||||
validateHooksUsage,
|
||||
validateNoRefAccessInRender,
|
||||
validateTerminalSuccessors,
|
||||
validateUnconditionalHooks,
|
||||
} from "../HIR";
|
||||
import { Environment, EnvironmentConfig } from "../HIR/Environment";
|
||||
import { findContextIdentifiers } from "../HIR/FindContextIdentifiers";
|
||||
@@ -45,8 +41,8 @@ import {
|
||||
pruneAllReactiveScopes,
|
||||
pruneNonEscapingScopes,
|
||||
pruneNonReactiveDependencies,
|
||||
pruneUnusedLabels,
|
||||
pruneUnusedLValues,
|
||||
pruneUnusedLabels,
|
||||
pruneUnusedScopes,
|
||||
renameVariables,
|
||||
} from "../ReactiveScopes";
|
||||
@@ -54,6 +50,12 @@ import { eliminateRedundantPhi, enterSSA, leaveSSA } from "../SSA";
|
||||
import { inferTypes } from "../TypeInference";
|
||||
import { logHIRFunction, logReactiveFunction } from "../Utils/logger";
|
||||
import { assertExhaustive } from "../Utils/utils";
|
||||
import {
|
||||
validateFrozenLambdas,
|
||||
validateHooksUsage,
|
||||
validateNoRefAccessInRender,
|
||||
validateUnconditionalHooks,
|
||||
} from "../Validation";
|
||||
|
||||
export type CompilerPipelineValue =
|
||||
| { kind: "ast"; name: string; value: t.FunctionDeclaration }
|
||||
@@ -78,8 +80,8 @@ export function* run(
|
||||
mergeConsecutiveBlocks(hir);
|
||||
yield log({ kind: "hir", name: "MergeConsecutiveBlocks", value: hir });
|
||||
|
||||
validateConsistentIdentifiers(hir);
|
||||
validateTerminalSuccessors(hir);
|
||||
assertConsistentIdentifiers(hir);
|
||||
assertTerminalSuccessorsExist(hir);
|
||||
|
||||
enterSSA(hir);
|
||||
yield log({ kind: "hir", name: "SSA", value: hir });
|
||||
@@ -87,7 +89,7 @@ export function* run(
|
||||
eliminateRedundantPhi(hir);
|
||||
yield log({ kind: "hir", name: "EliminateRedundantPhi", value: hir });
|
||||
|
||||
validateConsistentIdentifiers(hir);
|
||||
assertConsistentIdentifiers(hir);
|
||||
|
||||
constantPropagation(hir);
|
||||
yield log({ kind: "hir", name: "ConstantPropagation", value: hir });
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ import {
|
||||
* Validation pass to check that there is a 1:1 mapping between Identifier objects and IdentifierIds,
|
||||
* ie there can only be one Identifier instance per IdentifierId.
|
||||
*/
|
||||
export function validateConsistentIdentifiers(fn: HIRFunction): void {
|
||||
export function assertConsistentIdentifiers(fn: HIRFunction): void {
|
||||
const identifiers: Identifiers = new Map();
|
||||
const assignments: Set<IdentifierId> = new Set();
|
||||
for (const [, block] of fn.body.blocks) {
|
||||
+1
-1
@@ -10,7 +10,7 @@ import { GeneratedSource, HIRFunction } from "./HIR";
|
||||
import { printTerminal } from "./PrintHIR";
|
||||
import { mapTerminalSuccessors } from "./visitors";
|
||||
|
||||
export function validateTerminalSuccessors(fn: HIRFunction): void {
|
||||
export function assertTerminalSuccessorsExist(fn: HIRFunction): void {
|
||||
for (const [, block] of fn.body.blocks) {
|
||||
mapTerminalSuccessors(block.terminal, (successor) => {
|
||||
if (!fn.body.blocks.has(successor)) {
|
||||
@@ -5,6 +5,8 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
export { assertConsistentIdentifiers } from "./AssertConsistentIdentifiers";
|
||||
export { assertTerminalSuccessorsExist } from "./AssertTerminalSuccessorsExist";
|
||||
export { lower } from "./BuildHIR";
|
||||
export { computeDominatorTree, computePostDominatorTree } from "./Dominator";
|
||||
export { Environment, Hook } from "./Environment";
|
||||
@@ -17,9 +19,3 @@ export {
|
||||
} from "./HIRBuilder";
|
||||
export { mergeConsecutiveBlocks } from "./MergeConsecutiveBlocks";
|
||||
export { printFunction, printHIR } from "./PrintHIR";
|
||||
export { validateConsistentIdentifiers } from "./ValidateConsistentIdentifiers";
|
||||
export { validateFrozenLambdas } from "./ValidateFrozenLambdas";
|
||||
export { validateHooksUsage } from "./ValidateHooksUsage";
|
||||
export { validateNoRefAccessInRender } from "./ValidateNoRefAccesInRender";
|
||||
export { validateTerminalSuccessors } from "./ValidateTerminalSuccessors";
|
||||
export { validateUnconditionalHooks } from "./ValidateUnconditionalHooks";
|
||||
|
||||
+6
-6
@@ -14,15 +14,15 @@ import {
|
||||
Instruction,
|
||||
InstructionValue,
|
||||
LoadGlobal,
|
||||
Place,
|
||||
Primitive,
|
||||
assertConsistentIdentifiers,
|
||||
assertTerminalSuccessorsExist,
|
||||
markInstructionIds,
|
||||
markPredecessors,
|
||||
mergeConsecutiveBlocks,
|
||||
Place,
|
||||
Primitive,
|
||||
removeUnreachableFallthroughs,
|
||||
reversePostorderBlocks,
|
||||
validateConsistentIdentifiers,
|
||||
validateTerminalSuccessors,
|
||||
} from "../HIR";
|
||||
import {
|
||||
removeDeadDoWhileStatements,
|
||||
@@ -81,8 +81,8 @@ function constantPropagationImpl(fn: HIRFunction, constants: Constants): void {
|
||||
// consecutively
|
||||
mergeConsecutiveBlocks(fn);
|
||||
|
||||
validateConsistentIdentifiers(fn);
|
||||
validateTerminalSuccessors(fn);
|
||||
assertConsistentIdentifiers(fn);
|
||||
assertTerminalSuccessorsExist(fn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-2
@@ -18,8 +18,11 @@ import {
|
||||
Place,
|
||||
isRefValueType,
|
||||
isUseRefType,
|
||||
} from "./HIR";
|
||||
import { eachInstructionValueOperand, eachTerminalOperand } from "./visitors";
|
||||
} from "../HIR/HIR";
|
||||
import {
|
||||
eachInstructionValueOperand,
|
||||
eachTerminalOperand,
|
||||
} from "../HIR/visitors";
|
||||
|
||||
/**
|
||||
* Various APIs in React take ownership of the values passed to them, such that it is invalid
|
||||
+5
-2
@@ -10,9 +10,12 @@ import {
|
||||
CompilerErrorDetail,
|
||||
ErrorSeverity,
|
||||
} from "../CompilerError";
|
||||
import { HIRFunction, IdentifierId, Place, getHookKind } from "../HIR/HIR";
|
||||
import {
|
||||
eachInstructionValueOperand,
|
||||
eachTerminalOperand,
|
||||
} from "../HIR/visitors";
|
||||
import { hasBackEdge } from "../Optimization/DeadCodeElimination";
|
||||
import { HIRFunction, IdentifierId, Place, getHookKind } from "./HIR";
|
||||
import { eachInstructionValueOperand, eachTerminalOperand } from "./visitors";
|
||||
|
||||
/**
|
||||
* Validates that the function honors the [Rules of Hooks](https://react.dev/warnings/invalid-hook-call-warning)
|
||||
+6
-3
@@ -10,9 +10,12 @@ import {
|
||||
CompilerErrorDetail,
|
||||
ErrorSeverity,
|
||||
} from "../CompilerError";
|
||||
import { HIRFunction, Place, isRefValueType, isUseRefType } from "./HIR";
|
||||
import { printPlace } from "./PrintHIR";
|
||||
import { eachInstructionValueOperand, eachTerminalOperand } from "./visitors";
|
||||
import { HIRFunction, Place, isRefValueType, isUseRefType } from "../HIR/HIR";
|
||||
import { printPlace } from "../HIR/PrintHIR";
|
||||
import {
|
||||
eachInstructionValueOperand,
|
||||
eachTerminalOperand,
|
||||
} from "../HIR/visitors";
|
||||
|
||||
/**
|
||||
* Validates that ref values (the `current` property) are not accessed during render.
|
||||
+2
-2
@@ -10,10 +10,10 @@ import {
|
||||
CompilerErrorDetail,
|
||||
ErrorSeverity,
|
||||
} from "../CompilerError";
|
||||
import { PostDominator, computePostDominatorTree } from "../HIR/Dominator";
|
||||
import { BlockId, HIRFunction, getHookKind } from "../HIR/HIR";
|
||||
import { findBlocksWithBackEdges } from "../Optimization/DeadCodeElimination";
|
||||
import { Err, Ok, Result } from "../Utils/Result";
|
||||
import { PostDominator, computePostDominatorTree } from "./Dominator";
|
||||
import { BlockId, HIRFunction, getHookKind } from "./HIR";
|
||||
|
||||
/**
|
||||
* Validates that the function honors the [Rules of Hooks](https://react.dev/warnings/invalid-hook-call-warning)
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
export { validateFrozenLambdas } from "./ValidateFrozenLambdas";
|
||||
export { validateHooksUsage } from "./ValidateHooksUsage";
|
||||
export { validateNoRefAccessInRender } from "./ValidateNoRefAccesInRender";
|
||||
export { validateUnconditionalHooks } from "./ValidateUnconditionalHooks";
|
||||
Reference in New Issue
Block a user