@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.
Files changed (83) hide show
  1. package/.reuse/dep5 +2 -2
  2. package/CHANGELOG.md +59 -1
  3. package/CONTRIBUTING.md +1 -1
  4. package/README.md +4 -4
  5. package/jsdoc.json +2 -2
  6. package/lib/lbt/UI5ClientConstants.js +7 -8
  7. package/lib/lbt/analyzer/ComponentAnalyzer.js +60 -22
  8. package/lib/lbt/analyzer/FioriElementsAnalyzer.js +31 -20
  9. package/lib/lbt/analyzer/JSModuleAnalyzer.js +119 -77
  10. package/lib/lbt/analyzer/SmartTemplateAnalyzer.js +31 -20
  11. package/lib/lbt/analyzer/XMLCompositeAnalyzer.js +35 -25
  12. package/lib/lbt/analyzer/XMLTemplateAnalyzer.js +71 -18
  13. package/lib/lbt/analyzer/analyzeLibraryJS.js +22 -6
  14. package/lib/lbt/bundle/AutoSplitter.js +10 -11
  15. package/lib/lbt/bundle/Builder.js +33 -36
  16. package/lib/lbt/bundle/BundleDefinition.js +1 -5
  17. package/lib/lbt/bundle/BundleWriter.js +1 -2
  18. package/lib/lbt/bundle/ResolvedBundleDefinition.js +6 -7
  19. package/lib/lbt/bundle/Resolver.js +11 -12
  20. package/lib/lbt/calls/SapUiDefine.js +16 -11
  21. package/lib/lbt/graph/dependencyGraph.js +3 -4
  22. package/lib/lbt/graph/dominatorTree.js +3 -3
  23. package/lib/lbt/graph/topologicalSort.js +3 -3
  24. package/lib/lbt/resources/LibraryFileAnalyzer.js +6 -9
  25. package/lib/lbt/resources/LocatorResource.js +2 -2
  26. package/lib/lbt/resources/LocatorResourcePool.js +3 -3
  27. package/lib/lbt/resources/ModuleInfo.js +2 -3
  28. package/lib/lbt/resources/Resource.js +3 -4
  29. package/lib/lbt/resources/ResourceCollector.js +8 -9
  30. package/lib/lbt/resources/ResourceFilterList.js +38 -40
  31. package/lib/lbt/resources/ResourceInfo.js +1 -1
  32. package/lib/lbt/resources/ResourceInfoList.js +5 -3
  33. package/lib/lbt/resources/ResourcePool.js +15 -21
  34. package/lib/lbt/utils/ASTUtils.js +60 -44
  35. package/lib/lbt/utils/JSTokenizer.js +4 -4
  36. package/lib/lbt/utils/ModuleName.js +10 -20
  37. package/lib/lbt/utils/escapePropertiesFile.js +4 -4
  38. package/lib/lbt/utils/parseUtils.js +5 -11
  39. package/lib/processors/bootstrapHtmlTransformer.js +15 -7
  40. package/lib/processors/bundlers/flexChangesBundler.js +16 -8
  41. package/lib/processors/bundlers/moduleBundler.js +26 -15
  42. package/lib/processors/jsdoc/apiIndexGenerator.js +16 -9
  43. package/lib/processors/jsdoc/jsdocGenerator.js +37 -25
  44. package/lib/processors/jsdoc/lib/{createIndexFiles.js → createIndexFiles.cjs} +0 -0
  45. package/lib/processors/jsdoc/lib/{transformApiJson.js → transformApiJson.cjs} +59 -2
  46. package/lib/processors/jsdoc/lib/ui5/{plugin.js → plugin.cjs} +310 -119
  47. package/lib/processors/jsdoc/lib/ui5/template/{publish.js → publish.cjs} +6 -2
  48. package/lib/processors/jsdoc/lib/ui5/template/utils/{versionUtil.js → versionUtil.cjs} +0 -0
  49. package/lib/processors/jsdoc/sdkTransformer.js +18 -11
  50. package/lib/processors/libraryLessGenerator.js +28 -16
  51. package/lib/processors/manifestCreator.js +15 -14
  52. package/lib/processors/minifier.js +22 -16
  53. package/lib/processors/nonAsciiEscaper.js +17 -7
  54. package/lib/processors/resourceListCreator.js +13 -13
  55. package/lib/processors/stringReplacer.js +13 -6
  56. package/lib/processors/themeBuilder.js +33 -24
  57. package/lib/processors/versionInfoGenerator.js +40 -30
  58. package/lib/tasks/buildThemes.js +18 -11
  59. package/lib/tasks/bundlers/generateBundle.js +23 -12
  60. package/lib/tasks/bundlers/generateComponentPreload.js +23 -12
  61. package/lib/tasks/bundlers/generateFlexChangesBundle.js +16 -8
  62. package/lib/tasks/bundlers/generateLibraryPreload.js +33 -17
  63. package/lib/tasks/bundlers/generateStandaloneAppBundle.js +21 -13
  64. package/lib/tasks/bundlers/utils/createModuleNameMapping.js +7 -7
  65. package/lib/tasks/escapeNonAsciiCharacters.js +12 -5
  66. package/lib/tasks/generateCachebusterInfo.js +17 -9
  67. package/lib/tasks/generateLibraryManifest.js +14 -8
  68. package/lib/tasks/generateResourcesJson.js +15 -9
  69. package/lib/tasks/generateThemeDesignerResources.js +19 -9
  70. package/lib/tasks/generateVersionInfo.js +12 -5
  71. package/lib/tasks/jsdoc/executeJsdocSdkTransformation.js +17 -9
  72. package/lib/tasks/jsdoc/generateApiIndex.js +16 -10
  73. package/lib/tasks/jsdoc/generateJsdoc.js +131 -119
  74. package/lib/tasks/minify.js +13 -6
  75. package/lib/tasks/replaceBuildtime.js +12 -5
  76. package/lib/tasks/replaceCopyright.js +12 -5
  77. package/lib/tasks/replaceVersion.js +12 -5
  78. package/lib/tasks/taskRepository.js +24 -30
  79. package/lib/tasks/transformBootstrapHtml.js +6 -5
  80. package/package.json +44 -31
  81. package/index.js +0 -173
  82. package/lib/processors/bundlers/manifestBundler.js +0 -172
  83. package/lib/tasks/bundlers/generateManifestBundle.js +0 -49
