mirror of
https://github.com/davidhalter/parso.git
synced 2025-12-08 13:45:01 +08:00
Fix diff parser: Decorators were sometimes parsed without their functions
This commit is contained in:
@@ -23,6 +23,8 @@ DEBUG_DIFF_PARSER = False
|
|||||||
def _assert_valid_graph(node):
|
def _assert_valid_graph(node):
|
||||||
"""
|
"""
|
||||||
Checks if the parent/children relationship is correct.
|
Checks if the parent/children relationship is correct.
|
||||||
|
|
||||||
|
This is a check that only runs during debugging/testing.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
children = node.children
|
children = node.children
|
||||||
@@ -112,11 +114,15 @@ def _func_or_class_has_suite(node):
|
|||||||
return node.type in ('classdef', 'funcdef') and node.children[-1].type == 'suite'
|
return node.type in ('classdef', 'funcdef') and node.children[-1].type == 'suite'
|
||||||
|
|
||||||
|
|
||||||
def suite_or_file_input_is_valid(pgen_grammar, stack):
|
def _suite_or_file_input_is_valid(pgen_grammar, stack):
|
||||||
if not _flows_finished(pgen_grammar, stack):
|
if not _flows_finished(pgen_grammar, stack):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
for stack_node in reversed(stack):
|
for stack_node in reversed(stack):
|
||||||
|
if stack_node.nonterminal == 'decorator':
|
||||||
|
# A decorator is only valid with the upcoming function.
|
||||||
|
return False
|
||||||
|
|
||||||
if stack_node.nonterminal == 'suite':
|
if stack_node.nonterminal == 'suite':
|
||||||
# If only newline is in the suite, the suite is not valid, yet.
|
# If only newline is in the suite, the suite is not valid, yet.
|
||||||
return len(stack_node.nodes) > 1
|
return len(stack_node.nodes) > 1
|
||||||
@@ -388,7 +394,7 @@ class DiffParser(object):
|
|||||||
elif typ == PythonTokenTypes.NEWLINE and start_pos[0] >= until_line:
|
elif typ == PythonTokenTypes.NEWLINE and start_pos[0] >= until_line:
|
||||||
yield PythonToken(typ, string, start_pos, prefix)
|
yield PythonToken(typ, string, start_pos, prefix)
|
||||||
# Check if the parser is actually in a valid suite state.
|
# Check if the parser is actually in a valid suite state.
|
||||||
if suite_or_file_input_is_valid(self._pgen_grammar, stack):
|
if _suite_or_file_input_is_valid(self._pgen_grammar, stack):
|
||||||
start_pos = start_pos[0] + 1, 0
|
start_pos = start_pos[0] + 1, 0
|
||||||
while len(indents) > int(omitted_first_indent):
|
while len(indents) > int(omitted_first_indent):
|
||||||
indents.pop()
|
indents.pop()
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ class Differ(object):
|
|||||||
new_module = diff_parser.update(self.lines, lines)
|
new_module = diff_parser.update(self.lines, lines)
|
||||||
self.lines = lines
|
self.lines = lines
|
||||||
assert code == new_module.get_code()
|
assert code == new_module.get_code()
|
||||||
|
|
||||||
_assert_valid_graph(new_module)
|
_assert_valid_graph(new_module)
|
||||||
assert diff_parser._copy_count == copies
|
assert diff_parser._copy_count == copies
|
||||||
assert diff_parser._parser_count == parsers
|
assert diff_parser._parser_count == parsers
|
||||||
@@ -745,3 +746,42 @@ def test_paren_before_docstring(differ):
|
|||||||
differ.initialize(code1)
|
differ.initialize(code1)
|
||||||
differ.parse(code2, parsers=1, copies=1, expect_error_leaves=True)
|
differ.parse(code2, parsers=1, copies=1, expect_error_leaves=True)
|
||||||
differ.parse(code1, parsers=2, copies=1)
|
differ.parse(code1, parsers=2, copies=1)
|
||||||
|
|
||||||
|
|
||||||
|
def test_x(differ):
|
||||||
|
code1 = dedent('''\
|
||||||
|
class StackNode(object):
|
||||||
|
def __init__(self, dfa):
|
||||||
|
self.dfa = dfa
|
||||||
|
self.nodes = []
|
||||||
|
|
||||||
|
@property
|
||||||
|
def nonterminal(self):
|
||||||
|
return self.dfa.from_rule
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return '%s(%s, %s)' % (self.__class__.__name__, self.dfa, self.nodes)
|
||||||
|
|
||||||
|
def x():
|
||||||
|
pass
|
||||||
|
''')
|
||||||
|
|
||||||
|
code2 = dedent('''\
|
||||||
|
class StackNode(object):
|
||||||
|
def __init__(self, dfa):
|
||||||
|
self.dfa = dfa
|
||||||
|
self.nodes = []
|
||||||
|
(msg, type_.name, value, start_pos))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def nonterminal(self):
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
|
||||||
|
def x():
|
||||||
|
pass
|
||||||
|
''')
|
||||||
|
|
||||||
|
differ.initialize(code1)
|
||||||
|
differ.parse(code2, parsers=3, copies=1, expect_error_leaves=True)
|
||||||
|
differ.parse(code1, parsers=2, copies=2)
|
||||||
|
|||||||
Reference in New Issue
Block a user