From 85b572bfebaf72ba43c3a7b433d1f74b52748dd9 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Tue, 11 Mar 2014 19:20:46 +0400 Subject: [PATCH] do not store reference to PsiElement in add field quickfix --- .../PyUnresolvedReferencesInspection.java | 2 +- .../PyUnusedLocalInspectionVisitor.java | 6 +--- .../quickfix/AddFieldQuickFix.java | 30 +++++++++++++++---- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java index f1bf6e1f0d5e..5a74091c22ce 100644 --- a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java @@ -754,7 +754,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection { actions.add(new AddMethodQuickFix(refText, (PyClassType)type, true)); } else if (!(reference instanceof PyOperatorReference)) { - actions.add(new AddFieldQuickFix(refText, (PyClassType)type, "None")); + actions.add(new AddFieldQuickFix(refText, "None", type.getName())); } } } diff --git a/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java b/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java index 3dc42057348f..756ae140391f 100644 --- a/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java +++ b/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java @@ -42,7 +42,6 @@ import com.jetbrains.python.psi.impl.PyImportStatementNavigator; import com.jetbrains.python.psi.resolve.PyResolveContext; import com.jetbrains.python.psi.search.PyOverridingMethodsSearch; import com.jetbrains.python.psi.search.PySuperMethodsSearch; -import com.jetbrains.python.psi.types.PyClassTypeImpl; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -297,7 +296,7 @@ public class PyUnusedLocalInspectionVisitor extends PyInspectionVisitor { } } final LocalQuickFix[] fixes = mayBeField - ? new LocalQuickFix[] { new AddFieldQuickFix(name, new PyClassTypeImpl(containingClass, false), name) } + ? new LocalQuickFix[] { new AddFieldQuickFix(name, name, containingClass.getName()) } : LocalQuickFix.EMPTY_ARRAY; registerWarning(element, PyBundle.message("INSP.unused.locals.parameter.isnot.used", name), fixes); } @@ -416,9 +415,6 @@ public class PyUnusedLocalInspectionVisitor extends PyInspectionVisitor { private static boolean isEmptyFunction(@NotNull PyFunction f) { final PyStatementList statementList = f.getStatementList(); - if (statementList == null) { - return true; - } final PyStatement[] statements = statementList.getStatements(); if (statements.length == 0) { return true; diff --git a/python/src/com/jetbrains/python/inspections/quickfix/AddFieldQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/AddFieldQuickFix.java index 356748409818..c0de4854c136 100644 --- a/python/src/com/jetbrains/python/inspections/quickfix/AddFieldQuickFix.java +++ b/python/src/com/jetbrains/python/inspections/quickfix/AddFieldQuickFix.java @@ -29,6 +29,7 @@ import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.Function; import com.jetbrains.python.PyBundle; import com.jetbrains.python.PyNames; @@ -36,6 +37,9 @@ import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.impl.PyBuiltinCache; import com.jetbrains.python.psi.impl.PyPsiUtils; import com.jetbrains.python.psi.types.PyClassType; +import com.jetbrains.python.psi.types.PyClassTypeImpl; +import com.jetbrains.python.psi.types.PyType; +import com.jetbrains.python.psi.types.TypeEvalContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -48,19 +52,19 @@ import static com.jetbrains.python.PyNames.FAKE_OLD_BASE; */ public class AddFieldQuickFix implements LocalQuickFix { - private PyClassType myQualifierType; private final String myInitializer; + private final String myClassName; private String myIdentifier; - public AddFieldQuickFix(String identifier, PyClassType qualifierType, String initializer) { + public AddFieldQuickFix(@NotNull final String identifier, @NotNull final String initializer, final String className) { myIdentifier = identifier; - myQualifierType = qualifierType; myInitializer = initializer; + myClassName = className; } @NotNull public String getName() { - return PyBundle.message("QFIX.NAME.add.field.$0.to.class.$1", myIdentifier, myQualifierType.getName()); + return PyBundle.message("QFIX.NAME.add.field.$0.to.class.$1", myIdentifier, myClassName); } @NotNull @@ -87,9 +91,12 @@ public class AddFieldQuickFix implements LocalQuickFix { public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { // expect the descriptor to point to the unresolved identifier. - PyClass cls = myQualifierType.getPyClass(); + final PsiElement element = descriptor.getPsiElement(); + final PyClassType type = getClassType(element); + if (type == null) return; + final PyClass cls = type.getPyClass(); PsiElement initStatement; - if (!myQualifierType.isDefinition()) { + if (!type.isDefinition()) { initStatement = addFieldToInit(project, cls, myIdentifier, new CreateFieldCallback(project, myIdentifier, myInitializer)); } else { @@ -105,6 +112,17 @@ public class AddFieldQuickFix implements LocalQuickFix { PyUtil.showBalloon(project, PyBundle.message("QFIX.failed.to.add.field"), MessageType.ERROR); } + private static PyClassType getClassType(@NotNull final PsiElement element) { + if (element instanceof PyQualifiedExpression) { + final PyExpression qualifier = ((PyQualifiedExpression)element).getQualifier(); + if (qualifier == null) return null; + final PyType type = TypeEvalContext.userInitiated(element.getContainingFile()).getType(qualifier); + return type instanceof PyClassType ? (PyClassType)type : null; + } + final PyClass aClass = PsiTreeUtil.getParentOfType(element, PyClass.class); + return aClass != null ? new PyClassTypeImpl(aClass, false) : null; + } + private void showTemplateBuilder(PsiElement initStatement, @NotNull final PsiFile file) { initStatement = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(initStatement); if (initStatement instanceof PyAssignmentStatement) {