@@ -1,12 +1,21 @@
1
- "use strict";
2
-
3
- const {Syntax, VisitorKeys} = require("../utils/parseUtils");
4
- const escope = require("escope");
5
- const ModuleName = require("../utils/ModuleName");
6
- const {Format: ModuleFormat} = require("../resources/ModuleInfo");
7
- const UI5ClientConstants = require("../UI5ClientConstants");
8
- const {findOwnProperty, getLocation, getPropertyKey, isMethodCall, isString} = require("../utils/ASTUtils");
9
- const log = require("@ui5/logger").getLogger("lbt:analyzer:JSModuleAnalyzer");
1
+ import {Syntax, VisitorKeys} from "../utils/parseUtils.js";
2
+ import escope from "escope";
3
+ import {fromUI5LegacyName, fromRequireJSName, resolveRelativeRequireJSName} from "../utils/ModuleName.js";
4
+ import moduleInfo from "../resources/ModuleInfo.js";
5
+ const ModuleFormat = moduleInfo.Format;
6
+ import {MODULE__JQUERY_SAP_GLOBAL, MODULE__UI5LOADER_AUTOCONFIG} from "../UI5ClientConstants.js";
7
+ import {
8
+ findOwnProperty,
9
+ getLocation,
10
+ getPropertyKey,
11
+ isMethodCall,
12
+ isString,
13
+ getStringValue,
14
+ } from "../utils/ASTUtils.js";
15
+
16
+ import logger from "@ui5/logger";
17
+
18
+ const log = logger.getLogger("lbt:analyzer:JSModuleAnalyzer");
10
19
 
11
20
  // ------------------------------------------------------------------------------------------------------------------
12
21
 
