Skip to content

Commit

Permalink
[INTERNAL] JSDoc: fix issue with function types and record types
Browse files Browse the repository at this point in the history
JSDoc reduces function types to the keyword "function", all other
details of the signature (parameters, return type, constructor type) are
lost. This has been reported as
jsdoc/jsdoc#1510 and a fix has been proposed
in jsdoc/jsdoc#1735 .

This change monkey patches JSDoc 3.6.x with the change from the
mentioned PR 1735.

At the same time, a similar problem regarding record types (structures)
is fixed.

Cherry picked from SAP/openui5@ff8dec90f
  • Loading branch information
codeworrior authored and RandomByte committed Jun 14, 2022
1 parent 0482bb0 commit 909af67
Showing 1 changed file with 106 additions and 2 deletions.
108 changes: 106 additions & 2 deletions lib/processors/jsdoc/lib/ui5/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -1812,7 +1812,7 @@ function createAutoDoc(oClassInfo, classComment, doclet, node, parser, filename,
"",
"@param {object}",
" [oData] An application-specific payload object that will be passed to the event handler along with the event object when firing the event",
"@param {function}",
"@param {function(sap.ui.base.Event):void}",
" fnFunction The function to be called when the event occurs",
"@param {object}",
" [oListener] Context object to call the event handler with. Defaults to this <code>" + oClassInfo.name + "</code> itself",
Expand All @@ -1830,7 +1830,7 @@ function createAutoDoc(oClassInfo, classComment, doclet, node, parser, filename,
"",
"The passed function and listener object must match the ones used for event registration.",
"",
"@param {function}",
"@param {function(sap.ui.base.Event):void}",
" fnFunction The function to be called, when the event occurs",
"@param {object}",
" [oListener] Context object on which the given function had to be called",
Expand Down Expand Up @@ -2677,3 +2677,107 @@ exports.astNodeVisitor = {
}

};

(function() {
const jsdocType = require("jsdoc/lib/jsdoc/tag/type");
const catharsis = require('catharsis');
const TYPES = catharsis.Types;

const toTypeString = (type) => getTypeStrings(type).join("|");

/*
* This function has been copied from jsdoc/lib/jsdoc/tag/type (version 3.6.7)
* The copy has been enhanced with the changes from https://github.com/jsdoc/jsdoc/pull/1735
* to retain the full function signature for function types.
*
* JSDoc is copyright (c) 2011-present Michael Mathews [email protected] and the contributors to JSDoc.
*/
function getTypeStrings(parsedType, isOutermostType) {
let applications;
let typeString;
let types = [];
switch (parsedType.type) {
case TYPES.AllLiteral:
types.push('*');
break;
case TYPES.FunctionType:
typeString = 'function';
// #### BEGIN: MODIFIED BY SAP
const paramTypes = [];
if (parsedType.new) {
paramTypes.push(toTypeString(parsedType.new));
}
if (Array.isArray(parsedType.params)) {
paramTypes.push(...parsedType.params.map(toTypeString));
}
if (paramTypes.length || parsedType.result) {
typeString += `(${paramTypes.join(", ")})`;
}
if (parsedType.result) {
typeString += `:${toTypeString(parsedType.result)}`;
}
types.push(typeString);
// #### END: MODIFIED BY SAP
break;
case TYPES.NameExpression:
types.push(parsedType.name);
break;
case TYPES.NullLiteral:
types.push('null');
break;
case TYPES.RecordType:
// #### BEGIN: MODIFIED BY SAP
// types.push('Object');
if (Array.isArray(parsedType.fields)) {
typeString = `{${parsedType.fields.map(
({key,value}) => `${catharsis.stringify(key)}: ${toTypeString(value)}`
).join(', ')}}`;
types.push(typeString);
} else {
types.push('Object');
}
// #### END: MODIFIED BY SAP
break;
case TYPES.TypeApplication:
// if this is the outermost type, we strip the modifiers; otherwise, we keep them
if (isOutermostType) {
applications = parsedType.applications.map(application =>
catharsis.stringify(application)).join(', ');
typeString = `${getTypeStrings(parsedType.expression)[0]}.<${applications}>`;
types.push(typeString);
}
else {
types.push( catharsis.stringify(parsedType) );
}
break;
case TYPES.TypeUnion:
parsedType.elements.forEach(element => {
types = types.concat( getTypeStrings(element) );
});
break;
case TYPES.UndefinedLiteral:
types.push('undefined');
break;
case TYPES.UnknownLiteral:
types.push('?');
break;
default:
// this shouldn't happen
throw new Error(`unrecognized type ${parsedType.type} in parsed type: ${parsedType}`);
}
return types;
}

const origParse = jsdocType.parse;
jsdocType.parse = function() {
const tagInfo = origParse.apply(this, arguments);
if ( tagInfo && /function/.test(tagInfo.typeExpression) && tagInfo.parsedType ) {
// console.info("old typeExpression", tagInfo.typeExpression);
// console.info("old parse tree", tagInfo.parsedType);
// console.info("old parse result", tagInfo.type);
tagInfo.type = getTypeStrings(tagInfo.parsedType);
// console.info("new parse result", tagInfo.type);
}
return tagInfo;
}
}());

0 comments on commit 909af67

Please sign in to comment.