mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-08 06:44:46 +08:00
dynamic array additions are working with list.append
This commit is contained in:
64
dynamic.py
64
dynamic.py
@@ -1,6 +1,8 @@
|
|||||||
"""
|
"""
|
||||||
For dynamic completion.
|
For dynamic completion.
|
||||||
"""
|
"""
|
||||||
|
import copy
|
||||||
|
|
||||||
import parsing
|
import parsing
|
||||||
import evaluate
|
import evaluate
|
||||||
|
|
||||||
@@ -79,3 +81,65 @@ def search_params(param):
|
|||||||
func.listeners.remove(listener)
|
func.listeners.remove(listener)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
@evaluate.memoize_default([])
|
||||||
|
def check_array_additions(array, is_list=True):
|
||||||
|
"""
|
||||||
|
Checks if a `parsing.Array` has "add" statements:
|
||||||
|
>>> a = [""]
|
||||||
|
>>> a.append(1)
|
||||||
|
"""
|
||||||
|
def scan_array(arr, search_name):
|
||||||
|
""" Returns the function Calls that match func_name """
|
||||||
|
result = []
|
||||||
|
for sub in arr:
|
||||||
|
for s in sub:
|
||||||
|
if isinstance(s, parsing.Array):
|
||||||
|
result += scan_array(s, search_name)
|
||||||
|
elif isinstance(s, parsing.Call):
|
||||||
|
n = s.name
|
||||||
|
if isinstance(n, parsing.Name) and search_name in n.names:
|
||||||
|
result.append(s)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def check_calls(calls, add_name):
|
||||||
|
result = []
|
||||||
|
for c in calls:
|
||||||
|
call_path = list(c.generate_call_path())
|
||||||
|
separate_index = call_path.index(add_name)
|
||||||
|
if not len(call_path) > separate_index + 1:
|
||||||
|
# this means that there is no execution -> [].append
|
||||||
|
continue
|
||||||
|
backtrack_path = iter(call_path[:separate_index])
|
||||||
|
|
||||||
|
position = c.parent_stmt.start_pos
|
||||||
|
scope = c.parent_stmt.parent
|
||||||
|
print 'd', call_path
|
||||||
|
e = evaluate.follow_call_path(backtrack_path, scope, position)
|
||||||
|
print 'e', e
|
||||||
|
if not array in e:
|
||||||
|
# the `append`, etc. belong to other arrays
|
||||||
|
continue
|
||||||
|
|
||||||
|
if add_name in ['append', 'add']:
|
||||||
|
result += evaluate.follow_call_list(call_path[separate_index + 1])
|
||||||
|
elif add_name in ['extend', 'update']:
|
||||||
|
result += evaluate.follow_call_list(call_path[separate_index + 1])
|
||||||
|
return result
|
||||||
|
|
||||||
|
stmt = array._array.parent_stmt
|
||||||
|
current_module = stmt.get_parent_until()
|
||||||
|
search_names = ['append', 'extend', 'insert'] if is_list else \
|
||||||
|
['add', 'update']
|
||||||
|
possible_stmts = []
|
||||||
|
result = []
|
||||||
|
for n in search_names:
|
||||||
|
try:
|
||||||
|
possible_stmts += current_module.used_names[n]
|
||||||
|
except KeyError:
|
||||||
|
continue
|
||||||
|
for stmt in possible_stmts:
|
||||||
|
result += check_calls(scan_array(stmt.get_assignment_calls(), n), n)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|||||||
11
evaluate.py
11
evaluate.py
@@ -1171,9 +1171,14 @@ def follow_call_list(call_list):
|
|||||||
def follow_call(call):
|
def follow_call(call):
|
||||||
""" Follow a call is following a function, variable, string, etc. """
|
""" Follow a call is following a function, variable, string, etc. """
|
||||||
scope = call.parent_stmt.parent
|
scope = call.parent_stmt.parent
|
||||||
path = call.generate_call_list()
|
path = call.generate_call_path()
|
||||||
|
|
||||||
position = call.parent_stmt.start_pos
|
position = call.parent_stmt.start_pos
|
||||||
|
return follow_call_path(path, scope, position)
|
||||||
|
|
||||||
|
|
||||||
|
def follow_call_path(path, scope, position):
|
||||||
|
""" Follows a path generated by `parsing.Call.generate_call_path()` """
|
||||||
current = next(path)
|
current = next(path)
|
||||||
|
|
||||||
if isinstance(current, parsing.Array):
|
if isinstance(current, parsing.Array):
|
||||||
@@ -1239,7 +1244,9 @@ def follow_path(path, scope, position=None):
|
|||||||
if isinstance(current, parsing.Array):
|
if isinstance(current, parsing.Array):
|
||||||
# This must be an execution, either () or [].
|
# This must be an execution, either () or [].
|
||||||
if current.type == parsing.Array.LIST:
|
if current.type == parsing.Array.LIST:
|
||||||
result = scope.get_index_types(current)
|
result = list(scope.get_index_types(current))
|
||||||
|
if isinstance(scope, Array):
|
||||||
|
result += dynamic.check_array_additions(scope)
|
||||||
elif current.type not in [parsing.Array.DICT]:
|
elif current.type not in [parsing.Array.DICT]:
|
||||||
# Scope must be a class or func - make an instance or execution.
|
# Scope must be a class or func - make an instance or execution.
|
||||||
debug.dbg('exe', scope)
|
debug.dbg('exe', scope)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
import parsing
|
import parsing
|
||||||
|
import dynamic # must be before evaluate, because it needs to be loaded first.
|
||||||
import evaluate
|
import evaluate
|
||||||
import modules
|
import modules
|
||||||
import debug
|
import debug
|
||||||
|
|||||||
@@ -137,6 +137,12 @@ class frozenset():
|
|||||||
def copy(self):
|
def copy(self):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
class tuple():
|
||||||
|
def index(self):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def count(self):
|
||||||
|
return 1
|
||||||
|
|
||||||
#--------------------------------------------------------
|
#--------------------------------------------------------
|
||||||
# basic types
|
# basic types
|
||||||
|
|||||||
@@ -657,6 +657,7 @@ class Statement(Simple):
|
|||||||
c_type = Call.NUMBER
|
c_type = Call.NUMBER
|
||||||
|
|
||||||
if is_chain:
|
if is_chain:
|
||||||
|
#print 'chain', self, tok, result
|
||||||
call = Call(tok, c_type, parent=result)
|
call = Call(tok, c_type, parent=result)
|
||||||
result = result.set_next_chain_call(call)
|
result = result.set_next_chain_call(call)
|
||||||
is_chain = False
|
is_chain = False
|
||||||
@@ -807,17 +808,17 @@ class Call(object):
|
|||||||
call.parent = self
|
call.parent = self
|
||||||
return call
|
return call
|
||||||
|
|
||||||
def generate_call_list(self):
|
def generate_call_path(self):
|
||||||
try:
|
try:
|
||||||
for name_part in self.name.names:
|
for name_part in self.name.names:
|
||||||
yield name_part
|
yield name_part
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
yield self
|
yield self
|
||||||
if self.execution is not None:
|
if self.execution is not None:
|
||||||
for y in self.execution.generate_call_list():
|
for y in self.execution.generate_call_path():
|
||||||
yield y
|
yield y
|
||||||
if self.next is not None:
|
if self.next is not None:
|
||||||
for y in self.next.generate_call_list():
|
for y in self.next.generate_call_path():
|
||||||
yield y
|
yield y
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
|||||||
@@ -162,6 +162,13 @@ dic2 = {'asdf': 3, 'b': 'str'}
|
|||||||
#? int()
|
#? int()
|
||||||
dic2[index]
|
dic2[index]
|
||||||
|
|
||||||
|
# -----------------
|
||||||
|
# chaining
|
||||||
|
# -----------------
|
||||||
|
|
||||||
|
#? int()
|
||||||
|
[tuple()].index()
|
||||||
|
|
||||||
# -----------------
|
# -----------------
|
||||||
# __getitem__
|
# __getitem__
|
||||||
# -----------------
|
# -----------------
|
||||||
|
|||||||
@@ -74,8 +74,46 @@ class A():
|
|||||||
def __init__(self, a):
|
def __init__(self, a):
|
||||||
#? int()
|
#? int()
|
||||||
a
|
a
|
||||||
|
self.a = a
|
||||||
|
|
||||||
def test(self, a):
|
def test(self, a):
|
||||||
#? float()
|
#? float()
|
||||||
a
|
a
|
||||||
|
|
||||||
|
def test2(self):
|
||||||
|
##? int()
|
||||||
|
self.a
|
||||||
|
|
||||||
A(3).test(2.0)
|
A(3).test(2.0)
|
||||||
|
A(3).test2()
|
||||||
|
|
||||||
|
# -----------------
|
||||||
|
# list.append/insert
|
||||||
|
# -----------------
|
||||||
|
arr = []
|
||||||
|
for a in [1,2]:
|
||||||
|
arr.append(a);
|
||||||
|
|
||||||
|
arr.append # should not cause an exception
|
||||||
|
|
||||||
|
#? int()
|
||||||
|
arr[10]
|
||||||
|
|
||||||
|
arr = [tuple()]
|
||||||
|
for a in [1,2]:
|
||||||
|
arr.append(a);
|
||||||
|
|
||||||
|
#? int() tuple()
|
||||||
|
arr[10]
|
||||||
|
#? int()
|
||||||
|
arr[10].index()
|
||||||
|
|
||||||
|
arr = [""]
|
||||||
|
arr.insert(0, 1.0)
|
||||||
|
#? float() str()
|
||||||
|
arr[10]
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------
|
||||||
|
# set.append
|
||||||
|
# -----------------
|
||||||
|
|||||||
Reference in New Issue
Block a user