From 24fe58f18d95d086bd1e69a01b7d8da118dbd65d Mon Sep 17 00:00:00 2001 From: Rustam Vishniakov Date: Thu, 26 Jan 2023 19:44:35 +0100 Subject: [PATCH] [code-style] Fix post-processing logic and tests GitOrigin-RevId: 99d867a00a4f0a9e285ad1836d77ee92c881fab1 --- .../source/codeStyle/CoreCodeStyleUtil.java | 81 ++++++++++++------- .../testSrc/CodeStyleTest.kt | 10 +-- .../testData/codeStyle/json/exportToJson.json | 2 +- 3 files changed, 57 insertions(+), 36 deletions(-) diff --git a/platform/code-style-impl/src/com/intellij/psi/impl/source/codeStyle/CoreCodeStyleUtil.java b/platform/code-style-impl/src/com/intellij/psi/impl/source/codeStyle/CoreCodeStyleUtil.java index e094c0af017e..1e01c6db48a4 100644 --- a/platform/code-style-impl/src/com/intellij/psi/impl/source/codeStyle/CoreCodeStyleUtil.java +++ b/platform/code-style-impl/src/com/intellij/psi/impl/source/codeStyle/CoreCodeStyleUtil.java @@ -26,6 +26,7 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; @@ -40,30 +41,49 @@ public final class CoreCodeStyleUtil { private CoreCodeStyleUtil() { } - public static PsiElement postProcessElement(@NotNull PsiFile file, @NotNull final PsiElement formatted, boolean isWhitespaceOnly) { - PsiElement result = formatted; + public static PsiElement postProcessElement(@NotNull PsiFile file, @NotNull final PsiElement element, boolean isWhitespaceOnly) { CodeStyleSettings settingsForFile = CodeStyle.getSettings(file); - if (settingsForFile.FORMATTER_TAGS_ENABLED && formatted instanceof PsiFile) { - postProcessEnabledRanges((PsiFile)formatted, formatted.getTextRange(), settingsForFile, isWhitespaceOnly); + List textRanges; + if (settingsForFile.FORMATTER_TAGS_ENABLED) { + FormatterTagHandler tagHandler = new FormatterTagHandler(settingsForFile); + textRanges = tagHandler.getEnabledRanges(file.getNode(), file.getTextRange()); } else { - boolean brokenProcFound = false; - for (PostFormatProcessor postFormatProcessor : getPostProcessors(isWhitespaceOnly)) { - try { - result = postFormatProcessor.processElement(result, settingsForFile); - if (!result.isValid() && !brokenProcFound) { - LOG.error(new RuntimeExceptionWithAttachments(String.format("PSI crash detected: processor=%s, result=%s", postFormatProcessor, - result), new Attachment("text", result.getText()))); - brokenProcFound = true; - } - } - catch (ProcessCanceledException e) { - throw e; - } - catch (Throwable e) { - LOG.error(PluginException.createByClass(e, postFormatProcessor.getClass())); + textRanges = Collections.singletonList(element.getTextRange()); + } + for (TextRange range : textRanges) { + if (range.contains(element.getTextRange())) { + PsiElement currElement = element; + for (PostFormatProcessor postFormatProcessor : getPostProcessors(isWhitespaceOnly)) { + if (currElement == null) break; + currElement = processElementOrFail(postFormatProcessor, currElement, settingsForFile); } + return currElement; } + else if (range.intersects(element.getTextRange())) { + postProcessRange(file, element.getTextRange().intersection(range), settingsForFile, isWhitespaceOnly); + } + } + return element; + } + + private static @Nullable PsiElement processElementOrFail(@NotNull PostFormatProcessor processor, + @NotNull PsiElement element, + @NotNull CodeStyleSettings settings) { + PsiElement result = element; + try { + result = processor.processElement(result, settings); + if (!result.isValid()) { + LOG.error(new RuntimeExceptionWithAttachments(String.format("PSI crash detected: processor=%s, result=%s", processor, + result), new Attachment("text", result.getText()))); + return null; + } + } + catch (ProcessCanceledException e) { + throw e; + } + catch (Throwable e) { + LOG.error(PluginException.createByClass(e, processor.getClass())); } return result; } @@ -98,14 +118,12 @@ public final class CoreCodeStyleUtil { } public static void postProcessText(@NotNull final PsiFile file, @NotNull final TextRange textRange, boolean isWhitespaceOnly) { + CodeStyleSettings settings = CodeStyle.getSettings(file); if (!getSettings(file).FORMATTER_TAGS_ENABLED) { - TextRange currentRange = textRange; - for (final PostFormatProcessor myPostFormatProcessor : getPostProcessors(isWhitespaceOnly)) { - currentRange = myPostFormatProcessor.processText(file, currentRange, getSettings(file)); - } + postProcessRange(file, textRange, settings, isWhitespaceOnly); } else { - postProcessEnabledRanges(file, textRange, getSettings(file), isWhitespaceOnly); + postProcessEnabledRanges(file, textRange, settings, isWhitespaceOnly); } } @@ -117,13 +135,20 @@ public final class CoreCodeStyleUtil { int delta = 0; for (TextRange enabledRange : enabledRanges) { enabledRange = enabledRange.shiftRight(delta); - for (PostFormatProcessor processor : getPostProcessors(isWhitespaceOnly)) { - TextRange processedRange = processor.processText(file, enabledRange, settings); - delta += processedRange.getLength() - enabledRange.getLength(); - } + TextRange processedRange = postProcessRange(file, enabledRange, settings, isWhitespaceOnly); + delta += processedRange.getLength() - enabledRange.getLength(); } } + private static TextRange postProcessRange(@NotNull PsiFile file, @NotNull TextRange textRange, + @NotNull CodeStyleSettings settings, boolean isWhitespaceOnly) { + TextRange currentRange = textRange; + for (final PostFormatProcessor myPostFormatProcessor : getPostProcessors(isWhitespaceOnly)) { + currentRange = myPostFormatProcessor.processText(file, currentRange, settings); + } + return currentRange; + } + public static class RangeFormatInfo { private final PsiFile myFile; private final SmartPsiElementPointer startPointer; diff --git a/platform/configuration-store-impl/testSrc/CodeStyleTest.kt b/platform/configuration-store-impl/testSrc/CodeStyleTest.kt index 11b5d0248c6e..41834579c377 100644 --- a/platform/configuration-store-impl/testSrc/CodeStyleTest.kt +++ b/platform/configuration-store-impl/testSrc/CodeStyleTest.kt @@ -15,6 +15,7 @@ import org.jdom.Element import org.junit.ClassRule import org.junit.Rule import org.junit.Test +import org.junit.jupiter.api.Assertions.assertTrue internal class CodeStyleTest { companion object { @@ -191,16 +192,11 @@ internal class CodeStyleTest {