Skip to content

Commit

Permalink
Don't hoist a server function if a compile error was emitted (#73189)
Browse files Browse the repository at this point in the history
This allows us to skip unnecessary work, and also avoids generating invalid code, e.g. not allowed `super` calls in hoisted methods.
  • Loading branch information
unstubbable authored and wyattjoh committed Nov 28, 2024
1 parent 1763f32 commit 0ab07f4
Show file tree
Hide file tree
Showing 11 changed files with 75 additions and 156 deletions.
57 changes: 29 additions & 28 deletions crates/next-custom-transforms/src/transforms/server_actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -943,7 +943,7 @@ impl<C: Comments> VisitMut for ServerActions<C> {
fn visit_mut_function(&mut self, f: &mut Function) {
let directive = self.get_directive_for_function(f.body.as_mut());
let declared_idents_until = self.declared_idents.len();
let current_names = take(&mut self.names);
let old_names = take(&mut self.names);

if let Some(directive) = &directive {
self.this_status = ThisStatus::Forbidden {
Expand All @@ -967,19 +967,6 @@ impl<C: Comments> VisitMut for ServerActions<C> {
self.fn_decl_ident = old_fn_decl_ident;
}

if !self.config.is_react_server_layer {
return;
}

let mut child_names = if self.should_track_names {
let names = take(&mut self.names);
self.names = current_names;
self.names.extend(names.iter().cloned());
names
} else {
take(&mut self.names)
};

if let Some(directive) = directive {
if !f.is_async {
emit_error(ServerActionsErrorKind::InlineSyncFunction {
Expand All @@ -990,6 +977,19 @@ impl<C: Comments> VisitMut for ServerActions<C> {
return;
}

let has_errors = HANDLER.with(|handler| handler.has_errors());

// Don't hoist a function if 1) an error was emitted, or 2) we're in the client layer.
if has_errors || !self.config.is_react_server_layer {
return;
}

let mut child_names = take(&mut self.names);

if self.should_track_names {
self.names = [old_names, child_names.clone()].concat();
}

if let Directive::UseCache { cache_kind } = directive {
// Collect all the identifiers defined inside the closure and used
// in the cache function. With deduplication.
Expand Down Expand Up @@ -1116,7 +1116,7 @@ impl<C: Comments> VisitMut for ServerActions<C> {
}

let declared_idents_until = self.declared_idents.len();
let current_names = take(&mut self.names);
let old_names = take(&mut self.names);

{
// Visit children
Expand All @@ -1137,19 +1137,6 @@ impl<C: Comments> VisitMut for ServerActions<C> {
self.in_default_export_decl = old_in_default_export_decl;
}

if !self.config.is_react_server_layer {
return;
}

let mut child_names = if self.should_track_names {
let names = take(&mut self.names);
self.names = current_names;
self.names.extend(names.iter().cloned());
names
} else {
take(&mut self.names)
};

if let Some(directive) = directive {
if !a.is_async {
emit_error(ServerActionsErrorKind::InlineSyncFunction {
Expand All @@ -1160,6 +1147,20 @@ impl<C: Comments> VisitMut for ServerActions<C> {
return;
}

let has_errors = HANDLER.with(|handler| handler.has_errors());

// Don't hoist an arrow expression if 1) an error was emitted, or 2) we're in the client
// layer.
if has_errors || !self.config.is_react_server_layer {
return;
}

let mut child_names = take(&mut self.names);

if self.should_track_names {
self.names = [old_names, child_names.clone()].concat();
}

// Collect all the identifiers defined inside the closure and used
// in the action function. With deduplication.
retain_names_from_declared_idents(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
/* __next_internal_action_entry_do_not_use__ {"803128060c414d59f8552e4788b846c0d2b7f74743":"$$RSC_SERVER_CACHE_0"} */ import { registerServerReference } from "private-next-rsc-server-reference";
import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption";
import { cache as $$cache__ } from "private-next-rsc-cache-wrapper";
export var $$RSC_SERVER_CACHE_0 = $$cache__("x", "803128060c414d59f8552e4788b846c0d2b7f74743", 0, /*#__TURBOPACK_DISABLE_EXPORT_MERGING__*/ async function foo() {
export async function foo() {
return 'data';
});
Object.defineProperty($$RSC_SERVER_CACHE_0, "name", {
"value": "foo",
"writable": false
});
export var foo = registerServerReference($$RSC_SERVER_CACHE_0, "803128060c414d59f8552e4788b846c0d2b7f74743", null);
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
/* __next_internal_action_entry_do_not_use__ {"803128060c414d59f8552e4788b846c0d2b7f74743":"$$RSC_SERVER_CACHE_0"} */ import { registerServerReference } from "private-next-rsc-server-reference";
import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption";
import { cache as $$cache__ } from "private-next-rsc-cache-wrapper";
export var $$RSC_SERVER_CACHE_0 = $$cache__("x", "803128060c414d59f8552e4788b846c0d2b7f74743", 0, /*#__TURBOPACK_DISABLE_EXPORT_MERGING__*/ async function foo() {
export async function foo() {
return 'data';
});
Object.defineProperty($$RSC_SERVER_CACHE_0, "name", {
"value": "foo",
"writable": false
});
export var foo = registerServerReference($$RSC_SERVER_CACHE_0, "803128060c414d59f8552e4788b846c0d2b7f74743", null);
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
/* __next_internal_action_entry_do_not_use__ {"803128060c414d59f8552e4788b846c0d2b7f74743":"$$RSC_SERVER_CACHE_0"} */ import { registerServerReference } from "private-next-rsc-server-reference";
import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption";
import { cache as $$cache__ } from "private-next-rsc-cache-wrapper";
export var $$RSC_SERVER_CACHE_0 = $$cache__("default", "803128060c414d59f8552e4788b846c0d2b7f74743", 0, /*#__TURBOPACK_DISABLE_EXPORT_MERGING__*/ async function fn() {
export async function fn() {
'use server';
});
Object.defineProperty($$RSC_SERVER_CACHE_0, "name", {
"value": "fn",
"writable": false
});
export var fn = registerServerReference($$RSC_SERVER_CACHE_0, "803128060c414d59f8552e4788b846c0d2b7f74743", null);
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,2 @@
/* __next_internal_action_entry_do_not_use__ {"803128060c414d59f8552e4788b846c0d2b7f74743":"$$RSC_SERVER_CACHE_0"} */ import { registerServerReference } from "private-next-rsc-server-reference";
import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption";
import { cache as $$cache__ } from "private-next-rsc-cache-wrapper";
'use server';
export var $$RSC_SERVER_CACHE_0 = $$cache__("default", "803128060c414d59f8552e4788b846c0d2b7f74743", 0, /*#__TURBOPACK_DISABLE_EXPORT_MERGING__*/ async function fn() {});
Object.defineProperty($$RSC_SERVER_CACHE_0, "name", {
"value": "fn",
"writable": false
});
export var fn = registerServerReference($$RSC_SERVER_CACHE_0, "803128060c414d59f8552e4788b846c0d2b7f74743", null);
export async function fn() {}
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
/*#__TURBOPACK_DISABLE_EXPORT_MERGING__*/ /* __next_internal_action_entry_do_not_use__ {"006a88810ecce4a4e8b59d53b8327d7e98bbf251d7":"$$RSC_SERVER_ACTION_0","8069348c79fce073bae2f70f139565a2fda1c74c74":"$$RSC_SERVER_CACHE_2","80951c375b4a6a6e89d67b743ec5808127cfde405d":"$$RSC_SERVER_CACHE_1"} */ import { registerServerReference } from "private-next-rsc-server-reference";
import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption";
import { cache as $$cache__ } from "private-next-rsc-cache-wrapper";
export const /*#__TURBOPACK_DISABLE_EXPORT_MERGING__*/ $$RSC_SERVER_ACTION_0 = async function e() {
// this is not allowed here
this.foo();
// arguments is not allowed here
console.log(arguments);
};
export var $$RSC_SERVER_CACHE_1 = $$cache__("default", "80951c375b4a6a6e89d67b743ec5808127cfde405d", 0, async function a() {
async function a() {
// this is not allowed here
this.foo();
// arguments is not allowed here
Expand All @@ -29,27 +20,22 @@ export var $$RSC_SERVER_CACHE_1 = $$cache__("default", "80951c375b4a6a6e89d67b74
// arguments is allowed here
console.log(arguments);
};
const e = registerServerReference($$RSC_SERVER_ACTION_0, "006a88810ecce4a4e8b59d53b8327d7e98bbf251d7", null);
const e = async ()=>{
// this is not allowed here
this.foo();
// arguments is not allowed here
console.log(arguments);
};
}
});
Object.defineProperty($$RSC_SERVER_CACHE_1, "name", {
"value": "a",
"writable": false
});
var a = registerServerReference($$RSC_SERVER_CACHE_1, "80951c375b4a6a6e89d67b743ec5808127cfde405d", null);
export var $$RSC_SERVER_CACHE_2 = $$cache__("default", "8069348c79fce073bae2f70f139565a2fda1c74c74", 0, /*#__TURBOPACK_DISABLE_EXPORT_MERGING__*/ async function fetch1() {
// this is not allowed here
this.result = await fetch('https://example.com').then((res)=>res.json());
// arguments is not allowed here
console.log(arguments);
});
Object.defineProperty($$RSC_SERVER_CACHE_2, "name", {
"value": "fetch",
"writable": false
});
}
export const api = {
result: null,
product: {
fetch: registerServerReference($$RSC_SERVER_CACHE_2, "8069348c79fce073bae2f70f139565a2fda1c74c74", null)
async fetch () {
// this is not allowed here
this.result = await fetch('https://example.com').then((res)=>res.json());
// arguments is not allowed here
console.log(arguments);
}
}
};
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
/* __next_internal_action_entry_do_not_use__ {"006a88810ecce4a4e8b59d53b8327d7e98bbf251d7":"$$RSC_SERVER_ACTION_0"} */ import { registerServerReference } from "private-next-rsc-server-reference";
import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption";
export const /*#__TURBOPACK_DISABLE_EXPORT_MERGING__*/ $$RSC_SERVER_ACTION_0 = async function b() {
// this is not allowed here
this.foo();
// arguments is not allowed here
console.log(arguments);
};
// not exported!
async function a() {
// this is allowed here
this.foo();
// arguments is allowed here
console.log(arguments);
const b = registerServerReference($$RSC_SERVER_ACTION_0, "006a88810ecce4a4e8b59d53b8327d7e98bbf251d7", null);
const b = async ()=>{
// this is not allowed here
this.foo();
// arguments is not allowed here
console.log(arguments);
};
}
export const obj = {
foo () {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
/* __next_internal_action_entry_do_not_use__ {"006a88810ecce4a4e8b59d53b8327d7e98bbf251d7":"$$RSC_SERVER_ACTION_0","80951c375b4a6a6e89d67b743ec5808127cfde405d":"$$RSC_SERVER_CACHE_1"} */ import { registerServerReference } from "private-next-rsc-server-reference";
import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption";
import { cache as $$cache__ } from "private-next-rsc-cache-wrapper";
export const /*#__TURBOPACK_DISABLE_EXPORT_MERGING__*/ $$RSC_SERVER_ACTION_0 = async function e() {
// this is not allowed here
this.foo();
// arguments is not allowed here
console.log(arguments);
};
export var $$RSC_SERVER_CACHE_1 = $$cache__("default", "80951c375b4a6a6e89d67b743ec5808127cfde405d", 0, /*#__TURBOPACK_DISABLE_EXPORT_MERGING__*/ async function a() {
// exported!
export async function a() {
// this is not allowed here
this.foo();
// arguments is not allowed here
Expand All @@ -29,12 +21,11 @@ export var $$RSC_SERVER_CACHE_1 = $$cache__("default", "80951c375b4a6a6e89d67b74
// arguments is allowed here
console.log(arguments);
};
const e = registerServerReference($$RSC_SERVER_ACTION_0, "006a88810ecce4a4e8b59d53b8327d7e98bbf251d7", null);
const e = async ()=>{
// this is not allowed here
this.foo();
// arguments is not allowed here
console.log(arguments);
};
}
});
Object.defineProperty($$RSC_SERVER_CACHE_1, "name", {
"value": "a",
"writable": false
});
// exported!
export var a = registerServerReference($$RSC_SERVER_CACHE_1, "80951c375b4a6a6e89d67b743ec5808127cfde405d", null);
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
/* __next_internal_action_entry_do_not_use__ {"803128060c414d59f8552e4788b846c0d2b7f74743":"$$RSC_SERVER_CACHE_0"} */ import { registerServerReference } from "private-next-rsc-server-reference";
import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption";
import { cache as $$cache__ } from "private-next-rsc-cache-wrapper";
export var $$RSC_SERVER_CACHE_0 = $$cache__("default", "803128060c414d59f8552e4788b846c0d2b7f74743", 0, /*#__TURBOPACK_DISABLE_EXPORT_MERGING__*/ async function bar() {
// arguments is not allowed here
console.log(arguments);
// this is not allowed here
return this.foo();
});
Object.defineProperty($$RSC_SERVER_CACHE_0, "name", {
"value": "bar",
"writable": false
});
export class MyClass {
static async foo() {
return fetch('https://example.com').then((res)=>res.json());
}
static bar = registerServerReference($$RSC_SERVER_CACHE_0, "803128060c414d59f8552e4788b846c0d2b7f74743", null);
static async bar() {
// arguments is not allowed here
console.log(arguments);
// this is not allowed here
return this.foo();
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
/* __next_internal_action_entry_do_not_use__ {"803128060c414d59f8552e4788b846c0d2b7f74743":"$$RSC_SERVER_CACHE_0"} */ import { registerServerReference } from "private-next-rsc-server-reference";
import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption";
import { cache as $$cache__ } from "private-next-rsc-cache-wrapper";
export var $$RSC_SERVER_CACHE_0 = $$cache__("default", "803128060c414d59f8552e4788b846c0d2b7f74743", 0, /*#__TURBOPACK_DISABLE_EXPORT_MERGING__*/ async function Page() {
export default async function Page() {
return <p>hello world</p>;
});
Object.defineProperty($$RSC_SERVER_CACHE_0, "name", {
"value": "Page",
"writable": false
});
export default registerServerReference($$RSC_SERVER_CACHE_0, "803128060c414d59f8552e4788b846c0d2b7f74743", null);
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
/* __next_internal_action_entry_do_not_use__ {"803128060c414d59f8552e4788b846c0d2b7f74743":"$$RSC_SERVER_CACHE_0"} */ import { registerServerReference } from "private-next-rsc-server-reference";
import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption";
import { cache as $$cache__ } from "private-next-rsc-cache-wrapper";
export var $$RSC_SERVER_CACHE_0 = $$cache__("x", "803128060c414d59f8552e4788b846c0d2b7f74743", 0, /*#__TURBOPACK_DISABLE_EXPORT_MERGING__*/ async function Page() {
export default async function Page() {
return <p>hello world</p>;
});
Object.defineProperty($$RSC_SERVER_CACHE_0, "name", {
"value": "Page",
"writable": false
});
export default registerServerReference($$RSC_SERVER_CACHE_0, "803128060c414d59f8552e4788b846c0d2b7f74743", null);
}

0 comments on commit 0ab07f4

Please sign in to comment.