IDEA-281375 Don't run formatter on save on syntactically invalid file

GitOrigin-RevId: 2e610c2bebbe72325b51c8e95e9006c8e0a03c8d
This commit is contained in:
Rustam Vishnyakov
2021-12-16 20:31:35 +03:00
committed by intellij-monorepo-bot
parent f7d63db943
commit 4223851001
5 changed files with 55 additions and 1 deletions

View File

@@ -7,6 +7,7 @@ import com.intellij.formatting.FormattingModelBuilder;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.ExternalFormatProcessor;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -55,4 +56,15 @@ public final class LanguageFormatting extends LanguageExtension<FormattingModelB
}
return null;
}
/**
* Checks if automatic reformat is allowed for the given context element using {@link LanguageFormattingRestriction} extensions.
*
* @param context The element to check.
*
* @return True if formatting is allowed, false otherwise.
*/
public boolean isAutoFormatAllowed(@NotNull PsiElement context) {
return ContainerUtil.and(LanguageFormattingRestriction.EP_NAME.getExtensionList(), each -> each.isAutoFormatAllowed(context));
}
}

View File

@@ -24,4 +24,19 @@ public interface LanguageFormattingRestriction {
"com.intellij.lang.formatter.restriction");
boolean isFormatterAllowed(@NotNull PsiElement context);
/**
* Checks if automatic code reformat is allowed, for example, on save. By default, the method returns the same value as
* {@link #isFormatterAllowed(PsiElement)} used for explicit reformat.
*
* @param context A context element.
*
* @return True if automatic reformat is allowed, false to block it. For automatic formatting to work, this method and
* {@link #isFormatterAllowed(PsiElement)} must <i>both</i> return {@code true}.
*
* @see LanguageFormatting#isAutoFormatAllowed(PsiElement)
*/
default boolean isAutoFormatAllowed(@NotNull PsiElement context) {
return isFormatterAllowed(context);
}
}

View File

@@ -0,0 +1,24 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.lang;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiErrorElement;
import com.intellij.psi.SyntaxTraverser;
import org.jetbrains.annotations.NotNull;
public class InvalidPsiAutoFormatRestriction implements LanguageFormattingRestriction {
@Override
public boolean isFormatterAllowed(@NotNull PsiElement context) {
return true;
}
@Override
public boolean isAutoFormatAllowed(@NotNull PsiElement context) {
return context.isValid() && containsValidPsi(context);
}
private static boolean containsValidPsi(@NotNull PsiElement context) {
return SyntaxTraverser.psiTraverser(context).filter(PsiErrorElement.class).first() == null;
}
}

View File

@@ -3,6 +3,7 @@ package com.intellij.codeInsight.actions.onSave;
import com.intellij.codeInsight.actions.*;
import com.intellij.ide.actionsOnSave.impl.ActionsOnSaveFileDocumentManagerListener;
import com.intellij.lang.LanguageFormatting;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
@@ -35,7 +36,7 @@ public class FormatOnSaveAction extends ActionsOnSaveFileDocumentManagerListener
for (Document document : documents) {
PsiFile psiFile = manager.getPsiFile(document);
if (psiFile == null) continue;
if (psiFile == null || !LanguageFormatting.INSTANCE.isAutoFormatAllowed(psiFile)) continue;
allFiles.add(psiFile);

View File

@@ -1466,6 +1466,8 @@
<lang.documentationLinkResolver implementation="com.intellij.lang.documentation.psi.PsiDocumentationLinkResolver"/>
<projectService serviceInterface="com.intellij.lang.documentation.ide.IdeDocumentationTargetProvider"
serviceImplementation="com.intellij.lang.documentation.ide.impl.IdeDocumentationTargetProviderImpl"/>
<lang.formatter.restriction implementation="com.intellij.lang.InvalidPsiAutoFormatRestriction"/>
</extensions>
<applicationListeners>
<listener class="com.intellij.util.indexing.FileBasedIndexPluginListener" topic="com.intellij.ide.plugins.DynamicPluginListener"/>