PY-40778 Keep spaces between f-string fragment own braces and that of embedded expression

GitOrigin-RevId: f392f683b0c114fb046ede5b317bc4b0be207ec1
This commit is contained in:
Mikhail Golubev
2020-08-17 11:12:04 +00:00
committed by intellij-monorepo-bot
parent ed4b1332dc
commit 7183fd55b5
4 changed files with 36 additions and 2 deletions
@@ -6,6 +6,7 @@ import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.impl.source.tree.LeafElement;
import com.intellij.psi.impl.source.tree.TreeUtil;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
@@ -821,6 +822,19 @@ public class PyBlock implements ASTBlock {
if (isInsideFStringFragmentWithEqualsSign(myNode)) {
return Spacing.getReadOnlySpacing();
}
if (childType1 == PyTokenTypes.FSTRING_FRAGMENT_START) {
final LeafElement firstLeaf = TreeUtil.findFirstLeaf(node2);
if (firstLeaf != null && firstLeaf.getElementType() == PyTokenTypes.LBRACE) {
return Spacing.createSpacing(1, 1, 0, false, 0);
}
}
if (childType2 == PyTokenTypes.FSTRING_FRAGMENT_END) {
final ASTNode lastLeaf = TreeUtil.findLastLeaf(node1);
if (lastLeaf != null && lastLeaf.getElementType() == PyTokenTypes.RBRACE) {
return Spacing.createSpacing(1, 1, 0, false, 0);
}
}
if ((childType1 == PyTokenTypes.EQ || childType2 == PyTokenTypes.EQ)) {
final PyNamedParameter namedParameter = as(myNode.getPsi(), PyNamedParameter.class);
@@ -1176,8 +1190,7 @@ public class PyBlock implements ASTBlock {
private static boolean isInsideFStringFragmentWithEqualsSign(@NotNull ASTNode node) {
final ASTNode fStringFragmentParent = node.getElementType() == PyElementTypes.FSTRING_FRAGMENT
? node
: TreeUtil.findParent(node, TokenSet.create(PyElementTypes.FSTRING_FRAGMENT),
stopAtTokens);
: TreeUtil.findParent(node, TokenSet.create(PyElementTypes.FSTRING_FRAGMENT), stopAtTokens);
if (fStringFragmentParent == null) return false;
return fStringFragmentParent.findChildByType(PyTokenTypes.EQ) != null;
}
@@ -0,0 +1,8 @@
s = f'{ {} }'
s1 = f'{ {1} }'
s2 = f'{ {1: 2} }'
s3 = f'{ {x for x in "foo"} }'
s4 = f'{ {x: 42 for x in "foo"} }'
s5 = f'{ {1} + {2} }'
s6 = f'{ {1} if True else {2} }'
s7 = f'{ {1}.intersection({2}) }'
@@ -0,0 +1,8 @@
s = f'{ {} }'
s1 = f'{ {1} }'
s2 = f'{ {1: 2} }'
s3 = f'{ {x for x in "foo"} }'
s4 = f'{ {x: 42 for x in "foo"} }'
s5 = f'{ {1} + {2} }'
s6 = f'{ {1} if True else {2} }'
s7 = f'{ {1}.intersection({2})}'
@@ -956,6 +956,11 @@ public class PyFormatterTest extends PyTestCase {
runWithLanguageLevel(LanguageLevel.PYTHON36, this::doTest);
}
// PY-40778
public void testFStringSpacesBetweenFragmentAndExpressionBracesPreserved() {
runWithLanguageLevel(LanguageLevel.getLatest(), this::doTest);
}
// PY-31991
public void testSpacesAroundFStringFragmentExpressionStripped() {
runWithLanguageLevel(LanguageLevel.PYTHON36, this::doTest);