@@ -49,46 +49,6 @@ class CdsDb extends SourceNode {
4949 MethodCallNode getInsertCall ( ) { result = this .getAMemberCall ( "insert" ) }
5050}
5151
52- /**
53- * An entity object that belongs to a service.
54- *
55- * ```javascript
56- * // Obtained through `cds.entities`
57- * const { Service1 } = cds.entities("sample.application.namespace");
58- * // Obtained through `Service.entities`, in this case the `Service`
59- * // being a `this` variable of the service.
60- * const { Service1 } = this.entities;
61- * ```
62- */
63- abstract class EntityEntry instanceof PropRead {
64- Location getLocation ( ) { result = PropRead .super .getLocation ( ) }
65-
66- string toString ( ) { result = PropRead .super .toString ( ) }
67-
68- /**
69- * Gets the definition of the service to which this entity belongs to.
70- */
71- abstract UserDefinedApplicationService getServiceDefinition ( ) ;
72- }
73-
74- private class EntityEntryFromCdsEntities extends EntityEntry {
75- CdsEntitiesCall cdsEntities ;
76-
77- EntityEntryFromCdsEntities ( ) { this = cdsEntities .getAPropertyRead ( ) }
78-
79- override UserDefinedApplicationService getServiceDefinition ( ) {
80- result .getServiceName ( ) = cdsEntities .getNamespace ( )
81- }
82- }
83-
84- private class EntityEntryFromServiceInstance extends EntityEntry {
85- ServiceInstance srv ;
86-
87- EntityEntryFromServiceInstance ( ) { this = srv .getAPropertyRead ( "entities" ) .getAPropertyRead ( ) }
88-
89- override UserDefinedApplicationService getServiceDefinition ( ) { result = srv .getDefinition ( ) }
90- }
91-
9252/**
9353 * A call to `serve` on a CDS facade.
9454 */
@@ -645,38 +605,87 @@ class CdsTransaction extends MethodCallNode {
645605
646606abstract class CdsReference extends DataFlow:: Node { }
647607
608+ /**
609+ * A reference object to an entity that belongs to a service. e.g.
610+ *
611+ * ```javascript
612+ * // 1. Obtained through `cds.entities`
613+ * const { Entity1 } = cds.entities("sample.application.namespace");
614+ * // 2. Obtained through `Service.entities`, in this case the `Service`
615+ * // being a `this` variable of the service.
616+ * const { Entity2 } = this.entities;
617+ * // 3. A direct mention of a name in a literal pass to the fluent API builder.
618+ * SELECT.from`Books`.where(`ID=${id}`)
619+ * ```
620+ */
648621abstract class EntityReference extends CdsReference {
649622 abstract CdlEntity getCqlDefinition ( ) ;
650623}
651624
625+ /**
626+ * A reference object to an entity that belongs to a service, either
627+ * obtained through a method call to `entities`, or a read from property
628+ * `entities`. e.g.
629+ *
630+ * ```javascript
631+ * // 1. Obtained through `cds.entities`
632+ * const { Entity1 } = cds.entities("sample.application.namespace");
633+ * // 2. Obtained through `Service.entities`, in this case the `Service`
634+ * // being a `this` variable of the service.
635+ * const { Entity2 } = this.entities;
636+ * // 3. A direct mention of a name in a literal pass to the fluent API builder.
637+ * SELECT.from`Books`.where(`ID=${id}`)
638+ * ```
639+ */
652640class EntityReferenceFromEntities extends EntityReference instanceof PropRead {
653- DataFlow:: SourceNode entities ;
641+ /**
642+ * Property or call to entities
643+ */
644+ DataFlow:: SourceNode entitiesAccess ;
645+ /**
646+ * Receiver of the entities call or the base of propread
647+ */
654648 DataFlow:: Node receiver ;
649+ /**
650+ * Name of the (unqualified) entity being accessed
651+ */
655652 string entityName ;
656653
657654 EntityReferenceFromEntities ( ) {
655+ /*
656+ * 1. Reference obtained through a call to `entities` on the
657+ * service instance.
658+ */
659+
658660 exists ( MethodCallNode entitiesCall |
659- entities = entitiesCall and
661+ entitiesAccess = entitiesCall and
660662 receiver = entitiesCall .getReceiver ( ) and
661663 entitiesCall .getMethodName ( ) = "entities" and
662664 this = entitiesCall .getAPropertyRead ( entityName )
663665 )
664666 or
667+ /*
668+ * 2. Reference obtained through a read from property `entities` of the
669+ * service instance.
670+ */
671+
665672 exists ( PropRead entitiesRead |
666- entities = entitiesRead and
673+ entitiesAccess = entitiesRead and
667674 receiver = entitiesRead .getBase ( ) and
668675 entitiesRead .getPropertyName ( ) = "entities" and
669676 this = entitiesRead .getAPropertyRead ( entityName )
670677 )
671678 }
672679
673- DataFlow:: SourceNode getEntities ( ) { result = entities }
680+ DataFlow:: SourceNode getEntities ( ) { result = entitiesAccess }
674681
675682 DataFlow:: Node getReceiver ( ) { result = receiver }
676683
677684 string getEntityName ( ) { result = entityName }
678685
679686 abstract override CdlEntity getCqlDefinition ( ) ;
687+
688+ abstract UserDefinedApplicationService getServiceDefinition ( ) ;
680689}
681690
682691/**
@@ -686,13 +695,7 @@ class EntityReferenceFromUserDefinedServiceEntities extends EntityReferenceFromE
686695{
687696 ServiceInstance service ;
688697
689- EntityReferenceFromUserDefinedServiceEntities ( ) {
690- this .getReceiver ( ) = service .( ServiceInstanceFromThisNode )
691- or
692- this .getEntities ( ) = service .( ServiceInstanceFromCdsConnectTo ) .getAMemberCall ( "entities" )
693- or
694- this .getEntities ( ) = service .( ServiceInstanceFromCdsConnectTo ) .getAPropertyRead ( "entities" )
695- }
698+ EntityReferenceFromUserDefinedServiceEntities ( ) { this .getReceiver ( ) .getALocalSource ( ) = service }
696699
697700 override CdlEntity getCqlDefinition ( ) {
698701 this .getEntities ( ) instanceof PropRead and
@@ -709,28 +712,31 @@ class EntityReferenceFromUserDefinedServiceEntities extends EntityReferenceFromE
709712 .getEntity ( this .getEntities ( ) .( MethodCallNode ) .getArgument ( 0 ) .getStringValue ( ) + "." +
710713 entityName )
711714 }
715+
716+ override UserDefinedApplicationService getServiceDefinition ( ) { result = service .getDefinition ( ) }
712717}
713718
714719/**
715720 * db.entities, db.entities(...), cds.entities, cds.entities(...)
716721 */
717722class EntityReferenceFromDbOrCdsEntities extends EntityReferenceFromEntities {
718723 EntityReferenceFromDbOrCdsEntities ( ) {
719- exists ( DBServiceInstanceFromCdsConnectTo db |
720- entities = db .getAMemberCall ( "entities" ) or entities = db .getAPropertyRead ( "entities" )
721- )
722- or
723- exists ( CdsFacade cds |
724- entities = cds .getMember ( "entities" ) .getACall ( ) or
725- entities = cds .getMember ( "entities" ) .asSource ( )
726- )
724+ this .getReceiver ( ) .getALocalSource ( ) instanceof DBServiceInstanceFromCdsConnectTo or
725+ exists ( CdsFacade cds | this .getReceiver ( ) .getALocalSource ( ) = cds .getNode ( ) ) or
726+ exists ( CdsFacade cds | this .getReceiver ( ) .getALocalSource ( ) = cds .getMember ( "db" ) .asSource ( ) )
727727 }
728728
729729 override CdlEntity getCqlDefinition ( ) {
730730 /* NOTE: the result may be multiple; but they are all identical so we don't really care. */
731731 result .getName ( ) =
732732 this .getEntities ( ) .( MethodCallNode ) .getArgument ( 0 ) .getStringValue ( ) + "." + entityName
733733 }
734+
735+ override UserDefinedApplicationService getServiceDefinition ( ) {
736+ /* TODO: Always get the DB service definition. */
737+ none ( )
738+ // result.getServiceName() = this.(CdsEntitiesCall).getNamespace()
739+ }
734740}
735741
736742class EntityReferenceFromCqlClause extends EntityReference , ExprNode {
0 commit comments