Remove a lot of the old Name.names usages in favor of a direct NamePart usage.

This commit is contained in:
Dave Halter
2014-09-22 22:34:33 +02:00
parent 04cf742973
commit dae1a48d70
11 changed files with 44 additions and 50 deletions

View File

@@ -433,7 +433,7 @@ class Script(object):
and d.start_pos == (0, 0): and d.start_pos == (0, 0):
i = imports.ImportWrapper(self._evaluator, d.parent).follow(is_goto=True) i = imports.ImportWrapper(self._evaluator, d.parent).follow(is_goto=True)
definitions.remove(d) definitions.remove(d)
definitions |= follow_inexistent_imports(i.names[-1]) definitions |= follow_inexistent_imports(i)
return definitions return definitions
goto_path = self._user_context.get_path_under_cursor() goto_path = self._user_context.get_path_under_cursor()
@@ -468,7 +468,7 @@ class Script(object):
if add_import_name: if add_import_name:
import_name = user_stmt.get_defined_names() import_name = user_stmt.get_defined_names()
# imports have only one name # imports have only one name
np = import_name[0].names[-1] np = import_name[0]
if not user_stmt.star and unicode(name_part) == unicode(np): if not user_stmt.star and unicode(name_part) == unicode(np):
definitions.append(np) definitions.append(np)
else: else:
@@ -573,7 +573,7 @@ class Script(object):
key_name = unicode(detail[0][0].name) key_name = unicode(detail[0][0].name)
except (IndexError, AttributeError): except (IndexError, AttributeError):
pass pass
return [classes.CallSignature(self._evaluator, o.name.names[-1], call, index, key_name) return [classes.CallSignature(self._evaluator, o.name, call, index, key_name)
for o in origins if hasattr(o, 'py__call__')] for o in origins if hasattr(o, 'py__call__')]
def _analysis(self): def _analysis(self):
@@ -584,7 +584,7 @@ class Script(object):
iw = imports.ImportWrapper(self._evaluator, i, iw = imports.ImportWrapper(self._evaluator, i,
nested_resolve=True).follow() nested_resolve=True).follow()
if i.is_nested() and any(not isinstance(i, pr.Module) for i in iw): if i.is_nested() and any(not isinstance(i, pr.Module) for i in iw):
analysis.add(self._evaluator, 'import-error', i.namespace.names[-1]) analysis.add(self._evaluator, 'import-error', i.namespace_names[-1])
for stmt in sorted(stmts, key=lambda obj: obj.start_pos): for stmt in sorted(stmts, key=lambda obj: obj.start_pos):
if not (isinstance(stmt.parent, pr.ForFlow) if not (isinstance(stmt.parent, pr.ForFlow)
and stmt.parent.set_stmt == stmt): and stmt.parent.set_stmt == stmt):

View File

@@ -37,7 +37,7 @@ def defined_names(evaluator, scope):
include_builtin=False), None) include_builtin=False), None)
names = pair[1] if pair else [] names = pair[1] if pair else []
names = [n for n in names if isinstance(n, pr.Import) or (len(n) == 1)] names = [n for n in names if isinstance(n, pr.Import) or (len(n) == 1)]
return [Definition(evaluator, d.names[-1]) for d in sorted(names, key=lambda s: s.start_pos)] return [Definition(evaluator, d) for d in sorted(names, key=lambda s: s.start_pos)]
class BaseDefinition(object): class BaseDefinition(object):
@@ -176,8 +176,8 @@ class BaseDefinition(object):
par = self._definition par = self._definition
while par is not None: while par is not None:
if isinstance(par, pr.Import): if isinstance(par, pr.Import):
insert_nonnone(par.namespace) insert_nonnone(par.namespace_names)
insert_nonnone(par.from_ns) insert_nonnone(par.from_names)
if par.relative_count == 0: if par.relative_count == 0:
break break
with common.ignored(AttributeError): with common.ignored(AttributeError):
@@ -376,12 +376,12 @@ class BaseDefinition(object):
params = sub.params[1:] # ignore self params = sub.params[1:] # ignore self
except KeyError: except KeyError:
return [] return []
return [_Param(self._evaluator, p.get_name().names[-1]) for p in params] return [_Param(self._evaluator, p.get_name()) for p in params]
def parent(self): def parent(self):
scope = self._definition.get_parent_scope() scope = self._definition.get_parent_scope()
non_flow = scope.get_parent_until(pr.Flow, reverse=True) non_flow = scope.get_parent_until(pr.Flow, reverse=True)
return Definition(self._evaluator, non_flow.name.names[-1]) return Definition(self._evaluator, non_flow.name)
def __repr__(self): def __repr__(self):
return "<%s %s>" % (type(self).__name__, self.description) return "<%s %s>" % (type(self).__name__, self.description)
@@ -539,7 +539,7 @@ class Completion(BaseDefinition):
it's just PITA-slow. it's just PITA-slow.
""" """
defs = self._follow_statements_imports() defs = self._follow_statements_imports()
return [Definition(self._evaluator, d.name.names[-1]) for d in defs] return [Definition(self._evaluator, d.name) for d in defs]
class Definition(use_metaclass(CachedMetaClass, BaseDefinition)): class Definition(use_metaclass(CachedMetaClass, BaseDefinition)):

