1
0
forked from VimPlug/jedi

Merge branch 'remove_names_dicts' into diff

This commit is contained in:
Dave Halter
2016-09-11 13:24:11 +02:00
8 changed files with 26 additions and 51 deletions

View File

@@ -51,19 +51,6 @@ class OnErrorLeaf(Exception):
def _is_on_comment(leaf, position): def _is_on_comment(leaf, position):
# We might be on a comment.
if leaf.type == 'endmarker':
try:
dedent = leaf.get_previous_leaf()
if dedent.type == 'dedent' and dedent.prefix:
# TODO This is needed because the fast parser uses multiple
# endmarker tokens within a file which is obviously ugly.
# This is so ugly that I'm not even commenting how it exactly
# happens, but let me tell you that I want to get rid of it.
leaf = dedent
except IndexError:
pass
comment_lines = common.splitlines(leaf.prefix) comment_lines = common.splitlines(leaf.prefix)
difference = leaf.start_pos[0] - position[0] difference = leaf.start_pos[0] - position[0]
prefix_start_pos = leaf.get_start_pos_of_prefix() prefix_start_pos = leaf.get_start_pos_of_prefix()
@@ -98,9 +85,11 @@ def _get_code_for_stack(code_lines, module, position):
except IndexError: except IndexError:
return u('') return u('')
if leaf.type in ('indent', 'dedent'): if leaf.type == 'error_leaf' or leaf.type == 'string':
if leaf.start_pos[0] < position[0]:
# On a different line, we just begin anew.
return u('') return u('')
elif leaf.type == 'error_leaf' or leaf.type == 'string':
# Error leafs cannot be parsed, completion in strings is also # Error leafs cannot be parsed, completion in strings is also
# impossible. # impossible.
raise OnErrorLeaf(leaf) raise OnErrorLeaf(leaf)
@@ -142,7 +131,6 @@ def get_stack_at_position(grammar, code_lines, module, pos):
# completion. # completion.
# Use Z as a prefix because it's not part of a number suffix. # Use Z as a prefix because it's not part of a number suffix.
safeword = 'ZZZ_USER_WANTS_TO_COMPLETE_HERE_WITH_JEDI' safeword = 'ZZZ_USER_WANTS_TO_COMPLETE_HERE_WITH_JEDI'
# Remove as many indents from **all** code lines as possible.
code = code + safeword code = code + safeword
p = parser.ParserWithRecovery(grammar, code, start_parsing=False) p = parser.ParserWithRecovery(grammar, code, start_parsing=False)
@@ -266,9 +254,14 @@ def _get_call_signature_details_from_error_node(node, position):
def get_call_signature_details(module, position): def get_call_signature_details(module, position):
leaf = module.get_leaf_for_position(position, include_prefixes=True) leaf = module.get_leaf_for_position(position, include_prefixes=True)
if leaf.start_pos >= position:
# Whitespace / comments after the leaf count towards the previous leaf.
leaf = leaf.get_previous_leaf()
if leaf == ')': if leaf == ')':
if leaf.end_pos == position: if leaf.end_pos == position:
leaf = leaf.get_next_leaf() leaf = leaf.get_next_leaf()
# Now that we know where we are in the syntax tree, we start to look at # Now that we know where we are in the syntax tree, we start to look at
# parents for possible function definitions. # parents for possible function definitions.
node = leaf.parent node = leaf.parent

View File

@@ -181,9 +181,9 @@ def _get_faked(module, obj, name=None):
doc = '"""%s"""' % obj.__doc__ # TODO need escapes. doc = '"""%s"""' % obj.__doc__ # TODO need escapes.
suite = result.children[-1] suite = result.children[-1]
string = pt.String(pt.zero_position_modifier, doc, (0, 0), '') string = pt.String(pt.zero_position_modifier, doc, (0, 0), '')
new_line = pt.Newline('\n', (0, 0), '') new_line = pt.Newline(pt.zero_position_modifier, '\n', (0, 0))
docstr_node = pt.Node('simple_stmt', [string, new_line]) docstr_node = pt.Node('simple_stmt', [string, new_line])
suite.children.insert(2, docstr_node) suite.children.insert(1, docstr_node)
return result return result

View File

@@ -134,9 +134,9 @@ def _evaluate_for_statement_string(evaluator, string, module):
p = ParserWithRecovery(load_grammar(), code % indent_block(string)) p = ParserWithRecovery(load_grammar(), code % indent_block(string))
try: try:
pseudo_cls = p.module.subscopes[0] pseudo_cls = p.module.subscopes[0]
# First pick suite, then simple_stmt (-2 for DEDENT) and then the node, # First pick suite, then simple_stmt and then the node,
# which is also not the last item, because there's a newline. # which is also not the last item, because there's a newline.
stmt = pseudo_cls.children[-1].children[-2].children[-2] stmt = pseudo_cls.children[-1].children[-1].children[-2]
except (AttributeError, IndexError): except (AttributeError, IndexError):
return [] return []

View File

