Sun, 11 Dec 2022 15:49:39 +0100
Added a few TODO markers.
# -*- coding: utf-8 -*- # Copyright (c) 2005 - 2022 Detlev Offenbach <detlev@die-offenbachs.de> # """ Package implementing class browsers for various languages. Currently it offers class browser support for the following programming languages. <ul> <li>CORBA IDL</li> <li>JavaScript</li> <li>ProtoBuf</li> <li>Python 3</li> <li>Ruby</li> </ul> """ # TODO: move the IDL and Protobuf class browsers to the plugins. import importlib import os from eric7 import Preferences PY_SOURCE = 1 PTL_SOURCE = 128 RB_SOURCE = 129 IDL_SOURCE = 130 JS_SOURCE = 131 PROTO_SOURCE = 132 UNKNOWN_SOURCE = 255 SUPPORTED_TYPES = [ PY_SOURCE, PTL_SOURCE, RB_SOURCE, IDL_SOURCE, JS_SOURCE, PROTO_SOURCE, ] __extensions = { "IDL": [".idl"], "Python": [".py", ".pyw", ".ptl"], # currently not used "Ruby": [".rb"], "JavaScript": [".js"], "ProtoBuf": [".proto"], } def getClassBrowserModule(moduleType): """ Function to import a class browser module. @param moduleType type of class browser to load @type str @return reference to the imported class browser module @rtype module """ typeMapping = { "idl": ".idlclbr", "javascript": ".jsclbr", "protobuf": ".protoclbr", "python": ".pyclbr", "ruby": ".rbclbr", } if moduleType in typeMapping: mod = importlib.import_module(typeMapping[moduleType], __package__) return mod return None def readmodule(module, path=None, isPyFile=False): """ Function to read a source file and return a dictionary of classes, functions, modules, etc. . The real work of parsing the source file is delegated to the individual file parsers. @param module name of the source file @type str @param path list of paths the file should be searched in @type list of str @param isPyFile flag indicating a Python file @type bool @return the resulting dictionary @rtype dict """ ext = os.path.splitext(module)[1].lower() path = [] if path is None else path[:] if ext in __extensions["IDL"]: moduleType = "idl" elif ext in __extensions["ProtoBuf"]: moduleType = "protobuf" elif ext in __extensions["Ruby"]: moduleType = "ruby" elif ext in __extensions["JavaScript"]: moduleType = "javascript" elif ext in Preferences.getPython("Python3Extensions") or isPyFile: moduleType = "python" else: # try Python if it is without extension moduleType = "python" classBrowserModule = getClassBrowserModule(moduleType) if classBrowserModule: dictionary = classBrowserModule.readmodule_ex(module, path, isTypeFile=isPyFile) classBrowserModule.clearModulesCache() else: dictionary = {} return dictionary def find_module(name, path, isPyFile=False): """ Function to extend the Python module finding mechanism. This function searches for files in the given list of paths. If the file name doesn't have an extension or an extension of .py, the normal Python search implemented in the imp module is used. For all other supported files only the paths list is searched. @param name file name or module name to search for @type str @param path search paths @type list of str @param isPyFile flag indicating a Python file @type bool @return tuple of the open file, pathname and description. Description is a tuple of file suffix, file mode and file type) @rtype tuple @exception ImportError The file or module wasn't found. """ ext = os.path.splitext(name)[1].lower() if ext in __extensions["Ruby"]: sourceType = RB_SOURCE elif ext in __extensions["IDL"]: sourceType = IDL_SOURCE elif ext in __extensions["ProtoBuf"]: sourceType = PROTO_SOURCE elif ext in __extensions["JavaScript"]: sourceType = JS_SOURCE elif ext == ".ptl": sourceType = PTL_SOURCE elif ( name.lower().endswith(tuple(Preferences.getPython("Python3Extensions"))) or isPyFile ): sourceType = PY_SOURCE else: sourceType = UNKNOWN_SOURCE if sourceType != UNKNOWN_SOURCE: for p in path: # search in path pathname = os.path.join(p, name) if os.path.exists(pathname): return (open(pathname), pathname, (ext, "r", sourceType)) # __IGNORE_WARNING_Y115__ raise ImportError else: # standard Python module file if name.lower().endswith(".py"): name = name[:-3] spec = importlib.machinery.PathFinder.find_spec(name, path) if spec is None: raise ImportError if isinstance(spec.loader, importlib.machinery.SourceFileLoader): ext = os.path.splitext(spec.origin)[-1] return (open(spec.origin), spec.origin, (ext, "r", PY_SOURCE)) # __IGNORE_WARNING_Y115__ raise ImportError