mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-25356 Remove excess blank lines between line comments
The behavior of the formatter follows the way pycodestyle.py warns about these extra empty lines. Namely, it allows at most 2 blank lines after line comments that are directly at the top-level of a file (syntactically, not scope-wise), but only one blank line in any other position.
This commit is contained in:
@@ -90,18 +90,18 @@ public class PyBlock implements ASTBlock {
|
||||
private List<PyBlock> mySubBlocks = null;
|
||||
private Map<ASTNode, PyBlock> mySubBlockByNode = null;
|
||||
private final boolean myEmptySequence;
|
||||
|
||||
|
||||
// Shared among multiple children sub-blocks
|
||||
private Alignment myChildAlignment = null;
|
||||
private Alignment myDictAlignment = null;
|
||||
private Wrap myDictWrapping = null;
|
||||
private Wrap myFromImportWrapping = null;
|
||||
|
||||
public PyBlock(@Nullable PyBlock parent,
|
||||
@NotNull ASTNode node,
|
||||
@Nullable Alignment alignment,
|
||||
@NotNull Indent indent,
|
||||
@Nullable Wrap wrap,
|
||||
public PyBlock(@Nullable PyBlock parent,
|
||||
@NotNull ASTNode node,
|
||||
@Nullable Alignment alignment,
|
||||
@NotNull Indent indent,
|
||||
@Nullable Wrap wrap,
|
||||
@NotNull PyBlockContext context) {
|
||||
myParent = parent;
|
||||
myAlignment = alignment;
|
||||
@@ -189,7 +189,7 @@ public class PyBlock implements ASTBlock {
|
||||
Wrap childWrap = null;
|
||||
Indent childIndent = Indent.getNoneIndent();
|
||||
Alignment childAlignment = null;
|
||||
|
||||
|
||||
final PyCodeStyleSettings settings = myContext.getPySettings();
|
||||
|
||||
if (parentType == PyElementTypes.BINARY_EXPRESSION && !isInControlStatement()) {
|
||||
@@ -260,7 +260,7 @@ public class PyBlock implements ASTBlock {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (parentType == PyElementTypes.LIST_LITERAL_EXPRESSION || parentType == PyElementTypes.LIST_COMP_EXPRESSION) {
|
||||
if ((childType == PyTokenTypes.RBRACKET && !settings.HANG_CLOSING_BRACKETS) || childType == PyTokenTypes.LBRACKET) {
|
||||
childIndent = Indent.getNoneIndent();
|
||||
@@ -617,7 +617,7 @@ public class PyBlock implements ASTBlock {
|
||||
myContext.getMode() == FormattingMode.ADJUST_INDENT) {
|
||||
return true;
|
||||
}
|
||||
return !hasHangingIndent(myNode.getPsi()) && !(myNode.getElementType() == PyElementTypes.DICT_LITERAL_EXPRESSION &&
|
||||
return !hasHangingIndent(myNode.getPsi()) && !(myNode.getElementType() == PyElementTypes.DICT_LITERAL_EXPRESSION &&
|
||||
myContext.getPySettings().DICT_NEW_LINE_AFTER_LEFT_BRACE);
|
||||
}
|
||||
if (myNode.getElementType() == PyElementTypes.ARGUMENT_LIST) {
|
||||
@@ -726,6 +726,13 @@ public class PyBlock implements ASTBlock {
|
||||
final PsiElement psi1 = node1.getPsi();
|
||||
|
||||
PsiElement psi2 = node2.getPsi();
|
||||
|
||||
// pycodestyle.py enforces at most 2 blank lines only between comments directly
|
||||
// at the top-level of a file, not inside if, try/except, etc.
|
||||
if (psi1 instanceof PsiComment && myNode.getPsi() instanceof PsiFile) {
|
||||
return Spacing.createSpacing(0, 0, 1, true, 2);
|
||||
}
|
||||
|
||||
// skip not inline comments to handles blank lines between various declarations
|
||||
if (psi2 instanceof PsiComment && hasLineBreaksBeforeInSameParent(node2, 1)) {
|
||||
final PsiElement nonCommentAfter = PyPsiUtils.getNextNonCommentSibling(psi2, true);
|
||||
@@ -746,7 +753,7 @@ public class PyBlock implements ASTBlock {
|
||||
return Spacing.createSpacing(1, 1, 0, settings.KEEP_LINE_BREAKS, settings.KEEP_BLANK_LINES_IN_CODE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (childType1 == PyTokenTypes.COLON && psi2 instanceof PyStatementList) {
|
||||
if (needLineBreakInStatement()) {
|
||||
return Spacing.createSpacing(0, 0, 1, true, settings.KEEP_BLANK_LINES_IN_CODE);
|
||||
@@ -794,9 +801,6 @@ public class PyBlock implements ASTBlock {
|
||||
}
|
||||
}
|
||||
|
||||
if (psi2 instanceof PsiComment && !hasLineBreaksBeforeInSameParent(psi2.getNode(), 1) && pySettings.SPACE_BEFORE_NUMBER_SIGN) {
|
||||
return Spacing.createSpacing(2, 0, 0, false, 0);
|
||||
}
|
||||
}
|
||||
return myContext.getSpacingBuilder().getSpacing(this, child1, child2);
|
||||
}
|
||||
@@ -877,7 +881,7 @@ public class PyBlock implements ASTBlock {
|
||||
// delegation sometimes causes NPEs in formatter core, so we calculate the
|
||||
// correct indent manually.
|
||||
if (statementListsBelow > 0) { // was 1... strange
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
final int indent = myContext.getSettings().getIndentOptions().INDENT_SIZE;
|
||||
return new ChildAttributes(Indent.getSpaceIndent(indent * statementListsBelow), null);
|
||||
}
|
||||
|
||||
@@ -162,6 +162,9 @@ public class PyLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSettin
|
||||
indentOptions.INDENT_SIZE = 4;
|
||||
defaultSettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
|
||||
defaultSettings.KEEP_BLANK_LINES_IN_DECLARATIONS = 1;
|
||||
// Don't set it to 2 -- this setting is used implicitly in a lot of methods related to spacing,
|
||||
// e.g. in SpacingBuilder#blankLines(), and can lead to unexpected side-effects in formatter's
|
||||
// behavior
|
||||
defaultSettings.KEEP_BLANK_LINES_IN_CODE = 1;
|
||||
return defaultSettings;
|
||||
}
|
||||
|
||||
@@ -77,6 +77,8 @@ public class PythonFormattingModelBuilder implements FormattingModelBuilderEx, C
|
||||
|
||||
final CommonCodeStyleSettings commonSettings = settings.getCommonSettings(PythonLanguage.getInstance());
|
||||
return new SpacingBuilder(commonSettings)
|
||||
.before(END_OF_LINE_COMMENT).spacing(2, 0, 0, commonSettings.KEEP_LINE_BREAKS, commonSettings.KEEP_BLANK_LINES_IN_CODE)
|
||||
.after(END_OF_LINE_COMMENT).spacing(0, 0, 1, commonSettings.KEEP_LINE_BREAKS, commonSettings.KEEP_BLANK_LINES_IN_CODE)
|
||||
.between(CLASS_DECLARATION, STATEMENT_OR_DECLARATION).blankLines(commonSettings.BLANK_LINES_AROUND_CLASS)
|
||||
.between(STATEMENT_OR_DECLARATION, CLASS_DECLARATION).blankLines(commonSettings.BLANK_LINES_AROUND_CLASS)
|
||||
.between(FUNCTION_DECLARATION, STATEMENT_OR_DECLARATION).blankLines(commonSettings.BLANK_LINES_AROUND_METHOD)
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
# line comment 1
|
||||
# line comment 2
|
||||
|
||||
|
||||
# line comment 3
|
||||
|
||||
def f():
|
||||
# inner line comment 1
|
||||
# inner line comment 2
|
||||
|
||||
|
||||
# inner line comment 3
|
||||
|
||||
|
||||
x = 42 # trailing comment 1
|
||||
|
||||
# line comment 4
|
||||
|
||||
|
||||
def g():
|
||||
pass
|
||||
|
||||
if True:
|
||||
# semi top-level comment 1
|
||||
|
||||
|
||||
|
||||
# semi top-level comment 2
|
||||
|
||||
|
||||
# semi top-level comment 3
|
||||
|
||||
|
||||
class C:
|
||||
pass
|
||||
@@ -0,0 +1,31 @@
|
||||
# line comment 1
|
||||
# line comment 2
|
||||
|
||||
|
||||
# line comment 3
|
||||
|
||||
def f():
|
||||
# inner line comment 1
|
||||
# inner line comment 2
|
||||
|
||||
# inner line comment 3
|
||||
|
||||
x = 42 # trailing comment 1
|
||||
|
||||
|
||||
# line comment 4
|
||||
|
||||
|
||||
def g():
|
||||
pass
|
||||
|
||||
|
||||
if True:
|
||||
# semi top-level comment 1
|
||||
|
||||
# semi top-level comment 2
|
||||
|
||||
# semi top-level comment 3
|
||||
|
||||
class C:
|
||||
pass
|
||||
@@ -830,6 +830,11 @@ public class PyFormatterTest extends PyTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
// PY-25356
|
||||
public void testCommentsSpacing() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testVariableAnnotations() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON36, this::doTest);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user