diff --git a/python/helpers/pydev/pydevd_file_utils.py b/python/helpers/pydev/pydevd_file_utils.py
index 576815081082..151f89533239 100644
--- a/python/helpers/pydev/pydevd_file_utils.py
+++ b/python/helpers/pydev/pydevd_file_utils.py
@@ -47,6 +47,7 @@ import sys
import traceback
import zipfile
+normcase = os.path.normcase
basename = os.path.basename
exists = os.path.exists
join = os.path.join
@@ -81,7 +82,7 @@ def _NormFile(filename):
try:
return NORM_FILENAME_CONTAINER[filename]
except KeyError:
- r = rPath(filename)
+ r = normcase(rPath(filename))
#cache it for fast access later
NORM_FILENAME_CONTAINER[filename] = r
return r
@@ -186,7 +187,7 @@ if PATHS_FROM_ECLIPSE_TO_PYTHON:
return NORM_FILENAME_TO_SERVER_CONTAINER[filename]
except KeyError:
#used to translate a path from the client to the debug server
- translated = filename
+ translated = normcase(filename)
for eclipse_prefix, server_prefix in PATHS_FROM_ECLIPSE_TO_PYTHON:
if translated.startswith(eclipse_prefix):
if DEBUG_CLIENT_SERVER_TRANSLATION:
diff --git a/python/src/META-INF/python-plugin-common.xml b/python/src/META-INF/python-plugin-common.xml
index 3f364de6437d..1111e6f9f635 100644
--- a/python/src/META-INF/python-plugin-common.xml
+++ b/python/src/META-INF/python-plugin-common.xml
@@ -227,6 +227,7 @@
+
callback) {
+ public static PsiElement appendToMethod(PyFunction init, Function callback) {
// add this field as the last stmt of the constructor
final PyStatementList stmt_list = init.getStatementList();
PyStatement[] stmts = stmt_list.getStatements(); // NOTE: rather wasteful, consider iterable stmt list
@@ -93,7 +93,7 @@ public class AddFieldQuickFix implements LocalQuickFix {
if (cls != null && item_name != null) {
PyFunction init = cls.findMethodByName(PyNames.INIT, false);
if (init != null) {
- return appendToInit(init, callback);
+ return appendToMethod(init, callback);
}
else { // no init! boldly copy ancestor's.
for (PyClass ancestor : cls.iterateAncestorClasses()) {
@@ -105,7 +105,7 @@ public class AddFieldQuickFix implements LocalQuickFix {
return null;
}
- appendToInit(new_init, callback);
+ appendToMethod(new_init, callback);
PsiElement add_anchor = null;
PyFunction[] meths = cls.getMethods();
diff --git a/python/src/com/jetbrains/python/findUsages/PyFindUsagesHandlerFactory.java b/python/src/com/jetbrains/python/findUsages/PyFindUsagesHandlerFactory.java
index 4e16c3a7f63c..934cdab8df82 100644
--- a/python/src/com/jetbrains/python/findUsages/PyFindUsagesHandlerFactory.java
+++ b/python/src/com/jetbrains/python/findUsages/PyFindUsagesHandlerFactory.java
@@ -2,13 +2,19 @@ package com.jetbrains.python.findUsages;
import com.intellij.find.findUsages.FindUsagesHandler;
import com.intellij.find.findUsages.FindUsagesHandlerFactory;
+import com.intellij.openapi.ui.Messages;
import com.intellij.psi.PsiElement;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.PyFunction;
+import com.jetbrains.python.psi.search.PySuperMethodsSearch;
import org.jetbrains.annotations.NotNull;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
/**
* @author yole
*/
@@ -26,8 +32,39 @@ public class PyFindUsagesHandlerFactory extends FindUsagesHandlerFactory {
return new PyModuleFindUsagesHandler((PyFile) element);
}
if (element instanceof PyFunction) {
+ if (!forHighlightUsages) {
+ final Collection superMethods = PySuperMethodsSearch.search((PyFunction)element, true).findAll();
+ if (superMethods.size() > 0) {
+ final PsiElement next = superMethods.iterator().next();
+ // TODO should do this for Jython functions overriding Java methods too
+ if (next instanceof PyFunction && !isInClassobj((PyFunction)next)) {
+ StringBuilder messageBuilder = new StringBuilder("Method ");
+ messageBuilder.append(((PyFunction)element).getName());
+ messageBuilder.append(" overrides method of class ");
+ messageBuilder.append(((PyFunction)next).getContainingClass().getName());
+ messageBuilder.append(".\nDo you want to find usages of the base method?");
+ int rc = Messages.showYesNoCancelDialog(element.getProject(), messageBuilder.toString(), "Find Usages", Messages.getQuestionIcon());
+ if (rc == 0) {
+ List allMethods = new ArrayList();
+ allMethods.add(element);
+ allMethods.addAll(superMethods);
+ return new PyFunctionFindUsagesHandler(element, allMethods);
+ }
+ if (rc == 1) {
+ return new PyFunctionFindUsagesHandler(element);
+ }
+ return FindUsagesHandler.NULL_HANDLER;
+ }
+ }
+
+ }
return new PyFunctionFindUsagesHandler(element);
}
return new PyClassFindUsagesHandler((PyClass)element);
}
+
+ private static boolean isInClassobj(PyFunction fun) {
+ final PyClass containingClass = fun.getContainingClass();
+ return containingClass != null && PyNames.FAKE_OLD_BASE.equals(containingClass.getName());
+ }
}
diff --git a/python/src/com/jetbrains/python/findUsages/PyFunctionFindUsagesHandler.java b/python/src/com/jetbrains/python/findUsages/PyFunctionFindUsagesHandler.java
index cc7809ea92d0..0ab8c2c823f1 100644
--- a/python/src/com/jetbrains/python/findUsages/PyFunctionFindUsagesHandler.java
+++ b/python/src/com/jetbrains/python/findUsages/PyFunctionFindUsagesHandler.java
@@ -4,16 +4,32 @@ import com.intellij.find.findUsages.FindUsagesHandler;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
+import java.util.List;
+
/**
* @author yole
*/
public class PyFunctionFindUsagesHandler extends FindUsagesHandler {
+ private final List myAllElements;
+
protected PyFunctionFindUsagesHandler(@NotNull PsiElement psiElement) {
super(psiElement);
+ myAllElements = null;
+ }
+
+ protected PyFunctionFindUsagesHandler(@NotNull PsiElement psiElement, List allElements) {
+ super(psiElement);
+ myAllElements = allElements;
}
@Override
protected boolean isSearchForTextOccurencesAvailable(PsiElement psiElement, boolean isSingleFile) {
return true;
}
+
+ @NotNull
+ @Override
+ public PsiElement[] getPrimaryElements() {
+ return myAllElements != null ? myAllElements.toArray(new PsiElement[myAllElements.size()]) : super.getPrimaryElements();
+ }
}
diff --git a/python/src/com/jetbrains/python/findUsages/PyImportFilteringRule.java b/python/src/com/jetbrains/python/findUsages/PyImportFilteringRule.java
new file mode 100644
index 000000000000..0e9ba867df64
--- /dev/null
+++ b/python/src/com/jetbrains/python/findUsages/PyImportFilteringRule.java
@@ -0,0 +1,29 @@
+package com.jetbrains.python.findUsages;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.usages.Usage;
+import com.intellij.usages.rules.ImportFilteringRule;
+import com.intellij.usages.rules.PsiElementUsage;
+import com.jetbrains.python.psi.PyFile;
+import com.jetbrains.python.psi.PyImportStatementBase;
+
+/**
+ * @author yole
+ */
+public class PyImportFilteringRule extends ImportFilteringRule {
+ @Override
+ public boolean isVisible(Usage usage) {
+ if (usage instanceof PsiElementUsage) {
+ final PsiElement psiElement = ((PsiElementUsage)usage).getElement();
+ final PsiFile containingFile = psiElement.getContainingFile();
+ if (containingFile instanceof PyFile) {
+ // check whether the element is in the import list
+ final PyImportStatementBase importStatement = PsiTreeUtil.getParentOfType(psiElement, PyImportStatementBase.class, true);
+ return importStatement == null;
+ }
+ }
+ return true;
+ }
+}
diff --git a/python/src/com/jetbrains/python/formatter/PyBlock.java b/python/src/com/jetbrains/python/formatter/PyBlock.java
index c40796b32336..584ba85dad95 100644
--- a/python/src/com/jetbrains/python/formatter/PyBlock.java
+++ b/python/src/com/jetbrains/python/formatter/PyBlock.java
@@ -352,7 +352,7 @@ public class PyBlock implements ASTBlock {
if (type2 == PyElementTypes.STATEMENT_LIST) {
return Spacing.createSpacing(1, Integer.MAX_VALUE, 0, true, 0);
}
- if (parentType == PyElementTypes.KEY_VALUE_EXPRESSION) {
+ if (parentType == PyElementTypes.KEY_VALUE_EXPRESSION || parentType == PyElementTypes.LAMBDA_EXPRESSION) {
return getSpacingForOption(getPySettings().SPACE_AFTER_PY_COLON);
}
}
@@ -387,7 +387,7 @@ public class PyBlock implements ASTBlock {
if (type2 == PyElementTypes.ARGUMENT_LIST) {
return getSpacingForOption(mySettings.SPACE_BEFORE_METHOD_CALL_PARENTHESES);
}
- if (type2 == PyElementTypes.PARAMETER_LIST) {
+ if (type2 == PyElementTypes.PARAMETER_LIST && type1 != PyTokenTypes.LAMBDA_KEYWORD) {
return getSpacingForOption(mySettings.SPACE_BEFORE_METHOD_PARENTHESES);
}
diff --git a/python/src/com/jetbrains/python/parsing/FunctionParsing.java b/python/src/com/jetbrains/python/parsing/FunctionParsing.java
index 62f4d9508937..05a6ebc3e7ec 100644
--- a/python/src/com/jetbrains/python/parsing/FunctionParsing.java
+++ b/python/src/com/jetbrains/python/parsing/FunctionParsing.java
@@ -173,11 +173,15 @@ public class FunctionParsing extends Parsing {
}
}
- if (myBuilder.getTokenType() == endToken) {
+ if (myBuilder.getTokenType() == endToken && endToken == PyTokenTypes.RPAR) {
myBuilder.advanceLexer();
}
parameterList.done(PyElementTypes.PARAMETER_LIST);
+
+ if (myBuilder.getTokenType() == endToken && endToken == PyTokenTypes.COLON) {
+ myBuilder.advanceLexer();
+ }
}
private void parseParameterSubList() {
diff --git a/python/src/com/jetbrains/python/psi/search/PyInitReferenceSearchExecutor.java b/python/src/com/jetbrains/python/psi/search/PyInitReferenceSearchExecutor.java
index 7bcb0c3be475..bfeffac198eb 100644
--- a/python/src/com/jetbrains/python/psi/search/PyInitReferenceSearchExecutor.java
+++ b/python/src/com/jetbrains/python/psi/search/PyInitReferenceSearchExecutor.java
@@ -1,5 +1,7 @@
package com.jetbrains.python.psi.search;
+import com.intellij.openapi.application.AccessToken;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.QueryExecutorBase;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
@@ -23,23 +25,34 @@ public class PyInitReferenceSearchExecutor extends QueryExecutorBase suggestedNames = operation.getSuggestedNames();
+ if (suggestedNames.size() > 0) {
+ operation.setName(suggestedNames.iterator().next());
+ }
+ else {
+ operation.setName("x");
+ }
+ }
+ }
+
public enum InitPlace {
SAME_METHOD,
CONSTRUCTOR,
SET_UP
}
- private static void replaceExpression(PyExpression newExpression, Project project, PsiElement expression) {
+ @Nullable
+ private static PsiElement replaceExpression(PyExpression newExpression, Project project, PsiElement expression) {
PyExpressionStatement statement = PsiTreeUtil.getParentOfType(expression, PyExpressionStatement.class);
if (statement != null) {
if (statement.getExpression() == expression) {
statement.delete();
- return;
+ return null;
}
}
- PyPsiUtils.replaceExpression(project, expression, newExpression);
+ return PyPsiUtils.replaceExpression(project, expression, newExpression);
}
private final IntroduceValidator myValidator;
@@ -83,7 +98,7 @@ abstract public class IntroduceHandler implements RefactoringActionHandler {
}
public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
- performAction(project, editor, file, null, InitPlace.SAME_METHOD, false, false, false);
+ performAction(new IntroduceOperation(project, editor, file, null, false, false, false));
}
public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
@@ -134,16 +149,18 @@ abstract public class IntroduceHandler implements RefactoringActionHandler {
}
public void performAction(@NotNull final Project project, Editor editor, PsiFile file, String name, boolean replaceAll, boolean hasConstructor, boolean isTestClass) {
- performAction(project, editor, file, name, InitPlace.SAME_METHOD, replaceAll, hasConstructor, isTestClass);
+ performAction(new IntroduceOperation(project, editor, file, name, replaceAll, hasConstructor, isTestClass));
}
- public void performAction(@NotNull final Project project, Editor editor, PsiFile file, String name, InitPlace initInConstructor, boolean replaceAll, boolean hasConstructor, boolean isTestClass) {
+ public void performAction(IntroduceOperation operation) {
+ final PsiFile file = operation.getFile();
if (!CommonRefactoringUtil.checkReadOnlyStatus(file)) {
return;
}
PsiElement element1 = null;
PsiElement element2 = null;
+ final Editor editor = operation.getEditor();
final SelectionModel selectionModel = editor.getSelectionModel();
boolean singleElementSelection = false;
if (selectionModel.hasSelection()) {
@@ -162,7 +179,7 @@ abstract public class IntroduceHandler implements RefactoringActionHandler {
}
}
else {
- if (smartIntroduce(file, editor, name, initInConstructor, replaceAll, hasConstructor, isTestClass)) {
+ if (smartIntroduce(operation)) {
return;
}
final CaretModel caretModel = editor.getCaretModel();
@@ -173,6 +190,7 @@ abstract public class IntroduceHandler implements RefactoringActionHandler {
element2 = file.findElementAt(document.getLineEndOffset(lineNumber) - 1);
}
}
+ final Project project = operation.getProject();
if (element1 == null || element2 == null) {
showCannotPerformError(project, editor);
return;
@@ -194,7 +212,8 @@ abstract public class IntroduceHandler implements RefactoringActionHandler {
if (!checkIntroduceContext(file, editor, element1)) {
return;
}
- performActionOnElement(editor, element1, name, initInConstructor, replaceAll, hasConstructor, isTestClass);
+ operation.setElement(element1);
+ performActionOnElement(operation);
}
private void showCannotPerformError(Project project, Editor editor) {
@@ -202,7 +221,9 @@ abstract public class IntroduceHandler implements RefactoringActionHandler {
"refactoring.extractMethod");
}
- private boolean smartIntroduce(final PsiFile file, final Editor editor, final String name, final InitPlace initInConstructor, final boolean replaceAll, final boolean hasConstructor, final boolean isTestClass) {
+ private boolean smartIntroduce(final IntroduceOperation operation) {
+ final Editor editor = operation.getEditor();
+ final PsiFile file = operation.getFile();
int offset = editor.getCaretModel().getOffset();
PsiElement elementAtCaret = file.findElementAt(offset);
if (!checkIntroduceContext(file, editor, elementAtCaret)) return true;
@@ -217,14 +238,16 @@ abstract public class IntroduceHandler implements RefactoringActionHandler {
elementAtCaret = elementAtCaret.getParent();
}
if (expressions.size() == 1 || ApplicationManager.getApplication().isUnitTestMode()) {
- performActionOnElement(editor, expressions.get(0), name, initInConstructor, replaceAll, hasConstructor, isTestClass);
+ operation.setElement(expressions.get(0));
+ performActionOnElement(operation);
return true;
}
else if (expressions.size() > 1) {
IntroduceTargetChooser.showChooser(editor, expressions, new Pass() {
@Override
public void pass(PyExpression pyExpression) {
- performActionOnElement(editor, pyExpression, name, initInConstructor, replaceAll, hasConstructor, isTestClass);
+ operation.setElement(pyExpression);
+ performActionOnElement(operation);
}
}, new Function() {
public String fun(PyExpression pyExpression) {
@@ -261,56 +284,94 @@ abstract public class IntroduceHandler implements RefactoringActionHandler {
return true;
}
- private void performActionOnElement(Editor editor,
- @NotNull PsiElement element,
- String name,
- InitPlace initInConstructor,
- boolean replaceAll,
- boolean hasConstructor,
- boolean isTestClass) {
- final Project project = element.getProject();
- if (!checkEnabled(project, editor, element, myDialogTitle)) {
+ private void performActionOnElement(IntroduceOperation operation) {
+ final Project project = operation.getProject();
+ if (!checkEnabled(project, operation.getEditor(), operation.getElement(), myDialogTitle)) {
return;
}
+ final PsiElement element = operation.getElement();
final PsiElement parent = element.getParent();
final PyExpression initializer = parent instanceof PyAssignmentStatement ?
((PyAssignmentStatement)parent).getAssignedValue() :
(PyExpression)element;
+ operation.setInitializer(initializer);
- final List occurrences;
if (initializer.getUserData(PyPsiUtils.SELECTION_BREAKS_AST_NODE) == null) {
- occurrences = getOccurrences(element, initializer);
+ operation.setOccurrences(getOccurrences(element, initializer));
+ }
+ operation.setSuggestedNames(getSuggestedNames(initializer));
+ if (operation.getOccurrences().size() == 0) {
+ operation.setReplaceAll(false);
+ }
+
+ performActionOnElementOccurrences(operation);
+ }
+
+ protected void performActionOnElementOccurrences(final IntroduceOperation operation) {
+ final Editor editor = operation.getEditor();
+ if (editor.getSettings().isVariableInplaceRenameEnabled() && !ApplicationManager.getApplication().isUnitTestMode()) {
+ ensureName(operation);
+ new OccurrencesChooser(editor)
+ .showChooser(operation.getElement(), operation.getOccurrences(), new Pass() {
+ @Override
+ public void pass(OccurrencesChooser.ReplaceChoice replaceChoice) {
+ operation.setReplaceAll(replaceChoice == OccurrencesChooser.ReplaceChoice.ALL);
+ performInplaceIntroduce(operation);
+ }
+ });
}
else {
- occurrences = Collections.emptyList();
+ performIntroduceWithDialog(operation);
}
- Collection possibleNames = getSuggestedNames(initializer);
- replaceAll &= occurrences.size() > 0;
+ }
+
+ protected void performInplaceIntroduce(IntroduceOperation operation) {
+ final PyAssignmentStatement statement = performRefactoring(operation);
+ PyTargetExpression target = (PyTargetExpression) statement.getTargets() [0];
+ final List occurrences = operation.getOccurrences();
+ final InplaceVariableIntroducer introducer =
+ new PyInplaceVariableIntroducer(target, operation, occurrences);
+ introducer.performInplaceRename(false, new LinkedHashSet(operation.getSuggestedNames()));
+ }
- if (name == null) {
- PyIntroduceDialog dialog = new PyIntroduceDialog(project, initializer, myDialogTitle, myValidator, occurrences.size(), possibleNames, getHelpId(), hasConstructor, isTestClass);
+ protected void performIntroduceWithDialog(IntroduceOperation operation) {
+ final Project project = operation.getProject();
+ if (operation.getName() == null) {
+ PyIntroduceDialog dialog = new PyIntroduceDialog(project, myDialogTitle, myValidator, getHelpId(), operation);
dialog.show();
if (!dialog.isOK()) {
return;
}
- name = dialog.getName();
- replaceAll = dialog.doReplaceAllOccurrences();
- initInConstructor = dialog.getInitPlace();
+ operation.setName(dialog.getName());
+ operation.setReplaceAll(dialog.doReplaceAllOccurrences());
+ operation.setInitPlace(dialog.getInitPlace());
}
- initInConstructor = initInConstructor != null ? initInConstructor : InitPlace.SAME_METHOD;
- String assignmentText = name + " = " + initializer.getText().replace("\n", " ");
- PsiElement anchor = replaceAll ? findAnchor(occurrences) : PsiTreeUtil.getParentOfType(initializer, PyStatement.class);
- PyAssignmentStatement declaration = createDeclaration(project, assignmentText, anchor);
-
- assert name != null;
- declaration = performReplace(project, element, declaration, initializer, occurrences, name, replaceAll, initInConstructor);
- declaration = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(declaration);
+ PyAssignmentStatement declaration = performRefactoring(operation);
+ final Editor editor = operation.getEditor();
editor.getCaretModel().moveToOffset(declaration.getTextRange().getEndOffset());
editor.getSelectionModel().removeSelection();
}
+ protected PyAssignmentStatement performRefactoring(IntroduceOperation operation) {
+ PyAssignmentStatement declaration = createDeclaration(operation);
+
+ declaration = performReplace(declaration, operation);
+ declaration = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(declaration);
+ return declaration;
+ }
+
+ public PyAssignmentStatement createDeclaration(IntroduceOperation operation) {
+ final Project project = operation.getProject();
+ final PyExpression initializer = operation.getInitializer();
+ String assignmentText = operation.getName() + " = " + initializer.getText().replace("\n", " ");
+ PsiElement anchor = operation.isReplaceAll()
+ ? findAnchor(operation.getOccurrences())
+ : PsiTreeUtil.getParentOfType(initializer, PyStatement.class);
+ return createDeclaration(project, assignmentText, anchor);
+ }
+
protected abstract String getHelpId();
protected PyAssignmentStatement createDeclaration(Project project, String assignmentText, PsiElement anchor) {
@@ -333,40 +394,47 @@ abstract public class IntroduceHandler implements RefactoringActionHandler {
return PyRefactoringUtil.getOccurrences(expression, context);
}
- private PyAssignmentStatement performReplace(@NotNull final Project project,
- final PsiElement element,
- @NotNull final PyAssignmentStatement declaration,
- @NotNull final PsiElement expression,
- @NotNull final List occurrences,
- @NotNull final String name,
- final boolean replaceAll,
- final InitPlace initInConstructor) {
+ private PyAssignmentStatement performReplace(@NotNull final PyAssignmentStatement declaration,
+ final IntroduceOperation operation) {
+ final PyExpression expression = operation.getInitializer();
+ final Project project = operation.getProject();
return new WriteCommandAction(project, expression.getContainingFile()) {
protected void run(final Result result) throws Throwable {
- final Pair data = expression.getUserData(PyPsiUtils.SELECTION_BREAKS_AST_NODE);
- if (data == null) {
- result.setResult((PyAssignmentStatement)addDeclaration(expression, declaration, occurrences, replaceAll, initInConstructor));
- }
- else {
- result.setResult((PyAssignmentStatement)addDeclaration(data.first, declaration, occurrences, replaceAll, initInConstructor));
- }
+ result.setResult(addDeclaration(operation, declaration));
- PyExpression newExpression = createExpression(project, name, declaration);
+ PyExpression newExpression = createExpression(project, operation.getName(), declaration);
- if (replaceAll) {
- for (PsiElement occurrence : occurrences) {
- replaceExpression(newExpression, project, occurrence);
+ if (operation.isReplaceAll()) {
+ List newOccurrences = new ArrayList();
+ for (PsiElement occurrence : operation.getOccurrences()) {
+ final PsiElement replaced = replaceExpression(newExpression, project, occurrence);
+ if (replaced != null) {
+ newOccurrences.add(replaced);
+ }
}
+ operation.setOccurrences(newOccurrences);
}
else {
replaceExpression(newExpression, project, expression);
}
- postRefactoring(element);
+ postRefactoring(operation.getElement());
}
}.execute().getResultObject();
}
+ @Nullable
+ public PyAssignmentStatement addDeclaration(IntroduceOperation operation, PyAssignmentStatement declaration) {
+ final PsiElement expression = operation.getInitializer();
+ final Pair data = expression.getUserData(PyPsiUtils.SELECTION_BREAKS_AST_NODE);
+ if (data == null) {
+ return (PyAssignmentStatement)addDeclaration(expression, declaration, operation);
+ }
+ else {
+ return (PyAssignmentStatement)addDeclaration(data.first, declaration, operation);
+ }
+ }
+
protected PyExpression createExpression(Project project, String name, PyAssignmentStatement declaration) {
return PyElementGenerator.getInstance(project).createExpressionFromText(name);
}
@@ -374,10 +442,25 @@ abstract public class IntroduceHandler implements RefactoringActionHandler {
@Nullable
protected abstract PsiElement addDeclaration(@NotNull final PsiElement expression,
@NotNull final PsiElement declaration,
- @NotNull final List occurrences,
- final boolean replaceAll,
- final InitPlace initInConstructor);
+ @NotNull IntroduceOperation operation);
protected void postRefactoring(PsiElement element) {
}
+
+ private static class PyInplaceVariableIntroducer extends InplaceVariableIntroducer {
+ private final PyTargetExpression myTarget;
+
+ public PyInplaceVariableIntroducer(PyTargetExpression target,
+ IntroduceOperation operation,
+ List occurrences) {
+ super(target, operation.getEditor(), operation.getProject(), "Introduce Variable",
+ occurrences.toArray(new PsiElement[occurrences.size()]), null);
+ myTarget = target;
+ }
+
+ @Override
+ protected PsiElement checkLocalScope() {
+ return myTarget.getContainingFile();
+ }
+ }
}
diff --git a/python/src/com/jetbrains/python/refactoring/introduce/IntroduceOperation.java b/python/src/com/jetbrains/python/refactoring/introduce/IntroduceOperation.java
new file mode 100644
index 000000000000..06b203f8d655
--- /dev/null
+++ b/python/src/com/jetbrains/python/refactoring/introduce/IntroduceOperation.java
@@ -0,0 +1,122 @@
+package com.jetbrains.python.refactoring.introduce;
+
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.jetbrains.python.psi.PyExpression;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author yole
+ */
+public class IntroduceOperation {
+ private final Project myProject;
+ private final Editor myEditor;
+ private final PsiFile myFile;
+ private String myName;
+ private IntroduceHandler.InitPlace myInitPlace = IntroduceHandler.InitPlace.SAME_METHOD;
+ private boolean myReplaceAll;
+ private final boolean myHasConstructor;
+ private final boolean myTestClass;
+ private PsiElement myElement;
+ private PyExpression myInitializer;
+ private List myOccurrences = Collections.emptyList();
+ private Collection mySuggestedNames;
+
+ public IntroduceOperation(Project project,
+ Editor editor,
+ PsiFile file,
+ String name,
+ boolean replaceAll,
+ boolean hasConstructor,
+ boolean testClass) {
+ myProject = project;
+ myEditor = editor;
+ myFile = file;
+ myName = name;
+ myReplaceAll = replaceAll;
+ myHasConstructor = hasConstructor;
+ myTestClass = testClass;
+ }
+
+ public String getName() {
+ return myName;
+ }
+
+ public void setName(@Nullable String name) {
+ myName = name;
+ }
+
+ public Project getProject() {
+ return myProject;
+ }
+
+ public Editor getEditor() {
+ return myEditor;
+ }
+
+ public PsiFile getFile() {
+ return myFile;
+ }
+
+ public PsiElement getElement() {
+ return myElement;
+ }
+
+ public void setElement(PsiElement element) {
+ myElement = element;
+ }
+
+ public IntroduceHandler.InitPlace getInitPlace() {
+ return myInitPlace;
+ }
+
+ public void setInitPlace(IntroduceHandler.InitPlace initPlace) {
+ myInitPlace = initPlace;
+ }
+
+ public boolean isReplaceAll() {
+ return myReplaceAll;
+ }
+
+ public void setReplaceAll(boolean replaceAll) {
+ myReplaceAll = replaceAll;
+ }
+
+ public PyExpression getInitializer() {
+ return myInitializer;
+ }
+
+ public void setInitializer(PyExpression initializer) {
+ myInitializer = initializer;
+ }
+
+ public List getOccurrences() {
+ return myOccurrences;
+ }
+
+ public void setOccurrences(List occurrences) {
+ myOccurrences = occurrences;
+ }
+
+ public Collection getSuggestedNames() {
+ return mySuggestedNames;
+ }
+
+ public void setSuggestedNames(Collection suggestedNames) {
+ mySuggestedNames = suggestedNames;
+ }
+
+ public boolean hasConstructor() {
+ return myHasConstructor;
+ }
+
+ public boolean isTestClass() {
+ return myTestClass;
+ }
+}
diff --git a/python/src/com/jetbrains/python/refactoring/introduce/PyIntroduceDialog.java b/python/src/com/jetbrains/python/refactoring/introduce/PyIntroduceDialog.java
index f9276fd47f6c..77875e714474 100644
--- a/python/src/com/jetbrains/python/refactoring/introduce/PyIntroduceDialog.java
+++ b/python/src/com/jetbrains/python/refactoring/introduce/PyIntroduceDialog.java
@@ -42,26 +42,22 @@ public class PyIntroduceDialog extends DialogWrapper implements PyIntroduceSetti
private final String myHelpId;
public PyIntroduceDialog(@NotNull final Project project,
- @NotNull PyExpression expression,
@NotNull final String caption,
@NotNull final IntroduceValidator validator,
- final int occurrencesCount,
- final Collection possibleNames,
final String helpId,
- boolean hasConstructor,
- boolean isTestClass) {
+ final IntroduceOperation operation) {
super(project, true);
- myOccurrencesCount = occurrencesCount;
+ myOccurrencesCount = operation.getOccurrences().size();
myValidator = validator;
myProject = project;
- myExpression = expression;
+ myExpression = operation.getInitializer();
myHelpId = helpId;
- setUpNameComboBox(possibleNames);
+ setUpNameComboBox(operation.getSuggestedNames());
setModal(true);
setTitle(caption);
init();
- setupDialog(hasConstructor, isTestClass);
+ setupDialog(operation.hasConstructor(), operation.isTestClass());
updateControls();
}
diff --git a/python/src/com/jetbrains/python/refactoring/introduce/constant/ConstantIntroduceHandler.java b/python/src/com/jetbrains/python/refactoring/introduce/constant/PyIntroduceConstantHandler.java
similarity index 79%
rename from python/src/com/jetbrains/python/refactoring/introduce/constant/ConstantIntroduceHandler.java
rename to python/src/com/jetbrains/python/refactoring/introduce/constant/PyIntroduceConstantHandler.java
index 1b1e0d99debf..8a3a4d04a677 100644
--- a/python/src/com/jetbrains/python/refactoring/introduce/constant/ConstantIntroduceHandler.java
+++ b/python/src/com/jetbrains/python/refactoring/introduce/constant/PyIntroduceConstantHandler.java
@@ -7,25 +7,23 @@ import com.jetbrains.python.codeInsight.imports.AddImportHelper;
import com.jetbrains.python.psi.PyExpression;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.refactoring.introduce.IntroduceHandler;
+import com.jetbrains.python.refactoring.introduce.IntroduceOperation;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
-import java.util.List;
/**
* @author Alexey.Ivanov
*/
-public class ConstantIntroduceHandler extends IntroduceHandler {
- public ConstantIntroduceHandler() {
+public class PyIntroduceConstantHandler extends IntroduceHandler {
+ public PyIntroduceConstantHandler() {
super(new ConstantValidator(), PyBundle.message("refactoring.introduce.constant.dialog.title"));
}
@Override
protected PsiElement addDeclaration(@NotNull final PsiElement expression,
@NotNull final PsiElement declaration,
- @NotNull final List occurrences,
- final boolean replaceAll,
- InitPlace initInConstructor) {
+ @NotNull final IntroduceOperation operation) {
final PsiElement anchor = expression.getContainingFile();
assert anchor instanceof PyFile;
return anchor.addBefore(declaration, AddImportHelper.getFileInsertPosition((PyFile)anchor));
diff --git a/python/src/com/jetbrains/python/refactoring/introduce/field/FieldIntroduceHandler.java b/python/src/com/jetbrains/python/refactoring/introduce/field/PyIntroduceFieldHandler.java
similarity index 62%
rename from python/src/com/jetbrains/python/refactoring/introduce/field/FieldIntroduceHandler.java
rename to python/src/com/jetbrains/python/refactoring/introduce/field/PyIntroduceFieldHandler.java
index 652f2bdfd1d5..75c694706baf 100644
--- a/python/src/com/jetbrains/python/refactoring/introduce/field/FieldIntroduceHandler.java
+++ b/python/src/com/jetbrains/python/refactoring/introduce/field/PyIntroduceFieldHandler.java
@@ -1,6 +1,9 @@
package com.jetbrains.python.refactoring.introduce.field;
+import com.intellij.lang.ASTNode;
import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.application.AccessToken;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -13,6 +16,7 @@ import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.RefactoringBundle;
+import com.intellij.refactoring.introduce.inplace.InplaceVariableIntroducer;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.util.Function;
import com.jetbrains.python.PyNames;
@@ -20,27 +24,26 @@ import com.jetbrains.python.actions.AddFieldQuickFix;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyFunctionBuilder;
import com.jetbrains.python.refactoring.introduce.IntroduceHandler;
+import com.jetbrains.python.refactoring.introduce.IntroduceOperation;
import com.jetbrains.python.refactoring.introduce.variable.PyIntroduceVariableHandler;
import com.jetbrains.python.testing.PythonUnitTestUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
+import javax.swing.*;
+import java.util.*;
/**
* @author Dennis.Ushakov
*/
-public class FieldIntroduceHandler extends IntroduceHandler {
+public class PyIntroduceFieldHandler extends IntroduceHandler {
- public FieldIntroduceHandler() {
+ public PyIntroduceFieldHandler() {
super(new IntroduceFieldValidator(), RefactoringBundle.message("introduce.field.title"));
}
public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
- performAction(project, editor, file, null, InitPlace.SAME_METHOD, false, true, isTestClass(file, editor));
+ performAction(new IntroduceOperation(project, editor, file, null, false, true, isTestClass(file, editor)));
}
private static boolean isTestClass(PsiFile file, Editor editor) {
@@ -76,22 +79,23 @@ public class FieldIntroduceHandler extends IntroduceHandler {
@Nullable
@Override
- protected PsiElement addDeclaration(@NotNull PsiElement expression, @NotNull PsiElement declaration, @NotNull List occurrences,
- boolean replaceAll, InitPlace initInConstructor) {
+ protected PsiElement addDeclaration(@NotNull PsiElement expression, @NotNull PsiElement declaration, @NotNull IntroduceOperation operation) {
final PsiElement expr = expression instanceof PyClass ? expression : expression.getParent();
PsiElement anchor = PyUtil.getContainingClassOrSelf(expr);
assert anchor instanceof PyClass;
final PyClass clazz = (PyClass)anchor;
final Project project = anchor.getProject();
- if (initInConstructor == InitPlace.CONSTRUCTOR && !inConstructor(clazz, expression)) {
+ if (operation.getInitPlace() == InitPlace.CONSTRUCTOR && !inConstructor(expression)) {
return AddFieldQuickFix.addFieldToInit(project, clazz, "", new AddFieldDeclaration(declaration));
- } else if (initInConstructor == InitPlace.SET_UP) {
- return addFieldToSetUp(project, clazz, declaration);
+ } else if (operation.getInitPlace() == InitPlace.SET_UP) {
+ return addFieldToSetUp(clazz, new AddFieldDeclaration(declaration));
}
- return PyIntroduceVariableHandler.doIntroduceVariable(expression, declaration, occurrences, replaceAll);
+ return PyIntroduceVariableHandler.doIntroduceVariable(expression, declaration, operation.getOccurrences(), operation.isReplaceAll());
}
- private boolean inConstructor(@Nullable PyClass clazz, @NotNull PsiElement expression) {
+ private static boolean inConstructor(@NotNull PsiElement expression) {
+ final PsiElement expr = expression instanceof PyClass ? expression : expression.getParent();
+ PyClass clazz = PyUtil.getContainingClassOrSelf(expr);
PsiElement current = PyUtil.getConcealingParent(expression);
if (clazz != null && current != null && current instanceof PyFunction) {
PyFunction init = clazz.findMethodByName(PyNames.INIT, false);
@@ -103,18 +107,18 @@ public class FieldIntroduceHandler extends IntroduceHandler {
}
@Nullable
- private static PsiElement addFieldToSetUp(Project project, PyClass clazz, PsiElement declaration) {
+ private static PsiElement addFieldToSetUp(PyClass clazz, final Function callback) {
final PyFunction init = clazz.findMethodByName(PythonUnitTestUtil.TESTCASE_SETUP_NAME, false);
if (init != null) {
- return AddFieldQuickFix.appendToInit(init, new AddFieldDeclaration(declaration));
+ return AddFieldQuickFix.appendToMethod(init, callback);
}
final PyFunctionBuilder builder = new PyFunctionBuilder(PythonUnitTestUtil.TESTCASE_SETUP_NAME);
builder.parameter(PyNames.CANONICAL_SELF);
- PyFunction setUp = builder.buildFunction(project, LanguageLevel.getDefault());
+ PyFunction setUp = builder.buildFunction(clazz.getProject(), LanguageLevel.getDefault());
final PyStatementList statements = clazz.getStatementList();
final PsiElement anchor = statements.getFirstChild();
setUp = (PyFunction)statements.addBefore(setUp, anchor);
- return AddFieldQuickFix.appendToInit(setUp, new AddFieldDeclaration(declaration));
+ return AddFieldQuickFix.appendToMethod(setUp, callback);
}
@Override
@@ -217,4 +221,89 @@ public class FieldIntroduceHandler extends IntroduceHandler {
text.replaceFirst(PyNames.CANONICAL_SELF + "\\.", self_name + "."));
}
}
+
+ @Override
+ protected void performInplaceIntroduce(IntroduceOperation operation) {
+ final PyAssignmentStatement statement = performRefactoring(operation);
+ // put caret on identifier after "self."
+ putCaretOnFieldName(operation.getEditor(), statement);
+ PyTargetExpression target = (PyTargetExpression) statement.getTargets() [0];
+ final List occurrences = operation.getOccurrences();
+ final InplaceVariableIntroducer introducer =
+ new PyInplaceFieldIntroducer(target, operation, occurrences);
+ introducer.performInplaceRename(false, new LinkedHashSet(operation.getSuggestedNames()));
+ }
+
+ private static void putCaretOnFieldName(Editor editor, PyAssignmentStatement statement) {
+ final PsiElement elementAtOffset = statement.getContainingFile().findElementAt(editor.getCaretModel().getOffset());
+ PyQualifiedExpression qExpr = PsiTreeUtil.getParentOfType(elementAtOffset, PyQualifiedExpression.class);
+ if (qExpr != null && qExpr.getQualifier() == null) {
+ qExpr = PsiTreeUtil.getParentOfType(qExpr, PyQualifiedExpression.class);
+ }
+ if (qExpr != null) {
+ final ASTNode nameElement = qExpr.getNameElement();
+ if (nameElement != null) {
+ final int offset = nameElement.getTextRange().getStartOffset();
+ editor.getCaretModel().moveToOffset(offset);
+ }
+ }
+ }
+
+ private static class PyInplaceFieldIntroducer extends InplaceVariableIntroducer {
+ private final PyTargetExpression myTarget;
+ private final PyIntroduceFieldPanel myPanel;
+
+ public PyInplaceFieldIntroducer(PyTargetExpression target,
+ IntroduceOperation operation,
+ List occurrences) {
+ super(target, operation.getEditor(), operation.getProject(), "Introduce Field",
+ occurrences.toArray(new PsiElement[occurrences.size()]), null);
+ myTarget = target;
+ if (!inConstructor(target)) {
+ myPanel = new PyIntroduceFieldPanel(myProject, operation.isTestClass());
+ }
+ else {
+ myPanel = null;
+ }
+ }
+
+ @Override
+ protected PsiElement checkLocalScope() {
+ return myTarget.getContainingFile();
+ }
+
+ @Override
+ protected JComponent getComponent() {
+ return myPanel == null ? null : myPanel.getRootPanel();
+ }
+
+ @Override
+ public void finish() {
+ super.finish();
+ if (myPanel != null && myPanel.getInitPlace() != InitPlace.SAME_METHOD) {
+ final AccessToken accessToken = ApplicationManager.getApplication().acquireWriteActionLock(getClass());
+ try {
+ final PyAssignmentStatement initializer = PsiTreeUtil.getParentOfType(myTarget, PyAssignmentStatement.class);
+ assert initializer != null;
+ final Function callback = new Function() {
+ @Override
+ public PyStatement fun(String s) {
+ return initializer;
+ }
+ };
+ final PyClass pyClass = PyUtil.getContainingClassOrSelf(initializer);
+ if (myPanel.getInitPlace() == InitPlace.CONSTRUCTOR) {
+ AddFieldQuickFix.addFieldToInit(myProject, pyClass, "", callback);
+ }
+ else if (myPanel.getInitPlace() == InitPlace.SET_UP) {
+ addFieldToSetUp(pyClass, callback);
+ }
+ initializer.delete();
+ }
+ finally {
+ accessToken.finish();
+ }
+ }
+ }
+ }
}
diff --git a/python/src/com/jetbrains/python/refactoring/introduce/field/PyIntroduceFieldPanel.form b/python/src/com/jetbrains/python/refactoring/introduce/field/PyIntroduceFieldPanel.form
new file mode 100644
index 000000000000..2f0c34f27925
--- /dev/null
+++ b/python/src/com/jetbrains/python/refactoring/introduce/field/PyIntroduceFieldPanel.form
@@ -0,0 +1,40 @@
+
+
diff --git a/python/src/com/jetbrains/python/refactoring/introduce/field/PyIntroduceFieldPanel.java b/python/src/com/jetbrains/python/refactoring/introduce/field/PyIntroduceFieldPanel.java
new file mode 100644
index 000000000000..3a0fdb340a72
--- /dev/null
+++ b/python/src/com/jetbrains/python/refactoring/introduce/field/PyIntroduceFieldPanel.java
@@ -0,0 +1,38 @@
+package com.jetbrains.python.refactoring.introduce.field;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.refactoring.introduce.inplace.KeyboardComboSwitcher;
+import com.jetbrains.python.refactoring.introduce.IntroduceHandler;
+
+import javax.swing.*;
+
+/**
+ * @author yole
+ */
+public class PyIntroduceFieldPanel {
+ private JPanel myRootPanel;
+ private JComboBox myInitializerPlaceCombo;
+
+ public PyIntroduceFieldPanel(Project project, boolean testClass) {
+ KeyboardComboSwitcher.setupActions(myInitializerPlaceCombo, project);
+ if (testClass) {
+ ((DefaultComboBoxModel) myInitializerPlaceCombo.getModel()).addElement("setUp() method");
+ }
+ }
+
+ public JPanel getRootPanel() {
+ return myRootPanel;
+ }
+
+ public IntroduceHandler.InitPlace getInitPlace() {
+ final int index = myInitializerPlaceCombo.getSelectedIndex();
+ switch (index) {
+ case 1:
+ return IntroduceHandler.InitPlace.CONSTRUCTOR;
+ case 2:
+ return IntroduceHandler.InitPlace.SET_UP;
+ default:
+ return IntroduceHandler.InitPlace.SAME_METHOD;
+ }
+ }
+}
diff --git a/python/src/com/jetbrains/python/refactoring/introduce/variable/PyIntroduceVariableHandler.java b/python/src/com/jetbrains/python/refactoring/introduce/variable/PyIntroduceVariableHandler.java
index 7c0146a86b3e..1e3473c0e3f3 100644
--- a/python/src/com/jetbrains/python/refactoring/introduce/variable/PyIntroduceVariableHandler.java
+++ b/python/src/com/jetbrains/python/refactoring/introduce/variable/PyIntroduceVariableHandler.java
@@ -5,6 +5,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.psi.PyStatement;
import com.jetbrains.python.refactoring.introduce.IntroduceHandler;
+import com.jetbrains.python.refactoring.introduce.IntroduceOperation;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -20,10 +21,8 @@ public class PyIntroduceVariableHandler extends IntroduceHandler {
@Override
protected PsiElement addDeclaration(@NotNull final PsiElement expression,
@NotNull final PsiElement declaration,
- @NotNull final List occurrences,
- final boolean replaceAll,
- InitPlace initInConstructor) {
- return doIntroduceVariable(expression, declaration, occurrences, replaceAll);
+ @NotNull IntroduceOperation operation) {
+ return doIntroduceVariable(expression, declaration, operation.getOccurrences(), operation.isReplaceAll());
}
public static PsiElement doIntroduceVariable(PsiElement expression,
diff --git a/python/testData/formatter/lambdaColon.py b/python/testData/formatter/lambdaColon.py
new file mode 100644
index 000000000000..b46986036c6b
--- /dev/null
+++ b/python/testData/formatter/lambdaColon.py
@@ -0,0 +1 @@
+lambda o:o.fullName()
diff --git a/python/testData/formatter/lambdaColon_after.py b/python/testData/formatter/lambdaColon_after.py
new file mode 100644
index 000000000000..497e4dc07ffa
--- /dev/null
+++ b/python/testData/formatter/lambdaColon_after.py
@@ -0,0 +1 @@
+lambda o: o.fullName()
diff --git a/python/testData/psi/ConditionalParenLambda.txt b/python/testData/psi/ConditionalParenLambda.txt
index 0b46ac94c48c..b520d5732a99 100644
--- a/python/testData/psi/ConditionalParenLambda.txt
+++ b/python/testData/psi/ConditionalParenLambda.txt
@@ -25,7 +25,7 @@ PyFile:ConditionalParenLambda.py
PyParameterList
PyNamedParameter('x')
PsiElement(Py:IDENTIFIER)('x')
- PsiElement(Py:COLON)(':')
+ PsiElement(Py:COLON)(':')
PsiWhiteSpace(' ')
PyConditionalExpression
PyReferenceExpression: x
diff --git a/python/testData/psi/LambdaComprehension.txt b/python/testData/psi/LambdaComprehension.txt
index 6131eb274b0c..ebd6e914655e 100644
--- a/python/testData/psi/LambdaComprehension.txt
+++ b/python/testData/psi/LambdaComprehension.txt
@@ -16,7 +16,8 @@ PyFile:LambdaComprehension.py
PyLambdaExpression
PsiElement(Py:LAMBDA_KEYWORD)('lambda')
PyParameterList
- PsiElement(Py:COLON)(':')
+
+ PsiElement(Py:COLON)(':')
PsiWhiteSpace(' ')
PyReferenceExpression: True
PsiElement(Py:IDENTIFIER)('True')
@@ -25,7 +26,8 @@ PyFile:LambdaComprehension.py
PyLambdaExpression
PsiElement(Py:LAMBDA_KEYWORD)('lambda')
PyParameterList
- PsiElement(Py:COLON)(':')
+
+ PsiElement(Py:COLON)(':')
PsiWhiteSpace(' ')
PyReferenceExpression: False
PsiElement(Py:IDENTIFIER)('False')
diff --git a/python/testData/psi/LambdaConditional.txt b/python/testData/psi/LambdaConditional.txt
index 472135ee99e1..e5c424b8287c 100644
--- a/python/testData/psi/LambdaConditional.txt
+++ b/python/testData/psi/LambdaConditional.txt
@@ -6,7 +6,7 @@ PyFile:LambdaConditional.py
PyParameterList
PyNamedParameter('x')
PsiElement(Py:IDENTIFIER)('x')
- PsiElement(Py:COLON)(':')
+ PsiElement(Py:COLON)(':')
PsiWhiteSpace(' ')
PyConditionalExpression
PyNumericLiteralExpression
diff --git a/python/testSrc/com/jetbrains/python/PyFormatterTest.java b/python/testSrc/com/jetbrains/python/PyFormatterTest.java
index 814518e7d63b..e4e5b7ae80a7 100644
--- a/python/testSrc/com/jetbrains/python/PyFormatterTest.java
+++ b/python/testSrc/com/jetbrains/python/PyFormatterTest.java
@@ -135,6 +135,10 @@ public class PyFormatterTest extends PyLightFixtureTestCase {
CodeStyleSettingsManager.getInstance().getSettings(myFixture.getProject()).ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
doTest();
}
+
+ public void testLambdaColon() {
+ doTest();
+ }
public void testPsiFormatting() { // IDEA-69724
String initial =
diff --git a/python/testSrc/com/jetbrains/python/refactoring/PyIntroduceConstantTest.java b/python/testSrc/com/jetbrains/python/refactoring/PyIntroduceConstantTest.java
index c0ccdfbdd217..e656d57c9773 100644
--- a/python/testSrc/com/jetbrains/python/refactoring/PyIntroduceConstantTest.java
+++ b/python/testSrc/com/jetbrains/python/refactoring/PyIntroduceConstantTest.java
@@ -2,7 +2,7 @@ package com.jetbrains.python.refactoring;
import com.jetbrains.python.fixtures.PyLightFixtureTestCase;
import com.jetbrains.python.psi.LanguageLevel;
-import com.jetbrains.python.refactoring.introduce.constant.ConstantIntroduceHandler;
+import com.jetbrains.python.refactoring.introduce.constant.PyIntroduceConstantHandler;
/**
* @author yole
@@ -32,7 +32,7 @@ public class PyIntroduceConstantTest extends PyLightFixtureTestCase {
private void doTest() {
myFixture.configureByFile("/refactoring/introduceConstant/" + getTestName(true) + ".py");
- ConstantIntroduceHandler handler = new ConstantIntroduceHandler();
+ PyIntroduceConstantHandler handler = new PyIntroduceConstantHandler();
handler.performAction(myFixture.getProject(), myFixture.getEditor(), myFixture.getFile(), "a", true, false, false);
myFixture.checkResultByFile("/refactoring/introduceConstant/" + getTestName(true) + ".after.py");
}
diff --git a/python/testSrc/com/jetbrains/python/refactoring/PyIntroduceFieldTest.java b/python/testSrc/com/jetbrains/python/refactoring/PyIntroduceFieldTest.java
index 35b4cbdbf27e..de405ea2213a 100644
--- a/python/testSrc/com/jetbrains/python/refactoring/PyIntroduceFieldTest.java
+++ b/python/testSrc/com/jetbrains/python/refactoring/PyIntroduceFieldTest.java
@@ -2,7 +2,8 @@ package com.jetbrains.python.refactoring;
import com.jetbrains.python.fixtures.PyLightFixtureTestCase;
import com.jetbrains.python.refactoring.introduce.IntroduceHandler;
-import com.jetbrains.python.refactoring.introduce.field.FieldIntroduceHandler;
+import com.jetbrains.python.refactoring.introduce.IntroduceOperation;
+import com.jetbrains.python.refactoring.introduce.field.PyIntroduceFieldHandler;
/**
* @author yole
@@ -22,8 +23,10 @@ public class PyIntroduceFieldTest extends PyLightFixtureTestCase {
private void doTest(IntroduceHandler.InitPlace initPlace) {
myFixture.configureByFile("/refactoring/introduceField/" + getTestName(true) + ".py");
- FieldIntroduceHandler handler = new FieldIntroduceHandler();
- handler.performAction(myFixture.getProject(), myFixture.getEditor(), myFixture.getFile(), "a", initPlace, true, false, false);
+ PyIntroduceFieldHandler handler = new PyIntroduceFieldHandler();
+ final IntroduceOperation introduceOperation = new IntroduceOperation(myFixture.getProject(), myFixture.getEditor(), myFixture.getFile(), "a", true, false, false);
+ introduceOperation.setInitPlace(initPlace);
+ handler.performAction(introduceOperation);
myFixture.checkResultByFile("/refactoring/introduceField/" + getTestName(true) + ".after.py");
}
}