mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Slow TypeEvalContext for completion, documentation, find usages, quick-fixes
This commit is contained in:
@@ -53,6 +53,11 @@ public class TypeEvalContext {
|
||||
return myAllowDataFlow || element.getContainingFile() == myOrigin;
|
||||
}
|
||||
|
||||
/**
|
||||
* The most detailed type evaluation context for user-initiated actions.
|
||||
*
|
||||
* Should be used for code completion, go to definition, find usages, refactorings, documentation.
|
||||
*/
|
||||
public static TypeEvalContext slow() {
|
||||
return new TypeEvalContext(true, true, null);
|
||||
}
|
||||
|
||||
+1
-1
@@ -114,7 +114,7 @@ public class PyDictKeyNamesCompletionContributor extends CompletionContributor {
|
||||
if (callee == null) return;
|
||||
final String name = callee.getText();
|
||||
if ("dict".equals(name)) {
|
||||
final TypeEvalContext context = TypeEvalContext.fast();
|
||||
final TypeEvalContext context = TypeEvalContext.slow();
|
||||
final PyType type = context.getType(dictConstructor);
|
||||
if (type != null && type.isBuiltin(context)) {
|
||||
final PyArgumentList list = dictConstructor.getArgumentList();
|
||||
|
||||
@@ -113,7 +113,7 @@ public class DocStringTypeReference extends PsiPolyVariantReferenceBase<PsiEleme
|
||||
for (PyImportElement element : elements) {
|
||||
final PyReferenceExpression referenceExpression = element.getImportReferenceExpression();
|
||||
if (referenceExpression == null) continue;
|
||||
final PyType type = TypeEvalContext.fast().getType(referenceExpression);
|
||||
final PyType type = TypeEvalContext.slow().getType(referenceExpression);
|
||||
if (type instanceof PyClassType) {
|
||||
variants.add(((PyClassType)type).getPyClass());
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ class PyDocumentationBuilder {
|
||||
if (outer instanceof PyQualifiedExpression) {
|
||||
PyExpression qual = ((PyQualifiedExpression)outer).getQualifier();
|
||||
if (qual != null) {
|
||||
PyType type = TypeEvalContext.fast().getType(qual);
|
||||
PyType type = TypeEvalContext.slow().getType(qual);
|
||||
if (type instanceof PyClassType) {
|
||||
cls = ((PyClassType)type).getPyClass();
|
||||
Property property = cls.findProperty(elementName);
|
||||
|
||||
@@ -481,7 +481,7 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i
|
||||
@Nullable
|
||||
private static PyClass inferClassOfParameter(PsiElement context) {
|
||||
if (context instanceof PyNamedParameter) {
|
||||
final PyType type = TypeEvalContext.fast().getType((PyNamedParameter)context);
|
||||
final PyType type = TypeEvalContext.slow().getType((PyNamedParameter)context);
|
||||
if (type instanceof PyClassType) {
|
||||
return ((PyClassType)type).getPyClass();
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class PyUsageTypeProvider implements UsageTypeProviderEx {
|
||||
if (element instanceof PyQualifiedExpression) {
|
||||
final PyExpression qualifier = ((PyQualifiedExpression)element).getQualifier();
|
||||
if (qualifier != null) {
|
||||
final PyType type = TypeEvalContext.fast().getType(qualifier);
|
||||
final PyType type = TypeEvalContext.slow().getType(qualifier);
|
||||
if (type == null || type instanceof PyTypeReference) {
|
||||
final PyCallExpression call = PsiTreeUtil.getParentOfType(element, PyCallExpression.class);
|
||||
if (call != null && element == call.getCallee()) {
|
||||
|
||||
@@ -75,7 +75,7 @@ public class AddMethodQuickFix implements LocalQuickFix {
|
||||
boolean made_instance = false;
|
||||
if (call_by_class) {
|
||||
if (args.length > 0) {
|
||||
PyType first_arg_type = TypeEvalContext.fast().getType(args[0]);
|
||||
PyType first_arg_type = TypeEvalContext.slow().getType(args[0]);
|
||||
if (first_arg_type instanceof PyClassType && ((PyClassType)first_arg_type).getPyClass().isSubclass(cls)) {
|
||||
// class, first arg ok: instance method
|
||||
builder.parameter("self"); // NOTE: might use a name other than 'self', according to code style.
|
||||
|
||||
@@ -81,9 +81,10 @@ public class PyImportReference extends PyReferenceImpl {
|
||||
}
|
||||
|
||||
PyExpression qualifier = myElement.getQualifier();
|
||||
final TypeEvalContext context = TypeEvalContext.slow();
|
||||
if (qualifier != null) {
|
||||
// qualifier's type must be module, it should know how to complete
|
||||
PyType type = TypeEvalContext.fast().getType(qualifier);
|
||||
PyType type = context.getType(qualifier);
|
||||
if (type != null) {
|
||||
Object[] variants = getTypeCompletionVariants(myElement, type);
|
||||
if (!alreadyHasImportKeyword()) {
|
||||
@@ -97,7 +98,7 @@ public class PyImportReference extends PyReferenceImpl {
|
||||
}
|
||||
else {
|
||||
// complete to possible modules
|
||||
return new ImportVariantCollector().execute();
|
||||
return new ImportVariantCollector(context).execute();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,8 +154,10 @@ public class PyImportReference extends PyReferenceImpl {
|
||||
private final PsiFile myCurrentFile;
|
||||
private final Set<String> myNamesAlready;
|
||||
private final List<Object> myObjects;
|
||||
@NotNull private final TypeEvalContext myContext;
|
||||
|
||||
public ImportVariantCollector() {
|
||||
public ImportVariantCollector(@NotNull TypeEvalContext context) {
|
||||
myContext = context;
|
||||
PsiFile currentFile = myElement.getContainingFile();
|
||||
if (currentFile != null) currentFile = currentFile.getOriginalFile();
|
||||
myCurrentFile = currentFile;
|
||||
@@ -177,7 +180,7 @@ public class PyImportReference extends PyReferenceImpl {
|
||||
addImportedNames(from_import.getImportElements()); // don't propose already imported items
|
||||
// try to collect submodules
|
||||
PyExpression module = (PyExpression)mod_candidate;
|
||||
PyType qualifierType = TypeEvalContext.fast().getType(module);
|
||||
PyType qualifierType = myContext.getType(module);
|
||||
if (qualifierType != null) {
|
||||
ProcessingContext ctx = new ProcessingContext();
|
||||
ctx.put(PyType.CTX_NAMES, myNamesAlready);
|
||||
|
||||
@@ -33,7 +33,7 @@ public class PyTypeParserTest extends PyTestCase {
|
||||
myFixture.configureByFile("typeParser/typeParser.py");
|
||||
final PyCollectionType type = (PyCollectionType) PyTypeParser.getTypeByName(myFixture.getFile(), "list of MyObject");
|
||||
assertClassType(type, "list");
|
||||
assertClassType(type.getElementType(TypeEvalContext.fast()), "MyObject");
|
||||
assertClassType(type.getElementType(TypeEvalContext.slow()), "MyObject");
|
||||
}
|
||||
|
||||
public void testDictType() {
|
||||
@@ -41,7 +41,7 @@ public class PyTypeParserTest extends PyTestCase {
|
||||
final PyCollectionType type = (PyCollectionType) PyTypeParser.getTypeByName(myFixture.getFile(), "dict from str to MyObject");
|
||||
assertNotNull(type);
|
||||
assertClassType(type, "dict");
|
||||
final PyType elementType = type.getElementType(TypeEvalContext.fast());
|
||||
final PyType elementType = type.getElementType(TypeEvalContext.slow());
|
||||
assertInstanceOf(elementType, PyTupleType.class);
|
||||
final PyTupleType tupleType = (PyTupleType)elementType;
|
||||
assertEquals(2, tupleType.getElementCount());
|
||||
|
||||
Reference in New Issue
Block a user