Make it possible to list errors easier in a Python tree.

This commit is contained in:
Dave Halter
2017-07-09 16:57:09 +02:00
parent 9899c703ea
commit ceed7f183e
3 changed files with 60 additions and 5 deletions

View File

@@ -6,6 +6,11 @@ class Normalizer(object):
self._config = config
self.issues = []
def walk(self, node):
value = self.visit(node)
self.finalize()
return value
def visit(self, node):
try:
children = node.children
@@ -16,12 +21,15 @@ class Normalizer(object):
return ''.join(self.visit(child) for child in children)
@contextmanager
def visit_node(self):
def visit_node(self, node):
yield
def normalize(self, leaf):
def visit_leaf(self, leaf):
return leaf.prefix + leaf.value
def finalize(self):
pass
def add_issue(self, code, message, node):
issue = Issue(node, code, message)
if issue not in self.issues:

View File

@@ -1,4 +1,6 @@
from parso.normalizer import Normalizer
from contextlib import contextmanager
from parso.normalizer import Normalizer, NormalizerConfig
class CompressNormalizer(Normalizer):
@@ -7,3 +9,48 @@ class CompressNormalizer(Normalizer):
"""
def normalize(self, leaf):
return leaf.prefix + leaf.value
class ErrorFinder(Normalizer):
"""
Searches for errors in the syntax tree.
"""
def __init__(self, *args, **kwargs):
super(ErrorFinder, self).__init__(*args, **kwargs)
self._error_dict = {}
@contextmanager
def visit_node(self, node):
if node.type == 'error_node':
leaf = node.get_next_leaf()
self._add_error(901, "Syntax Error", leaf)
yield
def visit_leaf(self, leaf):
if leaf.type == 'error_leaf':
self._add_error(901, "Syntax Error", leaf)
return ''
def _add_error(self, code, message, node):
line = node.start_pos[0]
self._error_dict.setdefault(line, (code, message, node))
def finalize(self):
for code, message, node in self._error_dict.values():
self.add_issue(code, message, node)
def add_issue(self, code, message, node):
# Check if the issues are on the same line.
prev = node.get_previous_leaf()
if prev is not None and prev.type == 'error_leaf':
# There's already an error nearby. There's a huge chance they are
# related, so don't report this one.
return
super(ErrorFinder, self).add_issue(code, message, node)
class ErrorFinderConfig(NormalizerConfig):
normalizer_class = ErrorFinder

View File

@@ -168,11 +168,11 @@ class NodeOrLeaf(object):
The returned code will be normalized, e.g. PEP8 for Python.
"""
normalizer = self._get_normalizer(normalizer_config)
return normalizer.visit(self)
return normalizer.walk(self)
def _get_normalizer_issues(self, normalizer_config=None):
normalizer = self._get_normalizer(normalizer_config)
normalizer.visit(self)
normalizer.walk(self)
return normalizer.issues