Skip to content
Merged
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
1 change: 1 addition & 0 deletions .oxfmtrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
},
"ignorePatterns": [
"*.snap.*",
"packages/plugin-rsc/src/transforms/fixtures/source-map/wrap-export/default-comments.js",
"typescript-eslint/",
"packages/*/CHANGELOG.md",
"playground-temp/",
Expand Down
2 changes: 2 additions & 0 deletions packages/plugin-rsc/e2e/use-cache-callable.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,13 @@ function defineTests(f: Fixture) {
const example = page.getByTestId('file-directive-from-server')
const submissionCount = example.getByTestId('submission-count')
const executionCount = example.getByTestId('execution-count')
const ordinaryExports = example.getByTestId('ordinary-exports')
const result = example.getByTestId('result')
const argument = example.getByRole('textbox', { name: 'Cache key' })
await page.getByRole('button', { name: 'Reset' }).click()
await expect(submissionCount).toHaveText('0')
await expect(executionCount).toHaveText('0')
await expect(ordinaryExports).toHaveText('cached metadata: cache')
await expect(result).toHaveText('not called')

// The wrapped export is passed from a Server Component to a Client Component.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ export function callableCachePlugin(): Plugin {
const result = hasDirective(ast.body, directive)
? transformWrapExport(code, ast, {
runtime,
// Next.js calls rejecting primitive literals while permitting
// objects and arrays arbitrary, but keeps the latter for metadata
// and viewport exports.
// https://github.com/vercel/next.js/blob/aae4179ac628e55483b62cd023a7e1827dcef122/crates/next-custom-transforms/src/transforms/server_actions.rs#L1914-L1919
filter: (_name, meta) =>
meta.valueNode?.type !== 'ObjectExpression' &&
meta.valueNode?.type !== 'ArrayExpression',
rejectNonAsyncFunction: true,
})
: transformHoistInlineDirective(code, ast, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

import { state } from './state'

// Ordinary values remain available from "use cache" modules without becoming
// callable server references.
export const metadata = { title: 'cached metadata' }
export const tags = ['cache']

export async function cachedFromServer(formData: FormData) {
const argument = String(formData.get('argument'))
state.executionCount++
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useState } from 'react'
export function FileDirectiveFromServerClient(props: {
action: (formData: FormData) => Promise<void>
executionCount: number
ordinaryExports: string
resetAction: () => Promise<void>
result: string
}) {
Expand Down Expand Up @@ -35,6 +36,11 @@ export function FileDirectiveFromServerClient(props: {
{props.executionCount}
</output>
<br />
Ordinary exports:{' '}
<output data-testid="ordinary-exports">
{props.ordinaryExports}
</output>
<br />
Result: <output data-testid="result">{props.result}</output>
</span>
</p>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { cachedFromServer } from './action'
import { cachedFromServer, metadata, tags } from './action'
import { FileDirectiveFromServerClient } from './client'
import { resetAction } from './reset'
import { state } from './state'
Expand All @@ -8,6 +8,7 @@ export function FileDirectiveFromServer() {
<FileDirectiveFromServerClient
action={cachedFromServer}
executionCount={state.executionCount}
ordinaryExports={`${metadata.title}: ${tags.join(', ')}`}
resetAction={resetAction}
result={state.result}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use server'

export class NamedClass {}

export const ClassExpression = class InnerClass {}

export default class DefaultClass {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
## wrap-export

```txt
(0:0) "'use server'\n" --> (0:0) "'use server'\n"
(2:7) "class NamedClass {}\n" --> (2:0) "class NamedClass {}\n"
(4:7) "const" --> (4:0) "let"
(4:12) " ClassExpression = class InnerClass {}\n" --> (4:3) " ClassExpression = class InnerClass {}\n"
(6:15) "class DefaultClass {}\n" --> (6:0) "class DefaultClass {}\n"
(2:0) "export class NamedClass {}\n" --> (7:0) "NamedClass = /* #__PURE__ */ registerServerReference(NamedClass, \"NamedClass\");\n"
(2:0) "export class NamedClass {}\n" --> (8:0) "export { NamedClass };\n"
(4:0) "export const ClassExpression = class InnerClass {}\n" --> (9:0) "ClassExpression = /* #__PURE__ */ registerServerReference(ClassExpression, \"ClassExpression\");\n"
(4:0) "export const ClassExpression = class InnerClass {}\n" --> (10:0) "export { ClassExpression };\n"
[unmapped] --> (11:0) ";\n"
[unmapped] --> (12:0) "const $$wrap_DefaultClass = /* #__PURE__ */ registerServerReference(DefaultClass, \"default\");\n"
[unmapped] --> (13:0) "export { $$wrap_DefaultClass as default };\n"
```

## module-export-effect

```txt
(0:0) "'use server'\n" --> (0:0) "'use server'\n"
(2:7) "class NamedClass {}\n" --> (2:0) "class NamedClass {}\n"
(4:7) "const ClassExpression = class InnerClass {}\n" --> (4:0) "const ClassExpression = class InnerClass {}\n"
(6:15) "class DefaultClass {}\n" --> (6:0) "class DefaultClass {}\n"
(2:0) "export class NamedClass {}\n" --> (7:0) "\n"
(2:0) "export class NamedClass {}\n" --> (8:0) "registerServerReference(NamedClass, \"NamedClass\");\n"
(2:0) "export class NamedClass {}\n" --> (9:0) "export { NamedClass };\n"
(4:0) "export const ClassExpression = class InnerClass {}\n" --> (10:0) "\n"
(4:0) "export const ClassExpression = class InnerClass {}\n" --> (11:0) "registerServerReference(ClassExpression, \"ClassExpression\");\n"
(4:0) "export const ClassExpression = class InnerClass {}\n" --> (12:0) "export { ClassExpression };\n"
(6:0) "export default class DefaultClass {}\n" --> (13:0) "\n"
(6:0) "export default class DefaultClass {}\n" --> (14:0) "registerServerReference(DefaultClass, \"default\");\n"
(6:0) "export default class DefaultClass {}\n" --> (15:0) "export default DefaultClass;\n"
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
## Input

```js
'use server'

export class NamedClass {}

export const ClassExpression = class InnerClass {}

export default class DefaultClass {}
```

## wrap-export

**Status:** transformed

**References:** NamedClass, ClassExpression, default

[Source map visualization](https://evanw.github.io/source-map-visualization/#NDY1ACd1c2Ugc2VydmVyJwoKY2xhc3MgTmFtZWRDbGFzcyB7fQoKbGV0IENsYXNzRXhwcmVzc2lvbiA9IGNsYXNzIElubmVyQ2xhc3Mge30KCmNsYXNzIERlZmF1bHRDbGFzcyB7fQpOYW1lZENsYXNzID0gLyogI19fUFVSRV9fICovIHJlZ2lzdGVyU2VydmVyUmVmZXJlbmNlKE5hbWVkQ2xhc3MsICJOYW1lZENsYXNzIik7CmV4cG9ydCB7IE5hbWVkQ2xhc3MgfTsKQ2xhc3NFeHByZXNzaW9uID0gLyogI19fUFVSRV9fICovIHJlZ2lzdGVyU2VydmVyUmVmZXJlbmNlKENsYXNzRXhwcmVzc2lvbiwgIkNsYXNzRXhwcmVzc2lvbiIpOwpleHBvcnQgeyBDbGFzc0V4cHJlc3Npb24gfTsKOwpjb25zdCAkJHdyYXBfRGVmYXVsdENsYXNzID0gLyogI19fUFVSRV9fICovIHJlZ2lzdGVyU2VydmVyUmVmZXJlbmNlKERlZmF1bHRDbGFzcywgImRlZmF1bHQiKTsKZXhwb3J0IHsgJCR3cmFwX0RlZmF1bHRDbGFzcyBhcyBkZWZhdWx0IH07CjM4NwB7InZlcnNpb24iOjMsInNvdXJjZXMiOlsiIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc2VydmVyJ1xuXG5leHBvcnQgY2xhc3MgTmFtZWRDbGFzcyB7fVxuXG5leHBvcnQgY29uc3QgQ2xhc3NFeHByZXNzaW9uID0gY2xhc3MgSW5uZXJDbGFzcyB7fVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEZWZhdWx0Q2xhc3Mge31cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxDQUFDLEdBQUcsQ0FBQyxNQUFNOztBQUVKLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQzs7QUFFbEIsR0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDOztBQUVsQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7QUFKbkM7QUFBQTtBQUVBO0FBQUE7Ozs7In0=)

```js
'use server'

class NamedClass {}

let ClassExpression = class InnerClass {}

class DefaultClass {}
NamedClass = /* #__PURE__ */ registerServerReference(NamedClass, "NamedClass");
export { NamedClass };
ClassExpression = /* #__PURE__ */ registerServerReference(ClassExpression, "ClassExpression");
export { ClassExpression };
;
const $$wrap_DefaultClass = /* #__PURE__ */ registerServerReference(DefaultClass, "default");
export { $$wrap_DefaultClass as default };
```

## module-export-effect

**Status:** transformed

**References:** NamedClass, ClassExpression, default

[Source map visualization](https://evanw.github.io/source-map-visualization/#MzQ3ACd1c2Ugc2VydmVyJwoKY2xhc3MgTmFtZWRDbGFzcyB7fQoKY29uc3QgQ2xhc3NFeHByZXNzaW9uID0gY2xhc3MgSW5uZXJDbGFzcyB7fQoKY2xhc3MgRGVmYXVsdENsYXNzIHt9CgpyZWdpc3RlclNlcnZlclJlZmVyZW5jZShOYW1lZENsYXNzLCAiTmFtZWRDbGFzcyIpOwpleHBvcnQgeyBOYW1lZENsYXNzIH07CgpyZWdpc3RlclNlcnZlclJlZmVyZW5jZShDbGFzc0V4cHJlc3Npb24sICJDbGFzc0V4cHJlc3Npb24iKTsKZXhwb3J0IHsgQ2xhc3NFeHByZXNzaW9uIH07CgpyZWdpc3RlclNlcnZlclJlZmVyZW5jZShEZWZhdWx0Q2xhc3MsICJkZWZhdWx0Iik7CmV4cG9ydCBkZWZhdWx0IERlZmF1bHRDbGFzczsKNDA5AHsidmVyc2lvbiI6Mywic291cmNlcyI6WyIiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzZXJ2ZXInXG5cbmV4cG9ydCBjbGFzcyBOYW1lZENsYXNzIHt9XG5cbmV4cG9ydCBjb25zdCBDbGFzc0V4cHJlc3Npb24gPSBjbGFzcyBJbm5lckNsYXNzIHt9XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIERlZmF1bHRDbGFzcyB7fVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLENBQUMsR0FBRyxDQUFDLE1BQU07O0FBRUosS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDOztBQUVsQixLQUFLLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7O0FBRWxDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUpuQztBQUFBO0FBQUE7QUFFQTtBQUFBO0FBQUE7QUFFQTtBQUFBO0FBQUE7In0=)

```js
'use server'

class NamedClass {}

const ClassExpression = class InnerClass {}

class DefaultClass {}

registerServerReference(NamedClass, "NamedClass");
export { NamedClass };

registerServerReference(ClassExpression, "ClassExpression");
export { ClassExpression };

registerServerReference(DefaultClass, "default");
export default DefaultClass;
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
'use server'

export default class {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
## wrap-export

```txt
(0:0) "'use server'\n" --> (0:0) "'use server'\n"
(2:0) "export default " --> (2:0) "const $$default = "
(2:15) "class {}\n" --> (2:18) "class {}\n"
[unmapped] --> (3:0) ";\n"
[unmapped] --> (4:0) "const $$wrap_$$default = /* #__PURE__ */ registerServerReference($$default, \"default\");\n"
[unmapped] --> (5:0) "export { $$wrap_$$default as default };\n"
```

## module-export-effect

```txt
(0:0) "'use server'\n" --> (0:0) "'use server'\n"
(2:6) " default " --> (2:0) "const $$effect_default = "
(2:15) "class {}\n" --> (2:25) "class {}\n"
(2:0) "export default class {}\n" --> (3:0) "\n"
(2:0) "export default class {}\n" --> (4:0) "registerServerReference($$effect_default, \"default\");\n"
(2:0) "export default class {}\n" --> (5:0) "export default $$effect_default;\n"
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
## Input

```js
'use server'

export default class {}
```

## wrap-export

**Status:** transformed

**References:** default

[Source map visualization](https://evanw.github.io/source-map-visualization/#MTcxACd1c2Ugc2VydmVyJwoKY29uc3QgJCRkZWZhdWx0ID0gY2xhc3Mge30KOwpjb25zdCAkJHdyYXBfJCRkZWZhdWx0ID0gLyogI19fUFVSRV9fICovIHJlZ2lzdGVyU2VydmVyUmVmZXJlbmNlKCQkZGVmYXVsdCwgImRlZmF1bHQiKTsKZXhwb3J0IHsgJCR3cmFwXyQkZGVmYXVsdCBhcyBkZWZhdWx0IH07CjE3MQB7InZlcnNpb24iOjMsInNvdXJjZXMiOlsiIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc2VydmVyJ1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyB7fVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLENBQUMsR0FBRyxDQUFDLE1BQU07O0FBRVgsa0JBQWUsS0FBSyxDQUFDLENBQUM7Ozs7In0=)

```js
'use server'

const $$default = class {}
;
const $$wrap_$$default = /* #__PURE__ */ registerServerReference($$default, "default");
export { $$wrap_$$default as default };
```

## module-export-effect

**Status:** transformed

**References:** default

[Source map visualization](https://evanw.github.io/source-map-visualization/#MTM2ACd1c2Ugc2VydmVyJwoKY29uc3QgJCRlZmZlY3RfZGVmYXVsdCA9IGNsYXNzIHt9CgpyZWdpc3RlclNlcnZlclJlZmVyZW5jZSgkJGVmZmVjdF9kZWZhdWx0LCAiZGVmYXVsdCIpOwpleHBvcnQgZGVmYXVsdCAkJGVmZmVjdF9kZWZhdWx0OwoxODQAeyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHNlcnZlcidcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3Mge31cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxDQUFDLEdBQUcsQ0FBQyxNQUFNOztBQUVMLHlCQUFTLEtBQUssQ0FBQyxDQUFDO0FBQXRCO0FBQUE7QUFBQTsifQ==)

```js
'use server'

const $$effect_default = class {}

registerServerReference($$effect_default, "default");
export default $$effect_default;
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use server'

export /* before */ default /* after */ async function () {
return 'default comments called'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
## wrap-export

```txt
(0:0) "'use server'\n" --> (0:0) "'use server'\n"
(2:0) "export /* before */ default /* after */ " --> (2:0) "const $$default = "
(2:40) "async function () {\n" --> (2:18) "async function () {\n"
(3:0) " return 'default comments called'\n" --> (3:0) " return 'default comments called'\n"
(4:0) "}\n" --> (4:0) "}\n"
[unmapped] --> (5:0) ";\n"
[unmapped] --> (6:0) "const $$wrap_$$default = /* #__PURE__ */ registerServerReference($$default, \"default\");\n"
[unmapped] --> (7:0) "export { $$wrap_$$default as default };\n"
```

## module-export-effect

```txt
(0:0) "'use server'\n" --> (0:0) "'use server'\n"
(2:6) " /* before */ default /* after */ " --> (2:0) "const $$effect_default = "
(2:40) "async function () {\n" --> (2:25) "async function () {\n"
(3:0) " return 'default comments called'\n" --> (3:0) " return 'default comments called'\n"
(4:0) "}\n" --> (4:0) "}\n"
(2:0) "export /* before */ default /* after */ async function () {\n" --> (5:0) "\n"
(2:0) "export /* before */ default /* after */ async function () {\n" --> (6:0) "registerServerReference($$effect_default, \"default\");\n"
(2:0) "export /* before */ default /* after */ async function () {\n" --> (7:0) "export default $$effect_default;\n"
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
## Input

```js
'use server'

export /* before */ default /* after */ async function () {
return 'default comments called'
}
```

## wrap-export

**Status:** transformed

**References:** default

[Source map visualization](https://evanw.github.io/source-map-visualization/#MjE5ACd1c2Ugc2VydmVyJwoKY29uc3QgJCRkZWZhdWx0ID0gYXN5bmMgZnVuY3Rpb24gKCkgewogIHJldHVybiAnZGVmYXVsdCBjb21tZW50cyBjYWxsZWQnCn0KOwpjb25zdCAkJHdyYXBfJCRkZWZhdWx0ID0gLyogI19fUFVSRV9fICovIHJlZ2lzdGVyU2VydmVyUmVmZXJlbmNlKCQkZGVmYXVsdCwgImRlZmF1bHQiKTsKZXhwb3J0IHsgJCR3cmFwXyQkZGVmYXVsdCBhcyBkZWZhdWx0IH07CjMyOQB7InZlcnNpb24iOjMsInNvdXJjZXMiOlsiIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc2VydmVyJ1xuXG5leHBvcnQgLyogYmVmb3JlICovIGRlZmF1bHQgLyogYWZ0ZXIgKi8gYXN5bmMgZnVuY3Rpb24gKCkge1xuICByZXR1cm4gJ2RlZmF1bHQgY29tbWVudHMgY2FsbGVkJ1xufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLENBQUMsR0FBRyxDQUFDLE1BQU07O0FBRVgsa0JBQXdDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDMUQsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTTtBQUNqQzs7OzsifQ==)

```js
'use server'

const $$default = async function () {
return 'default comments called'
}
;
const $$wrap_$$default = /* #__PURE__ */ registerServerReference($$default, "default");
export { $$wrap_$$default as default };
```

## module-export-effect

**Status:** transformed

**References:** default

[Source map visualization](https://evanw.github.io/source-map-visualization/#MTg0ACd1c2Ugc2VydmVyJwoKY29uc3QgJCRlZmZlY3RfZGVmYXVsdCA9IGFzeW5jIGZ1bmN0aW9uICgpIHsKICByZXR1cm4gJ2RlZmF1bHQgY29tbWVudHMgY2FsbGVkJwp9CgpyZWdpc3RlclNlcnZlclJlZmVyZW5jZSgkJGVmZmVjdF9kZWZhdWx0LCAiZGVmYXVsdCIpOwpleHBvcnQgZGVmYXVsdCAkJGVmZmVjdF9kZWZhdWx0OwozNDEAeyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHNlcnZlcidcblxuZXhwb3J0IC8qIGJlZm9yZSAqLyBkZWZhdWx0IC8qIGFmdGVyICovIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuICdkZWZhdWx0IGNvbW1lbnRzIGNhbGxlZCdcbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxDQUFDLEdBQUcsQ0FBQyxNQUFNOztBQUVMLHlCQUFrQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzFELENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU07QUFDakM7QUFGQTtBQUFBO0FBQUE7In0=)

```js
'use server'

const $$effect_default = async function () {
return 'default comments called'
}

registerServerReference($$effect_default, "default");
export default $$effect_default;
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export async function direct() {}

const indirect = async () => {}
export { indirect }

consume(direct, indirect)
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
## wrap-export

```txt
(0:7) "async function direct() {}\n" --> (0:0) "async function direct() {}\n"
(2:0) "const indirect = async () => {}\n" --> (2:0) "const indirect = async () => {}\n"
(5:0) "consume(direct, indirect)\n" --> (5:0) "consume(direct, indirect)\n"
(0:0) "export async function direct() {}\n" --> (6:0) "direct = /* #__PURE__ */ registerServerReference(direct, \"direct\");\n"
(0:0) "export async function direct() {}\n" --> (7:0) "export { direct };\n"
[unmapped] --> (8:0) ";\n"
[unmapped] --> (9:0) "const $$wrap_indirect = /* #__PURE__ */ registerServerReference(indirect, \"indirect\");\n"
[unmapped] --> (10:0) "export { $$wrap_indirect as indirect };\n"
```

## module-export-effect

```txt
(0:7) "async function direct() {}\n" --> (0:0) "async function direct() {}\n"
(2:0) "const indirect = async () => {}\n" --> (2:0) "const indirect = async () => {}\n"
(3:0) "export { indirect }\n" --> (3:0) "export { indirect }\n"
(5:0) "consume(direct, indirect)\n" --> (5:0) "consume(direct, indirect)\n"
(0:0) "export async function direct() {}\n" --> (6:0) "\n"
(0:0) "export async function direct() {}\n" --> (7:0) "registerServerReference(direct, \"direct\");\n"
(0:0) "export async function direct() {}\n" --> (8:0) "export { direct };\n"
[unmapped] --> (10:0) "registerServerReference(indirect, \"indirect\");"
```
Loading
Loading