mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-05 01:50:56 +07:00
Revert "Revert "Merge branch 'master' of git.labs.intellij.net:idea/ultimate""
This reverts commit 3a2ad1f6c248ce02e860be14b796981de7ccfeee.
This commit is contained in:
@@ -26,7 +26,7 @@ if [ -z "$PYCHARM_JDK" ]; then
|
||||
fi
|
||||
if [ -z "$PYCHARM_JDK" ]; then
|
||||
echo ERROR: cannot start PyCharm.
|
||||
echo No JDK found to run PyCharm. Please validate either PYCHARM_JDK, JDK_HOME or JAVA_HOME points to valid JDK installation.
|
||||
echo No JDK found to run PyCharm. Please validate either PYCHARM_JDK, JDK_HOME or JAVA_HOME environment variable points to valid JDK installation.
|
||||
echo
|
||||
echo Press Enter to continue.
|
||||
read IGNORE
|
||||
@@ -47,7 +47,7 @@ if [ $OPEN_JDK -eq 0 ]; then
|
||||
echo THIS IS STRICTLY UNSUPPORTED DUE TO KNOWN PERFORMANCE AND GRAPHICS PROBLEMS
|
||||
echo
|
||||
echo NOTE: If you have both Sun JDK and OpenJDK installed
|
||||
echo please validate either PYCHARM_JDK or JDK_HOME points to valid Sun JDK installation
|
||||
echo please validate either PYCHARM_JDK or JDK_HOME environment variable points to valid Sun JDK installation
|
||||
echo
|
||||
echo Press Enter to continue.
|
||||
read IGNORE
|
||||
|
||||
@@ -280,7 +280,7 @@ def build_searchable_options() {
|
||||
ant.copy(file: "$home/build/idea.license", todir: paths.ideaSystem)
|
||||
ant.copy(file: "$home/build/pycharm.license", todir: paths.ideaSystem)
|
||||
ant.java(classname: "com.intellij.idea.Main", fork: "true") {
|
||||
jvmarg(line: "-ea -Xmx250m -Didea.home.path=$home -Didea.system.path=${paths.ideaSystem} -Didea.config.path=${paths.ideaConfig} -Didea.platform.prefix=Python")
|
||||
jvmarg(line: "-ea -Xmx250m -Didea.home.path=$home -Didea.system.path=${paths.ideaSystem} -Didea.config.path=${paths.ideaConfig} -Didea.platform.prefix=Python -Didea.no.jre.check=true")
|
||||
jvmarg(value: "-Xbootclasspath/a:${boot.output}")
|
||||
arg(line: "traverseUI ${dest_dir}/searchableOptions.xml")
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ settings_file = os.getenv('PYCHARM_DJANGO_SETTINGS_MODULE')
|
||||
if not settings_file:
|
||||
settings_file = 'settings'
|
||||
|
||||
print ("Importing Django settings module " + settings_file)
|
||||
|
||||
try:
|
||||
settings_module = __import__(settings_file)
|
||||
|
||||
@@ -19,4 +21,3 @@ except ImportError:
|
||||
|
||||
TEST_RUNNER = 'pycharm.django_test_runner.run_tests'
|
||||
|
||||
print ("pycharm django settings imported") # XXX
|
||||
@@ -69,8 +69,10 @@ class TeamcityTestResult(TestResult):
|
||||
error_value = err[1][0]
|
||||
|
||||
if error_value.startswith("'") or error_value.startswith('"'):
|
||||
first = self.find_first(err[1][0])
|
||||
second = self.find_second(err[1][0])
|
||||
# let's unescape strings to show sexy multiline diff in PyCharm.
|
||||
# By default all caret return chars are escaped by testing framework
|
||||
first = self._unescape(self.find_first(err[1][0]))
|
||||
second = self._unescape(self.find_second(err[1][0]))
|
||||
else:
|
||||
first = second = ""
|
||||
err = self.formatErr(err)
|
||||
@@ -118,6 +120,9 @@ class TeamcityTestResult(TestResult):
|
||||
self.messages.testSuiteFinished(self.current_suite)
|
||||
self.current_suite = None
|
||||
|
||||
def _unescape(self, text):
|
||||
return text.decode('string_escape')
|
||||
|
||||
class TeamcityTestRunner:
|
||||
def __init__(self, stream=sys.stdout):
|
||||
self.stream = stream
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
<orderEntry type="module" module-name="sass" scope="RUNTIME" />
|
||||
<orderEntry type="module" module-name="dom-impl" scope="RUNTIME" />
|
||||
<orderEntry type="library" name="Guava" level="project" />
|
||||
<orderEntry type="module" module-name="colorSchemes" scope="RUNTIME" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<component>
|
||||
<!-- <version name="IntelliJ IDEA" major="6" minor="0.2 Beta"/> -->
|
||||
<version codename="1.1 Early Access Preview" major="1" minor="0" eap="true" update-channel="pycharm"/>
|
||||
<version codename="1.2 Early Access Preview" major="1" minor="2" eap="true" update-channel="pycharm"/>
|
||||
<build number="__BUILD_NUMBER__" date="__BUILD_DATE__"/>
|
||||
<logo url="/pycharm_logo.png" textcolor="B7C9B5"/>
|
||||
<about url="/pycharm_about.png"/>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
@@ -277,6 +277,9 @@
|
||||
<moduleService serviceInterface="com.jetbrains.django.model.TemplateManager"
|
||||
serviceImplementation="com.jetbrains.django.model.TemplateManager"/>
|
||||
|
||||
<projectService serviceInterface="com.jetbrains.django.model.DjangoTagLibrary"
|
||||
serviceImplementation="com.jetbrains.django.model.DjangoTagLibrary"/>
|
||||
|
||||
<facetType implementation="com.jetbrains.django.facet.DjangoFacetType"/>
|
||||
|
||||
<codeInsight.lineMarkerProvider language="DjangoTemplate" implementationClass="com.jetbrains.django.annotator.ViewLineMarkerProvider"/>
|
||||
|
||||
@@ -204,8 +204,9 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
|
||||
condition.accept(assertionEvaluator);
|
||||
}
|
||||
// Set the head as the last instruction of condition
|
||||
Instruction head = getPrevInstruction(condition);
|
||||
myBuilder.prevInstruction = head;
|
||||
PyElement lastCondition = condition;
|
||||
Instruction lastBranchingPoint = getPrevInstruction(condition);
|
||||
myBuilder.prevInstruction = lastBranchingPoint;
|
||||
final PyStatementList thenStatements = ifPart.getStatementList();
|
||||
if (thenStatements != null) {
|
||||
myBuilder.startConditionalNode(thenStatements, condition, true);
|
||||
@@ -223,24 +224,26 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
|
||||
});
|
||||
myBuilder.addPendingEdge(node, myBuilder.prevInstruction);
|
||||
}
|
||||
for (PyIfPart part : node.getElifParts()) {
|
||||
// restore head
|
||||
myBuilder.prevInstruction = head;
|
||||
for (final PyIfPart part : node.getElifParts()) {
|
||||
// Set the head as the false branch
|
||||
myBuilder.prevInstruction = lastBranchingPoint;
|
||||
myBuilder.startConditionalNode(part, lastCondition, false);
|
||||
condition = part.getCondition();
|
||||
if (condition != null) {
|
||||
lastCondition = condition;
|
||||
lastBranchingPoint = getPrevInstruction(lastCondition);
|
||||
condition.accept(this);
|
||||
}
|
||||
// Set the head as the last instruction of condition
|
||||
head = getPrevInstruction(condition);
|
||||
myBuilder.prevInstruction = head;
|
||||
myBuilder.startConditionalNode(ifPart, condition, true);
|
||||
myBuilder.prevInstruction = getPrevInstruction(lastCondition);
|
||||
myBuilder.startConditionalNode(part, lastCondition, true);
|
||||
final PyStatementList statementList = part.getStatementList();
|
||||
if (statementList != null) {
|
||||
statementList.accept(this);
|
||||
}
|
||||
myBuilder.processPending(new ControlFlowBuilder.PendingProcessor() {
|
||||
public void process(final PsiElement pendingScope, final Instruction instruction) {
|
||||
if (pendingScope != null && PsiTreeUtil.isAncestor(ifPart, pendingScope, false)) {
|
||||
if (pendingScope != null && PsiTreeUtil.isAncestor(part, pendingScope, false)) {
|
||||
myBuilder.addPendingEdge(node, instruction);
|
||||
}
|
||||
else {
|
||||
@@ -250,15 +253,16 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
|
||||
});
|
||||
myBuilder.addPendingEdge(node, myBuilder.prevInstruction);
|
||||
}
|
||||
// restore head
|
||||
myBuilder.prevInstruction = head;
|
||||
final PyElsePart elseBranch = node.getElsePart();
|
||||
if (elseBranch != null) {
|
||||
myBuilder.startConditionalNode(elseBranch, condition, false);
|
||||
// Set the head as the false branch
|
||||
myBuilder.prevInstruction = lastBranchingPoint;
|
||||
myBuilder.startConditionalNode(elseBranch, lastCondition, false);
|
||||
elseBranch.accept(this);
|
||||
myBuilder.addPendingEdge(node, myBuilder.prevInstruction);
|
||||
} else {
|
||||
myBuilder.addPendingEdge(node, lastBranchingPoint);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.jetbrains.python.psi;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -29,6 +30,17 @@ public interface PyCallExpression extends PyExpression {
|
||||
@NotNull
|
||||
PyExpression[] getArguments();
|
||||
|
||||
/**
|
||||
* If the list of arguments has at least {@code index} elements and the index'th element is of type argClass,
|
||||
* returns it. Otherwise, returns null.
|
||||
*
|
||||
* @param index argument index
|
||||
* @param argClass argument expected type
|
||||
* @return the argument or null
|
||||
*/
|
||||
@Nullable
|
||||
<T extends PsiElement> T getArgument(int index, Class<T> argClass);
|
||||
|
||||
void addArgument(PyExpression expression);
|
||||
|
||||
/**
|
||||
@@ -61,9 +73,10 @@ public interface PyCallExpression extends PyExpression {
|
||||
|
||||
/**
|
||||
* Method-oriented constructor.
|
||||
* @param function the method (or any other callable, but why bother then).
|
||||
* @param flags result of decorators or wrapping.
|
||||
* @param offset implicit argument offset; parameters up to this are implicitly filled in the call.
|
||||
*
|
||||
* @param function the method (or any other callable, but why bother then).
|
||||
* @param flags result of decorators or wrapping.
|
||||
* @param offset implicit argument offset; parameters up to this are implicitly filled in the call.
|
||||
* @param implicitlyResolved value for {@link #isImplicitlyResolved()}
|
||||
*/
|
||||
public PyMarkedCallee(@NotNull Callable function, EnumSet<PyFunction.Flag> flags, int offset, boolean implicitlyResolved) {
|
||||
@@ -77,7 +90,7 @@ public interface PyCallExpression extends PyExpression {
|
||||
myCallable = callable;
|
||||
myFlags = EnumSet.noneOf(PyFunction.Flag.class);
|
||||
myImplicitOffset = 0;
|
||||
myImplicitlyResolved = implicitlyResolved;
|
||||
myImplicitlyResolved = implicitlyResolved;
|
||||
}
|
||||
|
||||
public Callable getCallable() {
|
||||
@@ -90,8 +103,8 @@ public interface PyCallExpression extends PyExpression {
|
||||
|
||||
/**
|
||||
* @return number of implicitly passed positional parameters; 0 means no parameters are passed implicitly.
|
||||
* Note that a <tt>*args</tt> is never marked as passed implicitly.
|
||||
* E.g. for a function like <tt>foo(a, b, *args)</tt> always holds <tt>getImplicitOffset() < 2</tt>.
|
||||
* Note that a <tt>*args</tt> is never marked as passed implicitly.
|
||||
* E.g. for a function like <tt>foo(a, b, *args)</tt> always holds <tt>getImplicitOffset() < 2</tt>.
|
||||
*/
|
||||
public int getImplicitOffset() {
|
||||
return myImplicitOffset;
|
||||
|
||||
@@ -47,6 +47,12 @@ public class PyCallExpressionImpl extends PyElementImpl implements PyCallExpress
|
||||
return argList != null ? argList.getArguments() : PyExpression.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends PsiElement> T getArgument(int index, Class<T> argClass) {
|
||||
PyExpression[] args = getArguments();
|
||||
return args.length >= index && argClass.isInstance(args[index]) ? argClass.cast(args[index]) : null;
|
||||
}
|
||||
|
||||
public void addArgument(PyExpression expression) {
|
||||
PyCallExpressionHelper.addArgument(this, expression);
|
||||
}
|
||||
@@ -56,7 +62,7 @@ public class PyCallExpressionImpl extends PyElementImpl implements PyCallExpress
|
||||
}
|
||||
|
||||
public boolean isCalleeText(@NotNull String... nameCandidates) {
|
||||
return PyCallExpressionHelper.isCalleeText(this, nameCandidates);
|
||||
return PyCallExpressionHelper.isCalleeText(this, nameCandidates);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -100,7 +106,7 @@ public class PyCallExpressionImpl extends PyElementImpl implements PyCallExpress
|
||||
if (target instanceof Callable) {
|
||||
final Callable callable = (Callable)target;
|
||||
if (context.allowReturnTypes()) {
|
||||
return callable.getReturnType(context, (PyReferenceExpression) callee);
|
||||
return callable.getReturnType(context, (PyReferenceExpression)callee);
|
||||
}
|
||||
if (callable instanceof PyFunction) {
|
||||
final PyType docStringType = ((PyFunction)callable).getReturnTypeFromDocString();
|
||||
@@ -118,7 +124,7 @@ public class PyCallExpressionImpl extends PyElementImpl implements PyCallExpress
|
||||
else {
|
||||
final PyType type = context.getType(callee);
|
||||
if (type instanceof PyClassType) {
|
||||
PyClassType classType = (PyClassType) type;
|
||||
PyClassType classType = (PyClassType)type;
|
||||
if (classType.isDefinition()) {
|
||||
return new PyClassType(classType.getPyClass(), false);
|
||||
}
|
||||
@@ -151,7 +157,7 @@ public class PyCallExpressionImpl extends PyElementImpl implements PyCallExpress
|
||||
final PsiElement element = qRef == null ? null : qRef.resolve();
|
||||
if (element instanceof PyParameter) {
|
||||
final PyParameterList parameterList = PsiTreeUtil.getParentOfType(element, PyParameterList.class);
|
||||
if (parameterList != null && element == parameterList.getParameters() [0]) {
|
||||
if (parameterList != null && element == parameterList.getParameters()[0]) {
|
||||
return getSuperCallType(context, containingClass, args[1]);
|
||||
}
|
||||
}
|
||||
@@ -201,7 +207,7 @@ public class PyCallExpressionImpl extends PyElementImpl implements PyCallExpress
|
||||
final PyClass[] supers = pyClass.getSuperClasses();
|
||||
if (supers.length > 0) {
|
||||
if (supers.length == 1) {
|
||||
return new PyClassType(supers [0], false);
|
||||
return new PyClassType(supers[0], false);
|
||||
}
|
||||
List<PyType> superTypes = new ArrayList<PyType>();
|
||||
for (PyClass aSuper : supers) {
|
||||
|
||||
@@ -9,7 +9,6 @@ import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.resolve.PyResolveUtil;
|
||||
import com.jetbrains.python.psi.stubs.PyDecoratorStub;
|
||||
import com.jetbrains.python.psi.PyDecorator;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -37,7 +36,7 @@ public class PyDecoratorImpl extends PyPresentableElementImpl<PyDecoratorStub> i
|
||||
@Override
|
||||
public String getName() {
|
||||
final PyQualifiedName qname = getQualifiedName();
|
||||
return qname != null? qname.getLastComponent() : null;
|
||||
return qname != null ? qname.getLastComponent() : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -101,6 +100,12 @@ public class PyDecoratorImpl extends PyPresentableElementImpl<PyDecoratorStub> i
|
||||
return argList != null ? argList.getArguments() : PyExpression.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends PsiElement> T getArgument(int index, Class<T> argClass) {
|
||||
PyExpression[] args = getArguments();
|
||||
return args.length >= index && argClass.isInstance(args[index]) ? argClass.cast(args[index]) : null;
|
||||
}
|
||||
|
||||
public void addArgument(PyExpression expression) {
|
||||
PyCallExpressionHelper.addArgument(this, expression);
|
||||
}
|
||||
@@ -108,7 +113,7 @@ public class PyDecoratorImpl extends PyPresentableElementImpl<PyDecoratorStub> i
|
||||
public PyMarkedCallee resolveCallee(TypeEvalContext context) {
|
||||
PyMarkedCallee callee = PyCallExpressionHelper.resolveCallee(this, context);
|
||||
if (callee == null) return null;
|
||||
if (! hasArgumentList()) {
|
||||
if (!hasArgumentList()) {
|
||||
// NOTE: that +1 thing looks fishy
|
||||
callee = new PyMarkedCallee(callee.getCallable(), callee.getFlags(), callee.getImplicitOffset() + 1, callee.isImplicitlyResolved());
|
||||
}
|
||||
@@ -132,7 +137,9 @@ public class PyDecoratorImpl extends PyPresentableElementImpl<PyDecoratorStub> i
|
||||
node.replaceChild(name_node, nameElement);
|
||||
return this;
|
||||
}
|
||||
else throw new IncorrectOperationException("No name node");
|
||||
else {
|
||||
throw new IncorrectOperationException("No name node");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: create a custom version of public PyType getType()
|
||||
|
||||
@@ -197,12 +197,12 @@ public class PyClassRefactoringUtil {
|
||||
}
|
||||
|
||||
private static void rememberNamedReferences(final List<PyFunction> methods) {
|
||||
for (PyFunction method : methods) {
|
||||
for (final PyFunction method : methods) {
|
||||
method.acceptChildren(new PyRecursiveElementVisitor() {
|
||||
@Override
|
||||
public void visitPyReferenceExpression(PyReferenceExpression node) {
|
||||
super.visitPyReferenceExpression(node);
|
||||
rememberReference(node);
|
||||
rememberReference(node, method);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -210,13 +210,13 @@ public class PyClassRefactoringUtil {
|
||||
|
||||
|
||||
private static final Key<PsiNamedElement> ENCODED_IMPORT = Key.create("PyEncodedImport");
|
||||
private static void rememberReference(PyReferenceExpression node) {
|
||||
private static void rememberReference(PyReferenceExpression node, PyFunction method) {
|
||||
// we will remember reference in deepest node
|
||||
if (node.getQualifier() instanceof PyReferenceExpression) return;
|
||||
|
||||
final PsiPolyVariantReference ref = node.getReference();
|
||||
final PsiElement target = ref.resolve();
|
||||
if (target instanceof PsiNamedElement) {
|
||||
if (target instanceof PsiNamedElement && !PsiTreeUtil.isAncestor(method, target, false)) {
|
||||
node.putCopyableUserData(ENCODED_IMPORT, (PsiNamedElement)target);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
3(4,5) element: PyIfStatement
|
||||
4(6) element: PyStatementList. Condition: 1:true
|
||||
5(6) element: PyElsePart. Condition: 1:false
|
||||
6(7,8,9) element: PyIfStatement
|
||||
7(9) element: PyStatementList. Condition: 2:true
|
||||
8(9) element: PyIfPartIf. Condition: 3:true
|
||||
9(10,11,12) element: PyIfStatement
|
||||
10(14) element: PyStatementList. Condition: 4:true
|
||||
11(14) element: PyIfPartIf. Condition: 5:true
|
||||
12(13) element: PyElsePart. Condition: 5:false
|
||||
13(14) element: PyExpressionStatement
|
||||
14() element: null
|
||||
6(7,8) element: PyIfStatement
|
||||
7(10) element: PyStatementList. Condition: 2:true
|
||||
8(9,10) element: PyIfPartElif. Condition: 2:false
|
||||
9(10) element: PyIfPartElif. Condition: 3:true
|
||||
10(11,12) element: PyIfStatement
|
||||
11(16) element: PyStatementList. Condition: 4:true
|
||||
12(13,14) element: PyIfPartElif. Condition: 4:false
|
||||
13(16) element: PyIfPartElif. Condition: 5:true
|
||||
14(15) element: PyElsePart. Condition: 5:false
|
||||
15(16) element: PyExpressionStatement
|
||||
16() element: null
|
||||
13
python/testData/codeInsight/controlflow/manyifs.py
Normal file
13
python/testData/codeInsight/controlflow/manyifs.py
Normal file
@@ -0,0 +1,13 @@
|
||||
var = 1
|
||||
if a == b:
|
||||
var = 2
|
||||
elif aa == bb:
|
||||
bbb = same_changet_expression
|
||||
|
||||
if bbb:
|
||||
var = 3 # <--- this highlight bug (unused variable)
|
||||
|
||||
else:
|
||||
var = 4
|
||||
|
||||
return {'variable': var}
|
||||
27
python/testData/codeInsight/controlflow/manyifs.txt
Normal file
27
python/testData/codeInsight/controlflow/manyifs.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
0(1) element: null
|
||||
1(2) element: PyAssignmentStatement
|
||||
2(3) WRITE ACCESS: var
|
||||
3(4) element: PyIfStatement
|
||||
4(5) READ ACCESS: a
|
||||
5(6,9) READ ACCESS: b
|
||||
6(7) element: PyStatementList. Condition: a == b:true
|
||||
7(8) element: PyAssignmentStatement
|
||||
8(24) WRITE ACCESS: var
|
||||
9(10,21) element: PyIfPartElif. Condition: a == b:false
|
||||
10(11) READ ACCESS: aa
|
||||
11(12) READ ACCESS: bb
|
||||
12(13) element: PyIfPartElif. Condition: aa == bb:true
|
||||
13(14) element: PyAssignmentStatement
|
||||
14(15) READ ACCESS: same_changet_expression
|
||||
15(16) WRITE ACCESS: bbb
|
||||
16(17) element: PyIfStatement
|
||||
17(18,24) READ ACCESS: bbb
|
||||
18(19) element: PyStatementList. Condition: bbb:true
|
||||
19(20) element: PyAssignmentStatement
|
||||
20(24) WRITE ACCESS: var
|
||||
21(22) element: PyElsePart. Condition: aa == bb:false
|
||||
22(23) element: PyAssignmentStatement
|
||||
23(24) WRITE ACCESS: var
|
||||
24(25) element: PyReturnStatement
|
||||
25(26) READ ACCESS: var
|
||||
26() element: null
|
||||
@@ -0,0 +1,9 @@
|
||||
from SuperClass import SuperClass
|
||||
|
||||
from sys import argv
|
||||
|
||||
class AnyClass(SuperClass):
|
||||
def this_should_be_in_super(self, some_argument):
|
||||
if not self.args:
|
||||
self.args = argv
|
||||
self.argument = some_argument
|
||||
@@ -0,0 +1,10 @@
|
||||
from sys import argv
|
||||
|
||||
class SuperClass(object):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def this_should_be_in_super(self, some_argument):
|
||||
if not self.args:
|
||||
self.args = argv
|
||||
self.argument = some_argument
|
||||
@@ -0,0 +1,5 @@
|
||||
from sys import argv
|
||||
|
||||
class SuperClass(object):
|
||||
def __init__(self):
|
||||
pass
|
||||
5
python/testData/refactoring/pullup/multiFile/Class.py
Normal file
5
python/testData/refactoring/pullup/multiFile/Class.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from SuperClass import SuperClass
|
||||
|
||||
class AnyClass(SuperClass):
|
||||
def this_should_be_in_super(self, some_argument):
|
||||
self.argument = some_argument
|
||||
@@ -0,0 +1,6 @@
|
||||
class SuperClass(object):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def this_should_be_in_super(self, some_argument):
|
||||
self.argument = some_argument
|
||||
@@ -0,0 +1,3 @@
|
||||
class SuperClass(object):
|
||||
def __init__(self):
|
||||
pass
|
||||
@@ -144,6 +144,10 @@ public class PyControlFlowBuilderTest extends LightMarkedTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testManyIfs() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testQualifiedSelfReference() throws Exception {
|
||||
final String testName = getTestName(false).toLowerCase();
|
||||
configureByFile(testName + ".py");
|
||||
|
||||
@@ -30,13 +30,33 @@ public class PyPullUpTest extends PyClassRefactoringTest {
|
||||
doHelperTest("Boo", ".boo", "Foo");
|
||||
}
|
||||
|
||||
public void testMultiFile() { // PY-2810
|
||||
doMultiFileTest();
|
||||
}
|
||||
|
||||
public void testDuplicateImport() { // PY-2810
|
||||
doMultiFileTest();
|
||||
}
|
||||
|
||||
private void doMultiFileTest() {
|
||||
String baseName = "refactoring/pullup/" + getTestName(true) + "/";
|
||||
myFixture.copyFileToProject(baseName + "Class.py", "Class.py");
|
||||
myFixture.copyFileToProject(baseName + "SuperClass.py", "SuperClass.py");
|
||||
doPullUp("AnyClass", ".this_should_be_in_super", "SuperClass");
|
||||
myFixture.checkResultByFile("SuperClass.py", "/" + baseName + "/SuperClass.after.py", true);
|
||||
}
|
||||
|
||||
private void doHelperTest(final String className, final String memberName, final String superClassName) {
|
||||
String baseName = "/refactoring/pullup/" + getTestName(true);
|
||||
myFixture.configureByFile(baseName + ".py");
|
||||
doPullUp(className, memberName, superClassName);
|
||||
myFixture.checkResultByFile(baseName + ".after.py");
|
||||
}
|
||||
|
||||
private void doPullUp(String className, String memberName, String superClassName) {
|
||||
final PyClass clazz = findClass(className);
|
||||
final PyElement member = findMember(className, memberName);
|
||||
final PyClass superClass = findClass(superClassName);
|
||||
PyPullUpHelper.pullUp(clazz, Collections.singleton(new PyMemberInfo(member)), superClass);
|
||||
myFixture.checkResultByFile(baseName + ".after.py");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user