mirror of
https://github.com/davidhalter/parso.git
synced 2025-12-08 05:34:51 +08:00
Make it possible to list errors easier in a Python tree.
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user