correctly return implicit superclass in the list of superclasses for both Py2 and Py3 (PY-1494); add mock SDK for Python 3.1

This commit is contained in:
Dmitry Jemerov
2010-08-17 21:35:44 +04:00
parent cb59df9887
commit 97cfc9984d
10 changed files with 88 additions and 41 deletions
@@ -28,7 +28,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.*;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* Provides access to Python builtins via skeletons.
@@ -207,31 +207,26 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
return Collections.emptyList();
}
List<PyClass> stubSuperClasses = resolveSuperClassesFromStub();
if (stubSuperClasses != null) {
return stubSuperClasses;
}
PsiElement[] superClassElements = getSuperClassElements();
if (superClassElements.length > 0) {
List<PyClass> result = new ArrayList<PyClass>();
// maybe a bare old-style class?
// TODO: depend on language version: py3k does not do old style classes
PsiElement paren = PsiTreeUtil.getChildOfType(this, PyArgumentList.class).getFirstChild(); // no NPE, we always have the par expr
if (paren != null && "(".equals(paren.getText())) { // "()" after class name, it's new style
for (PsiElement element : superClassElements) {
if (element instanceof PyClass) {
result.add((PyClass)element);
}
List<PyClass> superClasses = resolveSuperClassesFromStub();
if (superClasses == null) {
superClasses = new ArrayList<PyClass>();
PsiElement[] superClassElements = getSuperClassElements();
for (PsiElement element : superClassElements) {
if (element instanceof PyClass) {
superClasses.add((PyClass)element);
}
}
else if (!PyBuiltinCache.BUILTIN_FILE.equals(getContainingFile().getName())) { // old-style *and* not builtin object()
PyClass oldstyler = PyBuiltinCache.getInstance(this).getClass(PyNames.FAKE_OLD_BASE);
if (oldstyler != null) result.add(oldstyler);
}
return result;
}
return Collections.emptyList();
if (superClasses.size() == 0 && !PyBuiltinCache.getInstance(this).hasInBuiltins(this)) {
String implicitSuperclassName = LanguageLevel.forElement(this).isPy3K() ? PyNames.OBJECT : PyNames.FAKE_OLD_BASE;
PyClass implicitSuperclass = PyBuiltinCache.getInstance(this).getClass(implicitSuperclassName);
if (implicitSuperclass != null) {
superClasses.add(implicitSuperclass);
}
}
return superClasses;
}
@Nullable
+9
View File
@@ -0,0 +1,9 @@
class A:
x = 1
y = 1
class B(A):
def foo(self):
self.__repr__()
# <ref>
@@ -0,0 +1,43 @@
package com.jetbrains.python;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.testFramework.LightProjectDescriptor;
import com.jetbrains.python.fixtures.PyResolveTestCase;
import com.jetbrains.python.psi.LanguageLevel;
import com.jetbrains.python.psi.PyFunction;
import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher;
/**
* @author yole
*/
public class Py3ResolveTest extends PyResolveTestCase {
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return ourPy3Descriptor;
}
@Override
protected PsiElement doResolve() {
myFixture.configureByFile("resolve/" + getTestName(false) + ".py");
int offset = findMarkerOffset(myFixture.getFile());
final PsiReference ref = myFixture.getFile().findReferenceAt(offset);
return ref.resolve();
}
@Override
protected void setUp() throws Exception {
super.setUp();
PythonLanguageLevelPusher.setForcedLanguageLevel(myFixture.getProject(), LanguageLevel.PYTHON31);
}
@Override
protected void tearDown() throws Exception {
PythonLanguageLevelPusher.setForcedLanguageLevel(myFixture.getProject(), null);
super.tearDown();
}
public void testObjectMethods() { // PY-1494
assertResolvesTo(PyFunction.class, "__repr__");
}
}
@@ -35,7 +35,6 @@ public class PyPropertyTestSuite {
super.setUp();
PsiReference ref = myFixture.getReferenceAtCaretPosition("property/"+ getFileName());
final Project project = ref.getElement().getContainingFile().getProject();
project.putUserData(PyBuiltinCache.TEST_SDK, PythonMockSdk.findOrCreate());
PythonLanguageLevelPusher.setForcedLanguageLevel(project, myLanguageLevel);
PsiElement elt = ref.resolve();
assertInstanceOf(elt, PyExpression.class);
@@ -1,6 +1,5 @@
package com.jetbrains.python;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiPolyVariantReference;
import com.intellij.psi.PsiReference;
@@ -8,7 +7,6 @@ import com.intellij.psi.ResolveResult;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.python.fixtures.PyResolveTestCase;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher;
import com.jetbrains.python.psi.resolve.ImportedResolveResult;
@@ -16,8 +14,6 @@ public class PyResolveTest extends PyResolveTestCase {
@Override
protected PsiElement doResolve() {
myFixture.configureByFile("resolve/" + getTestName(false) + ".py");
final Project project = myFixture.getProject();
project.putUserData(PyBuiltinCache.TEST_SDK, PythonMockSdk.findOrCreate());
int offset = findMarkerOffset(myFixture.getFile());
final PsiReference ref = myFixture.getFile().findReferenceAt(offset);
return ref.resolve();
@@ -25,8 +21,6 @@ public class PyResolveTest extends PyResolveTestCase {
protected PsiElement resolve() {
PsiReference ref = configureByFile("resolve/" + getTestName(false) + ".py");
final Project project = ref.getElement().getContainingFile().getProject();
project.putUserData(PyBuiltinCache.TEST_SDK, PythonMockSdk.findOrCreate());
// if need be: PythonLanguageLevelPusher.setForcedLanguageLevel(project, LanguageLevel.PYTHON26);
return ref.resolve();
}
@@ -15,7 +15,6 @@ import com.intellij.testFramework.TestDataPath;
import com.intellij.util.indexing.FileBasedIndex;
import com.jetbrains.python.fixtures.PyLightFixtureTestCase;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
import com.jetbrains.python.psi.impl.PyFileImpl;
import com.jetbrains.python.psi.impl.PyQualifiedName;
import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher;
@@ -42,7 +41,6 @@ public class PyStubsTest extends PyLightFixtureTestCase {
final PyFile file = getTestFile();
// vfile is problematic, but we need an SDK to check builtins
final Project project = file.getProject();
project.putUserData(PyBuiltinCache.TEST_SDK, PythonMockSdk.findOrCreate());
try {
PythonLanguageLevelPusher.setForcedLanguageLevel(project, LanguageLevel.PYTHON26); // we need 2.6+ for @foo.setter
@@ -24,6 +24,7 @@ public class PythonAllTestsSuite {
PythonHighlightingTest.class,
PyStubsTest.class,
PyResolveTest.class,
Py3ResolveTest.class,
PyMultiFileResolveTest.class,
PyResolveCalleeTest.class,
PyAssignmentMappingTest.class,
@@ -1,6 +1,5 @@
package com.jetbrains.python;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkModificator;
@@ -19,25 +18,24 @@ import java.util.List;
public class PythonMockSdk {
@NonNls private static final String MOCK_SDK_NAME = "Mock Python SDK";
public static Sdk findOrCreate() {
public static Sdk findOrCreate(String version) {
final List<Sdk> sdkList = ProjectJdkTable.getInstance().getSdksOfType(PythonSdkType.getInstance());
for (Sdk sdk : sdkList) {
if (sdk.getName().equals(MOCK_SDK_NAME)) {
if (sdk.getName().equals(MOCK_SDK_NAME + " " + version)) {
return sdk;
}
}
return create();
return create(version);
}
public static Sdk create() {
final String version = "2.5"; // TODO: implement language level here
public static Sdk create(final String version) {
final String mock_path = PythonTestUtil.getTestDataPath() + "/MockSdk" + version + "/";
String sdkHome = new File(mock_path, "bin/python"+version).getPath();
SdkType sdkType = PythonSdkType.getInstance();
final Sdk sdk = new ProjectJdkImpl(MOCK_SDK_NAME, sdkType) {
final Sdk sdk = new ProjectJdkImpl(MOCK_SDK_NAME + " " + version, sdkType) {
@Override
public String getVersionString() {
return "Python " + version + " Mock SDK";
@@ -25,7 +25,8 @@ import org.jetbrains.annotations.Nullable;
*/
@TestDataPath("$CONTENT_ROOT/../testData/")
public abstract class PyLightFixtureTestCase extends UsefulTestCase {
private static final PyLightProjectDescriptor ourPyDescriptor = new PyLightProjectDescriptor();
private static final PyLightProjectDescriptor ourPyDescriptor = new PyLightProjectDescriptor("2.5");
protected static final PyLightProjectDescriptor ourPy3Descriptor = new PyLightProjectDescriptor("3.1");
protected CodeInsightTestFixture myFixture;
private static boolean ourPlatformPrefixInitialized;
@@ -74,12 +75,18 @@ public abstract class PyLightFixtureTestCase extends UsefulTestCase {
}
protected static class PyLightProjectDescriptor implements LightProjectDescriptor {
private final String myPythonVersion;
public PyLightProjectDescriptor(String pythonVersion) {
myPythonVersion = pythonVersion;
}
public ModuleType getModuleType() {
return EmptyModuleType.getInstance();
}
public Sdk getSdk() {
return PythonMockSdk.findOrCreate();
return PythonMockSdk.findOrCreate(myPythonVersion);
}
public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) {