@@ -135,6 +135,8 @@ module Tornado {
135135 API:: Node subclassRef ( ) {
136136 result = web ( ) .getMember ( "RequestHandler" ) .getASubclass * ( )
137137 or
138+ result = WebSocket:: WebSocketHandler:: subclassRef ( )
139+ or
138140 result = ModelOutput:: getATypeNode ( "tornado.web.RequestHandler~Subclass" ) .getASubclass * ( )
139141 }
140142
@@ -428,6 +430,49 @@ module Tornado {
428430 }
429431 }
430432 }
433+
434+ // ---------------------------------------------------------------------------
435+ // tornado.websocket
436+ // ---------------------------------------------------------------------------
437+ /** Gets a reference to the `tornado.websocket` module. */
438+ API:: Node websocket ( ) { result = Tornado:: tornado ( ) .getMember ( "websocket" ) }
439+
440+ /** Provides models for the `tornado.websocket` module */
441+ module WebSocket {
442+ /**
443+ * Provides models for the `tornado.websocket.WebSocketHandler` class and subclasses.
444+ *
445+ * See https://www.tornadoweb.org/en/stable/websocket.html#tornado.websocket.WebSocketHandler.
446+ */
447+ module WebSocketHandler {
448+ /** Gets a reference to the `tornado.websocket.WebSocketHandler` class or any subclass. */
449+ API:: Node subclassRef ( ) {
450+ result = websocket ( ) .getMember ( "WebSocketHandler" ) .getASubclass * ( )
451+ or
452+ result =
453+ ModelOutput:: getATypeNode ( "tornado.websocket.WebSocketHandler~Subclass" ) .getASubclass * ( )
454+ }
455+
456+ /** A subclass of `tornado.websocket.WebSocketHandler`. */
457+ class WebSocketHandlerClass extends Web:: RequestHandler:: RequestHandlerClass {
458+ WebSocketHandlerClass ( ) { this .getParent ( ) = subclassRef ( ) .asSource ( ) .asExpr ( ) }
459+
460+ override Function getARequestHandler ( ) {
461+ result = super .getARequestHandler ( )
462+ or
463+ result = this .getAMethod ( ) and
464+ result .getName ( ) = "open"
465+ }
466+
467+ /** Gets a function that could handle incoming WebSocket events, if any. */
468+ Function getAWebSocketEventHandler ( ) {
469+ result = this .getAMethod ( ) and
470+ result .getName ( ) =
471+ [ "on_message" , "on_close" , "on_ping" , "on_pong" , "select_subprotocol" , "check_origin" ]
472+ }
473+ }
474+ }
475+ }
431476 }
432477
433478 // ---------------------------------------------------------------------------
@@ -542,6 +587,27 @@ module Tornado {
542587 override string getFramework ( ) { result = "Tornado" }
543588 }
544589
590+ /** A request handler for WebSocket events. */
591+ private class TornadoWebSocketEventHandler extends Http:: Server:: RequestHandler:: Range {
592+ TornadoWebSocketEventHandler ( ) {
593+ exists ( TornadoModule:: WebSocket:: WebSocketHandler:: WebSocketHandlerClass cls |
594+ cls .getAWebSocketEventHandler ( ) = this
595+ )
596+ }
597+
598+ override Parameter getARoutedParameter ( ) {
599+ // The `open` method is handled as a normal request handler in `TornadoRouteSetup` or `TornadoRequestHandlerWithoutKnownRoute`.
600+ // For other event handlers (such as `on_message`), all parameters should be remote flow sources, as they are not affected by routing.
601+ result in [
602+ this .getArg ( _) , this .getArgByName ( _) , this .getVararg ( ) .( Parameter ) ,
603+ this .getKwarg ( ) .( Parameter )
604+ ] and
605+ not result = this .getArg ( 0 )
606+ }
607+
608+ override string getFramework ( ) { result = "Tornado" }
609+ }
610+
545611 // ---------------------------------------------------------------------------
546612 // Response modeling
547613 // ---------------------------------------------------------------------------
0 commit comments