mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-02-04 23:39:07 +07:00
IDEA-258255 Warn users when they open a file that should be associated with a plugin but it's ignored or plain-text
GitOrigin-RevId: db4e2351f1dcdb0dc1601fdbfb59c07ba61956de
This commit is contained in:
committed by
intellij-monorepo-bot
parent
1eb5648354
commit
fd2becf61e
@@ -0,0 +1,46 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
|
||||
package com.intellij.java.codeInsight.daemon;
|
||||
|
||||
import com.intellij.codeInsight.daemon.DaemonAnalyzerTestCase;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInspection.InspectionsBundle;
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.ReassignedToPlainTextInspection;
|
||||
import com.intellij.lang.annotation.HighlightSeverity;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.fileTypes.ExactFileNameMatcher;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.fileTypes.FileTypes;
|
||||
import com.intellij.openapi.fileTypes.PlainTextFileType;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class ReassignedToPlainTextTest extends DaemonAnalyzerTestCase {
|
||||
@Override
|
||||
protected LocalInspectionTool @NotNull [] configureLocalInspectionTools() {
|
||||
return new LocalInspectionTool[]{new ReassignedToPlainTextInspection()};
|
||||
}
|
||||
|
||||
public void testText() throws Exception {
|
||||
FileTypeManager fileTypeManager = FileTypeManager.getInstance();
|
||||
String name = "xx.xxxx";
|
||||
assertEquals(FileTypes.UNKNOWN, fileTypeManager.getFileTypeByFileName(name));
|
||||
WriteAction.run(() -> fileTypeManager.associate(PlainTextFileType.INSTANCE, new ExactFileNameMatcher(name)));
|
||||
assertEquals(PlainTextFileType.INSTANCE, fileTypeManager.getFileTypeByFileName(name));
|
||||
|
||||
VirtualFile file = getVirtualFile(createTempFile(name, "xxx"));
|
||||
configureByExistingFile(file);
|
||||
assertEquals(PlainTextFileType.INSTANCE, file.getFileType());
|
||||
|
||||
Collection<HighlightInfo> infos = doHighlighting(HighlightSeverity.WARNING);
|
||||
HighlightInfo info = assertOneElement(infos);
|
||||
assertEquals("This file was explicitly re-assigned to plain text", info.getDescription());
|
||||
|
||||
findAndInvokeIntentionAction(infos, InspectionsBundle.message("reassigned.to.plain.text.inspection.fix.remove.name"), getEditor(), getFile());
|
||||
assertEquals(FileTypes.UNKNOWN, fileTypeManager.getFileTypeByFileName(name));
|
||||
assertEquals(PlainTextFileType.INSTANCE, file.getFileType());
|
||||
}
|
||||
}
|
||||
@@ -308,4 +308,25 @@ public final class FileTypeAssocTable<T> {
|
||||
myExactFileNameMappings.clear();
|
||||
myExactFileNameAnyCaseMappings.clear();
|
||||
}
|
||||
|
||||
void removeAssociationsForFile(@NotNull CharSequence fileName, @NotNull T association) {
|
||||
T t = myExactFileNameMappings.get(fileName);
|
||||
if (association.equals(t)) {
|
||||
myExactFileNameMappings.remove(fileName);
|
||||
}
|
||||
|
||||
t = myExactFileNameAnyCaseMappings.get(fileName);
|
||||
if (association.equals(t)) {
|
||||
myExactFileNameAnyCaseMappings.remove(fileName);
|
||||
}
|
||||
|
||||
myMatchingMappings.removeIf(pair -> association.equals(pair.second)
|
||||
&& pair.getFirst().acceptsCharSequence(fileName));
|
||||
|
||||
CharSequence extension = FileUtilRt.getExtension(fileName);
|
||||
t = myExtensionMappings.get(extension);
|
||||
if (association.equals(t)) {
|
||||
myExtensionMappings.remove(extension);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,3 +307,8 @@ long.range.set.presentation.range.with.mod={0}; {1}
|
||||
inspection.results=Inspection Results
|
||||
inspections.results=Inspections Results
|
||||
notification.group.inspection.results=Code inspection completed
|
||||
|
||||
reassigned.to.plain.text.inspection.name=Reassigned to plain text
|
||||
reassigned.to.plain.text.inspection.message=This file was explicitly re-assigned to plain text
|
||||
reassigned.to.plain.text.inspection.fix.remove.name=Remove association
|
||||
reassigned.to.plain.text.inspection.fix.edit.name=Edit File Types
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInspection;
|
||||
|
||||
import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.fileTypes.PlainTextFileType;
|
||||
import com.intellij.openapi.fileTypes.impl.FileTypeManagerImpl;
|
||||
import com.intellij.openapi.fileTypes.impl.FileTypeSelectable;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.options.SearchableConfigurable;
|
||||
import com.intellij.openapi.options.ShowSettingsUtil;
|
||||
import com.intellij.openapi.options.ex.ConfigurableWrapper;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.FileViewProvider;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
// this file is assigned to "Plain text" file type even though there's a plugin supporting this specific extension/file pattern
|
||||
public class ReassignedToPlainTextInspection extends LocalInspectionTool {
|
||||
@Override
|
||||
@NonNls
|
||||
@NotNull
|
||||
public String getShortName() {
|
||||
return "ReassignedToPlainText";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProblemDescriptor @Nullable [] checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) {
|
||||
if (InjectedLanguageManager.getInstance(file.getProject()).isInjectedFragment(file)) return null;
|
||||
if (!file.isPhysical()) return null;
|
||||
FileViewProvider viewProvider = file.getViewProvider();
|
||||
if (viewProvider.getBaseLanguage() != file.getLanguage()) return null;
|
||||
VirtualFile virtualFile = file.getVirtualFile();
|
||||
if (virtualFile == null) return null;
|
||||
FileType fileType = virtualFile.getFileType();
|
||||
if (fileType != PlainTextFileType.INSTANCE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
FileType assigned = FileTypeManager.getInstance().getFileTypeByFileName(virtualFile.getNameSequence());
|
||||
if (assigned == PlainTextFileType.INSTANCE) {
|
||||
LocalQuickFix removeFix = new LocalQuickFix() {
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return InspectionsBundle.message("reassigned.to.plain.text.inspection.fix.remove.name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
((FileTypeManagerImpl)FileTypeManager.getInstance()).removePlainTextAssociationsForFile(descriptor.getPsiElement().getContainingFile().getName());
|
||||
}
|
||||
};
|
||||
LocalQuickFix editFix = new LocalQuickFix() {
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return InspectionsBundle.message("reassigned.to.plain.text.inspection.fix.edit.name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
editFileType(project, PlainTextFileType.INSTANCE);
|
||||
}
|
||||
};
|
||||
ProblemDescriptor descriptor = manager.createProblemDescriptor(file, InspectionsBundle.message("reassigned.to.plain.text.inspection.message"), new LocalQuickFix[]{removeFix, editFix},
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
||||
true, false);
|
||||
return new ProblemDescriptor[]{descriptor};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private static void editFileType(@Nullable Project project, @NotNull FileType fileType) {
|
||||
ShowSettingsUtil.getInstance().showSettingsDialog(project,
|
||||
configurable -> configurable instanceof SearchableConfigurable && ((SearchableConfigurable)configurable).getId().equals("preferences.fileTypes"),
|
||||
configurable -> {
|
||||
if (configurable instanceof ConfigurableWrapper) {
|
||||
configurable = (Configurable)((ConfigurableWrapper)configurable).getConfigurable();
|
||||
}
|
||||
FileTypeSelectable fileTypeSelectable = (FileTypeSelectable)configurable;
|
||||
fileTypeSelectable.selectFileType(fileType);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.openapi.vfs.newvfs.FileAttribute;
|
||||
import com.intellij.openapi.vfs.newvfs.FileSystemInterface;
|
||||
import com.intellij.openapi.vfs.newvfs.events.*;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.concurrency.AppExecutorUtil;
|
||||
import com.intellij.util.concurrency.BoundedTaskExecutor;
|
||||
@@ -322,7 +323,7 @@ final class FileTypeDetectionService implements Disposable {
|
||||
return !file.isDirectory()
|
||||
&& file.isValid()
|
||||
&& !file.is(VFileProperty.SPECIAL)
|
||||
&& file.getFileSystem() instanceof FileSystemInterface;
|
||||
&& (file.getFileSystem() instanceof FileSystemInterface || file instanceof LightVirtualFile);
|
||||
}
|
||||
|
||||
// read auto-detection flags from the persistent FS file attributes. If file attributes are absent, return 0 for flags
|
||||
|
||||
@@ -636,6 +636,18 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
|
||||
return getFileTypeOrUnknown(ftd);
|
||||
}
|
||||
|
||||
public void removePlainTextAssociationsForFile(@NotNull CharSequence fileName) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
myPendingInitializationLock.writeLock().lock();
|
||||
try {
|
||||
makeFileTypesChange("removePlainTextAssociationsForFile("+fileName+")", () ->
|
||||
myPatternsTable.removeAssociationsForFile(fileName, FileTypeWithDescriptor.allFor(PlainTextFileType.INSTANCE)));
|
||||
}
|
||||
finally {
|
||||
myPendingInitializationLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void freezeFileTypeTemporarilyIn(@NotNull VirtualFile file, @NotNull Runnable runnable) {
|
||||
FileType fileType = file.isDirectory() ? null : file.getFileType();
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<html>
|
||||
<body>
|
||||
Reports files that were explicitly re-assigned to Plain Text File Type.
|
||||
This association is unnecessary because the platform auto-detects text files by content automatically.
|
||||
|
||||
<p>You can dismiss this warning by removing the file type association
|
||||
in <b>Settings | Editor | File Types | Text</b>.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -985,6 +985,9 @@
|
||||
<localInspection shortName="LossyEncoding" bundle="messages.LangBundle" key="lossy.encoding"
|
||||
groupBundle="messages.InspectionsBundle" groupKey="group.names.internationalization.issues" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="com.intellij.codeInspection.LossyEncodingInspection"/>
|
||||
<localInspection shortName="ReassignedToPlainText" bundle="messages.InspectionsBundle" key="reassigned.to.plain.text.inspection.name"
|
||||
groupBundle="messages.InspectionsBundle" groupKey="inspection.general.tools.group.name" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="com.intellij.codeInspection.ReassignedToPlainTextInspection"/>
|
||||
<localInspection shortName="NonAsciiCharacters" bundle="messages.LangBundle" key="non.ascii.characters"
|
||||
groupBundle="messages.InspectionsBundle" groupKey="group.names.internationalization.issues" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="com.intellij.codeInspection.NonAsciiCharactersInspection"/>
|
||||
|
||||
Reference in New Issue
Block a user