mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Added names validator for Python Extract method refactoring
This commit is contained in:
@@ -149,6 +149,7 @@ refactoring.extract.method.error.cannot.perform.refactoring.no.corresponding.loo
|
||||
refactoring.extract.method.error.cannot.perform.refactoring.when.execution.flow.is.interrupted=Cannot perform refactoring when execution flow is interrupted
|
||||
refactoring.extract.method.error.cannot.perform.refactoring.when.from.import.inside=Cannot perform refactoring with from import statement inside code block
|
||||
refactoring.extract.method.error.cannot.perform.refactoring.using.selected.elements=Cannot perform extract method using selected element(s)
|
||||
refactoring.extract.method.error.name.clash=Method name clashes with already existing method name
|
||||
|
||||
### Annotators ###
|
||||
ANN.deleting.none=deleting None
|
||||
|
||||
+52
-11
@@ -20,10 +20,13 @@ import com.intellij.refactoring.extractMethod.AbstractVariableData;
|
||||
import com.intellij.refactoring.extractMethod.ExtractMethodDecorator;
|
||||
import com.intellij.refactoring.extractMethod.ExtractMethodValidator;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.hash.HashMap;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PythonLanguage;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -341,12 +344,16 @@ public class PyExtractMethodUtil {
|
||||
private static Pair<String, AbstractVariableData[]> getNameAndVariableData(final Project project,
|
||||
final CodeFragment fragment,
|
||||
final PsiElement element) {
|
||||
final ExtractMethodValidator validator = new PyExtractMethodValidator(element, project);
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()){
|
||||
|
||||
String name = System.getProperty(NAME);
|
||||
if (name == null){
|
||||
name = "foo";
|
||||
}
|
||||
final String result = validator.check(name);
|
||||
if (result != null){
|
||||
throw new CommonRefactoringUtil.RefactoringErrorHintException(result);
|
||||
}
|
||||
final List<AbstractVariableData> data = new ArrayList<AbstractVariableData>();
|
||||
for (String in : fragment.getInputVariables()) {
|
||||
final AbstractVariableData d = new AbstractVariableData();
|
||||
@@ -358,16 +365,6 @@ public class PyExtractMethodUtil {
|
||||
return Pair.create(name, data.toArray(new AbstractVariableData[data.size()]));
|
||||
}
|
||||
|
||||
final ExtractMethodValidator validator = new ExtractMethodValidator() {
|
||||
public String check(final String name) {
|
||||
// TODO[oleg] implement context for name clashes
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isValidName(final String name) {
|
||||
return LanguageNamesValidation.INSTANCE.forLanguage(PythonLanguage.getInstance()).isIdentifier(name, project);
|
||||
}
|
||||
};
|
||||
final boolean isMethod = PyPsiUtils.isMethodContext(element);
|
||||
final ExtractMethodDecorator decorator = new ExtractMethodDecorator() {
|
||||
public String createMethodPreview(final String methodName, final AbstractVariableData[] variableDatas) {
|
||||
@@ -402,5 +399,49 @@ public class PyExtractMethodUtil {
|
||||
return Pair.create(dialog.getMethodName(), dialog.getVariableData());
|
||||
}
|
||||
|
||||
private static class PyExtractMethodValidator implements ExtractMethodValidator {
|
||||
private final PsiElement myElement;
|
||||
private final Project myProject;
|
||||
private final Function<String, Boolean> myFunction;
|
||||
|
||||
public PyExtractMethodValidator(final PsiElement element, final Project project) {
|
||||
myElement = element;
|
||||
myProject = project;
|
||||
final PsiNamedElement parent = PsiTreeUtil.getParentOfType(myElement, PyFile.class, PyClass.class);
|
||||
if (parent instanceof PyFile){
|
||||
final List<PyFunction> functions = ((PyFile)parent).getTopLevelFunctions();
|
||||
myFunction = new Function<String, Boolean>() {
|
||||
public Boolean fun(@NotNull final String s) {
|
||||
for (PyFunction function : functions) {
|
||||
if (s.equals(function.getName())){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
} 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 {
|
||||
myFunction = null;
|
||||
}
|
||||
}
|
||||
|
||||
public String check(final String name) {
|
||||
if (myFunction != null && !myFunction.fun(name)){
|
||||
return PyBundle.message("refactoring.extract.method.error.name.clash");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isValidName(final String name) {
|
||||
return LanguageNamesValidation.INSTANCE.forLanguage(PythonLanguage.getInstance()).isIdentifier(name, myProject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,18 +69,17 @@ public class PyExtractMethodTest extends LightMarkedTestCase {
|
||||
doTest("controlFlow/while_output.before.py", "bar", "controlFlow/while_output.after.py");
|
||||
}
|
||||
|
||||
// TODO[oleg] implement me!!!
|
||||
//public void testNameCollisionClass() throws Throwable {
|
||||
// doTest("namesCollision/class.before.py", "hello", "Method name clashes with already existing method name");
|
||||
//}
|
||||
//
|
||||
//public void testNameCollisionFile() throws Throwable {
|
||||
// doTest("namesCollision/file.before.py", "hello", "Method name clashes with already existing method name");
|
||||
//}
|
||||
//
|
||||
//public void testNameCollisionSuperClass() throws Throwable {
|
||||
// doTest("namesCollision/superclass.before.py", "hello", "Method name clashes with already existing method name");
|
||||
//}
|
||||
public void testNameCollisionClass() throws Throwable {
|
||||
doTest("namesCollision/class.before.py", "hello", "Method name clashes with already existing method name");
|
||||
}
|
||||
|
||||
public void testNameCollisionFile() throws Throwable {
|
||||
doTest("namesCollision/file.before.py", "hello", "Method name clashes with already existing method name");
|
||||
}
|
||||
|
||||
public void testNameCollisionSuperClass() throws Throwable {
|
||||
doTest("namesCollision/superclass.before.py", "hello", "Method name clashes with already existing method name");
|
||||
}
|
||||
|
||||
public void testOutNotEmptyStatements() throws Throwable {
|
||||
doTest("outNotEmpty/statements.before.py", "sum_squares", "outNotEmpty/statements.after.py");
|
||||
|
||||
Reference in New Issue
Block a user