forked from VimPlug/jedi
Some diff parser refactorings.
This commit is contained in:
@@ -15,7 +15,7 @@ from jedi.parser.tree import Module, search_ancestor, EndMarker
|
|||||||
from jedi.parser.utils import parser_cache
|
from jedi.parser.utils import parser_cache
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi.parser.tokenize import (generate_tokens, NEWLINE, TokenInfo,
|
from jedi.parser.tokenize import (generate_tokens, NEWLINE, TokenInfo,
|
||||||
ENDMARKER, INDENT, DEDENT, tok_name)
|
ENDMARKER, INDENT, DEDENT)
|
||||||
|
|
||||||
|
|
||||||
class CachedFastParser(type):
|
class CachedFastParser(type):
|
||||||
@@ -197,6 +197,7 @@ class DiffParser(object):
|
|||||||
p_children = line_stmt.parent.children
|
p_children = line_stmt.parent.children
|
||||||
index = p_children.index(line_stmt)
|
index = p_children.index(line_stmt)
|
||||||
nodes = []
|
nodes = []
|
||||||
|
# Match all the nodes that are in the wanted range.
|
||||||
for node in p_children[index:]:
|
for node in p_children[index:]:
|
||||||
last_line = _get_last_line(node)
|
last_line = _get_last_line(node)
|
||||||
|
|
||||||
@@ -224,11 +225,11 @@ class DiffParser(object):
|
|||||||
|
|
||||||
if nodes:
|
if nodes:
|
||||||
self._copy_count += 1
|
self._copy_count += 1
|
||||||
from_ = nodes[0].start_pos[0]
|
|
||||||
to = _get_last_line(nodes[-1])
|
|
||||||
debug.dbg('diff actually copy %s to %s', from_, to)
|
|
||||||
self._update_positions(nodes, line_offset)
|
self._update_positions(nodes, line_offset)
|
||||||
self._insert_nodes(nodes)
|
self._insert_nodes(nodes)
|
||||||
|
from_ = nodes[0].get_start_pos_of_prefix()[0]
|
||||||
|
to = _get_last_line(nodes[-1])
|
||||||
|
debug.dbg('diff actually copy %s to %s', from_, to)
|
||||||
self._copied_ranges.append((from_, to))
|
self._copied_ranges.append((from_, to))
|
||||||
# We have copied as much as possible (but definitely not too
|
# We have copied as much as possible (but definitely not too
|
||||||
# much). Therefore we just parse the rest.
|
# much). Therefore we just parse the rest.
|
||||||
@@ -261,13 +262,6 @@ class DiffParser(object):
|
|||||||
node.start_pos = node.start_pos[0] + line_offset, node.start_pos[1]
|
node.start_pos = node.start_pos[0] + line_offset, node.start_pos[1]
|
||||||
else:
|
else:
|
||||||
self._update_positions(children, line_offset)
|
self._update_positions(children, line_offset)
|
||||||
if line_offset == 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
# Find start node:
|
|
||||||
node = self._parser.get_parsed_node()
|
|
||||||
while True:
|
|
||||||
return node
|
|
||||||
|
|
||||||
def _insert_nodes(self, nodes):
|
def _insert_nodes(self, nodes):
|
||||||
"""
|
"""
|
||||||
@@ -328,9 +322,6 @@ class DiffParser(object):
|
|||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# TODO check if the indentation is lower than the last statement
|
|
||||||
# and add a dedent error leaf.
|
|
||||||
# TODO do the same for indent error leafs.
|
|
||||||
p_children += nodes
|
p_children += nodes
|
||||||
assert new_parent.type in ('suite', 'file_input')
|
assert new_parent.type in ('suite', 'file_input')
|
||||||
break
|
break
|
||||||
@@ -379,7 +370,7 @@ class DiffParser(object):
|
|||||||
if divided_node is not None:
|
if divided_node is not None:
|
||||||
new_suite_children.append(divided_node)
|
new_suite_children.append(divided_node)
|
||||||
if len(new_suite_children) < 2:
|
if len(new_suite_children) < 2:
|
||||||
# A suite only with newline and indent is not valid.
|
# A suite only with newline is not valid.
|
||||||
return None
|
return None
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
@@ -403,7 +394,7 @@ class DiffParser(object):
|
|||||||
valid state is reached.
|
valid state is reached.
|
||||||
"""
|
"""
|
||||||
while until_line > self._parsed_until_line:
|
while until_line > self._parsed_until_line:
|
||||||
node = self._parse_scope_node(until_line)
|
node = self._try_parse_part(until_line)
|
||||||
nodes = self._get_children_nodes(node)
|
nodes = self._get_children_nodes(node)
|
||||||
self._insert_nodes(nodes)
|
self._insert_nodes(nodes)
|
||||||
_merge_used_names(
|
_merge_used_names(
|
||||||
@@ -415,15 +406,21 @@ class DiffParser(object):
|
|||||||
nodes = node.children
|
nodes = node.children
|
||||||
first_element = nodes[0]
|
first_element = nodes[0]
|
||||||
# TODO this looks very strange...
|
# TODO this looks very strange...
|
||||||
#if first_element.type == 'error_leaf' and \
|
if first_element.type == 'error_leaf' and \
|
||||||
#first_element.original_type == 'indent':
|
first_element.original_type == 'indent':
|
||||||
|
assert False, str(nodes)
|
||||||
#assert nodes[-1].type == 'dedent'
|
#assert nodes[-1].type == 'dedent'
|
||||||
## This means that the start and end leaf
|
## This means that the start and end leaf
|
||||||
#nodes = nodes[1:-1] + [nodes[-1]]
|
#nodes = nodes[1:-1] + [nodes[-1]]
|
||||||
|
|
||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
def _parse_scope_node(self, until_line):
|
def _try_parse_part(self, until_line):
|
||||||
|
"""
|
||||||
|
Sets up a normal parser that uses a spezialized tokenizer to only parse
|
||||||
|
until a certain position (or a bit longer if the statement hasn't
|
||||||
|
ended.
|
||||||
|
"""
|
||||||
self._parser_count += 1
|
self._parser_count += 1
|
||||||
# TODO speed up, shouldn't copy the whole list all the time.
|
# TODO speed up, shouldn't copy the whole list all the time.
|
||||||
# memoryview?
|
# memoryview?
|
||||||
@@ -442,6 +439,7 @@ class DiffParser(object):
|
|||||||
return self._active_parser.parse(tokenizer=tokenizer)
|
return self._active_parser.parse(tokenizer=tokenizer)
|
||||||
|
|
||||||
def _cleanup(self):
|
def _cleanup(self):
|
||||||
|
"""Add used names and an end marker."""
|
||||||
# Add the used names from the old parser to the new one.
|
# Add the used names from the old parser to the new one.
|
||||||
copied_line_numbers = set()
|
copied_line_numbers = set()
|
||||||
for l1, l2 in self._copied_ranges:
|
for l1, l2 in self._copied_ranges:
|
||||||
|
|||||||
@@ -298,3 +298,23 @@ def test_issues_with_error_leaves(differ):
|
|||||||
''')
|
''')
|
||||||
differ.initialize(code)
|
differ.initialize(code)
|
||||||
differ.parse(code2, parsers=2, copies=0, expect_error_leaves=True)
|
differ.parse(code2, parsers=2, copies=0, expect_error_leaves=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_unfinished_nodes(differ):
|
||||||
|
code = dedent('''
|
||||||
|
class a():
|
||||||
|
def __init__(self, a):
|
||||||
|
self.a = a
|
||||||
|
def p(self):
|
||||||
|
a(1)
|
||||||
|
''')
|
||||||
|
code2 = dedent('''
|
||||||
|
class a():
|
||||||
|
def __init__(self, a):
|
||||||
|
self.a = a
|
||||||
|
def p(self):
|
||||||
|
self.
|
||||||
|
a(1)
|
||||||
|
''')
|
||||||
|
differ.initialize(code)
|
||||||
|
differ.parse(code2, parsers=2, copies=1, expect_error_leaves=True)
|
||||||
|
|||||||
Reference in New Issue
Block a user