Skip to content

Commit fed99fb

Browse files
committed
[INTERNAL] lib/processors/jsdoc: Entity type visualization improved
Problem: In the API Reference section, the complex types of entities [declared in the jsdoc] are not properly displayed and linked to their composing types. Solution: -- Utilize the existing TypeParser in order to parse the individual simple-types composing a complex type. -- Render as links only the simple-types that correspond to UI5 symbols. Cherry-picked from SAP/openui5@03bb1394d.
1 parent de047d7 commit fed99fb

File tree

3 files changed

+587
-347
lines changed

3 files changed

+587
-347
lines changed

lib/processors/jsdoc/lib/transformApiJson.js

Lines changed: 97 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"use strict";
1111
const cheerio = require("cheerio");
1212
const path = require('path');
13+
const {TypeParser} = require("./ui5/template/utils/typeParser");
1314
const log = (function() {
1415
try {
1516
return require("@ui5/logger").getLogger("builder:processors:jsdoc:transformApiJson");
@@ -36,6 +37,7 @@ function normalizeToUI5GlobalNotation(sModuleName){
3637
return sModuleName.replace(/\//g, ".");
3738
}
3839

40+
const typeParser = new TypeParser();
3941

4042
/**
4143
* Transforms the api.json as created by the JSDoc build into a pre-processed api.json file suitable for the SDK.
@@ -110,15 +112,78 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles,
110112
return func;
111113
}
112114

113-
function fnCreateTypesArr(sTypes) {
114-
return sTypes.split("|").map(function (sType) {
115-
const bLinkEnabled = !isBuiltInType(sType) && possibleUI5Symbol(sType.replace(/\[\]$/, ""));
116-
const oTypeInfo = { value: sType };
117-
if (bLinkEnabled) { // default is false, so omit if not required
118-
oTypeInfo.linkEnabled = true;
119-
}
120-
return oTypeInfo;
121-
});
115+
function isUI5Type(sType) {
116+
return !isBuiltInType(sType) && possibleUI5Symbol(sType);
117+
}
118+
119+
/**
120+
* Returns an object with the parsed custom-type information, namely:
121+
* - types: array of the parsed UI5 types inside the given complex type
122+
* - template: the template string with placeholders for the parsed UI5 types
123+
*
124+
* Examples:
125+
*
126+
* - parseUI5Types("sap.ui.core.ID | sap.ui.core.Control") returns
127+
* {
128+
* template: "${0} | ${1}",
129+
* UI5Types: ["sap.ui.core.ID", "sap.ui.core.Control"]
130+
* }
131+
*
132+
* - parseUI5Types("Array<sap.ui.core.Control>") returns
133+
* {
134+
* template: "Array<${0}>",
135+
* UI5Types: ["sap.ui.core.Control"]
136+
* }
137+
*
138+
* - parseUI5Types("Array<sap.ui.core.ID|string>") returns
139+
* {
140+
* template: "Array<${0} | string>", // built-in types remain unchanged in the template
141+
* UI5Types: ["sap.ui.core.ID"]
142+
* }
143+
*
144+
* - parseUI5Types("Object<string, sap.ui.core.Control>") returns
145+
* {
146+
* template: "Object<string, ${0}>", // built-in types remain unchanged in the template
147+
* UI5Types: ["sap.ui.core.Control"]
148+
* }
149+
*
150+
* - parseUI5Types("string") returns
151+
* {
152+
* template: "string" // skip the types array if empty
153+
* }
154+
*
155+
* - parseUI5Types("sap.ui.core.Control") returns
156+
* {
157+
* UI5Types: ["sap.ui.core.Control"] // skip template if its value is "${0}" (default value)
158+
* }
159+
* @param {string} sComplexType
160+
* @returns {?template: string, ?UI5Types: string[]}
161+
*/
162+
function parseUI5Types(sComplexType) {
163+
let oParsed;
164+
try {
165+
oParsed = typeParser.parseSimpleTypes(sComplexType, isUI5Type);
166+
} catch (e) {
167+
log.error("Error parsing type: " + sComplexType);
168+
log.error(e);
169+
oParsed = { template: sComplexType };
170+
}
171+
172+
const result = {};
173+
174+
if (oParsed.template !== '${0}') { // default is '${0}', so omit if not required
175+
result.template = oParsed.template;
176+
}
177+
178+
if (oParsed.simpleTypes?.length) { // it can be empty if none of the included simple types satisfied the filter function
179+
result.UI5Types = oParsed.simpleTypes
180+
}
181+
182+
return result;
183+
}
184+
185+
function includesIgnoreCase(array, string) {
186+
return array.some(item => item.toLowerCase() === string.toLowerCase());
122187
}
123188

124189
/**
@@ -132,7 +197,7 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles,
132197
const builtInTypes = formatters._baseTypes;
133198

134199
// Early return if the type is directly in baseTypes
135-
if (builtInTypes.includes(type)) {
200+
if (includesIgnoreCase(builtInTypes, type)) {
136201
return true;
137202
}
138203

@@ -193,7 +258,7 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles,
193258
* @returns {boolean}
194259
*/
195260
function possibleUI5Symbol(sName) {
196-
const ui5SymbolRegex = /^(module:)?[a-zA-Z][a-zA-Z0-9/.]*[a-zA-Z0-9]$/;
261+
const ui5SymbolRegex = /^(module:)?sap[/.][a-zA-Z][a-zA-Z0-9/.$]*[a-zA-Z0-9]$/
197262
return ui5SymbolRegex.test(sName);
198263
}
199264

@@ -373,7 +438,7 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles,
373438
// Types
374439
oParameter.types = [];
375440
if (oParameter.type) {
376-
oParameter.types = fnCreateTypesArr(oParameter.type);
441+
oParameter.typeInfo = parseUI5Types(oParameter.type);
377442
// Keep file size in check
378443
delete oParameter.type;
379444
}
@@ -458,7 +523,7 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles,
458523
// Type
459524
if (oSymbol.kind !== "enum") { // enum properties don't have an own type
460525
if (oProperty.type) {
461-
oProperty.types = fnCreateTypesArr(oProperty.type);
526+
oProperty.typeInfo = parseUI5Types(oProperty.type);
462527
// Keep file size in check
463528
delete oProperty.type;
464529
}
@@ -498,7 +563,7 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles,
498563

499564
// Type
500565
if (oProperty.type) {
501-
oProperty.types = fnCreateTypesArr(oProperty.type);
566+
oProperty.typeInfo = parseUI5Types(oProperty.type);
502567
// Keep file size in check
503568
delete oProperty.type;
504569
}
@@ -622,8 +687,9 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles,
622687
oMeta.specialSettings.forEach(oSetting => {
623688

624689
// Link Enabled
625-
if (!isBuiltInType(oSetting.type)) {
626-
oSetting.linkEnabled = true;
690+
if (oSetting.type) {
691+
oSetting.typeInfo = parseUI5Types(oSetting.type);
692+
delete oSetting.type; // Keep file size in check
627693
}
628694

629695
// Description
@@ -682,9 +748,9 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles,
682748
if (oEvent.parameters && Array.isArray(oEvent.parameters)) {
683749
oEvent.parameters.forEach(oParameter => {
684750

685-
// Link Enabled
686-
if (!isBuiltInType(oParameter.type)) {
687-
oParameter.linkEnabled = true;
751+
if (oParameter.type) {
752+
oParameter.typeInfo = parseUI5Types(oParameter.type);
753+
delete oParameter.type; // Keep file size in check
688754
}
689755

690756
// Description
@@ -1153,9 +1219,14 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles,
11531219
"array",
11541220
"element",
11551221
"Element",
1222+
"HTMLElement",
1223+
"Node",
1224+
"Attr",
11561225
"Date",
11571226
"DomRef",
1227+
"jQuery",
11581228
"jQuery.promise",
1229+
"jQuery.event",
11591230
"QUnit.Assert",
11601231
"object",
11611232
"Object",
@@ -1174,6 +1245,10 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles,
11741245
"TouchList",
11751246
"undefined",
11761247
"this",
1248+
"Blob",
1249+
"RegExp",
1250+
"void",
1251+
"ArrayBuffer",
11771252
"[object Object]"
11781253
],
11791254
ANNOTATIONS_LINK: 'http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part3-csdl.html',
@@ -2092,7 +2167,7 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles,
20922167

20932168
// Handle types
20942169
if (oProperty.type) {
2095-
oProperty.types = fnCreateTypesArr(oProperty.type);
2170+
oProperty.typeInfo = parseUI5Types(oProperty.type);
20962171
// Keep file size in check
20972172
delete oProperty.type;
20982173
}
@@ -2124,7 +2199,7 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles,
21242199
if (oMethod.parameters) {
21252200
oMethod.parameters.forEach(function (oParameter) {
21262201
if (oParameter.type) {
2127-
oParameter.types = fnCreateTypesArr(oParameter.type);
2202+
oParameter.typeInfo = parseUI5Types(oParameter.type);
21282203
// Keep file size in check
21292204
delete oParameter.type;
21302205
}
@@ -2145,7 +2220,7 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles,
21452220
// Handle return values
21462221
if (oMethod.returnValue && oMethod.returnValue.type) {
21472222
// Handle types
2148-
oMethod.returnValue.types = fnCreateTypesArr(oMethod.returnValue.type);
2223+
oMethod.returnValue.typeInfo = parseUI5Types(oMethod.returnValue.type);
21492224
}
21502225

21512226
});

0 commit comments

Comments
 (0)