@@ -177,7 +177,27 @@ class ServiceInstanceFromConstructor extends ServiceInstance {
177177}
178178
179179/**
180- * A read to `this` variable which represents the service whose definition encloses this variable access.
180+ * A read to `this` variable which represents the service whose definition encloses
181+ * this variable access.
182+ * e.g.1. Given this code:
183+ * ``` javascript
184+ * const cds = require("@sap/cds");
185+ * module.exports = class SomeService extends cds.ApplicationService {
186+ * init() {
187+ * this.on("SomeEvent", (req) => { ... } )
188+ * }
189+ * }
190+ * ```
191+ * This class captures the access to the `this` variable as in `this.on(...)`.
192+ *
193+ * e.g.2. Given this code:
194+ * ``` javascript
195+ * const cds = require('@sap/cds');
196+ * module.exports = cds.service.impl (function() {
197+ * this.on("SomeEvent", (req) => { ... })
198+ * })
199+ * ```
200+ * This class captures the access to the `this` variable as in `this.on(...)`.
181201 */
182202class ServiceInstanceFromThisNode extends ServiceInstance , ThisNode {
183203 UserDefinedApplicationService userDefinedApplicationService ;
@@ -294,12 +314,56 @@ class DbServiceInstanceFromCdsConnectTo extends ServiceInstanceFromCdsConnectTo,
294314 override UserDefinedApplicationService getDefinition ( ) { none ( ) }
295315}
296316
317+ /**
318+ * The 0-th parameter of an exported closure that represents the service being implemented. e.g.
319+ * ``` javascript
320+ * const cds = require('@sap/cds')
321+ * module.exports = (srv) => {
322+ * srv.on("SomeEvent1", (req) => { ... })
323+ * }
324+ * ```
325+ * This class captures the `srv` parameter of the exported arrow function. Also see
326+ * `ServiceInstanceFromImplMethodCallClosureParameter` which is similar to this.
327+ */
328+ class ServiceInstanceFromExportedClosureParameter extends ServiceInstance , ParameterNode {
329+ ExportedClosureApplicationServiceDefinition exportedClosure ;
330+
331+ ServiceInstanceFromExportedClosureParameter ( ) { this = exportedClosure .getParameter ( 0 ) }
332+
333+ override UserDefinedApplicationService getDefinition ( ) { result = exportedClosure }
334+ }
335+
336+ /**
337+ * The 0-th parameter of a callback (usually an arrow function) passed to `cds.service.impl` that
338+ * represents the service being implemented. e.g.
339+ * ``` javascript
340+ * const cds = require('@sap/cds')
341+ * module.exports = cds.service.impl((srv) => {
342+ * srv.on("SomeEvent1", (req) => { ... })
343+ * })
344+ * ```
345+ * This class captures the `srv` parameter of the exported arrow function. Also see
346+ * `ServiceInstanceFromExportedClosureParameter` which is similar to this.
347+ */
348+ class ServiceInstanceFromImplMethodCallClosureParameter extends ServiceInstance , ParameterNode {
349+ ImplMethodCallApplicationServiceDefinition implMethodCallApplicationServiceDefinition ;
350+
351+ ServiceInstanceFromImplMethodCallClosureParameter ( ) {
352+ this = implMethodCallApplicationServiceDefinition .getInitFunction ( ) .getParameter ( 0 )
353+ }
354+
355+ override UserDefinedApplicationService getDefinition ( ) {
356+ result = implMethodCallApplicationServiceDefinition
357+ }
358+ }
359+
297360/**
298361 * A call to `before`, `on`, or `after` on an `cds.ApplicationService`.
299362 * It registers an handler to be executed when an event is fired,
300363 * to do something with the incoming request or event as its parameter.
301364 */
302365class HandlerRegistration extends MethodCallNode {
366+ /** The instance of the service a handler is registered on. */
303367 ServiceInstance srv ;
304368 string methodName ;
305369
@@ -308,6 +372,9 @@ class HandlerRegistration extends MethodCallNode {
308372 methodName = [ "before" , "on" , "after" ]
309373 }
310374
375+ /**
376+ * Gets the instance of the service a handler is registered on.
377+ */
311378 ServiceInstance getService ( ) { result = srv }
312379
313380 /**
@@ -347,7 +414,7 @@ class HandlerRegistration extends MethodCallNode {
347414
348415/**
349416 * The first parameter of a handler, representing the request object received either directly
350- * from a user, or from another service that may be internal (defined in the same application)
417+ * from a user, or from another service that may be internal (defined in the same application)
351418 * or external (defined in another application, or even served from a different server).
352419 * e.g.
353420 * ``` javascript
@@ -356,7 +423,7 @@ class HandlerRegistration extends MethodCallNode {
356423 * this.before("SomeEvent", "SomeEntity", (req, next) => { ... });
357424 * this.after("SomeEvent", "SomeEntity", (req, next) => { ... });
358425 * }
359- * ```
426+ * ```
360427 * All parameters named `req` above are captured. Also see `HandlerParameterOfExposedService`
361428 * for a subset of this class that is only about handlers exposed to some protocol.
362429 */
@@ -506,7 +573,7 @@ abstract class UserDefinedApplicationService extends UserDefinedService {
506573 /**
507574 * Holds if this service supports access from the outside through any kind of protocol.
508575 */
509- predicate isExposed ( ) { not this .isInternal ( ) }
576+ predicate isExposed ( ) { exists ( this . getCdsDeclaration ( ) ) and not this .isInternal ( ) }
510577
511578 /**
512579 * Holds if this service does not support access from the outside through any kind of protocol, thus being internal only.
@@ -539,9 +606,21 @@ class ES6ApplicationServiceDefinition extends ClassNode, UserDefinedApplicationS
539606
540607/**
541608 * Subclassing `cds.ApplicationService` via a call to `cds.service.impl`.
542- * ```js
609+ * e.g.1. Given this code:
610+ * ``` javascript
611+ * const cds = require('@sap/cds')
612+ * module.exports = cds.service.impl (function() {
613+ * this.on("SomeEvent1", (req) => { ... })
614+ * })
615+ * ```
616+ * This class captures the call `cds.service.impl (function() { ... })`.
617+ *
618+ * e.g.2. Given this code:
619+ * ``` javascript
543620 * const cds = require('@sap/cds')
544- * module.exports = cds.service.impl (function() { ... })
621+ * module.exports = cds.service.impl ((srv) => {
622+ * srv.on("SomeEvent1", (req) => { ... })
623+ * })
545624 * ```
546625 */
547626class ImplMethodCallApplicationServiceDefinition extends MethodCallNode ,
@@ -554,6 +633,40 @@ class ImplMethodCallApplicationServiceDefinition extends MethodCallNode,
554633 override FunctionNode getInitFunction ( ) { result = this .getArgument ( 0 ) }
555634}
556635
636+ /**
637+ * A user-defined application service that comes in a form of an exported
638+ * closure. e.g. Given the below code,
639+ * ``` javascript
640+ * const cds = require("@sap/cds");
641+ *
642+ * module.exports = (srv) => {
643+ * srv.before("SomeEvent1", "SomeEntity", (req, res) => { ... })
644+ * srv.on("SomeEvent2", (req) => { ... } )
645+ * srv.after("SomeEvent3", (req) => { ... } )
646+ * }
647+ * ```
648+ * This class captures the entire `(srv) => { ... }` function that is
649+ * exported.
650+ */
651+ class ExportedClosureApplicationServiceDefinition extends FunctionNode ,
652+ UserDefinedApplicationService
653+ {
654+ ExportedClosureApplicationServiceDefinition ( ) {
655+ /*
656+ * ==================== HACK ====================
657+ * See issue #221.
658+ */
659+
660+ exists ( PropWrite moduleExports |
661+ moduleExports .getBase ( ) .asExpr ( ) .( VarAccess ) .getName ( ) = "module" and
662+ moduleExports .getPropertyName ( ) = "exports" and
663+ this = moduleExports .getRhs ( )
664+ )
665+ }
666+
667+ override FunctionNode getInitFunction ( ) { result = this }
668+ }
669+
557670abstract class InterServiceCommunicationMethodCall extends MethodCallNode {
558671 string name ;
559672 ServiceInstance recipient ;
0 commit comments