mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-08 14:54:47 +08:00
Start moving api stuff to the inference module.
This commit is contained in:
@@ -14,8 +14,7 @@ import collections
|
|||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
from jedi._compatibility import unicode, builtins
|
from jedi._compatibility import unicode, builtins
|
||||||
from jedi.parser import Parser, load_grammar, ParseError
|
from jedi.parser import load_grammar
|
||||||
from jedi.parser.tokenize import source_tokens
|
|
||||||
from jedi.parser import tree
|
from jedi.parser import tree
|
||||||
from jedi.parser.user_context import UserContext, UserContextParser
|
from jedi.parser.user_context import UserContext, UserContextParser
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
@@ -27,12 +26,12 @@ from jedi.api import classes
|
|||||||
from jedi.api import interpreter
|
from jedi.api import interpreter
|
||||||
from jedi.api import usages
|
from jedi.api import usages
|
||||||
from jedi.api import helpers
|
from jedi.api import helpers
|
||||||
|
from jedi.api import inference
|
||||||
from jedi.evaluate import Evaluator
|
from jedi.evaluate import Evaluator
|
||||||
from jedi.evaluate import representation as er
|
from jedi.evaluate import representation as er
|
||||||
from jedi.evaluate import compiled
|
from jedi.evaluate import compiled
|
||||||
from jedi.evaluate import imports
|
from jedi.evaluate import imports
|
||||||
from jedi.evaluate.param import try_iter_content
|
from jedi.evaluate.param import try_iter_content
|
||||||
from jedi.evaluate.cache import memoize_default
|
|
||||||
from jedi.evaluate.helpers import FakeName, get_module_names
|
from jedi.evaluate.helpers import FakeName, get_module_names
|
||||||
from jedi.evaluate.finder import global_names_dict_generator, filter_definition_names
|
from jedi.evaluate.finder import global_names_dict_generator, filter_definition_names
|
||||||
from jedi.evaluate.sys_path import get_venv_path
|
from jedi.evaluate.sys_path import get_venv_path
|
||||||
@@ -270,7 +269,8 @@ class Script(object):
|
|||||||
if not names:
|
if not names:
|
||||||
continue
|
continue
|
||||||
completion_names += filter_definition_names(names, self._parser.user_stmt(), pos)
|
completion_names += filter_definition_names(names, self._parser.user_stmt(), pos)
|
||||||
elif self._get_under_cursor_stmt(path) is None:
|
elif inference.get_under_cursor_stmt(self._evaluator, self._parser,
|
||||||
|
path, self._pos) is None:
|
||||||
return []
|
return []
|
||||||
else:
|
else:
|
||||||
scopes = list(self._type_inference(path, True))
|
scopes = list(self._type_inference(path, True))
|
||||||
@@ -284,16 +284,16 @@ class Script(object):
|
|||||||
completion_names += filter_definition_names(names, self._parser.user_stmt())
|
completion_names += filter_definition_names(names, self._parser.user_stmt())
|
||||||
return completion_names
|
return completion_names
|
||||||
|
|
||||||
def _type_inference(self, goto_path, is_completion=False):
|
def _type_inference(self, dotted_path, is_completion=False):
|
||||||
"""
|
"""
|
||||||
Base for completions/goto. Basically it returns the resolved scopes
|
Base for completions/goto. Basically it returns the resolved scopes
|
||||||
under cursor.
|
under cursor.
|
||||||
"""
|
"""
|
||||||
debug.dbg('start: %s in %s', goto_path, self._parser.user_scope())
|
debug.dbg('start: %s in %s', dotted_path, self._parser.user_scope())
|
||||||
|
|
||||||
user_stmt = self._parser.user_stmt_with_whitespace()
|
user_stmt = self._parser.user_stmt_with_whitespace()
|
||||||
if not user_stmt and len(goto_path.split('\n')) > 1:
|
if not user_stmt and len(dotted_path.split('\n')) > 1:
|
||||||
# If the user_stmt is not defined and the goto_path is multi line,
|
# If the user_stmt is not defined and the dotted_path is multi line,
|
||||||
# something's strange. Most probably the backwards tokenizer
|
# something's strange. Most probably the backwards tokenizer
|
||||||
# matched to much.
|
# matched to much.
|
||||||
return []
|
return []
|
||||||
@@ -306,7 +306,8 @@ class Script(object):
|
|||||||
scopes = [i]
|
scopes = [i]
|
||||||
else:
|
else:
|
||||||
# Just parse one statement, take it and evaluate it.
|
# Just parse one statement, take it and evaluate it.
|
||||||
eval_stmt = self._get_under_cursor_stmt(goto_path)
|
eval_stmt = inference.get_under_cursor_stmt(self._evaluator,
|
||||||
|
self._parser, dotted_path, self._pos)
|
||||||
if eval_stmt is None:
|
if eval_stmt is None:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@@ -321,26 +322,6 @@ class Script(object):
|
|||||||
|
|
||||||
return scopes
|
return scopes
|
||||||
|
|
||||||
@memoize_default()
|
|
||||||
def _get_under_cursor_stmt(self, cursor_txt, start_pos=None):
|
|
||||||
try:
|
|
||||||
stmt = Parser(self._grammar, cursor_txt, 'eval_input').get_parsed_node()
|
|
||||||
except ParseError:
|
|
||||||
return None
|
|
||||||
|
|
||||||
user_stmt = self._parser.user_stmt()
|
|
||||||
if user_stmt is None:
|
|
||||||
# Set the start_pos to a pseudo position, that doesn't exist but
|
|
||||||
# works perfectly well (for both completions in docstrings and
|
|
||||||
# statements).
|
|
||||||
pos = start_pos or self._pos
|
|
||||||
else:
|
|
||||||
pos = user_stmt.start_pos
|
|
||||||
|
|
||||||
stmt.move(pos[0] - 1, pos[1]) # Moving the offset.
|
|
||||||
stmt.parent = self._parser.user_scope()
|
|
||||||
return stmt
|
|
||||||
|
|
||||||
def goto_definitions(self):
|
def goto_definitions(self):
|
||||||
"""
|
"""
|
||||||
Return the definitions of a the path under the cursor. goto function!
|
Return the definitions of a the path under the cursor. goto function!
|
||||||
@@ -430,7 +411,8 @@ class Script(object):
|
|||||||
user_stmt = self._parser.user_stmt()
|
user_stmt = self._parser.user_stmt()
|
||||||
user_scope = self._parser.user_scope()
|
user_scope = self._parser.user_scope()
|
||||||
|
|
||||||
stmt = self._get_under_cursor_stmt(goto_path)
|
stmt = inference.get_under_cursor_stmt(self._evaluator, self._parser,
|
||||||
|
goto_path, self._pos)
|
||||||
if stmt is None:
|
if stmt is None:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@@ -537,7 +519,8 @@ class Script(object):
|
|||||||
if call_txt is None:
|
if call_txt is None:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
stmt = self._get_under_cursor_stmt(call_txt, start_pos)
|
stmt = inference.get_under_cursor_stmt(self._evaluator, self._parser,
|
||||||
|
call_txt, start_pos)
|
||||||
if stmt is None:
|
if stmt is None:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|||||||
37
jedi/api/inference.py
Normal file
37
jedi/api/inference.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
"""
|
||||||
|
This module has helpers for doing type inference on strings. It is needed,
|
||||||
|
because we still want to infer types where the syntax is invalid.
|
||||||
|
"""
|
||||||
|
from jedi.parser import Parser, ParseError
|
||||||
|
from jedi.evaluate.cache import memoize_default
|
||||||
|
|
||||||
|
|
||||||
|
def type_inference(evaluator, parser, user_context, position, dotted_path, is_completion=False):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@memoize_default(evaluator_is_first_arg=True)
|
||||||
|
def get_under_cursor_stmt(evaluator, parser, cursor_txt, start_pos):
|
||||||
|
"""
|
||||||
|
Create a syntax tree node from a string under the cursor. Directly taking
|
||||||
|
the node under the cursor (of the actual syntax tree) would disallow
|
||||||
|
invalid code to be understood.
|
||||||
|
|
||||||
|
The start_pos is typically the position of the current cursor, which may
|
||||||
|
not be the real starting position of that node, but it works perfectly well
|
||||||
|
(for both completions in docstrings and statements).
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
stmt = Parser(evaluator.grammar, cursor_txt, 'eval_input').get_parsed_node()
|
||||||
|
except ParseError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
user_stmt = parser.user_stmt()
|
||||||
|
if user_stmt is None:
|
||||||
|
pos = start_pos
|
||||||
|
else:
|
||||||
|
pos = user_stmt.start_pos
|
||||||
|
|
||||||
|
stmt.move(pos[0] - 1, pos[1]) # Moving the offset.
|
||||||
|
stmt.parent = parser.user_scope()
|
||||||
|
return stmt
|
||||||
Reference in New Issue
Block a user