mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
IJ-CR-138822 [java-highlighting] IDEA-355777 Support JEP 477: implicit imports
- cache implicit static references - extract ImplicitlyImportedStaticMember into a separate file GitOrigin-RevId: 105a69ce72b4722f0d32d1d858c426e96b73f9c5
This commit is contained in:
committed by
intellij-monorepo-bot
parent
dc2f88d484
commit
ecff6e161b
@@ -465,13 +465,13 @@ public final class ImportUtils {
|
||||
public static class ImplicitImportChecker {
|
||||
|
||||
@NotNull
|
||||
private final Map<String, PsiJavaFile.StaticMember> myStaticImportStatements = new HashMap<>();
|
||||
private final Map<String, ImplicitlyImportedStaticMember> myStaticImportStatements = new HashMap<>();
|
||||
|
||||
@NotNull
|
||||
private final Set<String> packages = new HashSet<>();
|
||||
|
||||
private ImplicitImportChecker(@NotNull PsiJavaFile file) {
|
||||
for (PsiJavaFile.StaticMember imp : file.getImplicitlyImportedStaticMembers()) {
|
||||
for (ImplicitlyImportedStaticMember imp : file.getImplicitlyImportedStaticMembers()) {
|
||||
myStaticImportStatements.put(imp.getContainingClass(), imp);
|
||||
}
|
||||
packages.addAll(Arrays.asList(file.getImplicitlyImportedPackages()));
|
||||
@@ -480,7 +480,7 @@ public final class ImportUtils {
|
||||
public boolean isImplicitlyImported(@NotNull Import name) {
|
||||
String packageOrClassName = getPackageOrClassName(name.name);
|
||||
if (!name.isStatic && packages.contains(packageOrClassName)) return true;
|
||||
PsiJavaFile.StaticMember base = myStaticImportStatements.get(packageOrClassName);
|
||||
ImplicitlyImportedStaticMember base = myStaticImportStatements.get(packageOrClassName);
|
||||
if (base != null) {
|
||||
if (!name.isStatic) return false;
|
||||
if (base.isOnDemand()) {
|
||||
@@ -500,7 +500,7 @@ public final class ImportUtils {
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public record Import(String name, boolean isStatic) {}
|
||||
public record Import(@NotNull String name, boolean isStatic) {}
|
||||
|
||||
private static boolean memberReferenced(PsiMember member, PsiElement context) {
|
||||
final MemberReferenceVisitor visitor = new MemberReferenceVisitor(member);
|
||||
|
||||
@@ -100,7 +100,7 @@ public final class ImplicitToExplicitClassBackwardMigrationInspection extends Ab
|
||||
if (!(containingFile instanceof PsiJavaFile psiJavaFile)) {
|
||||
return;
|
||||
}
|
||||
PsiJavaFile.@NotNull StaticMember[] imports = PsiImplUtil.getImplicitStaticImports(psiJavaFile);
|
||||
@NotNull ImplicitlyImportedStaticMember[] imports = PsiImplUtil.getImplicitStaticImports(psiJavaFile);
|
||||
PsiElement replaced = implicitClass.replace(newClass);
|
||||
PsiJavaFile newPsiJavaFile = PsiTreeUtil.getParentOfType(replaced, PsiJavaFile.class);
|
||||
if (newPsiJavaFile == null) {
|
||||
@@ -111,7 +111,7 @@ public final class ImplicitToExplicitClassBackwardMigrationInspection extends Ab
|
||||
return;
|
||||
}
|
||||
JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
|
||||
for (PsiJavaFile.@NotNull StaticMember importMember : imports) {
|
||||
for (@NotNull ImplicitlyImportedStaticMember importMember : imports) {
|
||||
PsiClass psiClass = psiFacade.findClass(importMember.getContainingClass(), implicitClass.getResolveScope());
|
||||
if (psiClass == null) {
|
||||
continue;
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.psi;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Class representing a static member represented implicitly imported static members.
|
||||
* if memberName is `*`, it is on demand import
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
public final class ImplicitlyImportedStaticMember {
|
||||
public static final @NotNull ImplicitlyImportedStaticMember @NotNull [] EMPTY_ARRAY = new ImplicitlyImportedStaticMember[0];
|
||||
|
||||
private final @NotNull String myContainingClass;
|
||||
private final @NotNull String myMemberName;
|
||||
|
||||
private ImplicitlyImportedStaticMember(@NotNull String containingClass, @NotNull String memberName) {
|
||||
myContainingClass = containingClass;
|
||||
myMemberName = memberName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getContainingClass() {
|
||||
return myContainingClass;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getMemberName() {
|
||||
return myMemberName;
|
||||
}
|
||||
|
||||
public boolean isOnDemand() {
|
||||
return "*".equals(myMemberName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ImplicitlyImportedStaticMember create(@NotNull String containingClass, @NotNull String memberName) {
|
||||
return new ImplicitlyImportedStaticMember(containingClass, memberName);
|
||||
}
|
||||
}
|
||||
@@ -68,7 +68,10 @@ public interface PsiJavaFile extends PsiImportHolder, PsiClassOwner, AbstractBas
|
||||
* implicitly imported packages (for example, java.lang).
|
||||
*
|
||||
* @return the array of implicitly imported package reference elements.
|
||||
* @deprecated Use {@link PsiJavaFile#getImplicitlyImportedPackages()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval
|
||||
PsiJavaCodeReferenceElement @NotNull [] getImplicitlyImportedPackageReferences();
|
||||
|
||||
/**
|
||||
@@ -94,43 +97,7 @@ public interface PsiJavaFile extends PsiImportHolder, PsiClassOwner, AbstractBas
|
||||
* @return the array of implicitly imported static members.
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
default @NotNull StaticMember @NotNull [] getImplicitlyImportedStaticMembers() {
|
||||
return StaticMember.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class representing a static member represented implicitly imported static members.
|
||||
* if memberName is `*`, it is on demand import
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
class StaticMember {
|
||||
public static final @NotNull StaticMember @NotNull [] EMPTY_ARRAY = new StaticMember[0];
|
||||
|
||||
private final @NotNull String myContainingClass;
|
||||
private final @NotNull String myMemberName;
|
||||
|
||||
private StaticMember(@NotNull String containingClass, @NotNull String memberName) {
|
||||
myContainingClass = containingClass;
|
||||
myMemberName = memberName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getContainingClass() {
|
||||
return myContainingClass;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getMemberName() {
|
||||
return myMemberName;
|
||||
}
|
||||
|
||||
public boolean isOnDemand() {
|
||||
return "*".equals(myMemberName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static StaticMember create(@NotNull String containingClass, @NotNull String memberName) {
|
||||
return new StaticMember(containingClass, memberName);
|
||||
}
|
||||
default @NotNull ImplicitlyImportedStaticMember @NotNull [] getImplicitlyImportedStaticMembers() {
|
||||
return ImplicitlyImportedStaticMember.EMPTY_ARRAY;
|
||||
}
|
||||
}
|
||||
@@ -854,21 +854,21 @@ public final class PsiImplUtil {
|
||||
* @return an array of static members representing the implicit static imports
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
public static @NotNull PsiJavaFile.StaticMember @NotNull[] getImplicitStaticImports(@NotNull PsiFile file) {
|
||||
List<PsiJavaFile.StaticMember> staticImports = new ArrayList<>();
|
||||
public static @NotNull ImplicitlyImportedStaticMember @NotNull[] getImplicitStaticImports(@NotNull PsiFile file) {
|
||||
List<ImplicitlyImportedStaticMember> staticImports = new ArrayList<>();
|
||||
// java.lang.StringTemplate.STR
|
||||
if (PsiUtil.isAvailable(JavaFeature.STRING_TEMPLATES, file)) {
|
||||
staticImports.add(PsiJavaFile.StaticMember.create(CommonClassNames.JAVA_LANG_STRING_TEMPLATE, "STR"));
|
||||
staticImports.add(ImplicitlyImportedStaticMember.create(CommonClassNames.JAVA_LANG_STRING_TEMPLATE, "STR"));
|
||||
}
|
||||
|
||||
// java.io.IO.* for implicit classes
|
||||
if (PsiUtil.isAvailable(JavaFeature.IMPLICIT_IMPORT_IN_IMPLICIT_CLASSES, file) && file instanceof PsiJavaFile) {
|
||||
PsiClass[] classes = ((PsiJavaFile)file).getClasses();
|
||||
if (classes.length == 1 && classes[0] instanceof PsiImplicitClass) {
|
||||
staticImports.add(PsiJavaFile.StaticMember.create(JAVA_IO_IO, "*"));
|
||||
staticImports.add(ImplicitlyImportedStaticMember.create(JAVA_IO_IO, "*"));
|
||||
}
|
||||
}
|
||||
|
||||
return staticImports.toArray(PsiJavaFile.StaticMember.EMPTY_ARRAY);
|
||||
return staticImports.toArray(ImplicitlyImportedStaticMember.EMPTY_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJava
|
||||
|
||||
private final CachedValue<MostlySingularMultiMap<String, ResultWithContext>> myResolveCache;
|
||||
private final CachedValue<Map<String, Iterable<ResultWithContext>>> myCachedDeclarations;
|
||||
private final CachedValue<List<PsiImportStaticStatement>> myCachedImplicitImportStaticStatements;
|
||||
private volatile String myPackageName;
|
||||
|
||||
protected PsiJavaFileBaseImpl(@NotNull IElementType elementType, @NotNull IElementType contentElementType, @NotNull FileViewProvider viewProvider) {
|
||||
@@ -64,6 +65,13 @@ public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJava
|
||||
}
|
||||
return Result.create(declarations, PsiModificationTracker.MODIFICATION_COUNT);
|
||||
}, false);
|
||||
myCachedImplicitImportStaticStatements = cachedValuesManager.createCachedValue(() -> {
|
||||
List<PsiImportStaticStatement> statements = createImplicitImportStaticStatements();
|
||||
if (!this.isPhysical()) {
|
||||
return Result.create(statements, this.getContainingFile(), PsiModificationTracker.MODIFICATION_COUNT);
|
||||
}
|
||||
return Result.create(statements, PsiModificationTracker.MODIFICATION_COUNT);
|
||||
}, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -333,7 +341,7 @@ public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJava
|
||||
}
|
||||
}
|
||||
}
|
||||
for (PsiImportStaticStatement staticImport : ContainerUtil.append(getImplicitlyImportedStaticStatements(), getImportStaticStatements())) {
|
||||
for (PsiImportStaticStatement staticImport : ContainerUtil.append(getImplicitImportStaticStatements(), getImportStaticStatements())) {
|
||||
String name = staticImport.getReferenceName();
|
||||
if (name != null) {
|
||||
staticImports.putValue(name, staticImport);
|
||||
@@ -425,7 +433,7 @@ public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJava
|
||||
}
|
||||
|
||||
private boolean processOnDemandStaticImports(@NotNull ResolveState state, @NotNull StaticImportFilteringProcessor processor) {
|
||||
for (PsiImportStaticStatement importStaticStatement : ContainerUtil.append(getImplicitlyImportedStaticStatements(), getImportStaticStatements())) {
|
||||
for (PsiImportStaticStatement importStaticStatement : ContainerUtil.append(getImplicitImportStaticStatements(), getImportStaticStatements())) {
|
||||
if (!importStaticStatement.isOnDemand()) continue;
|
||||
PsiClass targetElement = importStaticStatement.resolveTargetClass();
|
||||
if (targetElement != null) {
|
||||
@@ -524,7 +532,7 @@ public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJava
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull StaticMember @NotNull [] getImplicitlyImportedStaticMembers() {
|
||||
public @NotNull ImplicitlyImportedStaticMember @NotNull [] getImplicitlyImportedStaticMembers() {
|
||||
return PsiImplUtil.getImplicitStaticImports(this);
|
||||
}
|
||||
|
||||
@@ -540,7 +548,13 @@ public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJava
|
||||
clearCaches();
|
||||
}
|
||||
|
||||
private List<PsiImportStaticStatement> getImplicitlyImportedStaticStatements() {
|
||||
@NotNull
|
||||
private List<PsiImportStaticStatement> getImplicitImportStaticStatements() {
|
||||
return myCachedImplicitImportStaticStatements.getValue();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<PsiImportStaticStatement> createImplicitImportStaticStatements() {
|
||||
PsiElementFactory factory = PsiElementFactory.getInstance(getProject());
|
||||
return ContainerUtil.map(getImplicitlyImportedStaticMembers(),
|
||||
member -> factory.createImportStaticStatementFromText(member.getContainingClass(), member.getMemberName()));
|
||||
|
||||
Reference in New Issue
Block a user