mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-07 06:24:27 +08:00
Work with a NameWrapper, so Django goto works better
This commit is contained in:
@@ -5,29 +5,13 @@ Bugs:
|
|||||||
- Can't infer ManyToManyField.
|
- Can't infer ManyToManyField.
|
||||||
"""
|
"""
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi.inference.base_value import LazyValueWrapper
|
from jedi.inference.base_value import LazyValueWrapper, ValueSet, NO_VALUES
|
||||||
from jedi.inference.utils import safe_property
|
from jedi.inference.utils import safe_property
|
||||||
from jedi.inference.filters import ParserTreeFilter, DictFilter
|
from jedi.inference.filters import ParserTreeFilter, DictFilter
|
||||||
from jedi.inference.names import ValueName
|
from jedi.inference.names import ValueName, NameWrapper
|
||||||
from jedi.inference.value.instance import TreeInstance
|
from jedi.inference.value.instance import TreeInstance
|
||||||
|
|
||||||
|
|
||||||
class DjangoModelField(LazyValueWrapper):
|
|
||||||
def __init__(self, cls, name):
|
|
||||||
self.inference_state = cls.inference_state
|
|
||||||
self._cls = cls
|
|
||||||
self._name = name
|
|
||||||
self.tree_node = self._name.tree_name
|
|
||||||
|
|
||||||
@safe_property
|
|
||||||
def name(self):
|
|
||||||
return ValueName(self, self._name.tree_name)
|
|
||||||
|
|
||||||
def _get_wrapped_value(self):
|
|
||||||
obj, = self._cls.execute_with_values()
|
|
||||||
return obj
|
|
||||||
|
|
||||||
|
|
||||||
mapping = {
|
mapping = {
|
||||||
'IntegerField': (None, 'int'),
|
'IntegerField': (None, 'int'),
|
||||||
'BigIntegerField': (None, 'int'),
|
'BigIntegerField': (None, 'int'),
|
||||||
@@ -59,14 +43,14 @@ def _infer_scalar_field(inference_state, field_name, field_tree_instance):
|
|||||||
module = inference_state.import_module((module_name,))
|
module = inference_state.import_module((module_name,))
|
||||||
|
|
||||||
for attribute in module.py__getattribute__(attribute_name):
|
for attribute in module.py__getattribute__(attribute_name):
|
||||||
return DjangoModelField(attribute, field_name)
|
return attribute.execute_with_values()
|
||||||
|
|
||||||
|
|
||||||
def _infer_field(cls, field_name):
|
def _infer_field(cls, field_name):
|
||||||
inference_state = cls.inference_state
|
inference_state = cls.inference_state
|
||||||
for field_tree_instance in field_name.infer():
|
for field_tree_instance in field_name.infer():
|
||||||
scalar_field = _infer_scalar_field(inference_state, field_name, field_tree_instance)
|
scalar_field = _infer_scalar_field(inference_state, field_name, field_tree_instance)
|
||||||
if scalar_field:
|
if scalar_field is not None:
|
||||||
return scalar_field
|
return scalar_field
|
||||||
|
|
||||||
if field_tree_instance.py__name__() == 'ForeignKey':
|
if field_tree_instance.py__name__() == 'ForeignKey':
|
||||||
@@ -79,25 +63,34 @@ def _infer_field(cls, field_name):
|
|||||||
if value.py__name__() == 'str':
|
if value.py__name__() == 'str':
|
||||||
foreign_key_class_name = value.get_safe_value()
|
foreign_key_class_name = value.get_safe_value()
|
||||||
module = cls.get_root_context()
|
module = cls.get_root_context()
|
||||||
for v in module.py__getattribute__(foreign_key_class_name):
|
return ValueSet.from_sets(
|
||||||
if v.is_class():
|
v.execute_with_values()
|
||||||
return DjangoModelField(v, field_name)
|
for v in module.py__getattribute__(foreign_key_class_name)
|
||||||
|
if v.is_class()
|
||||||
|
)
|
||||||
elif value.is_class():
|
elif value.is_class():
|
||||||
return DjangoModelField(value, field_name)
|
return value.execute_with_values()
|
||||||
|
|
||||||
debug.dbg('django plugin: fail to infer `%s` from class `%s`',
|
debug.dbg('django plugin: fail to infer `%s` from class `%s`',
|
||||||
field_name.string_name, cls.py__name__())
|
field_name.string_name, cls.py__name__())
|
||||||
return None
|
return field_name.infer()
|
||||||
|
|
||||||
|
|
||||||
|
class DjangoModelName(NameWrapper):
|
||||||
|
def __init__(self, cls, name):
|
||||||
|
super(DjangoModelName, self).__init__(name)
|
||||||
|
self._cls = cls
|
||||||
|
|
||||||
|
def infer(self):
|
||||||
|
return _infer_field(self._cls, self._wrapped_name)
|
||||||
|
|
||||||
|
|
||||||
def _new_dict_filter(cls):
|
def _new_dict_filter(cls):
|
||||||
def iterate():
|
filter_ = ParserTreeFilter(parent_context=cls.as_context())
|
||||||
filter_ = ParserTreeFilter(parent_context=cls.as_context())
|
return DictFilter({
|
||||||
for name in filter_.values():
|
name.string_name: DjangoModelName(cls, name)
|
||||||
django_field = _infer_field(cls, name)
|
for name in filter_.values()
|
||||||
if django_field is not None:
|
})
|
||||||
yield name.string_name, django_field.name
|
|
||||||
return DictFilter(dict(iterate()))
|
|
||||||
|
|
||||||
|
|
||||||
def get_metaclass_filters(func):
|
def get_metaclass_filters(func):
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ class BusinessModel(models.Model):
|
|||||||
category_fk3 = models.ForeignKey(1)
|
category_fk3 = models.ForeignKey(1)
|
||||||
category_fk4 = models.ForeignKey('models')
|
category_fk4 = models.ForeignKey('models')
|
||||||
category_fk5 = models.ForeignKey()
|
category_fk5 = models.ForeignKey()
|
||||||
|
|
||||||
integer_field = models.IntegerField()
|
integer_field = models.IntegerField()
|
||||||
big_integer_field = models.BigIntegerField()
|
big_integer_field = models.BigIntegerField()
|
||||||
positive_integer_field = models.PositiveIntegerField()
|
positive_integer_field = models.PositiveIntegerField()
|
||||||
@@ -70,6 +71,10 @@ model_instance.date_field
|
|||||||
#? datetime.datetime()
|
#? datetime.datetime()
|
||||||
model_instance.date_time_field
|
model_instance.date_time_field
|
||||||
|
|
||||||
|
#! ['category_fk = models.ForeignKey(Category)']
|
||||||
|
model_instance.category_fk
|
||||||
|
#! ['category_name = models.CharField()']
|
||||||
|
model_instance.category_fk.category_name
|
||||||
#? Category()
|
#? Category()
|
||||||
model_instance.category_fk
|
model_instance.category_fk
|
||||||
#? str()
|
#? str()
|
||||||
@@ -80,7 +85,7 @@ model_instance.category_fk2
|
|||||||
model_instance.category_fk2.category_name
|
model_instance.category_fk2.category_name
|
||||||
#? models.ForeignKey()
|
#? models.ForeignKey()
|
||||||
model_instance.category_fk3
|
model_instance.category_fk3
|
||||||
#? models.ForeignKey()
|
#?
|
||||||
model_instance.category_fk4
|
model_instance.category_fk4
|
||||||
#? models.ForeignKey()
|
#? models.ForeignKey()
|
||||||
model_instance.category_fk5
|
model_instance.category_fk5
|
||||||
|
|||||||
Reference in New Issue
Block a user