1
0
forked from VimPlug/jedi

first test working again with new fast_parser

This commit is contained in:
David Halter
2013-04-13 13:50:50 +04:30
parent 967d01d490
commit eeb8e0e21d

View File

@@ -44,26 +44,12 @@ class Module(pr.Simple, pr.Module):
return self.cache[key] return self.cache[key]
def __getattr__(self, name): def __getattr__(self, name):
operators = {'get_imports': operator.add, if name == 'global_vars':
'get_code': operator.add, return self._get(name, operator.add)
'get_set_vars': operator.add, elif name.startswith('__'):
'get_defined_names': operator.add, raise AttributeError('Not available!')
'is_empty': operator.and_
}
properties = {'subscopes': operator.add,
'imports': operator.add,
'statements': operator.add,
'imports': operator.add,
'asserts': operator.add,
'global_vars': operator.add
}
if name in operators:
return lambda *args, **kwargs: self._get(name, operators[name],
True, *args, **kwargs)
elif name in properties:
return self._get(name, properties[name])
else: else:
raise AttributeError("__getattr__ doesn't offer %s" % name) return getattr(self.parsers[0].module, name)
@property @property
def used_names(self): def used_names(self):
@@ -90,7 +76,7 @@ class Module(pr.Simple, pr.Module):
@start_pos.setter @start_pos.setter
def start_pos(self): def start_pos(self):
""" ignore """ """ ignore """
pass raise AttributeError('TODO remove - just a check if everything works fine.')
@property @property
def end_pos(self): def end_pos(self):
@@ -131,7 +117,7 @@ class ParserNode(object):
self.hash = hash(code) self.hash = hash(code)
self.children = [] self.children = []
self._checked = True self._old_children = []
# must be created before new things are added to it. # must be created before new things are added to it.
try: try:
# with fast_parser we have either 1 subscope or only statements. # with fast_parser we have either 1 subscope or only statements.
@@ -144,15 +130,13 @@ class ParserNode(object):
scope = self._content_scope scope = self._content_scope
self._contents = {} self._contents = {}
for c in SCOPE_CONTENTS: for c in SCOPE_CONTENTS:
self._contents[c] = list(getattr(scope, c)) self._contents[c] = getattr(scope, c)
self._is_generator = scope.is_generator self._is_generator = scope.is_generator
def reset_contents(self): def reset_contents(self):
self._checked = False
scope = self._content_scope scope = self._content_scope
for key, c in self._contents.items(): for key, c in self._contents.items():
setattr(scope, key, self.contents.items()) setattr(scope, key, c)
scope.is_generator = self._is_generator scope.is_generator = self._is_generator
for c in self.children: for c in self.children:
@@ -160,13 +144,7 @@ class ParserNode(object):
def parent_until_indent(self, indent): def parent_until_indent(self, indent):
if self.indent >= indent and self.parent: if self.indent >= indent and self.parent:
# check for self._old_children = []
for i, c in enumerate(self.children):
if not c._checked:
# all of the following
del self.children[i:]
break
return self.parent.parent_until_indent(indent) return self.parent.parent_until_indent(indent)
return self return self
@@ -184,21 +162,30 @@ class ParserNode(object):
el = module.imports[0] el = module.imports[0]
return el.start_pos[1] return el.start_pos[1]
def add_node(self, parser, code): def _set_items(self, parser, set_parent=False):
# only compare at the right indent level
insert = 0
for insert, c in enumerate(self.children):
if not c._checked:
break
node = ParserNode(parser, code, self)
self.children.insert(insert, node)
# insert parser objects into current structure # insert parser objects into current structure
scope = self._content_scope scope = self._content_scope
for c in SCOPE_CONTENTS: for c in SCOPE_CONTENTS:
content = getattr(scope, c) content = getattr(scope, c)
content += getattr(parser.module, c) items = getattr(parser.module, c)
if set_parent:
for i in items:
i.parent = scope
content += items
scope.is_generator |= parser.module.is_generator scope.is_generator |= parser.module.is_generator
def add_node(self, node):
"""Adding a node means adding a node that was already added earlier"""
self.children.append(node)
self._set_items(node.parser)
node._old_children = node.children
node.children = []
return node
def add_parser(self, parser, code):
node = ParserNode(parser, code, self)
self._set_items(parser, set_parent=True)
self.children.append(node)
return node return node
@@ -333,17 +320,17 @@ class FastParser(use_metaclass(CachedFastParser)):
if is_first or self._line_offset >= p.end_pos[0] - 1: if is_first or self._line_offset >= p.end_pos[0] - 1:
indent = len(re.match(r'[ \t]*', code_part).group(0)) indent = len(re.match(r'[ \t]*', code_part).group(0))
if is_first and self.current_node is not None: if is_first and self.current_node is not None:
nodes = [self] nodes = [self.current_node]
else: else:
nodes = [] nodes = []
if self.current_node is not None: if self.current_node is not None:
self.current_node = \ self.current_node = \
self.current_node.parent_until_indent(indent) self.current_node.parent_until_indent(indent)
nodes += self.current_node.children nodes += self.current_node._old_children
# check if code_part has already been parsed # check if code_part has already been parsed
p = self._get_parser(code_part, nodes) p, node = self._get_parser(code_part, nodes)
if is_first: if is_first:
if self.current_node is None: if self.current_node is None:
@@ -352,7 +339,11 @@ class FastParser(use_metaclass(CachedFastParser)):
self.current_node.parser = p self.current_node.parser = p
self.current_node.save_contents() self.current_node.save_contents()
else: else:
self.current_node = self.current_node.add_node(p, code) if node is None:
self.current_node = \
self.current_node.add_parser(p, code)
else:
self.current_node = self.current_node.add_node(node)
self.parsers.append(p) self.parsers.append(p)
is_first = False is_first = False
@@ -360,16 +351,17 @@ class FastParser(use_metaclass(CachedFastParser)):
self._line_offset += lines self._line_offset += lines
self._start += len(code_part) + 1 # +1 for newline self._start += len(code_part) + 1 # +1 for newline
print(self.parsers[0].module.get_code()) #print(self.parsers[0].module.get_code())
#for p in self.parsers: #for p in self.parsers:
# print(p.module.get_code()) # print(p.module.get_code())
# print(p.module.start_pos, p.module.end_pos) # print(p.module.start_pos, p.module.end_pos)
exit() #exit()
del self._code del self._code
def _get_parser(self, code, nodes): def _get_parser(self, code, nodes):
h = hash(code) h = hash(code)
hashes = [n.hash for n in nodes] hashes = [n.hash for n in nodes]
node = None
try: try:
index = hashes.index(h) index = hashes.index(h)
if nodes[index].code != code: if nodes[index].code != code:
@@ -394,7 +386,7 @@ class FastParser(use_metaclass(CachedFastParser)):
p.user_scope = p.user_stmt.parent p.user_scope = p.user_stmt.parent
else: else:
p.user_scope = self.scan_user_scope(m) or self.module p.user_scope = self.scan_user_scope(m) or self.module
return p return p, node
def reset_caches(self): def reset_caches(self):
self._user_scope = None self._user_scope = None