Merge branch 'python-fixes'

This commit is contained in:
Andrey Vlasovskikh
2012-05-23 20:31:04 +04:00
67 changed files with 553 additions and 108 deletions
@@ -8,14 +8,24 @@ import java.util.Set;
* @author vlan
*/
public class PyCodeFragment extends CodeFragment {
private final Set<String> myGlobals;
private final Set<String> myGlobalWrites;
private final Set<String> myNonlocalWrites;
public PyCodeFragment(final Set<String> input, final Set<String> output, final Set<String> globals, final boolean returnInside) {
public PyCodeFragment(final Set<String> input,
final Set<String> output,
final Set<String> globalWrites,
final Set<String> nonlocalWrites,
final boolean returnInside) {
super(input, output, returnInside);
myGlobals = globals;
myGlobalWrites = globalWrites;
myNonlocalWrites = nonlocalWrites;
}
public Set<String> getGlobals() {
return myGlobals;
public Set<String> getGlobalWrites() {
return myGlobalWrites;
}
public Set<String> getNonlocalWrites() {
return myNonlocalWrites;
}
}
@@ -42,11 +42,9 @@ public class PyCodeFragmentUtil {
final List<Instruction> graph = Arrays.asList(flow.getInstructions());
final List<Instruction> subGraph = getFragmentSubGraph(graph, start, end);
final AnalysisResult subGraphAnalysis = analyseSubGraph(subGraph, start, end);
if (subGraphAnalysis.regularExits > 0 && subGraphAnalysis.returns > 0) {
throw new CannotCreateCodeFragmentException(
PyBundle.message("refactoring.extract.method.error.cannot.perform.refactoring.when.execution.flow.is.interrupted"));
}
if (subGraphAnalysis.targetInstructions > 1) {
if ((subGraphAnalysis.regularExits > 0 && subGraphAnalysis.returns > 0) ||
subGraphAnalysis.targetInstructions > 1 ||
subGraphAnalysis.outerLoopBreaks > 0) {
throw new CannotCreateCodeFragmentException(
PyBundle.message("refactoring.extract.method.error.cannot.perform.refactoring.when.execution.flow.is.interrupted"));
}
@@ -56,16 +54,17 @@ public class PyCodeFragmentUtil {
}
final Set<String> globalWrites = getGlobalWrites(subGraph, owner);
final Set<String> nonlocalWrites = getNonlocalWrites(subGraph, owner);
final Set<String> inputNames = new HashSet<String>();
for (PsiElement element : filterElementsInScope(getInputElements(subGraph, graph), owner)) {
final String name = getName(element);
if (name != null) {
// Ignore "self", it is generated automatically when extracting any method fragment
if (PyPsiUtils.isMethodContext(element) && "self".equals(name)) {
// Ignore "self" and "cls", they are generated automatically when extracting any method fragment
if (resolvesToBoundMethodParameter(element)) {
continue;
}
if (globalWrites.contains(name)) {
if (globalWrites.contains(name) || nonlocalWrites.contains(name)) {
continue;
}
inputNames.add(name);
@@ -76,12 +75,41 @@ public class PyCodeFragmentUtil {
for (PsiElement element : getOutputElements(subGraph, graph)) {
final String name = getName(element);
if (name != null) {
if (globalWrites.contains(name) || nonlocalWrites.contains(name)) {
continue;
}
outputNames.add(name);
globalWrites.remove(name);
}
}
return new PyCodeFragment(inputNames, outputNames, globalWrites, subGraphAnalysis.returns > 0);
return new PyCodeFragment(inputNames, outputNames, globalWrites, nonlocalWrites, subGraphAnalysis.returns > 0);
}
private static boolean resolvesToBoundMethodParameter(@NotNull PsiElement element) {
if (PyPsiUtils.isMethodContext(element)) {
final PyFunction function = PsiTreeUtil.getParentOfType(element, PyFunction.class);
if (function != null) {
final PsiReference reference = element.getReference();
if (reference != null) {
final PsiElement resolved = reference.resolve();
if (resolved instanceof PyParameter) {
final PyParameterList parameterList = PsiTreeUtil.getParentOfType(resolved, PyParameterList.class);
if (parameterList != null) {
final PyParameter[] parameters = parameterList.getParameters();
if (parameters.length > 0) {
if (resolved == parameters[0]) {
final PyFunction.Modifier modifier = function.getModifier();
if (modifier == null || modifier == PyFunction.Modifier.CLASSMETHOD) {
return true;
}
}
}
}
}
}
}
}
return false;
}
@Nullable
@@ -135,12 +163,14 @@ public class PyCodeFragmentUtil {
private final int targetInstructions;
private final int regularExits;
private final int returns;
private final int outerLoopBreaks;
public AnalysisResult(int starImports, int targetInstructions, int returns, int regularExits) {
public AnalysisResult(int starImports, int targetInstructions, int returns, int regularExits, int outerLoopBreaks) {
this.starImports = starImports;
this.targetInstructions = targetInstructions;
this.regularExits = regularExits;
this.returns = returns;
this.outerLoopBreaks = outerLoopBreaks;
}
}
@@ -150,6 +180,7 @@ public class PyCodeFragmentUtil {
int regularSources = 0;
final Set<Instruction> targetInstructions = new HashSet<Instruction>();
int starImports = 0;
int outerLoopBreaks = 0;
for (Pair<Instruction, Instruction> edge : getOutgoingEdges(subGraph)) {
final Instruction sourceInstruction = edge.getFirst();
@@ -173,17 +204,23 @@ public class PyCodeFragmentUtil {
}
}
for (Instruction instruction : subGraph) {
final PsiElement element = instruction.getElement();
final Set<PsiElement> subGraphElements = getSubGraphElements(subGraph);
for (PsiElement element : subGraphElements) {
if (element instanceof PyFromImportStatement) {
final PyFromImportStatement fromImportStatement = (PyFromImportStatement)element;
if (fromImportStatement.getStarImportElement() != null) {
starImports++;
}
}
if (element instanceof PyContinueStatement || element instanceof PyBreakStatement) {
final PyLoopStatement loopStatement = PsiTreeUtil.getParentOfType(element, PyLoopStatement.class);
if (loopStatement != null && !subGraphElements.contains(loopStatement)) {
outerLoopBreaks++;
}
}
}
return new AnalysisResult(starImports, targetInstructions.size(), returnSources, regularSources);
return new AnalysisResult(starImports, targetInstructions.size(), returnSources, regularSources, outerLoopBreaks);
}
@NotNull
@@ -299,6 +336,21 @@ public class PyCodeFragmentUtil {
return globalWrites;
}
@NotNull
private static Set<String> getNonlocalWrites(@NotNull List<Instruction> instructions, @NotNull ScopeOwner owner) {
final Scope scope = ControlFlowCache.getScope(owner);
final Set<String> nonlocalWrites = new LinkedHashSet<String>();
for (Instruction instruction : getWriteInstructions(instructions)) {
if (instruction instanceof ReadWriteInstruction) {
final String name = ((ReadWriteInstruction)instruction).getName();
if (scope.isNonlocal(name)) {
nonlocalWrites.add(name);
}
}
}
return nonlocalWrites;
}
@NotNull
private static List<PsiElement> multiResolve(@NotNull PsiReference reference) {
if (reference instanceof PsiPolyVariantReference) {
@@ -310,6 +362,11 @@ public class PyCodeFragmentUtil {
resolved.add(element);
}
}
for (PsiElement element : resolved) {
if (element instanceof PyClass) {
return Collections.singletonList(element);
}
}
return resolved;
}
final PsiElement element = reference.resolve();
@@ -34,16 +34,17 @@ import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.PythonLanguage;
import com.jetbrains.python.codeInsight.codeFragment.PyCodeFragment;
import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache;
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.psi.*;
import com.jetbrains.python.psi.impl.PyFunctionBuilder;
import com.jetbrains.python.psi.impl.PyPsiUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
/**
* @author oleg
@@ -101,8 +102,8 @@ public class PyExtractMethodUtil {
final PsiElement firstElement = elementsRange.get(0);
final boolean isMethod = PyPsiUtils.isMethodContext(firstElement);
processParameters(project, generatedMethod, variableData, isMethod, isClassMethod, isStaticMethod);
processGlobalWrites(generatedMethod, fragment);
processNonlocalWrites(generatedMethod, fragment);
// Generating call element
final StringBuilder builder = new StringBuilder();
@@ -152,8 +153,8 @@ public class PyExtractMethodUtil {
// Process parameters
final boolean isMethod = PyPsiUtils.isMethodContext(elementsRange.get(0));
processParameters(project, generatedMethod, variableData, isMethod, isClassMethod, isStaticMethod);
processGlobalWrites(generatedMethod, fragment);
processNonlocalWrites(generatedMethod, fragment);
// Generate call element
builder.append(" = ");
@@ -177,12 +178,19 @@ public class PyExtractMethodUtil {
}
private static void processGlobalWrites(@NotNull PyFunction function, @NotNull PyCodeFragment fragment) {
final Set<String> globals = fragment.getGlobals();
if (!globals.isEmpty()) {
final Set<String> globalWrites = fragment.getGlobalWrites();
final Set<String> newGlobalNames = new LinkedHashSet<String>();
final Scope scope = ControlFlowCache.getScope(function);
for (String name : globalWrites) {
if (!scope.isGlobal(name)) {
newGlobalNames.add(name);
}
}
if (!newGlobalNames.isEmpty()) {
final PyElementGenerator generator = PyElementGenerator.getInstance(function.getProject());
final PyGlobalStatement globalStatement = generator.createFromText(LanguageLevel.forElement(function),
PyGlobalStatement.class,
"global " + StringUtil.join(globals, ", "));
"global " + StringUtil.join(newGlobalNames, ", "));
final PyStatementList statementList = function.getStatementList();
if (statementList != null) {
statementList.addBefore(globalStatement, statementList.getFirstChild());
@@ -190,6 +198,28 @@ public class PyExtractMethodUtil {
}
}
private static void processNonlocalWrites(@NotNull PyFunction function, @NotNull PyCodeFragment fragment) {
final Set<String> nonlocalWrites = fragment.getNonlocalWrites();
final Set<String> newNonlocalNames = new LinkedHashSet<String>();
final Scope scope = ControlFlowCache.getScope(function);
for (String name : nonlocalWrites) {
if (!scope.isNonlocal(name)) {
newNonlocalNames.add(name);
}
}
if (!newNonlocalNames.isEmpty()) {
final PyElementGenerator generator = PyElementGenerator.getInstance(function.getProject());
final PyNonlocalStatement nonlocalStatement = generator.createFromText(LanguageLevel.forElement(function),
PyNonlocalStatement.class,
"nonlocal " + StringUtil.join(newNonlocalNames, ", "));
final PyStatementList statementList = function.getStatementList();
if (statementList != null) {
statementList.addBefore(nonlocalStatement, statementList.getFirstChild());
}
}
}
private static void appendSelf(PsiElement firstElement, StringBuilder builder, boolean staticMethod) {
if (staticMethod) {
final PyClass containingClass = PsiTreeUtil.getParentOfType(firstElement, PyClass.class);
@@ -523,7 +553,13 @@ public class PyExtractMethodUtil {
public PyExtractMethodValidator(final PsiElement element, final Project project) {
myElement = element;
myProject = project;
final PsiNamedElement parent = PsiTreeUtil.getParentOfType(myElement, PyFile.class, PyClass.class);
ScopeOwner owner = ScopeUtil.getScopeOwner(myElement);
if (owner instanceof PyFunction) {
owner = ScopeUtil.getScopeOwner(owner);
}
final ScopeOwner parent = owner;
if (parent instanceof PyFile){
final List<PyFunction> functions = ((PyFile)parent).getTopLevelFunctions();
myFunction = new Function<String, Boolean>() {
@@ -536,14 +572,24 @@ public class PyExtractMethodUtil {
return true;
}
};
} else
if (parent instanceof PyClass){
}
else if (parent instanceof PyClass){
myFunction = new Function<String, Boolean>() {
public Boolean fun(@NotNull final String s) {
return ((PyClass) parent).findMethodByName(s, true) == null;
}
};
} else {
}
else if (parent instanceof PyFunction) {
final Scope scope = ControlFlowCache.getScope(parent);
myFunction = new Function<String, Boolean>() {
@Override
public Boolean fun(String s) {
return !scope.containsDeclaration(s);
}
};
}
else {
myFunction = null;
}
}
-1
View File
@@ -1 +0,0 @@
__author__ = 'user'
@@ -1,8 +1,9 @@
print("start")
<begin>
import foo
<end>
foo.bar
def foo():
print("start")
<begin>
import foo
<end>
foo.bar
<result>
In:
Out:
@@ -1,8 +1,9 @@
print("start")
<begin>
aaa = 123
<end>
print(aaa)
def foo():
print("start")
<begin>
aaa = 123
<end>
print(aaa)
<result>
In:
Out:
@@ -0,0 +1,4 @@
def foo():
return bbb
aaa = foo() && ccc
@@ -0,0 +1 @@
aaa = <selection>bbb</selection> && ccc
@@ -0,0 +1,6 @@
def bar(r_new):
return PI * r_new ** 2
def cylinder_volume(r, h):
h * bar(r)
@@ -0,0 +1,2 @@
def cylinder_volume(r, h):
h * <selection>PI * r ** 2</selection>
@@ -0,0 +1,5 @@
class PyCharm:
def bar():
print("Hello Pycharm!")
bar()
@@ -0,0 +1,2 @@
class PyCharm:
<selection>print("Hello Pycharm!")</selection>
@@ -1,8 +1,8 @@
class C:
@classmethod
def baz(cls):
print "hello world"
print('foo', cls)
@classmethod
def foo(cls):
cls.baz()
cls.baz()
@@ -0,0 +1,4 @@
class C:
@classmethod
def foo(cls):
<selection>print('foo', cls)</selection>
@@ -0,0 +1,11 @@
def bar():
class C(object):
pass
c = C()
return c
def foo():
c = bar()
return c
@@ -0,0 +1,5 @@
def foo():
<selection>class C(object):
pass
c = C()</selection>
return c
@@ -0,0 +1,8 @@
def plus(a_new, b_new):
return a_new + b_new * 123
def f():
a = 1
b = 1
c = plus(a, b)
@@ -0,0 +1,4 @@
def f():
a = 1
b = 1
c = <selection>a + b * 123</selection>
@@ -0,0 +1,4 @@
def foo(xs):
for x in xs:
<selection>if not x:
continue</selection>
@@ -1,10 +1,10 @@
a = 2
b = 3
def bar():
global a
a = a + 1
global a, c
a = a + b
c = a * 2
return c
c = bar()
bar()
print(c)
@@ -1,4 +1,5 @@
a = 2
<selection>a = a + 1
b = 3
<selection>a = a + b
c = a * 2</selection>
print(c)
@@ -0,0 +1,7 @@
class C:
def bar(self):
for x in [1, 2]:
print x
def foo(self):
self.bar()
@@ -0,0 +1,4 @@
class C:
def foo(self):
<selection>for x in [1, 2]:
print x</selection>
@@ -0,0 +1,8 @@
class Foo(X, Y, Z):
def bar(self, base_new):
try: base_new.__init__(self)
except AttributeError: pass
def __init__(self):
for base in self__class__.__bases__:
self.bar(base)
@@ -0,0 +1,5 @@
class Foo(X, Y, Z):
def __init__(self):
for base in self__class__.__bases__:
<selection>try: base.__init__(self)
except AttributeError: pass</selection>
@@ -0,0 +1,9 @@
class C:
def bar(self):
if (self.cond):
return 1
else:
return 2
def foo(self):
return self.bar()
@@ -0,0 +1,6 @@
class C:
def foo(self):
<selection>if (self.cond):
return 1
else:
return 2</selection>
@@ -0,0 +1,5 @@
class A:
def hello():
pass
<selection>print("Hello")</selection>
@@ -0,0 +1,4 @@
def hello():
pass
<selection>print("Hello")</selection>
@@ -0,0 +1,7 @@
class A:
def hello(self):
pass
class B(A):
def foo(self):
<selection>print("Hello")</selection>
@@ -0,0 +1,13 @@
def foo():
x = 1
def baz():
nonlocal x
x = 2
def bar():
nonlocal x
baz()
print(x)
bar()
foo()
@@ -0,0 +1,8 @@
def foo():
x = 1
def bar():
nonlocal x
<selection>x = 2</selection>
print(x)
bar()
foo()
@@ -0,0 +1,12 @@
def sum_squares(a_new, result_new):
while a_new < 10:
result_new += a_new * a_new
a_new += 1
return result_new
def f():
a = 10
result = 0
result = sum_squares(a, result)
print("Sum of squares: " + result)
@@ -0,0 +1,7 @@
def f():
a = 10
result = 0
<selection>while a < 10:
result += a * a
a += 1</selection>
print("Sum of squares: " + result)
@@ -0,0 +1,12 @@
def sum_squares(a_new):
result = 0
while a_new < 10:
result += a_new * a_new
a_new += 1
return a_new, result
def f():
a = 1
a, result = sum_squares(a)
print("Sum of squares: " + a + " = " + result)
@@ -0,0 +1,7 @@
def f():
a = 1
<selection>result = 0
while a < 10:
result += a * a
a += 1</selection>
print("Sum of squares: " + a + " = " + result)
@@ -0,0 +1,6 @@
def bar(a_new):
print(a_new)
def foo(a):
bar(a)
@@ -0,0 +1,2 @@
def foo(a):
<selection>print(a)</selection>
@@ -0,0 +1,25 @@
class Foo:
def __init__(self):
self.tmp = False
def bar(self, condition3_new, condition4_new):
self.tmp2 = True
if condition3_new:
print(condition3_new)
if condition4_new:
print(condition4_new)
print("misterious extract method test")
def extract_method(self, condition1, condition2, condition3, condition4):
list = (1, 2, 3)
a = 6
b = False
if a in list or self.tmp:
if condition1:
print(condition1)
if b is not condition2:
print(b)
else:
self.bar(condition3, condition4)
f = Foo()
f.extract_method(True, True, True, True)
@@ -0,0 +1,22 @@
class Foo:
def __init__(self):
self.tmp = False
def extract_method(self, condition1, condition2, condition3, condition4):
list = (1, 2, 3)
a = 6
b = False
if a in list or self.tmp:
if condition1:
print(condition1)
if b is not condition2:
print(b)
else:
<selection>self.tmp2 = True
if condition3:
print(condition3)
if condition4:
print(condition4)
print("misterious extract method test")</selection>
f = Foo()
f.extract_method(True, True, True, True)
@@ -0,0 +1,8 @@
def foo(a_new, b_new):
print(a_new + b_new * 123)
def f():
a = 1
b = 1
foo(a, b)
@@ -0,0 +1,4 @@
def f():
a = 1
b = 1
<selection>print(a + b * 123)</selection>
@@ -0,0 +1,10 @@
def foo():
if foo():
return -1
else:
return 1
return foo()
bar
@@ -0,0 +1,8 @@
<selection>
if foo():
return -1
else:
return 1
</selection>
bar
@@ -0,0 +1,10 @@
def foo(a_new, b_new):
puts(a_new + b_new * 123)
print("Hello from extract method")
def f():
a = 1
b = 1
foo(a, b)
@@ -0,0 +1,6 @@
def f():
a = 1
b = 1
<selection>puts(a + b * 123)
print("Hello from extract method")</selection>
@@ -0,0 +1,11 @@
def bar(a_new):
do_smth
a_new += 1
return a_new
def f():
a = 1
while a < 10:
a = bar(a)
print(a)
@@ -0,0 +1,6 @@
def f():
a = 1
while a < 10:
<selection>do_smth
a+=1</selection>
print(a)
@@ -0,0 +1 @@
<selection>from mymodule import *</selection>
@@ -0,0 +1,13 @@
class Settings(patterns.Observer, UnicodeAwareConfigParser):
def __init__(self):
pass
def set(self, section, option, value, new=False):
<selection>if new:
currentValue = 'a new option, so use something as current value'\
' that is unlikely to be equal to the new value'</selection>
else:
currentValue = self.get(section, option)
if value != currentValue:
patterns.Event('before.%s.%s'%(section, option), self, value).send()
super(Settings, self).set(section, option, value)
patterns.Event('%s.%s'%(section, option), self, value).send()
@@ -1,4 +0,0 @@
class C:
@classmethod
def foo(cls):
<selection>print "hello world"</selection>
@@ -1,162 +1,179 @@
package com.jetbrains.python.refactoring;
import com.intellij.lang.LanguageRefactoringSupport;
import com.intellij.lang.refactoring.RefactoringSupportProvider;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.refactoring.RefactoringActionHandler;
import com.jetbrains.python.PythonLanguage;
import com.jetbrains.python.fixtures.LightMarkedTestCase;
import com.jetbrains.python.psi.LanguageLevel;
import com.jetbrains.python.refactoring.extractmethod.PyExtractMethodUtil;
/**
* @author oleg
*/
public class PyExtractMethodTest extends LightMarkedTestCase {
private void doTest(final String testPath,
final String name,
final String result) {
myFixture.configureByFile("/refactoring/extractmethod/" + testPath);
final RefactoringActionHandler handler = LanguageRefactoringSupport.INSTANCE.forLanguage(PythonLanguage.getInstance()).getExtractMethodHandler();
private void doTest(String newName, LanguageLevel level) {
setLanguageLevel(level);
try {
System.setProperty(PyExtractMethodUtil.NAME, name);
try {
handler.invoke(myFixture.getProject(), myFixture.getEditor(), myFixture.getFile(), ((EditorEx) myFixture.getEditor()).getDataContext());
}
catch (Exception e) {
if (result.endsWith(".py")) { // expected output file, not an exception
e.printStackTrace();
}
assertEquals(result, e.getMessage());
return;
}
} finally {
System.clearProperty(PyExtractMethodUtil.NAME);
doTest(newName);
}
finally {
setLanguageLevel(null);
}
myFixture.checkResultByFile("/refactoring/extractmethod/" + result);
}
private void doTest(String newName) {
final String testName = getTestName(false);
doTest(testName + ".before.py", newName, testName + ".after.py");
final String beforeName = testName + ".before.py";
final String afterName = testName + ".after.py";
final String dir = "refactoring/extractmethod/";
myFixture.configureByFile(dir + beforeName);
final RefactoringSupportProvider provider = LanguageRefactoringSupport.INSTANCE.forLanguage(PythonLanguage.getInstance());
assertNotNull(provider);
final RefactoringActionHandler handler = provider.getExtractMethodHandler();
assertNotNull(handler);
final Editor editor = myFixture.getEditor();
assertInstanceOf(editor, EditorEx.class);
System.setProperty(PyExtractMethodUtil.NAME, newName);
try {
handler.invoke(myFixture.getProject(), editor, myFixture.getFile(), ((EditorEx)editor).getDataContext());
}
finally {
System.clearProperty(PyExtractMethodUtil.NAME);
}
myFixture.checkResultByFile(dir + afterName);
}
private void doFail(String newName, String message) {
try {
doTest(newName);
}
catch (Exception e) {
assertEquals(message, e.getMessage());
return;
}
fail("No exception was thrown");
}
public void testParameter() {
doTest("outEmpty/parameter.before.py", "bar", "outEmpty/parameter.after.py");
doTest("bar");
}
public void testBreakAst() {
doTest("outEmpty/break_ast.before.py", "bar", "outEmpty/break_ast.after.py");
doTest("bar");
}
public void testExpression() {
doTest("outEmpty/expression.before.py", "plus", "outEmpty/expression.after.py");
doTest("plus");
}
public void testStatement() {
doTest("outEmpty/statement.before.py", "foo", "outEmpty/statement.after.py");
doTest("foo");
}
public void testStatements() {
doTest("outEmpty/statements.before.py", "foo", "outEmpty/statements.after.py");
doTest("foo");
}
public void testStatementReturn() {
doTest("outEmpty/statement_return.before.py", "foo", "outEmpty/statement_return.after.py");
doTest("foo");
}
public void testBinaryExpression() {
doTest("controlFlow/binary_expr.before.py", "foo", "controlFlow/binary_expr.after.py");
doTest("foo");
}
public void testWhileOutput() {
doTest("controlFlow/while_output.before.py", "bar", "controlFlow/while_output.after.py");
doTest("bar");
}
public void testNameCollisionClass() {
doTest("namesCollision/class.before.py", "hello", "Method name clashes with already existing method name");
doFail("hello", "Method name clashes with already existing method name");
}
public void testNameCollisionFile() {
doTest("namesCollision/file.before.py", "hello", "Method name clashes with already existing method name");
doFail("hello", "Method name clashes with already existing method name");
}
public void testNameCollisionSuperClass() {
doTest("namesCollision/superclass.before.py", "hello", "Method name clashes with already existing method name");
doFail("hello", "Method name clashes with already existing method name");
}
public void testOutNotEmptyStatements() {
doTest("outNotEmpty/statements.before.py", "sum_squares", "outNotEmpty/statements.after.py");
doTest("sum_squares");
}
public void testOutNotEmptyStatements2() {
doTest("outNotEmpty/statements2.before.py", "sum_squares", "outNotEmpty/statements2.after.py");
doTest("sum_squares");
}
// PY-2903
public void _testComment() {
doTest("comment.before.py", "bar", "comment.after.py");
doTest("bar");
}
public void testFile() {
doTest("file.before.py", "bar", "file.after.py");
doTest("bar");
}
public void testMethod() {
doTest("context/method.before.py", "bar", "context/method.after.py");
public void testMethodContext() {
doTest("bar");
}
public void testMethodIndent() {
doTest("context/methodindent.before.py", "bar", "context/methodindent.after.py");
doTest("bar");
}
public void testMethodReturn() {
doTest("context/methodreturn.before.py", "bar", "context/methodreturn.after.py");
doTest("bar");
}
public void testWrongSelectionIfPart() {
doTest("wrongSelection/ifpart.before.py", "bar", "Cannot perform extract method using selected element(s)");
doFail("bar", "Cannot perform extract method using selected element(s)");
}
public void testFromImportStatement() {
doTest("wrongSelection/fromimport.before.py", "bar", "Cannot perform refactoring with from import statement inside code block");
public void testWrongSelectionFromImportStar() {
doFail("bar", "Cannot perform refactoring with from import statement inside code block");
}
public void testPy479() {
doTest("outEmpty/py479.before.py", "bar", "outEmpty/py479.after.py");
doTest("bar");
}
public void testClass() {
doTest("context/class.before.py", "bar", "context/class.after.py");
public void testClassContext() {
doTest("bar");
}
public void testConditionalReturn() {
doTest("conditionalreturn.before.py", "bar", "Cannot perform refactoring when execution flow is interrupted");
doFail("bar", "Cannot perform refactoring when execution flow is interrupted");
}
public void testReturnTuple() {
doTest("return_tuple.before.py", "bar", "return_tuple.after.py");
doTest("bar");
}
public void testComment2() {
doTest("comment2.before.py", "baz", "comment2.after.py");
doTest("baz");
}
public void testElseBody() {
doTest("elsebody.before.py", "baz", "elsebody.after.py");
doTest("baz");
}
public void testClassMethod() {
doTest("classmethod.before.py", "baz", "classmethod.after.py");
doTest("baz");
}
public void testStaticMethod() {
doTest("staticmethod.before.py", "baz", "staticmethod.after.py");
doTest("baz");
}
// PY-5123
public void testMethodInIf() {
doTest("methodInIf.before.py", "baz", "methodInIf.after.py");
doTest("baz");
}
// PY-6081
@@ -203,4 +220,19 @@ public class PyExtractMethodTest extends LightMarkedTestCase {
public void testGlobalToplevelAssignment() {
doTest("bar");
}
// PY-6623
public void testForLoopContinue() {
doFail("bar", "Cannot perform refactoring when execution flow is interrupted");
}
// PY-6622
public void testClassWithoutInit() {
doTest("bar");
}
// PY-6625
public void testNonlocal() {
doTest("baz", LanguageLevel.PYTHON30);
}
}