From 70d3040b0834d1f58c9273bdd64af6c2e2524b7c Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Tue, 8 Oct 2013 20:30:05 +0400 Subject: [PATCH] fixed PY-10976 Method override in nested class generated with incorrect super call --- .../override/PyOverrideImplementUtil.java | 12 +++++++++++- python/testData/override/innerClass.py | 6 ++++++ python/testData/override/innerClass_after.py | 9 +++++++++ .../com/jetbrains/python/PyOverrideTest.java | 13 +++++++++++++ 4 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 python/testData/override/innerClass.py create mode 100644 python/testData/override/innerClass_after.py diff --git a/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java b/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java index 64f2466618af..66a5fb58b931 100644 --- a/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java +++ b/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java @@ -1,5 +1,6 @@ package com.jetbrains.python.codeInsight.override; +import com.google.common.collect.Lists; import com.intellij.codeInsight.CodeInsightUtilCore; import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.featureStatistics.ProductivityFeatureNames; @@ -217,7 +218,16 @@ public class PyOverrideImplementUtil { if (!langLevel.isPy3K()) { final String baseFirstName = !baseParams.isEmpty() ? baseParams.get(0).getName() : null; final String firstName = baseFirstName != null ? baseFirstName : PyNames.CANONICAL_SELF; - statementBody.append(pyClass.getName()).append(", ").append(firstName); + PsiElement outerClass = PsiTreeUtil.getParentOfType(pyClass, PyClass.class, true); + String className = pyClass.getName(); + final List nameResult = Lists.newArrayList(className); + while(outerClass instanceof PyClass) { + nameResult.add(0, ((PyClass)outerClass).getName()); + outerClass = PsiTreeUtil.getParentOfType(outerClass, PyClass.class, true); + } + + className = StringUtil.join(nameResult, "."); + statementBody.append(className).append(", ").append(firstName); } statementBody.append(").").append(baseFunction.getName()).append("("); if (parameters.size() > 0) { diff --git a/python/testData/override/innerClass.py b/python/testData/override/innerClass.py new file mode 100644 index 000000000000..2fdb2ed9bd8d --- /dev/null +++ b/python/testData/override/innerClass.py @@ -0,0 +1,6 @@ +class X(object): + def foo(self): pass + +class Outer(object): + class Inner(X): + pass \ No newline at end of file diff --git a/python/testData/override/innerClass_after.py b/python/testData/override/innerClass_after.py new file mode 100644 index 000000000000..1c535a4756b2 --- /dev/null +++ b/python/testData/override/innerClass_after.py @@ -0,0 +1,9 @@ +class X(object): + def foo(self): pass + +class Outer(object): + class Inner(X): + def foo(self): + super(Outer.Inner, self).foo() + + \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyOverrideTest.java b/python/testSrc/com/jetbrains/python/PyOverrideTest.java index 3ee4a60a67b0..02d8b0454dda 100644 --- a/python/testSrc/com/jetbrains/python/PyOverrideTest.java +++ b/python/testSrc/com/jetbrains/python/PyOverrideTest.java @@ -1,5 +1,7 @@ package com.jetbrains.python; +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; import com.jetbrains.python.codeInsight.override.PyMethodMember; import com.jetbrains.python.codeInsight.override.PyOverrideImplementUtil; import com.jetbrains.python.fixtures.PyTestCase; @@ -63,6 +65,17 @@ public class PyOverrideTest extends PyTestCase { doTest(); } + public void testInnerClass() { // PY-10976 + myFixture.configureByFile("override/" + getTestName(true) + ".py"); + PyFunction toOverride = getTopLevelClass(0).getMethods()[0]; + final PsiElement element = myFixture.getElementAtCaret(); + PyClass pyClass = PsiTreeUtil.getParentOfType(element, PyClass.class, false); + assertNotNull(pyClass); + PyOverrideImplementUtil.overrideMethods(myFixture.getEditor(), pyClass, + Collections.singletonList(new PyMethodMember(toOverride))); + myFixture.checkResultByFile("override/" + getTestName(true) + "_after.py", true); + } + public void testQualified() { // PY-2171 myFixture.configureByFile("override/" + getTestName(true) + ".py"); PyClass dateClass = PyClassNameIndex.findClass("datetime.date", myFixture.getProject());