@ui5/builder 3.0.0-alpha.1 → 3.0.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +867 -0
- package/index.js +0 -43
- package/lib/lbt/analyzer/FioriElementsAnalyzer.js +23 -12
- package/lib/lbt/analyzer/JSModuleAnalyzer.js +115 -61
- package/lib/lbt/analyzer/SmartTemplateAnalyzer.js +23 -12
- package/lib/lbt/analyzer/XMLCompositeAnalyzer.js +29 -19
- package/lib/lbt/analyzer/XMLTemplateAnalyzer.js +2 -1
- package/lib/lbt/analyzer/analyzeLibraryJS.js +15 -0
- package/lib/lbt/bundle/Builder.js +365 -138
- package/lib/lbt/bundle/BundleWriter.js +17 -0
- package/lib/lbt/bundle/Resolver.js +2 -2
- package/lib/lbt/calls/SapUiDefine.js +13 -7
- package/lib/lbt/resources/LocatorResource.js +7 -7
- package/lib/lbt/resources/LocatorResourcePool.js +8 -4
- package/lib/lbt/resources/ResourceCollector.js +22 -15
- package/lib/lbt/resources/ResourceInfoList.js +0 -1
- package/lib/lbt/resources/ResourcePool.js +7 -6
- package/lib/lbt/utils/ASTUtils.js +45 -18
- package/lib/lbt/utils/escapePropertiesFile.js +3 -6
- package/lib/lbt/utils/parseUtils.js +1 -1
- package/lib/processors/bundlers/moduleBundler.js +31 -10
- package/lib/processors/jsdoc/lib/createIndexFiles.js +1 -1
- package/lib/processors/jsdoc/lib/transformApiJson.js +78 -22
- package/lib/processors/jsdoc/lib/ui5/plugin.js +414 -122
- package/lib/processors/jsdoc/lib/ui5/template/publish.js +112 -91
- package/lib/processors/jsdoc/lib/ui5/template/utils/versionUtil.js +1 -1
- package/lib/processors/manifestCreator.js +8 -45
- package/lib/processors/minifier.js +11 -5
- package/lib/tasks/buildThemes.js +1 -1
- package/lib/tasks/bundlers/generateBundle.js +70 -30
- package/lib/tasks/bundlers/generateComponentPreload.js +26 -19
- package/lib/tasks/bundlers/generateFlexChangesBundle.js +10 -5
- package/lib/tasks/bundlers/generateLibraryPreload.js +113 -94
- package/lib/tasks/bundlers/generateManifestBundle.js +8 -10
- package/lib/tasks/bundlers/generateStandaloneAppBundle.js +42 -10
- package/lib/tasks/bundlers/utils/createModuleNameMapping.js +31 -0
- package/lib/tasks/generateCachebusterInfo.js +7 -3
- package/lib/tasks/generateLibraryManifest.js +6 -8
- package/lib/tasks/generateResourcesJson.js +3 -3
- package/lib/tasks/generateThemeDesignerResources.js +118 -2
- package/lib/tasks/generateVersionInfo.js +5 -5
- package/lib/tasks/jsdoc/generateJsdoc.js +1 -1
- package/lib/tasks/minify.js +14 -4
- package/lib/tasks/taskRepository.js +1 -13
- package/lib/tasks/transformBootstrapHtml.js +6 -1
- package/package.json +13 -11
- package/lib/builder/BuildContext.js +0 -56
- package/lib/builder/ProjectBuildContext.js +0 -57
- package/lib/builder/builder.js +0 -419
- package/lib/tasks/TaskUtil.js +0 -160
- package/lib/types/AbstractBuilder.js +0 -270
- package/lib/types/AbstractFormatter.js +0 -66
- package/lib/types/AbstractUi5Formatter.js +0 -95
- package/lib/types/application/ApplicationBuilder.js +0 -211
- package/lib/types/application/ApplicationFormatter.js +0 -227
- package/lib/types/application/applicationType.js +0 -15
- package/lib/types/library/LibraryBuilder.js +0 -231
- package/lib/types/library/LibraryFormatter.js +0 -519
- package/lib/types/library/libraryType.js +0 -15
- package/lib/types/module/ModuleBuilder.js +0 -7
- package/lib/types/module/ModuleFormatter.js +0 -54
- package/lib/types/module/moduleType.js +0 -15
- package/lib/types/themeLibrary/ThemeLibraryBuilder.js +0 -63
- package/lib/types/themeLibrary/ThemeLibraryFormatter.js +0 -90
- package/lib/types/themeLibrary/themeLibraryType.js +0 -15
- package/lib/types/typeRepository.js +0 -46
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* JSDoc3 plugin for UI5 documentation generation.
|
|
3
3
|
*
|
|
4
|
-
* (c) Copyright 2009-
|
|
4
|
+
* (c) Copyright 2009-2022 SAP SE or an SAP affiliate company.
|
|
5
5
|
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
|
|
6
6
|
*/
|
|
7
7
|
|
|
@@ -53,7 +53,14 @@
|
|
|
53
53
|
*/
|
|
54
54
|
|
|
55
55
|
/* imports */
|
|
56
|
-
const Syntax =
|
|
56
|
+
const Syntax = {
|
|
57
|
+
// Those are currently not in the syntax.js file.
|
|
58
|
+
ChainExpression: "ChainExpression",
|
|
59
|
+
OptionalMemberExpression: "OptionalMemberExpression",
|
|
60
|
+
OptionalCallExpression: "OptionalCallExpression",
|
|
61
|
+
|
|
62
|
+
...require("jsdoc/src/syntax").Syntax,
|
|
63
|
+
};
|
|
57
64
|
const Doclet = require('jsdoc/doclet').Doclet;
|
|
58
65
|
const fs = require('jsdoc/fs');
|
|
59
66
|
const path = require('jsdoc/path');
|
|
@@ -234,9 +241,8 @@ function resolveModuleName(base, name) {
|
|
|
234
241
|
function analyzeModuleDefinition(node) {
|
|
235
242
|
const args = node.arguments;
|
|
236
243
|
let arg = 0;
|
|
237
|
-
if ( arg < args.length
|
|
238
|
-
|
|
239
|
-
currentModule.name = args[arg].value;
|
|
244
|
+
if ( arg < args.length && isStringLiteral(args[arg]) ) {
|
|
245
|
+
currentModule.name = convertValue(args[arg]);
|
|
240
246
|
warning(`module explicitly defined a module name '${currentModule.name}'`);
|
|
241
247
|
const resourceModuleName = getModuleName(currentModule.resource);
|
|
242
248
|
if (currentModule.name !== resourceModuleName) {
|
|
@@ -249,13 +255,19 @@ function analyzeModuleDefinition(node) {
|
|
|
249
255
|
currentModule.dependencies = convertValue(args[arg], "string[]");
|
|
250
256
|
arg++;
|
|
251
257
|
}
|
|
252
|
-
if ( arg < args.length &&
|
|
258
|
+
if ( arg < args.length &&
|
|
259
|
+
[Syntax.FunctionExpression, Syntax.ArrowFunctionExpression].includes(args[arg].type)) {
|
|
260
|
+
|
|
253
261
|
currentModule.factory = args[arg];
|
|
254
262
|
arg++;
|
|
255
263
|
}
|
|
256
264
|
if ( currentModule.dependencies && currentModule.factory ) {
|
|
257
265
|
for ( let i = 0; i < currentModule.dependencies.length && i < currentModule.factory.params.length; i++ ) {
|
|
258
|
-
const name =
|
|
266
|
+
const name =
|
|
267
|
+
(currentModule.factory.params[i].type === Syntax.ObjectPattern)
|
|
268
|
+
? currentModule.factory.params[i].properties[0].value.name // ObjectPattern means destructuring of the parameter
|
|
269
|
+
: currentModule.factory.params[i].name; // simple Identifier
|
|
270
|
+
|
|
259
271
|
const module = resolveModuleName(currentModule.module, currentModule.dependencies[i]);
|
|
260
272
|
debug(` import ${name} from '${module}'`);
|
|
261
273
|
currentModule.localNames[name] = {
|
|
@@ -265,7 +277,7 @@ function analyzeModuleDefinition(node) {
|
|
|
265
277
|
}
|
|
266
278
|
}
|
|
267
279
|
if ( currentModule.factory ) {
|
|
268
|
-
collectShortcuts(currentModule.factory
|
|
280
|
+
collectShortcuts(currentModule.factory);
|
|
269
281
|
}
|
|
270
282
|
}
|
|
271
283
|
|
|
@@ -276,31 +288,33 @@ function analyzeModuleDefinition(node) {
|
|
|
276
288
|
*
|
|
277
289
|
* @param {ASTNode} body AST node of a function body that shall be searched for shortcuts
|
|
278
290
|
*/
|
|
279
|
-
function collectShortcuts(
|
|
291
|
+
function collectShortcuts(factory) {
|
|
292
|
+
const body = factory.body;
|
|
280
293
|
|
|
281
294
|
function checkAssignment(name, valueNode) {
|
|
295
|
+
valueNode = resolvePotentialWrapperExpression(valueNode);
|
|
296
|
+
|
|
282
297
|
if ( valueNode.type === Syntax.Literal ) {
|
|
283
298
|
currentModule.localNames[name] = {
|
|
284
299
|
value: valueNode.value,
|
|
285
300
|
raw: valueNode.raw
|
|
286
301
|
};
|
|
287
302
|
debug("compile time constant found ", name, valueNode.value);
|
|
288
|
-
} else if ( valueNode
|
|
303
|
+
} else if ( isMemberExpression(valueNode) ) {
|
|
289
304
|
const _import = getLeftmostName(valueNode);
|
|
290
305
|
const local = _import && currentModule.localNames[_import];
|
|
291
|
-
|
|
306
|
+
const objectName = getObjectName(valueNode);
|
|
307
|
+
if ( objectName && typeof local === 'object' && local.module ) {
|
|
292
308
|
currentModule.localNames[name] = {
|
|
293
309
|
module: local.module,
|
|
294
|
-
path:
|
|
310
|
+
path: objectName.split('.').slice(1).join('.') // TODO chaining if local has path
|
|
295
311
|
};
|
|
296
312
|
debug(` found local shortcut: ${name} ${currentModule.localNames[name]}`);
|
|
297
313
|
}
|
|
298
314
|
} else if ( isRequireSyncCall(valueNode) || isProbingRequireCall(valueNode) ) {
|
|
299
|
-
if ( valueNode.arguments[0]
|
|
300
|
-
&& valueNode.arguments[0].type === Syntax.Literal
|
|
301
|
-
&& typeof valueNode.arguments[0].value === 'string' ) {
|
|
315
|
+
if ( valueNode.arguments[0] && isStringLiteral(valueNode.arguments[0]) ) {
|
|
302
316
|
currentModule.localNames[name] = {
|
|
303
|
-
module: valueNode.arguments[0]
|
|
317
|
+
module: convertValue(valueNode.arguments[0])
|
|
304
318
|
// no (or empty) path
|
|
305
319
|
};
|
|
306
320
|
debug(` found local import: ${name} = ${valueNode.callee.property.name}('${valueNode.arguments[0].value}')`);
|
|
@@ -314,8 +328,8 @@ function collectShortcuts(body) {
|
|
|
314
328
|
}
|
|
315
329
|
}
|
|
316
330
|
|
|
317
|
-
if ( body.type === Syntax.BlockStatement ) {
|
|
318
|
-
|
|
331
|
+
if ( body.type === Syntax.BlockStatement || isArrowFuncExpression(factory) ) {
|
|
332
|
+
const itemsResolver = function ( stmt ) {
|
|
319
333
|
// console.log(stmt);
|
|
320
334
|
if ( stmt.type === Syntax.FunctionDeclaration ) {
|
|
321
335
|
if ( stmt.id && stmt.id.type === Syntax.Identifier && stmt.loc && stmt.loc.start ) {
|
|
@@ -335,15 +349,28 @@ function collectShortcuts(body) {
|
|
|
335
349
|
&& stmt.expression.type === Syntax.AssignmentExpression
|
|
336
350
|
&& stmt.expression.left.type === Syntax.Identifier ) {
|
|
337
351
|
checkAssignment(stmt.expression.left.name, stmt.expression.right);
|
|
338
|
-
} else if ( stmt
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
352
|
+
} else if ( isReturningNode(stmt) ) {
|
|
353
|
+
const stmtArgument = isArrowFuncExpression(stmt)
|
|
354
|
+
? stmt.body
|
|
355
|
+
: resolvePotentialWrapperExpression(stmt).argument;
|
|
356
|
+
|
|
357
|
+
if ( stmtArgument && stmtArgument.type === Syntax.Identifier ) {
|
|
358
|
+
currentModule.defaultExport = stmtArgument.name;
|
|
359
|
+
} else if ( stmtArgument && stmtArgument.type === Syntax.ClassExpression && stmtArgument.id && stmtArgument.id.type === Syntax.Identifier ) {
|
|
360
|
+
debug(` found default export class definition: return class '${stmtArgument.id.name}'`);
|
|
361
|
+
currentModule.defaultExportClass = stmtArgument.id.name;
|
|
362
|
+
} else if ( stmtArgument && isExtendCall(stmtArgument) ) {
|
|
363
|
+
debug(` found default export class definition: return .extend('${stmtArgument.arguments[0].value}', ...)`);
|
|
364
|
+
currentModule.defaultExportClass = convertValue(stmtArgument.arguments[0]);
|
|
344
365
|
}
|
|
345
366
|
}
|
|
346
|
-
}
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
if (isArrowFuncExpression(factory)) {
|
|
370
|
+
itemsResolver(factory);
|
|
371
|
+
} else {
|
|
372
|
+
body.body.forEach(itemsResolver);
|
|
373
|
+
}
|
|
347
374
|
}
|
|
348
375
|
|
|
349
376
|
if ( currentModule.defaultExport && currentModule.localNames[currentModule.defaultExport] ) {
|
|
@@ -368,12 +395,12 @@ function guessSingularName(sPluralName) {
|
|
|
368
395
|
}
|
|
369
396
|
|
|
370
397
|
function getPropertyKey(prop) {
|
|
371
|
-
if ( prop.
|
|
398
|
+
if ( prop.type === Syntax.SpreadElement ) {
|
|
399
|
+
return;
|
|
400
|
+
} else if ( prop.key.type === Syntax.Identifier && prop.computed !== true ) {
|
|
372
401
|
return prop.key.name;
|
|
373
402
|
} else if ( prop.key.type === Syntax.Literal ) {
|
|
374
403
|
return String(prop.key.value);
|
|
375
|
-
} else {
|
|
376
|
-
return prop.key.toSource();
|
|
377
404
|
}
|
|
378
405
|
}
|
|
379
406
|
|
|
@@ -431,80 +458,180 @@ function createPropertyMap(node, defaultKey) {
|
|
|
431
458
|
return result;
|
|
432
459
|
}
|
|
433
460
|
|
|
461
|
+
/**
|
|
462
|
+
* Resolves potential wrapper expressions like: ChainExpression, AwaitExpression, etc.
|
|
463
|
+
* @param {Node} node
|
|
464
|
+
* @returns {Node} the resolved node
|
|
465
|
+
*/
|
|
466
|
+
function resolvePotentialWrapperExpression(node) {
|
|
467
|
+
switch (node && node.type) {
|
|
468
|
+
case Syntax.ChainExpression:
|
|
469
|
+
return node.expression;
|
|
470
|
+
|
|
471
|
+
case Syntax.AwaitExpression:
|
|
472
|
+
return node.argument;
|
|
473
|
+
|
|
474
|
+
case Syntax.ExpressionStatement:
|
|
475
|
+
if ( node.expression.type === Syntax.YieldExpression ) {
|
|
476
|
+
return node.expression.argument.type === Syntax.UpdateExpression
|
|
477
|
+
? node.expression.argument
|
|
478
|
+
: node.expression;
|
|
479
|
+
}
|
|
480
|
+
default:
|
|
481
|
+
return node;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Strips the ChainExpression wrapper if such
|
|
487
|
+
*
|
|
488
|
+
* @param {Node} rootNode
|
|
489
|
+
* @param {String} path
|
|
490
|
+
* @returns {Node}
|
|
491
|
+
*/
|
|
492
|
+
function stripChainWrappers(rootNode, path) {
|
|
493
|
+
const strip = (node) =>
|
|
494
|
+
node && node.type === Syntax.ChainExpression ? node.expression : node;
|
|
495
|
+
|
|
496
|
+
let curNode = strip(rootNode);
|
|
497
|
+
let chunks = path && path.split(".");
|
|
498
|
+
let name;
|
|
499
|
+
|
|
500
|
+
while (chunks && chunks.length) {
|
|
501
|
+
name = chunks.shift();
|
|
502
|
+
curNode = curNode && strip(curNode[name]);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
return curNode;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
function isTemplateLiteralWithoutExpression(node) {
|
|
509
|
+
return (
|
|
510
|
+
node?.type === Syntax.TemplateLiteral &&
|
|
511
|
+
node?.expressions?.length === 0 &&
|
|
512
|
+
node?.quasis?.length === 1
|
|
513
|
+
);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* Checks whether a node is Literal or TemplateLiteral without an expression
|
|
518
|
+
*
|
|
519
|
+
* @param {Node} node
|
|
520
|
+
* @returns {String}
|
|
521
|
+
*/
|
|
522
|
+
function isStringLiteral(node) {
|
|
523
|
+
return (
|
|
524
|
+
(node && node.type === Syntax.Literal && typeof node.value === "string")
|
|
525
|
+
|| isTemplateLiteralWithoutExpression(node)
|
|
526
|
+
);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
function isMemberExpression(node) {
|
|
530
|
+
return node && [Syntax.MemberExpression, Syntax.OptionalMemberExpression].includes(node.type);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
function isCaleeMemberExpression(node) {
|
|
534
|
+
return (
|
|
535
|
+
node &&
|
|
536
|
+
[Syntax.CallExpression, Syntax.OptionalCallExpression].includes(node.type) &&
|
|
537
|
+
isMemberExpression(node.callee)
|
|
538
|
+
);
|
|
539
|
+
}
|
|
540
|
+
|
|
434
541
|
function isExtendCall(node) {
|
|
542
|
+
node = stripChainWrappers(node);
|
|
435
543
|
|
|
436
544
|
return (
|
|
437
545
|
node
|
|
438
|
-
&& node
|
|
439
|
-
&& node
|
|
440
|
-
&& node
|
|
441
|
-
&& node.callee.property.name === 'extend'
|
|
546
|
+
&& isCaleeMemberExpression(node)
|
|
547
|
+
&& stripChainWrappers(node, "callee.property").type === Syntax.Identifier
|
|
548
|
+
&& stripChainWrappers(node, "callee.property").name === 'extend'
|
|
442
549
|
&& node.arguments.length >= 2
|
|
443
|
-
&& node.arguments[0]
|
|
444
|
-
&& typeof node.arguments[0].value === "string"
|
|
550
|
+
&& isStringLiteral(node.arguments[0])
|
|
445
551
|
&& node.arguments[1].type === Syntax.ObjectExpression
|
|
446
552
|
);
|
|
447
553
|
|
|
448
554
|
}
|
|
449
555
|
|
|
556
|
+
function isArrowFuncExpression(node) {
|
|
557
|
+
return (
|
|
558
|
+
node &&
|
|
559
|
+
node.type === Syntax.ArrowFunctionExpression &&
|
|
560
|
+
node.expression === true
|
|
561
|
+
);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Checks whether the node is of a "returning" type
|
|
566
|
+
*
|
|
567
|
+
* @param {Node} node
|
|
568
|
+
* @returns {Boolean}
|
|
569
|
+
*/
|
|
570
|
+
function isReturningNode(node) {
|
|
571
|
+
return (node && node.type === Syntax.ReturnStatement)
|
|
572
|
+
|| (node && node.type === Syntax.ExpressionStatement && node.expression.type === Syntax.YieldExpression)
|
|
573
|
+
|| isArrowFuncExpression(node);
|
|
574
|
+
}
|
|
575
|
+
|
|
450
576
|
function isSapUiDefineCall(node) {
|
|
451
577
|
|
|
452
578
|
return (
|
|
453
|
-
node
|
|
454
|
-
&& node
|
|
455
|
-
&& node
|
|
456
|
-
&& node
|
|
457
|
-
&& node
|
|
458
|
-
&& node
|
|
459
|
-
&& node
|
|
460
|
-
&& node
|
|
461
|
-
&& node
|
|
462
|
-
&& node.callee.property.name === 'define'
|
|
579
|
+
stripChainWrappers(node)
|
|
580
|
+
&& isCaleeMemberExpression(stripChainWrappers(node))
|
|
581
|
+
&& isMemberExpression(stripChainWrappers(node, "callee.object"))
|
|
582
|
+
&& stripChainWrappers(node, "callee.property").type === Syntax.Identifier
|
|
583
|
+
&& stripChainWrappers(node, "callee.property").name === 'define'
|
|
584
|
+
&& stripChainWrappers(node, "callee.object.object").type === Syntax.Identifier
|
|
585
|
+
&& stripChainWrappers(node, "callee.object.object").name === 'sap'
|
|
586
|
+
&& stripChainWrappers(node, "callee.object.property").type === Syntax.Identifier
|
|
587
|
+
&& stripChainWrappers(node, "callee.object.property").name === 'ui'
|
|
463
588
|
);
|
|
464
589
|
|
|
465
590
|
}
|
|
466
591
|
|
|
467
592
|
function isCreateDataTypeCall(node) {
|
|
593
|
+
node = stripChainWrappers(node);
|
|
594
|
+
|
|
468
595
|
return (
|
|
469
596
|
node
|
|
470
|
-
&& node
|
|
471
|
-
&& node
|
|
472
|
-
&&
|
|
473
|
-
&& node
|
|
474
|
-
&& node.callee.property.name === 'createType'
|
|
597
|
+
&& isCaleeMemberExpression(node)
|
|
598
|
+
&& getResolvedObjectName(stripChainWrappers(node, "callee.object")) === "sap.ui.base.DataType"
|
|
599
|
+
&& stripChainWrappers(node, "callee.property").type === Syntax.Identifier
|
|
600
|
+
&& stripChainWrappers(node, "callee.property").name === 'createType'
|
|
475
601
|
);
|
|
476
602
|
}
|
|
477
603
|
|
|
478
604
|
function isRequireSyncCall(node) {
|
|
605
|
+
node = stripChainWrappers(node);
|
|
606
|
+
|
|
479
607
|
return (
|
|
480
608
|
node
|
|
481
|
-
&& node
|
|
482
|
-
&& node
|
|
483
|
-
&& node
|
|
484
|
-
&& node
|
|
485
|
-
&& node
|
|
486
|
-
&& node
|
|
487
|
-
&& node
|
|
488
|
-
&& node
|
|
489
|
-
&& node.callee.property.name === 'requireSync'
|
|
609
|
+
&& isCaleeMemberExpression(node)
|
|
610
|
+
&& isMemberExpression( stripChainWrappers(node, "callee.object") )
|
|
611
|
+
&& stripChainWrappers(node, "callee.object.object").type === Syntax.Identifier
|
|
612
|
+
&& stripChainWrappers(node, "callee.object.object").name === 'sap'
|
|
613
|
+
&& stripChainWrappers(node, "callee.object.property").type === Syntax.Identifier
|
|
614
|
+
&& stripChainWrappers(node, "callee.object.property").name === 'ui'
|
|
615
|
+
&& stripChainWrappers(node, "callee.property").type === Syntax.Identifier
|
|
616
|
+
&& stripChainWrappers(node, "callee.property").name === 'requireSync'
|
|
490
617
|
);
|
|
491
618
|
}
|
|
492
619
|
|
|
493
620
|
function isProbingRequireCall(node) {
|
|
621
|
+
node = stripChainWrappers(node);
|
|
622
|
+
|
|
494
623
|
return (
|
|
495
624
|
node
|
|
496
|
-
&& node
|
|
497
|
-
&& node
|
|
498
|
-
&& node
|
|
499
|
-
&& node
|
|
500
|
-
&& node
|
|
501
|
-
&& node
|
|
502
|
-
&& node
|
|
503
|
-
&& node
|
|
504
|
-
&& node.callee.property.name === 'require'
|
|
625
|
+
&& isCaleeMemberExpression(node)
|
|
626
|
+
&& isMemberExpression( stripChainWrappers(node, "callee.object") )
|
|
627
|
+
&& stripChainWrappers(node, "callee.object.object").type === Syntax.Identifier
|
|
628
|
+
&& stripChainWrappers(node, "callee.object.object").name === 'sap'
|
|
629
|
+
&& stripChainWrappers(node, "callee.object.property").type === Syntax.Identifier
|
|
630
|
+
&& stripChainWrappers(node, "callee.object.property").name === 'ui'
|
|
631
|
+
&& stripChainWrappers(node, "callee.property").type === Syntax.Identifier
|
|
632
|
+
&& stripChainWrappers(node, "callee.property").name === 'require'
|
|
505
633
|
&& node.arguments.length === 1
|
|
506
|
-
&& node.arguments[0]
|
|
507
|
-
&& typeof node.arguments[0].value === 'string' // TODO generalize to statically analyzable constants
|
|
634
|
+
&& isStringLiteral(node.arguments[0])
|
|
508
635
|
);
|
|
509
636
|
}
|
|
510
637
|
|
|
@@ -520,7 +647,7 @@ function isCompileTimeConstant(node) {
|
|
|
520
647
|
}
|
|
521
648
|
|
|
522
649
|
function getObjectName(node) {
|
|
523
|
-
if ( node
|
|
650
|
+
if ( isMemberExpression(node) && !node.computed && node.property.type === Syntax.Identifier ) {
|
|
524
651
|
const prefix = getObjectName(node.object);
|
|
525
652
|
return prefix ? prefix + "." + node.property.name : null;
|
|
526
653
|
} else if ( node.type === Syntax.Identifier ) {
|
|
@@ -535,7 +662,7 @@ function getObjectName(node) {
|
|
|
535
662
|
* returns the leftmost identifier a
|
|
536
663
|
*/
|
|
537
664
|
function getLeftmostName(node) {
|
|
538
|
-
while ( node
|
|
665
|
+
while ( isMemberExpression(node) ) {
|
|
539
666
|
node = node.object;
|
|
540
667
|
}
|
|
541
668
|
if ( node.type === Syntax.Identifier ) {
|
|
@@ -603,7 +730,7 @@ function convertValueWithRaw(node, type, propertyName) {
|
|
|
603
730
|
raw: node.operator + node.argument.raw
|
|
604
731
|
};
|
|
605
732
|
|
|
606
|
-
} else if ( node
|
|
733
|
+
} else if ( isMemberExpression(node) && type ) {
|
|
607
734
|
|
|
608
735
|
// enum value (a.b.c)
|
|
609
736
|
value = getResolvedObjectName(node);
|
|
@@ -673,6 +800,11 @@ function convertValueWithRaw(node, type, propertyName) {
|
|
|
673
800
|
};
|
|
674
801
|
}
|
|
675
802
|
|
|
803
|
+
} else if ( isTemplateLiteralWithoutExpression(node) ) {
|
|
804
|
+
return {
|
|
805
|
+
value: node?.quasis?.[0]?.value?.cooked,
|
|
806
|
+
raw: node?.quasis?.[0]?.value?.raw,
|
|
807
|
+
};
|
|
676
808
|
}
|
|
677
809
|
|
|
678
810
|
value = "...see text or source";
|
|
@@ -696,10 +828,10 @@ function convertStringArray(node) {
|
|
|
696
828
|
}
|
|
697
829
|
const result = [];
|
|
698
830
|
for ( let i = 0; i < node.elements.length; i++ ) {
|
|
699
|
-
if ( node.elements[i]
|
|
831
|
+
if ( !isStringLiteral(node.elements[i]) ) {
|
|
700
832
|
throw new Error("not a string literal");
|
|
701
833
|
}
|
|
702
|
-
result.push(node.elements[i]
|
|
834
|
+
result.push( convertValue(node.elements[i]) );
|
|
703
835
|
}
|
|
704
836
|
// console.log(result);
|
|
705
837
|
return result;
|
|
@@ -735,7 +867,7 @@ function collectClassInfo(extendCall, classDoclet) {
|
|
|
735
867
|
if ( classDoclet && classDoclet.augments && classDoclet.augments.length === 1 ) {
|
|
736
868
|
baseType = classDoclet.augments[0];
|
|
737
869
|
}
|
|
738
|
-
if ( extendCall.callee
|
|
870
|
+
if ( isMemberExpression(extendCall.callee) ) {
|
|
739
871
|
const baseCandidate = getResolvedObjectName(extendCall.callee.object);
|
|
740
872
|
if ( baseCandidate && baseType == null ) {
|
|
741
873
|
baseType = baseCandidate;
|
|
@@ -745,7 +877,7 @@ function collectClassInfo(extendCall, classDoclet) {
|
|
|
745
877
|
}
|
|
746
878
|
|
|
747
879
|
const oClassInfo = {
|
|
748
|
-
name : extendCall.arguments[0]
|
|
880
|
+
name : convertValue(extendCall.arguments[0]),
|
|
749
881
|
baseType : baseType,
|
|
750
882
|
interfaces : [],
|
|
751
883
|
doc : classDoclet && classDoclet.description,
|
|
@@ -987,7 +1119,7 @@ function collectClassInfo(extendCall, classDoclet) {
|
|
|
987
1119
|
return oClassInfo;
|
|
988
1120
|
}
|
|
989
1121
|
|
|
990
|
-
function collectDesigntimeInfo(
|
|
1122
|
+
function collectDesigntimeInfo(dtNodeArgument) {
|
|
991
1123
|
|
|
992
1124
|
function each(node, defaultKey, callback) {
|
|
993
1125
|
const map = node && createPropertyMap(node.value);
|
|
@@ -1009,7 +1141,7 @@ function collectDesigntimeInfo(dtNode) {
|
|
|
1009
1141
|
|
|
1010
1142
|
let oDesigntimeInfo;
|
|
1011
1143
|
|
|
1012
|
-
const map = createPropertyMap(
|
|
1144
|
+
const map = createPropertyMap(dtNodeArgument);
|
|
1013
1145
|
|
|
1014
1146
|
if (map.annotations) {
|
|
1015
1147
|
|
|
@@ -1094,12 +1226,19 @@ function determineValueRangeBorder(range, expression, varname, inverse) {
|
|
|
1094
1226
|
function determineValueRange(expression, varname, inverse) {
|
|
1095
1227
|
const range = {};
|
|
1096
1228
|
if ( expression.type === Syntax.LogicalExpression
|
|
1097
|
-
&& expression.operator === '&&'
|
|
1098
1229
|
&& expression.left.type === Syntax.BinaryExpression
|
|
1099
|
-
&& expression.right.type === Syntax.BinaryExpression
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1230
|
+
&& expression.right.type === Syntax.BinaryExpression ) {
|
|
1231
|
+
|
|
1232
|
+
if ( expression.operator === "&&"
|
|
1233
|
+
&& determineValueRangeBorder(range, expression.left, varname, inverse)
|
|
1234
|
+
&& determineValueRangeBorder(range, expression.right, varname, inverse) ) {
|
|
1235
|
+
return range;
|
|
1236
|
+
} else if ( ["||", "??"].includes(expression.operator)
|
|
1237
|
+
&& ( determineValueRangeBorder(range, expression.left, varname, inverse)
|
|
1238
|
+
|| determineValueRangeBorder(range, expression.right, varname, inverse) )) {
|
|
1239
|
+
return range;
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1103
1242
|
} else if ( expression.type === Syntax.BinaryExpression
|
|
1104
1243
|
&& determineValueRangeBorder(range, expression, varname, inverse) ) {
|
|
1105
1244
|
return range;
|
|
@@ -1112,24 +1251,24 @@ function collectDataTypeInfo(extendCall, classDoclet) {
|
|
|
1112
1251
|
let i = 0,
|
|
1113
1252
|
name, def, base, pattern, range;
|
|
1114
1253
|
|
|
1115
|
-
if ( i < args.length && args[i]
|
|
1116
|
-
name = args[i++]
|
|
1254
|
+
if ( i < args.length && isStringLiteral(args[i]) ) {
|
|
1255
|
+
name = convertValue(args[i++]);
|
|
1117
1256
|
}
|
|
1118
1257
|
if ( i < args.length && args[i].type === Syntax.ObjectExpression ) {
|
|
1119
1258
|
def = createPropertyMap(args[i++]);
|
|
1120
1259
|
}
|
|
1121
1260
|
if ( i < args.length ) {
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
&&
|
|
1128
|
-
&&
|
|
1129
|
-
&&
|
|
1130
|
-
&&
|
|
1131
|
-
&&
|
|
1132
|
-
base = args[i++].arguments[0]
|
|
1261
|
+
const node = resolvePotentialWrapperExpression(args[i]);
|
|
1262
|
+
|
|
1263
|
+
if ( isStringLiteral(args[i]) ) {
|
|
1264
|
+
base = convertValue(args[i++]);
|
|
1265
|
+
} else if ( isCaleeMemberExpression(node)
|
|
1266
|
+
&& getResolvedObjectName(node.callee.object) === "sap.ui.base.DataType"
|
|
1267
|
+
&& node.callee.property.type === Syntax.Identifier
|
|
1268
|
+
&& node.callee.property.name === 'getType'
|
|
1269
|
+
&& node.arguments.length === 1
|
|
1270
|
+
&& isStringLiteral(node.arguments[0]) ) {
|
|
1271
|
+
base = convertValue(args[i++].arguments[0]);
|
|
1133
1272
|
} else {
|
|
1134
1273
|
future(`could not identify base type of data type '${name}'`);
|
|
1135
1274
|
}
|
|
@@ -1137,25 +1276,31 @@ function collectDataTypeInfo(extendCall, classDoclet) {
|
|
|
1137
1276
|
base = "any";
|
|
1138
1277
|
}
|
|
1139
1278
|
|
|
1279
|
+
const isArrowExpression = isArrowFuncExpression(def && def.isValid && def.isValid.value);
|
|
1280
|
+
|
|
1140
1281
|
if ( def
|
|
1141
1282
|
&& def.isValid
|
|
1142
|
-
&& def.isValid.value.type
|
|
1283
|
+
&& [Syntax.FunctionExpression, Syntax.ArrowFunctionExpression].includes(def.isValid.value.type)
|
|
1143
1284
|
&& def.isValid.value.params.length === 1
|
|
1144
1285
|
&& def.isValid.value.params[0].type === Syntax.Identifier
|
|
1145
|
-
&& def.isValid.value.body.body.length === 1 ) {
|
|
1286
|
+
&& (isArrowExpression || def.isValid.value.body.body.length === 1) ) {
|
|
1287
|
+
|
|
1146
1288
|
const varname = def.isValid.value.params[0].name;
|
|
1147
|
-
const stmt = def.isValid.value.body.body[0];
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
&&
|
|
1155
|
-
|
|
1289
|
+
const stmt = isArrowExpression ? def.isValid.value.body : def.isValid.value.body.body[0];
|
|
1290
|
+
|
|
1291
|
+
if ( isReturningNode(stmt) || isArrowExpression ) {
|
|
1292
|
+
const stmtArgument = resolvePotentialWrapperExpression(
|
|
1293
|
+
isArrowExpression ? stmt : stmt.argument
|
|
1294
|
+
);
|
|
1295
|
+
if ( isCaleeMemberExpression(stmtArgument)
|
|
1296
|
+
&& stmtArgument.callee.object.type === Syntax.Literal
|
|
1297
|
+
&& stmtArgument.callee.object.regex
|
|
1298
|
+
&& stmtArgument.callee.property.type === Syntax.Identifier
|
|
1299
|
+
&& stmtArgument.callee.property.name === 'test' ) {
|
|
1300
|
+
pattern = stmtArgument.callee.object.regex.pattern;
|
|
1156
1301
|
// console.log(pattern);
|
|
1157
1302
|
} else {
|
|
1158
|
-
range = determineValueRange(
|
|
1303
|
+
range = determineValueRange(stmtArgument, varname, false);
|
|
1159
1304
|
}
|
|
1160
1305
|
} else if ( stmt.type === Syntax.IfStatement
|
|
1161
1306
|
&& stmt.consequent.type === Syntax.BlockStatement
|
|
@@ -1617,7 +1762,7 @@ function createAutoDoc(oClassInfo, classComment, doclet, node, parser, filename,
|
|
|
1617
1762
|
"Removes a " + n1 + " from the aggregation " + link + ".",
|
|
1618
1763
|
"",
|
|
1619
1764
|
"@param {int | string | " + makeTypeString(info, true) + "} " + varname(n1, "variant") + " The " + n1 + " to remove or its index or id",
|
|
1620
|
-
"@returns {" + makeTypeString(info, true) + "} The removed " + n1 + " or <code>null</code>",
|
|
1765
|
+
"@returns {" + makeTypeString(info, true) + "|null} The removed " + n1 + " or <code>null</code>",
|
|
1621
1766
|
info.since ? "@since " + info.since : "",
|
|
1622
1767
|
info.deprecation ? "@deprecated " + info.deprecation : "",
|
|
1623
1768
|
info.experimental ? "@experimental " + info.experimental : "",
|
|
@@ -1740,7 +1885,7 @@ function createAutoDoc(oClassInfo, classComment, doclet, node, parser, filename,
|
|
|
1740
1885
|
newJSDoc([
|
|
1741
1886
|
"Removes an " + n1 + " from the association named " + link + ".",
|
|
1742
1887
|
"@param {int | sap.ui.core.ID | " + info.type + "} " + varname(n1, "variant") + " The " + n1 + " to be removed or its index or ID",
|
|
1743
|
-
"@returns {sap.ui.core.ID} The removed " + n1 + " or <code>null</code>",
|
|
1888
|
+
"@returns {sap.ui.core.ID|null} The removed " + n1 + " or <code>null</code>",
|
|
1744
1889
|
info.since ? "@since " + info.since : "",
|
|
1745
1890
|
info.deprecation ? "@deprecated " + info.deprecation : "",
|
|
1746
1891
|
info.experimental ? "@experimental " + info.experimental : "",
|
|
@@ -1812,7 +1957,7 @@ function createAutoDoc(oClassInfo, classComment, doclet, node, parser, filename,
|
|
|
1812
1957
|
"",
|
|
1813
1958
|
"@param {object}",
|
|
1814
1959
|
" [oData] An application-specific payload object that will be passed to the event handler along with the event object when firing the event",
|
|
1815
|
-
"@param {function}",
|
|
1960
|
+
"@param {function(sap.ui.base.Event):void}",
|
|
1816
1961
|
" fnFunction The function to be called when the event occurs",
|
|
1817
1962
|
"@param {object}",
|
|
1818
1963
|
" [oListener] Context object to call the event handler with. Defaults to this <code>" + oClassInfo.name + "</code> itself",
|
|
@@ -1830,7 +1975,7 @@ function createAutoDoc(oClassInfo, classComment, doclet, node, parser, filename,
|
|
|
1830
1975
|
"",
|
|
1831
1976
|
"The passed function and listener object must match the ones used for event registration.",
|
|
1832
1977
|
"",
|
|
1833
|
-
"@param {function}",
|
|
1978
|
+
"@param {function(sap.ui.base.Event):void}",
|
|
1834
1979
|
" fnFunction The function to be called, when the event occurs",
|
|
1835
1980
|
"@param {object}",
|
|
1836
1981
|
" [oListener] Context object on which the given function had to be called",
|
|
@@ -2582,24 +2727,37 @@ exports.astNodeVisitor = {
|
|
|
2582
2727
|
}
|
|
2583
2728
|
}
|
|
2584
2729
|
|
|
2585
|
-
if (
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2730
|
+
if ( [Syntax.ExpressionStatement, Syntax.LogicalExpression].includes(node.type) ) {
|
|
2731
|
+
let nodeToAnalyze;
|
|
2732
|
+
if (isSapUiDefineCall(node.expression)) {
|
|
2733
|
+
nodeToAnalyze = node.expression;
|
|
2734
|
+
|
|
2735
|
+
/*
|
|
2589
2736
|
} else if ( isJQuerySapDeclareCall(node.expression)
|
|
2590
2737
|
&& node.expression.arguments.length > 0
|
|
2591
2738
|
&& node.expression.arguments[0].type === Syntax.Literal
|
|
2592
2739
|
&& typeof node.expression.arguments[0].value === "string" ) {
|
|
2593
2740
|
warning(`module has explicit module name ${node.expression.arguments[0].value}`);
|
|
2594
2741
|
*/
|
|
2742
|
+
} else if (isSapUiDefineCall(node.left)) {
|
|
2743
|
+
nodeToAnalyze = node.left;
|
|
2744
|
+
} else if (isSapUiDefineCall(node.right)) {
|
|
2745
|
+
nodeToAnalyze = node.right;
|
|
2595
2746
|
}
|
|
2596
2747
|
|
|
2748
|
+
nodeToAnalyze && analyzeModuleDefinition(
|
|
2749
|
+
resolvePotentialWrapperExpression(nodeToAnalyze)
|
|
2750
|
+
);
|
|
2597
2751
|
}
|
|
2598
2752
|
|
|
2599
|
-
|
|
2753
|
+
const isArrowExpression = isArrowFuncExpression(node) && node.body.type === Syntax.ObjectExpression;
|
|
2754
|
+
const nodeArgument = isArrowExpression
|
|
2755
|
+
? node.body
|
|
2756
|
+
: resolvePotentialWrapperExpression(node).argument;
|
|
2757
|
+
if (isArrowExpression || (isReturningNode(node) && nodeArgument && nodeArgument.type === Syntax.ObjectExpression) && /\.designtime\.js$/.test(currentSourceName) ) {
|
|
2600
2758
|
|
|
2601
2759
|
// assume this node to return designtime metadata. Collect it and remember it by its module name
|
|
2602
|
-
const oDesigntimeInfo = collectDesigntimeInfo(
|
|
2760
|
+
const oDesigntimeInfo = collectDesigntimeInfo(nodeArgument);
|
|
2603
2761
|
if ( oDesigntimeInfo ) {
|
|
2604
2762
|
designtimeInfos[currentModule.module] = oDesigntimeInfo;
|
|
2605
2763
|
info(`collected designtime info ${currentModule.module}`);
|
|
@@ -2629,14 +2787,19 @@ exports.astNodeVisitor = {
|
|
|
2629
2787
|
}
|
|
2630
2788
|
});
|
|
2631
2789
|
|
|
2632
|
-
} else if (
|
|
2790
|
+
} else if ( isReturningNode(node)
|
|
2791
|
+
&& isExtendCall(resolvePotentialWrapperExpression(node).argument || node.body) ) {
|
|
2792
|
+
|
|
2793
|
+
const nodeArgument = isArrowFuncExpression(node)
|
|
2794
|
+
? node.body
|
|
2795
|
+
: resolvePotentialWrapperExpression(node).argument;
|
|
2633
2796
|
|
|
2634
2797
|
// return Something.extend(...)
|
|
2635
2798
|
|
|
2636
|
-
const className =
|
|
2637
|
-
const comment = getLeadingCommentNode(node, className) || getLeadingCommentNode(
|
|
2799
|
+
const className = convertValue(nodeArgument.arguments[0]);
|
|
2800
|
+
const comment = getLeadingCommentNode(node, className) || getLeadingCommentNode(nodeArgument, className);
|
|
2638
2801
|
// console.log(`ast node with comment ${comment}`);
|
|
2639
|
-
processExtendCall(
|
|
2802
|
+
processExtendCall(nodeArgument, comment, true);
|
|
2640
2803
|
} else if ( node.type === Syntax.ExpressionStatement && node.expression.type === Syntax.AssignmentExpression ) {
|
|
2641
2804
|
|
|
2642
2805
|
if ( isCreateDataTypeCall(node.expression.right) ) {
|
|
@@ -2677,3 +2840,132 @@ exports.astNodeVisitor = {
|
|
|
2677
2840
|
}
|
|
2678
2841
|
|
|
2679
2842
|
};
|
|
2843
|
+
|
|
2844
|
+
(function() {
|
|
2845
|
+
const jsdocType = require("jsdoc/lib/jsdoc/tag/type");
|
|
2846
|
+
const catharsis = require('catharsis');
|
|
2847
|
+
const TYPES = catharsis.Types;
|
|
2848
|
+
|
|
2849
|
+
const toTypeString = (type) => getTypeStrings(type).join("|");
|
|
2850
|
+
|
|
2851
|
+
/*
|
|
2852
|
+
* This function has been copied from jsdoc/lib/jsdoc/tag/type (version 3.6.7)
|
|
2853
|
+
* The copy has been enhanced with the changes from https://github.com/jsdoc/jsdoc/pull/1735
|
|
2854
|
+
* to retain the full function signature for function types and with a further change
|
|
2855
|
+
* to retain the full record type structure.
|
|
2856
|
+
*
|
|
2857
|
+
* JSDoc is copyright (c) 2011-present Michael Mathews micmath@gmail.com and the contributors to JSDoc.
|
|
2858
|
+
*/
|
|
2859
|
+
function getTypeStrings(parsedType, isOutermostType) {
|
|
2860
|
+
let applications;
|
|
2861
|
+
let typeString;
|
|
2862
|
+
let types = [];
|
|
2863
|
+
switch (parsedType.type) {
|
|
2864
|
+
case TYPES.AllLiteral:
|
|
2865
|
+
types.push('*');
|
|
2866
|
+
break;
|
|
2867
|
+
case TYPES.FunctionType:
|
|
2868
|
+
typeString = 'function';
|
|
2869
|
+
// #### BEGIN: MODIFIED BY SAP
|
|
2870
|
+
const paramTypes = [];
|
|
2871
|
+
if (parsedType.new) {
|
|
2872
|
+
paramTypes.push(toTypeString(parsedType.new));
|
|
2873
|
+
}
|
|
2874
|
+
if (Array.isArray(parsedType.params)) {
|
|
2875
|
+
paramTypes.push(...parsedType.params.map(toTypeString));
|
|
2876
|
+
}
|
|
2877
|
+
if (paramTypes.length || parsedType.result) {
|
|
2878
|
+
typeString += `(${paramTypes.join(", ")})`;
|
|
2879
|
+
}
|
|
2880
|
+
if (parsedType.result) {
|
|
2881
|
+
typeString += `:${toTypeString(parsedType.result)}`;
|
|
2882
|
+
}
|
|
2883
|
+
types.push(typeString);
|
|
2884
|
+
// #### END: MODIFIED BY SAP
|
|
2885
|
+
break;
|
|
2886
|
+
case TYPES.NameExpression:
|
|
2887
|
+
types.push(parsedType.name);
|
|
2888
|
+
break;
|
|
2889
|
+
case TYPES.NullLiteral:
|
|
2890
|
+
types.push('null');
|
|
2891
|
+
break;
|
|
2892
|
+
case TYPES.RecordType:
|
|
2893
|
+
// #### BEGIN: MODIFIED BY SAP
|
|
2894
|
+
// types.push('Object');
|
|
2895
|
+
if (Array.isArray(parsedType.fields)) {
|
|
2896
|
+
typeString = `{${parsedType.fields.map(
|
|
2897
|
+
({key,value}) => {
|
|
2898
|
+
const keyString = catharsis.stringify(key);
|
|
2899
|
+
if (value) {
|
|
2900
|
+
var propertyPlusType = `${keyString}: ${toTypeString(value)}`;
|
|
2901
|
+
return propertyPlusType;
|
|
2902
|
+
} else {
|
|
2903
|
+
let pos;
|
|
2904
|
+
if (keyString && (pos = keyString.indexOf(":")) > -1) {
|
|
2905
|
+
// When no space is present between colon and type (e.g. the structure looks like "{x:number}" with no space after
|
|
2906
|
+
// the colon), then Catharsis parses this as property name "x:number" with no type given.
|
|
2907
|
+
// In this case give a clear hint that this space is needed and throw an error to prevent such issues from being merged
|
|
2908
|
+
const realName = keyString.substring(0, pos);
|
|
2909
|
+
const realValue = keyString.substring(pos + 1, keyString.length);
|
|
2910
|
+
let message = `Cannot parse the "${keyString}" part of "${parsedType.typeExpression}" in RecordType (log output above may give a hint in which file).\n`;
|
|
2911
|
+
message += `Did you mean to specify a property "${realName}" of type "${realValue}"? Then insert a space after the colon and write "${realName}: ${realValue}".`
|
|
2912
|
+
error(message);
|
|
2913
|
+
return "x: any"; // unparseable property set to "any" - but the JSDoc run will fail now, anyway
|
|
2914
|
+
} else {
|
|
2915
|
+
// only property given without type; this will be turned into type "any" further downstream
|
|
2916
|
+
return keyString;
|
|
2917
|
+
}
|
|
2918
|
+
}
|
|
2919
|
+
}
|
|
2920
|
+
).join(', ')}}`;
|
|
2921
|
+
types.push(typeString);
|
|
2922
|
+
} else {
|
|
2923
|
+
types.push('Object');
|
|
2924
|
+
}
|
|
2925
|
+
// #### END: MODIFIED BY SAP
|
|
2926
|
+
break;
|
|
2927
|
+
case TYPES.TypeApplication:
|
|
2928
|
+
// if this is the outermost type, we strip the modifiers; otherwise, we keep them
|
|
2929
|
+
if (isOutermostType) {
|
|
2930
|
+
applications = parsedType.applications.map(application =>
|
|
2931
|
+
catharsis.stringify(application)).join(', ');
|
|
2932
|
+
typeString = `${getTypeStrings(parsedType.expression)[0]}.<${applications}>`;
|
|
2933
|
+
types.push(typeString);
|
|
2934
|
+
}
|
|
2935
|
+
else {
|
|
2936
|
+
types.push( catharsis.stringify(parsedType) );
|
|
2937
|
+
}
|
|
2938
|
+
break;
|
|
2939
|
+
case TYPES.TypeUnion:
|
|
2940
|
+
parsedType.elements.forEach(element => {
|
|
2941
|
+
types = types.concat( getTypeStrings(element) );
|
|
2942
|
+
});
|
|
2943
|
+
break;
|
|
2944
|
+
case TYPES.UndefinedLiteral:
|
|
2945
|
+
types.push('undefined');
|
|
2946
|
+
break;
|
|
2947
|
+
case TYPES.UnknownLiteral:
|
|
2948
|
+
types.push('?');
|
|
2949
|
+
break;
|
|
2950
|
+
default:
|
|
2951
|
+
// this shouldn't happen
|
|
2952
|
+
throw new Error(`unrecognized type ${parsedType.type} in parsed type: ${parsedType}`);
|
|
2953
|
+
}
|
|
2954
|
+
return types;
|
|
2955
|
+
}
|
|
2956
|
+
|
|
2957
|
+
const origParse = jsdocType.parse;
|
|
2958
|
+
jsdocType.parse = function() {
|
|
2959
|
+
const tagInfo = origParse.apply(this, arguments);
|
|
2960
|
+
// #### BEGIN: MODIFIED BY SAP
|
|
2961
|
+
if ( tagInfo && (/function/.test(tagInfo.typeExpression) || /\{.*\}/.test(tagInfo.typeExpression)) && tagInfo.parsedType ) {
|
|
2962
|
+
// #### END: MODIFIED BY SAP
|
|
2963
|
+
// console.info("old typeExpression", tagInfo.typeExpression);
|
|
2964
|
+
// console.info("old parse tree", tagInfo.parsedType);
|
|
2965
|
+
// console.info("old parse result", tagInfo.type);
|
|
2966
|
+
tagInfo.type = getTypeStrings(tagInfo.parsedType);
|
|
2967
|
+
// console.info("new parse result", tagInfo.type);
|
|
2968
|
+
}
|
|
2969
|
+
return tagInfo;
|
|
2970
|
+
}
|
|
2971
|
+
}());
|