Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[compiler] Outline jsx with duplicate attributes #31378

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
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 @@ -222,6 +222,8 @@ function collectProps(
const attributes: Array<OutlinedJsxAttribute> = [];
const jsxIds = new Set(instructions.map(i => i.lvalue.identifier.id));
const seen: Set<string> = new Set();
let id = 1;

for (const instr of instructions) {
const {value} = instr;

Expand All @@ -230,21 +232,17 @@ function collectProps(
return null;
}

/*
* TODO(gsn): Handle attributes that have same value across
* the outlined jsx instructions.
*/
if (seen.has(at.name)) {
return null;
}

if (at.kind === 'JsxAttribute') {
seen.add(at.name);
let newName = at.name;
while (seen.has(newName)) {
newName = `${at.name}${id++}`;
}
attributes.push({
originalName: at.name,
newName: at.name,
newName,
place: at.place,
});
seen.add(newName);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@

## Input

```javascript
// @enableJsxOutlining
function Component({arr}) {
const x = useX();
return (
<>
{arr.map((i, id) => {
return (
<Bar key={id} x={x}>
<Baz i={i + 'i'}></Baz>
<Foo k={i + 'j'}></Foo>
</Bar>
);
})}
</>
);
}
function Bar({x, children}) {
return (
<>
{x}
{children}
</>
);
}

function Baz({i}) {
return i;
}

function Foo({k}) {
return k;
}

function useX() {
return 'x';
}

export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{arr: ['foo', 'bar']}],
};

```

## Code

```javascript
import { c as _c } from "react/compiler-runtime"; // @enableJsxOutlining
function Component(t0) {
const $ = _c(7);
const { arr } = t0;
const x = useX();
let t1;
if ($[0] !== arr || $[1] !== x) {
let t2;
if ($[3] !== x) {
t2 = (i, id) => {
const T0 = _temp;
return <T0 i={i + "i"} k={i + "j"} key={id} x={x} />;
};
$[3] = x;
$[4] = t2;
} else {
t2 = $[4];
}
t1 = arr.map(t2);
$[0] = arr;
$[1] = x;
$[2] = t1;
} else {
t1 = $[2];
}
let t2;
if ($[5] !== t1) {
t2 = <>{t1}</>;
$[5] = t1;
$[6] = t2;
} else {
t2 = $[6];
}
return t2;
}
function _temp(t0) {
const $ = _c(8);
const { i: i, k: k, x: x } = t0;
let t1;
if ($[0] !== i) {
t1 = <Baz i={i} />;
$[0] = i;
$[1] = t1;
} else {
t1 = $[1];
}
let t2;
if ($[2] !== k) {
t2 = <Foo k={k} />;
$[2] = k;
$[3] = t2;
} else {
t2 = $[3];
}
let t3;
if ($[4] !== t1 || $[5] !== t2 || $[6] !== x) {
t3 = (
<Bar x={x}>
{t1}
{t2}
</Bar>
);
$[4] = t1;
$[5] = t2;
$[6] = x;
$[7] = t3;
} else {
t3 = $[7];
}
return t3;
}

function Bar(t0) {
const $ = _c(3);
const { x, children } = t0;
let t1;
if ($[0] !== children || $[1] !== x) {
t1 = (
<>
{x}
{children}
</>
);
$[0] = children;
$[1] = x;
$[2] = t1;
} else {
t1 = $[2];
}
return t1;
}

function Baz(t0) {
const { i } = t0;
return i;
}

function Foo(t0) {
const { k } = t0;
return k;
}

function useX() {
return "x";
}

export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ arr: ["foo", "bar"] }],
};

```

### Eval output
(kind: ok) xfooifoojxbaribarj
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// @enableJsxOutlining
function Component({arr}) {
const x = useX();
return (
<>
{arr.map((i, id) => {
return (
<Bar key={id} x={x}>
<Baz i={i + 'i'}></Baz>
<Foo k={i + 'j'}></Foo>
</Bar>
);
})}
</>
);
}
function Bar({x, children}) {
return (
<>
{x}
{children}
</>
);
}

function Baz({i}) {
return i;
}

function Foo({k}) {
return k;
}

function useX() {
return 'x';
}

export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{arr: ['foo', 'bar']}],
};
Loading
Loading