new inspection: "missorted imports" with quick-fix-only severity, to fix IDEA-334084 No "Optimize imports" action is displayed

GitOrigin-RevId: 92028252fc0b4c8ab05b7236de15ff44090a7183
This commit is contained in:
Alexey Kudravtsev
2023-11-08 14:55:31 +00:00
committed by intellij-monorepo-bot
parent a273cc34c0
commit 9b4cc7a05d
9 changed files with 135 additions and 13 deletions
@@ -422,6 +422,7 @@ unused.import.statement=Unused import statement
unused.library.display.name=Unused library
unused.library.problem.descriptor=Unused library ''{0}''
unused.library.roots.problem.descriptor=Unused roots {0} from library ''{1}''
missorted.imports.inspection.display.name=Missorted imports
var.can.be.replaced.with.explicit.type='var' can be replaced with explicit type
vararg.method.call.with.50.poly.arguments=Vararg method call with 50+ poly arguments may cause compilation and analysis slowdown
inspection.inconsistent.language.level.display.name=Inconsistent language level settings
@@ -245,6 +245,9 @@
<globalInspection groupPath="Java" language="JAVA" shortName="UNUSED_IMPORT" bundle="messages.JavaAnalysisBundle" key="unused.import.display.name"
groupBundle="messages.InspectionsBundle" groupKey="group.names.imports" editorAttributes="NOT_USED_ELEMENT_ATTRIBUTES" enabledByDefault="true" level="WARNING"
implementationClass="com.intellij.codeInspection.unusedImport.UnusedImportInspection"/>
<globalInspection groupPath="Java" language="JAVA" shortName="MISSORTED_IMPORTS" bundle="messages.JavaAnalysisBundle" key="missorted.imports.inspection.display.name"
groupBundle="messages.InspectionsBundle" groupKey="group.names.imports" enabledByDefault="true" level="INFORMATION"
implementationClass="com.intellij.codeInspection.unusedImport.MissortedImportsInspection"/>
<globalInspection groupPath="Java" language="JAVA" shortName="RedundantThrows" groupKey="group.names.declaration.redundancy" groupBundle="messages.InspectionsBundle"
enabledByDefault="true" level="WARNING"
implementationClass="com.intellij.codeInspection.unneededThrows.RedundantThrowsDeclarationInspection"
@@ -2,11 +2,13 @@
package com.intellij.codeInsight.daemon.impl;
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInspection.unusedImport.MissortedImportsInspection;
import com.intellij.codeInspection.unusedImport.UnusedImportInspection;
import com.intellij.ide.highlighter.JavaHighlightingColors;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.editor.colors.CodeInsightColors;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
public final class JavaHighlightInfoTypes {
@@ -15,6 +17,9 @@ public final class JavaHighlightInfoTypes {
public final static HighlightInfoType UNUSED_IMPORT = new HighlightInfoType.HighlightInfoTypeSeverityByKey(
HighlightDisplayKey.findOrRegister(UnusedImportInspection.SHORT_NAME, UnusedImportInspection.getDisplayNameText()), CodeInsightColors.NOT_USED_ELEMENT_ATTRIBUTES);
@NonNls
public static final HighlightInfoType MISSORTED_IMPORTS = new HighlightInfoType.HighlightInfoTypeSeverityByKey(
HighlightDisplayKey.findOrRegister(MissortedImportsInspection.SHORT_NAME, MissortedImportsInspection.getDisplayNameText()), JavaHighlightingColors.MISSORTED_IMPORTS_ATTRIBUTES);
public final static HighlightInfoType JAVA_KEYWORD = new HighlightInfoType.HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, JavaHighlightingColors.KEYWORD);
@@ -15,6 +15,7 @@ import com.intellij.codeInspection.SuppressionUtil;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspectionBase;
import com.intellij.codeInspection.ex.InspectionProfileImpl;
import com.intellij.codeInspection.ex.InspectionProfileWrapper;
import com.intellij.codeInspection.unusedImport.MissortedImportsInspection;
import com.intellij.codeInspection.unusedImport.UnusedImportInspection;
import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspectionBase;
import com.intellij.codeInspection.util.SpecialAnnotationsUtilBase;
@@ -58,7 +59,7 @@ class PostHighlightingVisitor extends JavaElementVisitor {
private final PsiFile myFile;
@NotNull private final Document myDocument;
private final GlobalUsageHelper myGlobalUsageHelper;
private IntentionAction myOptimizeImportsFix; // when not null, there are redundant/mis-sorted imports in the file
private IntentionAction myOptimizeImportsFix; // when not null, there are not-optimized imports in the file
private int myCurrentEntryIndex = -1;
private final UnusedSymbolLocalInspectionBase myUnusedSymbolInspection;
private final HighlightDisplayKey myDeadCodeKey;
@@ -113,15 +114,13 @@ class PostHighlightingVisitor extends JavaElementVisitor {
}
HighlightDisplayKey unusedImportKey = HighlightDisplayKey.find(UnusedImportInspection.SHORT_NAME);
if (unusedImportKey != null && isUnusedImportEnabled(unusedImportKey)) {
PsiJavaFile javaFile = (PsiJavaFile)myFile;
PsiImportList importList = javaFile.getImportList();
if (importList != null) {
PsiImportStatementBase[] imports = importList.getAllImportStatements();
for (PsiImportStatementBase statement : imports) {
ProgressManager.checkCanceled();
processImport(holder, javaFile, statement, unusedImportKey);
}
PsiJavaFile javaFile = ObjectUtils.tryCast(myFile, PsiJavaFile.class);
PsiImportList importList = javaFile == null ? null : javaFile.getImportList();
if (unusedImportKey != null && isUnusedImportEnabled(unusedImportKey) && importList != null) {
PsiImportStatementBase[] imports = importList.getAllImportStatements();
for (PsiImportStatementBase statement : imports) {
ProgressManager.checkCanceled();
processImport(holder, javaFile, statement, unusedImportKey);
}
}
@@ -134,6 +133,13 @@ class PostHighlightingVisitor extends JavaElementVisitor {
if (fix != null) {
OptimizeImportRestarter.getInstance(myProject).scheduleOnDaemonFinish(myFile, fix);
}
HighlightDisplayKey misSortedKey = HighlightDisplayKey.find(MissortedImportsInspection.SHORT_NAME);
if (misSortedKey != null && isToolEnabled(misSortedKey) && fix != null && importList != null) {
holder.add(HighlightInfo.newHighlightInfo(JavaHighlightInfoTypes.MISSORTED_IMPORTS)
.range(importList)
.registerFix(fix, null, HighlightDisplayKey.getDisplayNameByKey(misSortedKey), null, misSortedKey)
.create());
}
}
private void addInfo(@NotNull HighlightInfoHolder holder, @NotNull HighlightInfo.Builder builder) {
@@ -0,0 +1,79 @@
/*
* Copyright 2003-2015 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInspection.unusedImport;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.QuickFixFactory;
import com.intellij.codeInspection.*;
import com.intellij.java.analysis.JavaAnalysisBundle;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiImportList;
import com.intellij.psi.PsiImportStatementBase;
import com.intellij.psi.PsiJavaFile;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
public class MissortedImportsInspection extends GlobalSimpleInspectionTool {
@NonNls
public static final String SHORT_NAME = "MISSORTED_IMPORTS";
@Override
public void checkFile(@NotNull PsiFile file,
@NotNull InspectionManager manager,
@NotNull ProblemsHolder problemsHolder,
@NotNull GlobalInspectionContext globalContext,
@NotNull ProblemDescriptionsProcessor problemDescriptionsProcessor) {
if (!(file instanceof PsiJavaFile javaFile) || FileTypeUtils.isInServerPageFile(file)) return;
PsiImportList importList = javaFile.getImportList();
PsiImportStatementBase[] imports = importList == null ? PsiImportStatementBase.EMPTY_ARRAY : importList.getAllImportStatements();
int currentEntryIndex = 0;
for (PsiImportStatementBase importStatement : imports) {
ProgressManager.checkCanceled();
// jsp include directive hack
if (importStatement.isForeignFileImport()) {
continue;
}
int entryIndex = JavaCodeStyleManager.getInstance(javaFile.getProject()).findEntryIndex(importStatement);
if (entryIndex < currentEntryIndex) {
// mis-sorted import found
IntentionAction fix = QuickFixFactory.getInstance().createOptimizeImportsFix(true, javaFile);
problemsHolder.registerProblem(importList, getDisplayNameText(), new IntentionWrapper(fix));
return;
}
currentEntryIndex = entryIndex;
}
}
@NotNull
@Override
public String getShortName() {
return SHORT_NAME;
}
@Override
public boolean worksInBatchModeOnly() {
return false;
}
@NotNull
public static @Nls String getDisplayNameText() {
return JavaAnalysisBundle.message("missorted.imports.inspection.display.name");
}
}
@@ -54,7 +54,7 @@ public final class JavaHighlightingColors {
public static final TextAttributesKey CONSTRUCTOR_DECLARATION_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("CONSTRUCTOR_DECLARATION_ATTRIBUTES", DefaultLanguageHighlighterColors.FUNCTION_DECLARATION);
public static final TextAttributesKey ANNOTATION_NAME_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("ANNOTATION_NAME_ATTRIBUTES", DefaultLanguageHighlighterColors.METADATA);
public static final TextAttributesKey ANNOTATION_ATTRIBUTE_NAME_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("ANNOTATION_ATTRIBUTE_NAME_ATTRIBUTES", DefaultLanguageHighlighterColors.METADATA);
public static final TextAttributesKey ANNOTATION_ATTRIBUTE_VALUE_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("ANNOTATION_ATTRIBUTE_VALUE_ATTRIBUTES", DefaultLanguageHighlighterColors.METADATA);
public static final TextAttributesKey MISSORTED_IMPORTS_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("MISSORTED_IMPORTS_ATTRIBUTES");
//visibility
public static final TextAttributesKey PUBLIC_REFERENCE_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("PUBLIC_REFERENCE", (TextAttributesKey)null);
@@ -704,7 +704,10 @@ public final class QuickFixFactoryImpl extends QuickFixFactory {
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
if (myOnTheFly && !timeToOptimizeImports(file, myInContent, extensionsAllowToChangeFileSilently) || !(file instanceof PsiJavaFile)) {
if (!(file instanceof PsiJavaFile)) {
return false;
}
if (ApplicationManager.getApplication().isDispatchThread() && myOnTheFly && !timeToOptimizeImports(file, myInContent, extensionsAllowToChangeFileSilently)) {
return false;
}
VirtualFile virtualFile = file.getViewProvider().getVirtualFile();
@@ -0,0 +1,23 @@
<html>
<body>
Reports <code>import</code> statements which are not arranged according to the current code style (see Settings|Editor|Code Style).
<p><b>Example:</b></p>
<pre><code>
import java.util.List;
import java.util.ArrayList;
public class Example {
List list = new ArrayList();
}
</code></pre>
<p>After the "Optimize Imports" quick fix is applied:
<pre><code>
import java.util.ArrayList;
import java.util.List;
public class Example {
List list = new ArrayList();
}
</code></pre>
</body>
</html>
@@ -19,7 +19,9 @@ public final class HighlightInfoFilterImpl implements HighlightInfoFilter {
if (file != null && file.getOriginalFile() instanceof PsiCompiledFile) {
return info.getSeverity() == HighlightInfoType.SYMBOL_TYPE_SEVERITY;
}
if (info.findRegisteredQuickFix((__, __1) -> true) != null) {
return true; // must not hide if there are fixes to show
}
if (Holder.ourTestMode) {
return true; // Tests need to verify highlighting is applied no matter what attributes are defined for this kind of highlighting
}