Wrap comments in generated SDK (#1281)

* Wrap comments in generated SDK

* Fixed an issue related to reserved key words
This commit is contained in:
Xiaogang 2023-11-22 10:33:40 +08:00 коммит произвёл GitHub
Родитель 389b47f96d
Коммит 6f3ee99485
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
13 изменённых файлов: 83 добавлений и 78 удалений

Просмотреть файл

@ -15,7 +15,7 @@ import { VirtualProperty, getAllProperties, getAllPublicVirtualProperties, getMu
import { resolveParameterNames } from '../utils/resolve-conflicts';
import { OperationType } from '../utils/command-operation';
import { Header, HeaderPropertyType } from '@azure-tools/codemodel-v3';
import { getEscapedReservedName } from '../utils/code-namer';
import { getEscapedReservedName, isReserved } from '../utils/code-namer';
import { Helper } from '../sdk/utility';
function getPluralizationService(): EnglishPluralizationService {
@ -163,6 +163,9 @@ function createVirtualProperties(schema: ObjectSchema, stack: Array<string>, con
// run thru the properties in this class.
// dolauli handle properties in this class
for (const property of objectProperties) {
if (isReserved(property.language.default.name)) {
property.language.default.name = camelCase(getEscapedReservedName(property.language.default.name, 'Property'));
}
const mutability = getMutability(property);
const propertyName = property.language.default.name;
@ -292,6 +295,9 @@ function createVirtualProperties(schema: ObjectSchema, stack: Array<string>, con
}
for (const property of nonObjectProperties) {
if (isReserved(property.language.default.name)) {
property.language.default.name = camelCase(getEscapedReservedName(property.language.default.name, 'Property'));
}
const name = getEscapedReservedName(getPascalIdentifier(<string>property.language.default.name), 'Property');
// this is not something that has properties,
// so we don't need to do any inlining

Просмотреть файл

@ -11,7 +11,6 @@ import { ModelState } from '../utils/model-state';
import { Project } from '../sdk/project';
import { OperationGroup } from '@autorest/codemodel';
import { getAllPublicVirtualProperties } from '@azure-tools/codemodel-v3';
import { wrapComments } from '../utils/WrapComments';
const ejs = require('ejs');
@ -24,7 +23,7 @@ async function generateModels(project: Project) {
// skip flattened model and pageble model
continue;
}
const content = await ejs.renderFile(path, { model: model, project: project, wrapComments: wrapComments });
const content = await ejs.renderFile(path, { model: model, project: project });
project.state.writeFile(`${project.baseFolder}\\Models\\${model.language.default.name}.cs`, content, undefined, 'source-file-csharp');
}
}

Просмотреть файл

@ -10,7 +10,7 @@ namespace <%- project.namespace %>
<% if (project.model.info.description) { -%>
/// <summary>
/// <%- project.model.info.description %>
/// <%=project.helper.wrapComments(' ', '/// ', project.model.info.description)%>
/// </summary>
<% } -%>
<% var client = project.model.info.title -%>

Просмотреть файл

@ -17,7 +17,7 @@ namespace <%- project.namespace %>.Models
if (item.language.default.description) {
-%>
/// <summary>
/// <%-item.language.default.description%>
/// <%=project.helper.wrapComments(' ', '/// ', item.language.default.description)%>
/// </summary>
<% } -%>
[System.Runtime.Serialization.EnumMember(Value = "<%-item.value%>")]
@ -63,7 +63,7 @@ if (item.language.default.description) {
<%model.choices.forEach(function(choice){-%>
<%if(choice.language.default.description){-%>
/// <summary>
/// <%-choice.language.default.description%>
/// <%=project.helper.wrapComments(' ', '/// ', choice.language.default.description)%>
/// </summary>
<%}-%>
public const string <%-project.helper.GetValidCsharpName(choice.language.default.name)%> = "<%-choice.value%>";

Просмотреть файл

@ -2,7 +2,7 @@
<% var OperationsName = clientName != '' ? clientName : project.helper.PascalCase(key) + 'Operations'-%>
<%# ToDo: currently assume the SyncMethodsGenerationMode is Essential type, and need to add support for other types -%>
/// <summary>
/// <%=method.language.default.description%>
/// <%=project.helper.wrapComments(' ', '/// ', method.language.default.description)%>
<%# ToDo: add support for externaldocsurl -%>
/// </summary>
<%# ToDo: add <remarks> if there are both description and summary -%>
@ -11,7 +11,7 @@
/// </param>
<% if(method.parameters && !method.language.default.pageable?.nextPageOperation) { method.parameters.filter(p => p.implementation != 'Client' && !project.helper.IsConstantParameter(p) && p.protocol.http?.in != 'complexHeader' && !(p.extensions && p.extensions['x-ms-parameter-grouping'])).forEach(function (parameter) {-%>
/// <param name='<%-parameter.language.default.name%>'>
/// <%=parameter.language.default.description%>
/// <%=project.helper.wrapComments(' ', '/// ', parameter.language.default.description)%>
/// </param>
<% });}-%>
<% if(method.language.default.pageable?.nextPageOperation) {-%>
@ -32,7 +32,7 @@
}
/// <summary>
/// <%=method.language.default.description%>
/// <%=project.helper.wrapComments(' ', '/// ', method.language.default.description)%>
<%# ToDo: add support for externaldocsurl -%>
/// </summary>
<%# ToDo: add <remarks> if there are both description and summary -%>
@ -41,7 +41,7 @@
/// </param>
<% if(method.parameters && !method.language.default.pageable?.nextPageOperation) { method.parameters.filter(p => p.implementation != 'Client' && !project.helper.IsConstantParameter(p) && p.protocol.http?.in != 'complexHeader' && !p.readOnly && !(p.extensions && p.extensions['x-ms-parameter-grouping'])).forEach(function (parameter) {-%>
/// <param name='<%-parameter.language.default.name%>'>
/// <%=parameter.language.default.description%>
/// <%=project.helper.wrapComments(' ', '/// ', parameter.language.default.description)%>
/// </param>
<% });}-%>
<% if(method.language.default.pageable?.nextPageOperation) {-%>

Просмотреть файл

@ -8,7 +8,7 @@
<% if(method.parameters&&!method.language.default.pageable?.nextPageOperation) { method.parameters.filter(p => p.implementation != 'Client' && !project.helper.IsConstantParameter(p) && !(p.extensions && p.extensions['x-ms-parameter-grouping'])).forEach(function (parameter) {-%>
<%# ToDo: should use camel name instead of pascal name here -%>
/// <param name='<%-parameter.language.default.name%>'>
/// <%=parameter.language.default.description%>
/// <%=project.helper.wrapComments(' ', '/// ', parameter.language.default.description)%>
/// </param>
<% });}-%>
<% if(!method.language.default.pageable?.nextPageOperation) {-%>
@ -16,12 +16,12 @@
<%if(parameter.extensions && parameter.extensions['x-ms-client-flatten'] ) {-%>
<%project.helper.GetAllPublicVirtualProperties(parameter.schema.language.default.virtualProperties).filter(p => !project.helper.IsConstantEnumProperty(p) && !p.readOnly).forEach(function(vp) {-%>
/// <param name='<%-vp.property.language.default.name%>'>
/// <%= vp.property.language.default.description%>
/// <%=project.helper.wrapComments(' ', '/// ', vp.property.language.default.description)%>
/// </param>
<%});-%>
<%} else {-%>
/// <param name='<%-parameter.language.default.name%>'>
/// <%= parameter.language.default.description%>
/// <%=project.helper.wrapComments(' ', '/// ', parameter.language.default.description)%>
/// </param>
<%}-%>
<% });-%>

Просмотреть файл

@ -1,6 +1,6 @@
<% if (method.language.default.description) {-%>
/// <summary>
/// <%= method.language.default.description%>
/// <%=project.helper.wrapComments(' ', '/// ', method.language.default.description)%>
<%# ToDo: add externaldocsurl -%>
/// </summary>
<% };-%>
@ -8,7 +8,7 @@
<% if(method.parameters&&!method.language.default.pageable?.nextPageOperation) { method.parameters.filter(p => p.implementation != 'Client' && !project.helper.IsConstantParameter(p) && p.protocol.http?.in != 'complexHeader' && !(p.extensions && p.extensions['x-ms-parameter-grouping'])).forEach(function (parameter) {-%>
<%# ToDo: should use camel name instead of pascal name here -%>
/// <param name='<%-parameter.language.default.name%>'>
/// <%=parameter.language.default.description%>
/// <%=project.helper.wrapComments(' ', '/// ', parameter.language.default.description)%>
/// </param>
<% });}-%>
<% if(!method.language.default.pageable?.nextPageOperation) {-%>
@ -16,12 +16,12 @@
<%if(parameter.extensions && parameter.extensions['x-ms-client-flatten'] ) {-%>
<%project.helper.GetAllPublicVirtualProperties(parameter.schema.language.default.virtualProperties).filter(p => !project.helper.IsConstantEnumProperty(p) && !p.readOnly).forEach(function(vp) {-%>
/// <param name='<%-vp.property.language.default.name%>'>
/// <%= vp.property.language.default.description%>
/// <%=project.helper.wrapComments(' ', '/// ', vp.property.language.default.description)%>
/// </param>
<%});-%>
<%} else {-%>
/// <param name='<%-parameter.language.default.name%>'>
/// <%= parameter.language.default.description%>
/// <%=project.helper.wrapComments(' ', '/// ', parameter.language.default.description)%>
/// </param>
<%}-%>
<% });-%>

Просмотреть файл

@ -2,29 +2,29 @@
<%# ToDo: support for ExcludeFromInterface -%>
<% if(method.language.default.description) {-%>
/// <summary>
/// <%= method.language.default.description%>
/// <%=project.helper.wrapComments(' ', '/// ', method.language.default.description)%>
<%# ToDo: support for ExternalDocsUrl -%>
/// </summary>
/// <remarks>
/// <%= method.language.default.description%>
/// <%=project.helper.wrapComments(' ', '/// ', method.language.default.description)%>
/// </remarks>
<% };-%>
<% if(!method.language.default.pageable?.nextPageOperation) {-%>
<% method.parameters.filter(p=>p.implementation != 'Client' && !project.helper.IsConstantParameter(p) && p.protocol.http?.in != 'complexHeader' && !(p.extensions && p.extensions['x-ms-parameter-grouping'])).forEach(function(parameter){-%>
/// <param name='<%-parameter.language.default.name%>'>
/// <%= parameter.language.default.description%>
/// <%=project.helper.wrapComments(' ', '/// ', parameter.language.default.description)%>
/// </param>
<% }); -%>
<% (method.requests[0].parameters || []).filter(p=>p.protocol.http.in == 'body' && !project.helper.IsConstantEnumParameter(p)).forEach(function(parameter){-%>
<%if(parameter.extensions && parameter.extensions['x-ms-client-flatten'] ) {-%>
<%project.helper.GetAllPublicVirtualProperties(parameter.schema.language.default.virtualProperties).filter(p => !project.helper.IsConstantEnumProperty(p) && !p.readOnly).forEach(function(vp) {-%>
/// <param name='<%-vp.property.language.default.name%>'>
/// <%= vp.property.language.default.description%>
/// <%=project.helper.wrapComments(' ', '/// ', vp.property.language.default.description)%>
/// </param>
<%});-%>
<%} else {-%>
/// <param name='<%-parameter.language.default.name%>'>
/// <%= parameter.language.default.description%>
/// <%=project.helper.wrapComments(' ', '/// ', parameter.language.default.description)%>
/// </param>
<%}-%>
<% });-%>

Просмотреть файл

@ -7,12 +7,12 @@ namespace <%- project.namespace %>.Models
<%# ToDo: need to populate effectiveDocumentation in the model-%>
<% if (model.language.default.description) {-%>
/// <summary>
/// <%=wrapComments(' ', '/// ', model.language.default.description)%>
/// <%=project.helper.wrapComments(' ', '/// ', model.language.default.description)%>
/// </summary>
<% }-%>
<% if (model.summary && model.language.default.description) { -%>
/// <remarks>
/// <%=wrapComments(' ', '/// ', model.language.default.description)%>
/// <%=project.helper.wrapComments(' ', '/// ', model.language.default.description)%>
/// </remarks>
<% } -%>
<%# ToDo: support NeedsPolymorphicConverter-%>
@ -54,8 +54,8 @@ if (p.property.schema.type == 'sealed-choice' || p.property.schema.type == 'choi
additionInfo = additionInfo + choices.join(', ');
}
%>
/// <param name="<%-project.helper.CamelCase(p.name)%>"><%=wrapComments(' ', '/// ', p.property.language.default.description)%>
/// <%-wrapComments(' ', '/// ', additionInfo)%></param>
/// <param name="<%-project.helper.CamelCase(p.name)%>"><%=project.helper.wrapComments(' ', '/// ', p.property.language.default.description)%>
/// <%=project.helper.wrapComments(' ', '/// ', additionInfo)%></param>
<%});-%>
public <%- model.language.default.name%>(<%-model.language.default.constructorParametersDeclaration%>)
<%# If there is only one direct parent, will implement it as parent%>
@ -105,7 +105,7 @@ const quote = p.property.schema.choiceType.type !== 'string' ? '' : '"';
}
%>
/// <summary>
/// <%=wrapComments(' ', '/// ', p.property.language.csharp.formattedPropertySummary)%><%=additionInfo%>
/// <%=project.helper.wrapComments(' ', '/// ', p.property.language.csharp.formattedPropertySummary)%><%=additionInfo%>
/// </summary>
<% (p.property.schema.language.csharp.jsonConverters || []).forEach(function(ct) {-%>
[Newtonsoft.Json.JsonConverter(typeof(<%-ct%>))]

Просмотреть файл

@ -13,7 +13,7 @@
public Newtonsoft.Json.JsonSerializerSettings DeserializationSettings { get; private set; }
<% (project.model.globalParameters || []).filter(p=>p.language.default.name != '$host').forEach(function(parameter) {-%>
/// <summary>
/// <%=parameter.language.default.description%>
/// <%=project.helper.wrapComments(' ', '/// ', parameter.language.default.description)%>
/// </summary>
<% var type = parameter.schema.type == 'constant' ? parameter.schema.valueType.language.csharp.fullname : parameter.schema.language.csharp.fullname-%>
<%type = type.includes('.') || type == 'string' ? type : type + '?'-%>
@ -120,7 +120,7 @@ if (parameters.length > 0) {-%>
/// </summary>
<%parameters.filter(p => !project.helper.IsConstantParameter(p)).forEach(function(parameter){-%>
/// <param name='<%-project.helper.CamelCase(parameter.language.default.name)%>'>
/// Required. <%-parameter.language.default.description%>
/// Required. <%=project.helper.wrapComments(' ', '/// ', parameter.language.default.description)%>
/// </param>
<%});-%>
/// <param name='handlers'>
@ -153,7 +153,7 @@ if (parameters.length > 0) {-%>
/// </summary>
<%parameters.filter(p => !project.helper.IsConstantParameter(p)).forEach(function(parameter) {-%>
/// <param name="<%-project.helper.CamelCase(parameter.language.default.name)%>">
/// Required. <%-parameter.language.default.description%>
/// Required. <%=project.helper.wrapComments(' ', '/// ', parameter.language.default.description)%>
/// </param>
<%});-%>
/// <param name='httpClient'>
@ -187,7 +187,7 @@ if (parameters.length > 0) {-%>
/// </summary>
<%parameters.filter(p => !project.helper.IsConstantParameter(p)).forEach(function(parameter) {-%>
/// <param name="<%-project.helper.CamelCase(parameter.language.default.name)%>">
/// Required. <%-parameter.language.default.description%>
/// Required. <%=project.helper.wrapComments(' ', '/// ', parameter.language.default.description)%>
/// </param>
<%});-%>
/// <param name='rootHandler'>
@ -227,7 +227,7 @@ if (parameters.length > 0) {-%>
/// </param>
<%parameters.filter(p => !project.helper.IsConstantParameter(p)).forEach(function(parameter) {-%>
/// <param name="<%-project.helper.CamelCase(parameter.language.default.name)%>">
/// Required. <%-parameter.language.default.description%>
/// Required. <%=project.helper.wrapComments(' ', '/// ', parameter.language.default.description)%>
/// </param>
<%});-%>
/// <param name='handlers'>
@ -267,7 +267,7 @@ if (parameters.length > 0) {-%>
/// </param>
<%parameters.filter(p => !project.helper.IsConstantParameter(p)).forEach(function(parameter) {-%>
/// <param name="<%-project.helper.CamelCase(parameter.language.default.name)%>">
/// Required. <%-parameter.language.default.description%>
/// Required. <%=project.helper.wrapComments(' ', '/// ', parameter.language.default.description)%>
/// </param>
<%});-%>
/// <param name='rootHandler'>

Просмотреть файл

@ -8,7 +8,7 @@ namespace <%- project.namespace %>
<% }); -%>
/// <summary>
/// <%- project.model.info.description %>
/// <%=project.helper.wrapComments(' ', '/// ', project.model.info.description)%>
/// </summary>
<% var client = project.model.info.title -%>
public partial interface I<%- client %> : System.IDisposable
@ -30,7 +30,7 @@ namespace <%- project.namespace %>
<% (project.model.globalParameters || []).filter(p => p.language.default.name != '$host').forEach(function(parameter){ -%>
/// <summary>
/// <%- parameter.language.default.description %>
/// <%=project.helper.wrapComments(' ', '/// ', parameter.language.default.description)%>
/// </summary>
<%# ToDo: need to use fullname instead of namespace + name -%>
<% var type = parameter.schema.type == 'constant' ? parameter.schema.valueType.language.csharp.fullname : parameter.schema.language.csharp.fullname-%>

Просмотреть файл

@ -456,4 +456,47 @@ export class Helper {
}
return '';
}
public wrapComments(indentation: string, prefix: string, comments: string): string {
const defaultMaximumCommentColumns = 80;
if (comments === null || comments === undefined || comments.length === 0) {
return '';
}
//cannot predict indentation because we cannot get last line generated
const length = defaultMaximumCommentColumns - prefix.length - 1;
const result = this.lineBreak(comments, length);
for (let i = 0; i < result.length; i++) {
if (i != 0) {
result[i] = prefix + result[i];
}
}
return result.join('\n' + indentation);
}
private lineBreak(comments: string, length: number): Array<string> {
const splitter = /\r\n|\r|\n/i;
const lines = new Array<string>();
for (const line of comments.split(splitter)) {
let processedLine = line;
while (processedLine.length > 0) {
processedLine = processedLine.trim();
const whiteSpacePositions = [...new Array(processedLine.length).keys()].filter(i => /\s/.test(processedLine[i])).concat([processedLine.length]);
let preWidthWrapAt = 0;
let postWidthWrapAt = 0;
for (const index of whiteSpacePositions) {
if (index <= length) {
preWidthWrapAt = index;
} else if (postWidthWrapAt === 0) {
postWidthWrapAt = index;
}
}
const wrapAt = preWidthWrapAt != 0 ? preWidthWrapAt : (postWidthWrapAt != 0 ? postWidthWrapAt : processedLine.length);
lines.push(processedLine.substring(0, wrapAt));
processedLine = processedLine.substring(wrapAt);
}
}
return lines;
}
}

Просмотреть файл

@ -1,43 +0,0 @@
const defaultMaximumCommentColumns = 80;
const defaultGeneratedIndentation = ' ';
const splitter = /\r\n|\r|\n/i;
export function wrapComments(indentation: string, prefix: string, comments: string): string {
if (comments === null || comments.length === 0) {
return '';
}
//cannot predict indentation because we cannot get last line generated
const length = defaultMaximumCommentColumns - prefix.length - 1;
const result = lineBreak(comments, length);
for (let i = 0; i < result.length; i++) {
if (i != 0) {
result[i] = prefix + result[i];
}
}
return result.join('\n' + indentation);
}
function lineBreak(comments: string, length: number): Array<string> {
const lines = new Array<string>();
for (const line of comments.split(splitter)) {
let processedLine = line;
while (processedLine.length > 0) {
processedLine = processedLine.trim();
const whiteSpacePositions = [...new Array(processedLine.length).keys()].filter(i => /\s/.test(processedLine[i])).concat([processedLine.length]);
let preWidthWrapAt = 0;
let postWidthWrapAt = 0;
for (const index of whiteSpacePositions) {
if (index <= length) {
preWidthWrapAt = index;
} else if (postWidthWrapAt === 0) {
postWidthWrapAt = index;
}
}
const wrapAt = preWidthWrapAt != 0 ? preWidthWrapAt : (postWidthWrapAt != 0 ? postWidthWrapAt : processedLine.length);
lines.push(processedLine.substring(0, wrapAt));
processedLine = processedLine.substring(wrapAt);
}
}
return lines;
}