parent
22c76aacad
commit
59700aa9f1
|
@ -192,8 +192,7 @@ class ApiParser {
|
|||
method.argsArray.push(options);
|
||||
}
|
||||
p.required = false;
|
||||
// @ts-ignore
|
||||
options.type.properties.push(p);
|
||||
options.type?.properties?.push(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -363,11 +363,6 @@ class Member {
|
|||
this.alias = match[1];
|
||||
this.overloadIndex = (+match[2]) - 1;
|
||||
}
|
||||
/**
|
||||
* Param is true and option false
|
||||
* @type {Boolean | null}
|
||||
*/
|
||||
this.paramOrOption = null;
|
||||
}
|
||||
|
||||
index() {
|
||||
|
@ -384,10 +379,8 @@ class Member {
|
|||
for (const arg of this.argsArray) {
|
||||
this.args.set(arg.name, arg);
|
||||
arg.enclosingMethod = this;
|
||||
if (arg.name === 'options') {
|
||||
// @ts-ignore
|
||||
arg.type.properties.sort((p1, p2) => p1.name.localeCompare(p2.name));
|
||||
}
|
||||
if (arg.name === 'options')
|
||||
arg.type?.properties?.sort((p1, p2) => p1.name.localeCompare(p2.name));
|
||||
indexArg(arg);
|
||||
}
|
||||
}
|
||||
|
@ -410,11 +403,9 @@ class Member {
|
|||
continue;
|
||||
const overriddenArg = (arg.langs.overrides && arg.langs.overrides[lang]) || arg;
|
||||
overriddenArg.filterForLanguage(lang, options);
|
||||
// @ts-ignore
|
||||
if (overriddenArg.name === 'options' && !overriddenArg.type.properties.length)
|
||||
if (overriddenArg.name === 'options' && !overriddenArg.type?.properties?.length)
|
||||
continue;
|
||||
// @ts-ignore
|
||||
overriddenArg.type.filterForLanguage(lang, options);
|
||||
overriddenArg.type?.filterForLanguage(lang, options);
|
||||
argsArray.push(overriddenArg);
|
||||
}
|
||||
this.argsArray = argsArray;
|
||||
|
@ -433,7 +424,6 @@ class Member {
|
|||
const result = new Member(this.kind, { langs: this.langs, since: this.since, deprecated: this.deprecated, discouraged: this.discouraged }, this.name, this.type?.clone(), this.argsArray.map(arg => arg.clone()), this.spec, this.required);
|
||||
result.alias = this.alias;
|
||||
result.async = this.async;
|
||||
result.paramOrOption = this.paramOrOption;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -526,8 +516,7 @@ class Type {
|
|||
if (!inUnion && (parsedType.union || parsedType.unionName)) {
|
||||
const type = new Type(parsedType.unionName || '');
|
||||
type.union = [];
|
||||
// @ts-ignore
|
||||
for (let t = parsedType; t; t = t.union) {
|
||||
for (let /** @type {ParsedType | null} */ t = parsedType; t; t = t.union) {
|
||||
const nestedUnion = !!t.unionName && t !== parsedType;
|
||||
type.union.push(Type.fromParsedType(t, !nestedUnion));
|
||||
if (nestedUnion)
|
||||
|
@ -539,7 +528,6 @@ class Type {
|
|||
if (parsedType.args || parsedType.retType) {
|
||||
const type = new Type('function');
|
||||
type.args = [];
|
||||
// @ts-ignore
|
||||
for (let t = parsedType.args; t; t = t.next)
|
||||
type.args.push(Type.fromParsedType(t));
|
||||
type.returnType = parsedType.retType ? Type.fromParsedType(parsedType.retType) : undefined;
|
||||
|
@ -549,8 +537,7 @@ class Type {
|
|||
if (parsedType.template) {
|
||||
const type = new Type(parsedType.name);
|
||||
type.templates = [];
|
||||
// @ts-ignore
|
||||
for (let t = parsedType.template; t; t = t.next)
|
||||
for (let /** @type {ParsedType | null} */ t = parsedType.template; t; t = t.next)
|
||||
type.templates.push(Type.fromParsedType(t));
|
||||
return type;
|
||||
}
|
||||
|
@ -613,17 +600,6 @@ class Type {
|
|||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Member[] | undefined}
|
||||
*/
|
||||
sortedProperties() {
|
||||
if (!this.properties)
|
||||
return this.properties;
|
||||
const sortedProperties = [...this.properties];
|
||||
sortedProperties.sort((p1, p2) => p1.name.localeCompare(p2.name));
|
||||
return sortedProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} lang
|
||||
* @param {LanguageOptions=} options
|
||||
|
@ -768,11 +744,10 @@ function patchLinksInText(classOrMember, text, classesMap, membersMap, linkRende
|
|||
let alias = p2;
|
||||
if (classOrMember) {
|
||||
// param/option reference can only be in method or same method parameter comments.
|
||||
// @ts-ignore
|
||||
const method = classOrMember.enclosingMethod;
|
||||
const param = method.argsArray.find(a => a.name === p2);
|
||||
const method = /** @type {Member} */(classOrMember).enclosingMethod;
|
||||
const param = method?.argsArray.find(a => a.name === p2);
|
||||
if (!param)
|
||||
throw new Error(`Referenced parameter ${match} not found in the parent method ${method.name} `);
|
||||
throw new Error(`Referenced parameter ${match} not found in the parent method ${method?.name} `);
|
||||
alias = param.alias;
|
||||
}
|
||||
return linkRenderer({ param: alias, href }) || match;
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
// @ts-check
|
||||
|
||||
const path = require('path');
|
||||
const Documentation = require('./documentation');
|
||||
const { parseApi } = require('./api_parser');
|
||||
const PROJECT_DIR = path.join(__dirname, '..', '..');
|
||||
|
||||
|
@ -38,14 +37,14 @@ const PROJECT_DIR = path.join(__dirname, '..', '..');
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {Documentation} documentation
|
||||
* @param {import('./documentation').Documentation} documentation
|
||||
*/
|
||||
function serialize(documentation) {
|
||||
return documentation.classesArray.map(serializeClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Documentation.Class} clazz
|
||||
* @param {import('./documentation').Class} clazz
|
||||
*/
|
||||
function serializeClass(clazz) {
|
||||
const result = { name: clazz.name, spec: clazz.spec };
|
||||
|
@ -65,7 +64,7 @@ function serializeClass(clazz) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {Documentation.Member} member
|
||||
* @param {import('./documentation').Member} member
|
||||
*/
|
||||
function serializeMember(member) {
|
||||
const result = /** @type {any} */ ({ ...member });
|
||||
|
@ -76,14 +75,20 @@ function serializeMember(member) {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('./documentation').Member} arg
|
||||
*/
|
||||
function serializeProperty(arg) {
|
||||
const result = { ...arg, parent: undefined };
|
||||
sanitize(result);
|
||||
if (arg.type)
|
||||
result.type = serializeType(arg.type, arg.name === 'options');
|
||||
result.type = serializeType(arg.type);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} result
|
||||
*/
|
||||
function sanitize(result) {
|
||||
delete result.args;
|
||||
delete result.argsArray;
|
||||
|
@ -92,14 +97,13 @@ function sanitize(result) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {Documentation.Type} type
|
||||
* @param {boolean} sortProperties
|
||||
* @param {import('./documentation').Type} type
|
||||
*/
|
||||
function serializeType(type, sortProperties = false) {
|
||||
function serializeType(type) {
|
||||
/** @type {any} */
|
||||
const result = { ...type };
|
||||
if (type.properties)
|
||||
result.properties = (sortProperties ? type.sortedProperties() : type.properties).map(serializeProperty);
|
||||
result.properties = type.properties.map(serializeProperty);
|
||||
if (type.union)
|
||||
result.union = type.union.map(type => serializeType(type));
|
||||
if (type.templates)
|
||||
|
|
|
@ -91,7 +91,7 @@ class TypesGenerator {
|
|||
if (!docClass)
|
||||
return '';
|
||||
handledClasses.add(className);
|
||||
return this.writeComment(docClass.comment) + '\n';
|
||||
return this.writeComment(docClass.comment, '') + '\n';
|
||||
}, (className, methodName, overloadIndex) => {
|
||||
if (className === 'SuiteFunction' && methodName === '__call') {
|
||||
const cls = this.documentation.classes.get('Test');
|
||||
|
@ -218,7 +218,7 @@ class TypesGenerator {
|
|||
classToString(classDesc) {
|
||||
const parts = [];
|
||||
if (classDesc.comment) {
|
||||
parts.push(this.writeComment(classDesc.comment))
|
||||
parts.push(this.writeComment(classDesc.comment, ''))
|
||||
}
|
||||
const shouldExport = !this.doNotExportClassNames.has(classDesc.name);
|
||||
parts.push(`${shouldExport ? 'export ' : ''}interface ${classDesc.name} ${classDesc.extends ? `extends ${classDesc.extends} ` : ''}{`);
|
||||
|
@ -258,7 +258,7 @@ class TypesGenerator {
|
|||
const descriptions = [];
|
||||
for (let [eventName, value] of classDesc.events) {
|
||||
eventName = eventName.toLowerCase();
|
||||
const type = this.stringifyComplexType(value && value.type, 'out', ' ', classDesc.name, eventName, 'payload');
|
||||
const type = this.stringifyComplexType(value && value.type, 'out', ' ', [classDesc.name, eventName, 'payload']);
|
||||
const argName = this.argNameForType(type);
|
||||
const params = argName ? `${argName}: ${type}` : '';
|
||||
descriptions.push({
|
||||
|
@ -311,8 +311,8 @@ class TypesGenerator {
|
|||
return parts.join('\n');
|
||||
}
|
||||
const jsdoc = this.memberJSDOC(member, indent);
|
||||
const args = this.argsFromMember(member, indent, classDesc.name);
|
||||
let type = this.stringifyComplexType(member.type, 'out', indent, classDesc.name, member.alias);
|
||||
const args = this.argsFromMember(member, indent, [classDesc.name]);
|
||||
let type = this.stringifyComplexType(member.type, 'out', indent, [classDesc.name, member.alias]);
|
||||
if (member.async)
|
||||
type = `Promise<${type}>`;
|
||||
// do this late, because we still want object definitions for overridden types
|
||||
|
@ -351,7 +351,12 @@ class TypesGenerator {
|
|||
return this.documentation.classes.get(classDesc.extends);
|
||||
}
|
||||
|
||||
writeComment(comment, indent = '') {
|
||||
/**
|
||||
* @param {string} comment
|
||||
* @param {string} indent
|
||||
* @returns {string}
|
||||
*/
|
||||
writeComment(comment, indent) {
|
||||
const parts = [];
|
||||
const out = [];
|
||||
const pushLine = (line) => {
|
||||
|
@ -387,26 +392,30 @@ class TypesGenerator {
|
|||
|
||||
/**
|
||||
* @param {docs.Type|null} type
|
||||
* @param {'in' | 'out'} direction
|
||||
* @param {string} indent
|
||||
* @param {string[]} namespace
|
||||
* @returns {string}
|
||||
*/
|
||||
stringifyComplexType(type, direction, indent, ...namespace) {
|
||||
stringifyComplexType(type, direction, indent, namespace) {
|
||||
if (!type)
|
||||
return 'void';
|
||||
return this.stringifySimpleType(type, direction, indent, ...namespace);
|
||||
return this.stringifySimpleType(type, direction, indent, namespace);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {docs.Member[]} properties
|
||||
* @param {string} name
|
||||
* @param {string=} indent
|
||||
* @param {string} indent
|
||||
* @returns {string}
|
||||
*/
|
||||
stringifyObjectType(properties, name, indent = '') {
|
||||
stringifyObjectType(properties, name, indent) {
|
||||
const parts = [];
|
||||
parts.push(`{`);
|
||||
parts.push(properties.map(member => {
|
||||
const comment = this.memberJSDOC(member, indent + ' ');
|
||||
const args = this.argsFromMember(member, indent + ' ', name);
|
||||
const type = this.stringifyComplexType(member.type, 'out', indent + ' ', name, member.name);
|
||||
const args = this.argsFromMember(member, indent + ' ', [name]);
|
||||
const type = this.stringifyComplexType(member.type, 'out', indent + ' ', [name, member.name]);
|
||||
return `${comment}${this.nameForProperty(member)}${args}: ${type};`;
|
||||
}).join('\n\n'));
|
||||
parts.push(indent + '}');
|
||||
|
@ -416,14 +425,16 @@ class TypesGenerator {
|
|||
/**
|
||||
* @param {docs.Type | null | undefined} type
|
||||
* @param {'in' | 'out'} direction
|
||||
* @returns{string}
|
||||
* @param {string} indent
|
||||
* @param {string[]} namespace
|
||||
* @returns {string}
|
||||
*/
|
||||
stringifySimpleType(type, direction, indent = '', ...namespace) {
|
||||
stringifySimpleType(type, direction, indent, namespace) {
|
||||
if (!type)
|
||||
return 'void';
|
||||
if (type.name === 'Object' && type.templates) {
|
||||
const keyType = this.stringifySimpleType(type.templates[0], direction, indent, ...namespace);
|
||||
const valueType = this.stringifySimpleType(type.templates[1], direction, indent, ...namespace);
|
||||
const keyType = this.stringifySimpleType(type.templates[0], direction, indent, namespace);
|
||||
const valueType = this.stringifySimpleType(type.templates[1], direction, indent, namespace);
|
||||
return `{ [key: ${keyType}]: ${valueType}; }`;
|
||||
}
|
||||
let out = type.name;
|
||||
|
@ -434,7 +445,7 @@ class TypesGenerator {
|
|||
if (type.name === 'Object' && type.properties && type.properties.length) {
|
||||
const name = namespace.map(n => n[0].toUpperCase() + n.substring(1)).join('');
|
||||
const shouldExport = exported[name];
|
||||
const properties = namespace[namespace.length - 1] === 'options' ? type.sortedProperties() : type.properties;
|
||||
const properties = type.properties;
|
||||
if (!properties)
|
||||
throw new Error(`Object type must have properties`);
|
||||
if (!this.objectDefinitions.some(o => o.name === name))
|
||||
|
@ -448,10 +459,10 @@ class TypesGenerator {
|
|||
|
||||
if (type.args) {
|
||||
const stringArgs = type.args.map(a => ({
|
||||
type: this.stringifySimpleType(a, direction, indent, ...namespace),
|
||||
type: this.stringifySimpleType(a, direction, indent, namespace),
|
||||
name: a.name.toLowerCase()
|
||||
}));
|
||||
out = `((${stringArgs.map(({ name, type }) => `${name}: ${type}`).join(', ')}) => ${this.stringifySimpleType(type.returnType, 'out', indent, ...namespace)})`;
|
||||
out = `((${stringArgs.map(({ name, type }) => `${name}: ${type}`).join(', ')}) => ${this.stringifySimpleType(type.returnType, 'out', indent, namespace)})`;
|
||||
} else if (type.name === 'function') {
|
||||
out = 'Function';
|
||||
}
|
||||
|
@ -460,19 +471,22 @@ class TypesGenerator {
|
|||
if (out === 'Any')
|
||||
return 'any';
|
||||
if (type.templates)
|
||||
out += '<' + type.templates.map(t => this.stringifySimpleType(t, direction, indent, ...namespace)).join(', ') + '>';
|
||||
out += '<' + type.templates.map(t => this.stringifySimpleType(t, direction, indent, namespace)).join(', ') + '>';
|
||||
if (type.union)
|
||||
out = type.union.map(t => this.stringifySimpleType(t, direction, indent, ...namespace)).join('|');
|
||||
out = type.union.map(t => this.stringifySimpleType(t, direction, indent, namespace)).join('|');
|
||||
return out.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {docs.Member} member
|
||||
* @param {string} indent
|
||||
* @param {string[]} namespace
|
||||
* @returns {string}
|
||||
*/
|
||||
argsFromMember(member, indent, ...namespace) {
|
||||
argsFromMember(member, indent, namespace) {
|
||||
if (member.kind === 'property')
|
||||
return '';
|
||||
return '(' + member.argsArray.map(arg => `${this.nameForProperty(arg)}: ${this.stringifyComplexType(arg.type, 'in', indent, ...namespace, member.alias, arg.alias)}`).join(', ') + ')';
|
||||
return '(' + member.argsArray.map(arg => `${this.nameForProperty(arg)}: ${this.stringifyComplexType(arg.type, 'in', indent, [...namespace, member.alias, arg.alias])}`).join(', ') + ')';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue