@@ -239,6 +239,13 @@ function getDocumentation(node) {
239239 * @private
240240 */
241241class JSModuleAnalyzer {
242+ /**
243+ * Analyzes the JS AST
244+ *
245+ * @param {object } ast js ast
246+ * @param {string } defaultName default name
247+ * @param {ModuleInfo } info module info
248+ */
242249 analyze ( ast , defaultName , info ) {
243250 let mainModuleFound = false ;
244251 /**
@@ -260,6 +267,20 @@ class JSModuleAnalyzer {
260267 */
261268 let nModuleDeclarations = 0 ;
262269
270+ /**
271+ * Whether or not this is a UI5 module
272+ *
273+ * When in the non-conditional module execution there is a call to:
274+ * <ul>
275+ * <li>sap.ui.define call</li>
276+ * <li>jQuery.sap.declare call</li>
277+ * </ul>
278+ * this value is true
279+ *
280+ * @type {boolean }
281+ */
282+ let bIsUi5Module = false ;
283+
263284 // first analyze the whole AST...
264285 visit ( ast , false ) ;
265286
@@ -307,7 +328,7 @@ class JSModuleAnalyzer {
307328 info . addImplicitDependency ( UI5ClientConstants . MODULE__UI5LOADER_AUTOCONFIG ) ;
308329 }
309330
310- if ( nModuleDeclarations === 0 && info . dependencies . length === 0 && info . subModules . length === 0 ) {
331+ if ( ! bIsUi5Module ) {
311332 // when there are no indicators for module APIs, mark the module as 'raw' module
312333 info . rawModule = true ;
313334 }
@@ -320,7 +341,6 @@ class JSModuleAnalyzer {
320341 // console.log(info.name, "exposed globals", info.exposedGlobals, "ignoredGlobals", info.ignoredGlobals);
321342 }
322343
323- return ;
324344
325345 // hoisted functions
326346 function setMainModuleInfo ( name , description ) {
@@ -353,6 +373,7 @@ class JSModuleAnalyzer {
353373 // recognized a call to jQuery.sap.declare()
354374 nModuleDeclarations ++ ;
355375 info . setFormat ( ModuleFormat . UI5_LEGACY ) ;
376+ bIsUi5Module = true ;
356377 onDeclare ( node ) ;
357378 } else if ( ! conditional &&
358379 ( isMethodCall ( node , CALL_SAP_UI_DEFINE ) || isMethodCall ( node , CALL_AMD_DEFINE ) ) ) {
@@ -364,6 +385,7 @@ class JSModuleAnalyzer {
364385 } else {
365386 info . setFormat ( ModuleFormat . AMD ) ;
366387 }
388+ bIsUi5Module = true ;
367389 onDefine ( node ) ;
368390
369391 const args = node . arguments ;
@@ -380,8 +402,24 @@ class JSModuleAnalyzer {
380402 }
381403 } else if ( isMethodCall ( node , CALL_REQUIRE_PREDEFINE ) || isMethodCall ( node , CALL_SAP_UI_PREDEFINE ) ) {
382404 // recognized a call to require.predefine() or sap.ui.predefine()
405+ if ( ! conditional ) {
406+ bIsUi5Module = true ;
407+ }
383408 info . setFormat ( ModuleFormat . UI5_DEFINE ) ;
384- onSapUiPredefine ( node ) ;
409+ onSapUiPredefine ( node , conditional ) ;
410+
411+ const args = node . arguments ;
412+ let iArg = 0 ;
413+ if ( iArg < args . length && isString ( args [ iArg ] ) ) {
414+ iArg ++ ;
415+ }
416+ if ( iArg < args . length && args [ iArg ] . type == Syntax . ArrayExpression ) {
417+ iArg ++ ;
418+ }
419+ if ( iArg < args . length && isCallableExpression ( args [ iArg ] ) ) {
420+ // unconditionally execute the factory function
421+ visit ( args [ iArg ] . body , conditional ) ;
422+ }
385423 } else if ( isMethodCall ( node , CALL_SAP_UI_REQUIRE ) || isMethodCall ( node , CALL_AMD_REQUIRE ) ) {
386424 // recognized a call to require() or sap.ui.require()
387425 if ( isMethodCall ( node , CALL_SAP_UI_REQUIRE ) ) {
@@ -404,17 +442,24 @@ class JSModuleAnalyzer {
404442 } else if ( isMethodCall ( node , CALL_REQUIRE_SYNC ) || isMethodCall ( node , CALL_SAP_UI_REQUIRE_SYNC ) ) {
405443 // recognizes a call to sap.ui.requireSync
406444 info . setFormat ( ModuleFormat . UI5_DEFINE ) ;
445+
407446 onSapUiRequireSync ( node , conditional ) ;
408447 } else if ( isMethodCall ( node , CALL_JQUERY_SAP_REQUIRE ) ) {
409448 // recognizes a call to jQuery.sap.require
410449 info . setFormat ( ModuleFormat . UI5_LEGACY ) ;
411450 onJQuerySapRequire ( node , conditional ) ;
412451 } else if ( isMethodCall ( node , CALL_JQUERY_SAP_REGISTER_PRELOADED_MODULES ) ) {
413452 // recognizes a call to jQuery.sap.registerPreloadedModules
453+ if ( ! conditional ) {
454+ bIsUi5Module = true ;
455+ }
414456 info . setFormat ( ModuleFormat . UI5_LEGACY ) ;
415457 onRegisterPreloadedModules ( node , /* evoSyntax= */ false ) ;
416458 } else if ( isMethodCall ( node , CALL_SAP_UI_REQUIRE_PRELOAD ) ) {
417459 // recognizes a call to sap.ui.require.preload
460+ if ( ! conditional ) {
461+ bIsUi5Module = true ;
462+ }
418463 info . setFormat ( ModuleFormat . UI5_DEFINE ) ;
419464 onRegisterPreloadedModules ( node , /* evoSyntax= */ true ) ;
420465 } else if ( isCallableExpression ( node . callee ) ) {
@@ -560,6 +605,7 @@ class JSModuleAnalyzer {
560605
561606 if ( i < nArgs ) {
562607 if ( isString ( args [ i ] ) ) {
608+ // sap.ui.requireSync does not support relative dependencies
563609 const moduleName = ModuleName . fromRequireJSName ( args [ i ] . value ) ;
564610 info . addDependency ( moduleName , conditional ) ;
565611 } else {
@@ -569,7 +615,7 @@ class JSModuleAnalyzer {
569615 }
570616 }
571617
572- function onSapUiPredefine ( predefineCall ) {
618+ function onSapUiPredefine ( predefineCall , conditional ) {
573619 const args = predefineCall . arguments ;
574620 const nArgs = args . length ;
575621 let i = 0 ;
@@ -578,6 +624,16 @@ class JSModuleAnalyzer {
578624 if ( i < nArgs && isString ( args [ i ] ) ) {
579625 const moduleName = ModuleName . fromRequireJSName ( args [ i ++ ] . value ) ;
580626 info . addSubModule ( moduleName ) ;
627+
628+ // add dependencies
629+ // to correctly identify dependencies e.g. of a library-preload
630+ const elementArg = args [ i ++ ] ;
631+ if ( elementArg && elementArg . type === Syntax . ArrayExpression ) {
632+ elementArg . elements . forEach ( ( element ) => {
633+ const dependencyName = ModuleName . resolveRelativeRequireJSName ( moduleName , element . value ) ;
634+ info . addDependency ( dependencyName , conditional ) ;
635+ } ) ;
636+ }
581637 } else {
582638 log . warn ( "sap.ui.predefine call is missing a module name (ignored)" ) ;
583639 }
0 commit comments