mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-inspections] IJ-CR-123164 IDEA-341641 Intention to convert implicit class to explicit and vice versa
- more tests - small optimization - preserve first comment in created implicitly declared classes - fixed java docs - move highlighting to the whole declaration GitOrigin-RevId: e7ea706151f09852473e31d3831bb3008da62475
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d3b1e47df7
commit
858b2cd664
+29
-23
@@ -3,24 +3,25 @@ package com.intellij.codeInspection;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightingFeature;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.JavaModuleGraphUtil;
|
||||
import com.intellij.ide.highlighter.JavaFileType;
|
||||
import com.intellij.java.JavaBundle;
|
||||
import com.intellij.modcommand.ModPsiUpdater;
|
||||
import com.intellij.modcommand.PsiUpdateModCommandQuickFix;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.PackageScope;
|
||||
import com.intellij.psi.search.PsiSearchHelper;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.PsiMethodUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.siyeh.ig.psiutils.CommentTracker;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class ExplicitToImplicitClassMigrationInspection extends AbstractBaseJavaLocalInspectionTool {
|
||||
|
||||
private static final String JAVA_SUFFIX = ".java";
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
|
||||
@@ -32,6 +33,12 @@ public final class ExplicitToImplicitClassMigrationInspection extends AbstractBa
|
||||
return;
|
||||
}
|
||||
|
||||
PsiElement lBrace = aClass.getLBrace();
|
||||
PsiElement rBrace = aClass.getRBrace();
|
||||
if (lBrace == null || rBrace == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aClass.getContainingClass() != null) {
|
||||
return;
|
||||
}
|
||||
@@ -50,12 +57,13 @@ public final class ExplicitToImplicitClassMigrationInspection extends AbstractBa
|
||||
}
|
||||
|
||||
String fileName = file.getName();
|
||||
if (!fileName.endsWith(JAVA_SUFFIX)) {
|
||||
if (!fileName.endsWith(JavaFileType.DOT_DEFAULT_EXTENSION)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String className = aClass.getName();
|
||||
if (className == null || !className.equals(fileName.substring(0, fileName.length() - JAVA_SUFFIX.length()))) {
|
||||
if (className == null ||
|
||||
!className.equals(fileName.substring(0, fileName.length() - JavaFileType.DOT_DEFAULT_EXTENSION.length()))) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -67,7 +75,9 @@ public final class ExplicitToImplicitClassMigrationInspection extends AbstractBa
|
||||
return;
|
||||
}
|
||||
|
||||
if (aClass.getExtendsListTypes().length != 0 || aClass.getImplementsListTypes().length != 0) {
|
||||
PsiClassType[] extendsListTypes = aClass.getExtendsListTypes();
|
||||
if ((extendsListTypes.length != 0 && !onlyObjectExtends(extendsListTypes)) ||
|
||||
aClass.getImplementsListTypes().length != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -89,8 +99,8 @@ public final class ExplicitToImplicitClassMigrationInspection extends AbstractBa
|
||||
}
|
||||
}
|
||||
|
||||
Project project = aClass.getProject();
|
||||
PsiPackage aPackage = JavaPsiFacade.getInstance(project).findPackage(file.getPackageName());
|
||||
Project project = holder.getProject();
|
||||
PsiPackage aPackage = JavaPsiFacade.getInstance(project).findPackage("");
|
||||
if (aPackage == null) {
|
||||
return;
|
||||
}
|
||||
@@ -113,18 +123,19 @@ public final class ExplicitToImplicitClassMigrationInspection extends AbstractBa
|
||||
if (first != null) {
|
||||
return;
|
||||
}
|
||||
PsiElement lBrace = aClass.getLBrace();
|
||||
PsiElement rBrace = aClass.getRBrace();
|
||||
if (lBrace == null || rBrace == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (PsiTreeUtil.hasErrorElements(aClass)) {
|
||||
return;
|
||||
}
|
||||
|
||||
holder.registerProblem(classIdentifier, JavaBundle.message("inspection.explicit.to.implicit.class.migration.name"),
|
||||
new ReplaceWithImplicitClassFix());
|
||||
holder.registerProblem(aClass, new TextRange(0, classIdentifier.getTextRangeInParent().getEndOffset()),
|
||||
JavaBundle.message("inspection.explicit.to.implicit.class.migration.name"), new ReplaceWithImplicitClassFix());
|
||||
}
|
||||
|
||||
private static boolean onlyObjectExtends(PsiClassType[] types) {
|
||||
if (types.length != 1) return false;
|
||||
PsiClassType type = types[0];
|
||||
return type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -141,23 +152,18 @@ public final class ExplicitToImplicitClassMigrationInspection extends AbstractBa
|
||||
|
||||
@Override
|
||||
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
|
||||
PsiClass psiClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
|
||||
PsiClass psiClass = ObjectUtils.tryCast(element, PsiClass.class);
|
||||
if (psiClass == null) {
|
||||
return;
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
PsiElement lBrace = psiClass.getLBrace();
|
||||
PsiElement rBrace = psiClass.getRBrace();
|
||||
if (lBrace == null || rBrace == null) {
|
||||
if (lBrace == null || rBrace == null || lBrace.getNextSibling() == null || rBrace.getPrevSibling() == null) {
|
||||
return;
|
||||
}
|
||||
PsiElement psiElement = lBrace.getNextSibling();
|
||||
CommentTracker tracker = new CommentTracker();
|
||||
while (psiElement != null && psiElement != rBrace) {
|
||||
builder.append(tracker.text(psiElement));
|
||||
psiElement = psiElement.getNextSibling();
|
||||
}
|
||||
PsiImplicitClass newClass = PsiElementFactory.getInstance(project).createImplicitClassFromText(builder.toString(), psiClass);
|
||||
String body = tracker.rangeText(lBrace.getNextSibling(), rBrace.getPrevSibling());
|
||||
PsiImplicitClass newClass = PsiElementFactory.getInstance(project).createImplicitClassFromText(body, psiClass);
|
||||
PsiElement replaced = tracker.replace(psiClass, newClass);
|
||||
tracker.insertCommentsBefore(replaced);
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ public interface PsiJavaParserFacade {
|
||||
PsiParameter createParameterFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Creates an implicit class from the specified body text (the text between the braces).
|
||||
* Creates an implicit class from the specified body text.
|
||||
*
|
||||
* @param body the body text of the class to create.
|
||||
* @param context the PSI element used as context for resolving references which cannot be resolved
|
||||
|
||||
@@ -142,13 +142,17 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade {
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiImplicitClass createImplicitClassFromText(@NotNull String body, @Nullable PsiElement context) throws IncorrectOperationException {
|
||||
PsiJavaFile aFile = createDummyJavaFile(body);
|
||||
PsiJavaFile aFile = createDummyJavaFile(
|
||||
"int i = 0;" + //used to preserve first comments
|
||||
body);
|
||||
PsiClass[] classes = aFile.getClasses();
|
||||
if (classes.length != 1) {
|
||||
throw new IncorrectOperationException("Incorrect class '" + body + "'");
|
||||
}
|
||||
if (classes[0] instanceof PsiImplicitClass) {
|
||||
return (PsiImplicitClass)classes[0];
|
||||
PsiImplicitClass implicitClass = (PsiImplicitClass)classes[0];
|
||||
implicitClass.getFirstChild().delete(); //delete stub field
|
||||
return implicitClass;
|
||||
}
|
||||
throw new IncorrectOperationException("Incorrect implicit class '" + body + "'");
|
||||
}
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
// "Convert into implicitly declared class" "true-preview"
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Hello, world!");
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
// "Convert into implicitly declared class" "true-preview"
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Hello, world!");
|
||||
}
|
||||
+4
-1
@@ -2,6 +2,9 @@
|
||||
|
||||
/**
|
||||
* comments
|
||||
*/ /*comments2*/ public static void main(String[] args) {
|
||||
*/ /*comments2*/ /*comments3*/
|
||||
public static void main(String[] args) {
|
||||
//comments4
|
||||
System.out.println("Hello, world!");
|
||||
}
|
||||
//comments5
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// "Convert into implicitly declared class" "true-preview"
|
||||
|
||||
public static void main() {
|
||||
System.out.println("Hello, world!");
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// "Convert into implicitly declared class" "true-preview"
|
||||
|
||||
public void main() {
|
||||
System.out.println("Hello, world!");
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// "Convert into implicitly declared class" "true-preview"
|
||||
public<caret> class beforeCaretAtClass {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Hello, world!");
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// "Convert into implicitly declared class" "true-preview"
|
||||
public<caret> class beforeExtendsObject extends Object {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Hello, world!");
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -5,8 +5,10 @@
|
||||
*/
|
||||
|
||||
public /*comments2*/ class beforeSi<caret>mpleWithComments {
|
||||
|
||||
/*comments3*/
|
||||
public static void main(String[] args) {
|
||||
//comments4
|
||||
System.out.println("Hello, world!");
|
||||
}
|
||||
}
|
||||
//comments5
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// "Convert into implicitly declared class" "false"
|
||||
|
||||
public class beforeWith<caret>EnhancedMain2 {
|
||||
public void main(String arg) {
|
||||
System.out.println("Hello, world!");
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// "Convert into implicitly declared class" "true-preview"
|
||||
|
||||
public class be<caret>foreWithEnhancedMain {
|
||||
public static void main() {
|
||||
System.out.println("Hello, world!");
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// "Convert into implicitly declared class" "true-preview"
|
||||
|
||||
public class beforeWith<caret>EnhancedMain2 {
|
||||
public void main() {
|
||||
System.out.println("Hello, world!");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user