work in progress on fixing python surround

This commit is contained in:
Dmitry Jemerov
2009-12-08 20:56:23 +03:00
parent 31cce7674e
commit 77a3189d40
14 changed files with 97 additions and 16 deletions
@@ -1,9 +1,6 @@
package com.jetbrains.python;
import com.intellij.formatting.FormattingModel;
import com.intellij.formatting.FormattingModelBuilder;
import com.intellij.formatting.FormattingModelProvider;
import com.intellij.formatting.Indent;
import com.intellij.formatting.*;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
@@ -16,7 +13,7 @@ import org.jetbrains.annotations.NotNull;
* @author yole
*/
public class PythonFormattingModelBuilder implements FormattingModelBuilder {
private static final boolean DUMP_FORMATTING_AST = false;
private static final boolean DUMP_FORMATTING_AST = true;
@NotNull
public FormattingModel createModel(final PsiElement element, final CodeStyleSettings settings) {
@@ -27,6 +24,7 @@ public class PythonFormattingModelBuilder implements FormattingModelBuilder {
}
final PyBlock block = new PyBlock((PythonLanguage)PythonFileType.INSTANCE.getLanguage(),
element.getNode(), null, Indent.getNoneIndent(), null, settings);
FormattingModelDumper.dumpFormattingModel(block, 2, System.out);
return FormattingModelProvider.createFormattingModelForPsiFile(element.getContainingFile(), block, settings);
}
@@ -34,7 +32,7 @@ public class PythonFormattingModelBuilder implements FormattingModelBuilder {
return null;
}
private void printAST(ASTNode node, int indent) {
private static void printAST(ASTNode node, int indent) {
while (node != null) {
for (int i = 0; i < indent; i++) {
System.out.print(" ");
@@ -17,7 +17,7 @@ import org.jetbrains.annotations.NotNull;
public class PyStatementSurroundDescriptor implements SurroundDescriptor {
private static Surrounder[] SURROUNDERS =
{new PyWithIfSurrounder(), new PyWithIfElseSurrounder(), new PyWithWhileSurrounder(), new PyWithWhileElseSurrounder(),
new PyWithReturnSurrounder(), new PyWithTryExceptSurrounder(), new PyWithTryFinnalySurrounder()};
new PyWithReturnSurrounder(), new PyWithTryExceptSurrounder(), new PyWithTryFinallySurrounder()};
@NotNull
public PsiElement[] getElementsToSurround(PsiFile file, int startOffset, int endOffset) {
@@ -9,6 +9,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.util.IncorrectOperationException;
import com.jetbrains.python.PythonLanguage;
import com.jetbrains.python.psi.PyIfStatement;
import com.jetbrains.python.psi.PyStatementList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -24,9 +25,13 @@ public class PyWithIfElseSurrounder extends PyStatementSurrounder {
protected TextRange surroundStatement(@NotNull Project project, @NotNull Editor editor, @NotNull PsiElement[] elements)
throws IncorrectOperationException {
PyIfStatement ifStatement =
PythonLanguage.getInstance().getElementGenerator().createFromText(project, PyIfStatement.class, "if True:\n \nelse:\n");
PythonLanguage.getInstance().getElementGenerator().createFromText(project, PyIfStatement.class, "if True:\n pass\nelse: pass\n");
final PsiElement parent = elements[0].getParent();
ifStatement.getIfPart().addRange(elements[0], elements[elements.length - 1]);
final PyStatementList statementList = ifStatement.getIfPart().getStatementList();
assert statementList != null;
statementList.addRange(elements[0], elements[elements.length - 1]);
statementList.deleteChildRange(statementList.getFirstChild(), statementList.getFirstChild());
ifStatement = (PyIfStatement) parent.addBefore(ifStatement, elements[0]);
parent.deleteChildRange(elements[0], elements[elements.length - 1]);
@@ -9,6 +9,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.util.IncorrectOperationException;
import com.jetbrains.python.PythonLanguage;
import com.jetbrains.python.psi.PyIfStatement;
import com.jetbrains.python.psi.PyStatementList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -26,7 +27,9 @@ public class PyWithIfSurrounder extends PyStatementSurrounder {
PyIfStatement ifStatement =
PythonLanguage.getInstance().getElementGenerator().createFromText(project, PyIfStatement.class, "if True:\n ");
final PsiElement parent = elements[0].getParent();
ifStatement.getIfPart().addRange(elements[0], elements[elements.length - 1]);
final PyStatementList statementList = ifStatement.getIfPart().getStatementList();
assert statementList != null;
statementList.addRange(elements[0], elements[elements.length - 1]);
ifStatement = (PyIfStatement) parent.addBefore(ifStatement, elements[0]);
parent.deleteChildRange(elements[0], elements[elements.length - 1]);
@@ -34,7 +37,7 @@ public class PyWithIfSurrounder extends PyStatementSurrounder {
if (ifStatement == null) {
return null;
}
return ifStatement.getTextRange();
return ifStatement.getIfPart().getCondition().getTextRange();
}
public String getTemplateDescription() {
@@ -8,6 +8,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.util.IncorrectOperationException;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PythonLanguage;
import com.jetbrains.python.psi.PyStatementList;
import com.jetbrains.python.psi.PyTryExceptStatement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -24,9 +25,12 @@ public class PyWithTryExceptSurrounder extends PyStatementSurrounder {
protected TextRange surroundStatement(@NotNull Project project, @NotNull Editor editor, @NotNull PsiElement[] elements)
throws IncorrectOperationException {
PyTryExceptStatement tryStatement = PythonLanguage.getInstance().getElementGenerator()
.createFromText(project, PyTryExceptStatement.class, "try:\n \nexcept Exception:\n");
.createFromText(project, PyTryExceptStatement.class, "try:\n pass\nexcept:\n pass");
final PsiElement parent = elements[0].getParent();
tryStatement.getTryPart().addRange(elements[0], elements[elements.length - 1]);
final PyStatementList statementList = tryStatement.getTryPart().getStatementList();
assert statementList != null;
statementList.addRange(elements[0], elements[elements.length - 1]);
statementList.getFirstChild().delete();
tryStatement = (PyTryExceptStatement)parent.addBefore(tryStatement, elements[0]);
parent.deleteChildRange(elements[0], elements[elements.length - 1]);
@@ -18,7 +18,7 @@ import org.jetbrains.annotations.Nullable;
* Date: Aug 28, 2009
* Time: 6:52:06 PM
*/
public class PyWithTryFinnalySurrounder extends PyStatementSurrounder {
public class PyWithTryFinallySurrounder extends PyStatementSurrounder {
@Override
@Nullable
protected TextRange surroundStatement(@NotNull Project project, @NotNull Editor editor, @NotNull PsiElement[] elements)
@@ -8,6 +8,8 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.util.IncorrectOperationException;
import com.jetbrains.python.PythonLanguage;
import com.jetbrains.python.psi.PyExpression;
import com.jetbrains.python.psi.PyStatementList;
import com.jetbrains.python.psi.PyWhileStatement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -26,7 +28,9 @@ public class PyWithWhileSurrounder extends PyStatementSurrounder{
PyWhileStatement whileStatement =
PythonLanguage.getInstance().getElementGenerator().createFromText(project, PyWhileStatement.class, "while True:\n ");
final PsiElement parent = elements[0].getParent();
whileStatement.addRange(elements[0], elements[elements.length - 1]);
final PyStatementList statementList = whileStatement.getWhilePart().getStatementList();
assert statementList != null;
statementList.addRange(elements[0], elements[elements.length - 1]);
whileStatement = (PyWhileStatement) parent.addBefore(whileStatement, elements[0]);
parent.deleteChildRange(elements[0], elements[elements.length - 1]);
@@ -34,7 +38,9 @@ public class PyWithWhileSurrounder extends PyStatementSurrounder{
if (whileStatement == null) {
return null;
}
return whileStatement.getTextRange();
final PyExpression condition = whileStatement.getWhilePart().getCondition();
assert condition != null;
return condition.getTextRange();
}
public String getTemplateDescription() {
@@ -0,0 +1,3 @@
def foo():
<selection>print "hello"</selection>
@@ -0,0 +1,4 @@
def foo():
if <selection>True</selection>:
print "hello"
@@ -0,0 +1,3 @@
def foo():
<selection>print "hello"</selection>
@@ -0,0 +1,6 @@
def foo():
try:
print "hello"
except:
<selection>pass</selection>
@@ -0,0 +1,3 @@
def foo():
<selection>print "hello"</selection>
@@ -0,0 +1,4 @@
def foo():
while <selection>True</selection>:
print "hello"
@@ -0,0 +1,42 @@
package com.jetbrains.python;
import com.intellij.codeInsight.generation.surroundWith.SurroundWithHandler;
import com.intellij.lang.surroundWith.Surrounder;
import com.intellij.openapi.command.WriteCommandAction;
import com.jetbrains.python.fixtures.PyLightFixtureTestCase;
import com.jetbrains.python.refactoring.surround.surrounders.statements.PyWithIfSurrounder;
import com.jetbrains.python.refactoring.surround.surrounders.statements.PyWithTryExceptSurrounder;
import com.jetbrains.python.refactoring.surround.surrounders.statements.PyWithWhileSurrounder;
/**
* @author yole
*/
public class PySurroundWithTest extends PyLightFixtureTestCase {
public void testSurroundWithIf() throws Exception {
doTest(new PyWithIfSurrounder());
}
public void testSurroundWithWhile() throws Exception {
doTest(new PyWithWhileSurrounder());
}
public void testSurroundWithTryExcept() throws Exception {
doTest(new PyWithTryExceptSurrounder());
}
private void doTest(final Surrounder surrounder) throws Exception {
String baseName = "/" + getTestName(false);
myFixture.configureByFile(baseName + ".py");
new WriteCommandAction.Simple(myFixture.getProject()) {
@Override
protected void run() throws Throwable {
SurroundWithHandler.invoke(myFixture.getProject(), myFixture.getEditor(), myFixture.getFile(), surrounder);
}
}.execute();
myFixture.checkResultByFile(baseName + "_after.py");
}
protected String getTestDataPath() {
return PythonTestUtil.getTestDataPath() + "/surround/";
}
}