diff --git a/.prettierignore b/.prettierignore index 7e09af76a3af..ae076648cd43 100644 --- a/.prettierignore +++ b/.prettierignore @@ -22,6 +22,9 @@ compiler/**/.next # contains invalid graphql`...` which results in a promise rejection error from `yarn prettier-all`. compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-kitchensink.js +# contains explicit resource management syntax not yet parsed by prettier. +compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-await-using-declaration.js +compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-using-declaration.js compiler/crates compiler/target diff --git a/compiler/apps/playground/lib/compilation.ts b/compiler/apps/playground/lib/compilation.ts index b2bee8bd66d4..6fb6ce34bb40 100644 --- a/compiler/apps/playground/lib/compilation.ts +++ b/compiler/apps/playground/lib/compilation.ts @@ -46,7 +46,7 @@ function parseInput( }); } else { return babelParse(input, { - plugins: ['typescript', 'jsx'], + plugins: ['typescript', 'jsx', 'explicitResourceManagement'], sourceType: 'module', }) as ParseResult; } diff --git a/compiler/packages/babel-plugin-react-compiler/src/Babel/RunReactCompilerBabelPlugin.ts b/compiler/packages/babel-plugin-react-compiler/src/Babel/RunReactCompilerBabelPlugin.ts index d7960f7e612b..604fd9db07f2 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Babel/RunReactCompilerBabelPlugin.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Babel/RunReactCompilerBabelPlugin.ts @@ -22,7 +22,7 @@ export function runBabelPluginReactCompiler( ): BabelCore.BabelFileResult { const ast = BabelParser.parse(text, { sourceFilename: file, - plugins: [language, 'jsx'], + plugins: [language, 'jsx', 'explicitResourceManagement'], sourceType: 'module', }); const result = transformFromAstSync(ast, text, { diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts index 452aa0ce329d..1dbe6de4e74b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts @@ -903,7 +903,11 @@ function lowerStatement( case 'VariableDeclaration': { const stmt = stmtPath as NodePath; const nodeKind: t.VariableDeclaration['kind'] = stmt.node.kind; - if (nodeKind === 'var') { + if ( + nodeKind === 'var' || + nodeKind === 'using' || + nodeKind === 'await using' + ) { builder.recordError( new CompilerErrorDetail({ reason: `(BuildHIR::lowerStatement) Handle ${nodeKind} kinds in VariableDeclaration`, @@ -912,8 +916,8 @@ function lowerStatement( suggestions: null, }), ); - // Treat `var` as `let` so references to the variable don't break } + // Treat `var` as `let` so references to the variable don't break const kind = nodeKind === 'let' || nodeKind === 'var' ? InstructionKind.Let @@ -1183,6 +1187,17 @@ function lowerStatement( collection: {...value}, }); if (left.isVariableDeclaration()) { + const nodeKind = left.node.kind; + if (nodeKind === 'using' || nodeKind === 'await using') { + builder.recordError( + new CompilerErrorDetail({ + reason: `(BuildHIR::lowerStatement) Handle ${nodeKind} kinds in ForOfStatement`, + category: ErrorCategory.Todo, + loc: left.node.loc ?? null, + suggestions: null, + }), + ); + } const declarations = left.get('declarations'); CompilerError.invariant(declarations.length === 1, { reason: `Expected only one declaration in the init of a ForOfStatement, got ${declarations.length}`, @@ -1274,6 +1289,17 @@ function lowerStatement( value, }); if (left.isVariableDeclaration()) { + const nodeKind = left.node.kind; + if (nodeKind === 'using' || nodeKind === 'await using') { + builder.recordError( + new CompilerErrorDetail({ + reason: `(BuildHIR::lowerStatement) Handle ${nodeKind} kinds in ForInStatement`, + category: ErrorCategory.Todo, + loc: left.node.loc ?? null, + suggestions: null, + }), + ); + } const declarations = left.get('declarations'); CompilerError.invariant(declarations.length === 1, { reason: `Expected only one declaration in the init of a ForInStatement, got ${declarations.length}`, diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-await-using-declaration.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-await-using-declaration.expect.md new file mode 100644 index 000000000000..58476d514cd8 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-await-using-declaration.expect.md @@ -0,0 +1,35 @@ + +## Input + +```javascript +async function useAsyncResource() { + await using resource = createAsyncResource(); + return resource.value; +} + +export const FIXTURE_ENTRYPOINT = { + fn: useAsyncResource, + params: [], + isComponent: false, +}; + +``` + + +## Error + +``` +Found 1 error: + +Todo: (BuildHIR::lowerStatement) Handle await using kinds in VariableDeclaration + +error.todo-await-using-declaration.ts:2:2 + 1 | async function useAsyncResource() { +> 2 | await using resource = createAsyncResource(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (BuildHIR::lowerStatement) Handle await using kinds in VariableDeclaration + 3 | return resource.value; + 4 | } + 5 | +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-await-using-declaration.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-await-using-declaration.js new file mode 100644 index 000000000000..b42e272f5648 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-await-using-declaration.js @@ -0,0 +1,10 @@ +async function useAsyncResource() { + await using resource = createAsyncResource(); + return resource.value; +} + +export const FIXTURE_ENTRYPOINT = { + fn: useAsyncResource, + params: [], + isComponent: false, +}; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-using-declaration.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-using-declaration.expect.md new file mode 100644 index 000000000000..b6e0829638c6 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-using-declaration.expect.md @@ -0,0 +1,35 @@ + +## Input + +```javascript +function useResource() { + using resource = createResource(); + return resource.value; +} + +export const FIXTURE_ENTRYPOINT = { + fn: useResource, + params: [], + isComponent: false, +}; + +``` + + +## Error + +``` +Found 1 error: + +Todo: (BuildHIR::lowerStatement) Handle using kinds in VariableDeclaration + +error.todo-using-declaration.ts:2:2 + 1 | function useResource() { +> 2 | using resource = createResource(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (BuildHIR::lowerStatement) Handle using kinds in VariableDeclaration + 3 | return resource.value; + 4 | } + 5 | +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-using-declaration.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-using-declaration.js new file mode 100644 index 000000000000..e74bde0435e6 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-using-declaration.js @@ -0,0 +1,10 @@ +function useResource() { + using resource = createResource(); + return resource.value; +} + +export const FIXTURE_ENTRYPOINT = { + fn: useResource, + params: [], + isComponent: false, +}; diff --git a/compiler/packages/snap/src/compiler.ts b/compiler/packages/snap/src/compiler.ts index 0ee2ee0945b0..7fa532988fe5 100644 --- a/compiler/packages/snap/src/compiler.ts +++ b/compiler/packages/snap/src/compiler.ts @@ -120,7 +120,7 @@ export function parseInput( } else { return BabelParser.parse(input, { sourceFilename: filename, - plugins: ['typescript', 'jsx'], + plugins: ['typescript', 'jsx', 'explicitResourceManagement'], sourceType, }); }