@@ -27,7 +27,7 @@ def deep_ast_copy(obj, parent=None, new_elements=None):
for child in obj.children: for child in obj.children:
typ = child.type typ = child.type
if typ in ('newline', 'operator', 'keyword', 'number', 'string', if typ in ('newline', 'operator', 'keyword', 'number', 'string',
'indent', 'dedent', 'endmarker', 'error_leaf'): 'endmarker', 'error_leaf'):
# At the moment we're not actually copying those primitive # At the moment we're not actually copying those primitive
# elements, because there's really no need to. The parents are # elements, because there's really no need to. The parents are
# obviously wrong, but that's not an issue. # obviously wrong, but that's not an issue.

View File

@@ -172,6 +172,12 @@ class Parser(object):
try: try:
new_node = Parser.AST_MAPPING[symbol](children) new_node = Parser.AST_MAPPING[symbol](children)
except KeyError: except KeyError:
if symbol == 'suite':
# We don't want the INDENT/DEDENT in our parser tree. Those
# leaves are just cancer. They are virtual leaves and not real
# ones and therefore have pseudo start/end positions and no
# prefixes. Just ignore them.
children = [children[0]] + children[2:-1]
new_node = pt.Node(symbol, children) new_node = pt.Node(symbol, children)
# We need to check raw_node always, because the same node can be # We need to check raw_node always, because the same node can be
@@ -220,10 +226,6 @@ class Parser(object):
return pt.Number(self.position_modifier, value, start_pos, prefix) return pt.Number(self.position_modifier, value, start_pos, prefix)
elif type == NEWLINE: elif type == NEWLINE:
return pt.Newline(self.position_modifier, value, start_pos, prefix) return pt.Newline(self.position_modifier, value, start_pos, prefix)
elif type == INDENT:
return pt.Indent(self.position_modifier, value, start_pos, prefix)
elif type == DEDENT:
return pt.Dedent(self.position_modifier, value, start_pos, prefix)
elif type == ENDMARKER: elif type == ENDMARKER:
return pt.EndMarker(self.position_modifier, value, start_pos, prefix) return pt.EndMarker(self.position_modifier, value, start_pos, prefix)
else: else:

View File

@@ -87,7 +87,7 @@ class DocstringMixin(object):
elif isinstance(self, ClassOrFunc): elif isinstance(self, ClassOrFunc):
node = self.children[self.children.index(':') + 1] node = self.children[self.children.index(':') + 1]
if is_node(node, 'suite'): # Normally a suite if is_node(node, 'suite'): # Normally a suite
node = node.children[2] # -> NEWLINE INDENT stmt node = node.children[1] # -> NEWLINE stmt
else: # ExprStmt else: # ExprStmt
simple_stmt = self.parent simple_stmt = self.parent
c = simple_stmt.parent.children c = simple_stmt.parent.children
@@ -160,7 +160,7 @@ class Base(object):
return scope return scope
def get_definition(self): def get_definition(self):
if self.type in ('newline', 'dedent', 'indent', 'endmarker'): if self.type in ('newline', 'endmarker'):
raise ValueError('Cannot get the indentation of whitespace or indentation.') raise ValueError('Cannot get the indentation of whitespace or indentation.')
scope = self scope = self
while scope.parent is not None: while scope.parent is not None:
@@ -307,11 +307,7 @@ class Leaf(Base):
def get_start_pos_of_prefix(self): def get_start_pos_of_prefix(self):
try: try:
previous_leaf = self return self.get_previous_leaf().end_pos
while True:
previous_leaf = previous_leaf.get_previous_leaf()
if previous_leaf.type not in ('indent', 'dedent'):
return previous_leaf.end_pos
except IndexError: except IndexError:
return 1, 0 # It's the first leaf. return 1, 0 # It's the first leaf.
@@ -444,16 +440,6 @@ class String(Literal):
__slots__ = () __slots__ = ()
class Indent(Leaf):
type = 'indent'
__slots__ = ()
class Dedent(Leaf):
type = 'dedent'
__slots__ = ()
class Operator(Leaf): class Operator(Leaf):
type = 'operator' type = 'operator'
__slots__ = () __slots__ = ()
@@ -568,10 +554,6 @@ class BaseNode(Base):
try: try:
return c.get_leaf_for_position(position, include_prefixes) return c.get_leaf_for_position(position, include_prefixes)
except AttributeError: except AttributeError:
while c.type in ('indent', 'dedent'):
# We'd rather not have indents and dedents as a leaf,
# because they don't contain indentation information.
c = c.get_next_leaf()
return c return c
return None return None

View File

@@ -130,7 +130,7 @@ On Linux, if environment variable ``$XDG_CACHE_HOME`` is set,
# parser # parser
# ---------------- # ----------------
fast_parser = True fast_parser = False
""" """
Use the fast parser. This means that reparsing is only being done if Use the fast parser. This means that reparsing is only being done if
something has been changed e.g. to a function. If this happens, only the something has been changed e.g. to a function. If this happens, only the

View File

@@ -177,9 +177,7 @@ def test_end_pos_error_correction():
m = ParserWithRecovery(load_grammar(), s).module m = ParserWithRecovery(load_grammar(), s).module
func = m.children[0] func = m.children[0]
assert func.type == 'funcdef' assert func.type == 'funcdef'
# This is not exactly correct, but ok, because it doesn't make a difference assert func.end_pos == (2, 2)
# at all. We just want to make sure that the module end_pos is correct!
assert func.end_pos == (3, 0)
assert m.end_pos == (2, 2) assert m.end_pos == (2, 2)