From 1e54e457d49ee702bdf2885bbd6167d11f242c06 Mon Sep 17 00:00:00 2001 From: Ben Jackson Date: Tue, 23 Jul 2019 22:45:35 +0100 Subject: [PATCH] Finally fix breakpoint bugs --- python3/vimspector/breakpoints.py | 35 ++++++++++++++------ python3/vimspector/debug_session.py | 20 +++++++---- tests/breakpoints.test.vim | 21 +++++++++--- tests/lib/autoload/vimspector/test/signs.vim | 8 ++--- tests/lib/run_test.vim | 7 +++- 5 files changed, 63 insertions(+), 28 deletions(-) diff --git a/python3/vimspector/breakpoints.py b/python3/vimspector/breakpoints.py index ede8a62..7973032 100644 --- a/python3/vimspector/breakpoints.py +++ b/python3/vimspector/breakpoints.py @@ -15,6 +15,7 @@ from collections import defaultdict +import abc import vim import os import logging @@ -23,6 +24,16 @@ import json from vimspector import utils +class ServerBreakpointHandler( object ): + @abc.abstractmethod + def ClearBreakpoints( self ): + pass + + @abc.abstractmethod + def AddBreakpoints( self, source, message ): + pass + + class ProjectBreakpoints( object ): def __init__( self ): self._connection = None @@ -118,21 +129,26 @@ class ProjectBreakpoints( object ): return found_bp = False + action = 'New' for index, bp in enumerate( self._line_breakpoints[ file_name ] ): if bp[ 'line' ] == line: found_bp = True - if bp[ 'state' ] == 'ENABLED': + if bp[ 'state' ] == 'ENABLED' and not self._connection: bp[ 'state' ] = 'DISABLED' + action = 'Disable' else: if 'sign_id' in bp: vim.command( 'sign unplace {0} group=VimspectorBP'.format( bp[ 'sign_id' ] ) ) del self._line_breakpoints[ file_name ][ index ] + action = 'Delete' + break - self._logger.debug( "Toggle found bp at {}:{} ? {}".format( + self._logger.debug( "Toggle found bp at {}:{} ? {} ({})".format( file_name, line, - found_bp ) ) + found_bp, + action ) ) if not found_bp: self._line_breakpoints[ file_name ].append( { @@ -172,13 +188,10 @@ class ProjectBreakpoints( object ): def SendBreakpoints( self ): - if not self._breakpoints_handler: - def handler( source, msg ): - return self._ShowBreakpoints() + assert self._breakpoints_handler is not None - assert False - else: - handler = self._breakpoints_handler + # Clear any existing breakpoints prior to sending new ones + self._breakpoints_handler.ClearBreakpoints() for file_name, line_breakpoints in self._line_breakpoints.items(): breakpoints = [] @@ -199,7 +212,7 @@ class ProjectBreakpoints( object ): } self._connection.DoRequest( - lambda msg: handler( source, msg ), + lambda msg: self._breakpoints_handler.AddBreakpoints( source, msg ), { 'command': 'setBreakpoints', 'arguments': { @@ -212,7 +225,7 @@ class ProjectBreakpoints( object ): if self._server_capabilities.get( 'supportsFunctionBreakpoints' ): self._connection.DoRequest( - lambda msg: handler( None, msg ), + lambda msg: self._breakpoints_handler.AddBreakpoints( None, msg ), { 'command': 'setFunctionBreakpoints', 'arguments': { diff --git a/python3/vimspector/debug_session.py b/python3/vimspector/debug_session.py index 95d2800..08add06 100644 --- a/python3/vimspector/debug_session.py +++ b/python3/vimspector/debug_session.py @@ -183,14 +183,20 @@ class DebugSession( object ): self._outputView.ConnectionUp( self._connection ) self._breakpoints.ConnectionUp( self._connection ) - def update_breakpoints( source, message ): - if 'body' not in message: - return - self._codeView.AddBreakpoints( source, - message[ 'body' ][ 'breakpoints' ] ) - self._codeView.ShowBreakpoints() + class Handler( breakpoints.ServerBreakpointHandler ): + def __init__( self, codeView ): + self.codeView = codeView - self._breakpoints.SetBreakpointsHandler( update_breakpoints ) + def ClearBreakpoints( self ): + self.codeView.ClearBreakpoints() + + def AddBreakpoints( self, source, message ): + if 'body' not in message: + return + self.codeView.AddBreakpoints( source, + message[ 'body' ][ 'breakpoints' ] ) + + self._breakpoints.SetBreakpointsHandler( Handler( self._codeView ) ) if self._connection: self._StopDebugAdapter( start ) diff --git a/tests/breakpoints.test.vim b/tests/breakpoints.test.vim index c8efff0..61ef079 100644 --- a/tests/breakpoints.test.vim +++ b/tests/breakpoints.test.vim @@ -182,14 +182,25 @@ function Test_DisableBreakpointWhileDebugging() " Remove the breakpoint call feedkeys( "\", 'xt' ) - call vimspector#test#signs#AssertSignGroupEmptyAtLine( 'VimspectorCode', 16 ) + call WaitForAssert( {-> + \ vimspector#test#signs#AssertSignGroupEmptyAtLine( 'VimspectorCode', + \ 16 ) + \ } ) " Add the breakpoint call feedkeys( "\", 'xt' ) - call vimspector#test#signs#AssertSignGroupSingletonAtLine( - \ 'VimspectorCode', - \ 16, - \ 'vimspectorBP' ) + call WaitForAssert( {-> + \ vimspector#test#signs#AssertSignGroupSingletonAtLine( + \ 'VimspectorCode', + \ 16, + \ 'vimspectorBP' ) + \ } ) + + " Run to breakpoint + call setpos( '.', [ 0, 15, 1 ] ) + call feedkeys( "\", 'xt' ) + call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 16, 1 ) + call vimspector#test#signs#AssertPCIsAtLineInBuffer( 'simple.cpp', 16 ) call vimspector#Reset() call WaitForAssert( {-> diff --git a/tests/lib/autoload/vimspector/test/signs.vim b/tests/lib/autoload/vimspector/test/signs.vim index 9d3d200..6a67dad 100644 --- a/tests/lib/autoload/vimspector/test/signs.vim +++ b/tests/lib/autoload/vimspector/test/signs.vim @@ -46,10 +46,10 @@ function! vimspector#test#signs#AssertSignGroupSingletonAtLine( group, return assert_equal( 1, \ len( signs ), - \ 'Num buffers named %' ) && + \ 'Num buffers named %' ) || \ assert_equal( 1, \ len( signs[ 0 ].signs ), - \ 'Num signs in ' . a:group . ' at ' . a:line ) && + \ 'Num signs in ' . a:group . ' at ' . a:line ) || \ assert_equal( a:sign_name, \ signs[ 0 ].signs[ 0 ].name, \ 'Sign in group ' . a:group . ' at ' . a:line ) @@ -64,7 +64,7 @@ function! vimspector#test#signs#AssertSignGroupEmptyAtLine( group, line ) abort return assert_equal( 1, \ len( signs ), - \ 'Num buffers named %' ) && + \ 'Num buffers named %' ) || \ assert_equal( 0, \ len( signs[ 0 ].signs ), \ 'Num signs in ' . a:group . ' at ' . a:line ) @@ -77,7 +77,7 @@ function! vimspector#test#signs#AssertSignGroupEmpty( group ) abort \ } ) return assert_equal( 1, \ len( signs ), - \ 'Num buffers named %' ) && + \ 'Num buffers named %' ) || \ assert_equal( 0, \ len( signs[ 0 ].signs ), \ 'Num signs in ' . a:group ) diff --git a/tests/lib/run_test.vim b/tests/lib/run_test.vim index 1107ded..ffe1e9c 100644 --- a/tests/lib/run_test.vim +++ b/tests/lib/run_test.vim @@ -116,6 +116,11 @@ func RunTheTest(test) try let s:test = a:test let s:testid = g:testpath . ':' . a:test + let test_filesafe = substitute( a:test, ')', '_', 'g' ) + let test_filesafe = substitute( test_filesafe, '(', '_', 'g' ) + let test_filesafe = substitute( test_filesafe, ',', '_', 'g' ) + let test_filesafe = substitute( test_filesafe, ':', '_', 'g' ) + let s:testid_filesafe = g:testpath . '_' . test_filesafe au VimLeavePre * call EarlyExit(s:test) exe 'call ' . a:test au! VimLeavePre @@ -203,7 +208,7 @@ func AfterTheTest() let v:errors = [] let log = readfile( expand( '~/.vimspector.log' ) ) - let logfile = s:testid . '.vimspector.log' + let logfile = s:testid_filesafe . '.vimspector.log' call writefile( log, logfile, 's' ) call add( s:messages, 'Wrote log for failed test: ' . logfile ) endif