mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Scaffolding for rest params
Updates HIR to represent rest element function parameters. We don't construct these yet.
This commit is contained in:
@@ -48,7 +48,7 @@ export type SourceLocation = t.SourceLocation | typeof GeneratedSource;
|
||||
export type ReactiveFunction = {
|
||||
loc: SourceLocation;
|
||||
id: string | null;
|
||||
params: Array<Place>;
|
||||
params: Array<Place | SpreadPattern>;
|
||||
generator: boolean;
|
||||
async: boolean;
|
||||
body: ReactiveBlock;
|
||||
@@ -232,7 +232,7 @@ export type HIRFunction = {
|
||||
loc: SourceLocation;
|
||||
id: string | null;
|
||||
env: Environment;
|
||||
params: Array<Place>;
|
||||
params: Array<Place | SpreadPattern>;
|
||||
context: Array<Place>;
|
||||
body: HIR;
|
||||
generator: boolean;
|
||||
|
||||
@@ -110,13 +110,25 @@ export default function inferReferenceEffects(
|
||||
? ValueKind.Mutable
|
||||
: ValueKind.Frozen;
|
||||
for (const param of fn.params) {
|
||||
const value: InstructionValue = {
|
||||
kind: "Primitive",
|
||||
loc: param.loc,
|
||||
value: undefined,
|
||||
};
|
||||
let value: InstructionValue;
|
||||
let place: Place;
|
||||
if (param.kind === "Identifier") {
|
||||
place = param;
|
||||
value = {
|
||||
kind: "Primitive",
|
||||
loc: param.loc,
|
||||
value: undefined,
|
||||
};
|
||||
} else {
|
||||
place = param.place;
|
||||
value = {
|
||||
kind: "Primitive",
|
||||
loc: param.place.loc,
|
||||
value: undefined,
|
||||
};
|
||||
}
|
||||
initialState.initialize(value, paramKind);
|
||||
initialState.define(param, value);
|
||||
initialState.define(place, value);
|
||||
}
|
||||
|
||||
// Map of blocks to the last (merged) incoming state that was processed
|
||||
|
||||
+16
-2
@@ -54,10 +54,14 @@ export function codegenReactiveFunction(
|
||||
): Result<CodegenFunction, CompilerError> {
|
||||
const cx = new Context(fn.env, fn.id ?? "[[ anonymous ]]");
|
||||
for (const param of fn.params) {
|
||||
cx.temp.set(param.identifier.id, null);
|
||||
if (param.kind === "Identifier") {
|
||||
cx.temp.set(param.identifier.id, null);
|
||||
} else {
|
||||
cx.temp.set(param.place.identifier.id, null);
|
||||
}
|
||||
}
|
||||
|
||||
const params = fn.params.map((param) => convertIdentifier(param.identifier));
|
||||
const params = fn.params.map((param) => convertParameter(param));
|
||||
const body = codegenBlock(cx, fn.body);
|
||||
const statements = body.body;
|
||||
if (statements.length !== 0) {
|
||||
@@ -97,6 +101,16 @@ export function codegenReactiveFunction(
|
||||
});
|
||||
}
|
||||
|
||||
function convertParameter(
|
||||
param: Place | SpreadPattern
|
||||
): t.Identifier | t.RestElement {
|
||||
if (param.kind === "Identifier") {
|
||||
return convertIdentifier(param.identifier);
|
||||
} else {
|
||||
return t.restElement(convertIdentifier(param.place.identifier));
|
||||
}
|
||||
}
|
||||
|
||||
class Context {
|
||||
env: Environment;
|
||||
fnName: string;
|
||||
|
||||
+5
-1
@@ -188,7 +188,11 @@ export function inferReactiveIdentifiers(
|
||||
const visitor = new Visitor();
|
||||
const state = new State(fn.env);
|
||||
for (const param of fn.params) {
|
||||
state.reactivityMap.set(param.identifier.id, true);
|
||||
if (param.kind === "Identifier") {
|
||||
state.reactivityMap.set(param.identifier.id, true);
|
||||
} else {
|
||||
state.reactivityMap.set(param.place.identifier.id, true);
|
||||
}
|
||||
}
|
||||
visitReactiveFunction(fn, visitor, state);
|
||||
|
||||
|
||||
+5
-1
@@ -27,7 +27,11 @@ export function printReactiveFunction(fn: ReactiveFunction): string {
|
||||
writer.writeLine(`function ${fn.id !== null ? fn.id : "<unknown>"}(`);
|
||||
writer.indented(() => {
|
||||
for (const param of fn.params) {
|
||||
writer.writeLine(`${printPlace(param)},`);
|
||||
if (param.kind === "Identifier") {
|
||||
writer.writeLine(`${printPlace(param)},`);
|
||||
} else {
|
||||
writer.writeLine(`...${printPlace(param.place)},`);
|
||||
}
|
||||
}
|
||||
});
|
||||
writer.writeLine(") {");
|
||||
|
||||
+11
-4
@@ -50,10 +50,17 @@ export function propagateScopeDependencies(fn: ReactiveFunction): void {
|
||||
|
||||
const context = new Context(escapingTemporaries.usedOutsideDeclaringScope);
|
||||
for (const param of fn.params) {
|
||||
context.declare(param.identifier, {
|
||||
id: makeInstructionId(0),
|
||||
scope: empty(),
|
||||
});
|
||||
if (param.kind === "Identifier") {
|
||||
context.declare(param.identifier, {
|
||||
id: makeInstructionId(0),
|
||||
scope: empty(),
|
||||
});
|
||||
} else {
|
||||
context.declare(param.place.identifier, {
|
||||
id: makeInstructionId(0),
|
||||
scope: empty(),
|
||||
});
|
||||
}
|
||||
}
|
||||
visitReactiveFunction(fn, new PropagationVisitor(), context);
|
||||
}
|
||||
|
||||
+5
-1
@@ -117,7 +117,11 @@ export function pruneNonEscapingScopes(
|
||||
// and which values are returned.
|
||||
const state = new State(fn.env);
|
||||
for (const param of fn.params) {
|
||||
state.declare(param.identifier.id);
|
||||
if (param.kind === "Identifier") {
|
||||
state.declare(param.identifier.id);
|
||||
} else {
|
||||
state.declare(param.place.identifier.id);
|
||||
}
|
||||
}
|
||||
visitReactiveFunction(
|
||||
fn,
|
||||
|
||||
@@ -34,7 +34,11 @@ export function renameVariables(fn: ReactiveFunction): void {
|
||||
const scopes = new Scopes();
|
||||
scopes.enter(() => {
|
||||
for (const param of fn.params) {
|
||||
scopes.visit(param.identifier);
|
||||
if (param.kind === "Identifier") {
|
||||
scopes.visit(param.identifier);
|
||||
} else {
|
||||
scopes.visit(param.place.identifier);
|
||||
}
|
||||
}
|
||||
visitReactiveFunction(fn, new Visitor(), scopes);
|
||||
});
|
||||
|
||||
@@ -259,7 +259,16 @@ function enterSSAImpl(
|
||||
loc: func.loc,
|
||||
suggestions: null,
|
||||
});
|
||||
func.params = func.params.map((p) => builder.definePlace(p));
|
||||
func.params = func.params.map((param) => {
|
||||
if (param.kind === "Identifier") {
|
||||
return builder.definePlace(param);
|
||||
} else {
|
||||
return {
|
||||
kind: "Spread",
|
||||
place: builder.definePlace(param.place),
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (const instr of block.instructions) {
|
||||
@@ -282,9 +291,16 @@ function enterSSAImpl(
|
||||
loweredFunc.context = loweredFunc.context.map((p) =>
|
||||
builder.getPlace(p)
|
||||
);
|
||||
loweredFunc.params = loweredFunc.params.map((p) =>
|
||||
builder.definePlace(p)
|
||||
);
|
||||
loweredFunc.params = loweredFunc.params.map((param) => {
|
||||
if (param.kind === "Identifier") {
|
||||
return builder.definePlace(param);
|
||||
} else {
|
||||
return {
|
||||
kind: "Spread",
|
||||
place: builder.definePlace(param.place),
|
||||
};
|
||||
}
|
||||
});
|
||||
enterSSAImpl(loweredFunc, builder, rootEntry);
|
||||
});
|
||||
entry.preds.clear();
|
||||
|
||||
@@ -100,13 +100,14 @@ export function leaveSSA(fn: HIRFunction): void {
|
||||
> = new Map();
|
||||
|
||||
for (const param of fn.params) {
|
||||
if (param.identifier.name !== null) {
|
||||
declarations.set(param.identifier.name, {
|
||||
let place: Place = param.kind === "Identifier" ? param : param.place;
|
||||
if (place.identifier.name !== null) {
|
||||
declarations.set(place.identifier.name, {
|
||||
lvalue: {
|
||||
kind: InstructionKind.Let,
|
||||
place: param,
|
||||
place,
|
||||
},
|
||||
place: param,
|
||||
place,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user