Sat, 16 Sep 2017 18:51:19 +0200
Some code cleanup and refinement.
# -*- coding: utf-8 -*- # Copyright (c) 2017 Detlev Offenbach <detlev@die-offenbachs.de> # """ Module implementing the refactoring client interface to rope. """ from __future__ import unicode_literals import sys import os sys.path.insert(0, os.path.dirname(__file__)) if sys.version_info[0] >= 3: rope_path = os.path.join(os.path.dirname(__file__), 'rope_py3') else: rope_path = os.path.join(os.path.dirname(__file__), 'rope_py2') str = unicode # __IGNORE_WARNING__ sys.path.insert(0, rope_path) import rope import rope.base.project import rope.base.libutils from JsonClient import JsonClient class RefactoringClient(JsonClient): """ Class implementing the refactoring client interface to rope. """ def __init__(self, host, port, projectPath): """ Constructor @param host ip address the background service is listening @type str @param port port of the background service @type int @param projectPath path to the project @type str """ super(RefactoringClient, self).__init__(host, port) self.__methodMapping = { "AbortAction": self.__abortAction, "Validate": self.__validate, "QueryReferences": self.__queryReferences, "QueryDefinition": self.__queryDefinition, "QueryImplementations": self.__queryImplementations, "GetConfig": self.__getConfig, "ConfigChanged": self.__configChanged, "PerformSoa": self.__performSOA, "ReportChanged": self.__reportChanged, } from FileSystemCommands import RefactoringClientFileSystemCommands self.__fsCommands = RefactoringClientFileSystemCommands(self) self.__projectpath = projectPath self.__project = rope.base.project.Project( self.__projectpath, fscommands=self.__fsCommands) self.__progressHandle = None def handleCall(self, method, params): """ Public method to handle a method call from the server. @param method requested method name @type str @param params dictionary with method specific parameters @type dict """ ## if "filename" in params and sys.version_info[0] == 2: ## params["filename"] = params["filename"].encode( ## sys.getfilesystemencoding()) self.__methodMapping[method](params) def __handleRopeError(self, err): """ Private method to process a rope error. @param err rope exception object @type Exception @return dictionary containing the error information @rtype dict """ ropeError = str(type(err)).split()[-1] ropeError = ropeError[1:-2].split('.')[-1] errorDict = { "Error": ropeError, "ErrorString": str(err), } if ropeError == 'ModuleSyntaxError': errorDict["ErrorFile"] = err.filename errorDict["ErrorLine"] = err.lineno return errorDict def __abortAction(self, params): """ Private method to abort the current action. @param params dictionary containing the method parameters sent by the server @type dict """ if self.__progressHandle is not None and \ not self.__progressHandle.is_stopped(): self.__progressHandle.stop() def __validate(self, params): """ Private slot to validate the project. @param params dictionary containing the method parameters sent by the server @type dict """ self.__project.validate(self.__project.root) def __getConfig(self, params): """ Private method to send some configuration data to the server. @param params dictionary containing the method parameters sent by the server @type dict """ result = { "RopeFolderName": self.__project.ropefolder.real_path, "DefaultConfig": self.__project._default_config(), "RopeHelpFile": os.path.join( rope_path, "rope", "docs", "overview.txt"), "RopeInfo": rope.INFO, "RopeVersion": rope.VERSION, "RopeCopyright": rope.COPYRIGHT, } self.sendJson("Config", result) def __configChanged(self, params): """ Private method to handle a change of the configuration file. @param params dictionary containing the method parameters sent by the server @type dict """ self.__project.close() self.__project = rope.base.project.Project( self.__projectpath, fscommands=self.__fsCommands) def __queryReferences(self, params): """ Private method to handle the Find References action. @param params dictionary containing the method parameters sent by the server @type dict """ title = params["Title"] filename = params["FileName"] offset = params["Offset"] errorDict = {} occurrences = [] import rope.contrib.findit from ProgressHandle import ProgressHandle resource = rope.base.libutils.path_to_resource( self.__project, filename) self.__progressHandle = ProgressHandle(self, title, True) try: occurrences = rope.contrib.findit.find_occurrences( self.__project, resource, offset, unsure=True, in_hierarchy=True, task_handle=self.__progressHandle) except Exception as err: errorDict = self.__handleRopeError(err) self.__progressHandle.reset() self.__progressHandle = None result = { "Title": title, "EntriesCount": len(occurrences), "Entries": [ [occurrence.resource.real_path, occurrence.lineno, occurrence.unsure] for occurrence in occurrences ], } result.update(errorDict) self.sendJson("QueryReferencesResult", result) def __queryDefinition(self, params): """ Private method to handle the Find Definition action. @param params dictionary containing the method parameters sent by the server @type dict """ title = params["Title"] filename = params["FileName"] offset = params["Offset"] source = params["Source"] subcommand = params["Subcommand"] errorDict = {} location = None import rope.contrib.findit resource = rope.base.libutils.path_to_resource( self.__project, filename) try: location = rope.contrib.findit.find_definition( self.__project, source, offset, resource) except Exception as err: errorDict = self.__handleRopeError(err) result = { "Title": title, "Subcommand": subcommand, } if location is not None: result["Location"] = [ location.resource.real_path, location.lineno ] result.update(errorDict) self.sendJson("QueryDefinitionResult", result) def __queryImplementations(self, params): """ Private method to handle the Find Implementations action. @param params dictionary containing the method parameters sent by the server @type dict """ title = params["Title"] filename = params["FileName"] offset = params["Offset"] errorDict = {} occurrences = [] import rope.contrib.findit from ProgressHandle import ProgressHandle resource = rope.base.libutils.path_to_resource( self.__project, filename) self.__progressHandle = ProgressHandle(self, title, True) try: occurrences = rope.contrib.findit.find_implementations( self.__project, resource, offset, task_handle=self.__progressHandle) except Exception as err: errorDict = self.__handleRopeError(err) self.__progressHandle.reset() self.__progressHandle = None result = { "Title": title, "EntriesCount": len(occurrences), "Entries": [ [occurrence.resource.real_path, occurrence.lineno, occurrence.unsure] for occurrence in occurrences ], } result.update(errorDict) self.sendJson("QueryImplementationsResult", result) def __performSOA(self, params): """ Private method to perform SOA on all modules. @param params dictionary containing the method parameters sent by the server @type dict """ title = params["Title"] errorDict = {} from ProgressHandle import ProgressHandle self.__progressHandle = ProgressHandle(self, title, True) try: rope.base.libutils.analyze_modules( self.__project, task_handle=self.__progressHandle) except Exception as err: errorDict = self.__handleRopeError(err) self.__progressHandle.reset() self.__progressHandle = None result = { "Title": title, } result.update(errorDict) self.sendJson("SoaFinished", result) def __reportChanged(self, params): """ Private method to register some changed sources. @param params dictionary containing the method parameters sent by the server @type dict """ filename = params["FileName"] oldSource = params["OldSource"] try: rope.base.libutils.report_change( self.__project, filename, oldSource) except Exception: # simply ignore it pass if __name__ == '__main__': if len(sys.argv) != 4: print('Host, port and project path parameters are missing. Abort.') sys.exit(1) host, port, projectPath = sys.argv[1:] client = RefactoringClient(host, int(port), projectPath) # Start the main loop client.run() sys.exit(0) # # eflag: noqa = M801