diff --git a/parso/normalizer.py b/parso/normalizer.py new file mode 100644 index 0000000..f45033f --- /dev/null +++ b/parso/normalizer.py @@ -0,0 +1,13 @@ +class Normalizer(): + def normalize(self, leaf): + return leaf.prefix + leaf.value + + def iter_errors(self, leaf): + return iter([]) + + +class Error(): + def __init__(self, leaf, code, message): + self._leaf = leaf + self.code = code + self.message = message diff --git a/parso/python/normalizer.py b/parso/python/normalizer.py new file mode 100644 index 0000000..8e4b544 --- /dev/null +++ b/parso/python/normalizer.py @@ -0,0 +1,20 @@ +from parso.normalizer import Normalizer, Error + + +class CompressNormalizer(Normalizer): + """ + Removes comments and whitespace. + """ + def normalize(self, leaf): + return leaf.prefix + leaf.value + + +class PEP8Normalizer(Normalizer): + """ + Normalizing to PEP8. Not really implemented, yet. + """ + def normalize(self, leaf): + return leaf.prefix + leaf.value + + def iter_errors(self, leaf): + return iter([]) diff --git a/parso/python/tree.py b/parso/python/tree.py index 967d399..dbf6855 100644 --- a/parso/python/tree.py +++ b/parso/python/tree.py @@ -28,6 +28,7 @@ Any subclasses of :class:`Scope`, including :class:`Module` has an attribute from parso._compatibility import utf8_repr, unicode from parso.tree import Node, BaseNode, Leaf, ErrorNode, ErrorLeaf, \ search_ancestor +from parso.python import normalizer class DocstringMixin(object): @@ -63,6 +64,7 @@ class PythonMixin(object): Some Python specific utitilies. """ __slots__ = () + default_normalizer = normalizer.PEP8Normalizer() def get_definition(self): if self.type in ('newline', 'endmarker'): @@ -94,7 +96,7 @@ class PythonMixin(object): return None -class PythonLeaf(Leaf, PythonMixin): +class PythonLeaf(PythonMixin, Leaf): __slots__ = () @@ -110,19 +112,19 @@ class _LeafWithoutNewlines(PythonLeaf): # Python base classes -class PythonBaseNode(BaseNode, PythonMixin): +class PythonBaseNode(PythonMixin, BaseNode): __slots__ = () -class PythonNode(Node, PythonMixin): +class PythonNode(PythonMixin, Node): __slots__ = () -class PythonErrorNode(ErrorNode, PythonMixin): +class PythonErrorNode(PythonMixin, ErrorNode): __slots__ = () -class PythonErrorLeaf(ErrorLeaf, PythonMixin): +class PythonErrorLeaf(PythonMixin, ErrorLeaf): __slots__ = () @@ -1010,7 +1012,7 @@ class Param(PythonBaseNode): """ return search_ancestor(self, 'funcdef', 'lambdef') - def get_code(self, normalized=False, include_prefix=True, include_comma=True): + def get_code(self, include_prefix=True, include_comma=True): """ Like all the other get_code functions, but includes the param `include_comma`. @@ -1018,14 +1020,13 @@ class Param(PythonBaseNode): :param include_comma bool: If enabled includes the comma in the string output. """ if include_comma: - return super(Param, self).get_code(normalized, include_prefix) + return super(Param, self).get_code(include_prefix) children = self.children if children[-1] == ',': children = children[:-1] return self._get_code_for_children( children, - normalized=False, include_prefix=include_prefix ) diff --git a/parso/tree.py b/parso/tree.py index 0b0c780..a3a8b0e 100644 --- a/parso/tree.py +++ b/parso/tree.py @@ -22,6 +22,7 @@ class NodeOrLeaf(object): The base class for nodes and leaves. """ __slots__ = () + default_normalizer = None def get_root_node(self): """ @@ -145,17 +146,32 @@ class NodeOrLeaf(object): """ @abstractmethod - def get_code(self, normalized=False, include_prefix=True): + def get_code(self, include_prefix=True): """ Returns the code that was the input of the parser. - If a normalizer is given, the returned code will be normalized and will - not be equal to the input. - - :param include_prefix: Removes the prefix (whitespace and comments) of e.g. a statement. - :param normalized: Deprecated. Please don't use. Will be replaced with something more powerful. + :param include_prefix: Removes the prefix (whitespace and comments) of + e.g. a statement. """ + def normalize(self, normalizer=None): + """ + The returned code will be normalized, e.g. PEP8 for Python. + """ + if normalizer is None: + normalizer = self.default_normalizer + if normalizer is None: + raise ValueError("You need to specify a normalizer, because " + "there's no default normalizer for this tree.") + + try: + children = self.children + except AttributeError: + return normalizer(self) + else: + return ''.join(child.normalize(normalizer) for child in children) + + class Leaf(NodeOrLeaf): __slots__ = ('value', 'parent', 'line', 'indent', 'prefix') @@ -187,9 +203,7 @@ class Leaf(NodeOrLeaf): def get_last_leaf(self): return self - def get_code(self, normalized=False, include_prefix=True): - if normalized: - return self.value + def get_code(self, include_prefix=True): if include_prefix: return self.prefix + self.value else: @@ -238,16 +252,15 @@ class BaseNode(NodeOrLeaf): def end_pos(self): return self.children[-1].end_pos - def _get_code_for_children(self, children, normalized, include_prefix): - # TODO implement normalized (depending on context). + def _get_code_for_children(self, children, include_prefix): if include_prefix: - return "".join(c.get_code(normalized) for c in children) + return "".join(c.get_code() for c in children) else: first = children[0].get_code(include_prefix=False) - return first + "".join(c.get_code(normalized) for c in children[1:]) + return first + "".join(c.get_code() for c in children[1:]) - def get_code(self, normalized=False, include_prefix=True): - return self._get_code_for_children(self.children, normalized, include_prefix) + def get_code(self, include_prefix=True): + return self._get_code_for_children(self.children, include_prefix) def get_leaf_for_position(self, position, include_prefixes=False): def binary_search(lower, upper):