mirror of
https://github.com/zebrajr/react.git
synced 2026-01-15 12:15:22 +00:00
Adds a new compiler option `validateNoUseBeforeDefine`, which enables a
post-codegen pass to validate that there are no usages of values before they are
defined (which causes a ReferenceError at runtime). This can occur when a value
is accessed when its in the TDZ (temporary dead zone), after the hoisted
_declaration_ but before the variable is defined:
```javascript
function foo() {
x; // x is in the TDX here: the binding from the subsequent statement is
hoisted, but x is not yet defined.
let x;
}
```
* The validation is off by default, but enabled in transform-test
* The validation crashes compilation, rather than bailout, because the code has
already been mangled and we can't roll back at the point the validation runs.
* The validator uses ESLint's no-use-before-define rule by printing the program
to source and then configuring ESLint to use Hermes parser.
* transform-test now supports tests prefixed with "error." to indicate tests for
which compilation is expected to crash (not just bailout), and the expect file
includes the error message.
68 lines
1.8 KiB
TypeScript
68 lines
1.8 KiB
TypeScript
/**
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
import { NodePath } from "@babel/traverse";
|
|
import * as t from "@babel/types";
|
|
import * as BE from "./BackEnd";
|
|
import { CompilerContext } from "./CompilerContext";
|
|
import { CompilerOptions } from "./CompilerOptions";
|
|
import * as ME from "./MiddleEnd";
|
|
import { PassManager } from "./PassManager";
|
|
|
|
/**
|
|
* Compiler Driver
|
|
*
|
|
* Owns {@link CompilerContext} and source program.
|
|
*/
|
|
export interface CompilerDriver {
|
|
context: CompilerContext;
|
|
program: NodePath<t.Program>;
|
|
compile(): void;
|
|
}
|
|
|
|
export function createCompilerDriver(
|
|
options: CompilerOptions,
|
|
program: NodePath<t.Program>
|
|
): CompilerDriver {
|
|
const context = new CompilerContext(options, program);
|
|
|
|
return {
|
|
context,
|
|
program,
|
|
compile() {
|
|
const passManager = new PassManager(program, context);
|
|
|
|
// Syntax Analysis and IR Generation.
|
|
passManager.addPass(ME.ReactFuncsInfer);
|
|
passManager.addPass(ME.ParamAnalysis);
|
|
passManager.addPass(ME.BodyAnalysis);
|
|
passManager.addPass(ME.SketchyCodeCheck);
|
|
passManager.addPass(ME.RefKindInfer);
|
|
passManager.addPass(ME.DumpIR);
|
|
passManager.addPass(ME.IRCheck);
|
|
passManager.addPass(ME.DumpCFG);
|
|
|
|
// Dependency Analysis via DepGraph.
|
|
passManager.addPass(ME.DepGraphAnalysis);
|
|
|
|
// LIR Generation.
|
|
passManager.addPass(BE.LIRGen);
|
|
passManager.addPass(BE.MemoCacheAlloc);
|
|
passManager.addPass(BE.DumpLIR);
|
|
passManager.addPass(BE.SanityCheck);
|
|
|
|
// JS Generation.
|
|
passManager.addPass(BE.JSGen);
|
|
|
|
// Optionally sanity-check the transformed output
|
|
passManager.addPass(BE.PostCodegenValidator);
|
|
|
|
passManager.runAll();
|
|
},
|
|
};
|
|
}
|