@@ -139,6 +139,15 @@ class WebApp extends HTML::HtmlFile {
139139 * by a call to `sap.ui.getCore()`.
140140 */
141141class SapUiCore extends MethodCallNode {
142+ /*
143+ * NOTE: Ideally, we'd like to use `ModelOutput::getATypeNode("SapUICore").asSource()` to
144+ * take advantage of the inter-procedural flexibility of MaD, but doing so causes
145+ * non-monotomic recursion.
146+ *
147+ * So, we opt to use `SourceNode.getAPropertyRead/1` and `SourceNode.getAMethodCall/1`
148+ * instead and get away with local flow tracking they provide.
149+ */
150+
142151 SapUiCore ( ) { this = globalVarRef ( "sap" ) .getAPropertyRead ( "ui" ) .getAMethodCall ( "getCore" ) }
143152}
144153
@@ -1428,3 +1437,159 @@ class PropertyMetadata extends ObjectLiteralNode {
14281437 inSameWebApp ( this .getFile ( ) , result .getFile ( ) )
14291438 }
14301439}
1440+
1441+ module EventBus {
1442+ abstract class EventBusPublishCall extends CallNode {
1443+ abstract EventBusSubscribeCall getMatchingSubscribeCall ( ) ;
1444+
1445+ abstract DataFlow:: Node getPublishedData ( ) ;
1446+
1447+ string getChannelName ( ) { result = this .getArgument ( 0 ) .getALocalSource ( ) .getStringValue ( ) }
1448+
1449+ string getMessageType ( ) { result = this .getArgument ( 1 ) .getALocalSource ( ) .getStringValue ( ) }
1450+ }
1451+
1452+ abstract class EventBusSubscribeCall extends CallNode {
1453+ abstract EventBusPublishCall getMatchingPublishCall ( ) ;
1454+
1455+ abstract DataFlow:: Node getSubscriptionData ( ) ;
1456+
1457+ string getChannelName ( ) { result = this .getArgument ( 0 ) .getALocalSource ( ) .getStringValue ( ) }
1458+
1459+ string getMessageType ( ) { result = this .getArgument ( 1 ) .getALocalSource ( ) .getStringValue ( ) }
1460+ }
1461+
1462+ class GlobalEventBusPublishCall extends EventBusPublishCall {
1463+ API:: Node publishMethod ;
1464+
1465+ GlobalEventBusPublishCall ( ) {
1466+ publishMethod = ModelOutput:: getATypeNode ( "UI5EventBusPublish" ) and
1467+ this = publishMethod .getACall ( )
1468+ }
1469+
1470+ override GlobalEventBusSubscribeCall getMatchingSubscribeCall ( ) {
1471+ result .getChannelName ( ) = this .getChannelName ( ) and
1472+ result .getMessageType ( ) = this .getMessageType ( )
1473+ }
1474+
1475+ override DataFlow:: Node getPublishedData ( ) {
1476+ exists ( API:: Node publishedData |
1477+ publishedData = ModelOutput:: getATypeNode ( "UI5EventBusPublishedEventData" )
1478+ |
1479+ publishMethod .getASuccessor * ( ) = publishedData and
1480+ result = publishedData .getInducingNode ( )
1481+ )
1482+ }
1483+ }
1484+
1485+ class SapUICoreEventBusPublishCall extends EventBusPublishCall {
1486+ API:: Node publishMethod ;
1487+
1488+ SapUICoreEventBusPublishCall ( ) {
1489+ publishMethod = ModelOutput:: getATypeNode ( "SapUICoreEventBusPublish" ) and
1490+ this = publishMethod .getACall ( )
1491+ }
1492+
1493+ override SapUICoreEventBusSubscribeCall getMatchingSubscribeCall ( ) {
1494+ result .getChannelName ( ) = this .getChannelName ( ) and
1495+ result .getMessageType ( ) = this .getMessageType ( )
1496+ }
1497+
1498+ override DataFlow:: Node getPublishedData ( ) {
1499+ exists ( API:: Node publishedData |
1500+ publishedData = ModelOutput:: getATypeNode ( "SapUICoreEventBusPublishedEventData" )
1501+ |
1502+ publishMethod .getASuccessor * ( ) = publishedData and
1503+ result = publishedData .getInducingNode ( )
1504+ )
1505+ }
1506+ }
1507+
1508+ class ComponentEventBusPublishCall extends EventBusPublishCall {
1509+ CustomController controller ;
1510+ Component component ;
1511+
1512+ ComponentEventBusPublishCall ( ) {
1513+ component = controller .getOwnerComponent ( ) and
1514+ this = controller .getOwnerComponentRef ( ) .getAMemberCall ( "publish" )
1515+ }
1516+
1517+ override ComponentEventBusSubscribeCall getMatchingSubscribeCall ( ) {
1518+ result .getChannelName ( ) = this .getChannelName ( ) and
1519+ result .getMessageType ( ) = this .getMessageType ( ) and
1520+ result .getComponent ( ) = this .getComponent ( )
1521+ }
1522+
1523+ override DataFlow:: Node getPublishedData ( ) { result = this .getArgument ( 2 ) }
1524+
1525+ Component getComponent ( ) { result = component }
1526+ }
1527+
1528+ class GlobalEventBusSubscribeCall extends EventBusSubscribeCall {
1529+ API:: Node subscribeMethod ;
1530+
1531+ GlobalEventBusSubscribeCall ( ) {
1532+ subscribeMethod = ModelOutput:: getATypeNode ( "UI5EventBusSubscribe" ) and
1533+ this = subscribeMethod .getACall ( )
1534+ }
1535+
1536+ override GlobalEventBusPublishCall getMatchingPublishCall ( ) {
1537+ result .getChannelName ( ) = this .getChannelName ( ) and
1538+ result .getMessageType ( ) = this .getMessageType ( )
1539+ }
1540+
1541+ override DataFlow:: Node getSubscriptionData ( ) {
1542+ exists ( API:: Node subscribeMethodCallbackDataParameter |
1543+ subscribeMethodCallbackDataParameter =
1544+ ModelOutput:: getATypeNode ( "UI5EventSubscriptionHandlerDataParameter" )
1545+ |
1546+ subscribeMethod .getASuccessor * ( ) = subscribeMethodCallbackDataParameter and
1547+ result = subscribeMethodCallbackDataParameter .getInducingNode ( )
1548+ )
1549+ }
1550+ }
1551+
1552+ class SapUICoreEventBusSubscribeCall extends EventBusSubscribeCall {
1553+ API:: Node subscribeMethod ;
1554+
1555+ SapUICoreEventBusSubscribeCall ( ) {
1556+ subscribeMethod = ModelOutput:: getATypeNode ( "SapUICoreInstance" ) and
1557+ this = subscribeMethod .getACall ( )
1558+ }
1559+
1560+ override SapUICoreEventBusPublishCall getMatchingPublishCall ( ) {
1561+ result .getChannelName ( ) = this .getChannelName ( ) and
1562+ result .getMessageType ( ) = this .getMessageType ( )
1563+ }
1564+
1565+ override DataFlow:: Node getSubscriptionData ( ) {
1566+ exists ( API:: Node subscribeMethodCallbackDataParameter |
1567+ subscribeMethodCallbackDataParameter =
1568+ ModelOutput:: getATypeNode ( "SapUICoreEventSubscriptionHandlerDataParameter" )
1569+ |
1570+ subscribeMethod .getASuccessor * ( ) = subscribeMethodCallbackDataParameter and
1571+ result = subscribeMethodCallbackDataParameter .getInducingNode ( )
1572+ )
1573+ }
1574+ }
1575+
1576+ class ComponentEventBusSubscribeCall extends EventBusSubscribeCall {
1577+ CustomController controller ;
1578+ Component component ;
1579+
1580+ ComponentEventBusSubscribeCall ( ) {
1581+ component = controller .getOwnerComponent ( ) and
1582+ this = controller .getOwnerComponentRef ( ) .getAMemberCall ( "subscribe" )
1583+ }
1584+
1585+ override ComponentEventBusPublishCall getMatchingPublishCall ( ) {
1586+ result .getChannelName ( ) = this .getChannelName ( ) and
1587+ result .getMessageType ( ) = this .getMessageType ( ) and
1588+ result .getComponent ( ) = this .getComponent ( )
1589+ }
1590+
1591+ override DataFlow:: Node getSubscriptionData ( ) { result = this .getABoundCallbackParameter ( 2 , 2 ) }
1592+
1593+ Component getComponent ( ) { result = component }
1594+ }
1595+ }
0 commit comments