forked from VimPlug/jedi
Temporary parser implementation. Now we're pretty much done with pr.Name.
This commit is contained in:
@@ -101,16 +101,17 @@ class Parser(object):
|
|||||||
self.module.used_names[tok_name] = set([simple])
|
self.module.used_names[tok_name] = set([simple])
|
||||||
self.module.temp_used_names = []
|
self.module.temp_used_names = []
|
||||||
|
|
||||||
def _parse_dot_name(self, pre_used_token=None):
|
def _parse_dotted_name(self, pre_used_token=None):
|
||||||
"""
|
"""
|
||||||
The dot name parser parses a name, variable or function and returns
|
The dot name parser parses a name, variable or function and returns
|
||||||
their names.
|
their names.
|
||||||
|
Just used for parsing imports.
|
||||||
|
|
||||||
:return: tuple of Name, next_token
|
:return: tuple of Name, next_token
|
||||||
"""
|
"""
|
||||||
def append(el):
|
def append(tok):
|
||||||
names.append(el)
|
names.append(pr.NamePart(self.module, tok.string, None, tok.start_pos))
|
||||||
self.module.temp_used_names.append(el[0])
|
self.module.temp_used_names.append(tok.string)
|
||||||
|
|
||||||
names = []
|
names = []
|
||||||
tok = next(self._gen) if pre_used_token is None else pre_used_token
|
tok = next(self._gen) if pre_used_token is None else pre_used_token
|
||||||
@@ -118,26 +119,23 @@ class Parser(object):
|
|||||||
if tok.type != tokenize.NAME and tok.string != '*':
|
if tok.type != tokenize.NAME and tok.string != '*':
|
||||||
return None, tok
|
return None, tok
|
||||||
|
|
||||||
first_pos = tok.start_pos
|
append(tok)
|
||||||
append((tok.string, first_pos))
|
|
||||||
while True:
|
while True:
|
||||||
end_pos = tok.end_pos
|
|
||||||
tok = next(self._gen)
|
tok = next(self._gen)
|
||||||
if tok.string != '.':
|
if tok.string != '.':
|
||||||
break
|
break
|
||||||
tok = next(self._gen)
|
tok = next(self._gen)
|
||||||
if tok.type != tokenize.NAME:
|
if tok.type != tokenize.NAME:
|
||||||
break
|
break
|
||||||
append((tok.string, tok.start_pos))
|
append(tok)
|
||||||
|
|
||||||
n = pr.Name(self.module, names, first_pos, end_pos) if names else None
|
return names, tok
|
||||||
return n, tok
|
|
||||||
|
|
||||||
def _parse_name(self, pre_used_token=None):
|
def _parse_name(self, pre_used_token=None):
|
||||||
tok = next(self._gen) if pre_used_token is None else pre_used_token
|
tok = next(self._gen) if pre_used_token is None else pre_used_token
|
||||||
if tok.type != tokenize.NAME:
|
if tok.type != tokenize.NAME:
|
||||||
return None
|
return None, tok
|
||||||
return pr.NamePart(self.module, tok.string, None, tok.start_pos)
|
return pr.NamePart(self.module, tok.string, None, tok.start_pos), next(self._gen)
|
||||||
|
|
||||||
def _parse_import_list(self):
|
def _parse_import_list(self):
|
||||||
"""
|
"""
|
||||||
@@ -167,13 +165,13 @@ class Parser(object):
|
|||||||
tok = next(self._gen)
|
tok = next(self._gen)
|
||||||
if brackets and tok.type == tokenize.NEWLINE:
|
if brackets and tok.type == tokenize.NEWLINE:
|
||||||
tok = next(self._gen)
|
tok = next(self._gen)
|
||||||
i, tok = self._parse_dot_name(tok)
|
names, tok = self._parse_dotted_name(tok)
|
||||||
if not i:
|
if not names:
|
||||||
defunct = True
|
defunct = True
|
||||||
name2 = None
|
alias = None
|
||||||
if tok.string == 'as':
|
if tok.string == 'as':
|
||||||
name2, tok = self._parse_dot_name()
|
alias, tok = self._parse_name()
|
||||||
imports.append((i, name2, defunct))
|
imports.append((names, alias, defunct))
|
||||||
while tok.string not in continue_kw:
|
while tok.string not in continue_kw:
|
||||||
tok = next(self._gen)
|
tok = next(self._gen)
|
||||||
if not (tok.string == "," or brackets and tok.type == tokenize.NEWLINE):
|
if not (tok.string == "," or brackets and tok.type == tokenize.NEWLINE):
|
||||||
@@ -230,9 +228,8 @@ class Parser(object):
|
|||||||
if tok.type != tokenize.NAME:
|
if tok.type != tokenize.NAME:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
fname = self._parse_name(tok)
|
fname, tok = self._parse_name(tok)
|
||||||
|
|
||||||
tok = next(self._gen)
|
|
||||||
if tok.string != '(':
|
if tok.string != '(':
|
||||||
return None
|
return None
|
||||||
params = self._parse_parentheses(is_class=False)
|
params = self._parse_parentheses(is_class=False)
|
||||||
@@ -269,10 +266,9 @@ class Parser(object):
|
|||||||
cname.start_pos[0], tokenize.tok_name[cname.type], cname.string)
|
cname.start_pos[0], tokenize.tok_name[cname.type], cname.string)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
cname = self._parse_name(cname)
|
cname, _next = self._parse_name(cname)
|
||||||
|
|
||||||
superclasses = []
|
superclasses = []
|
||||||
_next = next(self._gen)
|
|
||||||
if _next.string == '(':
|
if _next.string == '(':
|
||||||
superclasses = self._parse_parentheses(is_class=True)
|
superclasses = self._parse_parentheses(is_class=True)
|
||||||
_next = next(self._gen)
|
_next = next(self._gen)
|
||||||
@@ -346,7 +342,7 @@ class Parser(object):
|
|||||||
if tok.string == 'as':
|
if tok.string == 'as':
|
||||||
tok = next(self._gen)
|
tok = next(self._gen)
|
||||||
if tok.type == tokenize.NAME:
|
if tok.type == tokenize.NAME:
|
||||||
n, tok = self._parse_dot_name(self._gen.current)
|
n, tok = self._parse_name(self._gen.current)
|
||||||
if n:
|
if n:
|
||||||
set_vars.append(n)
|
set_vars.append(n)
|
||||||
as_names.append(n)
|
as_names.append(n)
|
||||||
@@ -358,11 +354,6 @@ class Parser(object):
|
|||||||
elif in_lambda_param and tok.string == ':':
|
elif in_lambda_param and tok.string == ':':
|
||||||
in_lambda_param = False
|
in_lambda_param = False
|
||||||
elif tok.type == tokenize.NAME and not is_kw:
|
elif tok.type == tokenize.NAME and not is_kw:
|
||||||
n, tok = self._parse_dot_name(self._gen.current)
|
|
||||||
# removed last entry, because we add Name
|
|
||||||
tok_list.pop()
|
|
||||||
if n:
|
|
||||||
tok_list.append(n)
|
|
||||||
continue
|
continue
|
||||||
elif tok.string in opening_brackets:
|
elif tok.string in opening_brackets:
|
||||||
level += 1
|
level += 1
|
||||||
@@ -464,10 +455,10 @@ class Parser(object):
|
|||||||
# import stuff
|
# import stuff
|
||||||
elif tok_str == 'import':
|
elif tok_str == 'import':
|
||||||
imports = self._parse_import_list()
|
imports = self._parse_import_list()
|
||||||
for count, (m, alias, defunct) in enumerate(imports):
|
for count, (names, alias, defunct) in enumerate(imports):
|
||||||
e = (alias or m or self._gen.previous).end_pos
|
e = (alias or m or self._gen.previous).end_pos
|
||||||
end_pos = self._gen.previous.end_pos if count + 1 == len(imports) else e
|
end_pos = self._gen.previous.end_pos if count + 1 == len(imports) else e
|
||||||
i = pr.Import(self.module, first_pos, end_pos, m,
|
i = pr.Import(self.module, first_pos, end_pos, names,
|
||||||
alias, defunct=defunct)
|
alias, defunct=defunct)
|
||||||
self._check_user_stmt(i)
|
self._check_user_stmt(i)
|
||||||
self._scope.add_import(i)
|
self._scope.add_import(i)
|
||||||
@@ -486,26 +477,26 @@ class Parser(object):
|
|||||||
break
|
break
|
||||||
relative_count += 1
|
relative_count += 1
|
||||||
# the from import
|
# the from import
|
||||||
mod, tok = self._parse_dot_name(self._gen.current)
|
from_names, tok = self._parse_dotted_name(self._gen.current)
|
||||||
tok_str = tok.string
|
tok_str = tok.string
|
||||||
if str(mod) == 'import' and relative_count:
|
if len(from_names) == 1 and str(from_names[0]) == 'import' and relative_count:
|
||||||
self._gen.push_last_back()
|
self._gen.push_last_back()
|
||||||
tok_str = 'import'
|
tok_str = 'import'
|
||||||
mod = None
|
names = []
|
||||||
if not mod and not relative_count or tok_str != "import":
|
if not names and not relative_count or tok_str != "import":
|
||||||
debug.warning("from: syntax error@%s", tok.start_pos[0])
|
debug.warning("from: syntax error@%s", tok.start_pos[0])
|
||||||
defunct = True
|
defunct = True
|
||||||
if tok_str != 'import':
|
if tok_str != 'import':
|
||||||
self._gen.push_last_back()
|
self._gen.push_last_back()
|
||||||
names = self._parse_import_list()
|
names = self._parse_import_list()
|
||||||
for count, (name, alias, defunct2) in enumerate(names):
|
for count, (names, alias, defunct2) in enumerate(names):
|
||||||
star = name is not None and unicode(name.names[0]) == '*'
|
star = names and unicode(names) == '*'
|
||||||
if star:
|
if star:
|
||||||
name = None
|
names = []
|
||||||
e = (alias or name or self._gen.previous).end_pos
|
e = (alias or names and names[-1] or self._gen.previous).end_pos
|
||||||
end_pos = self._gen.previous.end_pos if count + 1 == len(names) else e
|
end_pos = self._gen.previous.end_pos if count + 1 == len(names) else e
|
||||||
i = pr.Import(self.module, first_pos, end_pos, name,
|
i = pr.Import(self.module, first_pos, end_pos, names,
|
||||||
alias, mod, star, relative_count,
|
alias, from_names, star, relative_count,
|
||||||
defunct=defunct or defunct2)
|
defunct=defunct or defunct2)
|
||||||
self._check_user_stmt(i)
|
self._check_user_stmt(i)
|
||||||
self._scope.add_import(i)
|
self._scope.add_import(i)
|
||||||
@@ -540,7 +531,7 @@ class Parser(object):
|
|||||||
if command == 'except' and tok.string == ',':
|
if command == 'except' and tok.string == ',':
|
||||||
# the except statement defines a var
|
# the except statement defines a var
|
||||||
# this is only true for python 2
|
# this is only true for python 2
|
||||||
n, tok = self._parse_dot_name()
|
n, tok = self._parse_name()
|
||||||
if n:
|
if n:
|
||||||
n.parent = statement
|
n.parent = statement
|
||||||
statement.as_names.append(n)
|
statement.as_names.append(n)
|
||||||
|
|||||||
@@ -768,25 +768,25 @@ class Import(Simple):
|
|||||||
|
|
||||||
:param start_pos: Position (line, column) of the Import.
|
:param start_pos: Position (line, column) of the Import.
|
||||||
:type start_pos: tuple(int, int)
|
:type start_pos: tuple(int, int)
|
||||||
:param namespace: The import, can be empty if a star is given
|
:param namespace_names: The import, can be empty if a star is given
|
||||||
:type namespace: Name
|
:type namespace_names: Name
|
||||||
:param alias: The alias of a namespace(valid in the current namespace).
|
:param alias: The alias of a namespace(valid in the current namespace).
|
||||||
:type alias: Name
|
:type alias: Name
|
||||||
:param from_ns: Like the namespace, can be equally used.
|
:param from_names: Like the namespace, can be equally used.
|
||||||
:type from_ns: Name
|
:type from_names: Name
|
||||||
:param star: If a star is used -> from time import *.
|
:param star: If a star is used -> from time import *.
|
||||||
:type star: bool
|
:type star: bool
|
||||||
:param defunct: An Import is valid or not.
|
:param defunct: An Import is valid or not.
|
||||||
:type defunct: bool
|
:type defunct: bool
|
||||||
"""
|
"""
|
||||||
def __init__(self, module, start_pos, end_pos, namespace, alias=None,
|
def __init__(self, module, start_pos, end_pos, namespace_names, alias=None,
|
||||||
from_ns=None, star=False, relative_count=0, defunct=False):
|
from_names=None, star=False, relative_count=0, defunct=False):
|
||||||
super(Import, self).__init__(module, start_pos, end_pos)
|
super(Import, self).__init__(module, start_pos, end_pos)
|
||||||
|
|
||||||
self.namespace = namespace
|
self.namespace_names = namespace_names
|
||||||
self.alias = alias
|
self.alias = alias
|
||||||
self.from_ns = from_ns
|
self.from_names = from_names
|
||||||
for n in namespace, alias, from_ns:
|
for n in namespace_names, alias, from_names:
|
||||||
if n:
|
if n:
|
||||||
n.parent = self.use_as_parent
|
n.parent = self.use_as_parent
|
||||||
|
|
||||||
@@ -797,20 +797,19 @@ class Import(Simple):
|
|||||||
def get_code(self, new_line=True):
|
def get_code(self, new_line=True):
|
||||||
# in case one of the names is None
|
# in case one of the names is None
|
||||||
alias = self.alias or ''
|
alias = self.alias or ''
|
||||||
namespace = self.namespace or ''
|
|
||||||
from_ns = self.from_ns or ''
|
|
||||||
|
|
||||||
|
namespace = '.'.join(self.namespace_names)
|
||||||
if self.alias:
|
if self.alias:
|
||||||
ns_str = "%s as %s" % (namespace, alias)
|
ns_str = "%s as %s" % ('.'.join(namespace), alias)
|
||||||
else:
|
else:
|
||||||
ns_str = unicode(namespace)
|
ns_str = namespace
|
||||||
|
|
||||||
nl = '\n' if new_line else ''
|
nl = '\n' if new_line else ''
|
||||||
if self.from_ns or self.relative_count:
|
if self.from_names or self.relative_count:
|
||||||
if self.star:
|
if self.star:
|
||||||
ns_str = '*'
|
ns_str = '*'
|
||||||
dots = '.' * self.relative_count
|
dots = '.' * self.relative_count
|
||||||
return "from %s%s import %s%s" % (dots, from_ns, ns_str, nl)
|
return "from %s%s import %s%s" % (dots, '.'.join(self.from_names), ns_str, nl)
|
||||||
else:
|
else:
|
||||||
return "import %s%s" % (ns_str, nl)
|
return "import %s%s" % (ns_str, nl)
|
||||||
|
|
||||||
@@ -821,22 +820,19 @@ class Import(Simple):
|
|||||||
return [self]
|
return [self]
|
||||||
if self.alias:
|
if self.alias:
|
||||||
return [self.alias]
|
return [self.alias]
|
||||||
if len(self.namespace) > 1:
|
if len(self.namespace_names) > 1:
|
||||||
o = self.namespace
|
return self.namespace_names[0]
|
||||||
n = Name(self._sub_module, [(unicode(o.names[0]), o.start_pos)],
|
|
||||||
o.start_pos, o.end_pos, parent=o.parent)
|
|
||||||
return [n]
|
|
||||||
else:
|
else:
|
||||||
return [self.namespace]
|
return [self.namespace_names]
|
||||||
|
|
||||||
def get_all_import_names(self):
|
def get_all_import_names(self):
|
||||||
n = []
|
n = []
|
||||||
if self.from_ns:
|
if self.from_names:
|
||||||
n += self.from_ns.names
|
n += self.from_names
|
||||||
if self.namespace:
|
if self.namespace_names:
|
||||||
n += self.namespace.names
|
n += self.namespace_names
|
||||||
if self.alias:
|
if self.alias is not None:
|
||||||
n += self.alias.names
|
n.append(self.alias)
|
||||||
return n
|
return n
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -854,7 +850,7 @@ class Import(Simple):
|
|||||||
|
|
||||||
import foo.bar
|
import foo.bar
|
||||||
"""
|
"""
|
||||||
return not self.alias and not self.from_ns and self.namespace is not None \
|
return not self.alias and not self.from_names and self.namespace is not None \
|
||||||
and len(self.namespace.names) > 1
|
and len(self.namespace.names) > 1
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user