Continued implementing the Jedi refactoring interface. eric7

Tue, 05 Oct 2021 18:13:40 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Tue, 05 Oct 2021 18:13:40 +0200
branch
eric7
changeset 8668
d29c775b8bd7
parent 8667
99dfcefcc4d8
child 8669
c26ecdb00a8b

Continued implementing the Jedi refactoring interface.

eric7/JediInterface/AssistantJedi.py file | annotate | diff | comparison | revisions
eric7/JediInterface/JediClient.py file | annotate | diff | comparison | revisions
eric7/JediInterface/JediServer.py file | annotate | diff | comparison | revisions
--- a/eric7/JediInterface/AssistantJedi.py	Mon Oct 04 19:59:59 2021 +0200
+++ b/eric7/JediInterface/AssistantJedi.py	Tue Oct 05 18:13:40 2021 +0200
@@ -226,6 +226,12 @@
         self.__menu.addAction(
             self.tr("Rename Variable"),
             self.__jediServer.refactoringRenameVariable)
+        self.__menu.addAction(
+            self.tr("Extract Variable"),
+            self.__jediServer.refactoringExtractNewVariable)
+        self.__menu.addAction(
+            self.tr("Inline Variable"),
+            self.__jediServer.refactoringInlineVariable)
     
     def __editorShowMenu(self, menuName, menu, editor):
         """
--- a/eric7/JediInterface/JediClient.py	Mon Oct 04 19:59:59 2021 +0200
+++ b/eric7/JediInterface/JediClient.py	Tue Oct 05 18:13:40 2021 +0200
@@ -42,7 +42,6 @@
         super().__init__(host, port, idString)
         
         # TODO: add additional methods for these topics
-        #       - rename variable
         #       - extract function
         #       - extract variable
         #       - inline variable
@@ -58,6 +57,8 @@
             "gotoReferences": self.__getReferences,
             
             "renameVariable": self.__renameVariable,
+            "extractVariable": self.__extractVariable,
+            "inlineVariable": self.__inlineVariable,
             "applyRefactoring": self.__applyRefactoring,
             "cancelRefactoring": self.__cancelRefactoring,
         }
@@ -444,7 +445,79 @@
         }
         result.update(errorDict)
         
-        self.sendJson("RenameVariableDiff", result)
+        self.sendJson("RefactoringDiff", result)
+    
+    def __extractVariable(self, params):
+        """
+        Private method to extract a statement to a new variable.
+        
+        @param params dictionary containing the method parameters
+        @type dict
+        """
+        filename = params["FileName"]
+        source = params["Source"]
+        line = params["Line"]
+        index = params["Index"]
+        endLine = params["EndLine"]
+        endIndex = params["EndIndex"]
+        uid = params["Uuid"]
+        newName = params["NewName"]
+        
+        errorDict = {}
+        diff = ""
+        
+        script = jedi.Script(source, path=filename, project=self.__project)
+        
+        try:
+            refactoring = script.extract_variable(
+                line, index, new_name=newName,
+                until_line=endLine, until_column=endIndex
+            )
+            self.__refactorings[uid] = refactoring
+            diff = refactoring.get_diff()
+        except SuppressedException as err:
+            errorDict = self.__handleError(err)
+        
+        result = {
+            "Diff": diff,
+            "Uuid": uid,
+        }
+        result.update(errorDict)
+        
+        self.sendJson("RefactoringDiff", result)
+    
+    def __inlineVariable(self, params):
+        """
+        Private method to inline a variable statement.
+        
+        @param params dictionary containing the method parameters
+        @type dict
+        """
+        filename = params["FileName"]
+        source = params["Source"]
+        line = params["Line"]
+        index = params["Index"]
+        uid = params["Uuid"]
+        
+        errorDict = {}
+        diff = ""
+        
+        script = jedi.Script(source, path=filename, project=self.__project)
+        
+        try:
+            refactoring = script.inline(line, index)
+            self.__refactorings[uid] = refactoring
+            diff = refactoring.get_diff()
+        except SuppressedException as err:
+            errorDict = self.__handleError(err)
+        
+        result = {
+            "Diff": diff,
+            "Uuid": uid,
+        }
+        result.update(errorDict)
+        
+        self.sendJson("RefactoringDiff", result)
     
     def __applyRefactoring(self, params):
         """