View File

@@ -357,7 +357,7 @@ class Evaluator(object):
params = typ.params params = typ.params
for param in params: for param in params:
if unicode(param.get_name()) == unicode(named_param_name): if unicode(param.get_name()) == unicode(named_param_name):
param_names.append(param.get_name().names[-1]) param_names.append(param.get_name())
return param_names return param_names
return [call_path[0]] return [call_path[0]]

View File

@@ -287,7 +287,7 @@ class NameFinder(object):
if isinstance(p, pr.Flow) and p.command == 'except' and p.inputs: if isinstance(p, pr.Flow) and p.command == 'except' and p.inputs:
as_names = p.inputs[0].as_names as_names = p.inputs[0].as_names
try: try:
if as_names[0].names[-1] == name: if as_names[0] == name:
# TODO check for types that are not classes and add it to # TODO check for types that are not classes and add it to
# the static analysis report. # the static analysis report.
types = list(chain.from_iterable( types = list(chain.from_iterable(
@@ -589,7 +589,7 @@ def find_assignments(lhs, results, seek_name):
""" """
if isinstance(lhs, pr.Array): if isinstance(lhs, pr.Array):
return _assign_tuples(lhs, results, seek_name) return _assign_tuples(lhs, results, seek_name)
elif unicode(lhs.name.names[-1]) == seek_name: elif unicode(lhs.name) == seek_name:
return results return results
else: else:
return [] return []

View File

@@ -217,7 +217,7 @@ def get_module_name_parts(module):
def scope_name_parts(scope): def scope_name_parts(scope):
for s in scope.subscopes: for s in scope.subscopes:
# Yield the name parts, not names. # Yield the name parts, not names.
yield s.name.names[0] yield s.name
for need_yield_from in scope_name_parts(s): for need_yield_from in scope_name_parts(s):
yield need_yield_from yield need_yield_from
@@ -237,8 +237,8 @@ def get_module_name_parts(module):
# token_list anymore, but for now this is the easiest way to get # token_list anymore, but for now this is the easiest way to get
# all the name_parts. # all the name_parts.
for tok in stmt_or_import._token_list: for tok in stmt_or_import._token_list:
if isinstance(tok, pr.Name): if isinstance(tok, pr.NamePart):
name_parts.update(tok.names) name_parts.add(tok)
return name_parts return name_parts

View File

@@ -67,13 +67,13 @@ class ImportWrapper(pr.Base):
# rest is import_path resolution # rest is import_path resolution
import_path = [] import_path = []
if import_stmt.from_ns: if import_stmt.from_names:
import_path += import_stmt.from_ns.names import_path += import_stmt.from_names
if import_stmt.namespace: if import_stmt.namespace_names:
if self.import_stmt.is_nested() and not nested_resolve: if self.import_stmt.is_nested() and not nested_resolve:
import_path.append(import_stmt.namespace.names[0]) import_path.append(import_stmt.namespace_names[0])
else: else:
import_path += import_stmt.namespace.names import_path += import_stmt.namespace_names
for i in range(kill_count + int(is_like_search)): for i in range(kill_count + int(is_like_search)):
if import_path: if import_path:
@@ -140,9 +140,9 @@ class ImportWrapper(pr.Base):
for s, scope_names in finder.get_names_of_scope(self._evaluator, for s, scope_names in finder.get_names_of_scope(self._evaluator,
scope, include_builtin=False): scope, include_builtin=False):
for n in scope_names: for n in scope_names:
if self.import_stmt.from_ns is None \ if self.import_stmt.from_names is None \
or self.is_partial_import: or self.is_partial_import:
# from_ns must be defined to access module # from_names must be defined to access module
# values plus a partial import means that there # values plus a partial import means that there
# is something after the import, which # is something after the import, which
# automatically implies that there must not be # automatically implies that there must not be
@@ -198,7 +198,7 @@ class ImportWrapper(pr.Base):
# goto only accepts Names or NameParts # goto only accepts Names or NameParts
if is_goto and not rest: if is_goto and not rest:
scopes = [s.name.names[-1] for s in scopes] scopes = [s.name for s in scopes]
# follow the rest of the import (not FS -> classes, functions) # follow the rest of the import (not FS -> classes, functions)
if len(rest) > 1 or rest and self.is_like_search: if len(rest) > 1 or rest and self.is_like_search:
@@ -243,12 +243,12 @@ class NestedImportModule(pr.Module):
# This is not an existing Import statement. Therefore, set position to # This is not an existing Import statement. Therefore, set position to
# 0 (0 is not a valid line number). # 0 (0 is not a valid line number).
zero = (0, 0) zero = (0, 0)
names = [unicode(name_part) for name_part in i.namespace.names[1:]] names = [unicode(name_part) for name_part in i.namespace_names[1:]]
name = helpers.FakeName(names, self._nested_import) name = helpers.FakeName(names, self._nested_import)
new = pr.Import(i._sub_module, zero, zero, name) new = pr.Import(i._sub_module, zero, zero, name)
new.parent = self._module new.parent = self._module
debug.dbg('Generated a nested import: %s', new) debug.dbg('Generated a nested import: %s', new)
return helpers.FakeName(str(i.namespace.names[1]), new) return helpers.FakeName(str(i.namespace_names[1]), new)
def _get_defined_names(self): def _get_defined_names(self):
""" """

View File

@@ -224,6 +224,7 @@ class Array(use_metaclass(CachedMetaClass, IterableWrapper)):
return "<e%s of %s>" % (type(self).__name__, self._array) return "<e%s of %s>" % (type(self).__name__, self._array)
# TODO REMOVE, not used.
class ArrayMethod(IterableWrapper): class ArrayMethod(IterableWrapper):
""" """
A name, e.g. `list.append`, it is used to access the original array A name, e.g. `list.append`, it is used to access the original array

View File

@@ -359,8 +359,6 @@ def _gen_param_name_copy(func, var_args, param, keys=(), values=(), array_type=N
new_param.set_expression_list([arr]) new_param.set_expression_list([arr])
name = copy.copy(param.get_name()) name = copy.copy(param.get_name())
name.names = [copy.copy(name.names[0])]
name.names[0].parent = name
name.parent = new_param name.parent = new_param
return name return name

View File

@@ -303,12 +303,6 @@ class InstanceElement(use_metaclass(CachedMetaClass, pr.Base)):
return [get_instance_el(self._evaluator, self.instance, command, self.is_class_var) return [get_instance_el(self._evaluator, self.instance, command, self.is_class_var)
for command in self.var.expression_list()] for command in self.var.expression_list()]
@property
@underscore_memoization
def names(self):
return [pr.NamePart(helpers.FakeSubModule, unicode(n), self, n.start_pos)
for n in self.var.names]
@property @property
@underscore_memoization @underscore_memoization
def name(self): def name(self):

View File

@@ -354,6 +354,7 @@ 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:
tok_list[-1], tok = self._parse_name(tok)
continue continue
elif tok.string in opening_brackets: elif tok.string in opening_brackets:
level += 1 level += 1
@@ -456,7 +457,7 @@ class Parser(object):
elif tok_str == 'import': elif tok_str == 'import':
imports = self._parse_import_list() imports = self._parse_import_list()
for count, (names, 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 names and names[-1] 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, names, i = pr.Import(self.module, first_pos, end_pos, names,
alias, defunct=defunct) alias, defunct=defunct)

View File

@@ -477,10 +477,10 @@ class SubModule(Scope, Module):
is a ``__future__`` import. is a ``__future__`` import.
""" """
for imp in self.imports: for imp in self.imports:
if imp.from_ns is None or imp.namespace is None: if imp.from_ns is None or imp.namespace_names is None:
continue continue
namespace, feature = imp.from_ns.names[0], imp.namespace.names[0] namespace, feature = imp.from_names[0], imp.namespace_names[0]
if unicode(namespace) == "__future__" and unicode(feature) == "absolute_import": if unicode(namespace) == "__future__" and unicode(feature) == "absolute_import":
return True return True
@@ -528,9 +528,9 @@ class Class(Scope):
if self._doc_token is not None: if self._doc_token is not None:
docstr = self.raw_doc docstr = self.raw_doc
for sub in self.subscopes: for sub in self.subscopes:
if unicode(sub.name.names[-1]) == '__init__': if unicode(sub.name) == '__init__':
return '%s\n\n%s' % ( return '%s\n\n%s' % (
sub.get_call_signature(funcname=self.name.names[-1]), docstr) sub.get_call_signature(funcname=self.name), docstr)
return docstr return docstr
def scope_names_generator(self, position=None): def scope_names_generator(self, position=None):
@@ -596,7 +596,7 @@ class Function(Scope):
:rtype: str :rtype: str
""" """
l = unicode(funcname or self.name.names[-1]) + '(' l = unicode(funcname or self.name) + '('
lines = [] lines = []
for (i, p) in enumerate(self.params): for (i, p) in enumerate(self.params):
code = p.get_code(False) code = p.get_code(False)
@@ -780,15 +780,16 @@ class Import(Simple):
:type defunct: bool :type defunct: bool
""" """
def __init__(self, module, start_pos, end_pos, namespace_names, alias=None, def __init__(self, module, start_pos, end_pos, namespace_names, alias=None,
from_names=None, star=False, relative_count=0, defunct=False): from_names=(), 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_names = namespace_names self.namespace_names = namespace_names
self.alias = alias self.alias = alias
if self.alias:
alias.parent = self
self.from_names = from_names self.from_names = from_names
for n in namespace_names, alias, from_names: for n in namespace_names + list(from_names):
if n: n.parent = self.use_as_parent
n.parent = self.use_as_parent
self.star = star self.star = star
self.relative_count = relative_count self.relative_count = relative_count
@@ -841,7 +842,7 @@ class Import(Simple):
TODO refactor and dont use this method, because NamePart will not exist in TODO refactor and dont use this method, because NamePart will not exist in
the future. the future.
""" """
return self.alias.names[0] if self.alias else None return self.alias
def is_nested(self): def is_nested(self):
""" """
@@ -850,8 +851,8 @@ class Import(Simple):
import foo.bar import foo.bar
""" """
return not self.alias and not self.from_names and self.namespace is not None \ return not self.alias and not self.from_names \
and len(self.namespace.names) > 1 and len(self.namespace_names) > 1
class KeywordStatement(Base): class KeywordStatement(Base):
@@ -1193,7 +1194,7 @@ class Statement(Simple, DocstringMixin):
continue continue
is_literal = token_type in (tokenize.STRING, tokenize.NUMBER) is_literal = token_type in (tokenize.STRING, tokenize.NUMBER)
if isinstance(tok_str, Name) or is_literal: if is_literal or isinstance(tok, NamePart):
cls = Literal if is_literal else Call cls = Literal if is_literal else Call
call = cls(self._sub_module, tok_str, tok.start_pos, tok.end_pos, self) call = cls(self._sub_module, tok_str, tok.start_pos, tok.end_pos, self)
@@ -1311,8 +1312,7 @@ class StatementElement(Simple):
def generate_call_path(self): def generate_call_path(self):
""" Helps to get the order in which statements are executed. """ """ Helps to get the order in which statements are executed. """
try: try:
for name_part in self.name.names: yield self.name
yield name_part
except AttributeError: except AttributeError:
yield self yield self
if self.next is not None: if self.next is not None: