DebugClients/Python/DebugBase.py

branch
debugger speed
changeset 5041
f00a4c8bcbbd
parent 5012
be693f11da53
child 5044
630b9f290a77
--- a/DebugClients/Python/DebugBase.py	Sat Jul 02 21:58:09 2016 +0200
+++ b/DebugClients/Python/DebugBase.py	Sun Jul 17 22:40:53 2016 +0200
@@ -17,6 +17,7 @@
 
 from DebugProtocol import ResponseClearWatch, ResponseClearBreak, \
     ResponseLine, ResponseSyntax, ResponseException, CallTrace
+from BreakpointWatch import Breakpoint, Watch
 
 gRecursionLimit = 64
 
@@ -69,7 +70,6 @@
         self._dbgClient = dbgClient
         self._mainThread = 1
         
-        self.breaks = self._dbgClient.breakpoints
         self.tracePythonLibs(0)
         
         self.__isBroken = False
@@ -261,7 +261,9 @@
                 self.botframe = frame.f_back
                 return self.trace_dispatch
             
-            if not (self.stop_here(frame) or self.break_anywhere(frame)):
+            if not (self.stop_here(frame) or
+                    self.break_anywhere(frame) or
+                    Watch.watches != []):
                 # No need to trace this function
                 return
             if self.quitting:
@@ -371,120 +373,6 @@
             self._fnCache[fn] = fixedName
             return fixedName
 
-    def set_watch(self, cond, temporary=0):
-        """
-        Public method to set a watch expression.
-        
-        @param cond expression of the watch expression (string)
-        @param temporary flag indicating a temporary watch expression (boolean)
-        """
-        bp = bdb.Breakpoint("Watch", 0, temporary, cond)
-        if cond.endswith('??created??') or cond.endswith('??changed??'):
-            bp.condition, bp.special = cond.split()
-        else:
-            bp.condition = cond
-            bp.special = ""
-        bp.values = {}
-        if "Watch" not in self.breaks:
-            self.breaks["Watch"] = 1
-        else:
-            self.breaks["Watch"] += 1
-    
-    def clear_watch(self, cond):
-        """
-        Public method to clear a watch expression.
-        
-        @param cond expression of the watch expression to be cleared (string)
-        """
-        try:
-            possibles = bdb.Breakpoint.bplist["Watch", 0]
-            for i in range(0, len(possibles)):
-                b = possibles[i]
-                if b.cond == cond:
-                    b.deleteMe()
-                    self.breaks["Watch"] -= 1
-                    if self.breaks["Watch"] == 0:
-                        del self.breaks["Watch"]
-                    break
-        except KeyError:
-            pass
-    
-    def get_watch(self, cond):
-        """
-        Public method to get a watch expression.
-        
-        @param cond expression of the watch expression to be cleared (string)
-        @return reference to the watch point
-        """
-        possibles = bdb.Breakpoint.bplist["Watch", 0]
-        for i in range(0, len(possibles)):
-            b = possibles[i]
-            if b.cond == cond:
-                return b
-    
-    def __do_clearWatch(self, cond):
-        """
-        Private method called to clear a temporary watch expression.
-        
-        @param cond expression of the watch expression to be cleared (string)
-        """
-        self.clear_watch(cond)
-        self._dbgClient.write('%s%s\n' % (ResponseClearWatch, cond))
-
-    def __effective(self, frame):
-        """
-        Private method to determine, if a watch expression is effective.
-        
-        @param frame the current execution frame
-        @return tuple of watch expression and a flag to indicate, that a
-            temporary watch expression may be deleted (bdb.Breakpoint, boolean)
-        """
-        possibles = bdb.Breakpoint.bplist["Watch", 0]
-        for i in range(0, len(possibles)):
-            b = possibles[i]
-            if b.enabled == 0:
-                continue
-            if not b.cond:
-                # watch expression without expression shouldn't occur,
-                # just ignore it
-                continue
-            try:
-                val = eval(b.condition, frame.f_globals, frame.f_locals)
-                if b.special:
-                    if b.special == '??created??':
-                        if b.values[frame][0] == 0:
-                            b.values[frame][0] = 1
-                            b.values[frame][1] = val
-                            return (b, 1)
-                        else:
-                            continue
-                    b.values[frame][0] = 1
-                    if b.special == '??changed??':
-                        if b.values[frame][1] != val:
-                            b.values[frame][1] = val
-                            if b.values[frame][2] > 0:
-                                b.values[frame][2] -= 1
-                                continue
-                            else:
-                                return (b, 1)
-                        else:
-                            continue
-                    continue
-                if val:
-                    if b.ignore > 0:
-                        b.ignore -= 1
-                        continue
-                    else:
-                        return (b, 1)
-            except Exception:
-                if b.special:
-                    try:
-                        b.values[frame][0] = 0
-                    except KeyError:
-                        b.values[frame] = [0, None, b.ignore]
-                continue
-        return (None, None)
-    
     def break_here(self, frame):
         """
         Public method reimplemented from bdb.py to fix the filename from the
@@ -493,33 +381,29 @@
         See fix_frame_filename for more info.
         
         @param frame the frame object
-        @return flag indicating the break status (boolean)
+        @type frame object
+        @return flag indicating the break status
+        @rtype bool
         """
         filename = self.fix_frame_filename(frame)
-        if filename not in self.breaks and "Watch" not in self.breaks:
-            return 0
-        
-        if filename in self.breaks:
-            lineno = frame.f_lineno
-            if lineno in self.breaks[filename]:
+        if (filename, frame.f_lineno) in Breakpoint.breaks:
+            bp, flag = Breakpoint.effectiveBreak(
+                filename, frame.f_lineno, frame)
+            if bp:
                 # flag says ok to delete temp. bp
-                (bp, flag) = bdb.effective(filename, lineno, frame)
-                if bp:
-                    self.currentbp = bp.number
-                    if (flag and bp.temporary):
-                        self.__do_clear(filename, lineno)
-                    return 1
+                if flag and bp.temporary:
+                    self.__do_clearBreak(filename, frame.f_lineno)
+                return True
         
-        if "Watch" in self.breaks:
-            # flag says ok to delete temp. bp
-            (bp, flag) = self.__effective(frame)
+        if Watch.watches != []:
+            bp, flag = Watch.effectiveWatch(frame)
             if bp:
-                self.currentbp = bp.number
-                if (flag and bp.temporary):
+                # flag says ok to delete temp. watch
+                if flag and bp.temporary:
                     self.__do_clearWatch(bp.cond)
-                return 1
+                return True
         
-        return 0
+        return False
 
     def break_anywhere(self, frame):
         """
@@ -529,81 +413,35 @@
         (see fix_frame_filename for more info).
         
         @param frame the frame object
-        @return flag indicating the break status (boolean)
-        """
-        return \
-            self.fix_frame_filename(frame) in self.breaks or \
-            ("Watch" in self.breaks and self.breaks["Watch"])
-
-    def set_break(self, filename, lineno, temporary=0, cond=None,
-                  funcname=None):
-        """
-        Public method reimplemented from bdb.py to normalize the filename and
-        set as a breakpoint.
-        
-        @param filename the filename where a breakpoint is set
-        @type str
-        @param lineno the line number of the breakpoint
-        @type int
-        @keyparam temporary flag to indicate a temporary breakpoint
-        @type int
-        @keyparam cond Python expression which dynamically enables this bp
-        @type str
-        @keyparam funcname name of the function (unused)
-        @type str or None
-        """
-        filename = os.path.abspath(filename)
-        list = self.breaks.setdefault(filename, [])
-        if lineno not in list:
-            list.append(lineno)
-        bdb.Breakpoint(filename, lineno, temporary, cond, funcname)
-
-    def get_break(self, filename, lineno):
+        @type frame object
+        @return flag indicating the break status
+        @rtype bool
         """
-        Public method reimplemented from bdb.py to get the first breakpoint of
-        a particular line.
-        
-        Because eric6 supports only one breakpoint per line, this overwritten
-        method will return this one and only breakpoint.
-        
-        @param filename the filename of the bp to retrieve
-        @type str
-        @param lineno the linenumber of the bp to retrieve
-        @type int
-        @return breakpoint or None, if there is no bp
-        @rtype breakpoint object or None
-        """
-        return (lineno in self.breaks.get(filename, []) and
-                bdb.Breakpoint.bplist[filename, lineno][0] or None)
-    
-    def clear_break(self, filename, lineno):
-        """
-        Public method reimplemented from bdb.py to clear a breakpoint.
-        
-        @param filename the filename of the bp to retrieve
-        @type str
-        @param lineno the linenumber of the bp to retrieve
-        @type int
-        """
-        if (filename, lineno) not in bdb.Breakpoint.bplist:
-            return
-        # If there's only one bp in the list for that file,line
-        # pair, then remove the breaks entry
-        for bp in bdb.Breakpoint.bplist[filename, lineno][:]:
-            bp.deleteMe()
-        self._prune_breaks(filename, lineno)
+        return self.fix_frame_filename(frame) in Breakpoint.breakInFile
 
-    def __do_clear(self, filename, lineno):
+    def __do_clearBreak(self, filename, lineno):
         """
         Private method called to clear a temporary breakpoint.
         
         @param filename name of the file the bp belongs to
+        @type str
         @param lineno linenumber of the bp
+        @type int
         """
-        self.clear_break(filename, lineno)
+        Breakpoint.clear_break(filename, lineno)
         self._dbgClient.write('%s%s,%d\n' % (ResponseClearBreak, filename,
                                              lineno))
 
+    def __do_clearWatch(self, cond):
+        """
+        Private method called to clear a temporary watch expression.
+        
+        @param cond expression of the watch expression to be cleared
+        @type str
+        """
+        Watch.clear_watch(cond)
+        self._dbgClient.write('%s%s\n' % (ResponseClearWatch, cond))
+
     def getStack(self):
         """
         Public method to get the stack.
@@ -887,6 +725,7 @@
         """
         return self.__isBroken
 
+
 #
 # eflag: FileType = Python2
 # eflag: noqa = M601, M702

eric ide

mercurial