Skip to content

Commit

Permalink
[compiler] Handle member expr as computed property (#31344)
Browse files Browse the repository at this point in the history
This PR loosens the restriction on the types of computed properties we
can handle.

Previously, we would disallow anything that is not an identifier because
non-identifiers could be mutating. But member expressions are not
mutating so we can treat them similar to identifiers.
  • Loading branch information
gsathya authored Oct 28, 2024
1 parent fe04dbc commit aded0ef
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -1418,7 +1418,7 @@ function lowerObjectPropertyKey(
name: key.node.value,
};
} else if (property.node.computed && key.isExpression()) {
if (!key.isIdentifier()) {
if (!key.isIdentifier() && !key.isMemberExpression()) {
/*
* NOTE: allowing complex key expressions can trigger a bug where a mutation is made conditional
* see fixture
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

## Input

```javascript
import {identity, mutate, mutateAndReturn} from 'shared-runtime';

function Component(props) {
const obj = {mutateAndReturn};
const key = {};
const context = {
[obj.mutateAndReturn(key)]: identity([props.value]),
};
mutate(key);
return context;
}

export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{value: 42}],
};

```


## Error

```
5 | const key = {};
6 | const context = {
> 7 | [obj.mutateAndReturn(key)]: identity([props.value]),
| ^^^^^^^^^^^^^^^^^^^^^^^^ Todo: (BuildHIR::lowerExpression) Expected Identifier, got CallExpression key in ObjectExpression (7:7)
8 | };
9 | mutate(key);
10 | return context;
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {identity, mutate, mutateAndReturn} from 'shared-runtime';

function Component(props) {
const obj = {mutateAndReturn};
const key = {};
const context = {
[obj.mutateAndReturn(key)]: identity([props.value]),
};
mutate(key);
return context;
}

export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{value: 42}],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

## Input

```javascript
import {identity, mutate, mutateAndReturn} from 'shared-runtime';

function Component(props) {
const key = {a: 'key'};
const context = {
[key.a]: identity([props.value]),
};
mutate(key);
return context;
}

export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{value: 42}],
};

```

## Code

```javascript
import { c as _c } from "react/compiler-runtime";
import { identity, mutate, mutateAndReturn } from "shared-runtime";

function Component(props) {
const $ = _c(2);
let context;
if ($[0] !== props.value) {
const key = { a: "key" };
context = { [key.a]: identity([props.value]) };

mutate(key);
$[0] = props.value;
$[1] = context;
} else {
context = $[1];
}
return context;
}

export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ value: 42 }],
};

```
### Eval output
(kind: ok) {"key":[42]}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {identity, mutate, mutateAndReturn} from 'shared-runtime';

function Component(props) {
const key = {a: 'key'};
const context = {
[key.a]: identity([props.value]),
};
mutate(key);
return context;
}

export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{value: 42}],
};

0 comments on commit aded0ef

Please sign in to comment.