Skip to content

Commit 2ad63e3

Browse files
committed
[INTERNAL] lib/processors/jsdoc: no duplicate interfaces when JSDoc/Runtime names differ
When the JSDoc name of an interface differs from the UI5 runtime metadata name, the interface must not be added twice to the api.json. Cherry-picked from UI5/openui5@934eef745
1 parent 0740f60 commit 2ad63e3

File tree

1 file changed

+28
-6
lines changed

1 file changed

+28
-6
lines changed

lib/processors/jsdoc/lib/ui5/plugin.js

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2432,6 +2432,21 @@ function location(doclet) {
24322432
return " #" + ui5data(doclet).id + "@" + filename + (doclet.meta.lineno != null ? ":" + doclet.meta.lineno : "") + (doclet.synthetic ? "(synthetic)" : "");
24332433
}
24342434

2435+
/**
2436+
* Converts a JSDoc name to a UI5 runtime metadata name.
2437+
*
2438+
* Basically, global names in dot notation don't require a conversion. Only when the JSDoc name
2439+
* is a `module:*` name, the prefix is removed and slashes are converted to dots.
2440+
*
2441+
* Note: the conversion in the opposite direction is not well-defined as not every dot has to be
2442+
* converted to a slash (e.g. not for named exports or subtypes in another module). This
2443+
* also implies that two different JSDoc names might map to the same UI5 runtime metadata
2444+
* name. API design should avoid such ambiguities.
2445+
*/
2446+
function toRuntimeMetadataName(longname) {
2447+
return longname?.startsWith("module:") ? longname.slice("module:".length).replace(/\//g, ".") : longname;
2448+
}
2449+
24352450
// ---- Comment handling ---------------------------------------------------------------------------
24362451

24372452
// --- comment related functions that depend on the JSdoc version (e.g. on the used parser)
@@ -2966,7 +2981,7 @@ exports.handlers = {
29662981
// add metadata to class symbols
29672982
let classInfo = classInfos[doclet.longname];
29682983
if (classInfo == null && doclet.longname?.startsWith("module:")) {
2969-
classInfo = classInfos[doclet.longname.slice("module:".length).replace(/\//g, ".")];
2984+
classInfo = classInfos[toRuntimeMetadataName(doclet.longname)];
29702985
}
29712986
if ( classInfo ) {
29722987
// debug("class data", doclet.longname, "'" + classInfos[doclet.longname].export + "'");
@@ -3000,11 +3015,18 @@ exports.handlers = {
30003015
// derive interface implementations from UI5 metadata
30013016
if ( doclet.__ui5.metadata.interfaces && doclet.__ui5.metadata.interfaces.length ) {
30023017
/* eslint-disable no-loop-func */
3003-
doclet.__ui5.metadata.interfaces.forEach((intf) => {
3018+
doclet.__ui5.metadata.interfaces.forEach((rtmIntf) => {
30043019
doclet.implements = doclet.implements || [];
3005-
if ( doclet.implements.indexOf(intf) < 0 ) {
3006-
info(` @implements ${intf} derived from UI5 metadata (${doclet.longname})`);
3007-
doclet.implements.push(intf);
3020+
// add an interface only if no "matching" JSDoc interface is present already
3021+
3022+
// TODO if the JSDoc name and runtime metadata name of an interface differ,
3023+
// this today requires redundant documentation. Ideally, the JSDoc plugin
3024+
// should handle this and convert the runtime metadata name to the JSDoc name.
3025+
// Unfortunately, at this processing step here, the necessary information is
3026+
// not yet available (external APIs are loaded only later).
3027+
if ( doclet.implements.every((jsdocIntf) => toRuntimeMetadataName(jsdocIntf) !== rtmIntf)) {
3028+
info(` @implements ${rtmIntf} derived from UI5 metadata (${doclet.longname})`);
3029+
doclet.implements.push(rtmIntf);
30083030
}
30093031
});
30103032
/* eslint-enable no-loop-func */
@@ -3014,7 +3036,7 @@ exports.handlers = {
30143036
// add DataType info to typedef symbols
30153037
let typeInfo = typeInfos[doclet.longname];
30163038
if (typeInfo == null && doclet.longname?.startsWith("module:")) {
3017-
typeInfo = typeInfos[doclet.longname.slice("module:".length).replace(/\//g, ".")];
3039+
typeInfo = typeInfos[toRuntimeMetadataName(doclet.longname)];
30183040
}
30193041
if ( typeInfo ) {
30203042
doclet.__ui5.stereotype = 'datatype';

0 commit comments

Comments
 (0)