@@ -177,7 +177,27 @@ class ServiceInstanceFromConstructor extends ServiceInstance {
177
177
}
178
178
179
179
/**
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(...)`.
181
201
*/
182
202
class ServiceInstanceFromThisNode extends ServiceInstance , ThisNode {
183
203
UserDefinedApplicationService userDefinedApplicationService ;
@@ -294,12 +314,56 @@ class DbServiceInstanceFromCdsConnectTo extends ServiceInstanceFromCdsConnectTo,
294
314
override UserDefinedApplicationService getDefinition ( ) { none ( ) }
295
315
}
296
316
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
+
297
360
/**
298
361
* A call to `before`, `on`, or `after` on an `cds.ApplicationService`.
299
362
* It registers an handler to be executed when an event is fired,
300
363
* to do something with the incoming request or event as its parameter.
301
364
*/
302
365
class HandlerRegistration extends MethodCallNode {
366
+ /** The instance of the service a handler is registered on. */
303
367
ServiceInstance srv ;
304
368
string methodName ;
305
369
@@ -308,6 +372,9 @@ class HandlerRegistration extends MethodCallNode {
308
372
methodName = [ "before" , "on" , "after" ]
309
373
}
310
374
375
+ /**
376
+ * Gets the instance of the service a handler is registered on.
377
+ */
311
378
ServiceInstance getService ( ) { result = srv }
312
379
313
380
/**
@@ -347,7 +414,7 @@ class HandlerRegistration extends MethodCallNode {
347
414
348
415
/**
349
416
* 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)
351
418
* or external (defined in another application, or even served from a different server).
352
419
* e.g.
353
420
* ``` javascript
@@ -356,7 +423,7 @@ class HandlerRegistration extends MethodCallNode {
356
423
* this.before("SomeEvent", "SomeEntity", (req, next) => { ... });
357
424
* this.after("SomeEvent", "SomeEntity", (req, next) => { ... });
358
425
* }
359
- * ```
426
+ * ```
360
427
* All parameters named `req` above are captured. Also see `HandlerParameterOfExposedService`
361
428
* for a subset of this class that is only about handlers exposed to some protocol.
362
429
*/
@@ -506,7 +573,7 @@ abstract class UserDefinedApplicationService extends UserDefinedService {
506
573
/**
507
574
* Holds if this service supports access from the outside through any kind of protocol.
508
575
*/
509
- predicate isExposed ( ) { not this .isInternal ( ) }
576
+ predicate isExposed ( ) { exists ( this . getCdsDeclaration ( ) ) and not this .isInternal ( ) }
510
577
511
578
/**
512
579
* 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
539
606
540
607
/**
541
608
* 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
543
620
* 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
+ * })
545
624
* ```
546
625
*/
547
626
class ImplMethodCallApplicationServiceDefinition extends MethodCallNode ,
@@ -554,6 +633,40 @@ class ImplMethodCallApplicationServiceDefinition extends MethodCallNode,
554
633
override FunctionNode getInitFunction ( ) { result = this .getArgument ( 0 ) }
555
634
}
556
635
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
+
557
670
abstract class InterServiceCommunicationMethodCall extends MethodCallNode {
558
671
string name ;
559
672
ServiceInstance recipient ;
0 commit comments