diff --git a/python/src/com/jetbrains/python/formatter/PyBlock.java b/python/src/com/jetbrains/python/formatter/PyBlock.java index 5a5a0f1bf0ee..ae0a1c5be019 100644 --- a/python/src/com/jetbrains/python/formatter/PyBlock.java +++ b/python/src/com/jetbrains/python/formatter/PyBlock.java @@ -1,19 +1,3 @@ -/* - * Copyright 2005 Pythonid Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS"; BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package com.jetbrains.python.formatter; import com.intellij.formatting.*; @@ -30,7 +14,6 @@ import com.jetbrains.python.PyElementTypes; import com.jetbrains.python.PyTokenTypes; import com.jetbrains.python.PythonLanguage; import com.jetbrains.python.psi.*; -import static com.jetbrains.python.psi.PyUtil.sure; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -38,17 +21,18 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import static com.jetbrains.python.psi.PyUtil.sure; + /** * @author yole */ public class PyBlock implements Block { - //TOLATER: fix formatter private final PythonLanguage _language; private final Alignment _alignment; private final Indent _indent; private final ASTNode _node; private final Wrap _wrap; - private final CodeStyleSettings _settings; + private final CodeStyleSettings mySettings; private List _subBlocks = null; private final Alignment _childListAlignment; private final TokenSet _listElementTypes; @@ -65,7 +49,7 @@ public class PyBlock implements Block { _indent = indent; _node = node; _wrap = wrap; - _settings = settings; + mySettings = settings; _childListAlignment = Alignment.createAlignment(); _listElementTypes = TokenSet.create(PyElementTypes.LIST_LITERAL_EXPRESSION, PyElementTypes.LIST_COMP_EXPRESSION, @@ -150,7 +134,7 @@ public class PyBlock implements Block { // not our cup of tea } - return new PyBlock(_language, child, childAlignment, childIndent, wrap, _settings); + return new PyBlock(_language, child, childAlignment, childIndent, wrap, mySettings); } private static boolean hasLineBreakBefore(ASTNode child) { @@ -200,6 +184,12 @@ public class PyBlock implements Block { IElementType parentType = _node.getElementType(); IElementType type1 = childNode1.getElementType(); IElementType type2 = childNode2.getElementType(); + + if (type1 == PyElementTypes.FUNCTION_DECLARATION) { + int blankLines = mySettings.BLANK_LINES_AROUND_METHOD + 1; + return Spacing.createSpacing(0, 0, blankLines, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_DECLARATIONS); + } + if (isStatementOrDeclaration(type1) && isStatementOrDeclaration(type2)) { return Spacing.createSpacing(0, Integer.MAX_VALUE, 1, false, 1); } @@ -221,7 +211,7 @@ public class PyBlock implements Block { //} //return new PySpacingProcessor(getNode(), childNode1, childNode2, - // _settings).getResult(); + // mySettings).getResult(); //return Spacing.createSpacing(0, Integer.MAX_VALUE, 1, true, Integer.MAX_VALUE); return null; @@ -281,7 +271,7 @@ public class PyBlock implements Block { // delegation sometimes causes NPEs in formatter core, so we calculate the // correct indent manually. if (statementListsBelow > 0) { // was 1... strange - int indent = _settings.getIndentSize(_language.getAssociatedFileType()); + int indent = mySettings.getIndentSize(_language.getAssociatedFileType()); return new ChildAttributes(Indent.getSpaceIndent(indent * statementListsBelow), null); } diff --git a/python/testData/formatter/blankLineBetweenMethods.py b/python/testData/formatter/blankLineBetweenMethods.py new file mode 100644 index 000000000000..54dab3e9134c --- /dev/null +++ b/python/testData/formatter/blankLineBetweenMethods.py @@ -0,0 +1,4 @@ +def foo(): + pass +def bar(): + pass \ No newline at end of file diff --git a/python/testData/formatter/blankLineBetweenMethods_after.py b/python/testData/formatter/blankLineBetweenMethods_after.py new file mode 100644 index 000000000000..ccd6736bb022 --- /dev/null +++ b/python/testData/formatter/blankLineBetweenMethods_after.py @@ -0,0 +1,5 @@ +def foo(): + pass + +def bar(): + pass \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyFormatterTest.java b/python/testSrc/com/jetbrains/python/PyFormatterTest.java new file mode 100644 index 000000000000..e1e4aac7706c --- /dev/null +++ b/python/testSrc/com/jetbrains/python/PyFormatterTest.java @@ -0,0 +1,20 @@ +package com.jetbrains.python; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.jetbrains.python.fixtures.PyLightFixtureTestCase; + +/** + * @author yole + */ +public class PyFormatterTest extends PyLightFixtureTestCase { + public void testBlankLineBetweenMethods() throws Exception { + myFixture.configureByFile("formatter/" + getTestName(true) + ".py"); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + CodeStyleManager.getInstance(myFixture.getProject()).reformat(myFixture.getFile()); + } + }); + myFixture.checkResultByFile("formatter/" + getTestName(true) + "_after.py"); + } +} diff --git a/python/testSrc/com/jetbrains/python/PythonAllTestsSuite.java b/python/testSrc/com/jetbrains/python/PythonAllTestsSuite.java index 0c0ba4d46290..86ef675c5c06 100644 --- a/python/testSrc/com/jetbrains/python/PythonAllTestsSuite.java +++ b/python/testSrc/com/jetbrains/python/PythonAllTestsSuite.java @@ -37,11 +37,12 @@ public class PythonAllTestsSuite { PySelectWordTest.class, PySurroundWithTest.class, PyEditingTest.class, + PyFormatterTest.class, PyRenameTest.class, PyExtractMethodTest.class, PyPullUpTest.class, PyPushDownTest.class, - PyExtractSuperclassTest.class + PyExtractSuperclassTest.class, }; public static TestSuite suite() {