Skip to content

Commit 8f9bf0f

Browse files
dgozmanaslushnikov
authored andcommitted
cherry-pick(#18818): chore: multiply overloaded options in csharp
This way we'll get the same treatment in docs generator as well as dotnet api generator. This also adds non-suffixed aliases for string options, e.g. `Name` in addition to `NameString` and `NameRegex`. Fixes #18407.
1 parent c3335e4 commit 8f9bf0f

File tree

4 files changed

+134
-80
lines changed

4 files changed

+134
-80
lines changed

docs/src/api/class-route.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,18 @@ If set changes the request method (e.g. GET or POST)
112112

113113
### option: Route.continue.postData
114114
* since: v1.8
115+
* langs: js, python, java
115116
- `postData` <[string]|[Buffer]>
116117

117118
If set changes the post data of request
118119

120+
### option: Route.continue.postData
121+
* since: v1.8
122+
* langs: csharp
123+
- `postData` <[Buffer]>
124+
125+
If set changes the post data of request
126+
119127
### option: Route.continue.headers
120128
* since: v1.8
121129
- `headers` <[Object]<[string], [string]>>
@@ -378,10 +386,18 @@ If set changes the request method (e.g. GET or POST)
378386

379387
### option: Route.fallback.postData
380388
* since: v1.23
389+
* langs: js, python, java
381390
- `postData` <[string]|[Buffer]>
382391

383392
If set changes the post data of request
384393

394+
### option: Route.fallback.postData
395+
* since: v1.23
396+
* langs: csharp
397+
- `postData` <[Buffer]>
398+
399+
If set changes the post data of request
400+
385401
### option: Route.fallback.headers
386402
* since: v1.23
387403
- `headers` <[Object]<[string], [string]>>

docs/src/chrome-extensions-js-python.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ First, add fixtures that will load the extension:
103103

104104
```ts
105105
// fixtures.ts
106-
import { test as base, expect, chromium, type BrowserContext } from "@playwright/test";
107-
import path from "path";
106+
import { test as base, expect, chromium, type BrowserContext } from '@playwright/test';
107+
import path from 'path';
108108

109109
export const test = base.extend<{
110110
context: BrowserContext;
@@ -185,16 +185,16 @@ def extension_id(context) -> Generator[str, None, None]:
185185
Then use these fixtures in a test:
186186

187187
```ts
188-
import { test, expect } from "./fixtures";
188+
import { test, expect } from './fixtures';
189189

190-
test("example test", async ({ page }) => {
191-
await page.goto("https://example.com");
192-
await expect(page.locator("body")).toHaveText("Changed by my-extension");
190+
test('example test', async ({ page }) => {
191+
await page.goto('https://example.com');
192+
await expect(page.locator('body')).toHaveText('Changed by my-extension');
193193
});
194194

195-
test("popup page", async ({ page, extensionId }) => {
195+
test('popup page', async ({ page, extensionId }) => {
196196
await page.goto(`chrome-extension://${extensionId}/popup.html`);
197-
await expect(page.locator("body")).toHaveText("my-extension popup");
197+
await expect(page.locator('body')).toHaveText('my-extension popup');
198198
});
199199
```
200200

utils/doclint/documentation.js

Lines changed: 99 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ const md = require('../markdown');
5959
* }} Metainfo
6060
*/
6161

62+
/**
63+
* @typedef {{
64+
* csharpOptionOverloadsShortNotation?: boolean,
65+
* }} LanguageOptions
66+
*/
67+
6268
class Documentation {
6369
/**
6470
* @param {!Array<!Documentation.Class>} classesArray
@@ -104,13 +110,14 @@ class Documentation {
104110

105111
/**
106112
* @param {string} lang
113+
* @param {LanguageOptions=} options
107114
*/
108-
filterForLanguage(lang) {
115+
filterForLanguage(lang, options = {}) {
109116
const classesArray = [];
110117
for (const clazz of this.classesArray) {
111118
if (clazz.langs.only && !clazz.langs.only.includes(lang))
112119
continue;
113-
clazz.filterForLanguage(lang);
120+
clazz.filterForLanguage(lang, options);
114121
classesArray.push(clazz);
115122
}
116123
this.classesArray = classesArray;
@@ -259,13 +266,14 @@ Documentation.Class = class {
259266

260267
/**
261268
* @param {string} lang
269+
* @param {LanguageOptions=} options
262270
*/
263-
filterForLanguage(lang) {
271+
filterForLanguage(lang, options = {}) {
264272
const membersArray = [];
265273
for (const member of this.membersArray) {
266274
if (member.langs.only && !member.langs.only.includes(lang))
267275
continue;
268-
member.filterForLanguage(lang);
276+
member.filterForLanguage(lang, options);
269277
membersArray.push(member);
270278
}
271279
this.membersArray = membersArray;
@@ -406,31 +414,41 @@ Documentation.Member = class {
406414
}
407415
}
408416

409-
/**
417+
/**
410418
* @param {string} lang
419+
* @param {LanguageOptions=} options
411420
*/
412-
filterForLanguage(lang) {
421+
filterForLanguage(lang, options = {}) {
413422
if (!this.type)
414423
return;
415424
if (this.langs.aliases && this.langs.aliases[lang])
416425
this.alias = this.langs.aliases[lang];
417426
if (this.langs.types && this.langs.types[lang])
418427
this.type = this.langs.types[lang];
419-
this.type.filterForLanguage(lang);
428+
this.type.filterForLanguage(lang, options);
420429
const argsArray = [];
421430
for (const arg of this.argsArray) {
422431
if (arg.langs.only && !arg.langs.only.includes(lang))
423432
continue;
424433
const overriddenArg = (arg.langs.overrides && arg.langs.overrides[lang]) || arg;
425-
overriddenArg.filterForLanguage(lang);
434+
overriddenArg.filterForLanguage(lang, options);
426435
// @ts-ignore
427436
if (overriddenArg.name === 'options' && !overriddenArg.type.properties.length)
428437
continue;
429438
// @ts-ignore
430-
overriddenArg.type.filterForLanguage(lang);
439+
overriddenArg.type.filterForLanguage(lang, options);
431440
argsArray.push(overriddenArg);
432441
}
433442
this.argsArray = argsArray;
443+
444+
const optionsArg = this.argsArray.find(arg => arg.name === 'options');
445+
if (lang === 'csharp' && optionsArg) {
446+
try {
447+
patchCSharpOptionOverloads(optionsArg, options);
448+
} catch (e) {
449+
throw new Error(`Error processing csharp options in ${this.clazz?.name}.${this.name}: ` + e.message);
450+
}
451+
}
434452
}
435453

436454
filterOutExperimental() {
@@ -642,15 +660,16 @@ Documentation.Type = class {
642660

643661
/**
644662
* @param {string} lang
663+
* @param {LanguageOptions=} options
645664
*/
646-
filterForLanguage(lang) {
665+
filterForLanguage(lang, options = {}) {
647666
if (!this.properties)
648667
return;
649668
const properties = [];
650669
for (const prop of this.properties) {
651670
if (prop.langs.only && !prop.langs.only.includes(lang))
652671
continue;
653-
prop.filterForLanguage(lang);
672+
prop.filterForLanguage(lang, options);
654673
properties.push(prop);
655674
}
656675
this.properties = properties;
@@ -839,4 +858,73 @@ function generateSourceCodeComment(spec) {
839858
return md.render(comments, 120);
840859
}
841860

861+
/**
862+
* @param {Documentation.Member} optionsArg
863+
* @param {LanguageOptions=} options
864+
*/
865+
function patchCSharpOptionOverloads(optionsArg, options = {}) {
866+
const props = optionsArg.type?.properties;
867+
if (!props)
868+
return;
869+
const propsToDelete = new Set();
870+
const propsToAdd = [];
871+
for (const prop of props) {
872+
const union = prop.type?.union;
873+
if (!union)
874+
continue;
875+
const isEnum = union[0].name.startsWith('"');
876+
const isNullable = union.length === 2 && union.some(type => type.name === 'null');
877+
if (isEnum || isNullable)
878+
continue;
879+
880+
const shortNotation = [];
881+
propsToDelete.add(prop);
882+
for (const type of union) {
883+
const suffix = csharpOptionOverloadSuffix(prop.name, type.name);
884+
if (options.csharpOptionOverloadsShortNotation) {
885+
if (type.name === 'string')
886+
shortNotation.push(prop.alias);
887+
else
888+
shortNotation.push(prop.alias + suffix);
889+
continue;
890+
}
891+
892+
const newProp = prop.clone();
893+
newProp.name = prop.name + suffix;
894+
newProp.alias = prop.alias + suffix;
895+
newProp.type = type;
896+
propsToAdd.push(newProp);
897+
898+
if (type.name === 'string') {
899+
const stringProp = prop.clone();
900+
stringProp.type = type;
901+
propsToAdd.push(stringProp);
902+
}
903+
}
904+
if (options.csharpOptionOverloadsShortNotation) {
905+
const newProp = prop.clone();
906+
newProp.alias = newProp.name = shortNotation.join('|');
907+
propsToAdd.push(newProp);
908+
}
909+
}
910+
for (const prop of propsToDelete)
911+
props.splice(props.indexOf(prop), 1);
912+
props.push(...propsToAdd);
913+
}
914+
915+
/**
916+
* @param {string} option
917+
* @param {string} type
918+
*/
919+
function csharpOptionOverloadSuffix(option, type) {
920+
switch (type) {
921+
case 'string': return 'String';
922+
case 'RegExp': return 'Regex';
923+
case 'function': return 'Func';
924+
case 'Buffer': return 'Byte';
925+
case 'Serializable': return 'Object';
926+
}
927+
throw new Error(`CSharp option "${option}" has unsupported type overload "${type}"`);
928+
}
929+
842930
module.exports = Documentation;

0 commit comments

Comments
 (0)