mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Start of making globals and hook declarations configurable
Some refactoring to allow the environment options to be passed in from the outside.
This commit is contained in:
@@ -7,12 +7,12 @@
|
||||
|
||||
/// <reference path="./plugin-syntax-jsx.d.ts" />
|
||||
|
||||
import * as t from "@babel/types";
|
||||
import type * as BabelCore from "@babel/core";
|
||||
import generate from "@babel/generator";
|
||||
import jsx from "@babel/plugin-syntax-jsx";
|
||||
import { CompilerFlags, parseCompilerFlags } from "../CompilerFlags";
|
||||
import * as t from "@babel/types";
|
||||
import prettier from "prettier";
|
||||
import { CompilerFlags, parseCompilerFlags } from "../CompilerFlags";
|
||||
import { compile } from "../CompilerPipeline";
|
||||
|
||||
type BabelPluginPass = {
|
||||
@@ -47,7 +47,7 @@ export default function ReactForgetBabelPlugin(
|
||||
if (fn.scope.getProgramParent() !== fn.scope.parent) {
|
||||
return;
|
||||
}
|
||||
const ast = compile(fn);
|
||||
const ast = compile(fn, null);
|
||||
|
||||
// We are generating a new FunctionDeclaration node, so we must skip over it or this
|
||||
// traversal will loop infinitely.
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
mergeConsecutiveBlocks,
|
||||
ReactiveFunction,
|
||||
} from "./HIR";
|
||||
import { EnvironmentOptions } from "./HIR/Environment";
|
||||
import {
|
||||
analyseFunctions,
|
||||
dropMemoCalls,
|
||||
@@ -47,9 +48,10 @@ export type CompilerPipelineValue =
|
||||
| { kind: "reactive"; name: string; value: ReactiveFunction };
|
||||
|
||||
export function* run(
|
||||
func: NodePath<t.FunctionDeclaration>
|
||||
func: NodePath<t.FunctionDeclaration>,
|
||||
options?: EnvironmentOptions | null
|
||||
): Generator<CompilerPipelineValue, t.Function> {
|
||||
const hir = lower(func).unwrap();
|
||||
const hir = lower(func, options ?? null).unwrap();
|
||||
yield log({ kind: "hir", name: "HIR", value: hir });
|
||||
|
||||
mergeConsecutiveBlocks(hir);
|
||||
@@ -186,8 +188,11 @@ export function* run(
|
||||
return ast;
|
||||
}
|
||||
|
||||
export function compile(func: NodePath<t.FunctionDeclaration>): t.Function {
|
||||
let generator = run(func);
|
||||
export function compile(
|
||||
func: NodePath<t.FunctionDeclaration>,
|
||||
options?: EnvironmentOptions | null
|
||||
): t.Function {
|
||||
let generator = run(func, options);
|
||||
while (true) {
|
||||
const next = generator.next();
|
||||
if (next.done) {
|
||||
|
||||
@@ -11,7 +11,7 @@ import invariant from "invariant";
|
||||
import { CompilerError, ErrorSeverity } from "../CompilerError";
|
||||
import { Err, Ok, Result } from "../Utils/Result";
|
||||
import { assertExhaustive } from "../Utils/utils";
|
||||
import { Environment } from "./Environment";
|
||||
import { Environment, EnvironmentOptions } from "./Environment";
|
||||
import {
|
||||
BlockId,
|
||||
BranchTerminal,
|
||||
@@ -51,9 +51,10 @@ import HIRBuilder from "./HIRBuilder";
|
||||
*/
|
||||
export function lower(
|
||||
func: NodePath<t.Function>,
|
||||
options: EnvironmentOptions | null,
|
||||
capturedRefs: t.Identifier[] = []
|
||||
): Result<HIRFunction, CompilerError> {
|
||||
const env = new Environment();
|
||||
const env = new Environment(options);
|
||||
const builder = new HIRBuilder(env, capturedRefs);
|
||||
const context: Place[] = [];
|
||||
|
||||
@@ -1334,7 +1335,7 @@ function lowerExpression(
|
||||
//
|
||||
// This isn't a problem in practice because use Babel's scope analysis to
|
||||
// identify the correct references.
|
||||
const lowering = lower(expr, [
|
||||
const lowering = lower(expr, builder.environment.options, [
|
||||
...builder.context,
|
||||
...captured.identifiers,
|
||||
]);
|
||||
|
||||
@@ -1,9 +1,40 @@
|
||||
import { IdentifierId, makeIdentifierId } from "./HIR";
|
||||
import { BUILTIN_HOOKS, Hook } from "./Hooks";
|
||||
|
||||
const HOOK_PATTERN = /^_?use/;
|
||||
|
||||
export type EnvironmentOptions = {
|
||||
customHooks: Map<string, Hook>;
|
||||
};
|
||||
|
||||
const DEFAULT_OPTIONS: EnvironmentOptions = {
|
||||
customHooks: new Map(),
|
||||
};
|
||||
|
||||
export class Environment {
|
||||
#options: EnvironmentOptions;
|
||||
#nextIdentifer: number = 0;
|
||||
|
||||
constructor(options: EnvironmentOptions | null) {
|
||||
this.#options = options ?? DEFAULT_OPTIONS;
|
||||
}
|
||||
|
||||
get options(): EnvironmentOptions {
|
||||
return this.#options;
|
||||
}
|
||||
|
||||
get nextIdentifierId(): IdentifierId {
|
||||
return makeIdentifierId(this.#nextIdentifer++);
|
||||
}
|
||||
|
||||
getHookDeclaration(name: string): Hook | null {
|
||||
if (!name.match(HOOK_PATTERN)) {
|
||||
return null;
|
||||
}
|
||||
const hook = BUILTIN_HOOKS.get(name) ?? this.#options.customHooks.get(name);
|
||||
if (hook !== undefined) {
|
||||
return hook;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,10 @@ export default class HIRBuilder {
|
||||
return this.#context;
|
||||
}
|
||||
|
||||
get environment(): Environment {
|
||||
return this.#env;
|
||||
}
|
||||
|
||||
constructor(env: Environment, context: t.Identifier[]) {
|
||||
this.#env = env;
|
||||
this.#context = context;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
import { Effect, Place, ValueKind } from "./HIR";
|
||||
|
||||
export const HOOKS: Map<string, Hook> = new Map([
|
||||
export const BUILTIN_HOOKS: Map<string, Hook> = new Map([
|
||||
[
|
||||
"useState",
|
||||
{
|
||||
@@ -68,7 +68,7 @@ export function parseHookCall(place: Place): Hook | null {
|
||||
if (name === null || !name.match(/^_?use/)) {
|
||||
return null;
|
||||
}
|
||||
const hook = HOOKS.get(name);
|
||||
const hook = BUILTIN_HOOKS.get(name);
|
||||
if (hook != null) {
|
||||
return hook;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user