@@ -214,9 +214,13 @@ class JQuerySap extends DataFlow::SourceNode {
214214 * A user-defined module through `jQuery.sap.declare`.
215215 */
216216class JQueryDefineModule extends UserModule , MethodCallExpr {
217- JQueryDefineModule ( ) { exists ( JQuerySap jquerySap | jquerySap .asExpr ( ) = this .getReceiver ( ) ) }
217+ JQueryDefineModule ( ) {
218+ exists ( JQuerySap jQuerySap | this = jQuerySap .getAMemberCall ( [ "declare" , "define" ] ) .asExpr ( ) )
219+ }
218220
219- override string getADependency ( ) { result = this .getArgument ( 0 ) .getStringValue ( ) }
221+ override string getADependency ( ) {
222+ result = this .getArgument ( 0 ) .getALocalSource ( ) .getStringValue ( )
223+ }
220224
221225 override string getModuleFileRelativePath ( ) { result = this .getFile ( ) .getRelativePath ( ) }
222226
@@ -229,8 +233,9 @@ class JQueryDefineModule extends UserModule, MethodCallExpr {
229233
230234class Renderer extends SapExtendCall {
231235 Renderer ( ) {
232- this . getReceiver ( ) . getALocalSource ( ) =
236+ this =
233237 TypeTrackers:: hasDependency ( [ "sap/ui/core/Renderer" , "sap.ui.core.Renderer" ] )
238+ .getAMemberCall ( "extend" )
234239 }
235240
236241 FunctionNode getRenderer ( ) {
@@ -244,8 +249,9 @@ class Renderer extends SapExtendCall {
244249
245250class CustomControl extends SapExtendCall {
246251 CustomControl ( ) {
247- this .getReceiver ( ) .getALocalSource ( ) =
248- TypeTrackers:: hasDependency ( [ "sap/ui/core/Control" , "sap.ui.core.Control" ] ) or
252+ this =
253+ TypeTrackers:: hasDependency ( [ "sap/ui/core/Control" , "sap.ui.core.Control" ] )
254+ .getAMemberCall ( "extend" ) or
249255 exists ( SapDefineModule sapModule | this .getDefine ( ) = sapModule .getExtendingModule ( ) )
250256 }
251257
@@ -293,28 +299,43 @@ class CustomControl extends SapExtendCall {
293299 result = renderer .getRenderer ( )
294300 )
295301 }
302+ }
296303
297- ValueNode getAThisNode ( ) {
298- exists ( ThisNode thisNode | thisNode .getBinder ( ) = this .getAMethod ( ) |
299- result .getALocalSource ( ) = thisNode
304+ class ControlPlaceAtCall extends MethodCallNode {
305+ ControlPlaceAtCall ( ) {
306+ exists ( SapElement ui5Control |
307+ // /* 1. `this.placeAt(...)` in a custom control definition */
308+ // this = ui5Control.asDefinition().getAThisNode()
309+ // or
310+ // /*
311+ // * 2. `new SomeControl(...).placeAt(...)` where `SomeControl`
312+ // * may be UI5 library control or a custom control
313+ // */
314+ // ui5Control.asInstantiation().
315+ // or
316+ // /* 3. `.byId(...).placeAt(...)` */
317+ // ui5Control.asReference().
318+ none ( ) // TODO
300319 )
301320 }
302321}
303322
304323abstract class Reference extends MethodCallNode { }
305324
325+ private predicate byId ( MethodCallNode byId ) { byId .getMethodName ( ) = "byId" }
326+
306327/**
307328 * A JS reference to a `UI5Control`, commonly obtained via its ID.
308329 */
309330class ControlReference extends Reference {
310331 string controlId ;
311332
312333 ControlReference ( ) {
313- this .getArgument ( 0 ) .getStringValue ( ) = controlId and
334+ this .getArgument ( 0 ) .getALocalSource ( ) . getStringValue ( ) = controlId and
314335 (
315336 exists ( CustomController controller |
316337 this = controller .getAViewReference ( ) .getAMemberCall ( "byId" ) or
317- this . getReceiver ( ) = controller .getAThisNode ( )
338+ this = controller .getAThisNode ( ) . getAMemberCall ( "byId" )
318339 )
319340 or
320341 exists ( SapUiCore sapUiCore | this = sapUiCore .getAMemberCall ( "byId" ) )
@@ -398,17 +419,11 @@ class ControlReference extends Reference {
398419class ViewReference extends Reference {
399420 CustomController controller ;
400421
401- ViewReference ( ) {
402- this .getMethodName ( ) = "getView" and
403- controller .getAThisNode ( ) = this .getReceiver ( )
404- }
422+ ViewReference ( ) { this = controller .getAThisNode ( ) .getAMemberCall ( "getView" ) }
405423
406424 UI5View getDefinition ( ) { result = controller .getView ( ) }
407425
408- MethodCallNode getABindElementCall ( ) {
409- result .getMethodName ( ) = "bindElement" and
410- this .flowsTo ( result .getReceiver ( ) )
411- }
426+ MethodCallNode getABindElementCall ( ) { result = this .getAMemberCall ( "bindElement" ) }
412427}
413428
414429/**
@@ -417,7 +432,7 @@ class ViewReference extends Reference {
417432class ControllerReference extends Reference {
418433 ViewReference viewReference ;
419434
420- ControllerReference ( ) { viewReference .flowsTo ( this . getReceiver ( ) ) }
435+ ControllerReference ( ) { this = viewReference .getAMemberCall ( "getController" ) }
421436
422437 CustomController getDefinition ( ) { result = viewReference .getDefinition ( ) .getController ( ) }
423438}
@@ -426,8 +441,9 @@ class CustomController extends SapExtendCall {
426441 string name ;
427442
428443 CustomController ( ) {
429- this .getReceiver ( ) .getALocalSource ( ) =
430- TypeTrackers:: hasDependency ( [ "sap/ui/core/mvc/Controller" , "sap.ui.core.mvc.Controller" ] ) and
444+ this =
445+ TypeTrackers:: hasDependency ( [ "sap/ui/core/mvc/Controller" , "sap.ui.core.mvc.Controller" ] )
446+ .getAMemberCall ( "extend" ) and
431447 name = this .getFile ( ) .getBaseName ( ) .regexpCapture ( "([a-zA-Z0-9]+).[cC]ontroller.js" , 1 )
432448 }
433449
@@ -447,39 +463,33 @@ class CustomController extends SapExtendCall {
447463 }
448464
449465 MethodCallNode getOwnerComponentRef ( ) {
450- this .getAThisNode ( ) = result .getReceiver ( ) and
451- result .getMethodName ( ) = "getOwnerComponent"
466+ result = this .getAThisNode ( ) .getAMemberCall ( "getOwnerComponent" )
452467 }
453468
454469 /**
455470 * Gets a reference to a view object that can be accessed from one of the methods of this controller.
456471 */
457- ViewReference getAViewReference ( ) {
458- result .getMethodName ( ) = "getView" and
459- result .( MethodCallNode ) .getReceiver ( ) = this .getAThisNode ( )
460- }
472+ ViewReference getAViewReference ( ) { result = this .getAThisNode ( ) .getAMemberCall ( "getView" ) }
461473
462474 UI5View getView ( ) { this = result .getController ( ) }
463475
464476 ControlReference getAControlReference ( ) {
465477 result = this .getAViewReference ( ) .getAMemberCall ( "byId" )
466478 }
467479
468- ValueNode getAThisNode ( ) {
469- exists ( ThisNode thisNode | thisNode .getBinder ( ) = this .getAMethod ( ) |
470- /* ========== 1. `this` referring to the binder ========== */
471- thisNode .flowsTo ( result )
472- or
473- /* 2. ========== `this` bound to an outside `this` ========== */
474- /*
475- * 2-1. The DisplayEventHandler's `this` bound to an outside `this` via
476- * `.attachDisplay` or `.detachDisplay`
477- */
480+ override ThisNode getAThisNode ( ) {
481+ /* 1. `this` referring to the binder */
482+ result = super .getAThisNode ( )
483+ or
484+ /* 2. `this` bound to a callback's `this` */
485+ /*
486+ * 2-1. The this node of `.attachDisplay` or `.detachDisplay` also represents this
487+ * controller.
488+ */
478489
479- exists ( DisplayEventHandler handler , ThisNode handlerThis | handlerThis .getBinder ( ) = handler |
480- thisNode .flowsTo ( handler .getAssociatedContextObject ( ) ) and
481- handlerThis .flowsTo ( result )
482- )
490+ exists ( DisplayEventHandler handler |
491+ handler .getAssociatedContextObject ( ) .getALocalSource ( ) = this .getAThisNode ( ) and
492+ result .getBinder ( ) = handler
483493 )
484494 }
485495
@@ -516,7 +526,7 @@ class RouteReference extends MethodCallNode {
516526 RouteReference ( ) {
517527 exists ( RouterReference routerReference |
518528 this = routerReference .getAMemberCall ( "getRoute" ) and
519- this .getArgument ( 0 ) .getStringValue ( ) = name
529+ this .getArgument ( 0 ) .getALocalSource ( ) . getStringValue ( ) = name
520530 )
521531 }
522532
@@ -545,10 +555,9 @@ class ControllerHandler extends EventHandler {
545555
546556class RouterReference extends MethodCallNode {
547557 RouterReference ( ) {
548- this .getMethodName ( ) = "getRouter" and
549558 exists ( CustomController controller |
550- controller .getAThisNode ( ) = this . getReceiver ( ) or
551- controller .getOwnerComponentRef ( ) .flowsTo ( this . getReceiver ( ) )
559+ this = controller .getAThisNode ( ) . getAMemberCall ( "getRouter" ) or
560+ this = controller .getOwnerComponentRef ( ) .getAMemberCall ( "getRouter" )
552561 )
553562 }
554563
@@ -565,9 +574,8 @@ class RoutingTarget extends MethodCallNode {
565574 RouterReference routerReference ;
566575
567576 RoutingTarget ( ) {
568- this .getArgument ( 0 ) .getALocalSource ( ) .asExpr ( ) .( StringLiteral ) .getValue ( ) = name and
569- routerReference = this .getReceiver ( ) .getALocalSource ( ) and
570- this .getMethodName ( ) = "getTarget"
577+ this .getArgument ( 0 ) .getALocalSource ( ) .getStringValue ( ) = name and
578+ this = routerReference .getAMemberCall ( "getTarget" )
571579 }
572580
573581 RouterReference getRouterReference ( ) { result = routerReference }
@@ -615,27 +623,22 @@ class DisplayEventHandler extends EventHandler {
615623 */
616624class ModelReference extends MethodCallNode {
617625 ModelReference ( ) {
618- this .getMethodName ( ) = "getModel" and
619- (
620- exists ( ViewReference view | view .flowsTo ( this .getReceiver ( ) ) )
621- or
622- exists ( CustomController controller |
623- controller .getAViewReference ( ) .flowsTo ( this .getReceiver ( ) ) or
624- controller .getOwnerComponentRef ( ) .flowsTo ( this .getReceiver ( ) )
625- )
626- or
627- exists ( Component component | component .getAThisNode ( ) .flowsTo ( this .getReceiver ( ) ) )
626+ exists ( ViewReference view | this = view .getAMemberCall ( "getModel" ) )
627+ or
628+ exists ( CustomController controller |
629+ this = controller .getAViewReference ( ) .getAMemberCall ( "getModel" ) or
630+ this = controller .getOwnerComponentRef ( ) .getAMemberCall ( "getModel" )
628631 )
632+ or
633+ exists ( Component component | this = component .getAThisNode ( ) .getAMemberCall ( "getModel" ) )
629634 }
630635
631636 predicate isDefaultModelReference ( ) { this .getNumArgument ( ) = 0 }
632637
633638 /**
634639 * Gets the models' name being referred to, given that it can be statically determined.
635640 */
636- string getModelName ( ) {
637- result = this .getArgument ( 0 ) .getALocalSource ( ) .asExpr ( ) .( StringLiteral ) .getValue ( )
638- }
641+ string getModelName ( ) { result = this .getArgument ( 0 ) .getALocalSource ( ) .getStringValue ( ) }
639642
640643 predicate isLocalModelReference ( ) {
641644 exists ( InternalModelManifest internalModelManifest |
@@ -704,10 +707,7 @@ class ModelReference extends MethodCallNode {
704707 /**
705708 * Gets a `getProperty` or `getObject` method call on this `ModelReference`. These methods read from a single property of the model this refers to.
706709 */
707- MethodCallNode getARead ( ) {
708- result .getMethodName ( ) = [ "getProperty" , "getObject" ] and
709- result .getReceiver ( ) .getALocalSource ( ) = this
710- }
710+ MethodCallNode getARead ( ) { result = this .getAMemberCall ( [ "getProperty" , "getObject" ] ) }
711711
712712 /**
713713 * Gets the resolved model of this `ModelReference` by looking for a matching `setModel` call.
@@ -724,10 +724,7 @@ abstract class UI5Model extends InvokeNode {
724724 /**
725725 * A `getProperty` or `getObject` method call on this `UI5Model`. These methods read from a single property of this model.
726726 */
727- MethodCallNode getARead ( ) {
728- result .getMethodName ( ) = [ "getProperty" , "getObject" ] and
729- result .getReceiver ( ) .getALocalSource ( ) = this
730- }
727+ MethodCallNode getARead ( ) { result = this .getAMemberCall ( [ "getProperty" , "getObject" ] ) }
731728}
732729
733730/**
@@ -748,16 +745,16 @@ import ManifestJson
748745 */
749746class Component extends SapExtendCall {
750747 Component ( ) {
751- this .getReceiver ( ) .getALocalSource ( ) =
752- /*
753- * Represents models that are loaded from an external source, e.g. OData service.
754- * It is the value flowing to a `setModel` call in a handler of a `CustomController` (which is represented by `ControllerHandler`), since it is the closest we can get to the actual model itself.
755- */
748+ /*
749+ * Represents models that are loaded from an external source, e.g. OData service.
750+ * It is the value flowing to a `setModel` call in a handler of a `CustomController` (which is represented by `ControllerHandler`), since it is the closest we can get to the actual model itself.
751+ */
756752
753+ this =
757754 TypeTrackers:: hasDependency ( [
758755 "sap/ui/core/mvc/Component" , "sap.ui.core.mvc.Component" , "sap/ui/core/UIComponent" ,
759756 "sap.ui.core.UIComponent"
760- ] )
757+ ] ) . getAMemberCall ( "extend" )
761758 }
762759
763760 string getId ( ) { result = this .getName ( ) .regexpCapture ( "([a-zA-Z0-9.]+).Component" , 1 ) }
@@ -788,8 +785,6 @@ class Component extends SapExtendCall {
788785 }
789786
790787 ExternalModelManifest getAnExternalModelDef ( ) { result = this .getExternalModelDef ( _) }
791-
792- ThisNode getAThisNode ( ) { result .getBinder ( ) = this .getAMethod ( ) }
793788}
794789
795790module ManifestJson {
@@ -1185,20 +1180,17 @@ class ResourceModel extends UI5Model, ModelReference {
11851180 /* A model reference obtained from this.getOwnerComponent().getModel("i18n") */
11861181 exists ( CustomController controller , ResourceModelManifest manifest |
11871182 (
1188- controller .getAThisNode ( ) = this . getReceiver ( ) or
1189- controller .getOwnerComponentRef ( ) .flowsTo ( this . ( ModelReference ) . getReceiver ( ) )
1183+ this = controller .getAThisNode ( ) . getAMemberCall ( "getModel" ) or
1184+ this = controller .getOwnerComponentRef ( ) .getAMemberCall ( "getModel" )
11901185 ) and
11911186 modelName = this .getModelName ( ) and
11921187 manifest .getName ( ) = modelName
11931188 )
11941189 }
11951190
1196- override MethodCallNode getARead ( ) { result = this . ( ModelReference ) .getARead ( ) }
1191+ override MethodCallNode getARead ( ) { result = ModelReference . super .getARead ( ) }
11971192
1198- MethodCallNode getResourceBundle ( ) {
1199- result .getMethodName ( ) = "getResourceBundle" and
1200- this = result .getReceiver ( ) .getALocalSource ( )
1201- }
1193+ MethodCallNode getResourceBundle ( ) { result = this .getAMemberCall ( "getResourceBundle" ) }
12021194}
12031195
12041196class BindingMode extends RequiredObject {
@@ -1250,7 +1242,7 @@ class SapExtendCall extends InvokeNode, MethodCallNode {
12501242
12511243 FunctionNode getAMethod ( ) { result = this .getMethod ( _) }
12521244
1253- string getName ( ) { result = this .getArgument ( 0 ) .getStringValue ( ) }
1245+ string getName ( ) { result = this .getArgument ( 0 ) .getALocalSource ( ) . getStringValue ( ) }
12541246
12551247 ObjectLiteralNode getContent ( ) { result = this .getArgument ( 1 ) }
12561248
@@ -1265,6 +1257,8 @@ class SapExtendCall extends InvokeNode, MethodCallNode {
12651257
12661258 /** Gets the `sap.ui.define` call that wraps this extension. */
12671259 SapDefineModule getDefine ( ) { this .getEnclosingFunction ( ) = result .getArgument ( 1 ) }
1260+
1261+ ThisNode getAThisNode ( ) { result .getBinder ( ) = this .getAMethod ( ) }
12681262}
12691263
12701264class ElementInstantiation extends NewNode {
@@ -1402,10 +1396,10 @@ class PropertyMetadata extends ObjectLiteralNode {
14021396 */
14031397 predicate isUnrestrictedStringType ( ) {
14041398 /* text : "string" */
1405- this .asExpr ( ) . ( StringLiteral ) . getValue ( ) = "string"
1399+ this .getStringValue ( ) = "string"
14061400 or
14071401 /* text: { type: "string" } */
1408- this .getAPropertySource ( "type" ) .asExpr ( ) . ( StringLiteral ) . getValue ( ) = "string"
1402+ this .getAPropertySource ( "type" ) .getStringValue ( ) = "string"
14091403 or
14101404 /* text: { someOther: "someOtherVal", ... } */
14111405 not exists ( this .getAPropertySource ( "type" ) )
0 commit comments