diff -r e9e7eca7efee -r bf71ee032bb4 src/eric7/Utilities/ClassBrowsers/jsclbr.py --- a/src/eric7/Utilities/ClassBrowsers/jsclbr.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/Utilities/ClassBrowsers/jsclbr.py Wed Jul 13 14:55:47 2022 +0200 @@ -17,21 +17,22 @@ from . import ClbrBaseClasses SUPPORTED_TYPES = [ClassBrowsers.JS_SOURCE] - -_modules = {} # cache of modules we've seen + +_modules = {} # cache of modules we've seen class VisibilityMixin(ClbrBaseClasses.ClbrVisibilityMixinBase): """ Mixin class implementing the notion of visibility. """ + def __init__(self): """ Constructor """ - if self.name.startswith('__'): + if self.name.startswith("__"): self.setPrivate() - elif self.name.startswith('_'): + elif self.name.startswith("_"): self.setProtected() else: self.setPublic() @@ -41,11 +42,11 @@ """ Class to represent a Python function. """ - def __init__(self, module, name, file, lineno, signature='', - separator=','): + + def __init__(self, module, name, file, lineno, signature="", separator=","): """ Constructor - + @param module name of the module containing this function @param name name of this function @param file filename containing this class @@ -53,8 +54,9 @@ @param signature parameterlist of the method @param separator string separating the parameters """ - ClbrBaseClasses.Function.__init__(self, module, name, file, lineno, - signature, separator) + ClbrBaseClasses.Function.__init__( + self, module, name, file, lineno, signature, separator + ) VisibilityMixin.__init__(self) @@ -62,10 +64,11 @@ """ Class to represent a class attribute. """ + def __init__(self, module, name, file, lineno): """ Constructor - + @param module name of the module containing this class @param name name of this class @param file filename containing this attribute @@ -79,10 +82,11 @@ """ Class implementing a visitor going through the parsed tree. """ + def __init__(self, src, module, filename): """ Constructor - + @param src source to be parsed (string) @param module name of the module (string) @param filename file name (string) @@ -91,22 +95,22 @@ self.__dict_counts = {} self.__root = None self.__stack = [] - + self.__module = module self.__file = filename self.__source = src - + # normalize line endings self.__source = self.__source.replace("\r\n", "\n").replace("\r", "\n") - + # ensure source ends with an eol - if bool(self.__source) and self.__source[-1] != '\n': - self.__source = self.__source + '\n' - + if bool(self.__source) and self.__source[-1] != "\n": + self.__source = self.__source + "\n" + def parse(self): """ Public method to parse the source. - + @return dictionary containing the parsed information """ try: @@ -118,28 +122,28 @@ except jsTokenizer.ParseError: # ignore syntax errors of the tokenizer pass - + return self.__dict - + def __visit(self, root): """ Private method implementing the visit logic delegating to interesting methods. - + @param root root node to visit """ + def call(n): - getattr(self, "visit_{0}".format(n.type), - self.visit_noop)(n) - + getattr(self, "visit_{0}".format(n.type), self.visit_noop)(n) + call(root) for node in root: self.__visit(node) - + def visit_noop(self, node): """ Public method to ignore the given node. - + @param node reference to the node (jasy.script.parse.Node.Node) """ pass @@ -147,18 +151,17 @@ def visit_function(self, node): """ Public method to treat a function node. - + @param node reference to the node (jasy.script.parse.Node.Node) """ if ( - node.type == "function" and - getattr(node, "name", None) and - node.functionForm == "declared_form" + node.type == "function" + and getattr(node, "name", None) + and node.functionForm == "declared_form" ): if self.__stack and self.__stack[-1].endlineno < node.line: del self.__stack[-1] - endline = node.line + self.__source.count( - '\n', node.start, node.end) + endline = node.line + self.__source.count("\n", node.start, node.end) if getattr(node, "params", None): func_sig = ", ".join([p.value for p in node.params]) else: @@ -166,19 +169,18 @@ if self.__stack: # it's a nested function cur_func = self.__stack[-1] - f = Function(None, node.name, - self.__file, node.line, func_sig) + f = Function(None, node.name, self.__file, node.line, func_sig) f.setEndLine(endline) cur_func._addmethod(node.name, f) else: - f = Function(self.__module, node.name, - self.__file, node.line, func_sig) + f = Function(self.__module, node.name, self.__file, node.line, func_sig) f.setEndLine(endline) func_name = node.name if func_name in self.__dict_counts: self.__dict_counts[func_name] += 1 func_name = "{0}_{1:d}".format( - func_name, self.__dict_counts[func_name]) + func_name, self.__dict_counts[func_name] + ) else: self.__dict_counts[func_name] = 0 self.__dict[func_name] = f @@ -187,14 +189,13 @@ def visit_property_init(self, node): """ Public method to treat a property_init node. - + @param node reference to the node (jasy.script.parse.Node.Node) """ if node.type == "property_init" and node[1].type == "function": if self.__stack and self.__stack[-1].endlineno < node[0].line: del self.__stack[-1] - endline = node[0].line + self.__source.count( - '\n', node.start, node[1].end) + endline = node[0].line + self.__source.count("\n", node.start, node[1].end) if getattr(node[1], "params", None): func_sig = ", ".join([p.value for p in node[1].params]) else: @@ -202,34 +203,64 @@ if self.__stack: # it's a nested function cur_func = self.__stack[-1] - f = Function(None, node[0].value, - self.__file, node[0].line, func_sig) + f = Function(None, node[0].value, self.__file, node[0].line, func_sig) f.setEndLine(endline) cur_func._addmethod(node[0].value, f) else: - f = Function(self.__module, node[0].value, - self.__file, node[0].line, func_sig) + f = Function( + self.__module, node[0].value, self.__file, node[0].line, func_sig + ) f.setEndLine(endline) func_name = node[0].value if func_name in self.__dict_counts: self.__dict_counts[func_name] += 1 func_name = "{0}_{1:d}".format( - func_name, self.__dict_counts[func_name]) + func_name, self.__dict_counts[func_name] + ) else: self.__dict_counts[func_name] = 0 self.__dict[func_name] = f self.__stack.append(f) - + def visit_var(self, node): """ Public method to treat a variable node. - + @param node reference to the node (jasy.script.parse.Node.Node) """ if ( - node.type == "var" and - node.parent.type == "script" and - node.getChildrenLength() + node.type == "var" + and node.parent.type == "script" + and node.getChildrenLength() + ): + if self.__stack and self.__stack[-1].endlineno < node[0].line: + del self.__stack[-1] + if self.__stack: + # function variables + for var in node: + attr = Attribute(self.__module, var.name, self.__file, var.line) + self.__stack[-1]._addattribute(attr) + else: + # global variable + if "@@Globals@@" not in self.__dict: + self.__dict["@@Globals@@"] = ClbrBaseClasses.ClbrBase( + self.__module, "Globals", self.__file, 0 + ) + for var in node: + self.__dict["@@Globals@@"]._addglobal( + Attribute(self.__module, var.name, self.__file, var.line) + ) + + def visit_const(self, node): + """ + Public method to treat a constant node. + + @param node reference to the node (jasy.script.parse.Node.Node) + """ + if ( + node.type == "const" + and node.parent.type == "script" + and node.getChildrenLength() ): if self.__stack and self.__stack[-1].endlineno < node[0].line: del self.__stack[-1] @@ -237,45 +268,21 @@ # function variables for var in node: attr = Attribute( - self.__module, var.name, self.__file, var.line) + self.__module, "const " + var.name, self.__file, var.line + ) self.__stack[-1]._addattribute(attr) else: # global variable if "@@Globals@@" not in self.__dict: self.__dict["@@Globals@@"] = ClbrBaseClasses.ClbrBase( - self.__module, "Globals", self.__file, 0) - for var in node: - self.__dict["@@Globals@@"]._addglobal(Attribute( - self.__module, var.name, self.__file, var.line)) - - def visit_const(self, node): - """ - Public method to treat a constant node. - - @param node reference to the node (jasy.script.parse.Node.Node) - """ - if ( - node.type == "const" and - node.parent.type == "script" and - node.getChildrenLength() - ): - if self.__stack and self.__stack[-1].endlineno < node[0].line: - del self.__stack[-1] - if self.__stack: - # function variables - for var in node: - attr = Attribute(self.__module, "const " + var.name, - self.__file, var.line) - self.__stack[-1]._addattribute(attr) - else: - # global variable - if "@@Globals@@" not in self.__dict: - self.__dict["@@Globals@@"] = ClbrBaseClasses.ClbrBase( - self.__module, "Globals", self.__file, 0) + self.__module, "Globals", self.__file, 0 + ) for var in node: self.__dict["@@Globals@@"]._addglobal( - Attribute(self.__module, "const " + var.name, - self.__file, var.line)) + Attribute( + self.__module, "const " + var.name, self.__file, var.line + ) + ) def readmodule_ex(module, path=None): @@ -287,7 +294,7 @@ @return the resulting dictionary """ global _modules - + if module in _modules: # we've seen this file before... return _modules[module] @@ -309,7 +316,7 @@ # can't do anything with this module _modules[module] = {} return {} - + _modules[module] = scan(src, file, module) return _modules[module] @@ -317,7 +324,7 @@ def scan(src, file, module): """ Public method to scan the given source text. - + @param src source text to be scanned @type str @param file file name associated with the source text @@ -329,7 +336,7 @@ """ # convert eol markers the Python style src = src.replace("\r\n", "\n").replace("\r", "\n") - + dictionary = {} visitor = Visitor(src, module, file)