@ui5/builder 3.0.0-alpha.9 → 3.0.0-beta.2
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/.reuse/dep5 +2 -2
- package/CHANGELOG.md +59 -1
- package/CONTRIBUTING.md +1 -1
- package/README.md +4 -4
- package/jsdoc.json +2 -2
- package/lib/lbt/UI5ClientConstants.js +7 -8
- package/lib/lbt/analyzer/ComponentAnalyzer.js +60 -22
- package/lib/lbt/analyzer/FioriElementsAnalyzer.js +31 -20
- package/lib/lbt/analyzer/JSModuleAnalyzer.js +119 -77
- package/lib/lbt/analyzer/SmartTemplateAnalyzer.js +31 -20
- package/lib/lbt/analyzer/XMLCompositeAnalyzer.js +35 -25
- package/lib/lbt/analyzer/XMLTemplateAnalyzer.js +71 -18
- package/lib/lbt/analyzer/analyzeLibraryJS.js +22 -6
- package/lib/lbt/bundle/AutoSplitter.js +10 -11
- package/lib/lbt/bundle/Builder.js +33 -36
- package/lib/lbt/bundle/BundleDefinition.js +1 -5
- package/lib/lbt/bundle/BundleWriter.js +1 -2
- package/lib/lbt/bundle/ResolvedBundleDefinition.js +6 -7
- package/lib/lbt/bundle/Resolver.js +11 -12
- package/lib/lbt/calls/SapUiDefine.js +16 -11
- package/lib/lbt/graph/dependencyGraph.js +3 -4
- package/lib/lbt/graph/dominatorTree.js +3 -3
- package/lib/lbt/graph/topologicalSort.js +3 -3
- package/lib/lbt/resources/LibraryFileAnalyzer.js +6 -9
- package/lib/lbt/resources/LocatorResource.js +2 -2
- package/lib/lbt/resources/LocatorResourcePool.js +3 -3
- package/lib/lbt/resources/ModuleInfo.js +2 -3
- package/lib/lbt/resources/Resource.js +3 -4
- package/lib/lbt/resources/ResourceCollector.js +8 -9
- package/lib/lbt/resources/ResourceFilterList.js +38 -40
- package/lib/lbt/resources/ResourceInfo.js +1 -1
- package/lib/lbt/resources/ResourceInfoList.js +5 -3
- package/lib/lbt/resources/ResourcePool.js +15 -21
- package/lib/lbt/utils/ASTUtils.js +60 -44
- package/lib/lbt/utils/JSTokenizer.js +4 -4
- package/lib/lbt/utils/ModuleName.js +10 -20
- package/lib/lbt/utils/escapePropertiesFile.js +4 -4
- package/lib/lbt/utils/parseUtils.js +5 -11
- package/lib/processors/bootstrapHtmlTransformer.js +15 -7
- package/lib/processors/bundlers/flexChangesBundler.js +16 -8
- package/lib/processors/bundlers/moduleBundler.js +26 -15
- package/lib/processors/jsdoc/apiIndexGenerator.js +16 -9
- package/lib/processors/jsdoc/jsdocGenerator.js +37 -25
- package/lib/processors/jsdoc/lib/{createIndexFiles.js → createIndexFiles.cjs} +0 -0
- package/lib/processors/jsdoc/lib/{transformApiJson.js → transformApiJson.cjs} +59 -2
- package/lib/processors/jsdoc/lib/ui5/{plugin.js → plugin.cjs} +310 -119
- package/lib/processors/jsdoc/lib/ui5/template/{publish.js → publish.cjs} +6 -2
- package/lib/processors/jsdoc/lib/ui5/template/utils/{versionUtil.js → versionUtil.cjs} +0 -0
- package/lib/processors/jsdoc/sdkTransformer.js +18 -11
- package/lib/processors/libraryLessGenerator.js +28 -16
- package/lib/processors/manifestCreator.js +15 -14
- package/lib/processors/minifier.js +22 -16
- package/lib/processors/nonAsciiEscaper.js +17 -7
- package/lib/processors/resourceListCreator.js +13 -13
- package/lib/processors/stringReplacer.js +13 -6
- package/lib/processors/themeBuilder.js +33 -24
- package/lib/processors/versionInfoGenerator.js +40 -30
- package/lib/tasks/buildThemes.js +18 -11
- package/lib/tasks/bundlers/generateBundle.js +23 -12
- package/lib/tasks/bundlers/generateComponentPreload.js +23 -12
- package/lib/tasks/bundlers/generateFlexChangesBundle.js +16 -8
- package/lib/tasks/bundlers/generateLibraryPreload.js +33 -17
- package/lib/tasks/bundlers/generateStandaloneAppBundle.js +21 -13
- package/lib/tasks/bundlers/utils/createModuleNameMapping.js +7 -7
- package/lib/tasks/escapeNonAsciiCharacters.js +12 -5
- package/lib/tasks/generateCachebusterInfo.js +17 -9
- package/lib/tasks/generateLibraryManifest.js +14 -8
- package/lib/tasks/generateResourcesJson.js +15 -9
- package/lib/tasks/generateThemeDesignerResources.js +19 -9
- package/lib/tasks/generateVersionInfo.js +12 -5
- package/lib/tasks/jsdoc/executeJsdocSdkTransformation.js +17 -9
- package/lib/tasks/jsdoc/generateApiIndex.js +16 -10
- package/lib/tasks/jsdoc/generateJsdoc.js +131 -119
- package/lib/tasks/minify.js +13 -6
- package/lib/tasks/replaceBuildtime.js +12 -5
- package/lib/tasks/replaceCopyright.js +12 -5
- package/lib/tasks/replaceVersion.js +12 -5
- package/lib/tasks/taskRepository.js +24 -30
- package/lib/tasks/transformBootstrapHtml.js +6 -5
- package/package.json +44 -31
- package/index.js +0 -173
- package/lib/processors/bundlers/manifestBundler.js +0 -172
- package/lib/tasks/bundlers/generateManifestBundle.js +0 -49
|
@@ -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,16 +288,19 @@ 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);
|
|
@@ -297,11 +312,9 @@ function collectShortcuts(body) {
|
|
|
297
312
|
debug(` found local shortcut: ${name} ${currentModule.localNames[name]}`);
|
|
298
313
|
}
|
|
299
314
|
} else if ( isRequireSyncCall(valueNode) || isProbingRequireCall(valueNode) ) {
|
|
300
|
-
if ( valueNode.arguments[0]
|
|
301
|
-
&& valueNode.arguments[0].type === Syntax.Literal
|
|
302
|
-
&& typeof valueNode.arguments[0].value === 'string' ) {
|
|
315
|
+
if ( valueNode.arguments[0] && isStringLiteral(valueNode.arguments[0]) ) {
|
|
303
316
|
currentModule.localNames[name] = {
|
|
304
|
-
module: valueNode.arguments[0]
|
|
317
|
+
module: convertValue(valueNode.arguments[0])
|
|
305
318
|
// no (or empty) path
|
|
306
319
|
};
|
|
307
320
|
debug(` found local import: ${name} = ${valueNode.callee.property.name}('${valueNode.arguments[0].value}')`);
|
|
@@ -315,8 +328,8 @@ function collectShortcuts(body) {
|
|
|
315
328
|
}
|
|
316
329
|
}
|
|
317
330
|
|
|
318
|
-
if ( body.type === Syntax.BlockStatement ) {
|
|
319
|
-
|
|
331
|
+
if ( body.type === Syntax.BlockStatement || isArrowFuncExpression(factory) ) {
|
|
332
|
+
const itemsResolver = function ( stmt ) {
|
|
320
333
|
// console.log(stmt);
|
|
321
334
|
if ( stmt.type === Syntax.FunctionDeclaration ) {
|
|
322
335
|
if ( stmt.id && stmt.id.type === Syntax.Identifier && stmt.loc && stmt.loc.start ) {
|
|
@@ -336,15 +349,28 @@ function collectShortcuts(body) {
|
|
|
336
349
|
&& stmt.expression.type === Syntax.AssignmentExpression
|
|
337
350
|
&& stmt.expression.left.type === Syntax.Identifier ) {
|
|
338
351
|
checkAssignment(stmt.expression.left.name, stmt.expression.right);
|
|
339
|
-
} else if ( stmt
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
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]);
|
|
345
365
|
}
|
|
346
366
|
}
|
|
347
|
-
}
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
if (isArrowFuncExpression(factory)) {
|
|
370
|
+
itemsResolver(factory);
|
|
371
|
+
} else {
|
|
372
|
+
body.body.forEach(itemsResolver);
|
|
373
|
+
}
|
|
348
374
|
}
|
|
349
375
|
|
|
350
376
|
if ( currentModule.defaultExport && currentModule.localNames[currentModule.defaultExport] ) {
|
|
@@ -369,12 +395,12 @@ function guessSingularName(sPluralName) {
|
|
|
369
395
|
}
|
|
370
396
|
|
|
371
397
|
function getPropertyKey(prop) {
|
|
372
|
-
if ( prop.
|
|
398
|
+
if ( prop.type === Syntax.SpreadElement ) {
|
|
399
|
+
return;
|
|
400
|
+
} else if ( prop.key.type === Syntax.Identifier && prop.computed !== true ) {
|
|
373
401
|
return prop.key.name;
|
|
374
402
|
} else if ( prop.key.type === Syntax.Literal ) {
|
|
375
403
|
return String(prop.key.value);
|
|
376
|
-
} else {
|
|
377
|
-
return prop.key.toSource();
|
|
378
404
|
}
|
|
379
405
|
}
|
|
380
406
|
|
|
@@ -432,80 +458,181 @@ function createPropertyMap(node, defaultKey) {
|
|
|
432
458
|
return result;
|
|
433
459
|
}
|
|
434
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 &&
|
|
511
|
+
node.type === Syntax.TemplateLiteral &&
|
|
512
|
+
node.expressions && node.expressions.length === 0 &&
|
|
513
|
+
node.quasis && node.quasis.length === 1
|
|
514
|
+
);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Checks whether a node is Literal or TemplateLiteral without an expression
|
|
519
|
+
*
|
|
520
|
+
* @param {Node} node
|
|
521
|
+
* @returns {String}
|
|
522
|
+
*/
|
|
523
|
+
function isStringLiteral(node) {
|
|
524
|
+
return (
|
|
525
|
+
(node && node.type === Syntax.Literal && typeof node.value === "string")
|
|
526
|
+
|| isTemplateLiteralWithoutExpression(node)
|
|
527
|
+
);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
function isMemberExpression(node) {
|
|
531
|
+
return node && [Syntax.MemberExpression, Syntax.OptionalMemberExpression].includes(node.type);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
function isCaleeMemberExpression(node) {
|
|
535
|
+
return (
|
|
536
|
+
node &&
|
|
537
|
+
[Syntax.CallExpression, Syntax.OptionalCallExpression].includes(node.type) &&
|
|
538
|
+
isMemberExpression(node.callee)
|
|
539
|
+
);
|
|
540
|
+
}
|
|
541
|
+
|
|
435
542
|
function isExtendCall(node) {
|
|
543
|
+
node = stripChainWrappers(node);
|
|
436
544
|
|
|
437
545
|
return (
|
|
438
546
|
node
|
|
439
|
-
&& node
|
|
440
|
-
&& node
|
|
441
|
-
&& node
|
|
442
|
-
&& node.callee.property.name === 'extend'
|
|
547
|
+
&& isCaleeMemberExpression(node)
|
|
548
|
+
&& stripChainWrappers(node, "callee.property").type === Syntax.Identifier
|
|
549
|
+
&& stripChainWrappers(node, "callee.property").name === 'extend'
|
|
443
550
|
&& node.arguments.length >= 2
|
|
444
|
-
&& node.arguments[0]
|
|
445
|
-
&& typeof node.arguments[0].value === "string"
|
|
551
|
+
&& isStringLiteral(node.arguments[0])
|
|
446
552
|
&& node.arguments[1].type === Syntax.ObjectExpression
|
|
447
553
|
);
|
|
448
554
|
|
|
449
555
|
}
|
|
450
556
|
|
|
557
|
+
function isArrowFuncExpression(node) {
|
|
558
|
+
return (
|
|
559
|
+
node &&
|
|
560
|
+
node.type === Syntax.ArrowFunctionExpression &&
|
|
561
|
+
node.expression === true
|
|
562
|
+
);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Checks whether the node is of a "returning" type
|
|
567
|
+
*
|
|
568
|
+
* @param {Node} node
|
|
569
|
+
* @returns {Boolean}
|
|
570
|
+
*/
|
|
571
|
+
function isReturningNode(node) {
|
|
572
|
+
return (node && node.type === Syntax.ReturnStatement)
|
|
573
|
+
|| (node && node.type === Syntax.ExpressionStatement && node.expression.type === Syntax.YieldExpression)
|
|
574
|
+
|| isArrowFuncExpression(node);
|
|
575
|
+
}
|
|
576
|
+
|
|
451
577
|
function isSapUiDefineCall(node) {
|
|
452
578
|
|
|
453
579
|
return (
|
|
454
|
-
node
|
|
455
|
-
&& node
|
|
456
|
-
&& node
|
|
457
|
-
&& node
|
|
458
|
-
&& node
|
|
459
|
-
&& node
|
|
460
|
-
&& node
|
|
461
|
-
&& node
|
|
462
|
-
&& node
|
|
463
|
-
&& node.callee.property.name === 'define'
|
|
580
|
+
stripChainWrappers(node)
|
|
581
|
+
&& isCaleeMemberExpression(stripChainWrappers(node))
|
|
582
|
+
&& isMemberExpression(stripChainWrappers(node, "callee.object"))
|
|
583
|
+
&& stripChainWrappers(node, "callee.property").type === Syntax.Identifier
|
|
584
|
+
&& stripChainWrappers(node, "callee.property").name === 'define'
|
|
585
|
+
&& stripChainWrappers(node, "callee.object.object").type === Syntax.Identifier
|
|
586
|
+
&& stripChainWrappers(node, "callee.object.object").name === 'sap'
|
|
587
|
+
&& stripChainWrappers(node, "callee.object.property").type === Syntax.Identifier
|
|
588
|
+
&& stripChainWrappers(node, "callee.object.property").name === 'ui'
|
|
464
589
|
);
|
|
465
590
|
|
|
466
591
|
}
|
|
467
592
|
|
|
468
593
|
function isCreateDataTypeCall(node) {
|
|
594
|
+
node = stripChainWrappers(node);
|
|
595
|
+
|
|
469
596
|
return (
|
|
470
597
|
node
|
|
471
|
-
&& node
|
|
472
|
-
&& node
|
|
473
|
-
&&
|
|
474
|
-
&& node
|
|
475
|
-
&& node.callee.property.name === 'createType'
|
|
598
|
+
&& isCaleeMemberExpression(node)
|
|
599
|
+
&& getResolvedObjectName(stripChainWrappers(node, "callee.object")) === "sap.ui.base.DataType"
|
|
600
|
+
&& stripChainWrappers(node, "callee.property").type === Syntax.Identifier
|
|
601
|
+
&& stripChainWrappers(node, "callee.property").name === 'createType'
|
|
476
602
|
);
|
|
477
603
|
}
|
|
478
604
|
|
|
479
605
|
function isRequireSyncCall(node) {
|
|
606
|
+
node = stripChainWrappers(node);
|
|
607
|
+
|
|
480
608
|
return (
|
|
481
609
|
node
|
|
482
|
-
&& node
|
|
483
|
-
&& node
|
|
484
|
-
&& node
|
|
485
|
-
&& node
|
|
486
|
-
&& node
|
|
487
|
-
&& node
|
|
488
|
-
&& node
|
|
489
|
-
&& node
|
|
490
|
-
&& node.callee.property.name === 'requireSync'
|
|
610
|
+
&& isCaleeMemberExpression(node)
|
|
611
|
+
&& isMemberExpression( stripChainWrappers(node, "callee.object") )
|
|
612
|
+
&& stripChainWrappers(node, "callee.object.object").type === Syntax.Identifier
|
|
613
|
+
&& stripChainWrappers(node, "callee.object.object").name === 'sap'
|
|
614
|
+
&& stripChainWrappers(node, "callee.object.property").type === Syntax.Identifier
|
|
615
|
+
&& stripChainWrappers(node, "callee.object.property").name === 'ui'
|
|
616
|
+
&& stripChainWrappers(node, "callee.property").type === Syntax.Identifier
|
|
617
|
+
&& stripChainWrappers(node, "callee.property").name === 'requireSync'
|
|
491
618
|
);
|
|
492
619
|
}
|
|
493
620
|
|
|
494
621
|
function isProbingRequireCall(node) {
|
|
622
|
+
node = stripChainWrappers(node);
|
|
623
|
+
|
|
495
624
|
return (
|
|
496
625
|
node
|
|
497
|
-
&& node
|
|
498
|
-
&& node
|
|
499
|
-
&& node
|
|
500
|
-
&& node
|
|
501
|
-
&& node
|
|
502
|
-
&& node
|
|
503
|
-
&& node
|
|
504
|
-
&& node
|
|
505
|
-
&& node.callee.property.name === 'require'
|
|
626
|
+
&& isCaleeMemberExpression(node)
|
|
627
|
+
&& isMemberExpression( stripChainWrappers(node, "callee.object") )
|
|
628
|
+
&& stripChainWrappers(node, "callee.object.object").type === Syntax.Identifier
|
|
629
|
+
&& stripChainWrappers(node, "callee.object.object").name === 'sap'
|
|
630
|
+
&& stripChainWrappers(node, "callee.object.property").type === Syntax.Identifier
|
|
631
|
+
&& stripChainWrappers(node, "callee.object.property").name === 'ui'
|
|
632
|
+
&& stripChainWrappers(node, "callee.property").type === Syntax.Identifier
|
|
633
|
+
&& stripChainWrappers(node, "callee.property").name === 'require'
|
|
506
634
|
&& node.arguments.length === 1
|
|
507
|
-
&& node.arguments[0]
|
|
508
|
-
&& typeof node.arguments[0].value === 'string' // TODO generalize to statically analyzable constants
|
|
635
|
+
&& isStringLiteral(node.arguments[0])
|
|
509
636
|
);
|
|
510
637
|
}
|
|
511
638
|
|
|
@@ -521,7 +648,7 @@ function isCompileTimeConstant(node) {
|
|
|
521
648
|
}
|
|
522
649
|
|
|
523
650
|
function getObjectName(node) {
|
|
524
|
-
if ( node
|
|
651
|
+
if ( isMemberExpression(node) && !node.computed && node.property.type === Syntax.Identifier ) {
|
|
525
652
|
const prefix = getObjectName(node.object);
|
|
526
653
|
return prefix ? prefix + "." + node.property.name : null;
|
|
527
654
|
} else if ( node.type === Syntax.Identifier ) {
|
|
@@ -536,7 +663,7 @@ function getObjectName(node) {
|
|
|
536
663
|
* returns the leftmost identifier a
|
|
537
664
|
*/
|
|
538
665
|
function getLeftmostName(node) {
|
|
539
|
-
while ( node
|
|
666
|
+
while ( isMemberExpression(node) ) {
|
|
540
667
|
node = node.object;
|
|
541
668
|
}
|
|
542
669
|
if ( node.type === Syntax.Identifier ) {
|
|
@@ -604,7 +731,7 @@ function convertValueWithRaw(node, type, propertyName) {
|
|
|
604
731
|
raw: node.operator + node.argument.raw
|
|
605
732
|
};
|
|
606
733
|
|
|
607
|
-
} else if ( node
|
|
734
|
+
} else if ( isMemberExpression(node) && type ) {
|
|
608
735
|
|
|
609
736
|
// enum value (a.b.c)
|
|
610
737
|
value = getResolvedObjectName(node);
|
|
@@ -674,6 +801,13 @@ function convertValueWithRaw(node, type, propertyName) {
|
|
|
674
801
|
};
|
|
675
802
|
}
|
|
676
803
|
|
|
804
|
+
} else if ( isTemplateLiteralWithoutExpression(node) ) {
|
|
805
|
+
let value = node.quasis[0].value || {};
|
|
806
|
+
|
|
807
|
+
return {
|
|
808
|
+
value: value.cooked,
|
|
809
|
+
raw: value.raw,
|
|
810
|
+
};
|
|
677
811
|
}
|
|
678
812
|
|
|
679
813
|
value = "...see text or source";
|
|
@@ -697,10 +831,10 @@ function convertStringArray(node) {
|
|
|
697
831
|
}
|
|
698
832
|
const result = [];
|
|
699
833
|
for ( let i = 0; i < node.elements.length; i++ ) {
|
|
700
|
-
if ( node.elements[i]
|
|
834
|
+
if ( !isStringLiteral(node.elements[i]) ) {
|
|
701
835
|
throw new Error("not a string literal");
|
|
702
836
|
}
|
|
703
|
-
result.push(node.elements[i]
|
|
837
|
+
result.push( convertValue(node.elements[i]) );
|
|
704
838
|
}
|
|
705
839
|
// console.log(result);
|
|
706
840
|
return result;
|
|
@@ -736,7 +870,7 @@ function collectClassInfo(extendCall, classDoclet) {
|
|
|
736
870
|
if ( classDoclet && classDoclet.augments && classDoclet.augments.length === 1 ) {
|
|
737
871
|
baseType = classDoclet.augments[0];
|
|
738
872
|
}
|
|
739
|
-
if ( extendCall.callee
|
|
873
|
+
if ( isMemberExpression(extendCall.callee) ) {
|
|
740
874
|
const baseCandidate = getResolvedObjectName(extendCall.callee.object);
|
|
741
875
|
if ( baseCandidate && baseType == null ) {
|
|
742
876
|
baseType = baseCandidate;
|
|
@@ -746,7 +880,7 @@ function collectClassInfo(extendCall, classDoclet) {
|
|
|
746
880
|
}
|
|
747
881
|
|
|
748
882
|
const oClassInfo = {
|
|
749
|
-
name : extendCall.arguments[0]
|
|
883
|
+
name : convertValue(extendCall.arguments[0]),
|
|
750
884
|
baseType : baseType,
|
|
751
885
|
interfaces : [],
|
|
752
886
|
doc : classDoclet && classDoclet.description,
|
|
@@ -988,7 +1122,7 @@ function collectClassInfo(extendCall, classDoclet) {
|
|
|
988
1122
|
return oClassInfo;
|
|
989
1123
|
}
|
|
990
1124
|
|
|
991
|
-
function collectDesigntimeInfo(
|
|
1125
|
+
function collectDesigntimeInfo(dtNodeArgument) {
|
|
992
1126
|
|
|
993
1127
|
function each(node, defaultKey, callback) {
|
|
994
1128
|
const map = node && createPropertyMap(node.value);
|
|
@@ -1010,7 +1144,7 @@ function collectDesigntimeInfo(dtNode) {
|
|
|
1010
1144
|
|
|
1011
1145
|
let oDesigntimeInfo;
|
|
1012
1146
|
|
|
1013
|
-
const map = createPropertyMap(
|
|
1147
|
+
const map = createPropertyMap(dtNodeArgument);
|
|
1014
1148
|
|
|
1015
1149
|
if (map.annotations) {
|
|
1016
1150
|
|
|
@@ -1095,12 +1229,19 @@ function determineValueRangeBorder(range, expression, varname, inverse) {
|
|
|
1095
1229
|
function determineValueRange(expression, varname, inverse) {
|
|
1096
1230
|
const range = {};
|
|
1097
1231
|
if ( expression.type === Syntax.LogicalExpression
|
|
1098
|
-
&& expression.operator === '&&'
|
|
1099
1232
|
&& expression.left.type === Syntax.BinaryExpression
|
|
1100
|
-
&& expression.right.type === Syntax.BinaryExpression
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1233
|
+
&& expression.right.type === Syntax.BinaryExpression ) {
|
|
1234
|
+
|
|
1235
|
+
if ( expression.operator === "&&"
|
|
1236
|
+
&& determineValueRangeBorder(range, expression.left, varname, inverse)
|
|
1237
|
+
&& determineValueRangeBorder(range, expression.right, varname, inverse) ) {
|
|
1238
|
+
return range;
|
|
1239
|
+
} else if ( ["||", "??"].includes(expression.operator)
|
|
1240
|
+
&& ( determineValueRangeBorder(range, expression.left, varname, inverse)
|
|
1241
|
+
|| determineValueRangeBorder(range, expression.right, varname, inverse) )) {
|
|
1242
|
+
return range;
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1104
1245
|
} else if ( expression.type === Syntax.BinaryExpression
|
|
1105
1246
|
&& determineValueRangeBorder(range, expression, varname, inverse) ) {
|
|
1106
1247
|
return range;
|
|
@@ -1113,24 +1254,24 @@ function collectDataTypeInfo(extendCall, classDoclet) {
|
|
|
1113
1254
|
let i = 0,
|
|
1114
1255
|
name, def, base, pattern, range;
|
|
1115
1256
|
|
|
1116
|
-
if ( i < args.length && args[i]
|
|
1117
|
-
name = args[i++]
|
|
1257
|
+
if ( i < args.length && isStringLiteral(args[i]) ) {
|
|
1258
|
+
name = convertValue(args[i++]);
|
|
1118
1259
|
}
|
|
1119
1260
|
if ( i < args.length && args[i].type === Syntax.ObjectExpression ) {
|
|
1120
1261
|
def = createPropertyMap(args[i++]);
|
|
1121
1262
|
}
|
|
1122
1263
|
if ( i < args.length ) {
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
&&
|
|
1129
|
-
&&
|
|
1130
|
-
&&
|
|
1131
|
-
&&
|
|
1132
|
-
&&
|
|
1133
|
-
base = args[i++].arguments[0]
|
|
1264
|
+
const node = resolvePotentialWrapperExpression(args[i]);
|
|
1265
|
+
|
|
1266
|
+
if ( isStringLiteral(args[i]) ) {
|
|
1267
|
+
base = convertValue(args[i++]);
|
|
1268
|
+
} else if ( isCaleeMemberExpression(node)
|
|
1269
|
+
&& getResolvedObjectName(node.callee.object) === "sap.ui.base.DataType"
|
|
1270
|
+
&& node.callee.property.type === Syntax.Identifier
|
|
1271
|
+
&& node.callee.property.name === 'getType'
|
|
1272
|
+
&& node.arguments.length === 1
|
|
1273
|
+
&& isStringLiteral(node.arguments[0]) ) {
|
|
1274
|
+
base = convertValue(args[i++].arguments[0]);
|
|
1134
1275
|
} else {
|
|
1135
1276
|
future(`could not identify base type of data type '${name}'`);
|
|
1136
1277
|
}
|
|
@@ -1138,25 +1279,31 @@ function collectDataTypeInfo(extendCall, classDoclet) {
|
|
|
1138
1279
|
base = "any";
|
|
1139
1280
|
}
|
|
1140
1281
|
|
|
1282
|
+
const isArrowExpression = isArrowFuncExpression(def && def.isValid && def.isValid.value);
|
|
1283
|
+
|
|
1141
1284
|
if ( def
|
|
1142
1285
|
&& def.isValid
|
|
1143
|
-
&& def.isValid.value.type
|
|
1286
|
+
&& [Syntax.FunctionExpression, Syntax.ArrowFunctionExpression].includes(def.isValid.value.type)
|
|
1144
1287
|
&& def.isValid.value.params.length === 1
|
|
1145
1288
|
&& def.isValid.value.params[0].type === Syntax.Identifier
|
|
1146
|
-
&& def.isValid.value.body.body.length === 1 ) {
|
|
1289
|
+
&& (isArrowExpression || def.isValid.value.body.body.length === 1) ) {
|
|
1290
|
+
|
|
1147
1291
|
const varname = def.isValid.value.params[0].name;
|
|
1148
|
-
const stmt = def.isValid.value.body.body[0];
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
&&
|
|
1156
|
-
|
|
1292
|
+
const stmt = isArrowExpression ? def.isValid.value.body : def.isValid.value.body.body[0];
|
|
1293
|
+
|
|
1294
|
+
if ( isReturningNode(stmt) || isArrowExpression ) {
|
|
1295
|
+
const stmtArgument = resolvePotentialWrapperExpression(
|
|
1296
|
+
isArrowExpression ? stmt : stmt.argument
|
|
1297
|
+
);
|
|
1298
|
+
if ( isCaleeMemberExpression(stmtArgument)
|
|
1299
|
+
&& stmtArgument.callee.object.type === Syntax.Literal
|
|
1300
|
+
&& stmtArgument.callee.object.regex
|
|
1301
|
+
&& stmtArgument.callee.property.type === Syntax.Identifier
|
|
1302
|
+
&& stmtArgument.callee.property.name === 'test' ) {
|
|
1303
|
+
pattern = stmtArgument.callee.object.regex.pattern;
|
|
1157
1304
|
// console.log(pattern);
|
|
1158
1305
|
} else {
|
|
1159
|
-
range = determineValueRange(
|
|
1306
|
+
range = determineValueRange(stmtArgument, varname, false);
|
|
1160
1307
|
}
|
|
1161
1308
|
} else if ( stmt.type === Syntax.IfStatement
|
|
1162
1309
|
&& stmt.consequent.type === Syntax.BlockStatement
|
|
@@ -1741,7 +1888,7 @@ function createAutoDoc(oClassInfo, classComment, doclet, node, parser, filename,
|
|
|
1741
1888
|
newJSDoc([
|
|
1742
1889
|
"Removes an " + n1 + " from the association named " + link + ".",
|
|
1743
1890
|
"@param {int | sap.ui.core.ID | " + info.type + "} " + varname(n1, "variant") + " The " + n1 + " to be removed or its index or ID",
|
|
1744
|
-
"@returns {sap.ui.core.ID} The removed " + n1 + " or <code>null</code>",
|
|
1891
|
+
"@returns {sap.ui.core.ID|null} The removed " + n1 + " or <code>null</code>",
|
|
1745
1892
|
info.since ? "@since " + info.since : "",
|
|
1746
1893
|
info.deprecation ? "@deprecated " + info.deprecation : "",
|
|
1747
1894
|
info.experimental ? "@experimental " + info.experimental : "",
|
|
@@ -2351,6 +2498,7 @@ exports.handlers = {
|
|
|
2351
2498
|
e.doclet.meta.__shortpath = getRelativePath(filepath);
|
|
2352
2499
|
_ui5data.resource = currentModule.resource;
|
|
2353
2500
|
_ui5data.module = currentModule.name || currentModule.module;
|
|
2501
|
+
_ui5data.initialLongname = e.doclet.longname;
|
|
2354
2502
|
|
|
2355
2503
|
const localDecl = findLocalDeclaration(e.doclet.meta.lineno, e.doclet.meta.columnno);
|
|
2356
2504
|
if ( localDecl ) {
|
|
@@ -2583,24 +2731,37 @@ exports.astNodeVisitor = {
|
|
|
2583
2731
|
}
|
|
2584
2732
|
}
|
|
2585
2733
|
|
|
2586
|
-
if (
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2734
|
+
if ( [Syntax.ExpressionStatement, Syntax.LogicalExpression].includes(node.type) ) {
|
|
2735
|
+
let nodeToAnalyze;
|
|
2736
|
+
if (isSapUiDefineCall(node.expression)) {
|
|
2737
|
+
nodeToAnalyze = node.expression;
|
|
2738
|
+
|
|
2739
|
+
/*
|
|
2590
2740
|
} else if ( isJQuerySapDeclareCall(node.expression)
|
|
2591
2741
|
&& node.expression.arguments.length > 0
|
|
2592
2742
|
&& node.expression.arguments[0].type === Syntax.Literal
|
|
2593
2743
|
&& typeof node.expression.arguments[0].value === "string" ) {
|
|
2594
2744
|
warning(`module has explicit module name ${node.expression.arguments[0].value}`);
|
|
2595
2745
|
*/
|
|
2746
|
+
} else if (isSapUiDefineCall(node.left)) {
|
|
2747
|
+
nodeToAnalyze = node.left;
|
|
2748
|
+
} else if (isSapUiDefineCall(node.right)) {
|
|
2749
|
+
nodeToAnalyze = node.right;
|
|
2596
2750
|
}
|
|
2597
2751
|
|
|
2752
|
+
nodeToAnalyze && analyzeModuleDefinition(
|
|
2753
|
+
resolvePotentialWrapperExpression(nodeToAnalyze)
|
|
2754
|
+
);
|
|
2598
2755
|
}
|
|
2599
2756
|
|
|
2600
|
-
|
|
2757
|
+
const isArrowExpression = isArrowFuncExpression(node) && node.body.type === Syntax.ObjectExpression;
|
|
2758
|
+
const nodeArgument = isArrowExpression
|
|
2759
|
+
? node.body
|
|
2760
|
+
: resolvePotentialWrapperExpression(node).argument;
|
|
2761
|
+
if (isArrowExpression || (isReturningNode(node) && nodeArgument && nodeArgument.type === Syntax.ObjectExpression) && /\.designtime\.js$/.test(currentSourceName) ) {
|
|
2601
2762
|
|
|
2602
2763
|
// assume this node to return designtime metadata. Collect it and remember it by its module name
|
|
2603
|
-
const oDesigntimeInfo = collectDesigntimeInfo(
|
|
2764
|
+
const oDesigntimeInfo = collectDesigntimeInfo(nodeArgument);
|
|
2604
2765
|
if ( oDesigntimeInfo ) {
|
|
2605
2766
|
designtimeInfos[currentModule.module] = oDesigntimeInfo;
|
|
2606
2767
|
info(`collected designtime info ${currentModule.module}`);
|
|
@@ -2630,14 +2791,19 @@ exports.astNodeVisitor = {
|
|
|
2630
2791
|
}
|
|
2631
2792
|
});
|
|
2632
2793
|
|
|
2633
|
-
} else if (
|
|
2794
|
+
} else if ( isReturningNode(node)
|
|
2795
|
+
&& isExtendCall(resolvePotentialWrapperExpression(node).argument || node.body) ) {
|
|
2796
|
+
|
|
2797
|
+
const nodeArgument = isArrowFuncExpression(node)
|
|
2798
|
+
? node.body
|
|
2799
|
+
: resolvePotentialWrapperExpression(node).argument;
|
|
2634
2800
|
|
|
2635
2801
|
// return Something.extend(...)
|
|
2636
2802
|
|
|
2637
|
-
const className =
|
|
2638
|
-
const comment = getLeadingCommentNode(node, className) || getLeadingCommentNode(
|
|
2803
|
+
const className = convertValue(nodeArgument.arguments[0]);
|
|
2804
|
+
const comment = getLeadingCommentNode(node, className) || getLeadingCommentNode(nodeArgument, className);
|
|
2639
2805
|
// console.log(`ast node with comment ${comment}`);
|
|
2640
|
-
processExtendCall(
|
|
2806
|
+
processExtendCall(nodeArgument, comment, true);
|
|
2641
2807
|
} else if ( node.type === Syntax.ExpressionStatement && node.expression.type === Syntax.AssignmentExpression ) {
|
|
2642
2808
|
|
|
2643
2809
|
if ( isCreateDataTypeCall(node.expression.right) ) {
|
|
@@ -2689,7 +2855,8 @@ exports.astNodeVisitor = {
|
|
|
2689
2855
|
/*
|
|
2690
2856
|
* This function has been copied from jsdoc/lib/jsdoc/tag/type (version 3.6.7)
|
|
2691
2857
|
* The copy has been enhanced with the changes from https://github.com/jsdoc/jsdoc/pull/1735
|
|
2692
|
-
* to retain the full function signature for function types
|
|
2858
|
+
* to retain the full function signature for function types and with a further change
|
|
2859
|
+
* to retain the full record type structure.
|
|
2693
2860
|
*
|
|
2694
2861
|
* JSDoc is copyright (c) 2011-present Michael Mathews micmath@gmail.com and the contributors to JSDoc.
|
|
2695
2862
|
*/
|
|
@@ -2731,7 +2898,29 @@ exports.astNodeVisitor = {
|
|
|
2731
2898
|
// types.push('Object');
|
|
2732
2899
|
if (Array.isArray(parsedType.fields)) {
|
|
2733
2900
|
typeString = `{${parsedType.fields.map(
|
|
2734
|
-
({key,value}) =>
|
|
2901
|
+
({key,value}) => {
|
|
2902
|
+
const keyString = catharsis.stringify(key);
|
|
2903
|
+
if (value) {
|
|
2904
|
+
var propertyPlusType = `${keyString}: ${toTypeString(value)}`;
|
|
2905
|
+
return propertyPlusType;
|
|
2906
|
+
} else {
|
|
2907
|
+
let pos;
|
|
2908
|
+
if (keyString && (pos = keyString.indexOf(":")) > -1) {
|
|
2909
|
+
// When no space is present between colon and type (e.g. the structure looks like "{x:number}" with no space after
|
|
2910
|
+
// the colon), then Catharsis parses this as property name "x:number" with no type given.
|
|
2911
|
+
// In this case give a clear hint that this space is needed and throw an error to prevent such issues from being merged
|
|
2912
|
+
const realName = keyString.substring(0, pos);
|
|
2913
|
+
const realValue = keyString.substring(pos + 1, keyString.length);
|
|
2914
|
+
let message = `Cannot parse the "${keyString}" part of "${parsedType.typeExpression}" in RecordType (log output above may give a hint in which file).\n`;
|
|
2915
|
+
message += `Did you mean to specify a property "${realName}" of type "${realValue}"? Then insert a space after the colon and write "${realName}: ${realValue}".`
|
|
2916
|
+
error(message);
|
|
2917
|
+
return "x: any"; // unparseable property set to "any" - but the JSDoc run will fail now, anyway
|
|
2918
|
+
} else {
|
|
2919
|
+
// only property given without type; this will be turned into type "any" further downstream
|
|
2920
|
+
return keyString;
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2923
|
+
}
|
|
2735
2924
|
).join(', ')}}`;
|
|
2736
2925
|
types.push(typeString);
|
|
2737
2926
|
} else {
|
|
@@ -2772,7 +2961,9 @@ exports.astNodeVisitor = {
|
|
|
2772
2961
|
const origParse = jsdocType.parse;
|
|
2773
2962
|
jsdocType.parse = function() {
|
|
2774
2963
|
const tagInfo = origParse.apply(this, arguments);
|
|
2775
|
-
|
|
2964
|
+
// #### BEGIN: MODIFIED BY SAP
|
|
2965
|
+
if ( tagInfo && (/function/.test(tagInfo.typeExpression) || /\{.*\}/.test(tagInfo.typeExpression)) && tagInfo.parsedType ) {
|
|
2966
|
+
// #### END: MODIFIED BY SAP
|
|
2776
2967
|
// console.info("old typeExpression", tagInfo.typeExpression);
|
|
2777
2968
|
// console.info("old parse tree", tagInfo.parsedType);
|
|
2778
2969
|
// console.info("old parse result", tagInfo.type);
|