api(dotnet): specialize waitForEvent (#6761)

This commit is contained in:
Pavel Feldman 2021-05-26 15:11:31 -07:00 committed by GitHub
parent 3aa1471489
commit bb0e196b15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 128 additions and 64 deletions

View File

@ -132,7 +132,7 @@ print(page.evaluate("location.href"))
``` ```
```csharp ```csharp
var popup = await context.RunAndWaitForEventAsync(BrowserContextEvent.Page, async => var popup = await context.RunAndWaitForPageAsync(async =>
{ {
await page.ClickAsync("a"); await page.ClickAsync("a");
}); });
@ -1194,9 +1194,8 @@ Optional handler function used to register a routing with [`method: BrowserConte
Optional handler function used to register a routing with [`method: BrowserContext.route`]. Optional handler function used to register a routing with [`method: BrowserContext.route`].
## async method: BrowserContext.waitForEvent ## async method: BrowserContext.waitForEvent
* langs: csharp, js, python * langs: js, python
- alias-python: expect_event - alias-python: expect_event
- alias-csharp: RunAndWaitForEventAsync
- returns: <[any]> - returns: <[any]>
Waits for event to fire and passes its value into the predicate function. Returns when the predicate returns truthy Waits for event to fire and passes its value into the predicate function. Returns when the predicate returns truthy
@ -1226,7 +1225,7 @@ page = event_info.value
``` ```
```csharp ```csharp
var page = await context.RunAndWaitForEventAsync(ContextEvent.Page, async () => var page = await context.RunAndWaitForPageAsync(async () =>
{ {
await page.ClickAsync("button"); await page.ClickAsync("button");
}); });
@ -1247,8 +1246,9 @@ Event name, same one would pass into `browserContext.on(event)`.
Either a predicate that receives an event or an options object. Optional. Either a predicate that receives an event or an options object. Optional.
## async method: BrowserContext.waitForPage ## async method: BrowserContext.waitForPage
* langs: java, python * langs: java, python, csharp
- alias-python: expect_page - alias-python: expect_page
- alias-csharp: RunAndWaitForPage
- returns: <[Page]> - returns: <[Page]>
Performs action and waits for a new [Page] to be created in the context. If predicate is provided, it passes Performs action and waits for a new [Page] to be created in the context. If predicate is provided, it passes
@ -1264,9 +1264,8 @@ Receives the [Page] object and resolves to truthy value when the waiting should
### option: BrowserContext.waitForPage.timeout = %%-wait-for-event-timeout-%% ### option: BrowserContext.waitForPage.timeout = %%-wait-for-event-timeout-%%
## async method: BrowserContext.waitForEvent2 ## async method: BrowserContext.waitForEvent2
* langs: python, csharp * langs: python
- alias-python: wait_for_event - alias-python: wait_for_event
- alias-csharp: WaitForEventAsync
- returns: <[any]> - returns: <[any]>
:::note :::note

View File

@ -49,7 +49,7 @@ path = download.path()
``` ```
```csharp ```csharp
var download = await page.RunAndWaitForEventAsync(PageEvent.Download, async () => var download = await page.RunAndWaitForDownloadAsync(async () =>
{ {
await page.ClickAsync("#downloadButton"); await page.ClickAsync("#downloadButton");
}); });

View File

@ -30,7 +30,7 @@ file_chooser.set_files("myfile.pdf")
``` ```
```csharp ```csharp
var fileChooser = await page.RunAndWaitForEventAsync(Page.FileChooser, async () => var fileChooser = await page.RunAndWaitForFileChooserAsync(async () =>
{ {
await page.ClickAsync("upload"); await page.ClickAsync("upload");
}); });

View File

@ -1387,6 +1387,7 @@ await frame.WaitForLoadStateAsync(); // Defaults to LoadState.Load
## async method: Frame.waitForNavigation ## async method: Frame.waitForNavigation
* langs: * langs:
* alias-python: expect_navigation * alias-python: expect_navigation
* alias-csharp: RunAndWaitForNavigation
- returns: <[null]|[Response]> - returns: <[null]|[Response]>
Waits for the frame navigation and returns the main resource response. In case of multiple redirects, the navigation Waits for the frame navigation and returns the main resource response. In case of multiple redirects, the navigation

View File

@ -266,7 +266,7 @@ try {
// Crash might happen during a click. // Crash might happen during a click.
await page.ClickAsync("button"); await page.ClickAsync("button");
// Or while waiting for an event. // Or while waiting for an event.
await page.WaitForEventAsync(PageEvent.Popup); await page.WaitForPopup();
} catch (PlaywrightException e) { } catch (PlaywrightException e) {
// When the page crashes, exception message contains "crash". // When the page crashes, exception message contains "crash".
} }
@ -397,7 +397,7 @@ print(popup.evaluate("location.href"))
``` ```
```csharp ```csharp
var popup = await page.RunAndWaitForEventAsync(PageEvent.Popup, async () => var popup = await page.RunAndWaitForPopupAsync(async () =>
{ {
await page.EvaluateAsync("() => window.open('https://microsoft.com')"); await page.EvaluateAsync("() => window.open('https://microsoft.com')");
}); });
@ -2933,13 +2933,14 @@ Performs action and waits for the Page to close.
### option: Page.waitForClose.timeout = %%-wait-for-event-timeout-%% ### option: Page.waitForClose.timeout = %%-wait-for-event-timeout-%%
## async method: Page.waitForConsoleMessage ## async method: Page.waitForConsoleMessage
* langs: java, python * langs: java, python, csharp
- alias-python: expect_console_message - alias-python: expect_console_message
- alias-csharp: RunAndWaitForConsoleMessage
- returns: <[ConsoleMessage]> - returns: <[ConsoleMessage]>
Performs action and waits for a [ConsoleMessage] to be logged by in the page. If predicate is provided, it passes Performs action and waits for a [ConsoleMessage] to be logged by in the page. If predicate is provided, it passes
[ConsoleMessage] value into the `predicate` function and waits for `predicate(message)` to return a truthy value. [ConsoleMessage] value into the `predicate` function and waits for `predicate(message)` to return a truthy value.
Will throw an error if the page is closed before the console event is fired. Will throw an error if the page is closed before the [`event: Page.console`] event is fired.
### option: Page.waitForConsoleMessage.predicate = ### option: Page.waitForConsoleMessage.predicate =
- `predicate` <[function]\([ConsoleMessage]\):[boolean]> - `predicate` <[function]\([ConsoleMessage]\):[boolean]>
@ -2949,8 +2950,9 @@ Receives the [ConsoleMessage] object and resolves to truthy value when the waiti
### option: Page.waitForConsoleMessage.timeout = %%-wait-for-event-timeout-%% ### option: Page.waitForConsoleMessage.timeout = %%-wait-for-event-timeout-%%
## async method: Page.waitForDownload ## async method: Page.waitForDownload
* langs: java, python * langs: java, python, csharp
- alias-python: expect_download - alias-python: expect_download
- alias-csharp: RunAndWaitForDownload
- returns: <[Download]> - returns: <[Download]>
Performs action and waits for a new [Download]. If predicate is provided, it passes Performs action and waits for a new [Download]. If predicate is provided, it passes
@ -2965,9 +2967,8 @@ Receives the [Download] object and resolves to truthy value when the waiting sho
### option: Page.waitForDownload.timeout = %%-wait-for-event-timeout-%% ### option: Page.waitForDownload.timeout = %%-wait-for-event-timeout-%%
## async method: Page.waitForEvent ## async method: Page.waitForEvent
* langs: csharp, js, python * langs: js, python
- alias-python: expect_event - alias-python: expect_event
- alias-csharp: RunAndWaitForEventAsync
- returns: <[any]> - returns: <[any]>
Waits for event to fire and passes its value into the predicate function. Returns when the predicate returns truthy Waits for event to fire and passes its value into the predicate function. Returns when the predicate returns truthy
@ -2992,13 +2993,6 @@ with page.expect_event("framenavigated") as event_info:
frame = event_info.value frame = event_info.value
``` ```
```csharp
var frame = await page.RunAndWaitForEventAsync(PageEvent.FrameNavigated, async () =>
{
await page.ClickAsync("button");
}
```
### param: Page.waitForEvent.event = %%-wait-for-event-event-%% ### param: Page.waitForEvent.event = %%-wait-for-event-event-%%
### param: Page.waitForEvent.optionsOrPredicate ### param: Page.waitForEvent.optionsOrPredicate
@ -3011,8 +3005,9 @@ var frame = await page.RunAndWaitForEventAsync(PageEvent.FrameNavigated, async (
Either a predicate that receives an event or an options object. Optional. Either a predicate that receives an event or an options object. Optional.
## async method: Page.waitForFileChooser ## async method: Page.waitForFileChooser
* langs: java, python * langs: java, python, csharp
- alias-python: expect_file_chooser - alias-python: expect_file_chooser
- alias-csharp: RunAndWaitForFileChooser
- returns: <[FileChooser]> - returns: <[FileChooser]>
Performs action and waits for a new [FileChooser] to be created. If predicate is provided, it passes Performs action and waits for a new [FileChooser] to be created. If predicate is provided, it passes
@ -3223,7 +3218,7 @@ print(popup.title()) # popup is ready to use.
``` ```
```csharp ```csharp
var popup = await page.RunAndWaitForEventAsync(PageEvent.Popup, async () => var popup = await page.RunAndWaitForPopupAsync(async () =>
{ {
await page.ClickAsync("button"); // click triggers the popup/ await page.ClickAsync("button"); // click triggers the popup/
}); });
@ -3240,6 +3235,7 @@ Shortcut for main frame's [`method: Frame.waitForLoadState`].
## async method: Page.waitForNavigation ## async method: Page.waitForNavigation
* langs: * langs:
* alias-python: expect_navigation * alias-python: expect_navigation
* alias-csharp: RunAndWaitForNavigation
- returns: <[null]|[Response]> - returns: <[null]|[Response]>
Waits for the main frame navigation and returns the main resource response. In case of multiple redirects, the navigation Waits for the main frame navigation and returns the main resource response. In case of multiple redirects, the navigation
@ -3296,8 +3292,9 @@ Shortcut for main frame's [`method: Frame.waitForNavigation`].
### option: Page.waitForNavigation.timeout = %%-navigation-timeout-%% ### option: Page.waitForNavigation.timeout = %%-navigation-timeout-%%
## async method: Page.waitForPopup ## async method: Page.waitForPopup
* langs: java, python * langs: java, python, csharp
- alias-python: expect_popup - alias-python: expect_popup
- alias-csharp: RunAndWaitForPopup
- returns: <[Page]> - returns: <[Page]>
Performs action and waits for a popup [Page]. If predicate is provided, it passes Performs action and waits for a popup [Page]. If predicate is provided, it passes
@ -3314,6 +3311,7 @@ Receives the [Page] object and resolves to truthy value when the waiting should
## async method: Page.waitForRequest ## async method: Page.waitForRequest
* langs: * langs:
* alias-python: expect_request * alias-python: expect_request
* alias-csharp: RunAndWaitForRequest
- returns: <[Request]> - returns: <[Request]>
Waits for the matching request and returns it. See [waiting for event](./events.md#waiting-for-event) for more details about events. Waits for the matching request and returns it. See [waiting for event](./events.md#waiting-for-event) for more details about events.
@ -3387,6 +3385,8 @@ await Task.WhenAll(page.WaitForRequestAsync(r => "https://example.com".Equals(r.
await page.waitForRequest(request => request.url().searchParams.get('foo') === 'bar' && request.url().searchParams.get('foo2') === 'bar2'); await page.waitForRequest(request => request.url().searchParams.get('foo') === 'bar' && request.url().searchParams.get('foo2') === 'bar2');
``` ```
### param: Page.waitForRequest.action = %%-csharp-wait-for-event-action-%%
### param: Page.waitForRequest.urlOrPredicate ### param: Page.waitForRequest.urlOrPredicate
- `urlOrPredicate` <[string]|[RegExp]|[function]\([Request]\):[boolean]> - `urlOrPredicate` <[string]|[RegExp]|[function]\([Request]\):[boolean]>
@ -3404,9 +3404,29 @@ Request URL string, regex or predicate receiving [Request] object.
Maximum wait time in milliseconds, defaults to 30 seconds, pass `0` to disable the timeout. The default value can be Maximum wait time in milliseconds, defaults to 30 seconds, pass `0` to disable the timeout. The default value can be
changed by using the [`method: Page.setDefaultTimeout`] method. changed by using the [`method: Page.setDefaultTimeout`] method.
## async method: Page.waitForRequestFinished
* langs: java, python, csharp
- alias-python: expect_request_finished
- alias-csharp: RunAndWaitForRequestFinished
- returns: <[Request]>
Performs action and waits for a [Request] to finish loading. If predicate is provided, it passes
[Request] value into the `predicate` function and waits for `predicate(request)` to return a truthy value.
Will throw an error if the page is closed before the [`event: Page.requestFinished`] event is fired.
### option: Page.waitForRequestFinished.predicate =
- `predicate` <[function]\([Request]\):[boolean]>
Receives the [ConsoleMessage] object and resolves to truthy value when the waiting should resolve.
### option: Page.waitForRequestFinished.timeout = %%-wait-for-event-timeout-%%
## async method: Page.waitForResponse ## async method: Page.waitForResponse
* langs: * langs:
* alias-python: expect_response * alias-python: expect_response
* alias-csharp: RunAndWaitForResponse
- returns: <[Response]> - returns: <[Response]>
Returns the matched response. See [waiting for event](./events.md#waiting-for-event) for more details about events. Returns the matched response. See [waiting for event](./events.md#waiting-for-event) for more details about events.
@ -3480,6 +3500,8 @@ await Task.WhenAll(page.WaitForResponseAsync(r => "https://example.com".Equals(r
page.ClickAsync("button.triggers-response")); page.ClickAsync("button.triggers-response"));
``` ```
### param: Page.waitForResponse.action = %%-csharp-wait-for-event-action-%%
### param: Page.waitForResponse.urlOrPredicate ### param: Page.waitForResponse.urlOrPredicate
- `urlOrPredicate` <[string]|[RegExp]|[function]\([Response]\):[boolean]> - `urlOrPredicate` <[string]|[RegExp]|[function]\([Response]\):[boolean]>
@ -3688,7 +3710,9 @@ Shortcut for main frame's [`method: Frame.waitForURL`].
### option: Page.waitForURL.waitUntil = %%-navigation-wait-until-%% ### option: Page.waitForURL.waitUntil = %%-navigation-wait-until-%%
## async method: Page.waitForWebSocket ## async method: Page.waitForWebSocket
* langs: java * langs: java, python, csharp
- alias-python: expect_websocket
- alias-csharp: RunAndWaitForWebSocket
- returns: <[WebSocket]> - returns: <[WebSocket]>
Performs action and waits for a new [WebSocket]. If predicate is provided, it passes Performs action and waits for a new [WebSocket]. If predicate is provided, it passes
@ -3703,8 +3727,9 @@ Receives the [WebSocket] object and resolves to truthy value when the waiting sh
### option: Page.waitForWebSocket.timeout = %%-wait-for-event-timeout-%% ### option: Page.waitForWebSocket.timeout = %%-wait-for-event-timeout-%%
## async method: Page.waitForWorker ## async method: Page.waitForWorker
* langs: java, python * langs: java, python, csharp
- alias-python: expect_worker - alias-python: expect_worker
- alias-csharp: RunAndWaitForWorker
- returns: <[Worker]> - returns: <[Worker]>
Performs action and waits for a new [Worker]. If predicate is provided, it passes Performs action and waits for a new [Worker]. If predicate is provided, it passes
@ -3729,9 +3754,8 @@ This does not contain ServiceWorkers
::: :::
## async method: Page.waitForEvent2 ## async method: Page.waitForEvent2
* langs: python, csharp * langs: python
- alias-python: wait_for_event - alias-python: wait_for_event
- alias-csharp: WaitForEventAsync
- returns: <[any]> - returns: <[any]>
:::note :::note

View File

@ -239,7 +239,7 @@ print(request.timing)
``` ```
```csharp ```csharp
var request = await page.RunAndWaitForEventAsync(PageEvent.RequestFinished, async () => var request = await page.RunAndWaitForRequestFinishedAsync(async () =>
{ {
await page.GotoAsync("https://www.microsoft.com"); await page.GotoAsync("https://www.microsoft.com");
}); });

View File

@ -6,3 +6,14 @@ Returns parsed request's body for `form-urlencoded` and JSON as a fallback if an
When the response is `application/x-www-form-urlencoded` then a key/value object of the values will be returned. When the response is `application/x-www-form-urlencoded` then a key/value object of the values will be returned.
Otherwise it will be parsed as JSON. Otherwise it will be parsed as JSON.
### param: BrowserContext.waitForPage.action = %%-csharp-wait-for-event-action-%%
### param: Frame.waitForNavigation.action = %%-csharp-wait-for-event-action-%%
### param: Page.waitForConsoleMessage.action = %%-csharp-wait-for-event-action-%%
### param: Page.waitForDownload.action = %%-csharp-wait-for-event-action-%%
### param: Page.waitForFileChooser.action = %%-csharp-wait-for-event-action-%%
### param: Page.waitForPopup.action = %%-csharp-wait-for-event-action-%%
### param: Page.waitForRequestFinished.action = %%-csharp-wait-for-event-action-%%
### param: Page.waitForNavigation.action = %%-csharp-wait-for-event-action-%%
### param: Page.waitForWebSocket.action = %%-csharp-wait-for-event-action-%%
### param: Page.waitForWorker.action = %%-csharp-wait-for-event-action-%%

View File

@ -518,6 +518,12 @@ Specify screenshot type, defaults to `png`.
Callback that performs the action triggering the event. Callback that performs the action triggering the event.
## csharp-wait-for-event-action
* langs: csharp
- `action` <[Func<Task>]>
Action that triggers the event.
## python-select-options-element ## python-select-options-element
* langs: python * langs: python
- `element` <[ElementHandle]|[Array]<[ElementHandle]>> - `element` <[ElementHandle]|[Array]<[ElementHandle]>>

View File

@ -92,7 +92,7 @@ popup.value.goto("https://wikipedia.org")
``` ```
```csharp ```csharp
var popup = await page.RunAndWaitForEventAsync(PageEvent.Popup, async => var popup = await page.RunAndWaitForPopupAsync(async =>
{ {
await page.EvaluateAsync("window.open()"); await page.EvaluateAsync("window.open()");
}); });

View File

@ -750,7 +750,7 @@ file_chooser.set_files("myfile.pdf")
``` ```
```csharp ```csharp
var fileChooser = page.RunAndWaitForAsync(PageEvent.FileChooser, async () => var fileChooser = page.RunAndWaitForFileChooserAsync(async () =>
{ {
await page.ClickAsync("upload"); await page.ClickAsync("upload");
}); });

View File

@ -209,7 +209,7 @@ print(new_page.title())
```csharp ```csharp
// Get page after a specific action (e.g. clicking a link) // Get page after a specific action (e.g. clicking a link)
var newPage = await context.RunAndWaitForEventAsync(BrowserContextEvent.Page, async () => var newPage = await context.RunAndWaitForPageAsync(async () =>
{ {
await page.ClickAsync("a[target='_blank']"); await page.ClickAsync("a[target='_blank']");
}); });
@ -311,7 +311,7 @@ print(popup.title())
```csharp ```csharp
// Get popup after a specific action (e.g., click) // Get popup after a specific action (e.g., click)
var newPage = await page.RunAndWaitForEventAsync(PageEvent.Popup, async () => var newPage = await page.RunAndWaitForPopupAsync(async () =>
{ {
await page.ClickAsync("#open"); await page.ClickAsync("#open");
}); });

View File

@ -434,7 +434,7 @@ popup.wait_for_load_state("load")
``` ```
```csharp ```csharp
var popup = await page.RunAndWaitForEventAsync(PageEvent.Popup, async () => var popup = await page.RunAndWaitForPopupAsync(async () =>
{ {
await page.ClickAsync("a[target='_blank']"); // Opens popup await page.ClickAsync("a[target='_blank']"); // Opens popup
}); });

View File

@ -244,7 +244,7 @@ popup = popup_info.value
``` ```
```csharp ```csharp
var popup = await page.RunAndWaitForEventAsync(PageEvent.Popup, async () => var popup = await page.RunAndWaitForPopupAsync(async () =>
{ {
await page.ClickAsync("#open"); await page.ClickAsync("#open");
}); });

View File

@ -58,10 +58,11 @@ const documentation = parseApi(path.join(PROJECT_DIR, 'docs', 'src', 'api'));
documentation.filterForLanguage('csharp'); documentation.filterForLanguage('csharp');
documentation.setLinkRenderer(item => { documentation.setLinkRenderer(item => {
const asyncSuffix = item.member && item.member.async ? 'Async' : '';
if (item.clazz) if (item.clazz)
return `<see cref="I${toTitleCase(item.clazz.name)}"/>`; return `<see cref="I${toTitleCase(item.clazz.name)}"/>`;
else if (item.member) else if (item.member)
return `<see cref="I${toTitleCase(item.member.clazz.name)}.${toMemberName(item.member)}"/>`; return `<see cref="I${toTitleCase(item.member.clazz.name)}.${toMemberName(item.member)}${asyncSuffix}"/>`;
else if (item.option) else if (item.option)
return `<paramref name="${item.option}"/>`; return `<paramref name="${item.option}"/>`;
else if (item.param) else if (item.param)
@ -137,8 +138,11 @@ function renderClass(clazz) {
return; return;
const body = []; const body = [];
for (const member of clazz.membersArray) for (const member of clazz.membersArray) {
if (member.alias.startsWith('RunAnd'))
renderMember(member, clazz, { trimRunAndPrefix: true }, body);
renderMember(member, clazz, {}, body); renderMember(member, clazz, {}, body);
}
writeFile( writeFile(
'public partial interface', 'public partial interface',
@ -169,8 +173,11 @@ function renderBaseClass(clazz) {
return; return;
const body = []; const body = [];
for (const member of methodsWithOptions) for (const member of methodsWithOptions) {
if (member.alias.startsWith('RunAnd'))
renderMethod(member, clazz, toMemberName(member), { mode: 'base', nodocs: true, public: true, trimRunAndPrefix: true }, body);
renderMethod(member, clazz, toMemberName(member), { mode: 'base', nodocs: true, public: true }, body); renderMethod(member, clazz, toMemberName(member), { mode: 'base', nodocs: true, public: true }, body);
}
writeFile( writeFile(
'internal partial class', 'internal partial class',
@ -269,16 +276,14 @@ function toArgumentName(name) {
/** /**
* @param {Documentation.Member} member * @param {Documentation.Member} member
* @param {{ omitAsync?: boolean; }=} options
*/ */
function toMemberName(member, options) { function toMemberName(member, makeAsync = false) {
const assumedName = toTitleCase(member.alias || member.name); const assumedName = toTitleCase(member.alias || member.name);
if (member.kind === 'interface') if (member.kind === 'interface')
return `I${assumedName}`; return `I${assumedName}`;
const omitAsync = options && options.omitAsync; if (makeAsync && member.async)
if (!omitAsync && member.kind === 'method' && member.async && !assumedName.endsWith('Async')) return assumedName + 'Async';
return `${assumedName}Async`; if (!makeAsync && assumedName.endsWith('Async'))
if (omitAsync && assumedName.endsWith('Async'))
return assumedName.substring(0, assumedName.length - 'Async'.length); return assumedName.substring(0, assumedName.length - 'Async'.length);
return assumedName; return assumedName;
} }
@ -317,13 +322,13 @@ function renderConstructors(name, type, out) {
* *
* @param {Documentation.Member} member * @param {Documentation.Member} member
* @param {Documentation.Class|Documentation.Type} parent * @param {Documentation.Class|Documentation.Type} parent
* @param {{nojson?: boolean}} options * @param {{nojson?: boolean, trimRunAndPrefix?: boolean}} options
* @param {string[]} out * @param {string[]} out
*/ */
function renderMember(member, parent, options, out) { function renderMember(member, parent, options, out) {
let name = toMemberName(member); let name = toMemberName(member);
if (member.kind === 'method') { if (member.kind === 'method') {
renderMethod(member, parent, name, { mode: 'options' }, out); renderMethod(member, parent, name, { mode: 'options', trimRunAndPrefix: options.trimRunAndPrefix }, out);
return; return;
} }
@ -477,23 +482,24 @@ function generateEnumNameIfApplicable(type) {
* nodocs?: boolean, * nodocs?: boolean,
* abstract?: boolean, * abstract?: boolean,
* public?: boolean, * public?: boolean,
* trimRunAndPrefix?: boolean,
* }} options * }} options
* @param {string[]} out * @param {string[]} out
*/ */
function renderMethod(member, parent, name, options, out) { function renderMethod(member, parent, name, options, out) {
// These are hard-coded in C#.
if (name.includes('WaitForEventAsync'))
return;
out.push(''); out.push('');
if (options.trimRunAndPrefix)
name = name.substring('RunAnd'.length);
/** /**
* @param {Documentation.Type} type * @param {Documentation.Type} type
* @returns * @returns
*/ */
function resolveType(type) { function resolveType(type) {
return translateType(type, parent, (t) => { return translateType(type, parent, (t) => {
let newName = `${parent.name}${toMemberName(member, { omitAsync: true })}Result`; let newName = `${parent.name}${toMemberName(member)}Result`;
documentedResults.set(newName, `Result of calling <see cref="I${toTitleCase(parent.name)}.${toMemberName(member)}"/>.`); documentedResults.set(newName, `Result of calling <see cref="I${toTitleCase(parent.name)}.${toMemberName(member, true)}"/>.`);
return newName; return newName;
}); });
} }
@ -595,9 +601,12 @@ function renderMethod(member, parent, name, options, out) {
* @param {Documentation.Member} arg * @param {Documentation.Member} arg
*/ */
function processArg(arg) { function processArg(arg) {
if (options.trimRunAndPrefix && arg.name === 'action')
return;
if (arg.name === 'options') { if (arg.name === 'options') {
if (options.mode === 'options' || options.mode === 'base') { if (options.mode === 'options' || options.mode === 'base') {
const optionsType = member.clazz.name + toMemberName(member, { omitAsync: true }) + 'Options'; const optionsType = member.clazz.name + name + 'Options';
optionTypes.set(optionsType, arg.type); optionTypes.set(optionsType, arg.type);
args.push(`${optionsType} options = default`); args.push(`${optionsType} options = default`);
argTypeMap.set(`${optionsType} options = default`, 'options'); argTypeMap.set(`${optionsType} options = default`, 'options');
@ -661,6 +670,12 @@ function renderMethod(member, parent, name, options, out) {
pushArg(argType, argName, arg); pushArg(argType, argName, arg);
} }
let modifiers = '';
if (options.abstract)
modifiers = 'protected abstract ';
if (options.public)
modifiers = 'public ';
member.argsArray member.argsArray
.sort((a, b) => b.alias === 'options' ? -1 : 0) //move options to the back to the arguments list .sort((a, b) => b.alias === 'options' ? -1 : 0) //move options to the back to the arguments list
.forEach(processArg); .forEach(processArg);
@ -670,6 +685,8 @@ function renderMethod(member, parent, name, options, out) {
// Generate options -> named transition. // Generate options -> named transition.
const tokens = []; const tokens = [];
for (const arg of member.argsArray) { for (const arg of member.argsArray) {
if (arg.name === 'action' && options.trimRunAndPrefix)
continue;
if (arg.name !== 'options') { if (arg.name !== 'options') {
tokens.push(toArgumentName(arg.name)); tokens.push(toArgumentName(arg.name));
continue; continue;
@ -689,23 +706,17 @@ function renderMethod(member, parent, name, options, out) {
} }
body = ` body = `
{ {
options ??= new ${member.clazz.name}${toMemberName(member, { omitAsync: true })}Options(); options ??= new ${member.clazz.name}${name}Options();
return ${name}(${tokens.join(', ')}); return ${toAsync(name, member.async)}(${tokens.join(', ')});
}`; }`;
} }
let modifiers = '';
if (options.abstract)
modifiers = 'protected abstract ';
if (options.public)
modifiers = 'public ';
if (!explodedArgs.length) { if (!explodedArgs.length) {
if (!options.nodocs) { if (!options.nodocs) {
out.push(...XmlDoc.renderXmlDoc(member.spec, maxDocumentationColumnWidth)); out.push(...XmlDoc.renderXmlDoc(member.spec, maxDocumentationColumnWidth));
paramDocs.forEach((value, i) => printArgDoc(i, value, out)); paramDocs.forEach((value, i) => printArgDoc(i, value, out));
} }
out.push(`${modifiers}${type} ${name}(${args.join(', ')})${body}`); out.push(`${modifiers}${type} ${toAsync(name, member.async)}(${args.join(', ')})${body}`);
} else { } else {
let containsOptionalExplodedArgs = false; let containsOptionalExplodedArgs = false;
explodedArgs.forEach((explodedArg, argIndex) => { explodedArgs.forEach((explodedArg, argIndex) => {
@ -727,7 +738,7 @@ function renderMethod(member, parent, name, options, out) {
overloadedArgs.push(arg); overloadedArgs.push(arg);
} }
} }
out.push(`${modifiers}${type} ${name}(${overloadedArgs.join(', ')})${body}`); out.push(`${modifiers}${type} ${toAsync(name, member.async)}(${overloadedArgs.join(', ')})${body}`);
if (argIndex < explodedArgs.length - 1) if (argIndex < explodedArgs.length - 1)
out.push(''); // output a special blank line out.push(''); // output a special blank line
}); });
@ -914,3 +925,15 @@ function printArgDoc(name, value, out) {
function toOverloadSuffix(typeName) { function toOverloadSuffix(typeName) {
return toTitleCase(typeName.replace(/[<].*[>]/, '').replace(/[^a-zA-Z]/g, '')); return toTitleCase(typeName.replace(/[<].*[>]/, '').replace(/[^a-zA-Z]/g, ''));
} }
/**
* @param {string} name
* @param {boolean} convert
*/
function toAsync(name, convert) {
if (!convert)
return name;
if (name.includes('<'))
return name.replace('<', 'Async<');
return name + 'Async';
}