mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-07 22:44:27 +08:00
split parsing functions file, the path following is now in evaluate.py
This commit is contained in:
58
evaluate.py
Normal file
58
evaluate.py
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import parsing
|
||||||
|
|
||||||
|
def Statement(object):
|
||||||
|
""" The statement object of functions, to """
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_names_for_scope(scope):
|
||||||
|
""" Get all completions possible for the current scope. """
|
||||||
|
comp = []
|
||||||
|
start_scope = scope
|
||||||
|
while scope:
|
||||||
|
# class variables/functions are only availabe
|
||||||
|
if not isinstance(scope, parsing.Class) or scope == start_scope:
|
||||||
|
comp += scope.get_set_vars()
|
||||||
|
scope = scope.parent
|
||||||
|
return comp
|
||||||
|
|
||||||
|
|
||||||
|
def follow_path(scope, path):
|
||||||
|
"""
|
||||||
|
Follow a path of python names.
|
||||||
|
recursive!
|
||||||
|
:returns: list(Scope)
|
||||||
|
"""
|
||||||
|
comp = get_names_for_scope(scope)
|
||||||
|
print path, comp
|
||||||
|
|
||||||
|
path = list(path)
|
||||||
|
name = path.pop(0)
|
||||||
|
scopes = []
|
||||||
|
|
||||||
|
# make the full comparison, because the names have to match exactly
|
||||||
|
comp = [c for c in comp if [name] == list(c.names)]
|
||||||
|
# TODO differentiate between the different comp input (some are overridden)
|
||||||
|
for c in comp:
|
||||||
|
p_class = c.parent.__class__
|
||||||
|
if p_class == parsing.Class or p_class == parsing.Scope:
|
||||||
|
scopes.append(c.parent)
|
||||||
|
#elif p_class == parsing.Function:
|
||||||
|
elif p_class == parsing.Statement:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
print 'error follow_path:', p_class, repr(c.parent)
|
||||||
|
|
||||||
|
if path:
|
||||||
|
new_scopes = []
|
||||||
|
for s in tuple(scopes):
|
||||||
|
new_scopes += follow_path(s, tuple(path))
|
||||||
|
scopes = new_scopes
|
||||||
|
return set(scopes)
|
||||||
|
|
||||||
|
|
||||||
|
def dbg(*args):
|
||||||
|
if debug_function:
|
||||||
|
debug_function(*args)
|
||||||
|
|
||||||
|
|
||||||
|
debug_function = None
|
||||||
51
functions.py
51
functions.py
@@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
import parsing
|
import parsing
|
||||||
|
import evaluate
|
||||||
import re
|
import re
|
||||||
|
|
||||||
__all__ = ['complete', 'set_debug_function']
|
__all__ = ['complete', 'set_debug_function']
|
||||||
@@ -181,8 +182,11 @@ def complete(source, row, column, file_callback=None):
|
|||||||
f = File(source=source, row=row)
|
f = File(source=source, row=row)
|
||||||
scope = f.parser.user_scope
|
scope = f.parser.user_scope
|
||||||
|
|
||||||
print
|
# print a dbg title
|
||||||
print
|
dbg()
|
||||||
|
dbg('-' * 70)
|
||||||
|
dbg(' ' * 62 + 'complete')
|
||||||
|
dbg('-' * 70)
|
||||||
print scope
|
print scope
|
||||||
print f.parser.user_scope.get_simple_for_line(row)
|
print f.parser.user_scope.get_simple_for_line(row)
|
||||||
|
|
||||||
@@ -197,7 +201,7 @@ def complete(source, row, column, file_callback=None):
|
|||||||
|
|
||||||
name = path.pop()
|
name = path.pop()
|
||||||
if path:
|
if path:
|
||||||
scopes = follow_path(scope, tuple(path))
|
scopes = evaluate.follow_path(scope, tuple(path))
|
||||||
|
|
||||||
dbg('possible scopes', scopes)
|
dbg('possible scopes', scopes)
|
||||||
compl = []
|
compl = []
|
||||||
@@ -213,46 +217,6 @@ def complete(source, row, column, file_callback=None):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def get_names_for_scope(scope):
|
|
||||||
""" Get all completions possible for the current scope. """
|
|
||||||
comp = []
|
|
||||||
start_scope = scope
|
|
||||||
while scope:
|
|
||||||
# class variables/functions are only availabe
|
|
||||||
if not isinstance(scope, parsing.Class) or scope == start_scope:
|
|
||||||
comp += scope.get_set_vars()
|
|
||||||
scope = scope.parent
|
|
||||||
return comp
|
|
||||||
|
|
||||||
def follow_path(scope, path):
|
|
||||||
"""
|
|
||||||
Follow a path of python names.
|
|
||||||
recursive!
|
|
||||||
:returns: list(Scope)
|
|
||||||
"""
|
|
||||||
comp = get_names_for_scope(scope)
|
|
||||||
print path, comp
|
|
||||||
|
|
||||||
path = list(path)
|
|
||||||
name = path.pop()
|
|
||||||
scopes = []
|
|
||||||
|
|
||||||
# make the full comparison, because the names have to match exactly
|
|
||||||
comp = [c for c in comp if [name] == list(c.names)]
|
|
||||||
# TODO differentiate between the different comp input (some are overridden)
|
|
||||||
for c in comp:
|
|
||||||
p_class = c.parent.__class__
|
|
||||||
if p_class == parsing.Class or p_class == parsing.Scope:
|
|
||||||
scopes.append(c.parent)
|
|
||||||
#elif p_class == parsing.Function:
|
|
||||||
else:
|
|
||||||
print 'error follow_path:', p_class
|
|
||||||
if path:
|
|
||||||
for s in tuple(scopes):
|
|
||||||
scopes += follow_path(s, tuple(path))
|
|
||||||
return set(scopes)
|
|
||||||
|
|
||||||
|
|
||||||
def dbg(*args):
|
def dbg(*args):
|
||||||
if debug_function:
|
if debug_function:
|
||||||
debug_function(*args)
|
debug_function(*args)
|
||||||
@@ -262,6 +226,7 @@ def set_debug_function(func):
|
|||||||
global debug_function
|
global debug_function
|
||||||
debug_function = func
|
debug_function = func
|
||||||
parsing.debug_function = func
|
parsing.debug_function = func
|
||||||
|
evaluate.debug_function = func
|
||||||
|
|
||||||
|
|
||||||
debug_function = None
|
debug_function = None
|
||||||
|
|||||||
50
parsing.py
50
parsing.py
@@ -60,6 +60,11 @@ class Simple(object):
|
|||||||
self.line_end = line_end
|
self.line_end = line_end
|
||||||
self.parent = None
|
self.parent = None
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
code = self.get_code().replace('\n', ' ')
|
||||||
|
return "<%s: %s@%s>" % \
|
||||||
|
(self.__class__.__name__, code, self.line_nr)
|
||||||
|
|
||||||
|
|
||||||
class Scope(Simple):
|
class Scope(Simple):
|
||||||
"""
|
"""
|
||||||
@@ -126,6 +131,7 @@ class Scope(Simple):
|
|||||||
|
|
||||||
def add_import(self, imp):
|
def add_import(self, imp):
|
||||||
self.imports.append(imp)
|
self.imports.append(imp)
|
||||||
|
imp.parent = self
|
||||||
|
|
||||||
def add_global(self, name):
|
def add_global(self, name):
|
||||||
"""
|
"""
|
||||||
@@ -137,14 +143,7 @@ class Scope(Simple):
|
|||||||
:type name: Name
|
:type name: Name
|
||||||
"""
|
"""
|
||||||
self.global_vars.append(name)
|
self.global_vars.append(name)
|
||||||
|
# set no parent here, because globals are not defined in this scope.
|
||||||
def _checkexisting(self, test):
|
|
||||||
"Convienance function... keep out duplicates"
|
|
||||||
if test.find('=') > -1:
|
|
||||||
var = test.split('=')[0].strip()
|
|
||||||
for l in self.locals:
|
|
||||||
if l.find('=') > -1 and var == l.split('=')[0].strip():
|
|
||||||
self.locals.remove(l)
|
|
||||||
|
|
||||||
def get_code(self, first_indent=False, indention=" "):
|
def get_code(self, first_indent=False, indention=" "):
|
||||||
"""
|
"""
|
||||||
@@ -291,7 +290,10 @@ class Function(Scope):
|
|||||||
def __init__(self, name, params, indent, line_nr, docstr=''):
|
def __init__(self, name, params, indent, line_nr, docstr=''):
|
||||||
Scope.__init__(self, indent, line_nr, docstr)
|
Scope.__init__(self, indent, line_nr, docstr)
|
||||||
self.name = name
|
self.name = name
|
||||||
|
name.parent = self
|
||||||
self.params = params
|
self.params = params
|
||||||
|
for p in params:
|
||||||
|
p.parent = self
|
||||||
self.decorators = []
|
self.decorators = []
|
||||||
|
|
||||||
def get_code(self, first_indent=False, indention=" "):
|
def get_code(self, first_indent=False, indention=" "):
|
||||||
@@ -340,10 +342,14 @@ class Flow(Scope):
|
|||||||
super(Flow, self).__init__(indent, line_nr, '')
|
super(Flow, self).__init__(indent, line_nr, '')
|
||||||
self.command = command
|
self.command = command
|
||||||
self.statement = statement
|
self.statement = statement
|
||||||
|
if statement:
|
||||||
|
statement.parent = self
|
||||||
if set_vars == None:
|
if set_vars == None:
|
||||||
self.set_vars = []
|
self.set_vars = []
|
||||||
else:
|
else:
|
||||||
self.set_vars = set_vars
|
self.set_vars = set_vars
|
||||||
|
for s in self.set_vars:
|
||||||
|
s.parent = self
|
||||||
self.next = None
|
self.next = None
|
||||||
|
|
||||||
def get_code(self, first_indent=False, indention=" "):
|
def get_code(self, first_indent=False, indention=" "):
|
||||||
@@ -395,22 +401,30 @@ class Import(Simple):
|
|||||||
|
|
||||||
:param line_nr: Line number.
|
:param line_nr: Line number.
|
||||||
:type line_nr: int
|
:type line_nr: int
|
||||||
:param namespace: The import, as an array list of Name, \
|
:param namespace: The import, can be empty if a star is given
|
||||||
e.g. ['datetime', 'time'].
|
:type namespace: Name
|
||||||
:type namespace: list
|
|
||||||
: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: str
|
:type alias: Name
|
||||||
:param from_ns: Like the namespace, can be equally used.
|
:param from_ns: Like the namespace, can be equally used.
|
||||||
:type from_ns: list
|
:type from_ns: 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
|
||||||
"""
|
"""
|
||||||
def __init__(self, indent, line_nr, line_end, namespace, alias='', \
|
def __init__(self, indent, line_nr, line_end, namespace, alias='', \
|
||||||
from_ns='', star=False):
|
from_ns='', star=False):
|
||||||
super(Import, self).__init__(indent, line_nr, line_end)
|
super(Import, self).__init__(indent, line_nr, line_end)
|
||||||
|
|
||||||
self.namespace = namespace
|
self.namespace = namespace
|
||||||
|
namespace.parent = self
|
||||||
|
|
||||||
self.alias = alias
|
self.alias = alias
|
||||||
|
if alias:
|
||||||
|
alias.parent = self
|
||||||
|
|
||||||
self.from_ns = from_ns
|
self.from_ns = from_ns
|
||||||
|
if from_ns:
|
||||||
|
from_ns.parent = self
|
||||||
|
|
||||||
self.star = star
|
self.star = star
|
||||||
|
|
||||||
def get_code(self):
|
def get_code(self):
|
||||||
@@ -430,10 +444,6 @@ class Import(Simple):
|
|||||||
return [self]
|
return [self]
|
||||||
return [self.alias] if self.alias else [self.namespace]
|
return [self.alias] if self.alias else [self.namespace]
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "<%s: %s@%s>" % \
|
|
||||||
(self.__class__.__name__, self.get_code(), self.line_nr)
|
|
||||||
|
|
||||||
|
|
||||||
class Statement(Simple):
|
class Statement(Simple):
|
||||||
"""
|
"""
|
||||||
@@ -462,6 +472,8 @@ class Statement(Simple):
|
|||||||
self.set_vars = set_vars
|
self.set_vars = set_vars
|
||||||
self.used_funcs = used_funcs
|
self.used_funcs = used_funcs
|
||||||
self.used_vars = used_vars
|
self.used_vars = used_vars
|
||||||
|
for s in set_vars + used_funcs + used_vars:
|
||||||
|
s.parent = self
|
||||||
|
|
||||||
def get_code(self, new_line=True):
|
def get_code(self, new_line=True):
|
||||||
if new_line:
|
if new_line:
|
||||||
@@ -503,10 +515,6 @@ class Name(Simple):
|
|||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash(self.names) + hash(self.indent) + hash(self.line_nr)
|
return hash(self.names) + hash(self.indent) + hash(self.line_nr)
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "<%s: %s@%s>" % \
|
|
||||||
(self.__class__.__name__, self.get_code(), self.line_nr)
|
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return len(self.names)
|
return len(self.names)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user