Debugger/DebugServer.py

changeset 4553
a6b2acd1a355
parent 4495
b99a70d5cb4b
child 4554
f3428ddd577c
diff -r b1ea4ea0190e -r a6b2acd1a355 Debugger/DebugServer.py
--- a/Debugger/DebugServer.py	Sat Nov 07 15:54:09 2015 +0100
+++ b/Debugger/DebugServer.py	Sun Nov 08 17:01:39 2015 +0100
@@ -30,12 +30,11 @@
 import Utilities
 
 
-DebuggerInterfaces = [
-    "DebuggerInterfacePython",
-    "DebuggerInterfacePython3",
-    ##    "DebuggerInterfaceRuby",
-    "DebuggerInterfaceNone",
-]
+DebuggerInterfaces = {
+    "Python": "DebuggerInterfacePython",
+    "Python3": "DebuggerInterfacePython3",
+    "None": "DebuggerInterfaceNone",
+}
 
 
 class DebugServer(QTcpServer):
@@ -161,6 +160,13 @@
         """
         super(DebugServer, self).__init__()
         
+        self.__debuggerInterfaceRegistry = {}
+        # the client language is the key, a list containing the client
+        # capabilities, the list of associated file extensions, a
+        # function reference to create the debugger interface (see
+        # __createDebuggerInterface() below) and a function to be called
+        # to get the registration data as values
+        
         # create our models
         self.breakpointModel = BreakPointModel(self)
         self.watchpointModel = WatchPointModel(self)
@@ -282,44 +288,81 @@
         """
         Public slot to handle the preferencesChanged signal.
         """
-        # TODO: eric 6.2: change this to call all registered debugger
-        #       interfaces getRegistryData() method ignoring the client
-        #       language and update the client capabilities and client
-        #       associations.
-        self.__registerDebuggerInterfaces()
+        registeredInterfaces = {}
+        for language in self.__debuggerInterfaceRegistry:
+            registeredInterfaces[language] = \
+                self.__debuggerInterfaceRegistry[language][-1]
+                # last entry is the registry data function
+        
+        self.__debuggerInterfaceRegistry = {}
+        for language, getRegistryData in registeredInterfaces.items():
+            self.registerDebuggerInterface(language, getRegistryData)
+        
+    def registerDebuggerInterface(self, name, getRegistryData):
+        """
+        Public method to register a debugger interface.
+        
+        @param name name of the debugger interface
+        @type str
+        @param getRegistryData reference to a function to be called
+            to get the debugger interface details. This method shall
+            return the client language, the client capabilities, the
+            list of associated file extensions and a function reference
+            to create the debugger interface (see __createDebuggerInterface())
+        @type function
+        """
+        if name in self.__debuggerInterfaceRegistry:
+            E5MessageBox.warning(
+                None,
+                self.tr("Register Debugger Interface"),
+                self.tr("""<p>The debugger interface <b>{0}</b> has already"""
+                        """ been registered. Ignoring this request.</p>"""))
+            return
+        
+        clientLanguage, clientCapabilities, clientExtensions, \
+        interfaceCreator = getRegistryData()
+        if clientLanguage:
+            self.__debuggerInterfaceRegistry[clientLanguage] = \
+                [clientCapabilities, clientExtensions, interfaceCreator, 
+                 getRegistryData]
+        
+    def unregisterDebuggerInterface(self, name):
+        """
+        Private method to unregister a debugger interface.
+        
+        @param name name of the debugger interface
+        @type str
+        """
+        if name in self.__debuggerInterfaceRegistry:
+            del self.__debuggerInterfaceRegistry[name]
+        
+    def __findLanguageForExtension(self, ext):
+        """
+        Private method to get the language associated with a file extension.
+        
+        @param ext file extension
+        @type str
+        @return associated language
+        @rtype str
+        """
+        for language in self.__debuggerInterfaceRegistry:
+            if ext in self.__debuggerInterfaceRegistry[language][1]:
+                return language
+        
+        return ""
         
     def __registerDebuggerInterfaces(self):
         """
-        Private method to register the available debugger interface modules.
+        Private method to register the available internal debugger interfaces.
         """
-        self.__clientCapabilities = {}
-        self.__clientAssociations = {}
-        # TODO: eric 6.2: Add a debugger interface registry dictionary with the
-        #       debugger name (language) as a key
-        # TODO: eric 6.2: Add a registerDebuggerInterface() method taking a
-        #       name and a getRegistryData() method. This method should be
-        #       called when a debugger backend plug-in is activated.
-        #       getRegistryData() shall return the client language, the client
-        #       capabilities, the list of associated file extensions and a
-        #       function reference to create the debugger interface (see
-        #       __createDebuggerInterface() below
-        # TODO: eric 6.2: Add an unregisterDebuggerInterface() method with a
-        #       name as parameter to revert the above.
-        
-        for interface in DebuggerInterfaces:
+        for name, interface in DebuggerInterfaces.items():
             modName = "Debugger.{0}".format(interface)
             mod = __import__(modName)
             components = modName.split('.')
             for comp in components[1:]:
                 mod = getattr(mod, comp)
             
-            clientLanguage, clientCapabilities, clientExtensions = \
-                mod.getRegistryData()
-            if clientLanguage:
-                self.__clientCapabilities[clientLanguage] = clientCapabilities
-                for extension in clientExtensions:
-                    if extension not in self.__clientAssociations:
-                        self.__clientAssociations[extension] = clientLanguage
+            self.registerDebuggerInterface(name, mod.getRegistryData)
         
     def getSupportedLanguages(self, shellOnly=False):
         """
@@ -329,7 +372,7 @@
             interactive shell should be returned
         @return list of supported languages (list of strings)
         """
-        languages = list(self.__clientCapabilities.keys())
+        languages = list(self.__debuggerInterfaceRegistry.keys())
         try:
             languages.remove("None")
         except ValueError:
@@ -338,7 +381,7 @@
         if shellOnly:
             languages = \
                 [lang for lang in languages
-                 if self.__clientCapabilities[lang] &
+                 if self.__debuggerInterfaceRegistry[lang][0] &
                     DebugClientCapabilities.HasShell]
         
         return languages[:]
@@ -351,12 +394,10 @@
         @return tuple of extensions associated with the language
             (tuple of strings)
         """
-        extensions = []
-        for ext, lang in list(self.__clientAssociations.items()):
-            if lang == language:
-                extensions.append(ext)
-        
-        return tuple(extensions)
+        if language in self.__debuggerInterfaceRegistry:
+            return tuple(self.__debuggerInterfaceRegistry[language][1])
+        else:
+            return tuple()
         
     def __createDebuggerInterface(self, clientType=None):
         """
@@ -364,31 +405,17 @@
         
         @param clientType type of the client interface to be created (string)
         """
-        # TODO: eric 6.2: make debugger interfaces be registered in order to
-        # allow to implement a debugger backend as a plug-in.
         if self.lastClientType != self.clientType or clientType is not None:
             if clientType is None:
                 clientType = self.clientType
-            if clientType == "Python2":
-                from .DebuggerInterfacePython import DebuggerInterfacePython
-                self.debuggerInterface = DebuggerInterfacePython(
-                    self, self.passive)
-            elif clientType == "Python3":
-                from .DebuggerInterfacePython3 import DebuggerInterfacePython3
-                self.debuggerInterface = DebuggerInterfacePython3(
-                    self, self.passive)
-            elif clientType == "Ruby":
-                from .DebuggerInterfaceRuby import DebuggerInterfaceRuby
-                self.debuggerInterface = DebuggerInterfaceRuby(
-                    self, self.passive)
-            elif clientType == "None":
-                from .DebuggerInterfaceNone import DebuggerInterfaceNone
-                self.debuggerInterface = DebuggerInterfaceNone(
-                    self, self.passive)
+            if clientType in self.__debuggerInterfaceRegistry:
+                self.debuggerInterface = \
+                    self.__debuggerInterfaceRegistry[clientType][2](
+                        self, self.passive)
             else:
-                from .DebuggerInterfaceNone import DebuggerInterfaceNone
-                self.debuggerInterface = DebuggerInterfaceNone(
-                    self, self.passive)
+                self.debuggerInterface = \
+                    self.__debuggerInterfaceRegistry["None"][2](
+                        self, self.passive)
                 self.clientType = "None"
         
     def __setClientType(self, clType):
@@ -674,7 +701,7 @@
         @return debug client capabilities (integer)
         """
         try:
-            return self.__clientCapabilities[type]
+            return self.__debuggerInterfaceRegistry[type][0]
         except KeyError:
             return 0    # no capabilities
         
@@ -792,7 +819,7 @@
                 self.__setClientType(clientType)
             else:
                 self.__setClientType(
-                    self.__clientAssociations[os.path.splitext(fn)[1]])
+                    self.__findLanguageForExtension(os.path.splitext(fn)[1]))
         except KeyError:
             self.__setClientType('Python3')    # assume it is a Python3 file
         self.startClient(False, forProject=forProject,
@@ -837,7 +864,7 @@
                 self.__setClientType(clientType)
             else:
                 self.__setClientType(
-                    self.__clientAssociations[os.path.splitext(fn)[1]])
+                    self.__findLanguageForExtension(os.path.splitext(fn)[1]))
         except KeyError:
             self.__setClientType('Python3')    # assume it is a Python3 file
         self.startClient(False, forProject=forProject,
@@ -876,7 +903,7 @@
                 self.__setClientType(clientType)
             else:
                 self.__setClientType(
-                    self.__clientAssociations[os.path.splitext(fn)[1]])
+                    self.__findLanguageForExtension(os.path.splitext(fn)[1]))
         except KeyError:
             self.__setClientType('Python3')    # assume it is a Python3 file
         self.startClient(False, forProject=forProject,
@@ -916,7 +943,7 @@
                 self.__setClientType(clientType)
             else:
                 self.__setClientType(
-                    self.__clientAssociations[os.path.splitext(fn)[1]])
+                    self.__findLanguageForExtension(os.path.splitext(fn)[1]))
         except KeyError:
             self.__setClientType('Python3')    # assume it is a Python3 file
         self.startClient(False, forProject=forProject,
@@ -1161,7 +1188,7 @@
                 self.__setClientType(clientType)
             else:
                 self.__setClientType(
-                    self.__clientAssociations[os.path.splitext(fn)[1]])
+                    self.__findLanguageForExtension(os.path.splitext(fn)[1]))
         except KeyError:
             self.__setClientType('Python3')    # assume it is a Python3 file
         self.startClient(False)
@@ -1380,7 +1407,7 @@
         @param capabilities bitmaks with the client capabilities (integer)
         @param clientType type of the debug client (string)
         """
-        self.__clientCapabilities[clientType] = capabilities
+        self.__debuggerInterfaceRegistry[clientType][0] = capabilities
         self.clientCapabilities.emit(capabilities, clientType)
         
     def signalClientCompletionList(self, completionList, text):

eric ide

mercurial