diff --git a/jedi/api/interpreter.py b/jedi/api/interpreter.py index 17540d6c..534447f5 100644 --- a/jedi/api/interpreter.py +++ b/jedi/api/interpreter.py @@ -99,7 +99,8 @@ class LazyName(helpers.FakeName): found = [evaluated] content = iterable.AlreadyEvaluated(found) - stmt = pt.ExprStmt([self, pt.Operator('=', (0, 0), ''), content]) + stmt = pt.ExprStmt([self, pt.Operator(pt.zero_position_modifier, + '=', (0, 0), ''), content]) stmt.parent = self._module return stmt diff --git a/jedi/evaluate/compiled/fake.py b/jedi/evaluate/compiled/fake.py index 954a5808..56d98d95 100644 --- a/jedi/evaluate/compiled/fake.py +++ b/jedi/evaluate/compiled/fake.py @@ -106,7 +106,7 @@ def get_faked(module, obj, name=None): # contain it). doc = '"""%s"""' % obj.__doc__ # TODO need escapes. suite = result.children[-1] - expr_stmt = pt.ExprStmt([pt.String(doc, (0, 0), '')]) + expr_stmt = pt.ExprStmt([pt.String(pt.zero_position_modifier, doc, (0, 0), '')]) new_line = pt.Whitespace('\n', (0, 0), '') docstr_node = pt.Node('simple_stmt', [expr_stmt, new_line]) suite.children.insert(2, docstr_node) diff --git a/jedi/evaluate/helpers.py b/jedi/evaluate/helpers.py index 59bad818..ca94016d 100644 --- a/jedi/evaluate/helpers.py +++ b/jedi/evaluate/helpers.py @@ -158,8 +158,6 @@ def get_module_names(module, all_scopes): class FakeSubModule(): line_offset = 0 - parent = None - path = None class FakeImport(pr.Import): @@ -196,7 +194,7 @@ class FakeName(pr.Name): In case is_definition is defined (not None), that bool value will be returned. """ - super(FakeName, self).__init__(name_str, start_pos) + super(FakeName, self).__init__(pr.zero_position_modifier, name_str, start_pos) self.parent = parent self._is_definition = is_definition diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index 8b921ab5..9463020c 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -260,7 +260,9 @@ class LazyInstanceDict(object): class InstanceName(pr.Name): def __init__(self, origin_name, parent): - super(InstanceName, self).__init__(origin_name.value, origin_name.start_pos) + super(InstanceName, self).__init__(origin_name.position_modifier, + origin_name.value, + origin_name.start_pos) self._origin_name = origin_name self.parent = parent diff --git a/jedi/parser/__init__.py b/jedi/parser/__init__.py index dfd9fcbb..273cd96f 100644 --- a/jedi/parser/__init__.py +++ b/jedi/parser/__init__.py @@ -128,6 +128,8 @@ class Parser(object): self.used_names = {} self.scope_names_stack = [{}] self.error_statement_stacks = [] + # For fast parser + self.position_modifier = pt.PositionModifier() p = PgenParser(grammar, self.convert_node, self.convert_leaf, self.error_recovery) tokenizer = tokenizer or tokenize.source_tokens(source) @@ -184,9 +186,9 @@ class Parser(object): if value in ('def', 'class', 'lambda'): self.scope_names_stack.append({}) - return pt.Keyword(value, start_pos, prefix) + return pt.Keyword(self.position_modifier, value, start_pos, prefix) else: - name = pt.Name(value, start_pos, prefix) + name = pt.Name(self.position_modifier, value, start_pos, prefix) # Keep a listing of all used names arr = self.used_names.setdefault(name.value, []) arr.append(name) @@ -194,13 +196,13 @@ class Parser(object): arr.append(name) return name elif type == token.STRING: - return pt.String(value, start_pos, prefix) + return pt.String(self.position_modifier, value, start_pos, prefix) elif type == token.NUMBER: - return pt.Number(value, start_pos, prefix) + return pt.Number(self.position_modifier, value, start_pos, prefix) elif type in (token.NEWLINE, token.ENDMARKER): - return pt.Whitespace(value, start_pos, prefix) + return pt.Whitespace(self.position_modifier, value, start_pos, prefix) else: - return pt.Operator(value, start_pos, prefix) + return pt.Operator(self.position_modifier, value, start_pos, prefix) def error_recovery(self, grammar, stack, typ, value, start_pos, prefix, add_token_callback): diff --git a/jedi/parser/tree.py b/jedi/parser/tree.py index 82a500de..34edb95d 100644 --- a/jedi/parser/tree.py +++ b/jedi/parser/tree.py @@ -51,6 +51,15 @@ def is_node(node, *symbol_names): return type in symbol_names +class PositionModifier(object): + """A start_pos modifier for the fast parser.""" + def __init__(self): + self.line = 0 + + +zero_position_modifier = PositionModifier() + + class DocstringMixin(object): __slots__ = () @@ -137,9 +146,10 @@ class Base(object): class Leaf(Base): - __slots__ = ('value', 'parent', 'start_pos', 'prefix') + __slots__ = ('position_modifier', 'value', 'parent', 'start_pos', 'prefix') - def __init__(self, value, start_pos, prefix=''): + def __init__(self, position_modifier, value, start_pos, prefix=''): + self.position_modifier = position_modifier self.value = value self.start_pos = start_pos self.prefix = prefix @@ -620,7 +630,7 @@ class SubModule(Scope, Module): string = re.sub('\.[a-z]+-\d{2}[mud]{0,3}$', '', r.group(1)) # Positions are not real, but a module starts at (1, 0) p = (1, 0) - name = Name(string, p) + name = Name(zero_position_modifier, string, p) name.parent = self return name