[PY-34710] Fix adding not implemented function to imported module

GitOrigin-RevId: cd11eaf0b7b4004d0822cb2688bbb3a1b9a60116
This commit is contained in:
andrey.matveev
2020-07-13 13:12:21 +07:00
committed by intellij-monorepo-bot
parent fa2f830142
commit 4115b0eac4
11 changed files with 60 additions and 12 deletions

View File

@@ -16,6 +16,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.IncorrectOperationException;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PyPsiBundle;
@@ -71,7 +72,12 @@ public class AddFunctionQuickFix implements LocalQuickFix {
try {
final PsiElement problemElement = descriptor.getPsiElement();
if (!(problemElement instanceof PyQualifiedExpression)) return;
final PyExpression qualifier = ((PyQualifiedExpression)problemElement).getQualifier();
PyExpression qualifier = ((PyQualifiedExpression)problemElement).getQualifier();
if (qualifier == null) {
final PyFromImportStatement fromImport = PsiTreeUtil.getParentOfType(problemElement, PyFromImportStatement.class);
if (fromImport == null) return;
qualifier = fromImport.getImportSource();
}
if (qualifier == null) return;
final PyType type = TypeEvalContext.userInitiated(problemElement.getProject(), problemElement.getContainingFile()).getType(qualifier);
if (!(type instanceof PyModuleType)) return;

View File

@@ -0,0 +1,4 @@
from mod import <error descr="Cannot find reference 'foo' in 'mod.py'"><caret>foo</error>
foo()

View File

@@ -0,0 +1,2 @@
def foo():
return None

View File

@@ -0,0 +1,3 @@
import mod
mod.<caret><warning descr="Cannot find reference 'func' in 'mod.py'"><caret>func</warning>()

View File

@@ -0,0 +1,2 @@
def func():
return None

View File

@@ -0,0 +1,3 @@
from mypack import <error descr="Cannot find reference 'foo' in '__init__.py'"><caret>foo</error>
a = foo()

View File

@@ -0,0 +1,2 @@
def foo():
return None

View File

@@ -2,6 +2,7 @@
package com.jetbrains.python;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.ex.InspectionProfileImpl;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.testFramework.TestDataFile;
@@ -227,14 +228,25 @@ public class PyQuickFixTest extends PyTestCase {
() -> doInspectionTest(PyUnresolvedReferencesInspection.class, PyBundle.message("QFIX.NAME.unresolved.reference.create.function", "my_function"), true, true));
}
// PY-1602
public void testAddFunctionToModule() {
doInspectionTest(
"AddFunctionToModule.py",
PyUnresolvedReferencesInspection.class,
PyPsiBundle.message("QFIX.NAME.add.function.$0.to.module.$1", "frob", "AddFunctionToModule.py"),
true, true
);
// PY-1465
public void testAddFunctionToModuleInImport() {
doMultiFilesInspectionTest(PyUnresolvedReferencesInspection.class,
PyPsiBundle.message("QFIX.NAME.add.function.$0.to.module.$1", "func", "mod.py"),
"mod.py");
}
// PY-34710
public void testAddFunctionToModuleInFromImport() {
doMultiFilesInspectionTest(PyUnresolvedReferencesInspection.class,
PyPsiBundle.message("QFIX.NAME.add.function.$0.to.module.$1", "foo", "mod.py"),
"mod.py");
}
// PY-34710
public void testAddFunctionToPackageInFromImport() {
doMultiFilesInspectionTest(PyUnresolvedReferencesInspection.class,
PyPsiBundle.message("QFIX.NAME.add.function.$0.to.module.$1", "foo", "__init__.py"),
"mypack/__init__.py");
}
// PY-1470
@@ -724,7 +736,7 @@ public class PyQuickFixTest extends PyTestCase {
return PythonTestUtil.getTestDataPath() + "/inspections/";
}
private void doInspectionTest(@NotNull Class inspectionClass,
private void doInspectionTest(@NotNull Class<? extends LocalInspectionTool> inspectionClass,
@NotNull String quickFixName,
boolean applyFix,
boolean available) {
@@ -732,7 +744,7 @@ public class PyQuickFixTest extends PyTestCase {
}
protected void doInspectionTest(@TestDataFile @NonNls @NotNull String testFileName,
@NotNull Class inspectionClass,
@NotNull Class<? extends LocalInspectionTool> inspectionClass,
@NonNls @NotNull String quickFixName,
boolean applyFix,
boolean available) {
@@ -750,7 +762,7 @@ public class PyQuickFixTest extends PyTestCase {
* @throws Exception
*/
protected void doInspectionTest(@NonNls String @NotNull [] testFiles,
@NotNull Class inspectionClass,
@NotNull Class<? extends LocalInspectionTool> inspectionClass,
@NonNls @NotNull String quickFixName,
boolean applyFix,
boolean available) {
@@ -777,6 +789,20 @@ public class PyQuickFixTest extends PyTestCase {
}
}
private void doMultiFilesInspectionTest(@NotNull Class<? extends LocalInspectionTool> inspectionClass,
@NotNull String intentionStr,
@NotNull String modifiedFile) {
myFixture.enableInspections(inspectionClass);
myFixture.copyDirectoryToProject(getTestName(true), "");
myFixture.configureFromTempProjectFile(getTestName(true) + ".py");
myFixture.checkHighlighting(true, false, false);
final IntentionAction intentionAction = myFixture.findSingleIntention(intentionStr);
assertNotNull(intentionAction);
myFixture.launchAction(intentionAction);
final String expectedFile = getTestName(true) + "/" + graftBeforeExt(modifiedFile, "_after");
myFixture.checkResultByFile(modifiedFile, expectedFile, true);
}
// Turns "name.ext" to "name_insertion.ext"
@NonNls