--- a/eric7/JediInterface/JediServer.py	Mon Oct 04 19:59:59 2021 +0200
+++ b/eric7/JediInterface/JediServer.py	Tue Oct 05 18:13:40 2021 +0200
@@ -90,7 +90,7 @@
             "GotoDefinitionResult": self.__processGotoDefinitionResult,
             "GotoReferencesResult": self.__processGotoReferencesResult,
             
-            "RenameVariableDiff": self.__showRenameVariableDiff,
+            "RefactoringDiff": self.__showRefactoringDiff,
             "RefactoringApplyResult": self.__checkRefactoringResult,
             
             "ClientException": self.__processClientException,
@@ -511,7 +511,6 @@
             if ok and newName:
                 filename = editor.getFileName()
                 line, index = editor.getCursorPosition()
-                line += 1       # jedi line numbers are 1 based
                 source = editor.text()
                 
                 self.__ensureActive(idString)
@@ -522,21 +521,89 @@
                 self.sendJson("renameVariable", {
                     "FileName": filename,
                     "Source": source,
-                    "Line": line,
+                    "Line": line + 1,
                     "Index": index,
                     "Uuid": euuid,
                     "NewName": newName,
                 }, idString=idString)
     
-    def __showRenameVariableDiff(self, result):
+    @pyqtSlot()
+    def refactoringExtractNewVariable(self):
+        """
+        Public slot to extract a statement to a new variable.
         """
-        Private method to show the diff of the Rename Variable refactoring.
+        editor = self.__vm.activeWindow()
+        if editor:
+            idString = self.__idString(editor)
+            if not idString:
+                return
+            
+            newName, ok = QInputDialog.getText(
+                None,
+                self.tr("Extract Variable"),
+                self.tr("Enter the name for the new variable:"),
+                QLineEdit.EchoMode.Normal
+            )
+            
+            if ok and newName:
+                filename = editor.getFileName()
+                sLine, sIndex, eLine, eIndex = editor.getSelection()
+                source = editor.text()
+                    
+                self.__ensureActive(idString)
+                
+                euuid = str(uuid.uuid4())
+                self.__editors[euuid] = editor
+                
+                self.sendJson("extractVariable", {
+                    "FileName": filename,
+                    "Source": source,
+                    "Line": sLine + 1,
+                    "Index": sIndex,
+                    "EndLine": eLine + 1,
+                    "EndIndex": eIndex,
+                    "Uuid": euuid,
+                    "NewName": newName,
+                }, idString=idString)
+    
+    @pyqtSlot()
+    def refactoringInlineVariable(self):
+        """
+        Public slot to inline the selected variable.
+        
+        Note: This is the opposite to Extract New Variable.
+        """
+        editor = self.__vm.activeWindow()
+        if editor:
+            idString = self.__idString(editor)
+            if not idString:
+                return
+            
+            filename = editor.getFileName()
+            line, index = editor.getCursorPosition()
+            source = editor.text()
+            
+            self.__ensureActive(idString)
+            
+            euuid = str(uuid.uuid4())
+            self.__editors[euuid] = editor
+            
+            self.sendJson("inlineVariable", {
+                "FileName": filename,
+                "Source": source,
+                "Line": line + 1,
+                "Index": index,
+                "Uuid": euuid,
+            }, idString=idString)
+    
+    def __showRefactoringDiff(self, result):
+        """
+        Private method to show the diff of a refactoring.
         
         @param result dictionary containing the result data
         @type dict
         """
         if "Error" not in result:
-            # ignore errors silently
             euuid = result["Uuid"]
             diff = result["Diff"]
             dlg = RefactoringPreviewDialog(self.tr("Rename Variable"), diff)
@@ -544,6 +611,13 @@
                 self.__applyRefactoring(euuid)
             else:
                 self.__cancelRefactoring(euuid)
+        else:
+            EricMessageBox.critical(
+                None,
+                self.tr("Refactoring"),
+                self.tr("<p>The refactoring could not be performed.</p>"
+                        "<p>Reason: {0}</p>").format(result["ErrorString"])
+            )
     
     def __applyRefactoring(self, uid):
         """
@@ -588,7 +662,7 @@
         """
         if "Error" in result:
             EricMessageBox.critical(
-                self,
+                None,
                 self.tr("Apply Refactoring"),
                 self.tr("<p>The refactoring could not be applied.</p>"
                         "<p>Reason: {0}</p>").format(result["ErrorString"])

eric ide

mercurial