@@ -64,7 +73,7 @@ const EnrichedVisitorKeys = (function() {
64
73
  BreakStatement: [],
65
74
  CallExpression: [], // special handling
66
75
  CatchClause: ["param", "body"],
67
- ChainExpression: [],
76
+ ChainExpression: ["expression"],
68
77
  ClassBody: [],
69
78
  ClassDeclaration: [],
70
79
  ClassExpression: [],
@@ -114,7 +123,7 @@ const EnrichedVisitorKeys = (function() {
114
123
  ImportSpecifier: [], // imported, local
115
124
  Literal: [],
116
125
  LabeledStatement: [],
117
- LogicalExpression: [],
126
+ LogicalExpression: ["right"],
118
127
  MemberExpression: [],
119
128
  MetaProperty: toBeDone(["meta", "property"]),
120
129
  MethodDefinition: [],
@@ -126,10 +135,10 @@ const EnrichedVisitorKeys = (function() {
126
135
  * All properties in an object pattern are executed.
127
136
  */
128
137
  ObjectPattern: [], // properties
129
- // PrivateIdentifier: [], // will come with ES2022
138
+ PrivateIdentifier: [],
130
139
  Program: [],
131
140
  Property: [],
132
- // PropertyDefinition: [], // will come with ES2022
141
+ PropertyDefinition: [],
133
142
  /*
134
143
  * argument of the rest element is always executed under the same condition as the rest element itself
135
144
  */
@@ -137,7 +146,7 @@ const EnrichedVisitorKeys = (function() {
137
146
  ReturnStatement: [],
138
147
  SequenceExpression: [],
139
148
  SpreadElement: [], // the argument of the spread operator always needs to be evaluated - argument
140
- // StaticBlock: [], // will come with ES2022
149
+ StaticBlock: [],
141
150
  Super: [],
142
151
  SwitchStatement: [],
143
152
  SwitchCase: ["test", "consequent"], // test and consequent are executed only conditionally
@@ -187,15 +196,6 @@ const EnrichedVisitorKeys = (function() {
187
196
  return;
188
197
  }
189
198
 
190
- // Ignore new ES2022 syntax as we currently use ES2021 (see parseUtils.js)
191
- if (
192
- type === "PrivateIdentifier" ||
193
- type === "PropertyDefinition" ||
194
- type === "StaticBlock"
195
- ) {
196
- return;
197
- }
198
-
199
199
  const visitorKeys = VisitorKeys[type];
200
200
  const condKeys = TempKeys[type];
201
201
  if ( condKeys === undefined ) {
@@ -350,13 +350,13 @@ class JSModuleAnalyzer {
350
350
 
351
351
  // depending on the used module APIs, add an implicit dependency to the loader entry module
352
352
  if ( info.format === ModuleFormat.UI5_LEGACY ) {
353
- info.addImplicitDependency(UI5ClientConstants.MODULE__JQUERY_SAP_GLOBAL);
353
+ info.addImplicitDependency(MODULE__JQUERY_SAP_GLOBAL);
354
354
  } else if ( info.format === ModuleFormat.UI5_DEFINE ) {
355
355
  // Note: the implicit dependency for sap.ui.define modules points to the standard UI5
356
356
  // loader config module. A more general approach would be to add a dependency to the loader
357
357
  // only, but then standard configuration would be missed by dependency resolution
358
358
  // (to be clarified)
359
- info.addImplicitDependency(UI5ClientConstants.MODULE__UI5LOADER_AUTOCONFIG);
359
+ info.addImplicitDependency(MODULE__UI5LOADER_AUTOCONFIG);
360
360
  }
361
361
 
362
362
  if ( !bIsUi5Module ) {
@@ -526,6 +526,15 @@ class JSModuleAnalyzer {
526
526
  }
527
527
  break;
528
528
 
529
+ case Syntax.PropertyDefinition:
530
+
531
+ // Instance properties (static=false) are only initialized when an instance is created (conditional)
532
+ // but a computed key is always evaluated on class initialization (eager)
533
+ visit(node.key, conditional);
534
+ visit(node.value, !node.static || conditional);
535
+
536
+ break;
537
+
529
538
  default:
530
539
  if ( condKeys == null ) {
531
540
  log.error("Unhandled AST node type " + node.type, node);
@@ -541,21 +550,27 @@ class JSModuleAnalyzer {
541
550
 
542
551
  function onDeclare(node) {
543
552
  const args = node.arguments;
544
- if ( args.length > 0 && isString(args[0]) ) {
545
- const name = ModuleName.fromUI5LegacyName( args[0].value );
546
- if ( nModuleDeclarations === 1 && !mainModuleFound) {
547
- // if this is the first declaration, then this is the main module declaration
548
- // note that this overrides an already given name
549
- setMainModuleInfo(name, getDocumentation(node));
550
- } else if ( nModuleDeclarations > 1 && name === info.name ) {
551
- // ignore duplicate declarations (e.g. in behavior file of design time controls)
552
- log.warn(`duplicate declaration of module name at ${getLocation(args)} in ${name}`);
553
+ if (args.length > 0) {
554
+ const value = getStringValue(args[0]);
555
+ if (value !== undefined) {
556
+ const name = fromUI5LegacyName(value);
557
+ if ( nModuleDeclarations === 1 && !mainModuleFound) {
558
+ // if this is the first declaration, then this is the main module declaration
559
+ // note that this overrides an already given name
560
+ setMainModuleInfo(name, getDocumentation(node));
561
+ } else if ( nModuleDeclarations > 1 && name === info.name ) {
562
+ // ignore duplicate declarations (e.g. in behavior file of design time controls)
563
+ log.warn(`duplicate declaration of module name at ${getLocation(args)} in ${name}`);
564
+ } else {
565
+ // otherwise it is just a submodule declaration
566
+ info.addSubModule(name);
567
+ }
568
+ return;
553
569
  } else {
554
- // otherwise it is just a submodule declaration
555
- info.addSubModule(name);
570
+ log.error("jQuery.sap.declare: module name could not be determined from first argument:", args[0]);
556
571
  }
557
572
  } else {
558
- log.error("jQuery.sap.declare: module name could not be determined from first argument:", args[0]);
573
+ log.error("jQuery.sap.declare: module name could not be determined, no arguments are given");
559
574
  }
560
575
  }
561
576
 
@@ -569,20 +584,26 @@ class JSModuleAnalyzer {
569
584
 
570
585
  // determine the name of the module
571
586
  let name = null;
572
- if ( i < nArgs && isString(args[i]) ) {
573
- name = ModuleName.fromRequireJSName( args[i++].value );
574
- if ( name === defaultName ) {
575
- // hardcoded name equals the file name, so this definition qualifies as main module definition
576
- setMainModuleInfo(name, desc);
577
- } else {
578
- info.addSubModule(name);
579
- if ( candidateName == null ) {
580
- // remember the name and description in case no other module qualifies as main module
581
- candidateName = name;
582
- candidateDescription = desc;
587
+ if ( i < nArgs ) {
588
+ const value = getStringValue( args[i] );
589
+ if ( value !== undefined ) {
590
+ name = fromRequireJSName(value);
591
+ if ( name === defaultName ) {
592
+ // hardcoded name equals the file name, so this definition qualifies as main module definition
593
+ setMainModuleInfo(name, desc);
594
+ } else {
595
+ info.addSubModule(name);
596
+ if ( candidateName == null ) {
597
+ // remember the name and description in case no other module qualifies as main module
598
+ candidateName = name;
599
+ candidateDescription = desc;
600
+ }
583
601
  }
602
+ i++;
584
603
  }
585
- } else {
604
+ }
605
+
606
+ if ( !name ) {
586
607
  nUnnamedDefines++;
587
608
  if ( nUnnamedDefines > 1 ) {
588
609
  throw new Error(
@@ -614,15 +635,25 @@ class JSModuleAnalyzer {
614
635
  // UI5 signature with one or many required modules
615
636
  for (let i = 0; i < nArgs; i++) {
616
637
  const arg = args[i];
617
- if ( isString(arg) ) {
618
- const requiredModuleName = ModuleName.fromUI5LegacyName( arg.value );
638
+ const value = getStringValue(arg);
639
+ if ( value !== undefined ) {
640
+ const requiredModuleName = fromUI5LegacyName( value );
619
641
  info.addDependency(requiredModuleName, conditional);
620
- } else if ( arg.type == Syntax.ConditionalExpression &&
621
- isString(arg.consequent) && isString(arg.alternate) ) {
622
- const requiredModuleName1 = ModuleName.fromUI5LegacyName( arg.consequent.value );
623
- info.addDependency(requiredModuleName1, true);
624
- const requiredModuleName2 = ModuleName.fromUI5LegacyName( arg.alternate.value );
625
- info.addDependency(requiredModuleName2, true);
642
+ } else if ( arg.type == Syntax.ConditionalExpression) {
643
+ const consequentValue = getStringValue(arg.consequent);
644
+ const alternateValue = getStringValue(arg.alternate);
645
+ if ( consequentValue !== undefined ) {
646
+ const requiredModuleName1 = fromUI5LegacyName( consequentValue );
647
+ info.addDependency(requiredModuleName1, true);
648
+ }
649
+ if ( alternateValue !== undefined ) {
650
+ const requiredModuleName2 = fromUI5LegacyName( alternateValue );
651
+ info.addDependency(requiredModuleName2, true);
652
+ }
653
+ if ( consequentValue === undefined || alternateValue === undefined ) {
654
+ log.verbose("jQuery.sap.require: cannot evaluate dynamic arguments: ", arg && arg.type);
655
+ info.dynamicDependencies = true;
656
+ }
626
657
  } else {
627
658
  log.verbose("jQuery.sap.require: cannot evaluate dynamic arguments: ", arg && arg.type);
628
659
  info.dynamicDependencies = true;
@@ -637,9 +668,10 @@ class JSModuleAnalyzer {
637
668
  const i = 0;
638
669
 
639
670
  if ( i < nArgs ) {
640
- if ( isString(args[i]) ) {
671
+ const value = getStringValue(args[i]);
672
+ if ( value !== undefined ) {
641
673
  // sap.ui.requireSync does not support relative dependencies
642
- const moduleName = ModuleName.fromRequireJSName( args[i].value );
674
+ const moduleName = fromRequireJSName( value );
643
675
  info.addDependency(moduleName, conditional);
644
676
  } else {
645
677
  log.verbose("sap.ui.requireSync: cannot evaluate dynamic arguments: ", args[i] && args[i].type);
@@ -654,18 +686,24 @@ class JSModuleAnalyzer {
654
686
  let i = 0;
655
687
 
656
688
  // determine the name of the module
657
- if ( i < nArgs && isString(args[i]) ) {
658
- const moduleName = ModuleName.fromRequireJSName( args[i++].value );
659
- info.addSubModule(moduleName);
660
-
661
- // add dependencies
662
- // to correctly identify dependencies e.g. of a library-preload
663
- const elementArg = args[i++];
664
- if (elementArg && elementArg.type === Syntax.ArrayExpression) {
665
- elementArg.elements.forEach((element) => {
666
- const dependencyName = ModuleName.resolveRelativeRequireJSName(moduleName, element.value);
667
- info.addDependency(dependencyName, conditional);
668
- });
689
+ if ( i < nArgs ) {
690
+ const value = getStringValue(args[i++]);
691
+ if ( value !== undefined ) {
692
+ const moduleName = fromRequireJSName( value );
693
+ info.addSubModule(moduleName);
694
+
695
+ // add dependencies
696
+ // to correctly identify dependencies e.g. of a library-preload
697
+ const elementArg = args[i++];
698
+ if (elementArg && elementArg.type === Syntax.ArrayExpression) {
699
+ elementArg.elements.forEach((element) => {
700
+ const dependencyName = resolveRelativeRequireJSName(moduleName,
701
+ getStringValue(element));
702
+ info.addDependency(dependencyName, conditional);
703
+ });
704
+ }
705
+ } else {
706
+ log.warn("sap.ui.predefine call has a non supported type for module name (ignored)");
669
707
  }
670
708
  } else {
671
709
  log.warn("sap.ui.predefine call is missing a module name (ignored)");
@@ -692,8 +730,11 @@ class JSModuleAnalyzer {
692
730
  if ( modules && modules.type == Syntax.ObjectExpression ) {
693
731
  modules.properties.forEach( function(property) {
694
732
  let moduleName = getPropertyKey(property);
733
+ if ( !moduleName ) {
734
+ return;
735
+ }
695
736
  if ( namesUseLegacyNotation ) {
696
- moduleName = ModuleName.fromUI5LegacyName(moduleName);
737
+ moduleName = fromUI5LegacyName(moduleName);
697
738
  }
698
739
  info.addSubModule(moduleName);
699
740
  });
@@ -705,16 +746,17 @@ class JSModuleAnalyzer {
705
746
  function analyzeDependencyArray(array, conditional, name) {
706
747
  // console.log(array);
707
748
  array.forEach( (item) => {
708
- if ( isString(item) ) {
749
+ const value = getStringValue(item);
750
+ if ( value !== undefined ) {
709
751
  // ignore special AMD dependencies (require, exports, module)
710
- if ( SPECIAL_AMD_DEPENDENCIES.indexOf(item.value) >= 0 ) {
752
+ if ( SPECIAL_AMD_DEPENDENCIES.indexOf(value) >= 0 ) {
711
753
  return;
712
754
  }
713
755
  let requiredModule;
714
756
  if (name == null) {
715
- requiredModule = ModuleName.fromRequireJSName( item.value );
757
+ requiredModule = fromRequireJSName( value );
716
758
  } else {
717
- requiredModule = ModuleName.resolveRelativeRequireJSName(name, item.value);
759
+ requiredModule = resolveRelativeRequireJSName(name, value);
718
760
  }
719
761
  info.addDependency( requiredModule, conditional );
720
762
  } else {
@@ -766,4 +808,4 @@ class JSModuleAnalyzer {
766
808
  }
767
809
 
768
810
 
769
- module.exports = JSModuleAnalyzer;
811
+ export default JSModuleAnalyzer;
@@ -23,13 +23,13 @@
23
23
  * This class can handle multiple concurrent analysis calls, it has no instance state other than the pool
24
24
  * (which is readonly).
25
25
  */
26
- "use strict";
27
26
 
28
- const ModuleName = require("../utils/ModuleName");
29
- const SapUiDefine = require("../calls/SapUiDefine");
30
- const {parseJS, Syntax} = require("../utils/parseUtils");
31
- const {getValue, isMethodCall, isString} = require("../utils/ASTUtils");
32
- const log = require("@ui5/logger").getLogger("lbt:analyzer:SmartTemplateAnalyzer");
27
+ import {fromUI5LegacyName} from "../utils/ModuleName.js";
28
+ import SapUiDefine from "../calls/SapUiDefine.js";
29
+ import {parseJS, Syntax} from "../utils/parseUtils.js";
30
+ import {getValue, isMethodCall, getStringValue} from "../utils/ASTUtils.js";
31
+ import logger from "@ui5/logger";
32
+ const log = logger.getLogger("lbt:analyzer:SmartTemplateAnalyzer");
33
33
 
34
34
  // ---------------------------------------------------------------------------------------------------------
35
35
 
@@ -84,7 +84,7 @@ class TemplateComponentAnalyzer {
84
84
  const st = (manifest && manifest["sap.ui.generic.app"]) || {};
85
85
  function recursePage(page) {
86
86
  if ( page.component && page.component.name ) {
87
- const module = ModuleName.fromUI5LegacyName( page.component.name + ".Component" );
87
+ const module = fromUI5LegacyName( page.component.name + ".Component" );
88
88
  log.verbose("template app: add dependency to template component %s", module);
89
89
  info.addDependency(module);
90
90
  promises.push( that._analyzeTemplateComponent(module, page, info) );
@@ -113,7 +113,7 @@ class TemplateComponentAnalyzer {
113
113
  const templateName = (pageConfig.component && pageConfig.component.settings &&
114
114
  pageConfig.component.settings.templateName) || defaultTemplateName;
115
115
  if ( templateName ) {
116
- const templateModuleName = ModuleName.fromUI5LegacyName( templateName, ".view.xml" );
116
+ const templateModuleName = fromUI5LegacyName( templateName, ".view.xml" );
117
117
  log.verbose("template app: add dependency to template view %s", templateModuleName);
118
118
  appInfo.addDependency(templateModuleName);
119
119
  }
@@ -134,25 +134,36 @@ class TemplateComponentAnalyzer {
134
134
  const TA = defineCall.findImportName("sap/suite/ui/generic/template/lib/TemplateAssembler.js");
135
135
  // console.log("local name for TemplateAssembler: %s", TA);
136
136
  if ( TA && defineCall.factory ) {
137
- defineCall.factory.body.body.forEach( (stmt) => {
138
- if ( stmt.type === Syntax.ReturnStatement &&
139
- isMethodCall(stmt.argument, [TA, "getTemplateComponent"]) &&
140
- stmt.argument.arguments.length > 2 &&
141
- stmt.argument.arguments[2].type === "ObjectExpression" ) {
142
- templateName = this._analyzeTemplateClassDefinition(stmt.argument.arguments[2]) || templateName;
137
+ if (defineCall.factory.type === Syntax.ArrowFunctionExpression &&
138
+ defineCall.factory.expression === true) {
139
+ if ( this._isTemplateClassDefinition(TA, defineCall.factory.body) ) {
140
+ templateName =
141
+ this._analyzeTemplateClassDefinition(defineCall.factory.body.arguments[2]) || templateName;
143
142
  }
144
- });
143
+ } else {
144
+ defineCall.factory.body.body.forEach( (stmt) => {
145
+ if ( stmt.type === Syntax.ReturnStatement &&
146
+ this._isTemplateClassDefinition(TA, stmt.argument)
147
+ ) {
148
+ templateName =
149
+ this._analyzeTemplateClassDefinition(stmt.argument.arguments[2]) || templateName;
150
+ }
151
+ });
152
+ }
145
153
  }
146
154
  }
147
155
  return templateName;
148
156
  }
149
157
 
158
+ _isTemplateClassDefinition(TA, node) {
159
+ return isMethodCall(node, [TA, "getTemplateComponent"]) &&
160
+ node.arguments.length > 2 &&
161
+ node.arguments[2].type === "ObjectExpression";
162
+ }
163
+
150
164
  _analyzeTemplateClassDefinition(clazz) {
151
- const defaultValue = getValue(clazz, ["metadata", "properties", "templateName", "defaultValue"]);
152
- if ( isString(defaultValue) ) {
153
- return defaultValue.value;
154
- }
165
+ return getStringValue(getValue(clazz, ["metadata", "properties", "templateName", "defaultValue"]));
155
166
  }
156
167
  }
157
168
 
158
- module.exports = TemplateComponentAnalyzer;
169
+ export default TemplateComponentAnalyzer;
@@ -1,10 +1,10 @@
1
- "use strict";
2
1
 
3
- const {Syntax} = require("../utils/parseUtils");
4
- const SapUiDefine = require("../calls/SapUiDefine");
5
- const {getValue, isMethodCall, isString} = require("../utils/ASTUtils");
6
- const ModuleName = require("../utils/ModuleName");
7
- const log = require("@ui5/logger").getLogger("lbt:analyzer:XMLCompositeAnalyzer");
2
+ import {Syntax} from "../utils/parseUtils.js";
3
+ import SapUiDefine from "../calls/SapUiDefine.js";
4
+ import {getValue, isMethodCall, getStringValue} from "../utils/ASTUtils.js";
5
+ import {fromUI5LegacyName} from "../utils/ModuleName.js";
6
+ import logger from "@ui5/logger";
7
+ const log = logger.getLogger("lbt:analyzer:XMLCompositeAnalyzer");
8
8
 
9
9
  const CALL_DEFINE = ["define"];
10
10
  const CALL_SAP_UI_DEFINE = ["sap", "ui", "define"];
@@ -19,18 +19,30 @@ class XMLCompositeAnalyzer {
19
19
  const XMLC = defineCall.findImportName("sap/ui/core/XMLComposite.js");
20
20
  // console.log("local name for XMLComposite: %s", XMLC);
21
21
  if ( XMLC && defineCall.factory ) {
22
- defineCall.factory.body.body.forEach( (stmt) => {
23
- if ( stmt.type === Syntax.VariableDeclaration ) {
24
- stmt.declarations.forEach( (decl) => {
25
- fragmentName = this._checkForXMLCClassDefinition( XMLC, decl.init ) || fragmentName;
26
- });
27
- } else if ( stmt.type === Syntax.ExpressionStatement &&
28
- stmt.expression.type === Syntax.AssignmentExpression ) {
29
- fragmentName = this._checkForXMLCClassDefinition( XMLC, stmt.expression.right ) || fragmentName;
30
- }
31
- });
32
- if ( fragmentName ) {
33
- const fragmentModule = ModuleName.fromUI5LegacyName( fragmentName, ".control.xml" );
22
+ if (defineCall.factory.type === Syntax.ArrowFunctionExpression &&
23
+ defineCall.factory.expression === true) {
24
+ fragmentName = this._checkForXMLCClassDefinition(XMLC, defineCall.factory.body);
25
+ } else {
26
+ defineCall.factory.body.body.forEach((stmt) => {
27
+ if (stmt.type === Syntax.VariableDeclaration) {
28
+ stmt.declarations.forEach((decl) => {
29
+ fragmentName = this._checkForXMLCClassDefinition(XMLC, decl.init) || fragmentName;
30
+ });
31
+ } else if (
32
+ stmt.type === Syntax.ReturnStatement &&
33
+ ( stmt?.argument?.type === Syntax.CallExpression && stmt.argument.arguments?.length > 1 &&
34
+ stmt.argument.arguments[1].type === Syntax.ObjectExpression)) {
35
+ fragmentName =
36
+ this._checkForXMLCClassDefinition(XMLC, stmt.argument) || fragmentName;
37
+ } else if (stmt.type === Syntax.ExpressionStatement &&
38
+ stmt.expression.type === Syntax.AssignmentExpression) {
39
+ fragmentName =
40
+ this._checkForXMLCClassDefinition(XMLC, stmt.expression.right) || fragmentName;
41
+ }
42
+ });
43
+ }
44
+ if (fragmentName) {
45
+ const fragmentModule = fromUI5LegacyName(fragmentName, ".control.xml");
34
46
  log.verbose("fragment control: add dependency to template fragment %s", fragmentModule);
35
47
  info.addDependency(fragmentModule);
36
48
  }
@@ -42,8 +54,9 @@ class XMLCompositeAnalyzer {
42
54
  let fragmentName;
43
55
  if ( isMethodCall(stmt, [XMLC, "extend"]) ) {
44
56
  // log.verbose(stmt);
45
- if ( stmt.arguments.length > 0 && isString(stmt.arguments[0]) ) {
46
- fragmentName = stmt.arguments[0].value;
57
+ const value = getStringValue(stmt.arguments[0]);
58
+ if ( stmt.arguments.length > 0 && value ) {
59
+ fragmentName = value;
47
60
  }
48
61
  if ( stmt.arguments.length > 1 && stmt.arguments[1].type === Syntax.ObjectExpression ) {
49
62
  fragmentName = this._analyzeXMLCClassDefinition(stmt.arguments[1]) || fragmentName;
@@ -54,12 +67,9 @@ class XMLCompositeAnalyzer {
54
67
 
55
68
  _analyzeXMLCClassDefinition(clazz) {
56
69
  // log.verbose(clazz);
57
- const fragmentName = getValue(clazz, ["fragment"]);
58
- if ( isString(fragmentName) ) {
59
- return fragmentName.value;
60
- }
70
+ return getStringValue(getValue(clazz, ["fragment"]));
61
71
  }
62
72
  }
63
73
 
64
74
 
65
- module.exports = XMLCompositeAnalyzer;
75
+ export default XMLCompositeAnalyzer;