mirror of
https://github.com/davidhalter/parso.git
synced 2025-12-07 05:14:29 +08:00
Diff parser: Need to care for eror dedents in some open parentheses/always break contexts
This commit is contained in:
@@ -24,6 +24,7 @@ _INDENTATION_TOKENS = 'INDENT', 'ERROR_DEDENT', 'DEDENT'
|
|||||||
|
|
||||||
NEWLINE = PythonTokenTypes.NEWLINE
|
NEWLINE = PythonTokenTypes.NEWLINE
|
||||||
DEDENT = PythonTokenTypes.DEDENT
|
DEDENT = PythonTokenTypes.DEDENT
|
||||||
|
ERROR_DEDENT = PythonTokenTypes.ERROR_DEDENT
|
||||||
ENDMARKER = PythonTokenTypes.ENDMARKER
|
ENDMARKER = PythonTokenTypes.ENDMARKER
|
||||||
|
|
||||||
|
|
||||||
@@ -381,6 +382,9 @@ class DiffParser(object):
|
|||||||
nodes = node.children
|
nodes = node.children
|
||||||
|
|
||||||
self._nodes_tree.add_parsed_nodes(nodes)
|
self._nodes_tree.add_parsed_nodes(nodes)
|
||||||
|
if self._replace_tos_indent is not None:
|
||||||
|
self._nodes_tree.indents[-1] = self._replace_tos_indent
|
||||||
|
|
||||||
LOG.debug(
|
LOG.debug(
|
||||||
'parse_part from %s to %s (to %s in part parser)',
|
'parse_part from %s to %s (to %s in part parser)',
|
||||||
nodes[0].get_start_pos_of_prefix()[0],
|
nodes[0].get_start_pos_of_prefix()[0],
|
||||||
@@ -426,6 +430,7 @@ class DiffParser(object):
|
|||||||
indents=indents
|
indents=indents
|
||||||
)
|
)
|
||||||
stack = self._active_parser.stack
|
stack = self._active_parser.stack
|
||||||
|
self._replace_tos_indent = None
|
||||||
#print('start', line_offset + 1, indents)
|
#print('start', line_offset + 1, indents)
|
||||||
for token in tokens:
|
for token in tokens:
|
||||||
#print(token, indents)
|
#print(token, indents)
|
||||||
@@ -435,8 +440,15 @@ class DiffParser(object):
|
|||||||
# We are done here, only thing that can come now is an
|
# We are done here, only thing that can come now is an
|
||||||
# endmarker or another dedented code block.
|
# endmarker or another dedented code block.
|
||||||
while True:
|
while True:
|
||||||
typ, string, start_pos, prefix = next(tokens)
|
typ, string, start_pos, prefix = token = next(tokens)
|
||||||
if typ != DEDENT:
|
if typ in (DEDENT, ERROR_DEDENT):
|
||||||
|
if typ == ERROR_DEDENT:
|
||||||
|
# We want to force an error dedent in the next
|
||||||
|
# parser/pass. To make this possible we just
|
||||||
|
# increase the location by one.
|
||||||
|
self._replace_tos_indent = start_pos[1] + 1
|
||||||
|
pass
|
||||||
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
if '\n' in prefix or '\r' in prefix:
|
if '\n' in prefix or '\r' in prefix:
|
||||||
|
|||||||
@@ -1541,3 +1541,27 @@ def c():
|
|||||||
''')
|
''')
|
||||||
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)
|
||||||
|
|
||||||
|
|
||||||
|
def test_class_with_paren_breaker(differ):
|
||||||
|
code1 = dedent('''\
|
||||||
|
class Grammar:
|
||||||
|
x
|
||||||
|
def parse():
|
||||||
|
y
|
||||||
|
parser(
|
||||||
|
)
|
||||||
|
z
|
||||||
|
''')
|
||||||
|
code2 = dedent('''\
|
||||||
|
class Grammar:
|
||||||
|
x
|
||||||
|
def parse():
|
||||||
|
y
|
||||||
|
parser(
|
||||||
|
finally ;
|
||||||
|
)
|
||||||
|
z
|
||||||
|
''')
|
||||||
|
differ.initialize(code1)
|
||||||
|
differ.parse(code2, parsers=3, copies=1, expect_error_leaves=True)
|
||||||
|
|||||||
Reference in New Issue
Block a user