Skip to content

Commit

Permalink
feat(compiler): Support MetaProperty (#29752)
Browse files Browse the repository at this point in the history
## Summary
See #29737

## How did you test this change?
As the feature requires module support and the test runner does
currently not support running tests as modules, I could only test it via
playground.
  • Loading branch information
nikeee authored Jun 8, 2024
1 parent c2ae9e2 commit f5af92d
Show file tree
Hide file tree
Showing 17 changed files with 202 additions and 2 deletions.
22 changes: 22 additions & 0 deletions compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2427,6 +2427,28 @@ function lowerExpression(
let expr = exprPath as NodePath<t.TSNonNullExpression>;
return lowerExpression(builder, expr.get("expression"));
}
case "MetaProperty": {
let expr = exprPath as NodePath<t.MetaProperty>;
if (
expr.node.meta.name === "import" &&
expr.node.property.name === "meta"
) {
return {
kind: "MetaProperty",
meta: expr.node.meta.name,
property: expr.node.property.name,
loc: expr.node.loc ?? GeneratedSource,
};
}

builder.errors.push({
reason: `(BuildHIR::lowerExpression) Handle MetaProperty expressions other than import.meta`,
severity: ErrorSeverity.Todo,
loc: exprPath.node.loc ?? null,
suggestions: null,
});
return { kind: "UnsupportedNode", node: exprNode, loc: exprLoc };
}
default: {
builder.errors.push({
reason: `(BuildHIR::lowerExpression) Handle ${exprPath.type} expressions`,
Expand Down
6 changes: 6 additions & 0 deletions compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,12 @@ export type InstructionValue =
flags: string;
loc: SourceLocation;
}
| {
kind: "MetaProperty";
meta: string;
property: string;
loc: SourceLocation;
}

// store `object.property = value`
| {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,10 @@ export function printInstructionValue(instrValue: ReactiveValue): string {
value = `RegExp /${instrValue.pattern}/${instrValue.flags}`;
break;
}
case "MetaProperty": {
value = `MetaProperty ${instrValue.meta}.${instrValue.property}`;
break;
}
case "Await": {
value = `Await ${printPlace(instrValue.value)}`;
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ export function* eachInstructionValueOperand(
}
case "Debugger":
case "RegExpLiteral":
case "MetaProperty":
case "LoadGlobal":
case "UnsupportedNode":
case "Primitive":
Expand Down Expand Up @@ -566,6 +567,7 @@ export function mapInstructionValueOperands(
}
case "Debugger":
case "RegExpLiteral":
case "MetaProperty":
case "LoadGlobal":
case "UnsupportedNode":
case "Primitive":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1216,6 +1216,18 @@ function inferBlock(
};
break;
}
case "MetaProperty": {
if (instrValue.meta !== "import" || instrValue.property !== "meta") {
continue;
}

valueKind = {
kind: ValueKind.Global,
reason: new Set([ValueReason.Global]),
context: new Set(),
};
break;
}
case "LoadGlobal":
valueKind = {
kind: ValueKind.Global,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ function pruneableValue(value: InstructionValue, state: State): boolean {
return false;
}
case "RegExpLiteral":
case "MetaProperty":
case "LoadGlobal":
case "ArrayExpression":
case "BinaryExpression":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2021,6 +2021,13 @@ function codegenInstructionValue(
value = t.regExpLiteral(instrValue.pattern, instrValue.flags);
break;
}
case "MetaProperty": {
value = t.metaProperty(
t.identifier(instrValue.meta),
t.identifier(instrValue.property)
);
break;
}
case "Await": {
value = t.awaitExpression(codegenPlaceToExpression(cx, instrValue.value));
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ function mayAllocate(env: Environment, instruction: Instruction): boolean {
case "DeclareContext":
case "StoreLocal":
case "LoadGlobal":
case "MetaProperty":
case "TypeCastExpression":
case "LoadLocal":
case "LoadContext":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@ function computeMemoizationInputs(
case "ComputedDelete":
case "PropertyDelete":
case "LoadGlobal":
case "MetaProperty":
case "TemplateLiteral":
case "Primitive":
case "JSXText":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ function* generateInstructionTypes(
case "DeclareLocal":
case "NewExpression":
case "RegExpLiteral":
case "MetaProperty":
case "PropertyStore":
case "ComputedStore":
case "ComputedLoad":
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

## Input

```javascript
import { Stringify } from "shared-runtime";

function foo() {
const nt = new.target;
return <Stringify value={nt} />;
}

```


## Error

```
2 |
3 | function foo() {
> 4 | const nt = new.target;
| ^^^^^^^^^^ Todo: (BuildHIR::lowerExpression) Handle MetaProperty expressions other than import.meta (4:4)
5 | return <Stringify value={nt} />;
6 | }
7 |
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Stringify } from "shared-runtime";

function foo() {
const nt = new.target;
return <Stringify value={nt} />;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@

## Input

```javascript
function a() {
return import.meta.url;
}

function b() {
let a = 0;
if (import.meta.url) {
a = 1;
}
return a;
}

function c() {
let a = 0;
if (import.meta.foo) {
a = 1;
}
return a;
}

function d() {
let a = 0;
if (import.meta) {
a = 1;
}
return a;
}

```
## Code
```javascript
function a() {
return import.meta.url;
}

function b() {
let a = 0;
if (import.meta.url) {
a = 1;
}
return a;
}

function c() {
let a = 0;
if (import.meta.foo) {
a = 1;
}
return a;
}

function d() {
let a = 0;
if (import.meta) {
a = 1;
}
return a;
}

```
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
function a() {
return import.meta.url;
}

function b() {
let a = 0;
if (import.meta.url) {
a = 1;
}
return a;
}

function c() {
let a = 0;
if (import.meta.foo) {
a = 1;
}
return a;
}

function d() {
let a = 0;
if (import.meta) {
a = 1;
}
return a;
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@
},
"include": [
"./compiler/**/*.js",
"./compiler/**/*.jsx",
"./compiler/**/*.mjs",
"./compiler/**/*.cjs",
"./compiler/**/*.ts",
"./compiler/**/*.mts",
"./compiler/**/*.cts",
"./compiler/**/*.jsx",
"./compiler/**/*.tsx"
]
}
3 changes: 3 additions & 0 deletions compiler/packages/snap/src/SproutTodoFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,9 @@ const skipFilter = new Set([
"useState-unpruned-dependency",
"useState-and-other-hook-unpruned-dependency",
"change-detect-reassign",

// needs to be executed as a module
"meta-property",
]);

export default skipFilter;
11 changes: 10 additions & 1 deletion compiler/packages/snap/src/fixture-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,16 @@ import * as glob from "glob";
import path from "path";
import { FILTER_PATH, FIXTURES_PATH, SNAPSHOT_EXTENSION } from "./constants";

const INPUT_EXTENSIONS = [".js", ".ts", ".jsx", ".tsx"];
const INPUT_EXTENSIONS = [
".js",
".cjs",
".mjs",
".ts",
".cts",
".mts",
".jsx",
".tsx",
];

export type TestFilter = {
debug: boolean;
Expand Down

0 comments on commit f5af92d

Please sign in to comment.