From 1bcff41926215d879226a9813ea458c3431d907a Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Thu, 14 May 2015 15:13:52 +0300 Subject: [PATCH] [PsiBasedFormattingModel] Perform whitespace modification with disabled automatic formatting of changed psi elements. Changed whitespace would not be formatted twice, which will prevent from reformatting whitespaces of aligned blocks and producing inconsistent result --- .../formatter/PsiBasedFormattingModel.java | 27 ++++++++++++++----- .../alignDictLiteralOnValue_after.py | 4 +-- ...tDestroyAlignment_OnPostponedFormatting.py | 4 +++ ...oyAlignment_OnPostponedFormatting_after.py | 4 +++ .../com/jetbrains/python/PyFormatterTest.java | 5 ++++ 5 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 python/testData/formatter/doNotDestroyAlignment_OnPostponedFormatting.py create mode 100644 python/testData/formatter/doNotDestroyAlignment_OnPostponedFormatting_after.py diff --git a/platform/lang-impl/src/com/intellij/psi/formatter/PsiBasedFormattingModel.java b/platform/lang-impl/src/com/intellij/psi/formatter/PsiBasedFormattingModel.java index 3712158a6b4c..e2a0958c4e2a 100644 --- a/platform/lang-impl/src/com/intellij/psi/formatter/PsiBasedFormattingModel.java +++ b/platform/lang-impl/src/com/intellij/psi/formatter/PsiBasedFormattingModel.java @@ -27,6 +27,7 @@ import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.TokenType; +import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.impl.source.SourceTreeToPsiMap; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import org.jetbrains.annotations.NotNull; @@ -36,18 +37,19 @@ public class PsiBasedFormattingModel implements FormattingModelEx { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.formatter.PsiBasedFormattingModel"); + private final Project myProject; private final ASTNode myASTNode; private final FormattingDocumentModelImpl myDocumentModel; @NotNull private final Block myRootBlock; protected boolean myCanModifyAllWhiteSpaces = false; - + public PsiBasedFormattingModel(final PsiFile file, @NotNull final Block rootBlock, final FormattingDocumentModelImpl documentModel) { myASTNode = SourceTreeToPsiMap.psiElementToTree(file); myDocumentModel = documentModel; myRootBlock = rootBlock; - + myProject = file.getProject(); } @@ -81,7 +83,7 @@ public class PsiBasedFormattingModel implements FormattingModelEx { @Nullable - private String replaceWithPSI(final TextRange textRange, String whiteSpace) { + private String replaceWithPSI(final TextRange textRange, final String whiteSpace) { final int offset = textRange.getEndOffset(); ASTNode leafElement = findElementAt(offset); @@ -101,7 +103,14 @@ public class PsiBasedFormattingModel implements FormattingModelEx { return replaceWithPsiInLeaf(textRange, whiteSpace, leafElement); } } else if (textRange.getEndOffset() == myASTNode.getTextLength()){ - FormatterUtil.replaceLastWhiteSpace(myASTNode, whiteSpace, textRange); + + CodeStyleManager.getInstance(myProject).performActionWithFormatterDisabled(new Runnable() { + @Override + public void run() { + FormatterUtil.replaceLastWhiteSpace(myASTNode, whiteSpace, textRange); + } + }); + return whiteSpace; } else { return null; @@ -109,12 +118,18 @@ public class PsiBasedFormattingModel implements FormattingModelEx { } @Nullable - protected String replaceWithPsiInLeaf(final TextRange textRange, String whiteSpace, ASTNode leafElement) { + protected String replaceWithPsiInLeaf(final TextRange textRange, final String whiteSpace, final ASTNode leafElement) { if (!myCanModifyAllWhiteSpaces) { if (leafElement.getElementType() == TokenType.WHITE_SPACE) return null; } - FormatterUtil.replaceWhiteSpace(whiteSpace, leafElement, TokenType.WHITE_SPACE, textRange); + CodeStyleManager.getInstance(myProject).performActionWithFormatterDisabled(new Runnable() { + @Override + public void run() { + FormatterUtil.replaceWhiteSpace(whiteSpace, leafElement, TokenType.WHITE_SPACE, textRange); + } + }); + return whiteSpace; } diff --git a/python/testData/formatter/alignDictLiteralOnValue_after.py b/python/testData/formatter/alignDictLiteralOnValue_after.py index c333ffcc903f..13881b918e21 100644 --- a/python/testData/formatter/alignDictLiteralOnValue_after.py +++ b/python/testData/formatter/alignDictLiteralOnValue_after.py @@ -1,6 +1,6 @@ { - "a": 1, - "bbb": [ + "a": 1, + "bbb": [ 2 ], "bbbbb": 3 diff --git a/python/testData/formatter/doNotDestroyAlignment_OnPostponedFormatting.py b/python/testData/formatter/doNotDestroyAlignment_OnPostponedFormatting.py new file mode 100644 index 000000000000..a0486c9a8d5e --- /dev/null +++ b/python/testData/formatter/doNotDestroyAlignment_OnPostponedFormatting.py @@ -0,0 +1,4 @@ +{ + "aaaaa": 1, + "bbb aaaaaaa": 2 +} \ No newline at end of file diff --git a/python/testData/formatter/doNotDestroyAlignment_OnPostponedFormatting_after.py b/python/testData/formatter/doNotDestroyAlignment_OnPostponedFormatting_after.py new file mode 100644 index 000000000000..e04ac0be0bc5 --- /dev/null +++ b/python/testData/formatter/doNotDestroyAlignment_OnPostponedFormatting_after.py @@ -0,0 +1,4 @@ +{ + "aaaaa" : 1, + "bbb aaaaaaa": 2 +} diff --git a/python/testSrc/com/jetbrains/python/PyFormatterTest.java b/python/testSrc/com/jetbrains/python/PyFormatterTest.java index 35a3283e6c80..605a8b5f83da 100644 --- a/python/testSrc/com/jetbrains/python/PyFormatterTest.java +++ b/python/testSrc/com/jetbrains/python/PyFormatterTest.java @@ -601,6 +601,11 @@ public class PyFormatterTest extends PyTestCase { doTest(); } + public void testDoNotDestroyAlignment_OnPostponedFormatting() throws Exception { + getCustomSettings().DICT_ALIGNMENT = PyCodeStyleSettings.DICT_ALIGNMENT_ON_COLON; + doTest(); + } + public void testAlignmentOfEmptyCollectionLiterals() { doTest(); }