diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyTargetExpression.java b/python/psi-api/src/com/jetbrains/python/psi/PyTargetExpression.java index 930a4c310af9..d27d84191bc7 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/PyTargetExpression.java +++ b/python/psi-api/src/com/jetbrains/python/psi/PyTargetExpression.java @@ -12,7 +12,8 @@ import org.jetbrains.annotations.Nullable; /** * @author yole */ -public interface PyTargetExpression extends PyQualifiedExpression, PsiNamedElement, PsiNameIdentifierOwner, StubBasedPsiElement { +public interface PyTargetExpression extends PyQualifiedExpression, PsiNamedElement, PsiNameIdentifierOwner, PyDocStringOwner, + StubBasedPsiElement { PyTargetExpression[] EMPTY_ARRAY = new PyTargetExpression[0]; /** diff --git a/python/psi-api/src/com/jetbrains/python/psi/stubs/PyTargetExpressionStub.java b/python/psi-api/src/com/jetbrains/python/psi/stubs/PyTargetExpressionStub.java index aedd7d3740e0..7ec0c2e7788e 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/stubs/PyTargetExpressionStub.java +++ b/python/psi-api/src/com/jetbrains/python/psi/stubs/PyTargetExpressionStub.java @@ -45,4 +45,7 @@ public interface PyTargetExpressionStub extends NamedStub { @Nullable T getCustomStub(Class stubClass); + + @Nullable + String getDocString(); } diff --git a/python/src/com/jetbrains/python/documentation/DocStringUtil.java b/python/src/com/jetbrains/python/documentation/DocStringUtil.java index dd07c8d84a26..812f518963e6 100644 --- a/python/src/com/jetbrains/python/documentation/DocStringUtil.java +++ b/python/src/com/jetbrains/python/documentation/DocStringUtil.java @@ -1,7 +1,5 @@ package com.jetbrains.python.documentation; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.psi.PsiComment; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiWhiteSpace; @@ -19,12 +17,6 @@ public class DocStringUtil { private DocStringUtil() { } - public static String trimDocString(String s) { - return s.trim() - .replaceFirst("^((:py)?:class:`[~!]?|[A-Z]\\{)", "") - .replaceFirst("(`|\\})?\\.?$", ""); - } - @Nullable public static String getDocStringValue(@NotNull PyDocStringOwner owner) { return PyPsiUtils.strValue(owner.getDocStringExpression()); @@ -81,24 +73,6 @@ public class DocStringUtil { return false; } - @Nullable - public static PyStringLiteralExpression getAttributeDocString(@NotNull PyTargetExpression attr) { - if (attr.getParent() instanceof PyAssignmentStatement) { - final PyAssignmentStatement assignment = (PyAssignmentStatement)attr.getParent(); - PsiElement nextSibling = assignment.getNextSibling(); - while (nextSibling != null && (nextSibling instanceof PsiWhiteSpace || nextSibling instanceof PsiComment)) { - nextSibling = nextSibling.getNextSibling(); - } - if (nextSibling instanceof PyExpressionStatement) { - final PyExpression expression = ((PyExpressionStatement)nextSibling).getExpression(); - if (expression instanceof PyStringLiteralExpression) { - return (PyStringLiteralExpression)expression; - } - } - } - return null; - } - @Nullable public static String getAttributeDocComment(@NotNull PyTargetExpression attr) { if (attr.getParent() instanceof PyAssignmentStatement) { @@ -115,31 +89,26 @@ public class DocStringUtil { } public static boolean isVariableDocString(@NotNull PyStringLiteralExpression expr) { - final Module module = ModuleUtilCore.findModuleForPsiElement(expr); - if (module == null) return false; - final PyDocumentationSettings settings = PyDocumentationSettings.getInstance(module); - if (settings.isEpydocFormat(expr.getContainingFile()) || settings.isReSTFormat(expr.getContainingFile())) { - final PsiElement parent = expr.getParent(); - if (!(parent instanceof PyExpressionStatement)) { - return false; - } - PsiElement prevElement = parent.getPrevSibling(); - while (prevElement instanceof PsiWhiteSpace || prevElement instanceof PsiComment) { - prevElement = prevElement.getPrevSibling(); - } - if (prevElement instanceof PyAssignmentStatement) { - if (expr.getText().contains("type:")) return true; + final PsiElement parent = expr.getParent(); + if (!(parent instanceof PyExpressionStatement)) { + return false; + } + PsiElement prevElement = parent.getPrevSibling(); + while (prevElement instanceof PsiWhiteSpace || prevElement instanceof PsiComment) { + prevElement = prevElement.getPrevSibling(); + } + if (prevElement instanceof PyAssignmentStatement) { + if (expr.getText().contains("type:")) return true; - final PyAssignmentStatement assignmentStatement = (PyAssignmentStatement)prevElement; - final ScopeOwner scope = PsiTreeUtil.getParentOfType(prevElement, ScopeOwner.class); - if (scope instanceof PyClass || scope instanceof PyFile) { - return true; - } - if (scope instanceof PyFunction) { - for (PyExpression target : assignmentStatement.getTargets()) { - if (PyUtil.isInstanceAttribute(target)) { - return true; - } + final PyAssignmentStatement assignmentStatement = (PyAssignmentStatement)prevElement; + final ScopeOwner scope = PsiTreeUtil.getParentOfType(prevElement, ScopeOwner.class); + if (scope instanceof PyClass || scope instanceof PyFile) { + return true; + } + if (scope instanceof PyFunction) { + for (PyExpression target : assignmentStatement.getTargets()) { + if (PyUtil.isInstanceAttribute(target)) { + return true; } } } diff --git a/python/src/com/jetbrains/python/documentation/PyDocumentationBuilder.java b/python/src/com/jetbrains/python/documentation/PyDocumentationBuilder.java index 99aa25356fa6..281f7b186865 100644 --- a/python/src/com/jetbrains/python/documentation/PyDocumentationBuilder.java +++ b/python/src/com/jetbrains/python/documentation/PyDocumentationBuilder.java @@ -14,7 +14,6 @@ import com.intellij.psi.util.PsiTreeUtil; import com.jetbrains.python.PyBundle; import com.jetbrains.python.PyNames; import com.jetbrains.python.PythonFileType; -import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; import com.jetbrains.python.console.PyConsoleUtil; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.impl.PyBuiltinCache; @@ -229,9 +228,7 @@ class PyDocumentationBuilder { } private boolean isAttribute() { - return myElement instanceof PyTargetExpression && - (PyUtil.isInstanceAttribute((PyTargetExpression)myElement) || - PsiTreeUtil.getParentOfType(myElement, ScopeOwner.class) instanceof PyClass); + return myElement instanceof PyTargetExpression && PyUtil.isAttribute((PyTargetExpression)myElement); } @Nullable @@ -449,7 +446,7 @@ class PyDocumentationBuilder { .addItem(" of class ").addWith(PythonDocumentationProvider.LinkMyClass, $().addWith(TagCode, $(cls.getName()))).addItem(BR) ; - final String docString = PyPsiUtils.strValue(DocStringUtil.getAttributeDocString((PyTargetExpression)myElement)); + final String docString = ((PyTargetExpression)myElement).getDocStringValue(); if (docString != null) { addFormattedDocString(myElement, docString, myBody, myEpilog); } diff --git a/python/src/com/jetbrains/python/psi/PyFileElementType.java b/python/src/com/jetbrains/python/psi/PyFileElementType.java index 355818dede2e..14154f11d6a9 100644 --- a/python/src/com/jetbrains/python/psi/PyFileElementType.java +++ b/python/src/com/jetbrains/python/psi/PyFileElementType.java @@ -47,7 +47,8 @@ public class PyFileElementType extends IStubFileElementType { @Override public int getStubVersion() { - return 47; + // Don't forget to update versions of indexes that use the updated stub-based elements + return 48; } @Nullable diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index e1413a826059..f01213651151 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -435,6 +435,10 @@ public class PyUtil { if (!thing) throw new IncorrectOperationException(); } + public static boolean isAttribute(PyTargetExpression ex) { + return isInstanceAttribute(ex) || isClassAttribute(ex); + } + public static boolean isInstanceAttribute(PyExpression target) { if (!(target instanceof PyTargetExpression)) { return false; @@ -443,6 +447,9 @@ public class PyUtil { if (owner instanceof PyFunction) { final PyFunction method = (PyFunction)owner; if (method.getContainingClass() != null) { + if (method.getStub() != null) { + return true; + } final PyParameter[] params = method.getParameterList().getParameters(); if (params.length > 0) { final PyTargetExpression targetExpr = (PyTargetExpression)target; diff --git a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java index 829cde42f98e..0cfb00d6223b 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java @@ -926,9 +926,8 @@ public class PyClassImpl extends PyPresentableElementImpl implement if (params.length == 0) { return; } - final PyFunctionStub methodStub = method.getStub(); for (PyTargetExpression target : getTargetExpressions(method)) { - if (methodStub != null || PyUtil.isInstanceAttribute(target)) { + if (PyUtil.isInstanceAttribute(target)) { result.put(target.getName(), target); } } diff --git a/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java index eb278620b1a4..97f0a39be9f2 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java @@ -4,10 +4,7 @@ import com.intellij.lang.ASTNode; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiPolyVariantReference; -import com.intellij.psi.PsiReference; -import com.intellij.psi.ResolveResult; +import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.SearchScope; @@ -25,7 +22,6 @@ import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; import com.jetbrains.python.codeInsight.dataflow.scope.Scope; import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil; import com.jetbrains.python.documentation.DocStringUtil; -import com.jetbrains.python.psi.StructuredDocString; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.impl.references.PyQualifiedReference; import com.jetbrains.python.psi.impl.references.PyTargetReference; @@ -120,10 +116,14 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl imp private final InitializerType myInitializerType; private final PyQualifiedName myInitializer; private final boolean myQualified; + @Nullable private final String myDocString; private final CustomTargetExpressionStub myCustomStub; - public PyTargetExpressionStubImpl(String name, CustomTargetExpressionStub customStub, StubElement parent) { + public PyTargetExpressionStubImpl(String name, + @Nullable String docString, + CustomTargetExpressionStub customStub, + StubElement parent) { super(parent, PyElementTypes.TARGET_EXPRESSION); myName = name; myInitializerType = InitializerType.Custom; myInitializer = null; myQualified = false; myCustomStub = customStub; + myDocString = docString; } - public PyTargetExpressionStubImpl(final String name, final InitializerType initializerType, + public PyTargetExpressionStubImpl(final String name, @Nullable String docString, final InitializerType initializerType, final PyQualifiedName initializer, final boolean qualified, final StubElement parentStub) { @@ -39,6 +44,7 @@ public class PyTargetExpressionStubImpl extends StubBase imp myInitializer = initializer; myQualified = qualified; myCustomStub = null; + myDocString = docString; } public String getName() { @@ -67,6 +73,12 @@ public class PyTargetExpressionStubImpl extends StubBase imp return null; } + @Nullable + @Override + public String getDocString() { + return myDocString; + } + @Override public String toString() { return "PyTargetExpressionStub(name=" + myName + ")"; diff --git a/python/src/com/jetbrains/python/psi/stubs/PyInstanceAttributeIndex.java b/python/src/com/jetbrains/python/psi/stubs/PyInstanceAttributeIndex.java index 408cf5183794..57967b31a39d 100644 --- a/python/src/com/jetbrains/python/psi/stubs/PyInstanceAttributeIndex.java +++ b/python/src/com/jetbrains/python/psi/stubs/PyInstanceAttributeIndex.java @@ -16,6 +16,11 @@ import java.util.Collection; public class PyInstanceAttributeIndex extends StringStubIndexExtension { public static final StubIndexKey KEY = StubIndexKey.createIndexKey("Py.instanceAttribute.name"); + @Override + public int getVersion() { + return super.getVersion() + 1; + } + @NotNull @Override public StubIndexKey getKey() { diff --git a/python/src/com/jetbrains/python/psi/stubs/PyVariableNameIndex.java b/python/src/com/jetbrains/python/psi/stubs/PyVariableNameIndex.java index 392e974ef3cd..162734c51e6d 100644 --- a/python/src/com/jetbrains/python/psi/stubs/PyVariableNameIndex.java +++ b/python/src/com/jetbrains/python/psi/stubs/PyVariableNameIndex.java @@ -16,6 +16,11 @@ import java.util.Collection; public class PyVariableNameIndex extends StringStubIndexExtension { public static final StubIndexKey KEY = StubIndexKey.createIndexKey("Py.variable.shortName"); + @Override + public int getVersion() { + return super.getVersion() + 1; + } + @NotNull public StubIndexKey getKey() { return KEY; diff --git a/python/src/com/jetbrains/python/refactoring/PyRefactoringProvider.java b/python/src/com/jetbrains/python/refactoring/PyRefactoringProvider.java index caee4384ea5b..84232bde99b1 100644 --- a/python/src/com/jetbrains/python/refactoring/PyRefactoringProvider.java +++ b/python/src/com/jetbrains/python/refactoring/PyRefactoringProvider.java @@ -17,6 +17,7 @@ import com.jetbrains.python.refactoring.introduce.parameter.PyIntroduceParameter import com.jetbrains.python.refactoring.introduce.constant.PyIntroduceConstantHandler; import com.jetbrains.python.refactoring.introduce.field.PyIntroduceFieldHandler; import com.jetbrains.python.refactoring.introduce.variable.PyIntroduceVariableHandler; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** @@ -59,7 +60,7 @@ public class PyRefactoringProvider extends RefactoringSupportProvider { } @Override - public boolean isInplaceRenameAvailable(PsiElement element, PsiElement context) { + public boolean isInplaceRenameAvailable(@NotNull PsiElement element, PsiElement context) { if (context != null && context.getContainingFile() != element.getContainingFile()) return false; PyFunction containingFunction = PsiTreeUtil.getParentOfType(element, PyFunction.class); if (containingFunction != null) { diff --git a/python/testData/inspections/MoveDocstring.py b/python/testData/inspections/MoveDocstring.py index 468be246dd68..1db4e3f4d282 100644 --- a/python/testData/inspections/MoveDocstring.py +++ b/python/testData/inspections/MoveDocstring.py @@ -1,9 +1,8 @@ class GetCustomerPaymentProfileRequest(CustomerRequest): - _keys = CustomerRequest._keys + ["customerPaymentProfileId"] + def __init__(self, user, profileid): + CustomerRequest.__init__(self, user, + customerPaymentProfileId=profileid) """ Gets a payment profile by user Account object and authorize.net profileid of the payment profile. """ - def __init__(self, user, profileid): - CustomerRequest.__init__(self, user, - customerPaymentProfileId=profileid) \ No newline at end of file diff --git a/python/testData/inspections/MoveDocstring_after.py b/python/testData/inspections/MoveDocstring_after.py index e262aaa10637..1833c32c75fe 100644 --- a/python/testData/inspections/MoveDocstring_after.py +++ b/python/testData/inspections/MoveDocstring_after.py @@ -3,8 +3,7 @@ class GetCustomerPaymentProfileRequest(CustomerRequest): Gets a payment profile by user Account object and authorize.net profileid of the payment profile. """ - _keys = CustomerRequest._keys + ["customerPaymentProfileId"] def __init__(self, user, profileid): CustomerRequest.__init__(self, user, - customerPaymentProfileId=profileid) \ No newline at end of file + customerPaymentProfileId=profileid) diff --git a/python/testData/stubs/TargetExpressionDocString.py b/python/testData/stubs/TargetExpressionDocString.py new file mode 100644 index 000000000000..e6051a8b74e7 --- /dev/null +++ b/python/testData/stubs/TargetExpressionDocString.py @@ -0,0 +1,6 @@ +class C(object): + foo = None + """Foo docstring.""" + + bar = None + diff --git a/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java b/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java index da0bb6533ef8..09695ea2bcf1 100644 --- a/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java +++ b/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java @@ -3,7 +3,6 @@ package com.jetbrains.python; import com.intellij.codeInsight.controlflow.ControlFlow; import com.intellij.codeInsight.controlflow.Instruction; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache; @@ -14,7 +13,6 @@ import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyFile; import com.jetbrains.python.psi.PyFunction; -import java.io.File; import java.io.IOException; /** @@ -234,7 +232,7 @@ public class PyControlFlowBuilderTest extends LightMarkedTestCase { for (Instruction instruction : instructions) { buffer.append(instruction).append("\n"); } - final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/')); + final VirtualFile vFile = getVirtualFileByName(fullPath); try { final String fileText = StringUtil.convertLineSeparators(VfsUtil.loadText(vFile), "\n"); assertEquals(fileText.trim(), buffer.toString().trim()); diff --git a/python/testSrc/com/jetbrains/python/PyQuickDocTest.java b/python/testSrc/com/jetbrains/python/PyQuickDocTest.java index de9ea7ff9c04..9747a59c770f 100644 --- a/python/testSrc/com/jetbrains/python/PyQuickDocTest.java +++ b/python/testSrc/com/jetbrains/python/PyQuickDocTest.java @@ -1,7 +1,6 @@ package com.jetbrains.python; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; @@ -11,7 +10,6 @@ import com.jetbrains.python.fixtures.LightMarkedTestCase; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher; -import java.io.File; import java.io.IOException; import java.util.Map; @@ -35,7 +33,7 @@ public class PyQuickDocTest extends LightMarkedTestCase { private void checkByHTML(String text, @TestDataFile String filePath) { final String fullPath = getTestDataPath() + filePath; - final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/')); + final VirtualFile vFile = getVirtualFileByName(fullPath); assertNotNull("file " + fullPath + " not found", vFile); String loadedText; diff --git a/python/testSrc/com/jetbrains/python/PyStubsTest.java b/python/testSrc/com/jetbrains/python/PyStubsTest.java index fdf34339ee4c..95306b724a08 100644 --- a/python/testSrc/com/jetbrains/python/PyStubsTest.java +++ b/python/testSrc/com/jetbrains/python/PyStubsTest.java @@ -402,6 +402,14 @@ public class PyStubsTest extends PyTestCase { } classes = PyClassNameIndex.find("Foo", project, GlobalSearchScope.allScope(project)); assertEquals(classes.size(), 1); + } + public void testTargetExpressionDocString() { + final PyFile file = getTestFile(); + final PyClass c = file.findTopLevelClass("C"); + assertNotNull(c); + final PyTargetExpression foo = c.findClassAttribute("foo", false); + final String docString = foo.getDocStringValue(); + assertEquals("Foo docstring.", docString); } } diff --git a/python/testSrc/com/jetbrains/python/PyTypeTest.java b/python/testSrc/com/jetbrains/python/PyTypeTest.java index 2046a3230983..5fa7cd7db11e 100644 --- a/python/testSrc/com/jetbrains/python/PyTypeTest.java +++ b/python/testSrc/com/jetbrains/python/PyTypeTest.java @@ -646,6 +646,44 @@ public class PyTypeTest extends PyTestCase { "expr = func(foo)\n"); } + // PY-6584 + public void testClassAttributeTypeInClassDocStringViaClass() { + doTest("int", + "class C(object):\n" + + " '''\n" + + " :type foo: int\n" + + " '''\n" + + " foo = None\n" + + "\n" + + "expr = C.foo\n"); + } + + // PY-6584 + public void testClassAttributeTypeInClassDocStringViaInstance() { + doTest("int", + "class C(object):\n" + + " '''\n" + + " :type foo: int\n" + + " '''\n" + + " foo = None\n" + + "\n" + + "expr = C().foo\n"); + } + + // PY-6584 + public void testInstanceAttributeTypeInClassDocString() { + doTest("int", + "class C(object):\n" + + " '''\n" + + " :type foo: int\n" + + " '''\n" + + " def __init__(self, bar):\n" + + " self.foo = bar\n" + + "\n" + + "def f(x):\n" + + " expr = C(x).foo\n"); + } + private static TypeEvalContext getTypeEvalContext(@NotNull PyExpression element) { return TypeEvalContext.userInitiated(element.getContainingFile()).withTracing(); } diff --git a/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java b/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java index 6bdca7aaf470..ceda9ec399b4 100644 --- a/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java +++ b/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java @@ -140,15 +140,7 @@ public class PythonInspectionsTest extends PyTestCase { } public void testPyStatementEffectInspection() { - final PyDocumentationSettings documentationSettings = PyDocumentationSettings.getInstance(myFixture.getModule()); - final String oldFormat = documentationSettings.getFormat(); - try { - documentationSettings.setFormat(DocStringFormat.EPYTEXT); - doHighlightingTest(PyStatementEffectInspection.class, LanguageLevel.PYTHON26); - } - finally { - documentationSettings.setFormat(oldFormat); - } + doHighlightingTest(PyStatementEffectInspection.class, LanguageLevel.PYTHON26); } public void testPySimplifyBooleanCheckInspection() { diff --git a/python/testSrc/com/jetbrains/python/fixtures/LightMarkedTestCase.java b/python/testSrc/com/jetbrains/python/fixtures/LightMarkedTestCase.java index ef40041264eb..73a06d79a220 100644 --- a/python/testSrc/com/jetbrains/python/fixtures/LightMarkedTestCase.java +++ b/python/testSrc/com/jetbrains/python/fixtures/LightMarkedTestCase.java @@ -1,7 +1,6 @@ package com.jetbrains.python.fixtures; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; @@ -10,7 +9,6 @@ import com.intellij.testFramework.TestDataFile; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NonNls; -import java.io.File; import java.io.IOException; import java.util.Map; import java.util.regex.Matcher; @@ -49,7 +47,7 @@ public abstract class LightMarkedTestCase extends PyTestCase { */ protected Map configureByFile(@TestDataFile @NonNls String filePath, @NonNls String markerRegexp) { final String fullPath = getTestDataPath() + filePath; - final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/')); + final VirtualFile vFile = getVirtualFileByName(fullPath); assertNotNull("file " + fullPath + " not found", vFile); final String text; diff --git a/python/testSrc/com/jetbrains/python/fixtures/PyTestCase.java b/python/testSrc/com/jetbrains/python/fixtures/PyTestCase.java index 2e78bb6f40da..7a1d27ddcac9 100644 --- a/python/testSrc/com/jetbrains/python/fixtures/PyTestCase.java +++ b/python/testSrc/com/jetbrains/python/fixtures/PyTestCase.java @@ -31,6 +31,8 @@ import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.File; + /** * @author yole */ @@ -46,6 +48,11 @@ public abstract class PyTestCase extends UsefulTestCase { protected CodeInsightTestFixture myFixture; private static boolean ourPlatformPrefixInitialized; + @Nullable + protected static VirtualFile getVirtualFileByName(String fileName) { + return LocalFileSystem.getInstance().findFileByPath(fileName.replace(File.separatorChar, '/')); + } + @Override protected void setUp() throws Exception { super.setUp(); diff --git a/python/testSrc/com/jetbrains/python/refactoring/PyCodeFragmentTest.java b/python/testSrc/com/jetbrains/python/refactoring/PyCodeFragmentTest.java index 8f46ff540429..2b8510418040 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/PyCodeFragmentTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/PyCodeFragmentTest.java @@ -4,7 +4,6 @@ import com.intellij.codeInsight.codeFragment.CannotCreateCodeFragmentException; import com.intellij.codeInsight.codeFragment.CodeFragment; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; @@ -15,7 +14,6 @@ import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; import com.jetbrains.python.fixtures.LightMarkedTestCase; import com.jetbrains.python.psi.PyFile; -import java.io.File; import java.util.TreeSet; /** @@ -35,7 +33,7 @@ public class PyCodeFragmentTest extends LightMarkedTestCase { final String testName = getTestName(false).toLowerCase(); final String fullPath = getTestDataPath() + testName + ".test"; - final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/')); + final VirtualFile vFile = getVirtualFileByName(fullPath); String fileText = StringUtil.convertLineSeparators(VfsUtil.loadText(vFile), "\n"); final int beginMarker = fileText.indexOf(BEGIN_MARKER); diff --git a/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java b/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java index 83da6385f4f3..198285281b9b 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java @@ -1,7 +1,6 @@ package com.jetbrains.python.refactoring; import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesProcessor; @@ -16,7 +15,6 @@ import com.jetbrains.python.psi.stubs.PyFunctionNameIndex; import com.jetbrains.python.refactoring.move.PyMoveClassOrFunctionProcessor; import org.jetbrains.annotations.Nullable; -import java.io.File; import java.io.IOException; import java.util.Collection; @@ -178,11 +176,6 @@ public class PyMoveTest extends PyTestCase { } } - @Nullable - private static VirtualFile getVirtualFileByName(String fileName) { - return LocalFileSystem.getInstance().findFileByPath(fileName.replace(File.separatorChar, '/')); - } - @Nullable private PsiNamedElement findFirstNamedElement(String name) { final Collection classes = PyClassNameIndex.find(name, myFixture.getProject(), false); diff --git a/python/testSrc/com/jetbrains/python/refactoring/PyRenameTest.java b/python/testSrc/com/jetbrains/python/refactoring/PyRenameTest.java index bc5360ad931d..e0d58067cbb6 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/PyRenameTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/PyRenameTest.java @@ -1,7 +1,6 @@ package com.jetbrains.python.refactoring; import com.intellij.codeInsight.TargetElementUtilBase; -import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; @@ -10,9 +9,7 @@ import com.intellij.testFramework.PlatformTestUtil; import com.jetbrains.python.PythonTestUtil; import com.jetbrains.python.fixtures.PyTestCase; import com.jetbrains.python.psi.LanguageLevel; -import org.jetbrains.annotations.Nullable; -import java.io.File; import java.io.IOException; /** @@ -197,7 +194,7 @@ public class PyRenameTest extends PyTestCase { PsiDocumentManager.getInstance(myFixture.getProject()).commitAllDocuments(); myFixture.configureFromTempProjectFile("a.py"); myFixture.renameElementAtCaret(newName); - VirtualFile dir2 = getVirtualFileByName(PythonTestUtil.getTestDataPath() + "/" + RENAME_DATA_PATH + testName + "/after"); + VirtualFile dir2 = PyTestCase.getVirtualFileByName(PythonTestUtil.getTestDataPath() + "/" + RENAME_DATA_PATH + testName + "/after"); try { PlatformTestUtil.assertDirectoriesEqual(dir2, dir1); } @@ -205,9 +202,4 @@ public class PyRenameTest extends PyTestCase { throw new RuntimeException(e); } } - - @Nullable - private static VirtualFile getVirtualFileByName(String fileName) { - return LocalFileSystem.getInstance().findFileByPath(fileName.replace(File.separatorChar, '/')); - } }