chore(dotnet): split unions into multiple overloads (#6400)
This commit is contained in:
parent
9433cae4fe
commit
67f98d00eb
|
|
@ -200,7 +200,7 @@ const customTypeNames = new Map([
|
|||
out.push(`\t${escapedName},`);
|
||||
});
|
||||
}, enumsDir));
|
||||
|
||||
|
||||
if (process.argv[3] !== "--skip-format") {
|
||||
// run the formatting tool for .net, to ensure the files are prepped
|
||||
execSync(`dotnet format -f "${typesDir}" --include-generated --fix-whitespace`);
|
||||
|
|
@ -294,16 +294,16 @@ function renderMember(member, parent, out) {
|
|||
let propertyOrigin = member.name;
|
||||
if (member.type.expression === '[string]|[float]')
|
||||
propertyOrigin = `${member.name}String`;
|
||||
if(!member.clazz)
|
||||
if (!member.clazz)
|
||||
output(`[JsonPropertyName("${propertyOrigin}")]`)
|
||||
if (parent && member && member.name === 'children') { // this is a special hack for Accessibility
|
||||
console.warn(`children property found in ${parent.name}, assuming array.`);
|
||||
type = `IEnumerable<${parent.name}>`;
|
||||
}
|
||||
|
||||
if(!type.endsWith('?') && !member.required && nullableTypes.includes(type))
|
||||
if (!type.endsWith('?') && !member.required && nullableTypes.includes(type))
|
||||
type = `${type}?`;
|
||||
if(member.clazz)
|
||||
if (member.clazz)
|
||||
output(`public ${type} ${name} { get; }`);
|
||||
else
|
||||
output(`public ${type} ${name} { get; set; }`);
|
||||
|
|
@ -484,19 +484,28 @@ function renderMethod(member, parent, output, name) {
|
|||
|
||||
// render args
|
||||
let args = [];
|
||||
let explodedArgs = [];
|
||||
let argTypeMap = new Map([]);
|
||||
/**
|
||||
*
|
||||
* @param {string} innerArgType
|
||||
* @param {string} innerArgName
|
||||
* @param {Documentation.Member} argument
|
||||
* @param {boolean} isExploded
|
||||
*/
|
||||
const pushArg = (innerArgType, innerArgName, argument) => {
|
||||
const pushArg = (innerArgType, innerArgName, argument, isExploded = false) => {
|
||||
let isNullable = nullableTypes.includes(innerArgType);
|
||||
const requiredPrefix = argument.required ? "" : isNullable ? "?" : "";
|
||||
const requiredSuffix = argument.required ? "" : " = default";
|
||||
args.push(`${innerArgType}${requiredPrefix} ${innerArgName}${requiredSuffix}`);
|
||||
const requiredPrefix = (argument.required || isExploded) ? "" : isNullable ? "?" : "";
|
||||
const requiredSuffix = (argument.required || isExploded) ? "" : " = default";
|
||||
var push = `${innerArgType}${requiredPrefix} ${innerArgName}${requiredSuffix}`;
|
||||
if (isExploded)
|
||||
explodedArgs.push(push)
|
||||
else
|
||||
args.push(push);
|
||||
argTypeMap.set(push, innerArgName);
|
||||
};
|
||||
|
||||
|
||||
let parseArg = (/** @type {Documentation.Member} */ arg) => {
|
||||
if (arg.name === "options") {
|
||||
arg.type.properties.forEach(parseArg);
|
||||
|
|
@ -539,11 +548,13 @@ function renderMethod(member, parent, output, name) {
|
|||
|
||||
let argDocumentation = XmlDoc.renderTextOnly(arg.spec, maxDocumentationColumnWidth);
|
||||
for (const newArg of translatedArguments) {
|
||||
const sanitizedArgName = newArg.match(/(?<=^[\s"']*)(\w+)/g, '')[0] || newArg;
|
||||
let nonGenericType = newArg.replace(/\IEnumerable<(.*)\>/g, (m, v) => 'Enumerable' + v[0].toUpperCase() + v.substring(1))
|
||||
const sanitizedArgName = nonGenericType.match(/(?<=^[\s"']*)(\w+)/g, '')[0] || nonGenericType;
|
||||
const newArgName = `${argName}${sanitizedArgName[0].toUpperCase() + sanitizedArgName.substring(1)}`;
|
||||
pushArg(newArg, newArgName, arg);
|
||||
pushArg(newArg, newArgName, arg, true); // push the exploded arg
|
||||
addParamsDoc(newArgName, argDocumentation);
|
||||
}
|
||||
args.push(arg.required ? 'EXPLODED_ARG' : 'OPTIONAL_EXPLODED_ARG');
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -561,8 +572,7 @@ function renderMethod(member, parent, output, name) {
|
|||
.sort((a, b) => b.alias === 'options' ? -1 : 0) //move options to the back to the arguments list
|
||||
.forEach(parseArg);
|
||||
|
||||
output(XmlDoc.renderXmlDoc(member.spec, maxDocumentationColumnWidth));
|
||||
paramDocs.forEach((val, ind) => {
|
||||
let printArgDoc = function (val, ind) {
|
||||
if (val && val.length === 1)
|
||||
output(`/// <param name="${ind}">${val}</param>`);
|
||||
else {
|
||||
|
|
@ -570,8 +580,56 @@ function renderMethod(member, parent, output, name) {
|
|||
output(val.map(l => `/// ${l}`));
|
||||
output(`/// </param>`);
|
||||
}
|
||||
});
|
||||
output(`${type} ${name}(${args.join(', ')});`);
|
||||
}
|
||||
|
||||
let getArgType = function (argType) {
|
||||
var type = argTypeMap.get(argType);
|
||||
return type;
|
||||
}
|
||||
|
||||
if (!explodedArgs.length) {
|
||||
output(XmlDoc.renderXmlDoc(member.spec, maxDocumentationColumnWidth));
|
||||
paramDocs.forEach((val, ind) => printArgDoc(val, ind));
|
||||
output(`${type} ${name}(${args.join(', ')});`);
|
||||
} else {
|
||||
let containsOptionalExplodedArgs = false;
|
||||
explodedArgs.forEach((explodedArg, argIndex) => {
|
||||
output(XmlDoc.renderXmlDoc(member.spec, maxDocumentationColumnWidth));
|
||||
let overloadedArgs = [];
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
let arg = args[i];
|
||||
if (arg === 'EXPLODED_ARG' || arg === 'OPTIONAL_EXPLODED_ARG') {
|
||||
containsOptionalExplodedArgs = arg === 'OPTIONAL_EXPLODED_ARG';
|
||||
let argType = getArgType(explodedArg);
|
||||
printArgDoc(paramDocs.get(argType), argType);
|
||||
overloadedArgs.push(explodedArg);
|
||||
} else {
|
||||
let argType = getArgType(arg);
|
||||
printArgDoc(paramDocs.get(argType), argType);
|
||||
overloadedArgs.push(arg);
|
||||
}
|
||||
}
|
||||
output(`${type} ${name}(${overloadedArgs.join(', ')});`);
|
||||
if (argIndex < explodedArgs.length - 1)
|
||||
output(``); // output a special blank line
|
||||
});
|
||||
|
||||
// If the exploded union arguments are optional, we also output a special
|
||||
// signature, to help prevent compilation errors with ambigious overloads.
|
||||
// That particular overload only contains the required arguments, or rather
|
||||
// contains all the arguments *except* the exploded ones.
|
||||
if (containsOptionalExplodedArgs) {
|
||||
var filteredArgs = args.filter(x => x !== 'OPTIONAL_EXPLODED_ARG');
|
||||
output(XmlDoc.renderXmlDoc(member.spec, maxDocumentationColumnWidth));
|
||||
filteredArgs.forEach((arg) => {
|
||||
if (arg === 'EXPLODED_ARG')
|
||||
throw new Error(`Unsupported required union arg combined an optional union inside ${member.name}`);
|
||||
let argType = getArgType(arg);
|
||||
printArgDoc(paramDocs.get(argType), argType);
|
||||
});
|
||||
output(`${type} ${name}(${filteredArgs.join(', ')});`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -652,9 +710,7 @@ function translateType(type, parent, generateNameCallback = t => t.name) {
|
|||
} else if (type.union.length == 2 && type.union[1].name === 'Array' && type.union[1].templates[0].name === type.union[0].name)
|
||||
return `IEnumerable<${type.union[0].name}>`; // an example of this is [string]|[Array]<[string]>
|
||||
else if (type.union[0].name === 'path')
|
||||
// we don't support path, but we know it's usually an object on the other end, and we expect
|
||||
// the dotnet folks to use [NameOfTheObject].LoadFromPath(); method which we can provide separately
|
||||
return translateType(type.union[1], parent, generateNameCallback);
|
||||
return null;
|
||||
else if (type.expression === '[float]|"raf"')
|
||||
return `Polling`; // hardcoded because there's no other way to denote this
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue