diff --git a/python/python-common-tests/com/jetbrains/python/PythonCommonFormatterTest.java b/python/python-common-tests/com/jetbrains/python/PythonCommonFormatterTest.java index 3749aac48057..223de92ae5d4 100644 --- a/python/python-common-tests/com/jetbrains/python/PythonCommonFormatterTest.java +++ b/python/python-common-tests/com/jetbrains/python/PythonCommonFormatterTest.java @@ -1560,4 +1560,14 @@ public abstract class PythonCommonFormatterTest extends PythonCommonTestCase { getPythonCodeStyleSettings().HANG_CLOSING_BRACKETS = true; doTest(); } + + public void testWrappingInCollectionsCommentsStayOnTheSameLine() { + getPythonCodeStyleSettings().TUPLE_WRAPPING = CommonCodeStyleSettings.WRAP_ALWAYS; + getPythonCodeStyleSettings().DICT_WRAPPING = CommonCodeStyleSettings.WRAP_ALWAYS; + getPythonCodeStyleSettings().SET_WRAPPING = CommonCodeStyleSettings.WRAP_ALWAYS; + getPythonCodeStyleSettings().LIST_WRAPPING = CommonCodeStyleSettings.WRAP_ALWAYS; + getCodeStyleSettings().METHOD_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_ALWAYS; + getCodeStyleSettings().CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_ALWAYS; + doTest(); + } } diff --git a/python/python-syntax-core/src/com/jetbrains/python/formatter/PyBlock.java b/python/python-syntax-core/src/com/jetbrains/python/formatter/PyBlock.java index 0b95aaa59df9..ef26d5c4613f 100644 --- a/python/python-syntax-core/src/com/jetbrains/python/formatter/PyBlock.java +++ b/python/python-syntax-core/src/com/jetbrains/python/formatter/PyBlock.java @@ -451,40 +451,7 @@ public class PyBlock implements ASTBlock { } } } - if (childType == PyElementTypes.KEY_VALUE_EXPRESSION && isChildOfDictLiteral(child)) { - childWrap = myDictWrapping; - } - if (parentType == PyElementTypes.LIST_LITERAL_EXPRESSION && - childType != PyTokenTypes.COMMA && - childType != PyTokenTypes.LBRACKET && - childType != PyTokenTypes.RBRACKET) { - childWrap = myListWrapping; - } - if (parentType == PyElementTypes.SET_LITERAL_EXPRESSION && - childType != PyTokenTypes.COMMA && - childType != PyTokenTypes.LBRACE && - childType != PyTokenTypes.RBRACE) { - childWrap = mySetWrapping; - } - if (parentType == PyElementTypes.TUPLE_EXPRESSION && - grandparentType == PyElementTypes.PARENTHESIZED_EXPRESSION && - childType != PyTokenTypes.COMMA && - childType != PyTokenTypes.LPAR && - childType != PyTokenTypes.RPAR) { - childWrap = myTupleWrapping; - } - if (parentType == PyElementTypes.PARAMETER_LIST && - childType != PyTokenTypes.COMMA && - childType != PyTokenTypes.LPAR && - childType != PyTokenTypes.RPAR) { - childWrap = myParameterListWrapping; - } - if (parentType == PyElementTypes.ARGUMENT_LIST && - childType != PyTokenTypes.COMMA && - childType != PyTokenTypes.LPAR && - childType != PyTokenTypes.RPAR) { - childWrap = myArgumentListWrapping; - } + childWrap = getSpecialWrapForContainers(child, childType, childWrap, parentType); if (isAfterStatementList(child) && !hasLineBreaksBeforeInSameParent(child, 2) && @@ -539,6 +506,32 @@ public class PyBlock implements ASTBlock { return new PyBlock(this, child, childAlignment, childIndent, childWrap, myContext); } + private @Nullable Wrap getSpecialWrapForContainers(@NotNull ASTNode child, + @NotNull IElementType childType, + @Nullable Wrap childWrap, + @Nullable IElementType parentType) { + if (childType != PyTokenTypes.COMMA && childType != PyTokenTypes.END_OF_LINE_COMMENT) { + // (...) + if (childType != PyTokenTypes.LPAR && childType != PyTokenTypes.RPAR) { + if (parentType == PyElementTypes.TUPLE_EXPRESSION) return myTupleWrapping; + if (parentType == PyElementTypes.PARAMETER_LIST) return myParameterListWrapping; + if (parentType == PyElementTypes.ARGUMENT_LIST) return myArgumentListWrapping; + } + // [...] + if (childType != PyTokenTypes.LBRACKET && childType != PyTokenTypes.RBRACKET) { + if (parentType == PyElementTypes.LIST_LITERAL_EXPRESSION) return myListWrapping; + } + // {...} + if (childType != PyTokenTypes.LBRACE && childType != PyTokenTypes.RBRACE) { + if (parentType == PyElementTypes.SET_LITERAL_EXPRESSION) return mySetWrapping; + } + } + if (childType == PyElementTypes.KEY_VALUE_EXPRESSION && isChildOfDictLiteral(child)) { + return myDictWrapping; + } + return childWrap; + } + private static boolean isInsideWithStatementParentheses(@NotNull ASTNode withStatement, @NotNull ASTNode node) { ASTNode openingParenthesis = withStatement.findChildByType(PyTokenTypes.LPAR); if (openingParenthesis == null) { diff --git a/python/testData/formatter/wrappingInCollectionsCommentsStayOnTheSameLine.py b/python/testData/formatter/wrappingInCollectionsCommentsStayOnTheSameLine.py new file mode 100644 index 000000000000..9175359bbb02 --- /dev/null +++ b/python/testData/formatter/wrappingInCollectionsCommentsStayOnTheSameLine.py @@ -0,0 +1,57 @@ +num_dict = { + "one": 1, # comment + "two": 2, # comment + "three": 3, # comment + "four": 4, # comment + "five": 5 # comment +} + +colors = [ + 'red', # comment + 'green', # comment + 'blue', # comment + 'black', # comment + 'white', # comment + 'gray' # comment +] + +star_names = { + "Sirius", # comment + "Betelgeuse", # comment + "Polaris", # comment + "Vega", # comment + "Arcturus", # comment + "Aldebaran" # comment +} + +planets = ( + "Mercury", # comment + "Venus", # comment + "Earth", # comment + "Mars", # comment + "Jupiter", # comment + "Saturn", # comment + "Uranus", # comment + "Neptune" # comment +) + + +def xyzzy( + a1, # comment + a2, # comment + long_parameter_1, # comment + a3, # comment + a4, # comment + long_parameter_2 # comment +): + pass + + +xyzzy( + 1, # comment + 2, # comment + 'long_string_constant1', # comment + 3, # comment + 4, # comment + 'long_string_constant2' # comment +) diff --git a/python/testData/formatter/wrappingInCollectionsCommentsStayOnTheSameLine_after.py b/python/testData/formatter/wrappingInCollectionsCommentsStayOnTheSameLine_after.py new file mode 100644 index 000000000000..9175359bbb02 --- /dev/null +++ b/python/testData/formatter/wrappingInCollectionsCommentsStayOnTheSameLine_after.py @@ -0,0 +1,57 @@ +num_dict = { + "one": 1, # comment + "two": 2, # comment + "three": 3, # comment + "four": 4, # comment + "five": 5 # comment +} + +colors = [ + 'red', # comment + 'green', # comment + 'blue', # comment + 'black', # comment + 'white', # comment + 'gray' # comment +] + +star_names = { + "Sirius", # comment + "Betelgeuse", # comment + "Polaris", # comment + "Vega", # comment + "Arcturus", # comment + "Aldebaran" # comment +} + +planets = ( + "Mercury", # comment + "Venus", # comment + "Earth", # comment + "Mars", # comment + "Jupiter", # comment + "Saturn", # comment + "Uranus", # comment + "Neptune" # comment +) + + +def xyzzy( + a1, # comment + a2, # comment + long_parameter_1, # comment + a3, # comment + a4, # comment + long_parameter_2 # comment +): + pass + + +xyzzy( + 1, # comment + 2, # comment + 'long_string_constant1', # comment + 3, # comment + 4, # comment + 'long_string_constant2' # comment +)