1
0
forked from VimPlug/jedi

The fast parser splitting now also checks for parentheses levels, because without that, sometimes we split in very strange positions, while ignoring others.

This commit is contained in:
Dave Halter
2015-02-18 13:48:08 +01:00
parent 38e26892f2
commit 595da50ab8
2 changed files with 42 additions and 5 deletions

View File

@@ -278,6 +278,7 @@ class FastParser(use_metaclass(CachedFastParser)):
# Use -1, because that indent is always smaller than any other. # Use -1, because that indent is always smaller than any other.
indent_list = [-1, 0] indent_list = [-1, 0]
new_indent = False new_indent = False
parentheses_level = 0
flow_indent = None flow_indent = None
# All things within flows are simply being ignored. # All things within flows are simply being ignored.
for i, l in enumerate(self._lines): for i, l in enumerate(self._lines):
@@ -299,9 +300,8 @@ class FastParser(use_metaclass(CachedFastParser)):
# This automatically resets the flow_indent if there was a # This automatically resets the flow_indent if there was a
# dedent or a flow just on one line (with one simple_stmt). # dedent or a flow just on one line (with one simple_stmt).
new_indent = False new_indent = False
if flow_indent is None: if flow_indent is None and current_lines and not parentheses_level:
if current_lines: yield gen_part()
yield gen_part()
flow_indent = None flow_indent = None
# Check lines for functions/classes and split the code there. # Check lines for functions/classes and split the code there.
@@ -310,18 +310,23 @@ class FastParser(use_metaclass(CachedFastParser)):
if m: if m:
# Strip whitespace and colon from flows as a check. # Strip whitespace and colon from flows as a check.
if m.group(1).strip(' \t\r\n:') in FLOWS: if m.group(1).strip(' \t\r\n:') in FLOWS:
flow_indent = indent if not parentheses_level:
flow_indent = indent
else: else:
if not is_decorator and not just_newlines(current_lines): if not is_decorator and not just_newlines(current_lines):
yield gen_part() yield gen_part()
is_decorator = '@' == m.group(1) is_decorator = '@' == m.group(1)
if not is_decorator: if not is_decorator:
parentheses_level = 0
# The new indent needs to be higher # The new indent needs to be higher
indent_list.append(indent + 1) indent_list.append(indent + 1)
new_indent = True new_indent = True
elif is_decorator: elif is_decorator:
is_decorator = False is_decorator = False
parentheses_level += (l.count('(') + l.count('[') + l.count('{')
- l.count(')') - l.count(']') - l.count('}'))
current_lines.append(l) current_lines.append(l)
if current_lines: if current_lines:
yield gen_part() yield gen_part()

View File

@@ -334,7 +334,39 @@ def test_open_parentheses():
# however that would require to also break properly at flow level. That is # however that would require to also break properly at flow level. That is
# not possible because of ternary statements and would lead to strange # not possible because of ternary statements and would lead to strange
# behavior without much more knowledge. So we just keep it this way. # behavior without much more knowledge. So we just keep it this way.
assert p.number_parsers_used == 1 assert p.number_parsers_used == 2
def test_strange_parentheses():
src = dedent("""
class X():
a = (1
if 1 else 2)
def x():
pass
""")
check_fp(src, 2)
def test_backslash():
src = dedent("""\
a = 1\
if 1 else 2
def x():
pass
""")
check_fp(src, 2)
src = dedent("""\
if 2:
a = 1\
if 1 else 2
def y():
pass
""")
# The dangling if leads to not splitting where we theoretically could
# split.
check_fp(src, 1)
def test_incomplete_function(): def test_incomplete_function():