Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,16 @@ function process(
return {instrs: newInstrs, fn: outlinedFn};
}

type OutlinedJsxAttribute = {
originalName: string;
newName: string;
place: Place;
};

function collectProps(
instructions: Array<JsxInstruction>,
): Array<JsxAttribute> | null {
const attributes: Array<JsxAttribute> = [];
): Array<OutlinedJsxAttribute> | null {
const attributes: Array<OutlinedJsxAttribute> = [];
const jsxIds = new Set(instructions.map(i => i.lvalue.identifier.id));
const seen: Set<string> = new Set();
for (const instr of instructions) {
Expand All @@ -234,7 +240,11 @@ function collectProps(

if (at.kind === 'JsxAttribute') {
seen.add(at.name);
attributes.push(at);
attributes.push({
originalName: at.name,
newName: at.name,
place: at.place,
});
}
}

Expand All @@ -252,9 +262,15 @@ function collectProps(
function emitOutlinedJsx(
env: Environment,
instructions: Array<Instruction>,
props: Array<JsxAttribute>,
outlinedProps: Array<OutlinedJsxAttribute>,
outlinedTag: string,
): Array<Instruction> {
const props: Array<JsxAttribute> = outlinedProps.map(p => ({
kind: 'JsxAttribute',
name: p.newName,
place: p.place,
}));

const loadJsx: Instruction = {
id: makeInstructionId(0),
loc: GeneratedSource,
Expand Down Expand Up @@ -290,7 +306,7 @@ function emitOutlinedJsx(
function emitOutlinedFn(
env: Environment,
jsx: Array<JsxInstruction>,
oldProps: Array<JsxAttribute>,
oldProps: Array<OutlinedJsxAttribute>,
globals: LoadGlobalMap,
): HIRFunction | null {
const instructions: Array<Instruction> = [];
Expand All @@ -299,9 +315,11 @@ function emitOutlinedFn(
const propsObj: Place = createTemporaryPlace(env, GeneratedSource);
promoteTemporary(propsObj.identifier);

const destructurePropsInstr = emitDestructureProps(env, propsObj, [
...oldToNewProps.values(),
]);
const destructurePropsInstr = emitDestructureProps(
env,
propsObj,
oldToNewProps,
);
instructions.push(destructurePropsInstr);

const updatedJsxInstructions = emitUpdatedJsx(jsx, oldToNewProps);
Expand Down Expand Up @@ -368,7 +386,7 @@ function emitLoadGlobals(

function emitUpdatedJsx(
jsx: Array<JsxInstruction>,
oldToNewProps: Map<IdentifierId, ObjectProperty>,
oldToNewProps: Map<IdentifierId, OutlinedJsxAttribute>,
): Array<JsxInstruction> {
const newInstrs: Array<JsxInstruction> = [];

Expand All @@ -390,7 +408,8 @@ function emitUpdatedJsx(
`Expected a new property for ${printIdentifier(prop.place.identifier)}`,
);
newProps.push({
...prop,
kind: 'JsxAttribute',
name: newProp.originalName,
place: newProp.place,
});
}
Expand All @@ -409,31 +428,21 @@ function emitUpdatedJsx(

function createOldToNewPropsMapping(
env: Environment,
oldProps: Array<JsxAttribute>,
): Map<IdentifierId, ObjectProperty> {
oldProps: Array<OutlinedJsxAttribute>,
): Map<IdentifierId, OutlinedJsxAttribute> {
const oldToNewProps = new Map();

for (const oldProp of oldProps) {
invariant(
oldProp.kind === 'JsxAttribute',
`Expected only attributes but found ${oldProp.kind}`,
);

// Do not read key prop in the outlined component
if (oldProp.name === 'key') {
if (oldProp.originalName === 'key') {
continue;
}

const newProp: ObjectProperty = {
kind: 'ObjectProperty',
key: {
kind: 'string',
name: oldProp.name,
},
type: 'property',
const newProp: OutlinedJsxAttribute = {
...oldProp,
place: createTemporaryPlace(env, GeneratedSource),
};
newProp.place.identifier.name = makeIdentifierName(oldProp.name);
newProp.place.identifier.name = makeIdentifierName(oldProp.newName);
oldToNewProps.set(oldProp.place.identifier.id, newProp);
}

Expand All @@ -443,8 +452,21 @@ function createOldToNewPropsMapping(
function emitDestructureProps(
env: Environment,
propsObj: Place,
properties: Array<ObjectProperty>,
oldToNewProps: Map<IdentifierId, OutlinedJsxAttribute>,
): Instruction {
const properties: Array<ObjectProperty> = [];
for (const [_, prop] of oldToNewProps) {
properties.push({
kind: 'ObjectProperty',
key: {
kind: 'string',
name: prop.newName,
},
type: 'property',
place: prop.place,
});
}

const destructurePropsInstr: Instruction = {
id: makeInstructionId(0),
lvalue: createTemporaryPlace(env, GeneratedSource),
Expand Down