Add a way to have adapter specific message handlers

This commit is contained in:
Ben Jackson 2021-02-26 19:21:40 +00:00
commit cb0fdc7613
5 changed files with 67 additions and 22 deletions

View file

@ -0,0 +1,34 @@
# vimspector - A multi-language debugging system for Vim
# Copyright 2021 Ben Jackson
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from vimspector.debug_session import DebugSession
from vimspector import utils
class JavaDebugAdapter( object ):
def __init__( self, debug_session: DebugSession ):
self.debug_session = debug_session
def OnEvent_hotcodereplace( self, message ):
# Hack for java debug server hot-code-replace
if utils.Call( 'confirm',
'Code has changed, hot reload?',
'&Yes,&No',
1,
'Question' ) == 1:
self.debug_session._connection.DoRequest( None, {
'command': 'redefineClasses',
'arguments': {},
} )

View file

@ -29,14 +29,14 @@ class PendingRequest( object ):
class DebugAdapterConnection( object ): class DebugAdapterConnection( object ):
def __init__( self, handler, send_func ): def __init__( self, handlers, send_func ):
self._logger = logging.getLogger( __name__ ) self._logger = logging.getLogger( __name__ )
utils.SetUpLogging( self._logger ) utils.SetUpLogging( self._logger )
self._Write = send_func self._Write = send_func
self._SetState( 'READ_HEADER' ) self._SetState( 'READ_HEADER' )
self._buffer = bytes() self._buffer = bytes()
self._handler = handler self._handlers = handlers
self._next_message_id = 0 self._next_message_id = 0
self._outstanding_requests = {} self._outstanding_requests = {}
@ -124,7 +124,7 @@ class DebugAdapterConnection( object ):
def Reset( self ): def Reset( self ):
self._Write = None self._Write = None
self._handler = None self._handlers = None
while self._outstanding_requests: while self._outstanding_requests:
_, request = self._outstanding_requests.popitem() _, request = self._outstanding_requests.popitem()
@ -237,7 +237,7 @@ class DebugAdapterConnection( object ):
def _OnMessageReceived( self, message ): def _OnMessageReceived( self, message ):
if not self._handler: if not self._handlers:
return return
if message[ 'type' ] == 'response': if message[ 'type' ] == 'response':
@ -270,25 +270,21 @@ class DebugAdapterConnection( object ):
self._logger.error( 'Request failed: {0}'.format( reason ) ) self._logger.error( 'Request failed: {0}'.format( reason ) )
if request.failure_handler: if request.failure_handler:
request.failure_handler( reason, message ) request.failure_handler( reason, message )
elif 'OnFailure' in dir( self._handler ):
self._handler.OnFailure( reason, request.msg, message )
else: else:
utils.UserMessage( 'Request failed: {0}'.format( reason ) ) for h in self._handlers:
if 'OnFailure' in dir( h ):
h.OnFailure( reason, request.msg, message )
elif message[ 'type' ] == 'event': elif message[ 'type' ] == 'event':
method = 'OnEvent_' + message[ 'event' ] method = 'OnEvent_' + message[ 'event' ]
if method in dir( self._handler ): for h in self._handlers:
getattr( self._handler, method )( message ) if method in dir( h ):
else: getattr( h, method )( message )
utils.UserMessage( 'Unhandled event: {0}'.format( message[ 'event' ] ),
persist = True )
elif message[ 'type' ] == 'request': elif message[ 'type' ] == 'request':
method = 'OnRequest_' + message[ 'command' ] method = 'OnRequest_' + message[ 'command' ]
if method in dir( self._handler ): for h in self._handlers:
getattr( self._handler, method )( message ) if method in dir( h ):
else: getattr( h, method )( message )
utils.UserMessage(
'Unhandled request: {0}'.format( message[ 'command' ] ),
persist = True )
def _KillTimer( request ): def _KillTimer( request ):

View file

@ -21,6 +21,7 @@ import shlex
import subprocess import subprocess
import functools import functools
import vim import vim
import importlib
from vimspector import ( breakpoints, from vimspector import ( breakpoints,
code, code,
@ -781,8 +782,21 @@ class DebugSession( object ):
self._splash_screen, self._splash_screen,
"Unable to start adapter" ) "Unable to start adapter" )
else: else:
if 'custom_handler' in self._adapter:
spec = self._adapter[ 'custom_handler' ]
if isinstance( spec, dict ):
module = spec[ 'module' ]
cls = spec[ 'class' ]
else:
module, cls = spec.rsplit( '.', 1 )
CustomHandler = getattr( importlib.import_module( module ), cls )
handlers = [ CustomHandler( self ), self ]
else:
handlers = [ self ]
self._connection = debug_adapter_connection.DebugAdapterConnection( self._connection = debug_adapter_connection.DebugAdapterConnection(
self, handlers,
lambda msg: utils.Call( lambda msg: utils.Call(
"vimspector#internal#{}#Send".format( self._connection_type ), "vimspector#internal#{}#Send".format( self._connection_type ),
msg ) ) msg ) )

View file

@ -159,7 +159,8 @@ GADGETS = {
"port": "${DAPPort}", "port": "${DAPPort}",
"configuration": { "configuration": {
"cwd": "${workspaceRoot}" "cwd": "${workspaceRoot}"
} },
'custom_handler': 'vimspector.custom.java.JavaDebugAdapter'
} }
}, },
}, },

View file

@ -4,7 +4,7 @@
<artifactId>TestApplication</artifactId> <artifactId>TestApplication</artifactId>
<version>1</version> <version>1</version>
<properties> <properties>
<maven.compiler.source>8</maven.compiler.source> <maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target> <maven.compiler.target>11</maven.compiler.target>
</properties> </properties>
</project> </project>