From 6b1e4261e3137ddba154a6108116f31d394abdea Mon Sep 17 00:00:00 2001 From: UNV Date: Thu, 24 Apr 2025 19:44:57 +0300 Subject: [PATCH 1/2] Reformatting callers of DefaultPsiElementFinderImpl.processPackageDirectories. --- .../java/language/psi/PsiElementFinder.java | 330 ++-- .../psi/impl/DefaultPsiElementFinderImpl.java | 280 +-- .../impl/psi/impl/JavaPsiFacadeImpl.java | 596 +++---- .../language/impl/psi/impl/PsiImplUtil.java | 1562 +++++++++-------- .../impl/psi/impl/PsiSuperMethodImplUtil.java | 807 +++++---- .../impl/psi/impl/file/PsiPackageImpl.java | 552 +++--- .../impl/source/PsiAnnotationMethodImpl.java | 105 +- .../impl/psi/impl/source/PsiMethodImpl.java | 662 +++---- .../findUsages/JavaFindUsagesHandler.java | 75 +- 9 files changed, 2564 insertions(+), 2405 deletions(-) diff --git a/java-language-api/src/main/java/com/intellij/java/language/psi/PsiElementFinder.java b/java-language-api/src/main/java/com/intellij/java/language/psi/PsiElementFinder.java index 9878e1f4f..02856ecdd 100644 --- a/java-language-api/src/main/java/com/intellij/java/language/psi/PsiElementFinder.java +++ b/java-language-api/src/main/java/com/intellij/java/language/psi/PsiElementFinder.java @@ -38,175 +38,181 @@ */ @ExtensionAPI(ComponentScope.PROJECT) public abstract class PsiElementFinder { - public static final ExtensionPointName EP_NAME = ExtensionPointName.create(PsiElementFinder.class); - - /** - * Searches the specified scope within the project for a class with the specified full-qualified - * name and returns one if it is found. - * - * @param qualifiedName the full-qualified name of the class to find. - * @param scope the scope to search. - * @return the PSI class, or null if no class with such name is found. - * @see JavaPsiFacade#findClass(String, GlobalSearchScope) - */ - @Nullable - public abstract PsiClass findClass(@Nonnull String qualifiedName, @Nonnull GlobalSearchScope scope); - - /** - * Searches the specified scope within the project for classes with the specified full-qualified - * name and returns all found classes. - * - * @param qualifiedName the full-qualified name of the class to find. - * @param scope the scope to search. - * @return the array of found classes, or an empty array if no classes are found. - * @see JavaPsiFacade#findClasses(String, GlobalSearchScope) - */ - @Nonnull - public abstract PsiClass[] findClasses(@Nonnull String qualifiedName, @Nonnull GlobalSearchScope scope); - - /** - * Searches the project for the package with the specified full-qualified name and returns one - * if it is found. - * - * @param qualifiedName the full-qualified name of the package to find. - * @return the PSI package, or null if no package with such name is found. - * @see JavaPsiFacade#findPackage(String) - */ - @Nullable - public PsiJavaPackage findPackage(@Nonnull String qualifiedName) { - return null; - } - - /** - * Search java module for file. Can be automatic module or explicit declaration from java file - */ - @Nullable - public PsiJavaModule findModule(@Nonnull VirtualFile file) { - return null; - } - - @Nonnull - public Collection findModules(@Nonnull String moduleName, @Nonnull GlobalSearchScope scope) { - return List.of(); - } - - /** - * Returns the list of subpackages of the specified package in the specified search scope. - * - * @param psiPackage the package to return the list of subpackages for. - * @param scope the scope in which subpackages are searched. - * @return the list of subpackages. - * @see PsiJavaPackage#getSubPackages(GlobalSearchScope) - */ - @Nonnull - public PsiJavaPackage[] getSubPackages(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { - return PsiJavaPackage.EMPTY_ARRAY; - } - - /** - * Returns a array of files belonging to the specified package which are not located in any of the package directories. - * - * @param psiPackage the package to return the list of files for. - * @param scope the scope in which files are searched. - * @return the array of files. - */ - @Nonnull - public PsiFile[] getPackageFiles(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { - return PsiFile.EMPTY_ARRAY; - } - - /** - * Returns the filter to use for filtering the list of files in the directories belonging to a package to exclude files - * that actually belong to a different package. (For example, in Kotlin the package of a file is determined by its - * package statement and not by its location in the directory structure, so the files which have a differring package - * statement need to be excluded.) - * - * @param psiPackage the package for which the list of files is requested. - * @param scope the scope in which children are requested. - * @return the filter to use, or null if no additional filtering is necessary. - */ - @Nullable - public Predicate getPackageFilesFilter(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { - return null; - } - - /** - * Returns the list of classes in the specified package and in the specified search scope. - * - * @param psiPackage the package to return the list of classes in. - * @param scope the scope in which classes are searched. - * @return the list of classes. - * @see PsiJavaPackage#getClasses(GlobalSearchScope) - */ - @Nonnull - public PsiClass[] getClasses(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { - return PsiClass.EMPTY_ARRAY; - } - - /** - * A method to optimize resolve (to only search classes in a package which might be there) - */ - @Nonnull - public Set getClassNames(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { - return getClassNames(getClasses(psiPackage, scope)); - } - - @Nonnull - protected static Set getClassNames(@Nonnull PsiClass[] classes) { - if (classes.length == 0) { - return Collections.emptySet(); + public static final ExtensionPointName EP_NAME = ExtensionPointName.create(PsiElementFinder.class); + + /** + * Searches the specified scope within the project for a class with the specified full-qualified + * name and returns one if it is found. + * + * @param qualifiedName the full-qualified name of the class to find. + * @param scope the scope to search. + * @return the PSI class, or null if no class with such name is found. + * @see JavaPsiFacade#findClass(String, GlobalSearchScope) + */ + @Nullable + public abstract PsiClass findClass(@Nonnull String qualifiedName, @Nonnull GlobalSearchScope scope); + + /** + * Searches the specified scope within the project for classes with the specified full-qualified + * name and returns all found classes. + * + * @param qualifiedName the full-qualified name of the class to find. + * @param scope the scope to search. + * @return the array of found classes, or an empty array if no classes are found. + * @see JavaPsiFacade#findClasses(String, GlobalSearchScope) + */ + @Nonnull + public abstract PsiClass[] findClasses(@Nonnull String qualifiedName, @Nonnull GlobalSearchScope scope); + + /** + * Searches the project for the package with the specified full-qualified name and returns one + * if it is found. + * + * @param qualifiedName the full-qualified name of the package to find. + * @return the PSI package, or null if no package with such name is found. + * @see JavaPsiFacade#findPackage(String) + */ + @Nullable + public PsiJavaPackage findPackage(@Nonnull String qualifiedName) { + return null; } - final HashSet names = new HashSet(); - for (PsiClass aClass : classes) { - ContainerUtil.addIfNotNull(names, aClass.getName()); + /** + * Search java module for file. Can be automatic module or explicit declaration from java file + */ + @Nullable + public PsiJavaModule findModule(@Nonnull VirtualFile file) { + return null; } - return names; - } - - public boolean processPackageDirectories(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope, - @Nonnull Processor consumer) { - return processPackageDirectories(psiPackage, scope, consumer, false); - } - - public boolean processPackageDirectories(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope, - @Nonnull Processor consumer, boolean includeLibrarySources) { - return true; - } - - /** - * Returns the list of classes in the specified package and in the specified search scope. - * - * @param className short name of the class - * @param psiPackage the package to return the list of classes in. - * @param scope the scope in which classes are searched. - * @return the list of classes. - * @see PsiJavaPackage#getClasses(GlobalSearchScope) - */ - @Nonnull - public PsiClass[] getClasses(@Nullable String className, @Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { - PsiClass[] allClasses = getClasses(psiPackage, scope); - if (className == null) { - return allClasses; + + @Nonnull + public Collection findModules(@Nonnull String moduleName, @Nonnull GlobalSearchScope scope) { + return List.of(); + } + + /** + * Returns the list of subpackages of the specified package in the specified search scope. + * + * @param psiPackage the package to return the list of subpackages for. + * @param scope the scope in which subpackages are searched. + * @return the list of subpackages. + * @see PsiJavaPackage#getSubPackages(GlobalSearchScope) + */ + @Nonnull + public PsiJavaPackage[] getSubPackages(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { + return PsiJavaPackage.EMPTY_ARRAY; + } + + /** + * Returns a array of files belonging to the specified package which are not located in any of the package directories. + * + * @param psiPackage the package to return the list of files for. + * @param scope the scope in which files are searched. + * @return the array of files. + */ + @Nonnull + public PsiFile[] getPackageFiles(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { + return PsiFile.EMPTY_ARRAY; + } + + /** + * Returns the filter to use for filtering the list of files in the directories belonging to a package to exclude files + * that actually belong to a different package. (For example, in Kotlin the package of a file is determined by its + * package statement and not by its location in the directory structure, so the files which have a differring package + * statement need to be excluded.) + * + * @param psiPackage the package for which the list of files is requested. + * @param scope the scope in which children are requested. + * @return the filter to use, or null if no additional filtering is necessary. + */ + @Nullable + public Predicate getPackageFilesFilter(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { + return null; + } + + /** + * Returns the list of classes in the specified package and in the specified search scope. + * + * @param psiPackage the package to return the list of classes in. + * @param scope the scope in which classes are searched. + * @return the list of classes. + * @see PsiJavaPackage#getClasses(GlobalSearchScope) + */ + @Nonnull + public PsiClass[] getClasses(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { + return PsiClass.EMPTY_ARRAY; + } + + /** + * A method to optimize resolve (to only search classes in a package which might be there) + */ + @Nonnull + public Set getClassNames(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { + return getClassNames(getClasses(psiPackage, scope)); + } + + @Nonnull + protected static Set getClassNames(@Nonnull PsiClass[] classes) { + if (classes.length == 0) { + return Collections.emptySet(); + } + + final HashSet names = new HashSet(); + for (PsiClass aClass : classes) { + ContainerUtil.addIfNotNull(names, aClass.getName()); + } + return names; } - return filterByName(className, allClasses); - } - @Nonnull - public static PsiClass[] filterByName(@Nonnull String className, @Nonnull PsiClass[] classes) { - if (classes.length == 0) { - return PsiClass.EMPTY_ARRAY; + public boolean processPackageDirectories( + @Nonnull PsiJavaPackage psiPackage, + @Nonnull GlobalSearchScope scope, + @Nonnull Processor consumer + ) { + return processPackageDirectories(psiPackage, scope, consumer, false); } - if (classes.length == 1) { - return className.equals(classes[0].getName()) ? classes : PsiClass.EMPTY_ARRAY; + + public boolean processPackageDirectories( + @Nonnull PsiJavaPackage psiPackage, + @Nonnull GlobalSearchScope scope, + @Nonnull Processor consumer, + boolean includeLibrarySources + ) { + return true; } - List foundClasses = new SmartList(); - for (PsiClass psiClass : classes) { - if (className.equals(psiClass.getName())) { - foundClasses.add(psiClass); - } + + /** + * Returns the list of classes in the specified package and in the specified search scope. + * + * @param className short name of the class + * @param psiPackage the package to return the list of classes in. + * @param scope the scope in which classes are searched. + * @return the list of classes. + * @see PsiJavaPackage#getClasses(GlobalSearchScope) + */ + @Nonnull + public PsiClass[] getClasses(@Nullable String className, @Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { + PsiClass[] allClasses = getClasses(psiPackage, scope); + if (className == null) { + return allClasses; + } + return filterByName(className, allClasses); } - return foundClasses.isEmpty() ? PsiClass.EMPTY_ARRAY : foundClasses.toArray(new PsiClass[foundClasses.size()]); - } + @Nonnull + public static PsiClass[] filterByName(@Nonnull String className, @Nonnull PsiClass[] classes) { + if (classes.length == 0) { + return PsiClass.EMPTY_ARRAY; + } + if (classes.length == 1) { + return className.equals(classes[0].getName()) ? classes : PsiClass.EMPTY_ARRAY; + } + List foundClasses = new SmartList(); + for (PsiClass psiClass : classes) { + if (className.equals(psiClass.getName())) { + foundClasses.add(psiClass); + } + } + return foundClasses.isEmpty() ? PsiClass.EMPTY_ARRAY : foundClasses.toArray(new PsiClass[foundClasses.size()]); + } } diff --git a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/DefaultPsiElementFinderImpl.java b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/DefaultPsiElementFinderImpl.java index fc56e7b67..4ced69b80 100644 --- a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/DefaultPsiElementFinderImpl.java +++ b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/DefaultPsiElementFinderImpl.java @@ -24,156 +24,158 @@ import java.util.*; /** -* @author VISTALL -* @since 09/12/2022 -*/ + * @author VISTALL + * @since 09/12/2022 + */ @ExtensionImpl(id = "default", order = "first") public class DefaultPsiElementFinderImpl extends PsiElementFinder implements DumbAware { - private final Project myProject; - private final JavaFileManager myJavaFileManager; - - @Inject - public DefaultPsiElementFinderImpl(Project project, JavaFileManager javaFileManager) { - myProject = project; - myJavaFileManager = javaFileManager; - } - - @Override - public PsiClass findClass(@Nonnull String qualifiedName, @Nonnull GlobalSearchScope scope) { - return myJavaFileManager.findClass(qualifiedName, scope); - } - - @Override - @Nonnull - public PsiClass[] findClasses(@Nonnull String qualifiedName, @Nonnull GlobalSearchScope scope) { - return myJavaFileManager.findClasses(qualifiedName, scope); - } - - @Override - public PsiJavaPackage findPackage(@Nonnull String qualifiedName) { - return myJavaFileManager.findPackage(qualifiedName); - } - - @Override - @Nonnull - public PsiJavaPackage[] getSubPackages(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { - final Map packagesMap = new HashMap<>(); - final String qualifiedName = psiPackage.getQualifiedName(); - for (PsiDirectory dir : psiPackage.getDirectories(scope)) { - PsiDirectory[] subDirs = dir.getSubdirectories(); - for (PsiDirectory subDir : subDirs) { - final PsiJavaPackage aPackage = JavaDirectoryService.getInstance().getPackage(subDir); - if (aPackage != null) { - final String subQualifiedName = aPackage.getQualifiedName(); - if (subQualifiedName.startsWith(qualifiedName) && !packagesMap.containsKey(subQualifiedName)) { - packagesMap.put(aPackage.getQualifiedName(), aPackage); - } - } - } + private final Project myProject; + private final JavaFileManager myJavaFileManager; + + @Inject + public DefaultPsiElementFinderImpl(Project project, JavaFileManager javaFileManager) { + myProject = project; + myJavaFileManager = javaFileManager; } - packagesMap.remove(qualifiedName); // avoid SOE caused by returning a package as a subpackage of itself - return packagesMap.values().toArray(new PsiJavaPackage[packagesMap.size()]); - } - - @Override - @Nonnull - public PsiClass[] getClasses(@Nonnull PsiJavaPackage psiPackage, @Nonnull final GlobalSearchScope scope) { - return getClasses(null, psiPackage, scope); - } - - @Override - @Nonnull - public PsiClass[] getClasses(@Nullable String shortName, @Nonnull PsiJavaPackage psiPackage, @Nonnull final GlobalSearchScope scope) { - List list = null; - String packageName = psiPackage.getQualifiedName(); - for (PsiDirectory dir : psiPackage.getDirectories(scope)) { - PsiClass[] classes = JavaDirectoryService.getInstance().getClasses(dir); - if (classes.length == 0) { - continue; - } - if (list == null) { - list = new ArrayList<>(); - } - for (PsiClass aClass : classes) { - // class file can be located in wrong place inside file system - String qualifiedName = aClass.getQualifiedName(); - if (qualifiedName != null) { - qualifiedName = StringUtil.getPackageName(qualifiedName); - } - if (Comparing.strEqual(qualifiedName, packageName)) { - if (shortName == null || shortName.equals(aClass.getName())) { - list.add(aClass); - } + @Override + public PsiClass findClass(@Nonnull String qualifiedName, @Nonnull GlobalSearchScope scope) { + return myJavaFileManager.findClass(qualifiedName, scope); + } + + @Override + @Nonnull + public PsiClass[] findClasses(@Nonnull String qualifiedName, @Nonnull GlobalSearchScope scope) { + return myJavaFileManager.findClasses(qualifiedName, scope); + } + + @Override + public PsiJavaPackage findPackage(@Nonnull String qualifiedName) { + return myJavaFileManager.findPackage(qualifiedName); + } + + @Override + @Nonnull + public PsiJavaPackage[] getSubPackages(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { + final Map packagesMap = new HashMap<>(); + final String qualifiedName = psiPackage.getQualifiedName(); + for (PsiDirectory dir : psiPackage.getDirectories(scope)) { + PsiDirectory[] subDirs = dir.getSubdirectories(); + for (PsiDirectory subDir : subDirs) { + final PsiJavaPackage aPackage = JavaDirectoryService.getInstance().getPackage(subDir); + if (aPackage != null) { + final String subQualifiedName = aPackage.getQualifiedName(); + if (subQualifiedName.startsWith(qualifiedName) && !packagesMap.containsKey(subQualifiedName)) { + packagesMap.put(aPackage.getQualifiedName(), aPackage); + } + } + } } - } + + packagesMap.remove(qualifiedName); // avoid SOE caused by returning a package as a subpackage of itself + return packagesMap.values().toArray(new PsiJavaPackage[packagesMap.size()]); } - if (list == null) { - return PsiClass.EMPTY_ARRAY; + + @Override + @Nonnull + public PsiClass[] getClasses(@Nonnull PsiJavaPackage psiPackage, @Nonnull final GlobalSearchScope scope) { + return getClasses(null, psiPackage, scope); } - if (list.size() > 1) { - Lists.quickSort(list, (o1, o2) -> { - VirtualFile file1 = PsiUtilCore.getVirtualFile(o1); - VirtualFile file2 = PsiUtilCore.getVirtualFile(o2); - return file1 == null ? file2 == null ? 0 : -1 : file2 == null ? 1 : scope.compare(file2, file1); - }); + @Override + @Nonnull + public PsiClass[] getClasses(@Nullable String shortName, @Nonnull PsiJavaPackage psiPackage, @Nonnull final GlobalSearchScope scope) { + List list = null; + String packageName = psiPackage.getQualifiedName(); + for (PsiDirectory dir : psiPackage.getDirectories(scope)) { + PsiClass[] classes = JavaDirectoryService.getInstance().getClasses(dir); + if (classes.length == 0) { + continue; + } + if (list == null) { + list = new ArrayList<>(); + } + for (PsiClass aClass : classes) { + // class file can be located in wrong place inside file system + String qualifiedName = aClass.getQualifiedName(); + if (qualifiedName != null) { + qualifiedName = StringUtil.getPackageName(qualifiedName); + } + if (Comparing.strEqual(qualifiedName, packageName)) { + if (shortName == null || shortName.equals(aClass.getName())) { + list.add(aClass); + } + } + } + } + if (list == null) { + return PsiClass.EMPTY_ARRAY; + } + + if (list.size() > 1) { + Lists.quickSort(list, (o1, o2) -> { + VirtualFile file1 = PsiUtilCore.getVirtualFile(o1); + VirtualFile file2 = PsiUtilCore.getVirtualFile(o2); + return file1 == null ? file2 == null ? 0 : -1 : file2 == null ? 1 : scope.compare(file2, file1); + }); + } + + return list.toArray(new PsiClass[list.size()]); } - return list.toArray(new PsiClass[list.size()]); - } - - @Nonnull - @Override - public Set getClassNames(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { - Set names = null; - FileIndexFacade facade = FileIndexFacade.getInstance(myProject); - for (PsiDirectory dir : psiPackage.getDirectories(scope)) { - for (PsiFile file : dir.getFiles()) { - if (file instanceof PsiClassOwner && file.getViewProvider().getLanguages().size() == 1) { - VirtualFile vFile = file.getVirtualFile(); - if (vFile != null && - !(file instanceof PsiCompiledElement) && - !facade.isInSourceContent(vFile) && - (!scope.isForceSearchingInLibrarySources() || !StubTreeLoader.getInstance().canHaveStub(vFile))) { - continue; - } - - Set inFile = - file instanceof PsiClassOwnerEx ? ((PsiClassOwnerEx)file).getClassNames() : getClassNames(((PsiClassOwner)file).getClasses()); - - if (inFile.isEmpty()) { - continue; - } - if (names == null) { - names = new HashSet<>(); - } - names.addAll(inFile); + @Nonnull + @Override + public Set getClassNames(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { + Set names = null; + FileIndexFacade facade = FileIndexFacade.getInstance(myProject); + for (PsiDirectory dir : psiPackage.getDirectories(scope)) { + for (PsiFile file : dir.getFiles()) { + if (file instanceof PsiClassOwner && file.getViewProvider().getLanguages().size() == 1) { + VirtualFile vFile = file.getVirtualFile(); + if (vFile != null && + !(file instanceof PsiCompiledElement) && + !facade.isInSourceContent(vFile) && + (!scope.isForceSearchingInLibrarySources() || !StubTreeLoader.getInstance().canHaveStub(vFile))) { + continue; + } + + Set inFile = + file instanceof PsiClassOwnerEx ? ((PsiClassOwnerEx)file).getClassNames() : getClassNames(((PsiClassOwner)file).getClasses()); + + if (inFile.isEmpty()) { + continue; + } + if (names == null) { + names = new HashSet<>(); + } + names.addAll(inFile); + } + } + } - } + return names == null ? Collections.emptySet() : names; + } + + @Override + public boolean processPackageDirectories( + @Nonnull PsiJavaPackage psiPackage, + @Nonnull final GlobalSearchScope scope, + @Nonnull final Processor consumer + ) { + final PsiManager psiManager = PsiManager.getInstance(myProject); + return DirectoryIndex.getInstance(myProject) + .getDirectoriesByPackageName(psiPackage.getQualifiedName(), false) + .forEach(new ReadActionProcessor<>() { + @RequiredReadAction + @Override + public boolean processInReadAction(final VirtualFile dir) { + if (!scope.contains(dir)) { + return true; + } + PsiDirectory psiDir = psiManager.findDirectory(dir); + return psiDir == null || consumer.process(psiDir); + } + }); } - return names == null ? Collections.emptySet() : names; - } - - - @Override - public boolean processPackageDirectories(@Nonnull PsiJavaPackage psiPackage, - @Nonnull final GlobalSearchScope scope, - @Nonnull final Processor consumer) { - final PsiManager psiManager = PsiManager.getInstance(myProject); - return DirectoryIndex.getInstance(myProject) - .getDirectoriesByPackageName(psiPackage.getQualifiedName(), false) - .forEach(new ReadActionProcessor<>() { - @RequiredReadAction - @Override - public boolean processInReadAction(final VirtualFile dir) { - if (!scope.contains(dir)) { - return true; - } - PsiDirectory psiDir = psiManager.findDirectory(dir); - return psiDir == null || consumer.process(psiDir); - } - }); - } } diff --git a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/JavaPsiFacadeImpl.java b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/JavaPsiFacadeImpl.java index 854e427ec..ad1af64b0 100644 --- a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/JavaPsiFacadeImpl.java +++ b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/JavaPsiFacadeImpl.java @@ -47,343 +47,347 @@ @Singleton @ServiceImpl public class JavaPsiFacadeImpl extends JavaPsiFacadeEx { - private final PsiConstantEvaluationHelper myConstantEvaluationHelper; - - private final Project myProject; - private final PsiPackageManager myPackageManager; - private final PsiResolveHelper myPsiResolveHelper; - private final PsiElementFactory myPsiElementFactory; - private final PsiNameHelper myPsiNameHelper; - - private final Map>> myModulesByScopeCache = - ContainerUtil.createConcurrentSoftKeySoftValueMap(); - - private final Map myModuleScopeByFile = ContainerUtil.createConcurrentWeakKeyWeakValueMap(); - - @Inject - public JavaPsiFacadeImpl(Project project, - PsiResolveHelper psiResolveHelper, - PsiPackageManager psiManager, - PsiElementFactory psiElementFactory, - PsiNameHelper psiNameHelper) { - myProject = project; - myPackageManager = psiManager; - myPsiResolveHelper = psiResolveHelper; - myPsiElementFactory = psiElementFactory; - myPsiNameHelper = psiNameHelper; - myConstantEvaluationHelper = new PsiConstantEvaluationHelperImpl(); - - project.getMessageBus().connect().subscribe(PsiModificationTrackerListener.class, () -> { - myModulesByScopeCache.clear(); - myModuleScopeByFile.clear(); - }); - - JavaElementType.ANNOTATION.getIndex(); // Initialize stubs. - } - - @Override - public PsiClass findClass(@Nonnull final String qualifiedName, @Nonnull GlobalSearchScope scope) { - ProgressIndicatorProvider.checkCanceled(); // We hope this method is being called often enough to cancel daemon processes smoothly - - if (DumbService.getInstance(getProject()).isDumb()) { - PsiClass[] classes = findClassesInDumbMode(qualifiedName, scope); - if (classes.length != 0) { - return classes[0]; - } - return null; + private final PsiConstantEvaluationHelper myConstantEvaluationHelper; + + private final Project myProject; + private final PsiPackageManager myPackageManager; + private final PsiResolveHelper myPsiResolveHelper; + private final PsiElementFactory myPsiElementFactory; + private final PsiNameHelper myPsiNameHelper; + + private final Map>> myModulesByScopeCache = + ContainerUtil.createConcurrentSoftKeySoftValueMap(); + + private final Map myModuleScopeByFile = ContainerUtil.createConcurrentWeakKeyWeakValueMap(); + + @Inject + public JavaPsiFacadeImpl( + Project project, + PsiResolveHelper psiResolveHelper, + PsiPackageManager psiManager, + PsiElementFactory psiElementFactory, + PsiNameHelper psiNameHelper + ) { + myProject = project; + myPackageManager = psiManager; + myPsiResolveHelper = psiResolveHelper; + myPsiElementFactory = psiElementFactory; + myPsiNameHelper = psiNameHelper; + myConstantEvaluationHelper = new PsiConstantEvaluationHelperImpl(); + + project.getMessageBus().connect().subscribe(PsiModificationTrackerListener.class, () -> { + myModulesByScopeCache.clear(); + myModuleScopeByFile.clear(); + }); + + JavaElementType.ANNOTATION.getIndex(); // Initialize stubs. } - for (PsiElementFinder finder : finders()) { - PsiClass aClass = finder.findClass(qualifiedName, scope); - if (aClass != null) { - return aClass; - } - } + @Override + public PsiClass findClass(@Nonnull final String qualifiedName, @Nonnull GlobalSearchScope scope) { + ProgressIndicatorProvider.checkCanceled(); // We hope this method is being called often enough to cancel daemon processes smoothly - return null; - } - - @Nonnull - private PsiClass[] findClassesInDumbMode(@Nonnull String qualifiedName, @Nonnull GlobalSearchScope scope) { - final String packageName = StringUtil.getPackageName(qualifiedName); - final PsiJavaPackage pkg = findPackage(packageName); - final String className = StringUtil.getShortName(qualifiedName); - if (pkg == null && packageName.length() < qualifiedName.length()) { - PsiClass[] containingClasses = findClassesInDumbMode(packageName, scope); - if (containingClasses.length == 1) { - return PsiElementFinder.filterByName(className, containingClasses[0].getInnerClasses()); - } - - return PsiClass.EMPTY_ARRAY; - } + if (DumbService.getInstance(getProject()).isDumb()) { + PsiClass[] classes = findClassesInDumbMode(qualifiedName, scope); + if (classes.length != 0) { + return classes[0]; + } + return null; + } + + for (PsiElementFinder finder : finders()) { + PsiClass aClass = finder.findClass(qualifiedName, scope); + if (aClass != null) { + return aClass; + } + } - if (pkg == null || !pkg.containsClassNamed(className)) { - return PsiClass.EMPTY_ARRAY; + return null; } - return pkg.findClassByShortName(className, scope); - } + @Nonnull + private PsiClass[] findClassesInDumbMode(@Nonnull String qualifiedName, @Nonnull GlobalSearchScope scope) { + final String packageName = StringUtil.getPackageName(qualifiedName); + final PsiJavaPackage pkg = findPackage(packageName); + final String className = StringUtil.getShortName(qualifiedName); + if (pkg == null && packageName.length() < qualifiedName.length()) { + PsiClass[] containingClasses = findClassesInDumbMode(packageName, scope); + if (containingClasses.length == 1) { + return PsiElementFinder.filterByName(className, containingClasses[0].getInnerClasses()); + } + + return PsiClass.EMPTY_ARRAY; + } + + if (pkg == null || !pkg.containsClassNamed(className)) { + return PsiClass.EMPTY_ARRAY; + } - @Override - @Nonnull - public PsiClass[] findClasses(@Nonnull String qualifiedName, @Nonnull GlobalSearchScope scope) { - if (DumbService.getInstance(getProject()).isDumb()) { - return findClassesInDumbMode(qualifiedName, scope); + return pkg.findClassByShortName(className, scope); } - List classes = new SmartList<>(); - for (PsiElementFinder finder : finders()) { - PsiClass[] finderClasses = finder.findClasses(qualifiedName, scope); - ContainerUtil.addAll(classes, finderClasses); + @Override + @Nonnull + public PsiClass[] findClasses(@Nonnull String qualifiedName, @Nonnull GlobalSearchScope scope) { + if (DumbService.getInstance(getProject()).isDumb()) { + return findClassesInDumbMode(qualifiedName, scope); + } + + List classes = new SmartList<>(); + for (PsiElementFinder finder : finders()) { + PsiClass[] finderClasses = finder.findClasses(qualifiedName, scope); + ContainerUtil.addAll(classes, finderClasses); + } + + return classes.toArray(new PsiClass[classes.size()]); } - return classes.toArray(new PsiClass[classes.size()]); - } - - @Nonnull - private List finders() { - return myProject.getExtensionList(PsiElementFinder.class); - } - - @Override - @Nonnull - public PsiConstantEvaluationHelper getConstantEvaluationHelper() { - return myConstantEvaluationHelper; - } - - @Override - public PsiJavaPackage findPackage(@Nonnull String qualifiedName) { - for (PsiElementFinder elementFinder : filteredFinders()) { - PsiJavaPackage aPackage = elementFinder.findPackage(qualifiedName); - if (aPackage != null) { - return aPackage; - } + @Nonnull + private List finders() { + return myProject.getExtensionList(PsiElementFinder.class); } - return (PsiJavaPackage)myPackageManager.findPackage(qualifiedName, JavaModuleExtension.class); - } - - @Nullable - @Override - public PsiJavaModule findModule(@Nonnull VirtualFile file) { - PsiJavaModule psiJavaModule = myModuleScopeByFile.get(file); - if (psiJavaModule != null) { - return psiJavaModule; + + @Override + @Nonnull + public PsiConstantEvaluationHelper getConstantEvaluationHelper() { + return myConstantEvaluationHelper; } - for (PsiElementFinder finder : filteredFinders()) { - PsiJavaModule module = finder.findModule(file); - if (module != null) { - myModuleScopeByFile.put(file, module); - return module; - } + @Override + public PsiJavaPackage findPackage(@Nonnull String qualifiedName) { + for (PsiElementFinder elementFinder : filteredFinders()) { + PsiJavaPackage aPackage = elementFinder.findPackage(qualifiedName); + if (aPackage != null) { + return aPackage; + } + } + return (PsiJavaPackage)myPackageManager.findPackage(qualifiedName, JavaModuleExtension.class); } - return null; - } - - @Override - @Nonnull - public PsiJavaPackage[] getSubPackages(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { - LinkedHashSet result = new LinkedHashSet<>(); - for (PsiElementFinder finder : filteredFinders()) { - PsiJavaPackage[] packages = finder.getSubPackages(psiPackage, scope); - ContainerUtil.addAll(result, packages); + + @Nullable + @Override + public PsiJavaModule findModule(@Nonnull VirtualFile file) { + PsiJavaModule psiJavaModule = myModuleScopeByFile.get(file); + if (psiJavaModule != null) { + return psiJavaModule; + } + + for (PsiElementFinder finder : filteredFinders()) { + PsiJavaModule module = finder.findModule(file); + if (module != null) { + myModuleScopeByFile.put(file, module); + return module; + } + } + return null; } - return result.toArray(new PsiJavaPackage[result.size()]); - } + @Override + @Nonnull + public PsiJavaPackage[] getSubPackages(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { + LinkedHashSet result = new LinkedHashSet<>(); + for (PsiElementFinder finder : filteredFinders()) { + PsiJavaPackage[] packages = finder.getSubPackages(psiPackage, scope); + ContainerUtil.addAll(result, packages); + } - @Nonnull - private List filteredFinders() { - DumbService dumbService = DumbService.getInstance(getProject()); - List finders = finders(); - if (dumbService.isDumb()) { - return dumbService.filterByDumbAwareness(finders); + return result.toArray(new PsiJavaPackage[result.size()]); } - return finders; - } - - @Override - @Nonnull - public PsiJavaParserFacade getParserFacade() { - return getElementFactory(); - } - - @Override - @Nonnull - public PsiResolveHelper getResolveHelper() { - return myPsiResolveHelper; - } - - @Override - @Nonnull - public PsiNameHelper getNameHelper() { - return myPsiNameHelper; - } - - @Nonnull - public Set getClassNames(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { - Set result = new HashSet<>(); - for (PsiElementFinder finder : filteredFinders()) { - result.addAll(finder.getClassNames(psiPackage, scope)); + + @Nonnull + private List filteredFinders() { + DumbService dumbService = DumbService.getInstance(getProject()); + List finders = finders(); + if (dumbService.isDumb()) { + return dumbService.filterByDumbAwareness(finders); + } + return finders; } - return result; - } - - @Nonnull - public PsiClass[] getClasses(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { - List result = null; - for (PsiElementFinder finder : filteredFinders()) { - PsiClass[] classes = finder.getClasses(psiPackage, scope); - if (classes.length == 0) { - continue; - } - if (result == null) { - result = new ArrayList<>(); - } - ContainerUtil.addAll(result, classes); + + @Override + @Nonnull + public PsiJavaParserFacade getParserFacade() { + return getElementFactory(); } - return result == null ? PsiClass.EMPTY_ARRAY : result.toArray(new PsiClass[result.size()]); - } + @Override + @Nonnull + public PsiResolveHelper getResolveHelper() { + return myPsiResolveHelper; + } - @Nonnull - public PsiFile[] getPackageFiles(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { - Predicate filter = null; + @Override + @Nonnull + public PsiNameHelper getNameHelper() { + return myPsiNameHelper; + } - for (PsiElementFinder finder : filteredFinders()) { - Predicate finderFilter = finder.getPackageFilesFilter(psiPackage, scope); - if (finderFilter != null) { - if (filter == null) { - filter = finderFilter; + @Nonnull + public Set getClassNames(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { + Set result = new HashSet<>(); + for (PsiElementFinder finder : filteredFinders()) { + result.addAll(finder.getClassNames(psiPackage, scope)); } - else { - final Predicate oldFilter = filter; - filter = psiFile -> oldFilter.test(psiFile) && finderFilter.test(psiFile); - } - } + return result; } - Set result = new LinkedHashSet<>(); - PsiDirectory[] directories = psiPackage.getDirectories(scope); - for (PsiDirectory directory : directories) { - for (PsiFile file : directory.getFiles()) { - if (filter == null || filter.test(file)) { - result.add(file); + @Nonnull + public PsiClass[] getClasses(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { + List result = null; + for (PsiElementFinder finder : filteredFinders()) { + PsiClass[] classes = finder.getClasses(psiPackage, scope); + if (classes.length == 0) { + continue; + } + if (result == null) { + result = new ArrayList<>(); + } + ContainerUtil.addAll(result, classes); } - } - } - for (PsiElementFinder finder : filteredFinders()) { - Collections.addAll(result, finder.getPackageFiles(psiPackage, scope)); + return result == null ? PsiClass.EMPTY_ARRAY : result.toArray(new PsiClass[result.size()]); } - return result.toArray(PsiFile.EMPTY_ARRAY); - } - - public boolean processPackageDirectories(@Nonnull PsiJavaPackage psiPackage, - @Nonnull GlobalSearchScope scope, - @Nonnull Processor consumer) { - for (PsiElementFinder finder : filteredFinders()) { - if (!finder.processPackageDirectories(psiPackage, scope, consumer)) { - return false; - } + + @Nonnull + public PsiFile[] getPackageFiles(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { + Predicate filter = null; + + for (PsiElementFinder finder : filteredFinders()) { + Predicate finderFilter = finder.getPackageFilesFilter(psiPackage, scope); + if (finderFilter != null) { + if (filter == null) { + filter = finderFilter; + } + else { + final Predicate oldFilter = filter; + filter = psiFile -> oldFilter.test(psiFile) && finderFilter.test(psiFile); + } + } + } + + Set result = new LinkedHashSet<>(); + PsiDirectory[] directories = psiPackage.getDirectories(scope); + for (PsiDirectory directory : directories) { + for (PsiFile file : directory.getFiles()) { + if (filter == null || filter.test(file)) { + result.add(file); + } + } + } + + for (PsiElementFinder finder : filteredFinders()) { + Collections.addAll(result, finder.getPackageFiles(psiPackage, scope)); + } + return result.toArray(PsiFile.EMPTY_ARRAY); } - return true; - } - - public PsiClass[] findClassByShortName(String name, PsiJavaPackage psiPackage, GlobalSearchScope scope) { - List result = null; - for (PsiElementFinder finder : filteredFinders()) { - PsiClass[] classes = finder.getClasses(name, psiPackage, scope); - if (classes.length == 0) { - continue; - } - if (result == null) { - result = new ArrayList<>(); - } - ContainerUtil.addAll(result, classes); + + public boolean processPackageDirectories( + @Nonnull PsiJavaPackage psiPackage, + @Nonnull GlobalSearchScope scope, + @Nonnull Processor consumer + ) { + for (PsiElementFinder finder : filteredFinders()) { + if (!finder.processPackageDirectories(psiPackage, scope, consumer)) { + return false; + } + } + return true; } - return result == null ? PsiClass.EMPTY_ARRAY : result.toArray(new PsiClass[result.size()]); - } + public PsiClass[] findClassByShortName(String name, PsiJavaPackage psiPackage, GlobalSearchScope scope) { + List result = null; + for (PsiElementFinder finder : filteredFinders()) { + PsiClass[] classes = finder.getClasses(name, psiPackage, scope); + if (classes.length == 0) { + continue; + } + if (result == null) { + result = new ArrayList<>(); + } + ContainerUtil.addAll(result, classes); + } + + return result == null ? PsiClass.EMPTY_ARRAY : result.toArray(new PsiClass[result.size()]); + } - @Override - public boolean isPartOfPackagePrefix(@Nonnull String packageName) { - final Collection packagePrefixes = JavaFileManager.getInstance(myProject).getNonTrivialPackagePrefixes(); - for (final String subpackageName : packagePrefixes) { - if (isSubpackageOf(subpackageName, packageName)) { - return true; - } + @Override + public boolean isPartOfPackagePrefix(@Nonnull String packageName) { + final Collection packagePrefixes = JavaFileManager.getInstance(myProject).getNonTrivialPackagePrefixes(); + for (final String subpackageName : packagePrefixes) { + if (isSubpackageOf(subpackageName, packageName)) { + return true; + } + } + return false; } - return false; - } - - private static boolean isSubpackageOf(@Nonnull String subpackageName, @Nonnull String packageName) { - return subpackageName.equals(packageName) || subpackageName.startsWith(packageName) && subpackageName.charAt(packageName.length()) == '.'; - } - - @Override - public boolean isInPackage(@Nonnull PsiElement element, @Nonnull PsiJavaPackage aPackage) { - final PsiFile file = FileContextUtil.getContextFile(element); - if (file instanceof JavaDummyHolder) { - return ((JavaDummyHolder)file).isInPackage(aPackage); + + private static boolean isSubpackageOf(@Nonnull String subpackageName, @Nonnull String packageName) { + return subpackageName.equals(packageName) || subpackageName.startsWith(packageName) && subpackageName.charAt(packageName.length()) == '.'; } - if (file instanceof PsiJavaFile) { - final String packageName = ((PsiJavaFile)file).getPackageName(); - return packageName.equals(aPackage.getQualifiedName()); + + @Override + public boolean isInPackage(@Nonnull PsiElement element, @Nonnull PsiJavaPackage aPackage) { + final PsiFile file = FileContextUtil.getContextFile(element); + if (file instanceof JavaDummyHolder) { + return ((JavaDummyHolder)file).isInPackage(aPackage); + } + if (file instanceof PsiJavaFile) { + final String packageName = ((PsiJavaFile)file).getPackageName(); + return packageName.equals(aPackage.getQualifiedName()); + } + return false; } - return false; - } - - @Override - public boolean arePackagesTheSame(@Nonnull PsiElement element1, @Nonnull PsiElement element2) { - PsiFile file1 = FileContextUtil.getContextFile(element1); - PsiFile file2 = FileContextUtil.getContextFile(element2); - if (Comparing.equal(file1, file2)) { - return true; + + @Override + public boolean arePackagesTheSame(@Nonnull PsiElement element1, @Nonnull PsiElement element2) { + PsiFile file1 = FileContextUtil.getContextFile(element1); + PsiFile file2 = FileContextUtil.getContextFile(element2); + if (Comparing.equal(file1, file2)) { + return true; + } + if (file1 instanceof JavaDummyHolder && file2 instanceof JavaDummyHolder) { + return true; + } + if (file1 instanceof JavaDummyHolder || file2 instanceof JavaDummyHolder) { + JavaDummyHolder dummyHolder = (JavaDummyHolder)(file1 instanceof JavaDummyHolder ? file1 : file2); + PsiElement other = file1 instanceof JavaDummyHolder ? file2 : file1; + return dummyHolder.isSamePackage(other); + } + if (!(file1 instanceof PsiClassOwner)) { + return false; + } + if (!(file2 instanceof PsiClassOwner)) { + return false; + } + String package1 = ((PsiClassOwner)file1).getPackageName(); + String package2 = ((PsiClassOwner)file2).getPackageName(); + return Comparing.equal(package1, package2); } - if (file1 instanceof JavaDummyHolder && file2 instanceof JavaDummyHolder) { - return true; + + @Override + @Nonnull + public Project getProject() { + return myProject; } - if (file1 instanceof JavaDummyHolder || file2 instanceof JavaDummyHolder) { - JavaDummyHolder dummyHolder = (JavaDummyHolder)(file1 instanceof JavaDummyHolder ? file1 : file2); - PsiElement other = file1 instanceof JavaDummyHolder ? file2 : file1; - return dummyHolder.isSamePackage(other); + + @Override + @Nonnull + public PsiElementFactory getElementFactory() { + return myPsiElementFactory; } - if (!(file1 instanceof PsiClassOwner)) { - return false; + + @Override + public PsiJavaModule findModule(@Nonnull String moduleName, @Nonnull GlobalSearchScope scope) { + Collection modules = findModules(moduleName, scope); + return modules.size() == 1 ? modules.iterator().next() : null; } - if (!(file2 instanceof PsiClassOwner)) { - return false; + + @Nonnull + @Override + public Collection findModules(@Nonnull String moduleName, @Nonnull GlobalSearchScope scope) { + return myModulesByScopeCache + .computeIfAbsent(scope, k -> ContainerUtil.createConcurrentWeakValueMap()) + .computeIfAbsent(moduleName, k -> JavaFileManager.getInstance(myProject).findModules(k, scope)); } - String package1 = ((PsiClassOwner)file1).getPackageName(); - String package2 = ((PsiClassOwner)file2).getPackageName(); - return Comparing.equal(package1, package2); - } - - @Override - @Nonnull - public Project getProject() { - return myProject; - } - - @Override - @Nonnull - public PsiElementFactory getElementFactory() { - return myPsiElementFactory; - } - - @Override - public PsiJavaModule findModule(@Nonnull String moduleName, @Nonnull GlobalSearchScope scope) { - Collection modules = findModules(moduleName, scope); - return modules.size() == 1 ? modules.iterator().next() : null; - } - - @Nonnull - @Override - public Collection findModules(@Nonnull String moduleName, @Nonnull GlobalSearchScope scope) { - return myModulesByScopeCache - .computeIfAbsent(scope, k -> ContainerUtil.createConcurrentWeakValueMap()) - .computeIfAbsent(moduleName, k -> JavaFileManager.getInstance(myProject).findModules(k, scope)); - } } diff --git a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/PsiImplUtil.java b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/PsiImplUtil.java index a30625a8c..d6983eebc 100644 --- a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/PsiImplUtil.java +++ b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/PsiImplUtil.java @@ -69,826 +69,850 @@ import static com.intellij.java.language.psi.PsiAnnotation.TargetType; public class PsiImplUtil { - private static final Logger LOG = Logger.getInstance(PsiImplUtil.class); - - private PsiImplUtil() { - } - - @Nonnull - public static PsiMethod[] getConstructors(@Nonnull PsiClass aClass) { - List result = null; - for (PsiMethod method : aClass.getMethods()) { - if (method.isConstructor()) { - if (result == null) { - result = new SmartList<>(); - } - result.add(method); - } - } - return result == null ? PsiMethod.EMPTY_ARRAY : result.toArray(new PsiMethod[result.size()]); - } - - @Nullable - public static PsiAnnotationMemberValue findDeclaredAttributeValue(@Nonnull PsiAnnotation annotation, String attributeName) { - return findDeclaredAttributeValueImpl(annotation, attributeName, PsiNameValuePair::getValue); - } - - @Nullable - public static PsiAnnotationMemberValue findDeclaredAttributeDetachedValue(@Nonnull PsiAnnotation annotation, String attributeName) { - return findDeclaredAttributeValueImpl(annotation, attributeName, PsiNameValuePair::getDetachedValue); - } - - @Nullable - private static PsiAnnotationMemberValue findDeclaredAttributeValueImpl(@Nonnull PsiAnnotation annotation, - String attributeName, - @Nonnull Function valueGetter) { - if ("value".equals(attributeName)) { - attributeName = null; - } - - PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes(); - for (PsiNameValuePair attribute : attributes) { - final String name = attribute.getName(); - if (Objects.equals(name, attributeName) || attributeName == null && PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(name)) { - return valueGetter.apply(attribute); - } - } - return null; - } - - @Nullable - public static PsiAnnotationMemberValue findAttributeValue(@Nonnull PsiAnnotation annotation, @Nullable @NonNls String attributeName) { - final PsiAnnotationMemberValue value = findDeclaredAttributeValue(annotation, attributeName); - if (value != null) { - return value; - } - - if (attributeName == null) { - attributeName = "value"; - } - final PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement(); - if (referenceElement != null) { - PsiElement resolved = referenceElement.resolve(); - if (resolved != null) { - PsiMethod[] methods = ((PsiClass)resolved).findMethodsByName(attributeName, false); - for (PsiMethod method : methods) { - if (PsiUtil.isAnnotationMethod(method)) { - return ((PsiAnnotationMethod)method).getDefaultValue(); - } - } - } - } - return null; - } - - @Nonnull - public static PsiTypeParameter[] getTypeParameters(@Nonnull PsiTypeParameterListOwner owner) { - final PsiTypeParameterList typeParameterList = owner.getTypeParameterList(); - if (typeParameterList != null) { - return typeParameterList.getTypeParameters(); - } - return PsiTypeParameter.EMPTY_ARRAY; - } - - @Nonnull - public static PsiJavaCodeReferenceElement[] namesToPackageReferences(@Nonnull PsiManager manager, @Nonnull String[] names) { - PsiJavaCodeReferenceElement[] refs = new PsiJavaCodeReferenceElement[names.length]; - for (int i = 0; i < names.length; i++) { - String name = names[i]; - try { - refs[i] = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createPackageReferenceElement(name); - } - catch (IncorrectOperationException e) { - LOG.error(e); - } - } - return refs; - } - - public static int getParameterIndex(@Nonnull PsiParameter parameter, @Nonnull PsiParameterList parameterList) { - PsiElement parameterParent = parameter.getParent(); - assert parameterParent == parameterList : parameterList + "; " + parameterParent; - PsiParameter[] parameters = parameterList.getParameters(); - for (int i = 0; i < parameters.length; i++) { - PsiParameter paramInList = parameters[i]; - if (parameter.equals(paramInList)) { - return i; - } - } - String name = parameter.getName(); - PsiParameter suspect = null; - int i; - for (i = parameters.length - 1; i >= 0; i--) { - PsiParameter paramInList = parameters[i]; - if (Comparing.equal(name, paramInList.getName())) { - suspect = paramInList; - break; - } - } - String message = - parameter + ":" + parameter.getClass() + " not found among parameters: " + Arrays.asList(parameters) + "." + " parameterList' parent: " + parameterList.getParent() + ";" + - "" + " parameter.isValid()=" + parameter.isValid() + ";" + " parameterList.isValid()= " + parameterList.isValid() + ";" + " parameterList stub: " + (parameterList instanceof - StubBasedPsiElement ? ((StubBasedPsiElement)parameterList).getStub() : "---") + "; " + " parameter stub: " + (parameter instanceof StubBasedPsiElement ? ((StubBasedPsiElement) - parameter).getStub() : "---") + ";" + " suspect: " + suspect + " (index=" + i + "); " + (suspect == null ? null : suspect.getClass()) + " suspect stub: " + (suspect instanceof - StubBasedPsiElement ? ((StubBasedPsiElement)suspect).getStub() : suspect == null ? "-null-" : "---" + suspect.getClass()) + ";" + " parameter.equals(suspect) = " + parameter.equals - (suspect) + "; " + " parameter.getNode() == suspect.getNode(): " + (parameter.getNode() == (suspect == null ? null : suspect.getNode())) + "; " + "."; - LOG.error(message); - return i; - } - - public static int getTypeParameterIndex(@Nonnull PsiTypeParameter typeParameter, @Nonnull PsiTypeParameterList typeParameterList) { - PsiTypeParameter[] typeParameters = typeParameterList.getTypeParameters(); - for (int i = 0; i < typeParameters.length; i++) { - if (typeParameter.equals(typeParameters[i])) { + private static final Logger LOG = Logger.getInstance(PsiImplUtil.class); + + private PsiImplUtil() { + } + + @Nonnull + public static PsiMethod[] getConstructors(@Nonnull PsiClass aClass) { + List result = null; + for (PsiMethod method : aClass.getMethods()) { + if (method.isConstructor()) { + if (result == null) { + result = new SmartList<>(); + } + result.add(method); + } + } + return result == null ? PsiMethod.EMPTY_ARRAY : result.toArray(new PsiMethod[result.size()]); + } + + @Nullable + public static PsiAnnotationMemberValue findDeclaredAttributeValue(@Nonnull PsiAnnotation annotation, String attributeName) { + return findDeclaredAttributeValueImpl(annotation, attributeName, PsiNameValuePair::getValue); + } + + @Nullable + public static PsiAnnotationMemberValue findDeclaredAttributeDetachedValue(@Nonnull PsiAnnotation annotation, String attributeName) { + return findDeclaredAttributeValueImpl(annotation, attributeName, PsiNameValuePair::getDetachedValue); + } + + @Nullable + private static PsiAnnotationMemberValue findDeclaredAttributeValueImpl( + @Nonnull PsiAnnotation annotation, + String attributeName, + @Nonnull Function valueGetter + ) { + if ("value".equals(attributeName)) { + attributeName = null; + } + + PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes(); + for (PsiNameValuePair attribute : attributes) { + final String name = attribute.getName(); + if (Objects.equals(name, attributeName) || attributeName == null && PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(name)) { + return valueGetter.apply(attribute); + } + } + return null; + } + + @Nullable + public static PsiAnnotationMemberValue findAttributeValue(@Nonnull PsiAnnotation annotation, @Nullable @NonNls String attributeName) { + final PsiAnnotationMemberValue value = findDeclaredAttributeValue(annotation, attributeName); + if (value != null) { + return value; + } + + if (attributeName == null) { + attributeName = "value"; + } + final PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement(); + if (referenceElement != null) { + PsiElement resolved = referenceElement.resolve(); + if (resolved != null) { + PsiMethod[] methods = ((PsiClass)resolved).findMethodsByName(attributeName, false); + for (PsiMethod method : methods) { + if (PsiUtil.isAnnotationMethod(method)) { + return ((PsiAnnotationMethod)method).getDefaultValue(); + } + } + } + } + return null; + } + + @Nonnull + public static PsiTypeParameter[] getTypeParameters(@Nonnull PsiTypeParameterListOwner owner) { + final PsiTypeParameterList typeParameterList = owner.getTypeParameterList(); + if (typeParameterList != null) { + return typeParameterList.getTypeParameters(); + } + return PsiTypeParameter.EMPTY_ARRAY; + } + + @Nonnull + public static PsiJavaCodeReferenceElement[] namesToPackageReferences(@Nonnull PsiManager manager, @Nonnull String[] names) { + PsiJavaCodeReferenceElement[] refs = new PsiJavaCodeReferenceElement[names.length]; + for (int i = 0; i < names.length; i++) { + String name = names[i]; + try { + refs[i] = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createPackageReferenceElement(name); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + return refs; + } + + public static int getParameterIndex(@Nonnull PsiParameter parameter, @Nonnull PsiParameterList parameterList) { + PsiElement parameterParent = parameter.getParent(); + assert parameterParent == parameterList : parameterList + "; " + parameterParent; + PsiParameter[] parameters = parameterList.getParameters(); + for (int i = 0; i < parameters.length; i++) { + PsiParameter paramInList = parameters[i]; + if (parameter.equals(paramInList)) { + return i; + } + } + String name = parameter.getName(); + PsiParameter suspect = null; + int i; + for (i = parameters.length - 1; i >= 0; i--) { + PsiParameter paramInList = parameters[i]; + if (Comparing.equal(name, paramInList.getName())) { + suspect = paramInList; + break; + } + } + String message = + parameter + ":" + parameter.getClass() + " not found among parameters: " + Arrays.asList(parameters) + "." + " parameterList' parent: " + parameterList.getParent() + ";" + + "" + " parameter.isValid()=" + parameter.isValid() + ";" + " parameterList.isValid()= " + parameterList.isValid() + ";" + " parameterList stub: " + (parameterList instanceof + StubBasedPsiElement ? ((StubBasedPsiElement)parameterList).getStub() : "---") + "; " + " parameter stub: " + (parameter instanceof StubBasedPsiElement ? ((StubBasedPsiElement) + parameter).getStub() : "---") + ";" + " suspect: " + suspect + " (index=" + i + "); " + (suspect == null ? null : suspect.getClass()) + " suspect stub: " + (suspect instanceof + StubBasedPsiElement ? ((StubBasedPsiElement)suspect).getStub() : suspect == null ? "-null-" : "---" + suspect.getClass()) + ";" + " parameter.equals(suspect) = " + parameter.equals + (suspect) + "; " + " parameter.getNode() == suspect.getNode(): " + (parameter.getNode() == (suspect == null ? null : suspect.getNode())) + "; " + "."; + LOG.error(message); return i; - } - } - LOG.assertTrue(false); - return -1; - } - - @Nonnull - public static Object[] getReferenceVariantsByFilter(@Nonnull PsiJavaCodeReferenceElement reference, @Nonnull ElementFilter filter) { - FilterScopeProcessor processor = new FilterScopeProcessor(filter); - PsiScopesUtil.resolveAndWalk(processor, reference, null, true); - return processor.getResults().toArray(); - } - - public static boolean processDeclarationsInMethod(@Nonnull final PsiMethod method, - @Nonnull final PsiScopeProcessor processor, - @Nonnull final ResolveState state, - final PsiElement lastParent, - @Nonnull final PsiElement place) { - final boolean fromBody = lastParent instanceof PsiCodeBlock; - final PsiTypeParameterList typeParameterList = method.getTypeParameterList(); - return processDeclarationsInMethodLike(method, processor, state, place, fromBody, typeParameterList); - } - - public static boolean processDeclarationsInLambda(@Nonnull final PsiLambdaExpression lambda, - @Nonnull final PsiScopeProcessor processor, - @Nonnull final ResolveState state, - final PsiElement lastParent, - @Nonnull final PsiElement place) { - final boolean fromBody = lastParent != null && lastParent == lambda.getBody(); - return processDeclarationsInMethodLike(lambda, processor, state, place, fromBody, null); - } - - private static boolean processDeclarationsInMethodLike(@Nonnull final PsiParameterListOwner element, - @Nonnull final PsiScopeProcessor processor, - @Nonnull final ResolveState state, - @Nonnull final PsiElement place, - final boolean fromBody, - @Nullable final PsiTypeParameterList typeParameterList) { - processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, element); - - if (typeParameterList != null) { - final ElementClassHint hint = processor.getHint(ElementClassHint.KEY); - if (hint == null || hint.shouldProcess(ElementClassHint.DeclarationKind.CLASS)) { - if (!typeParameterList.processDeclarations(processor, state, null, place)) { - return false; - } - } - } - - if (fromBody) { - final PsiParameter[] parameters = element.getParameterList().getParameters(); - for (PsiParameter parameter : parameters) { - if (!processor.execute(parameter, state)) { - return false; - } - } - } - - return true; - } - - public static boolean processDeclarationsInResourceList(@Nonnull final PsiResourceList resourceList, - @Nonnull final PsiScopeProcessor processor, - @Nonnull final ResolveState state, - final PsiElement lastParent) { - final ElementClassHint hint = processor.getHint(ElementClassHint.KEY); - if (hint != null && !hint.shouldProcess(ElementClassHint.DeclarationKind.VARIABLE)) { - return true; - } - - for (PsiResourceListElement resource : resourceList) { - if (resource == lastParent) { - break; - } - if (resource instanceof PsiResourceVariable && !processor.execute(resource, state)) { - return false; - } - } - - return true; - } - - public static boolean hasTypeParameters(@Nonnull PsiTypeParameterListOwner owner) { - final PsiTypeParameterList typeParameterList = owner.getTypeParameterList(); - return typeParameterList != null && typeParameterList.getTypeParameters().length != 0; - } - - @Nonnull - public static PsiType[] typesByReferenceParameterList(@Nonnull PsiReferenceParameterList parameterList) { - PsiTypeElement[] typeElements = parameterList.getTypeParameterElements(); - - return typesByTypeElements(typeElements); - } - - @Nonnull - public static PsiType[] typesByTypeElements(@Nonnull PsiTypeElement[] typeElements) { - PsiType[] types = PsiType.createArray(typeElements.length); - for (int i = 0; i < types.length; i++) { - types[i] = typeElements[i].getType(); - } - if (types.length == 1 && types[0] instanceof PsiDiamondType) { - return ((PsiDiamondType)types[0]).resolveInferredTypes().getTypes(); - } - return types; - } - - @Nonnull - public static PsiType getType(@Nonnull PsiClassObjectAccessExpression classAccessExpression) { - GlobalSearchScope resolveScope = classAccessExpression.getResolveScope(); - PsiManager manager = classAccessExpression.getManager(); - final PsiClass classClass = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.lang.Class", resolveScope); - if (classClass == null) { - return new PsiClassReferenceType(new LightClassReference(manager, "Class", "java.lang.Class", resolveScope), null); - } - if (!PsiUtil.isLanguageLevel5OrHigher(classAccessExpression)) { - //Raw java.lang.Class - return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createType(classClass); - } - - PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; - PsiType operandType = classAccessExpression.getOperand().getType(); - if (operandType instanceof PsiPrimitiveType && !PsiType.NULL.equals(operandType)) { - if (PsiType.VOID.equals(operandType)) { - operandType = JavaPsiFacade.getInstance(manager.getProject()) - .getElementFactory() - .createTypeByFQClassName("java.lang.Void", classAccessExpression.getResolveScope()); - } - else { - operandType = ((PsiPrimitiveType)operandType).getBoxedType(classAccessExpression); - } } - final PsiTypeParameter[] typeParameters = classClass.getTypeParameters(); - if (typeParameters.length == 1) { - substitutor = substitutor.put(typeParameters[0], operandType); + + public static int getTypeParameterIndex(@Nonnull PsiTypeParameter typeParameter, @Nonnull PsiTypeParameterList typeParameterList) { + PsiTypeParameter[] typeParameters = typeParameterList.getTypeParameters(); + for (int i = 0; i < typeParameters.length; i++) { + if (typeParameter.equals(typeParameters[i])) { + return i; + } + } + LOG.assertTrue(false); + return -1; + } + + @Nonnull + public static Object[] getReferenceVariantsByFilter(@Nonnull PsiJavaCodeReferenceElement reference, @Nonnull ElementFilter filter) { + FilterScopeProcessor processor = new FilterScopeProcessor(filter); + PsiScopesUtil.resolveAndWalk(processor, reference, null, true); + return processor.getResults().toArray(); + } + + public static boolean processDeclarationsInMethod( + @Nonnull final PsiMethod method, + @Nonnull final PsiScopeProcessor processor, + @Nonnull final ResolveState state, + final PsiElement lastParent, + @Nonnull final PsiElement place + ) { + final boolean fromBody = lastParent instanceof PsiCodeBlock; + final PsiTypeParameterList typeParameterList = method.getTypeParameterList(); + return processDeclarationsInMethodLike(method, processor, state, place, fromBody, typeParameterList); + } + + public static boolean processDeclarationsInLambda( + @Nonnull final PsiLambdaExpression lambda, + @Nonnull final PsiScopeProcessor processor, + @Nonnull final ResolveState state, + final PsiElement lastParent, + @Nonnull final PsiElement place + ) { + final boolean fromBody = lastParent != null && lastParent == lambda.getBody(); + return processDeclarationsInMethodLike(lambda, processor, state, place, fromBody, null); + } + + private static boolean processDeclarationsInMethodLike( + @Nonnull final PsiParameterListOwner element, + @Nonnull final PsiScopeProcessor processor, + @Nonnull final ResolveState state, + @Nonnull final PsiElement place, + final boolean fromBody, + @Nullable final PsiTypeParameterList typeParameterList + ) { + processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, element); + + if (typeParameterList != null) { + final ElementClassHint hint = processor.getHint(ElementClassHint.KEY); + if (hint == null || hint.shouldProcess(ElementClassHint.DeclarationKind.CLASS)) { + if (!typeParameterList.processDeclarations(processor, state, null, place)) { + return false; + } + } + } + + if (fromBody) { + final PsiParameter[] parameters = element.getParameterList().getParameters(); + for (PsiParameter parameter : parameters) { + if (!processor.execute(parameter, state)) { + return false; + } + } + } + + return true; } - return new PsiImmediateClassType(classClass, substitutor); - } + public static boolean processDeclarationsInResourceList( + @Nonnull final PsiResourceList resourceList, + @Nonnull final PsiScopeProcessor processor, + @Nonnull final ResolveState state, + final PsiElement lastParent + ) { + final ElementClassHint hint = processor.getHint(ElementClassHint.KEY); + if (hint != null && !hint.shouldProcess(ElementClassHint.DeclarationKind.VARIABLE)) { + return true; + } + + for (PsiResourceListElement resource : resourceList) { + if (resource == lastParent) { + break; + } + if (resource instanceof PsiResourceVariable && !processor.execute(resource, state)) { + return false; + } + } + + return true; + } - @Nullable - public static PsiAnnotation findAnnotation(@Nullable PsiAnnotationOwner annotationOwner, @Nonnull String qualifiedName) { - if (annotationOwner == null) { - return null; + public static boolean hasTypeParameters(@Nonnull PsiTypeParameterListOwner owner) { + final PsiTypeParameterList typeParameterList = owner.getTypeParameterList(); + return typeParameterList != null && typeParameterList.getTypeParameters().length != 0; } - PsiAnnotation[] annotations = annotationOwner.getAnnotations(); - if (annotations.length == 0) { - return null; + @Nonnull + public static PsiType[] typesByReferenceParameterList(@Nonnull PsiReferenceParameterList parameterList) { + PsiTypeElement[] typeElements = parameterList.getTypeParameterElements(); + + return typesByTypeElements(typeElements); } - String shortName = StringUtil.getShortName(qualifiedName); - for (PsiAnnotation annotation : annotations) { - PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement(); - if (referenceElement != null && shortName.equals(referenceElement.getReferenceName())) { - if (qualifiedName.equals(annotation.getQualifiedName())) { - return annotation; + @Nonnull + public static PsiType[] typesByTypeElements(@Nonnull PsiTypeElement[] typeElements) { + PsiType[] types = PsiType.createArray(typeElements.length); + for (int i = 0; i < types.length; i++) { + types[i] = typeElements[i].getType(); } - } + if (types.length == 1 && types[0] instanceof PsiDiamondType) { + return ((PsiDiamondType)types[0]).resolveInferredTypes().getTypes(); + } + return types; } - return null; - } + @Nonnull + public static PsiType getType(@Nonnull PsiClassObjectAccessExpression classAccessExpression) { + GlobalSearchScope resolveScope = classAccessExpression.getResolveScope(); + PsiManager manager = classAccessExpression.getManager(); + final PsiClass classClass = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.lang.Class", resolveScope); + if (classClass == null) { + return new PsiClassReferenceType(new LightClassReference(manager, "Class", "java.lang.Class", resolveScope), null); + } + if (!PsiUtil.isLanguageLevel5OrHigher(classAccessExpression)) { + //Raw java.lang.Class + return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createType(classClass); + } + + PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; + PsiType operandType = classAccessExpression.getOperand().getType(); + if (operandType instanceof PsiPrimitiveType && !PsiType.NULL.equals(operandType)) { + if (PsiType.VOID.equals(operandType)) { + operandType = JavaPsiFacade.getInstance(manager.getProject()) + .getElementFactory() + .createTypeByFQClassName("java.lang.Void", classAccessExpression.getResolveScope()); + } + else { + operandType = ((PsiPrimitiveType)operandType).getBoxedType(classAccessExpression); + } + } + final PsiTypeParameter[] typeParameters = classClass.getTypeParameters(); + if (typeParameters.length == 1) { + substitutor = substitutor.put(typeParameters[0], operandType); + } - /** - * @deprecated use {@link AnnotationTargetUtil#findAnnotationTarget(PsiAnnotation, TargetType...)} (to be removed ion IDEA 17) - */ - @SuppressWarnings("unused") - public static TargetType findApplicableTarget(@Nonnull PsiAnnotation annotation, @Nonnull TargetType... types) { - return AnnotationTargetUtil.findAnnotationTarget(annotation, types); - } + return new PsiImmediateClassType(classClass, substitutor); + } - /** - * @deprecated use {@link AnnotationTargetUtil#findAnnotationTarget(PsiClass, TargetType...)} (to be removed ion IDEA 17) - */ - @SuppressWarnings("unused") - public static TargetType findApplicableTarget(@Nonnull PsiClass annotationType, @Nonnull TargetType... types) { - return AnnotationTargetUtil.findAnnotationTarget(annotationType, types); - } + @Nullable + public static PsiAnnotation findAnnotation(@Nullable PsiAnnotationOwner annotationOwner, @Nonnull String qualifiedName) { + if (annotationOwner == null) { + return null; + } - /** - * @deprecated use {@link AnnotationTargetUtil#getAnnotationTargets(PsiClass)} (to be removed ion IDEA 17) - */ - @SuppressWarnings("unused") - public static Set getAnnotationTargets(@Nonnull PsiClass annotationType) { - return AnnotationTargetUtil.getAnnotationTargets(annotationType); - } + PsiAnnotation[] annotations = annotationOwner.getAnnotations(); + if (annotations.length == 0) { + return null; + } - /** - * @deprecated use {@link AnnotationTargetUtil#getTargetsForLocation(PsiAnnotationOwner)} (to be removed ion IDEA 17) - */ - @SuppressWarnings("unused") - public static TargetType[] getTargetsForLocation(@Nullable PsiAnnotationOwner owner) { - return AnnotationTargetUtil.getTargetsForLocation(owner); - } + String shortName = StringUtil.getShortName(qualifiedName); + for (PsiAnnotation annotation : annotations) { + PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement(); + if (referenceElement != null && shortName.equals(referenceElement.getReferenceName())) { + if (qualifiedName.equals(annotation.getQualifiedName())) { + return annotation; + } + } + } - @Nullable - public static ASTNode findDocComment(@Nonnull CompositeElement element) { - TreeElement node = element.getFirstChildNode(); - while (node != null && (isWhitespaceOrComment(node) && !(node.getPsi() instanceof PsiDocComment))) { - node = node.getTreeNext(); + return null; } - if (node != null && node.getElementType() == JavaDocElementType.DOC_COMMENT) { - return node; + /** + * @deprecated use {@link AnnotationTargetUtil#findAnnotationTarget(PsiAnnotation, TargetType...)} (to be removed ion IDEA 17) + */ + @SuppressWarnings("unused") + public static TargetType findApplicableTarget(@Nonnull PsiAnnotation annotation, @Nonnull TargetType... types) { + return AnnotationTargetUtil.findAnnotationTarget(annotation, types); } - else { - return null; + + /** + * @deprecated use {@link AnnotationTargetUtil#findAnnotationTarget(PsiClass, TargetType...)} (to be removed ion IDEA 17) + */ + @SuppressWarnings("unused") + public static TargetType findApplicableTarget(@Nonnull PsiClass annotationType, @Nonnull TargetType... types) { + return AnnotationTargetUtil.findAnnotationTarget(annotationType, types); } - } - public static PsiType normalizeWildcardTypeByPosition(@Nonnull PsiType type, @Nonnull PsiExpression expression) { - PsiUtilCore.ensureValid(expression); - PsiUtil.ensureValidType(type); + /** + * @deprecated use {@link AnnotationTargetUtil#getAnnotationTargets(PsiClass)} (to be removed ion IDEA 17) + */ + @SuppressWarnings("unused") + public static Set getAnnotationTargets(@Nonnull PsiClass annotationType) { + return AnnotationTargetUtil.getAnnotationTargets(annotationType); + } - PsiExpression topLevel = expression; - while (topLevel.getParent() instanceof PsiArrayAccessExpression && ((PsiArrayAccessExpression)topLevel.getParent()).getArrayExpression() == topLevel) { - topLevel = (PsiExpression)topLevel.getParent(); + /** + * @deprecated use {@link AnnotationTargetUtil#getTargetsForLocation(PsiAnnotationOwner)} (to be removed ion IDEA 17) + */ + @SuppressWarnings("unused") + public static TargetType[] getTargetsForLocation(@Nullable PsiAnnotationOwner owner) { + return AnnotationTargetUtil.getTargetsForLocation(owner); } - if (topLevel instanceof PsiArrayAccessExpression && !PsiUtil.isAccessedForWriting(topLevel)) { - return PsiUtil.captureToplevelWildcards(type, expression); + @Nullable + public static ASTNode findDocComment(@Nonnull CompositeElement element) { + TreeElement node = element.getFirstChildNode(); + while (node != null && (isWhitespaceOrComment(node) && !(node.getPsi() instanceof PsiDocComment))) { + node = node.getTreeNext(); + } + + if (node != null && node.getElementType() == JavaDocElementType.DOC_COMMENT) { + return node; + } + else { + return null; + } } - final PsiType normalized = doNormalizeWildcardByPosition(type, expression, topLevel); - LOG.assertTrue(normalized.isValid(), type); - if (normalized instanceof PsiClassType && !PsiUtil.isAccessedForWriting(topLevel)) { - return PsiUtil.captureToplevelWildcards(normalized, expression); + public static PsiType normalizeWildcardTypeByPosition(@Nonnull PsiType type, @Nonnull PsiExpression expression) { + PsiUtilCore.ensureValid(expression); + PsiUtil.ensureValidType(type); + + PsiExpression topLevel = expression; + while (topLevel.getParent() instanceof PsiArrayAccessExpression && ((PsiArrayAccessExpression)topLevel.getParent()).getArrayExpression() == topLevel) { + topLevel = (PsiExpression)topLevel.getParent(); + } + + if (topLevel instanceof PsiArrayAccessExpression && !PsiUtil.isAccessedForWriting(topLevel)) { + return PsiUtil.captureToplevelWildcards(type, expression); + } + + final PsiType normalized = doNormalizeWildcardByPosition(type, expression, topLevel); + LOG.assertTrue(normalized.isValid(), type); + if (normalized instanceof PsiClassType && !PsiUtil.isAccessedForWriting(topLevel)) { + return PsiUtil.captureToplevelWildcards(normalized, expression); + } + + return normalized; } - return normalized; - } + private static PsiType doNormalizeWildcardByPosition(PsiType type, @Nonnull PsiExpression expression, PsiExpression topLevel) { + if (type instanceof PsiCapturedWildcardType) { + final PsiWildcardType wildcardType = ((PsiCapturedWildcardType)type).getWildcard(); + if (expression instanceof PsiReferenceExpression && LambdaUtil.isLambdaReturnExpression(expression)) { + return type; + } + + if (PsiUtil.isAccessedForWriting(topLevel)) { + return wildcardType.isSuper() ? wildcardType.getBound() : PsiCapturedWildcardType.create(wildcardType, expression); + } + else { + final PsiType upperBound = ((PsiCapturedWildcardType)type).getUpperBound(); + return upperBound instanceof PsiWildcardType ? doNormalizeWildcardByPosition(upperBound, expression, topLevel) : upperBound; + } + } + + + if (type instanceof PsiWildcardType) { + final PsiWildcardType wildcardType = (PsiWildcardType)type; + + if (PsiUtil.isAccessedForWriting(topLevel)) { + return wildcardType.isSuper() ? wildcardType.getBound() : PsiCapturedWildcardType.create(wildcardType, expression); + } + else { + if (wildcardType.isExtends()) { + return wildcardType.getBound(); + } + else { + return PsiType.getJavaLangObject(expression.getManager(), expression.getResolveScope()); + } + } + } + else if (type instanceof PsiArrayType) { + final PsiType componentType = ((PsiArrayType)type).getComponentType(); + final PsiType normalizedComponentType = doNormalizeWildcardByPosition(componentType, expression, topLevel); + if (normalizedComponentType != componentType) { + return normalizedComponentType.createArrayType(); + } + } - private static PsiType doNormalizeWildcardByPosition(PsiType type, @Nonnull PsiExpression expression, PsiExpression topLevel) { - if (type instanceof PsiCapturedWildcardType) { - final PsiWildcardType wildcardType = ((PsiCapturedWildcardType)type).getWildcard(); - if (expression instanceof PsiReferenceExpression && LambdaUtil.isLambdaReturnExpression(expression)) { return type; - } + } + + @Nonnull + public static SearchScope getMemberUseScope(@Nonnull PsiMember member) { + PsiFile file = member.getContainingFile(); + PsiElement topElement = file == null ? member : file; + Project project = topElement.getProject(); + final GlobalSearchScope maximalUseScope = ResolveScopeManager.getInstance(project).getUseScope(topElement); + if (isInServerPage(file)) { + return maximalUseScope; + } + + PsiClass aClass = member.getContainingClass(); + if (aClass instanceof PsiAnonymousClass) { + //member from anonymous class can be called from outside the class + PsiElement methodCallExpr = PsiUtil.isLanguageLevel8OrHigher(aClass) + ? PsiTreeUtil.getTopmostParentOfType(aClass, PsiStatement.class) + : PsiTreeUtil.getParentOfType(aClass, PsiMethodCallExpression.class); + return new LocalSearchScope(methodCallExpr != null ? methodCallExpr : aClass); + } + + PsiModifierList modifierList = member.getModifierList(); + int accessLevel = modifierList == null ? PsiUtil.ACCESS_LEVEL_PUBLIC : PsiUtil.getAccessLevel(modifierList); + if (accessLevel == PsiUtil.ACCESS_LEVEL_PUBLIC || accessLevel == PsiUtil.ACCESS_LEVEL_PROTECTED) { + return maximalUseScope; // class use scope doesn't matter, since another very visible class can inherit from aClass + } + if (accessLevel == PsiUtil.ACCESS_LEVEL_PRIVATE) { + PsiClass topClass = PsiUtil.getTopLevelClass(member); + return topClass != null ? new LocalSearchScope(topClass) : file == null ? maximalUseScope : new LocalSearchScope(file); + } + if (file instanceof PsiJavaFile) { + PsiJavaPackage aPackage = JavaPsiFacade.getInstance(project).findPackage(((PsiJavaFile)file).getPackageName()); + if (aPackage != null) { + SearchScope scope = PackageScope.packageScope(aPackage, false); + return scope.intersectWith(maximalUseScope); + } + } + return maximalUseScope; + } + + public static boolean isInServerPage(@Nullable final PsiElement element) { + return getServerPageFile(element) != null; + } + + @Nullable + public static ServerPageFile getServerPageFile(final PsiElement element) { + final PsiFile psiFile = PsiUtilCore.getTemplateLanguageFile(element); + return psiFile instanceof ServerPageFile ? (ServerPageFile)psiFile : null; + } - if (PsiUtil.isAccessedForWriting(topLevel)) { - return wildcardType.isSuper() ? wildcardType.getBound() : PsiCapturedWildcardType.create(wildcardType, expression); - } - else { - final PsiType upperBound = ((PsiCapturedWildcardType)type).getUpperBound(); - return upperBound instanceof PsiWildcardType ? doNormalizeWildcardByPosition(upperBound, expression, topLevel) : upperBound; - } + public static PsiElement setName(@Nonnull PsiElement element, @Nonnull String name) throws IncorrectOperationException { + PsiManager manager = element.getManager(); + PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); + PsiIdentifier newNameIdentifier = factory.createIdentifier(name); + return element.replace(newNameIdentifier); } + public static boolean isDeprecatedByAnnotation(@Nonnull PsiModifierListOwner owner) { + PsiModifierList modifierList = owner.getModifierList(); + return modifierList != null && modifierList.findAnnotation("java.lang.Deprecated") != null; + } - if (type instanceof PsiWildcardType) { - final PsiWildcardType wildcardType = (PsiWildcardType)type; + public static boolean isDeprecatedByDocTag(@Nonnull PsiJavaDocumentedElement owner) { + PsiDocComment docComment = owner.getDocComment(); + return docComment != null && docComment.findTagByName("deprecated") != null; + } - if (PsiUtil.isAccessedForWriting(topLevel)) { - return wildcardType.isSuper() ? wildcardType.getBound() : PsiCapturedWildcardType.create(wildcardType, expression); - } - else { - if (wildcardType.isExtends()) { - return wildcardType.getBound(); + @Nullable + public static PsiJavaDocumentedElement findDocCommentOwner(@Nonnull PsiDocComment comment) { + PsiElement parent = comment.getParent(); + if (parent instanceof PsiJavaDocumentedElement) { + PsiJavaDocumentedElement owner = (PsiJavaDocumentedElement)parent; + if (owner.getDocComment() == comment) { + return owner; + } } - else { - return PsiType.getJavaLangObject(expression.getManager(), expression.getResolveScope()); - } - } - } - else if (type instanceof PsiArrayType) { - final PsiType componentType = ((PsiArrayType)type).getComponentType(); - final PsiType normalizedComponentType = doNormalizeWildcardByPosition(componentType, expression, topLevel); - if (normalizedComponentType != componentType) { - return normalizedComponentType.createArrayType(); - } - } - - return type; - } - - @Nonnull - public static SearchScope getMemberUseScope(@Nonnull PsiMember member) { - PsiFile file = member.getContainingFile(); - PsiElement topElement = file == null ? member : file; - Project project = topElement.getProject(); - final GlobalSearchScope maximalUseScope = ResolveScopeManager.getInstance(project).getUseScope(topElement); - if (isInServerPage(file)) { - return maximalUseScope; - } - - PsiClass aClass = member.getContainingClass(); - if (aClass instanceof PsiAnonymousClass) { - //member from anonymous class can be called from outside the class - PsiElement methodCallExpr = PsiUtil.isLanguageLevel8OrHigher(aClass) ? PsiTreeUtil.getTopmostParentOfType(aClass, - PsiStatement.class) : PsiTreeUtil.getParentOfType( - aClass, - PsiMethodCallExpression.class); - return new LocalSearchScope(methodCallExpr != null ? methodCallExpr : aClass); - } - - PsiModifierList modifierList = member.getModifierList(); - int accessLevel = modifierList == null ? PsiUtil.ACCESS_LEVEL_PUBLIC : PsiUtil.getAccessLevel(modifierList); - if (accessLevel == PsiUtil.ACCESS_LEVEL_PUBLIC || accessLevel == PsiUtil.ACCESS_LEVEL_PROTECTED) { - return maximalUseScope; // class use scope doesn't matter, since another very visible class can inherit from aClass - } - if (accessLevel == PsiUtil.ACCESS_LEVEL_PRIVATE) { - PsiClass topClass = PsiUtil.getTopLevelClass(member); - return topClass != null ? new LocalSearchScope(topClass) : file == null ? maximalUseScope : new LocalSearchScope(file); - } - if (file instanceof PsiJavaFile) { - PsiJavaPackage aPackage = JavaPsiFacade.getInstance(project).findPackage(((PsiJavaFile)file).getPackageName()); - if (aPackage != null) { - SearchScope scope = PackageScope.packageScope(aPackage, false); - return scope.intersectWith(maximalUseScope); - } - } - return maximalUseScope; - } - - public static boolean isInServerPage(@Nullable final PsiElement element) { - return getServerPageFile(element) != null; - } - - @Nullable - public static ServerPageFile getServerPageFile(final PsiElement element) { - final PsiFile psiFile = PsiUtilCore.getTemplateLanguageFile(element); - return psiFile instanceof ServerPageFile ? (ServerPageFile)psiFile : null; - } - - public static PsiElement setName(@Nonnull PsiElement element, @Nonnull String name) throws IncorrectOperationException { - PsiManager manager = element.getManager(); - PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); - PsiIdentifier newNameIdentifier = factory.createIdentifier(name); - return element.replace(newNameIdentifier); - } - - public static boolean isDeprecatedByAnnotation(@Nonnull PsiModifierListOwner owner) { - PsiModifierList modifierList = owner.getModifierList(); - return modifierList != null && modifierList.findAnnotation("java.lang.Deprecated") != null; - } - - public static boolean isDeprecatedByDocTag(@Nonnull PsiJavaDocumentedElement owner) { - PsiDocComment docComment = owner.getDocComment(); - return docComment != null && docComment.findTagByName("deprecated") != null; - } - - @Nullable - public static PsiJavaDocumentedElement findDocCommentOwner(@Nonnull PsiDocComment comment) { - PsiElement parent = comment.getParent(); - if (parent instanceof PsiJavaDocumentedElement) { - PsiJavaDocumentedElement owner = (PsiJavaDocumentedElement)parent; - if (owner.getDocComment() == comment) { - return owner; - } - } - return null; - } - - @Nullable - public static PsiAnnotationMemberValue setDeclaredAttributeValue(@Nonnull PsiAnnotation psiAnnotation, - @Nullable String attributeName, - @Nullable PsiAnnotationMemberValue value, - @Nonnull PairFunction annotationCreator) { - PsiAnnotationMemberValue existing = psiAnnotation.findDeclaredAttributeValue(attributeName); - if (value == null) { - if (existing == null) { return null; - } - existing.getParent().delete(); - } - else { - if (existing != null) { - ((PsiNameValuePair)existing.getParent()).setValue(value); - } - else { - PsiNameValuePair[] attributes = psiAnnotation.getParameterList().getAttributes(); - if (attributes.length == 1) { - PsiNameValuePair attribute = attributes[0]; - if (attribute.getName() == null) { - PsiAnnotationMemberValue defValue = attribute.getValue(); - assert defValue != null : attribute; - attribute.replace(createNameValuePair(defValue, PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME + "=", annotationCreator)); - } - } - - boolean allowNoName = attributes.length == 0 && ("value".equals(attributeName) || null == attributeName); - final String namePrefix; - if (allowNoName) { - namePrefix = ""; + } + + @Nullable + public static PsiAnnotationMemberValue setDeclaredAttributeValue( + @Nonnull PsiAnnotation psiAnnotation, + @Nullable String attributeName, + @Nullable PsiAnnotationMemberValue value, + @Nonnull PairFunction annotationCreator + ) { + PsiAnnotationMemberValue existing = psiAnnotation.findDeclaredAttributeValue(attributeName); + if (value == null) { + if (existing == null) { + return null; + } + existing.getParent().delete(); } else { - namePrefix = attributeName + "="; - } - psiAnnotation.getParameterList().addBefore(createNameValuePair(value, namePrefix, annotationCreator), null); - } - } - return psiAnnotation.findDeclaredAttributeValue(attributeName); - } - - private static PsiNameValuePair createNameValuePair(@Nonnull PsiAnnotationMemberValue value, - @Nonnull String namePrefix, - @Nonnull PairFunction annotationCreator) { - return annotationCreator.fun(value.getProject(), "@A(" + namePrefix + value.getText() + ")").getParameterList().getAttributes()[0]; - } - - @Nullable - public static ASTNode skipWhitespaceAndComments(final ASTNode node) { - return skipWhitespaceCommentsAndTokens(node, TokenSet.EMPTY); - } - - @Nullable - public static ASTNode skipWhitespaceCommentsAndTokens(final ASTNode node, TokenSet alsoSkip) { - ASTNode element = node; - while (true) { - if (element == null) { - return null; - } - if (!isWhitespaceOrComment(element) && !alsoSkip.contains(element.getElementType())) { - break; - } - element = element.getTreeNext(); - } - return element; - } - - @Nullable - public static PsiSwitchExpression findEnclosingSwitchExpression(@Nonnull PsiElement start) { - for (PsiElement e = start; !isCodeBoundary(e); e = e.getParent()) { - if (e instanceof PsiSwitchExpression) - return (PsiSwitchExpression)e; - } - return null; - } - - private static boolean isCodeBoundary(@Nullable PsiElement e) { - return e == null || e instanceof PsiMethod || e instanceof PsiClassInitializer || e instanceof PsiLambdaExpression; - } - - public static boolean isWhitespaceOrComment(ASTNode element) { - return element.getPsi() instanceof PsiWhiteSpace || element.getPsi() instanceof PsiComment; - } - - @Nullable - public static ASTNode skipWhitespaceAndCommentsBack(final ASTNode node) { - if (node == null) { - return null; - } - if (!isWhitespaceOrComment(node)) { - return node; - } - - ASTNode parent = node.getTreeParent(); - ASTNode prev = node; - while (prev instanceof CompositeElement) { - if (!isWhitespaceOrComment(prev)) { - return prev; - } - prev = prev.getTreePrev(); - } - if (prev == null) { - return null; - } - ASTNode firstChildNode = parent.getFirstChildNode(); - ASTNode lastRelevant = null; - while (firstChildNode != prev) { - if (!isWhitespaceOrComment(firstChildNode)) { - lastRelevant = firstChildNode; - } - firstChildNode = firstChildNode.getTreeNext(); - } - return lastRelevant; - } - - @Nullable - public static ASTNode findStatementChild(CompositePsiElement statement) { - if (DebugUtil.CHECK_INSIDE_ATOMIC_ACTION_ENABLED) { - ApplicationManager.getApplication().assertReadAccessAllowed(); - } - for (ASTNode element = statement.getFirstChildNode(); element != null; element = element.getTreeNext()) { - if (element.getPsi() instanceof PsiStatement) { + if (existing != null) { + ((PsiNameValuePair)existing.getParent()).setValue(value); + } + else { + PsiNameValuePair[] attributes = psiAnnotation.getParameterList().getAttributes(); + if (attributes.length == 1) { + PsiNameValuePair attribute = attributes[0]; + if (attribute.getName() == null) { + PsiAnnotationMemberValue defValue = attribute.getValue(); + assert defValue != null : attribute; + attribute.replace(createNameValuePair( + defValue, + PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME + "=", + annotationCreator + )); + } + } + + boolean allowNoName = attributes.length == 0 && ("value".equals(attributeName) || null == attributeName); + final String namePrefix; + if (allowNoName) { + namePrefix = ""; + } + else { + namePrefix = attributeName + "="; + } + psiAnnotation.getParameterList().addBefore(createNameValuePair(value, namePrefix, annotationCreator), null); + } + } + return psiAnnotation.findDeclaredAttributeValue(attributeName); + } + + private static PsiNameValuePair createNameValuePair( + @Nonnull PsiAnnotationMemberValue value, + @Nonnull String namePrefix, + @Nonnull PairFunction annotationCreator + ) { + return annotationCreator.fun(value.getProject(), "@A(" + namePrefix + value.getText() + ")").getParameterList().getAttributes()[0]; + } + + @Nullable + public static ASTNode skipWhitespaceAndComments(final ASTNode node) { + return skipWhitespaceCommentsAndTokens(node, TokenSet.EMPTY); + } + + @Nullable + public static ASTNode skipWhitespaceCommentsAndTokens(final ASTNode node, TokenSet alsoSkip) { + ASTNode element = node; + while (true) { + if (element == null) { + return null; + } + if (!isWhitespaceOrComment(element) && !alsoSkip.contains(element.getElementType())) { + break; + } + element = element.getTreeNext(); + } return element; - } } - return null; - } - public static PsiStatement[] getChildStatements(CompositeElement psiCodeBlock) { - ApplicationManager.getApplication().assertReadAccessAllowed(); - // no lock is needed because all chameleons are expanded already - int count = 0; - for (ASTNode child1 = psiCodeBlock.getFirstChildNode(); child1 != null; child1 = child1.getTreeNext()) { - if (child1.getPsi() instanceof PsiStatement) { - count++; - } + @Nullable + public static PsiSwitchExpression findEnclosingSwitchExpression(@Nonnull PsiElement start) { + for (PsiElement e = start; !isCodeBoundary(e); e = e.getParent()) { + if (e instanceof PsiSwitchExpression) { + return (PsiSwitchExpression)e; + } + } + return null; + } + + private static boolean isCodeBoundary(@Nullable PsiElement e) { + return e == null || e instanceof PsiMethod || e instanceof PsiClassInitializer || e instanceof PsiLambdaExpression; + } + + public static boolean isWhitespaceOrComment(ASTNode element) { + return element.getPsi() instanceof PsiWhiteSpace || element.getPsi() instanceof PsiComment; + } + + @Nullable + public static ASTNode skipWhitespaceAndCommentsBack(final ASTNode node) { + if (node == null) { + return null; + } + if (!isWhitespaceOrComment(node)) { + return node; + } + + ASTNode parent = node.getTreeParent(); + ASTNode prev = node; + while (prev instanceof CompositeElement) { + if (!isWhitespaceOrComment(prev)) { + return prev; + } + prev = prev.getTreePrev(); + } + if (prev == null) { + return null; + } + ASTNode firstChildNode = parent.getFirstChildNode(); + ASTNode lastRelevant = null; + while (firstChildNode != prev) { + if (!isWhitespaceOrComment(firstChildNode)) { + lastRelevant = firstChildNode; + } + firstChildNode = firstChildNode.getTreeNext(); + } + return lastRelevant; + } + + @Nullable + public static ASTNode findStatementChild(CompositePsiElement statement) { + if (DebugUtil.CHECK_INSIDE_ATOMIC_ACTION_ENABLED) { + ApplicationManager.getApplication().assertReadAccessAllowed(); + } + for (ASTNode element = statement.getFirstChildNode(); element != null; element = element.getTreeNext()) { + if (element.getPsi() instanceof PsiStatement) { + return element; + } + } + return null; + } + + public static PsiStatement[] getChildStatements(CompositeElement psiCodeBlock) { + ApplicationManager.getApplication().assertReadAccessAllowed(); + // no lock is needed because all chameleons are expanded already + int count = 0; + for (ASTNode child1 = psiCodeBlock.getFirstChildNode(); child1 != null; child1 = child1.getTreeNext()) { + if (child1.getPsi() instanceof PsiStatement) { + count++; + } + } + + PsiStatement[] result = PsiStatement.ARRAY_FACTORY.create(count); + if (count == 0) { + return result; + } + int idx = 0; + for (ASTNode child = psiCodeBlock.getFirstChildNode(); child != null && idx < count; child = child.getTreeNext()) { + PsiElement element = child.getPsi(); + if (element instanceof PsiStatement) { + result[idx++] = (PsiStatement)element; + } + } + return result; + } + + public static boolean isVarArgs(@Nonnull PsiMethod method) { + PsiParameter[] parameters = method.getParameterList().getParameters(); + return parameters.length > 0 && parameters[parameters.length - 1].isVarArgs(); } - PsiStatement[] result = PsiStatement.ARRAY_FACTORY.create(count); - if (count == 0) { - return result; + public static PsiElement handleMirror(PsiElement element) { + return element instanceof PsiMirrorElement ? ((PsiMirrorElement)element).getPrototype() : element; } - int idx = 0; - for (ASTNode child = psiCodeBlock.getFirstChildNode(); child != null && idx < count; child = child.getTreeNext()) { - PsiElement element = child.getPsi(); - if (element instanceof PsiStatement) { - result[idx++] = (PsiStatement)element; - } - } - return result; - } - public static boolean isVarArgs(@Nonnull PsiMethod method) { - PsiParameter[] parameters = method.getParameterList().getParameters(); - return parameters.length > 0 && parameters[parameters.length - 1].isVarArgs(); - } + @Nullable + public static PsiModifierList findNeighbourModifierList(@Nonnull PsiJavaCodeReferenceElement ref) { + PsiElement parent = PsiTreeUtil.skipParentsOfType(ref, PsiJavaCodeReferenceElement.class); + if (parent instanceof PsiTypeElement) { + PsiElement grandParent = parent.getParent(); + if (grandParent instanceof PsiModifierListOwner) { + return ((PsiModifierListOwner)grandParent).getModifierList(); + } + } + + return null; + } + + public static boolean isTypeAnnotation(@Nullable PsiElement element) { + return element instanceof PsiAnnotation && AnnotationTargetUtil.isTypeAnnotation((PsiAnnotation)element); + } + + public static void collectTypeUseAnnotations(@Nonnull PsiModifierList modifierList, @Nonnull List annotations) { + for (PsiAnnotation annotation : modifierList.getAnnotations()) { + if (AnnotationTargetUtil.isTypeAnnotation(annotation)) { + annotations.add(annotation); + } + } + } + + /** + * @deprecated use {@link #collectTypeUseAnnotations(PsiModifierList, List)} (to be removed in IDEA 16) + */ + @SuppressWarnings("unused") + public static List getTypeUseAnnotations(@Nonnull PsiModifierList modifierList) { + SmartList result = null; + + for (PsiAnnotation annotation : modifierList.getAnnotations()) { + if (isTypeAnnotation(annotation)) { + if (result == null) { + result = new SmartList(); + } + result.add(annotation); + } + } + + return result; + } + + private static final Key TYPE_ANNO_MARK = Key.create("type.annotation.mark"); + + public static void markTypeAnnotations(@Nonnull PsiTypeElement typeElement) { + PsiElement left = PsiTreeUtil.skipSiblingsBackward(typeElement, PsiComment.class, PsiWhiteSpace.class, PsiTypeParameterList.class); + if (left instanceof PsiModifierList) { + for (PsiAnnotation annotation : ((PsiModifierList)left).getAnnotations()) { + if (AnnotationTargetUtil.isTypeAnnotation(annotation)) { + annotation.putUserData(TYPE_ANNO_MARK, Boolean.TRUE); + } + } + } + } + + public static void deleteTypeAnnotations(@Nonnull PsiTypeElement typeElement) { + PsiElement left = PsiTreeUtil.skipSiblingsBackward(typeElement, PsiComment.class, PsiWhiteSpace.class, PsiTypeParameterList.class); + if (left instanceof PsiModifierList) { + for (PsiAnnotation annotation : ((PsiModifierList)left).getAnnotations()) { + if (TYPE_ANNO_MARK.get(annotation) == Boolean.TRUE) { + annotation.delete(); + } + } + } + } + + public static boolean isLeafElementOfType(@Nullable PsiElement element, IElementType type) { + return element instanceof LeafElement && ((LeafElement)element).getElementType() == type; + } + + public static boolean isLeafElementOfType(PsiElement element, TokenSet tokenSet) { + return element instanceof LeafElement && tokenSet.contains(((LeafElement)element).getElementType()); + } + + public static PsiType buildTypeFromTypeString( + @Nonnull final String typeName, + @Nonnull final PsiElement context, + @Nonnull final PsiFile psiFile + ) { + PsiType resultType; + final PsiManager psiManager = psiFile.getManager(); + + if (typeName.indexOf('<') != -1 || typeName.indexOf('[') != -1 || typeName.indexOf('.') == -1) { + try { + return JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory().createTypeFromText(typeName, context); + } + catch (Exception ignored) { + } // invalid syntax will produce unresolved class type + } - public static PsiElement handleMirror(PsiElement element) { - return element instanceof PsiMirrorElement ? ((PsiMirrorElement)element).getPrototype() : element; - } + PsiClass aClass = JavaPsiFacade.getInstance(psiManager.getProject()).findClass(typeName, context.getResolveScope()); - @Nullable - public static PsiModifierList findNeighbourModifierList(@Nonnull PsiJavaCodeReferenceElement ref) { - PsiElement parent = PsiTreeUtil.skipParentsOfType(ref, PsiJavaCodeReferenceElement.class); - if (parent instanceof PsiTypeElement) { - PsiElement grandParent = parent.getParent(); - if (grandParent instanceof PsiModifierListOwner) { - return ((PsiModifierListOwner)grandParent).getModifierList(); - } + if (aClass == null) { + final LightClassReference ref = + new LightClassReference(psiManager, PsiNameHelper.getShortClassName(typeName), typeName, PsiSubstitutor.EMPTY, psiFile); + resultType = new PsiClassReferenceType(ref, null); + } + else { + PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory(); + PsiSubstitutor substitutor = factory.createRawSubstitutor(aClass); + resultType = factory.createType(aClass, substitutor); + } + + return resultType; } - return null; - } + @Nonnull + public static JavaResolveResult[] multiResolveImpl( + @Nonnull T element, + boolean incompleteCode, + @Nonnull ResolveCache.PolyVariantContextResolver resolver + ) { + FileASTNode fileElement = SharedImplUtil.findFileElement(element.getNode()); + if (fileElement == null) { + PsiUtilCore.ensureValid(element); + LOG.error("fileElement == null!"); + return JavaResolveResult.EMPTY_ARRAY; + } + PsiFile psiFile = SharedImplUtil.getContainingFile(fileElement); + PsiManager manager = psiFile == null ? null : psiFile.getManager(); + if (manager == null) { + PsiUtilCore.ensureValid(element); + LOG.error("getManager() == null!"); + return JavaResolveResult.EMPTY_ARRAY; + } + boolean valid = psiFile.isValid(); + if (!valid) { + PsiUtilCore.ensureValid(element); + LOG.error("psiFile.isValid() == false!"); + return JavaResolveResult.EMPTY_ARRAY; + } + if (element instanceof PsiMethodReferenceExpression) { + // method refs: do not cache results during parent conflict resolving, acceptable checks, etc + final Map map = LambdaUtil.ourFunctionTypes.get(); + if (map != null && map.containsKey(element)) { + return (JavaResolveResult[])resolver.resolve(element, psiFile, incompleteCode); + } + } - public static boolean isTypeAnnotation(@Nullable PsiElement element) { - return element instanceof PsiAnnotation && AnnotationTargetUtil.isTypeAnnotation((PsiAnnotation)element); - } + return multiResolveImpl(manager.getProject(), psiFile, element, incompleteCode, resolver); + } + + @Nonnull + public static JavaResolveResult[] multiResolveImpl( + @Nonnull Project project, + @Nonnull PsiFile psiFile, + @Nonnull T element, + boolean incompleteCode, + @Nonnull ResolveCache.PolyVariantContextResolver resolver + ) { + ResolveResult[] results = ResolveCache.getInstance(project).resolveWithCaching(element, resolver, true, incompleteCode, psiFile); + return results.length == 0 ? JavaResolveResult.EMPTY_ARRAY : (JavaResolveResult[])results; + } + + /** + * Returns enclosing label statement for given label expression + * + * @param expression switch label expression + * @return enclosing label statement or null if given expression is not a label statement expression + */ + @Nullable + public static PsiSwitchLabelStatementBase getSwitchLabel(@Nonnull PsiExpression expression) { + PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent()); + if (parent instanceof PsiExpressionList) { + PsiElement grand = parent.getParent(); + if (grand instanceof PsiSwitchLabelStatementBase) { + return (PsiSwitchLabelStatementBase)grand; + } + } + return null; + } - public static void collectTypeUseAnnotations(@Nonnull PsiModifierList modifierList, @Nonnull List annotations) { - for (PsiAnnotation annotation : modifierList.getAnnotations()) { - if (AnnotationTargetUtil.isTypeAnnotation(annotation)) { - annotations.add(annotation); - } - } - } - - /** - * @deprecated use {@link #collectTypeUseAnnotations(PsiModifierList, List)} (to be removed in IDEA 16) - */ - @SuppressWarnings("unused") - public static List getTypeUseAnnotations(@Nonnull PsiModifierList modifierList) { - SmartList result = null; - - for (PsiAnnotation annotation : modifierList.getAnnotations()) { - if (isTypeAnnotation(annotation)) { - if (result == null) { - result = new SmartList(); - } - result.add(annotation); - } - } - - return result; - } - - private static final Key TYPE_ANNO_MARK = Key.create("type.annotation.mark"); - - public static void markTypeAnnotations(@Nonnull PsiTypeElement typeElement) { - PsiElement left = PsiTreeUtil.skipSiblingsBackward(typeElement, PsiComment.class, PsiWhiteSpace.class, PsiTypeParameterList.class); - if (left instanceof PsiModifierList) { - for (PsiAnnotation annotation : ((PsiModifierList)left).getAnnotations()) { - if (AnnotationTargetUtil.isTypeAnnotation(annotation)) { - annotation.putUserData(TYPE_ANNO_MARK, Boolean.TRUE); - } - } - } - } - - public static void deleteTypeAnnotations(@Nonnull PsiTypeElement typeElement) { - PsiElement left = PsiTreeUtil.skipSiblingsBackward(typeElement, PsiComment.class, PsiWhiteSpace.class, PsiTypeParameterList.class); - if (left instanceof PsiModifierList) { - for (PsiAnnotation annotation : ((PsiModifierList)left).getAnnotations()) { - if (TYPE_ANNO_MARK.get(annotation) == Boolean.TRUE) { - annotation.delete(); - } - } - } - } - - public static boolean isLeafElementOfType(@Nullable PsiElement element, IElementType type) { - return element instanceof LeafElement && ((LeafElement)element).getElementType() == type; - } - - public static boolean isLeafElementOfType(PsiElement element, TokenSet tokenSet) { - return element instanceof LeafElement && tokenSet.contains(((LeafElement)element).getElementType()); - } - - public static PsiType buildTypeFromTypeString(@Nonnull final String typeName, - @Nonnull final PsiElement context, - @Nonnull final PsiFile psiFile) { - PsiType resultType; - final PsiManager psiManager = psiFile.getManager(); - - if (typeName.indexOf('<') != -1 || typeName.indexOf('[') != -1 || typeName.indexOf('.') == -1) { - try { - return JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory().createTypeFromText(typeName, context); - } - catch (Exception ignored) { - } // invalid syntax will produce unresolved class type - } - - PsiClass aClass = JavaPsiFacade.getInstance(psiManager.getProject()).findClass(typeName, context.getResolveScope()); - - if (aClass == null) { - final LightClassReference ref = - new LightClassReference(psiManager, PsiNameHelper.getShortClassName(typeName), typeName, PsiSubstitutor.EMPTY, psiFile); - resultType = new PsiClassReferenceType(ref, null); - } - else { - PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory(); - PsiSubstitutor substitutor = factory.createRawSubstitutor(aClass); - resultType = factory.createType(aClass, substitutor); - } - - return resultType; - } - - @Nonnull - public static JavaResolveResult[] multiResolveImpl(@Nonnull T element, - boolean incompleteCode, - @Nonnull ResolveCache.PolyVariantContextResolver resolver) { - FileASTNode fileElement = SharedImplUtil.findFileElement(element.getNode()); - if (fileElement == null) { - PsiUtilCore.ensureValid(element); - LOG.error("fileElement == null!"); - return JavaResolveResult.EMPTY_ARRAY; - } - PsiFile psiFile = SharedImplUtil.getContainingFile(fileElement); - PsiManager manager = psiFile == null ? null : psiFile.getManager(); - if (manager == null) { - PsiUtilCore.ensureValid(element); - LOG.error("getManager() == null!"); - return JavaResolveResult.EMPTY_ARRAY; - } - boolean valid = psiFile.isValid(); - if (!valid) { - PsiUtilCore.ensureValid(element); - LOG.error("psiFile.isValid() == false!"); - return JavaResolveResult.EMPTY_ARRAY; - } - if (element instanceof PsiMethodReferenceExpression) { - // method refs: do not cache results during parent conflict resolving, acceptable checks, etc - final Map map = LambdaUtil.ourFunctionTypes.get(); - if (map != null && map.containsKey(element)) { - return (JavaResolveResult[])resolver.resolve(element, psiFile, incompleteCode); - } - } - - return multiResolveImpl(manager.getProject(), psiFile, element, incompleteCode, resolver); - } - - @Nonnull - public static JavaResolveResult[] multiResolveImpl(@Nonnull Project project, - @Nonnull PsiFile psiFile, - @Nonnull T element, - boolean incompleteCode, - @Nonnull ResolveCache.PolyVariantContextResolver resolver) { - ResolveResult[] results = ResolveCache.getInstance(project).resolveWithCaching(element, resolver, true, incompleteCode, psiFile); - return results.length == 0 ? JavaResolveResult.EMPTY_ARRAY : (JavaResolveResult[])results; - } - - /** - * Returns enclosing label statement for given label expression - * - * @param expression switch label expression - * @return enclosing label statement or null if given expression is not a label statement expression - */ - @Nullable - public static PsiSwitchLabelStatementBase getSwitchLabel(@Nonnull PsiExpression expression) { - PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent()); - if (parent instanceof PsiExpressionList) { - PsiElement grand = parent.getParent(); - if (grand instanceof PsiSwitchLabelStatementBase) { - return (PsiSwitchLabelStatementBase)grand; - } - } - return null; - } - - public static VirtualFile getModuleVirtualFile(@Nonnull PsiJavaModule module) { - if (module instanceof AutomaticJavaModule) { - return ((AutomaticJavaModule)module).getRootVirtualFile(); - } - else { - return module.getContainingFile().getVirtualFile(); - } - } + public static VirtualFile getModuleVirtualFile(@Nonnull PsiJavaModule module) { + if (module instanceof AutomaticJavaModule) { + return ((AutomaticJavaModule)module).getRootVirtualFile(); + } + else { + return module.getContainingFile().getVirtualFile(); + } + } } diff --git a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/PsiSuperMethodImplUtil.java b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/PsiSuperMethodImplUtil.java index 7bc33a73f..332d01152 100644 --- a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/PsiSuperMethodImplUtil.java +++ b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/PsiSuperMethodImplUtil.java @@ -40,432 +40,493 @@ import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; + import java.util.*; import java.util.function.Function; public class PsiSuperMethodImplUtil { - private static final Logger LOG = Logger.getInstance(PsiSuperMethodImplUtil.class); - private static final PsiCacheKey, PsiClass> SIGNATURES_FOR_CLASS_KEY = PsiCacheKey.create("SIGNATURES_FOR_CLASS_KEY", (Function>) dom -> buildMethodHierarchy(dom, null, PsiSubstitutor.EMPTY, true, new HashSet(), false, dom.getResolveScope())); - private static final PsiCacheKey>, PsiClass> SIGNATURES_BY_NAME_KEY = PsiCacheKey.create("SIGNATURES_BY_NAME_KEY", psiClass - -> ConcurrentFactoryMap.createMap(methodName -> buildMethodHierarchy(psiClass, methodName, PsiSubstitutor.EMPTY, true, new HashSet<>(), false, psiClass.getResolveScope()))); - - private PsiSuperMethodImplUtil() { - } - - @Nonnull - public static PsiMethod[] findSuperMethods(@Nonnull PsiMethod method) { - return findSuperMethods(method, null); - } - - @Nonnull - public static PsiMethod[] findSuperMethods(@Nonnull PsiMethod method, boolean checkAccess) { - if (!canHaveSuperMethod(method, checkAccess, false)) { - return PsiMethod.EMPTY_ARRAY; + private static final Logger LOG = Logger.getInstance(PsiSuperMethodImplUtil.class); + private static final PsiCacheKey, PsiClass> SIGNATURES_FOR_CLASS_KEY = + PsiCacheKey.create( + "SIGNATURES_FOR_CLASS_KEY", + (Function>)dom -> buildMethodHierarchy( + dom, + null, + PsiSubstitutor.EMPTY, + true, + new HashSet(), + false, + dom.getResolveScope() + ) + ); + private static final PsiCacheKey>, PsiClass> SIGNATURES_BY_NAME_KEY = + PsiCacheKey.create( + "SIGNATURES_BY_NAME_KEY", + psiClass -> ConcurrentFactoryMap.createMap(methodName -> buildMethodHierarchy( + psiClass, + methodName, + PsiSubstitutor.EMPTY, + true, + new HashSet<>(), + false, + psiClass.getResolveScope() + )) + ); + + private PsiSuperMethodImplUtil() { } - return findSuperMethodsInternal(method, null); - } - @Nonnull - public static PsiMethod[] findSuperMethods(@Nonnull PsiMethod method, PsiClass parentClass) { - if (!canHaveSuperMethod(method, true, false)) { - return PsiMethod.EMPTY_ARRAY; + @Nonnull + public static PsiMethod[] findSuperMethods(@Nonnull PsiMethod method) { + return findSuperMethods(method, null); } - return findSuperMethodsInternal(method, parentClass); - } - - @Nonnull - private static PsiMethod[] findSuperMethodsInternal(@Nonnull PsiMethod method, PsiClass parentClass) { - List outputMethods = findSuperMethodSignatures(method, parentClass, false); - - return MethodSignatureUtil.convertMethodSignaturesToMethods(outputMethods); - } + @Nonnull + public static PsiMethod[] findSuperMethods(@Nonnull PsiMethod method, boolean checkAccess) { + if (!canHaveSuperMethod(method, checkAccess, false)) { + return PsiMethod.EMPTY_ARRAY; + } + return findSuperMethodsInternal(method, null); + } - @Nonnull - public static List findSuperMethodSignaturesIncludingStatic(@Nonnull PsiMethod method, boolean checkAccess) { - if (!canHaveSuperMethod(method, checkAccess, true)) { - return Collections.emptyList(); + @Nonnull + public static PsiMethod[] findSuperMethods(@Nonnull PsiMethod method, PsiClass parentClass) { + if (!canHaveSuperMethod(method, true, false)) { + return PsiMethod.EMPTY_ARRAY; + } + return findSuperMethodsInternal(method, parentClass); } - return findSuperMethodSignatures(method, null, true); - } - @Nonnull - private static List findSuperMethodSignatures(@Nonnull PsiMethod method, PsiClass parentClass, boolean allowStaticMethod) { - return new ArrayList<>(SuperMethodsSearch.search(method, parentClass, true, allowStaticMethod).findAll()); - } - private static boolean canHaveSuperMethod(@Nonnull PsiMethod method, boolean checkAccess, boolean allowStaticMethod) { - if (method.isConstructor()) { - return false; - } - if (!allowStaticMethod && method.hasModifierProperty(PsiModifier.STATIC)) { - return false; - } - if (checkAccess && method.hasModifierProperty(PsiModifier.PRIVATE)) { - return false; + @Nonnull + private static PsiMethod[] findSuperMethodsInternal(@Nonnull PsiMethod method, PsiClass parentClass) { + List outputMethods = findSuperMethodSignatures(method, parentClass, false); + + return MethodSignatureUtil.convertMethodSignaturesToMethods(outputMethods); } - PsiClass parentClass = method.getContainingClass(); - return parentClass != null && !JavaClassNames.JAVA_LANG_OBJECT.equals(parentClass.getQualifiedName()); - } - - @Nullable - public static PsiMethod findDeepestSuperMethod(@Nonnull PsiMethod method) { - if (!canHaveSuperMethod(method, true, false)) { - return null; + + @Nonnull + public static List findSuperMethodSignaturesIncludingStatic( + @Nonnull PsiMethod method, + boolean checkAccess + ) { + if (!canHaveSuperMethod(method, checkAccess, true)) { + return Collections.emptyList(); + } + return findSuperMethodSignatures(method, null, true); } - return DeepestSuperMethodsSearch.search(method).findFirst(); - } - @Nonnull - public static PsiMethod[] findDeepestSuperMethods(@Nonnull PsiMethod method) { - if (!canHaveSuperMethod(method, true, false)) { - return PsiMethod.EMPTY_ARRAY; + @Nonnull + private static List findSuperMethodSignatures( + @Nonnull PsiMethod method, + PsiClass parentClass, + boolean allowStaticMethod + ) { + return new ArrayList<>(SuperMethodsSearch.search(method, parentClass, true, allowStaticMethod).findAll()); } - Collection collection = DeepestSuperMethodsSearch.search(method).findAll(); - return collection.toArray(new PsiMethod[collection.size()]); - } - - @Nonnull - private static Map buildMethodHierarchy(@Nonnull PsiClass aClass, - @Nullable String nameHint, - @Nonnull PsiSubstitutor substitutor, - final boolean includePrivates, - @Nonnull final Set visited, - boolean isInRawContext, - GlobalSearchScope resolveScope) { - ProgressManager.checkCanceled(); - Map result = Maps.newLinkedHashMap(new HashingStrategy() { - @Override - public int hashCode(MethodSignature object) { - return object.hashCode(); - } - - @Override - public boolean equals(MethodSignature o1, MethodSignature o2) { - if (o1.equals(o2)) { - final PsiMethod method1 = ((MethodSignatureBackedByPsiMethod) o1).getMethod(); - final PsiType returnType1 = method1.getReturnType(); - final PsiMethod method2 = ((MethodSignatureBackedByPsiMethod) o2).getMethod(); - final PsiType returnType2 = method2.getReturnType(); - if (method1.hasModifierProperty(PsiModifier.STATIC) || method2.hasModifierProperty(PsiModifier.STATIC)) { - return true; - } - - if (MethodSignatureUtil.isReturnTypeSubstitutable(o1, o2, returnType1, returnType2)) { - return true; - } - - final PsiClass containingClass1 = method1.getContainingClass(); - final PsiClass containingClass2 = method2.getContainingClass(); - if (containingClass1 != null && containingClass2 != null) { - return containingClass1.isAnnotationType() || containingClass2.isAnnotationType(); - } - } - return false; - } - }); - final Map> sameParameterErasureMethods = Maps.newHashMap(MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY); - - Map map = Maps.newHashMap(new HashingStrategy() { - @Override - public int hashCode(MethodSignature signature) { - return MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY.hashCode(signature); - } - - @Override - public boolean equals(MethodSignature o1, MethodSignature o2) { - if (!MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY.equals(o1, o2)) { - return false; - } - List list = sameParameterErasureMethods.get(o1); - boolean toCheckReturnType = list != null && list.size() > 1; - if (!toCheckReturnType) { - return true; + + private static boolean canHaveSuperMethod(@Nonnull PsiMethod method, boolean checkAccess, boolean allowStaticMethod) { + if (method.isConstructor()) { + return false; } - PsiType returnType1 = ((MethodSignatureBackedByPsiMethod) o1).getMethod().getReturnType(); - PsiType returnType2 = ((MethodSignatureBackedByPsiMethod) o2).getMethod().getReturnType(); - if (returnType1 == null && returnType2 == null) { - return true; + if (!allowStaticMethod && method.hasModifierProperty(PsiModifier.STATIC)) { + return false; } - if (returnType1 == null || returnType2 == null) { - return false; + if (checkAccess && method.hasModifierProperty(PsiModifier.PRIVATE)) { + return false; } + PsiClass parentClass = method.getContainingClass(); + return parentClass != null && !JavaClassNames.JAVA_LANG_OBJECT.equals(parentClass.getQualifiedName()); + } - PsiType erasure1 = TypeConversionUtil.erasure(o1.getSubstitutor().substitute(returnType1)); - PsiType erasure2 = TypeConversionUtil.erasure(o2.getSubstitutor().substitute(returnType2)); - return erasure1.equals(erasure2); - } - }); - - PsiMethod[] methods = aClass.getMethods(); - for (PsiMethod method : methods) { - if (!method.isValid()) { - throw new PsiInvalidElementAccessException(method, "class.valid=" + aClass.isValid() + "; name=" + method.getName()); - } - if (nameHint != null && !nameHint.equals(method.getName())) { - continue; - } - if (!includePrivates && method.hasModifierProperty(PsiModifier.PRIVATE)) { - continue; - } - final MethodSignatureBackedByPsiMethod signature = MethodSignatureBackedByPsiMethod.create(method, PsiSubstitutor.EMPTY, isInRawContext); - HierarchicalMethodSignatureImpl newH = new HierarchicalMethodSignatureImpl(MethodSignatureBackedByPsiMethod.create(method, substitutor, isInRawContext)); - - List list = sameParameterErasureMethods.get(signature); - if (list == null) { - list = new SmartList<>(); - sameParameterErasureMethods.put(signature, list); - } - list.add(method); - - LOG.assertTrue(newH.getMethod().isValid()); - result.put(signature, newH); - map.put(signature, newH); + @Nullable + public static PsiMethod findDeepestSuperMethod(@Nonnull PsiMethod method) { + if (!canHaveSuperMethod(method, true, false)) { + return null; + } + return DeepestSuperMethodsSearch.search(method).findFirst(); } - final List superTypes = PsiClassImplUtil.getScopeCorrectedSuperTypes(aClass, resolveScope); - - for (PsiClassType.ClassResolveResult superTypeResolveResult : superTypes) { - PsiClass superClass = superTypeResolveResult.getElement(); - if (superClass == null) { - continue; - } - if (!visited.add(superClass)) { - continue; // cyclic inheritance - } - final PsiSubstitutor superSubstitutor = superTypeResolveResult.getSubstitutor(); - PsiSubstitutor finalSubstitutor = PsiSuperMethodUtil.obtainFinalSubstitutor(superClass, superSubstitutor, substitutor, isInRawContext); - - final boolean isInRawContextSuper = (isInRawContext || PsiUtil.isRawSubstitutor(superClass, superSubstitutor)) && superClass.getTypeParameters().length != 0; - Map superResult = buildMethodHierarchy(superClass, nameHint, finalSubstitutor, false, visited, isInRawContextSuper, resolveScope); - visited.remove(superClass); - - List> flattened = new ArrayList<>(); - for (Map.Entry entry : superResult.entrySet()) { - HierarchicalMethodSignature hms = entry.getValue(); - MethodSignature signature = MethodSignatureBackedByPsiMethod.create(hms.getMethod(), hms.getSubstitutor(), hms.isRaw()); - PsiClass containingClass = hms.getMethod().getContainingClass(); - List supers = new ArrayList<>(hms.getSuperSignatures()); - for (HierarchicalMethodSignature aSuper : supers) { - PsiClass superContainingClass = aSuper.getMethod().getContainingClass(); - if (containingClass != null && superContainingClass != null && !containingClass.isInheritor(superContainingClass, true)) { - // methods must be inherited from unrelated classes, so flatten hierarchy here - // class C implements SAM1, SAM2 { void methodimpl() {} } - //hms.getSuperSignatures().remove(aSuper); - flattened.add(Pair.create(signature, aSuper)); - } + @Nonnull + public static PsiMethod[] findDeepestSuperMethods(@Nonnull PsiMethod method) { + if (!canHaveSuperMethod(method, true, false)) { + return PsiMethod.EMPTY_ARRAY; } - putInMap(aClass, result, map, hms, signature); - } - for (Pair pair : flattened) { - putInMap(aClass, result, map, pair.second, pair.first); - } + Collection collection = DeepestSuperMethodsSearch.search(method).findAll(); + return collection.toArray(new PsiMethod[collection.size()]); } + @Nonnull + private static Map buildMethodHierarchy( + @Nonnull PsiClass aClass, + @Nullable String nameHint, + @Nonnull PsiSubstitutor substitutor, + final boolean includePrivates, + @Nonnull final Set visited, + boolean isInRawContext, + GlobalSearchScope resolveScope + ) { + ProgressManager.checkCanceled(); + Map result = Maps.newLinkedHashMap(new HashingStrategy() { + @Override + public int hashCode(MethodSignature object) { + return object.hashCode(); + } + + @Override + public boolean equals(MethodSignature o1, MethodSignature o2) { + if (o1.equals(o2)) { + final PsiMethod method1 = ((MethodSignatureBackedByPsiMethod)o1).getMethod(); + final PsiType returnType1 = method1.getReturnType(); + final PsiMethod method2 = ((MethodSignatureBackedByPsiMethod)o2).getMethod(); + final PsiType returnType2 = method2.getReturnType(); + if (method1.hasModifierProperty(PsiModifier.STATIC) || method2.hasModifierProperty(PsiModifier.STATIC)) { + return true; + } + + if (MethodSignatureUtil.isReturnTypeSubstitutable(o1, o2, returnType1, returnType2)) { + return true; + } + + final PsiClass containingClass1 = method1.getContainingClass(); + final PsiClass containingClass2 = method2.getContainingClass(); + if (containingClass1 != null && containingClass2 != null) { + return containingClass1.isAnnotationType() || containingClass2.isAnnotationType(); + } + } + return false; + } + }); + final Map> sameParameterErasureMethods = + Maps.newHashMap(MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY); + + Map map = Maps.newHashMap(new HashingStrategy() { + @Override + public int hashCode(MethodSignature signature) { + return MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY.hashCode(signature); + } + + @Override + public boolean equals(MethodSignature o1, MethodSignature o2) { + if (!MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY.equals(o1, o2)) { + return false; + } + List list = sameParameterErasureMethods.get(o1); + boolean toCheckReturnType = list != null && list.size() > 1; + if (!toCheckReturnType) { + return true; + } + PsiType returnType1 = ((MethodSignatureBackedByPsiMethod)o1).getMethod().getReturnType(); + PsiType returnType2 = ((MethodSignatureBackedByPsiMethod)o2).getMethod().getReturnType(); + if (returnType1 == null && returnType2 == null) { + return true; + } + if (returnType1 == null || returnType2 == null) { + return false; + } + + PsiType erasure1 = TypeConversionUtil.erasure(o1.getSubstitutor().substitute(returnType1)); + PsiType erasure2 = TypeConversionUtil.erasure(o2.getSubstitutor().substitute(returnType2)); + return erasure1.equals(erasure2); + } + }); + + PsiMethod[] methods = aClass.getMethods(); + for (PsiMethod method : methods) { + if (!method.isValid()) { + throw new PsiInvalidElementAccessException(method, "class.valid=" + aClass.isValid() + "; name=" + method.getName()); + } + if (nameHint != null && !nameHint.equals(method.getName())) { + continue; + } + if (!includePrivates && method.hasModifierProperty(PsiModifier.PRIVATE)) { + continue; + } + final MethodSignatureBackedByPsiMethod signature = + MethodSignatureBackedByPsiMethod.create(method, PsiSubstitutor.EMPTY, isInRawContext); + HierarchicalMethodSignatureImpl newH = + new HierarchicalMethodSignatureImpl(MethodSignatureBackedByPsiMethod.create(method, substitutor, isInRawContext)); + + List list = sameParameterErasureMethods.get(signature); + if (list == null) { + list = new SmartList<>(); + sameParameterErasureMethods.put(signature, list); + } + list.add(method); + + LOG.assertTrue(newH.getMethod().isValid()); + result.put(signature, newH); + map.put(signature, newH); + } - for (Map.Entry entry : map.entrySet()) { - HierarchicalMethodSignatureImpl hierarchicalMethodSignature = entry.getValue(); - MethodSignature methodSignature = entry.getKey(); - if (result.get(methodSignature) == null) { - LOG.assertTrue(hierarchicalMethodSignature.getMethod().isValid()); - result.put(methodSignature, hierarchicalMethodSignature); - } - } + final List superTypes = PsiClassImplUtil.getScopeCorrectedSuperTypes(aClass, resolveScope); + + for (PsiClassType.ClassResolveResult superTypeResolveResult : superTypes) { + PsiClass superClass = superTypeResolveResult.getElement(); + if (superClass == null) { + continue; + } + if (!visited.add(superClass)) { + continue; // cyclic inheritance + } + final PsiSubstitutor superSubstitutor = superTypeResolveResult.getSubstitutor(); + PsiSubstitutor finalSubstitutor = + PsiSuperMethodUtil.obtainFinalSubstitutor(superClass, superSubstitutor, substitutor, isInRawContext); + + final boolean isInRawContextSuper = + (isInRawContext || PsiUtil.isRawSubstitutor(superClass, superSubstitutor)) && superClass.getTypeParameters().length != 0; + Map superResult = + buildMethodHierarchy(superClass, nameHint, finalSubstitutor, false, visited, isInRawContextSuper, resolveScope); + visited.remove(superClass); + + List> flattened = new ArrayList<>(); + for (Map.Entry entry : superResult.entrySet()) { + HierarchicalMethodSignature hms = entry.getValue(); + MethodSignature signature = MethodSignatureBackedByPsiMethod.create(hms.getMethod(), hms.getSubstitutor(), hms.isRaw()); + PsiClass containingClass = hms.getMethod().getContainingClass(); + List supers = new ArrayList<>(hms.getSuperSignatures()); + for (HierarchicalMethodSignature aSuper : supers) { + PsiClass superContainingClass = aSuper.getMethod().getContainingClass(); + if (containingClass != null && superContainingClass != null + && !containingClass.isInheritor(superContainingClass, true)) { + // methods must be inherited from unrelated classes, so flatten hierarchy here + // class C implements SAM1, SAM2 { void methodimpl() {} } + //hms.getSuperSignatures().remove(aSuper); + flattened.add(Pair.create(signature, aSuper)); + } + } + putInMap(aClass, result, map, hms, signature); + } + for (Pair pair : flattened) { + putInMap(aClass, result, map, pair.second, pair.first); + } + } - return result; - } - - private static void putInMap(@Nonnull PsiClass aClass, - @Nonnull Map result, - @Nonnull Map map, - @Nonnull HierarchicalMethodSignature hierarchicalMethodSignature, - @Nonnull MethodSignature signature) { - HierarchicalMethodSignatureImpl existing = map.get(signature); - if (existing == null) { - HierarchicalMethodSignatureImpl copy = copy(hierarchicalMethodSignature); - LOG.assertTrue(copy.getMethod().isValid()); - map.put(signature, copy); - } else if (isReturnTypeIsMoreSpecificThan(hierarchicalMethodSignature, existing) && isSuperMethod(aClass, hierarchicalMethodSignature, existing)) { - HierarchicalMethodSignatureImpl newSuper = copy(hierarchicalMethodSignature); - mergeSupers(newSuper, existing); - LOG.assertTrue(newSuper.getMethod().isValid()); - map.put(signature, newSuper); - } else if (isSuperMethod(aClass, existing, hierarchicalMethodSignature)) { - mergeSupers(existing, hierarchicalMethodSignature); - } - // just drop an invalid method declaration there - to highlight accordingly - else if (!result.containsKey(signature)) { - LOG.assertTrue(hierarchicalMethodSignature.getMethod().isValid()); - result.put(signature, hierarchicalMethodSignature); - } - } - - private static boolean isReturnTypeIsMoreSpecificThan(@Nonnull HierarchicalMethodSignature thisSig, @Nonnull HierarchicalMethodSignature thatSig) { - PsiType thisRet = thisSig.getSubstitutor().substitute(thisSig.getMethod().getReturnType()); - PsiType thatRet = thatSig.getSubstitutor().substitute(thatSig.getMethod().getReturnType()); - PsiSubstitutor unifyingSubstitutor = MethodSignatureUtil.isSubsignature(thatSig, thisSig) ? MethodSignatureUtil.getSuperMethodSignatureSubstitutor(thisSig, thatSig) : null; - if (unifyingSubstitutor != null) { - thisRet = unifyingSubstitutor.substitute(thisRet); - thatRet = unifyingSubstitutor.substitute(thatRet); - } - return thatRet != null && thisRet != null && !thatRet.equals(thisRet) && TypeConversionUtil.isAssignable(thatRet, thisRet, false); - } - - private static void mergeSupers(@Nonnull HierarchicalMethodSignatureImpl existing, @Nonnull HierarchicalMethodSignature superSignature) { - for (HierarchicalMethodSignature existingSuper : existing.getSuperSignatures()) { - if (existingSuper.getMethod() == superSignature.getMethod()) { - for (HierarchicalMethodSignature signature : superSignature.getSuperSignatures()) { - mergeSupers((HierarchicalMethodSignatureImpl) existingSuper, signature); + + for (Map.Entry entry : map.entrySet()) { + HierarchicalMethodSignatureImpl hierarchicalMethodSignature = entry.getValue(); + MethodSignature methodSignature = entry.getKey(); + if (result.get(methodSignature) == null) { + LOG.assertTrue(hierarchicalMethodSignature.getMethod().isValid()); + result.put(methodSignature, hierarchicalMethodSignature); + } } - return; - } + + return result; } - if (existing.getMethod() == superSignature.getMethod()) { - List existingSupers = existing.getSuperSignatures(); - for (HierarchicalMethodSignature supers : superSignature.getSuperSignatures()) { - if (!existingSupers.contains(supers)) { - existing.addSuperSignature(copy(supers)); + + private static void putInMap( + @Nonnull PsiClass aClass, + @Nonnull Map result, + @Nonnull Map map, + @Nonnull HierarchicalMethodSignature hierarchicalMethodSignature, + @Nonnull MethodSignature signature + ) { + HierarchicalMethodSignatureImpl existing = map.get(signature); + if (existing == null) { + HierarchicalMethodSignatureImpl copy = copy(hierarchicalMethodSignature); + LOG.assertTrue(copy.getMethod().isValid()); + map.put(signature, copy); + } + else if (isReturnTypeIsMoreSpecificThan(hierarchicalMethodSignature, existing) + && isSuperMethod(aClass, hierarchicalMethodSignature, existing)) { + HierarchicalMethodSignatureImpl newSuper = copy(hierarchicalMethodSignature); + mergeSupers(newSuper, existing); + LOG.assertTrue(newSuper.getMethod().isValid()); + map.put(signature, newSuper); + } + else if (isSuperMethod(aClass, existing, hierarchicalMethodSignature)) { + mergeSupers(existing, hierarchicalMethodSignature); + } + // just drop an invalid method declaration there - to highlight accordingly + else if (!result.containsKey(signature)) { + LOG.assertTrue(hierarchicalMethodSignature.getMethod().isValid()); + result.put(signature, hierarchicalMethodSignature); } - } - } else { - HierarchicalMethodSignatureImpl copy = copy(superSignature); - existing.addSuperSignature(copy); } - } - - private static boolean isSuperMethod(@Nonnull PsiClass aClass, - @Nonnull MethodSignatureBackedByPsiMethod hierarchicalMethodSignature, - @Nonnull MethodSignatureBackedByPsiMethod superSignatureHierarchical) { - PsiMethod superMethod = superSignatureHierarchical.getMethod(); - PsiClass superClass = superMethod.getContainingClass(); - PsiMethod method = hierarchicalMethodSignature.getMethod(); - PsiClass containingClass = method.getContainingClass(); - if (!superMethod.isConstructor() && !aClass.equals(superClass) && MethodSignatureUtil.isSubsignature(superSignatureHierarchical, hierarchicalMethodSignature) && superClass != null) { - if (superClass.isInterface() || JavaClassNames.JAVA_LANG_OBJECT.equals(superClass.getQualifiedName())) { - if (superMethod.hasModifierProperty(PsiModifier.STATIC) || superMethod.hasModifierProperty(PsiModifier.DEFAULT) && method.hasModifierProperty(PsiModifier.STATIC) && !InheritanceUtil - .isInheritorOrSelf(containingClass, superClass, true)) { - return false; + + private static boolean isReturnTypeIsMoreSpecificThan( + @Nonnull HierarchicalMethodSignature thisSig, + @Nonnull HierarchicalMethodSignature thatSig + ) { + PsiType thisRet = thisSig.getSubstitutor().substitute(thisSig.getMethod().getReturnType()); + PsiType thatRet = thatSig.getSubstitutor().substitute(thatSig.getMethod().getReturnType()); + PsiSubstitutor unifyingSubstitutor = + MethodSignatureUtil.isSubsignature(thatSig, thisSig) + ? MethodSignatureUtil.getSuperMethodSignatureSubstitutor(thisSig, thatSig) + : null; + if (unifyingSubstitutor != null) { + thisRet = unifyingSubstitutor.substitute(thisRet); + thatRet = unifyingSubstitutor.substitute(thatRet); } + return thatRet != null && thisRet != null && !thatRet.equals(thisRet) && TypeConversionUtil.isAssignable(thatRet, thisRet, false); + } - if (superMethod.hasModifierProperty(PsiModifier.DEFAULT) || method.hasModifierProperty(PsiModifier.DEFAULT)) { - return superMethod.equals(method) || !InheritanceUtil.isInheritorOrSelf(superClass, containingClass, true); + private static void mergeSupers( + @Nonnull HierarchicalMethodSignatureImpl existing, + @Nonnull HierarchicalMethodSignature superSignature + ) { + for (HierarchicalMethodSignature existingSuper : existing.getSuperSignatures()) { + if (existingSuper.getMethod() == superSignature.getMethod()) { + for (HierarchicalMethodSignature signature : superSignature.getSuperSignatures()) { + mergeSupers((HierarchicalMethodSignatureImpl)existingSuper, signature); + } + return; + } } - return true; - } + if (existing.getMethod() == superSignature.getMethod()) { + List existingSupers = existing.getSuperSignatures(); + for (HierarchicalMethodSignature supers : superSignature.getSuperSignatures()) { + if (!existingSupers.contains(supers)) { + existing.addSuperSignature(copy(supers)); + } + } + } + else { + HierarchicalMethodSignatureImpl copy = copy(superSignature); + existing.addSuperSignature(copy); + } + } - if (containingClass != null) { - if (containingClass.isInterface()) { - return false; + private static boolean isSuperMethod( + @Nonnull PsiClass aClass, + @Nonnull MethodSignatureBackedByPsiMethod hierarchicalMethodSignature, + @Nonnull MethodSignatureBackedByPsiMethod superSignatureHierarchical + ) { + PsiMethod superMethod = superSignatureHierarchical.getMethod(); + PsiClass superClass = superMethod.getContainingClass(); + PsiMethod method = hierarchicalMethodSignature.getMethod(); + PsiClass containingClass = method.getContainingClass(); + if (!superMethod.isConstructor() && !aClass.equals(superClass) + && MethodSignatureUtil.isSubsignature(superSignatureHierarchical, hierarchicalMethodSignature) && superClass != null) { + if (superClass.isInterface() || JavaClassNames.JAVA_LANG_OBJECT.equals(superClass.getQualifiedName())) { + if (superMethod.hasModifierProperty(PsiModifier.STATIC) + || superMethod.hasModifierProperty(PsiModifier.DEFAULT) && method.hasModifierProperty(PsiModifier.STATIC) + && !InheritanceUtil.isInheritorOrSelf(containingClass, superClass, true)) { + return false; + } + + if (superMethod.hasModifierProperty(PsiModifier.DEFAULT) || method.hasModifierProperty(PsiModifier.DEFAULT)) { + return superMethod.equals(method) || !InheritanceUtil.isInheritorOrSelf(superClass, containingClass, true); + } + return true; + } + + if (containingClass != null) { + if (containingClass.isInterface()) { + return false; + } + + if (!aClass.isInterface() && !InheritanceUtil.isInheritorOrSelf(superClass, containingClass, true)) { + return true; + } + } } + return false; + } - if (!aClass.isInterface() && !InheritanceUtil.isInheritorOrSelf(superClass, containingClass, true)) { - return true; + @Nonnull + private static HierarchicalMethodSignatureImpl copy(@Nonnull HierarchicalMethodSignature hi) { + HierarchicalMethodSignatureImpl hierarchicalMethodSignature = new HierarchicalMethodSignatureImpl(hi); + for (HierarchicalMethodSignature his : hi.getSuperSignatures()) { + hierarchicalMethodSignature.addSuperSignature(copy(his)); } - } + return hierarchicalMethodSignature; } - return false; - } - - @Nonnull - private static HierarchicalMethodSignatureImpl copy(@Nonnull HierarchicalMethodSignature hi) { - HierarchicalMethodSignatureImpl hierarchicalMethodSignature = new HierarchicalMethodSignatureImpl(hi); - for (HierarchicalMethodSignature his : hi.getSuperSignatures()) { - hierarchicalMethodSignature.addSuperSignature(copy(his)); + + @Nonnull + public static Collection getVisibleSignatures(@Nonnull PsiClass aClass) { + Map map = getSignaturesMap(aClass); + return map.values(); } - return hierarchicalMethodSignature; - } - - @Nonnull - public static Collection getVisibleSignatures(@Nonnull PsiClass aClass) { - Map map = getSignaturesMap(aClass); - return map.values(); - } - - @Nonnull - public static HierarchicalMethodSignature getHierarchicalMethodSignature(@Nonnull final PsiMethod method) { - Project project = method.getProject(); - return CachedValuesManager.getManager(project).getParameterizedCachedValue(method, HIERARCHICAL_SIGNATURE_KEY, HIERARCHICAL_SIGNATURE_PROVIDER, false, method); - } - - private static final Key> HIERARCHICAL_SIGNATURE_KEY = Key.create("HierarchicalMethodSignature"); - private static final ParameterizedCachedValueProvider HIERARCHICAL_SIGNATURE_PROVIDER = new ParameterizedCachedValueProvider() { - @Override - public CachedValueProvider.Result compute(PsiMethod method) { - PsiClass aClass = method.getContainingClass(); - HierarchicalMethodSignature result = null; - if (aClass != null) { - result = SIGNATURES_BY_NAME_KEY.getValue(aClass).get(method.getName()).get(method.getSignature(PsiSubstitutor.EMPTY)); - } - if (result == null) { - result = new HierarchicalMethodSignatureImpl((MethodSignatureBackedByPsiMethod) method.getSignature(PsiSubstitutor.EMPTY)); - } - - if (!method.isPhysical() && !(method instanceof SyntheticElement) && !(method instanceof LightElement)) { - return CachedValueProvider.Result.create(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT, method); - } - return CachedValueProvider.Result.create(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); + + @Nonnull + public static HierarchicalMethodSignature getHierarchicalMethodSignature(@Nonnull final PsiMethod method) { + Project project = method.getProject(); + return CachedValuesManager.getManager(project) + .getParameterizedCachedValue(method, HIERARCHICAL_SIGNATURE_KEY, HIERARCHICAL_SIGNATURE_PROVIDER, false, method); } - }; - @Nonnull - private static Map getSignaturesMap(@Nonnull PsiClass aClass) { - return SIGNATURES_FOR_CLASS_KEY.getValue(aClass); - } + private static final Key> HIERARCHICAL_SIGNATURE_KEY = + Key.create("HierarchicalMethodSignature"); + private static final ParameterizedCachedValueProvider HIERARCHICAL_SIGNATURE_PROVIDER = + new ParameterizedCachedValueProvider() { + @Override + public CachedValueProvider.Result compute(PsiMethod method) { + PsiClass aClass = method.getContainingClass(); + HierarchicalMethodSignature result = null; + if (aClass != null) { + result = SIGNATURES_BY_NAME_KEY.getValue(aClass).get(method.getName()).get(method.getSignature(PsiSubstitutor.EMPTY)); + } + if (result == null) { + result = + new HierarchicalMethodSignatureImpl((MethodSignatureBackedByPsiMethod)method.getSignature(PsiSubstitutor.EMPTY)); + } + + if (!method.isPhysical() && !(method instanceof SyntheticElement) && !(method instanceof LightElement)) { + return CachedValueProvider.Result.create(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT, method); + } + return CachedValueProvider.Result.create(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); + } + }; + + @Nonnull + private static Map getSignaturesMap(@Nonnull PsiClass aClass) { + return SIGNATURES_FOR_CLASS_KEY.getValue(aClass); + } - // uses hierarchy signature tree if available, traverses class structure by itself otherwise - public static boolean processDirectSuperMethodsSmart(@Nonnull PsiMethod method, @Nonnull Processor superMethodProcessor) { - //boolean old = PsiSuperMethodUtil.isSuperMethod(method, superMethod); + // uses hierarchy signature tree if available, traverses class structure by itself otherwise + public static boolean processDirectSuperMethodsSmart(@Nonnull PsiMethod method, @Nonnull Processor superMethodProcessor) { + //boolean old = PsiSuperMethodUtil.isSuperMethod(method, superMethod); - PsiClass aClass = method.getContainingClass(); - if (aClass == null) { - return false; - } + PsiClass aClass = method.getContainingClass(); + if (aClass == null) { + return false; + } - if (!canHaveSuperMethod(method, true, false)) { - return false; - } + if (!canHaveSuperMethod(method, true, false)) { + return false; + } - Map cachedMap = SIGNATURES_BY_NAME_KEY.getValue(aClass).get(method.getName()); - HierarchicalMethodSignature signature = cachedMap.get(method.getSignature(PsiSubstitutor.EMPTY)); - if (signature != null) { - List superSignatures = signature.getSuperSignatures(); - for (HierarchicalMethodSignature superSignature : superSignatures) { - if (!superMethodProcessor.process(superSignature.getMethod())) { - return false; + Map cachedMap = SIGNATURES_BY_NAME_KEY.getValue(aClass).get(method.getName()); + HierarchicalMethodSignature signature = cachedMap.get(method.getSignature(PsiSubstitutor.EMPTY)); + if (signature != null) { + List superSignatures = signature.getSuperSignatures(); + for (HierarchicalMethodSignature superSignature : superSignatures) { + if (!superMethodProcessor.process(superSignature.getMethod())) { + return false; + } + } } - } + return true; } - return true; - } - // uses hierarchy signature tree if available, traverses class structure by itself otherwise - public static boolean isSuperMethodSmart(@Nonnull PsiMethod method, @Nonnull PsiMethod superMethod) { - //boolean old = PsiSuperMethodUtil.isSuperMethod(method, superMethod); + // uses hierarchy signature tree if available, traverses class structure by itself otherwise + public static boolean isSuperMethodSmart(@Nonnull PsiMethod method, @Nonnull PsiMethod superMethod) { + //boolean old = PsiSuperMethodUtil.isSuperMethod(method, superMethod); - if (method == superMethod) { - return false; - } - PsiClass aClass = method.getContainingClass(); - PsiClass superClass = superMethod.getContainingClass(); + if (method == superMethod) { + return false; + } + PsiClass aClass = method.getContainingClass(); + PsiClass superClass = superMethod.getContainingClass(); - if (aClass == null || superClass == null || superClass == aClass) { - return false; - } + if (aClass == null || superClass == null || superClass == aClass) { + return false; + } - if (!canHaveSuperMethod(method, true, false)) { - return false; - } + if (!canHaveSuperMethod(method, true, false)) { + return false; + } - Map cachedMap = SIGNATURES_BY_NAME_KEY.getValue(aClass).get(method.getName()); - HierarchicalMethodSignature signature = cachedMap.get(method.getSignature(PsiSubstitutor.EMPTY)); + Map cachedMap = SIGNATURES_BY_NAME_KEY.getValue(aClass).get(method.getName()); + HierarchicalMethodSignature signature = cachedMap.get(method.getSignature(PsiSubstitutor.EMPTY)); - for (PsiMethod superCandidate : MethodSignatureUtil.convertMethodSignaturesToMethods(signature.getSuperSignatures())) { - if (superMethod.equals(superCandidate) || isSuperMethodSmart(superCandidate, superMethod)) { - return true; - } + for (PsiMethod superCandidate : MethodSignatureUtil.convertMethodSignaturesToMethods(signature.getSuperSignatures())) { + if (superMethod.equals(superCandidate) || isSuperMethodSmart(superCandidate, superMethod)) { + return true; + } + } + return false; } - return false; - } } \ No newline at end of file diff --git a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/file/PsiPackageImpl.java b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/file/PsiPackageImpl.java index 5314c49a7..dc69f56fe 100644 --- a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/file/PsiPackageImpl.java +++ b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/file/PsiPackageImpl.java @@ -56,299 +56,309 @@ import java.util.Set; public class PsiPackageImpl extends PsiPackageBase implements PsiJavaPackage, Queryable { - private static final Logger LOGGER = Logger.getInstance(PsiPackageImpl.class); - - private volatile CachedValue myAnnotationList; - private volatile CachedValue> myDirectories; - private volatile SoftReference> myPublicClassNamesCache; - - public PsiPackageImpl(PsiManager manager, - PsiPackageManager packageManager, - Class extensionClass, - String qualifiedName) { - super(manager, packageManager, extensionClass, qualifiedName); - } - - @Override - protected Collection getAllDirectories(boolean includeLibrarySource) { - if (myDirectories == null) { - myDirectories = - CachedValuesManager.getManager(myManager.getProject()).createCachedValue(new CachedValueProvider>() { - @Override - public Result> compute() { - final CommonProcessors.CollectProcessor processor = new CommonProcessors.CollectProcessor(); - getFacade().processPackageDirectories(PsiPackageImpl.this, allScope(), processor); - return Result.create(processor.getResults(), - PsiPackageImplementationHelper.getInstance().getDirectoryCachedValueDependencies(PsiPackageImpl.this)); - } - }, false); + private static final Logger LOGGER = Logger.getInstance(PsiPackageImpl.class); + + private volatile CachedValue myAnnotationList; + private volatile CachedValue> myDirectories; + private volatile SoftReference> myPublicClassNamesCache; + + public PsiPackageImpl( + PsiManager manager, + PsiPackageManager packageManager, + Class extensionClass, + String qualifiedName + ) { + super(manager, packageManager, extensionClass, qualifiedName); } - return myDirectories.getValue(); - } - - @Override - public void handleQualifiedNameChange(@Nonnull final String newQualifiedName) { - PsiPackageImplementationHelper.getInstance().handleQualifiedNameChange(this, newQualifiedName); - } - - @Override - public VirtualFile[] occursInPackagePrefixes() { - return PsiPackageImplementationHelper.getInstance().occursInPackagePrefixes(this); - } - - @Override - public PsiPackageImpl getParentPackage() { - return (PsiPackageImpl)super.getParentPackage(); - } - - - @RequiredReadAction - @Override - @Nonnull - public Language getLanguage() { - return JavaLanguage.INSTANCE; - } - - @Override - public boolean isValid() { - return PsiPackageImplementationHelper.getInstance().packagePrefixExists(this) || !getAllDirectories(true).isEmpty(); - } - - @Override - public void accept(@Nonnull PsiElementVisitor visitor) { - if (visitor instanceof JavaElementVisitor) { - ((JavaElementVisitor)visitor).visitPackage(this); + + @Override + protected Collection getAllDirectories(boolean includeLibrarySource) { + if (myDirectories == null) { + myDirectories = + CachedValuesManager.getManager(myManager.getProject()) + .createCachedValue(new CachedValueProvider>() { + @Override + public Result> compute() { + final CommonProcessors.CollectProcessor processor = + new CommonProcessors.CollectProcessor(); + getFacade().processPackageDirectories(PsiPackageImpl.this, allScope(), processor); + return Result.create( + processor.getResults(), + PsiPackageImplementationHelper.getInstance().getDirectoryCachedValueDependencies(PsiPackageImpl.this) + ); + } + }, false); + } + return myDirectories.getValue(); } - else { - visitor.visitElement(this); + + @Override + public void handleQualifiedNameChange(@Nonnull final String newQualifiedName) { + PsiPackageImplementationHelper.getInstance().handleQualifiedNameChange(this, newQualifiedName); } - } - - public String toString() { - return "PsiJavaPackage:" + getQualifiedName(); - } - - @Override - @Nonnull - public PsiClass[] getClasses() { - return getClasses(allScope()); - } - - protected GlobalSearchScope allScope() { - return PsiPackageImplementationHelper.getInstance().adjustAllScope(this, GlobalSearchScope.allScope(getProject())); - } - - @Override - @Nonnull - public PsiClass[] getClasses(@Nonnull GlobalSearchScope scope) { - return getFacade().getClasses(this, scope); - } - - @Override - @Nonnull - public PsiFile[] getFiles(@Nonnull GlobalSearchScope scope) { - return getFacade().getPackageFiles(this, scope); - } - - @Override - @Nullable - public PsiModifierList getAnnotationList() { - if (myAnnotationList == null) { - myAnnotationList = - CachedValuesManager.getManager(myManager.getProject()).createCachedValue(new PackageAnnotationValueProvider(), false); + + @Override + public VirtualFile[] occursInPackagePrefixes() { + return PsiPackageImplementationHelper.getInstance().occursInPackagePrefixes(this); } - return myAnnotationList.getValue(); - } - - @Override - @Nonnull - public PsiJavaPackage[] getSubPackages() { - return getFacade().getSubPackages(this, allScope()); - } - - @Override - @Nonnull - public PsiJavaPackage[] getSubPackages(@Nonnull GlobalSearchScope scope) { - return getFacade().getSubPackages(this, scope); - } - - @Override - protected ArrayFactory getPackageArrayFactory() { - return PsiJavaPackage.ARRAY_FACTORY; - } - - private JavaPsiFacadeImpl getFacade() { - return (JavaPsiFacadeImpl)JavaPsiFacade.getInstance(myManager.getProject()); - } - - private Set getClassNamesCache() { - SoftReference> ref = myPublicClassNamesCache; - Set cache = ref == null ? null : ref.get(); - if (cache == null) { - GlobalSearchScope scope = allScope(); - - if (!scope.isForceSearchingInLibrarySources()) { - scope = new DelegatingGlobalSearchScope(scope) { - @Override - public boolean isForceSearchingInLibrarySources() { - return true; - } - }; - } - cache = getFacade().getClassNames(this, scope); - myPublicClassNamesCache = new SoftReference>(cache); + + @Override + public PsiPackageImpl getParentPackage() { + return (PsiPackageImpl)super.getParentPackage(); } - return cache; - } - - @Nonnull - private PsiClass[] findClassesByName(String name, GlobalSearchScope scope) { - final String qName = getQualifiedName(); - final String classQName = !qName.isEmpty() ? qName + "." + name : name; - return getFacade().findClasses(classQName, scope); - } - - @Override - public boolean containsClassNamed(String name) { - return getClassNamesCache().contains(name); - } - - @Nonnull - @Override - public PsiClass[] findClassByShortName(@Nonnull String name, @Nonnull GlobalSearchScope scope) { - return getFacade().findClassByShortName(name, this, scope); - } - - @Nullable - private PsiJavaPackage findSubPackageByName(String name) { - final String qName = getQualifiedName(); - final String subpackageQName = qName.isEmpty() ? name : qName + "." + name; - return getFacade().findPackage(subpackageQName); - } - - @Override - public boolean processDeclarations(@Nonnull PsiScopeProcessor processor, - @Nonnull ResolveState state, - PsiElement lastParent, - @Nonnull PsiElement place) { - GlobalSearchScope scope = place.getResolveScope(); - - processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, this); - ElementClassHint classHint = processor.getHint(ElementClassHint.KEY); - - final Condition nameCondition = processor.getHint(JavaCompletionHints.NAME_FILTER); - - NameHint providedNameHint = processor.getHint(NameHint.KEY); - final String providedName = providedNameHint == null ? null : providedNameHint.getName(state); - - if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.CLASS)) { - if (providedName != null) { - final PsiClass[] classes = findClassByShortName(providedName, scope); - if (!processClasses(processor, state, classes, Conditions.alwaysTrue())) { - return false; + + @RequiredReadAction + @Override + @Nonnull + public Language getLanguage() { + return JavaLanguage.INSTANCE; + } + + @Override + public boolean isValid() { + return PsiPackageImplementationHelper.getInstance().packagePrefixExists(this) || !getAllDirectories(true).isEmpty(); + } + + @Override + public void accept(@Nonnull PsiElementVisitor visitor) { + if (visitor instanceof JavaElementVisitor) { + ((JavaElementVisitor)visitor).visitPackage(this); } - } - else { - PsiClass[] classes = getClasses(scope); - if (!processClasses(processor, state, classes, nameCondition != null ? nameCondition : Conditions.alwaysTrue())) { - return false; + else { + visitor.visitElement(this); } - } } - if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.PACKAGE)) { - if (providedName != null) { - PsiPackage aPackage = findSubPackageByName(providedName); - if (aPackage != null) { - if (!processor.execute(aPackage, state)) { - return false; - } + + public String toString() { + return "PsiJavaPackage:" + getQualifiedName(); + } + + @Override + @Nonnull + public PsiClass[] getClasses() { + return getClasses(allScope()); + } + + protected GlobalSearchScope allScope() { + return PsiPackageImplementationHelper.getInstance().adjustAllScope(this, GlobalSearchScope.allScope(getProject())); + } + + @Override + @Nonnull + public PsiClass[] getClasses(@Nonnull GlobalSearchScope scope) { + return getFacade().getClasses(this, scope); + } + + @Override + @Nonnull + public PsiFile[] getFiles(@Nonnull GlobalSearchScope scope) { + return getFacade().getPackageFiles(this, scope); + } + + @Override + @Nullable + public PsiModifierList getAnnotationList() { + if (myAnnotationList == null) { + myAnnotationList = + CachedValuesManager.getManager(myManager.getProject()).createCachedValue(new PackageAnnotationValueProvider(), false); } - } - else { - PsiPackage[] packs = getSubPackages(scope); - for (PsiPackage pack : packs) { - final String packageName = pack.getName(); - if (packageName == null) { - continue; - } - if (!PsiNameHelper.getInstance(myManager.getProject()).isIdentifier(packageName, PsiUtil.getLanguageLevel(this))) { - continue; - } - if (!processor.execute(pack, state)) { - return false; - } + return myAnnotationList.getValue(); + } + + @Override + @Nonnull + public PsiJavaPackage[] getSubPackages() { + return getFacade().getSubPackages(this, allScope()); + } + + @Override + @Nonnull + public PsiJavaPackage[] getSubPackages(@Nonnull GlobalSearchScope scope) { + return getFacade().getSubPackages(this, scope); + } + + @Override + protected ArrayFactory getPackageArrayFactory() { + return PsiJavaPackage.ARRAY_FACTORY; + } + + private JavaPsiFacadeImpl getFacade() { + return (JavaPsiFacadeImpl)JavaPsiFacade.getInstance(myManager.getProject()); + } + + private Set getClassNamesCache() { + SoftReference> ref = myPublicClassNamesCache; + Set cache = ref == null ? null : ref.get(); + if (cache == null) { + GlobalSearchScope scope = allScope(); + + if (!scope.isForceSearchingInLibrarySources()) { + scope = new DelegatingGlobalSearchScope(scope) { + @Override + public boolean isForceSearchingInLibrarySources() { + return true; + } + }; + } + cache = getFacade().getClassNames(this, scope); + myPublicClassNamesCache = new SoftReference>(cache); } - } + + return cache; + } + + @Nonnull + private PsiClass[] findClassesByName(String name, GlobalSearchScope scope) { + final String qName = getQualifiedName(); + final String classQName = !qName.isEmpty() ? qName + "." + name : name; + return getFacade().findClasses(classQName, scope); + } + + @Override + public boolean containsClassNamed(String name) { + return getClassNamesCache().contains(name); + } + + @Nonnull + @Override + public PsiClass[] findClassByShortName(@Nonnull String name, @Nonnull GlobalSearchScope scope) { + return getFacade().findClassByShortName(name, this, scope); + } + + @Nullable + private PsiJavaPackage findSubPackageByName(String name) { + final String qName = getQualifiedName(); + final String subpackageQName = qName.isEmpty() ? name : qName + "." + name; + return getFacade().findPackage(subpackageQName); } - return true; - } - - private static boolean processClasses(@Nonnull PsiScopeProcessor processor, - @Nonnull ResolveState state, - @Nonnull PsiClass[] classes, - @Nonnull Condition nameCondition) { - for (PsiClass aClass : classes) { - String name = aClass.getName(); - if (name != null && nameCondition.value(name)) { - try { - if (!processor.execute(aClass, state)) { - return false; - } + + @Override + public boolean processDeclarations( + @Nonnull PsiScopeProcessor processor, + @Nonnull ResolveState state, + PsiElement lastParent, + @Nonnull PsiElement place + ) { + GlobalSearchScope scope = place.getResolveScope(); + + processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, this); + ElementClassHint classHint = processor.getHint(ElementClassHint.KEY); + + final Condition nameCondition = processor.getHint(JavaCompletionHints.NAME_FILTER); + + NameHint providedNameHint = processor.getHint(NameHint.KEY); + final String providedName = providedNameHint == null ? null : providedNameHint.getName(state); + + if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.CLASS)) { + if (providedName != null) { + final PsiClass[] classes = findClassByShortName(providedName, scope); + if (!processClasses(processor, state, classes, Conditions.alwaysTrue())) { + return false; + } + } + else { + PsiClass[] classes = getClasses(scope); + if (!processClasses(processor, state, classes, nameCondition != null ? nameCondition : Conditions.alwaysTrue())) { + return false; + } + } } - catch (ProcessCanceledException e) { - throw e; + if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.PACKAGE)) { + if (providedName != null) { + PsiPackage aPackage = findSubPackageByName(providedName); + if (aPackage != null) { + if (!processor.execute(aPackage, state)) { + return false; + } + } + } + else { + PsiPackage[] packs = getSubPackages(scope); + for (PsiPackage pack : packs) { + final String packageName = pack.getName(); + if (packageName == null) { + continue; + } + if (!PsiNameHelper.getInstance(myManager.getProject()).isIdentifier(packageName, PsiUtil.getLanguageLevel(this))) { + continue; + } + if (!processor.execute(pack, state)) { + return false; + } + } + } } - catch (Exception e) { - LOGGER.error(e); + return true; + } + + private static boolean processClasses( + @Nonnull PsiScopeProcessor processor, + @Nonnull ResolveState state, + @Nonnull PsiClass[] classes, + @Nonnull Condition nameCondition + ) { + for (PsiClass aClass : classes) { + String name = aClass.getName(); + if (name != null && nameCondition.value(name)) { + try { + if (!processor.execute(aClass, state)) { + return false; + } + } + catch (ProcessCanceledException e) { + throw e; + } + catch (Exception e) { + LOGGER.error(e); + } + } } - } + return true; } - return true; - } - @Override - public void navigate(final boolean requestFocus) { - PsiPackageImplementationHelper.getInstance().navigate(this, requestFocus); - } + @Override + public void navigate(final boolean requestFocus) { + PsiPackageImplementationHelper.getInstance().navigate(this, requestFocus); + } - private class PackageAnnotationValueProvider implements CachedValueProvider { - private final Object[] OOCB_DEPENDENCY = {PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT}; + private class PackageAnnotationValueProvider implements CachedValueProvider { + private final Object[] OOCB_DEPENDENCY = {PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT}; + + @Override + public Result compute() { + List list = new ArrayList(); + for (PsiDirectory directory : getDirectories()) { + PsiFile file = directory.findFile(PACKAGE_INFO_FILE); + if (file != null) { + PsiPackageStatement stmt = PsiTreeUtil.getChildOfType(file, PsiPackageStatement.class); + if (stmt != null) { + final PsiModifierList modifierList = stmt.getAnnotationList(); + if (modifierList != null) { + list.add(modifierList); + } + } + } + } - @Override - public Result compute() { - List list = new ArrayList(); - for (PsiDirectory directory : getDirectories()) { - PsiFile file = directory.findFile(PACKAGE_INFO_FILE); - if (file != null) { - PsiPackageStatement stmt = PsiTreeUtil.getChildOfType(file, PsiPackageStatement.class); - if (stmt != null) { - final PsiModifierList modifierList = stmt.getAnnotationList(); - if (modifierList != null) { - list.add(modifierList); + final JavaPsiFacade facade = getFacade(); + final GlobalSearchScope scope = allScope(); + for (PsiClass aClass : facade.findClasses(getQualifiedName() + ".package-info", scope)) { + ContainerUtil.addIfNotNull(list, aClass.getModifierList()); } - } + + return new Result(list.isEmpty() ? null : new PsiCompositeModifierList(getManager(), list), OOCB_DEPENDENCY); } - } + } - final JavaPsiFacade facade = getFacade(); - final GlobalSearchScope scope = allScope(); - for (PsiClass aClass : facade.findClasses(getQualifiedName() + ".package-info", scope)) { - ContainerUtil.addIfNotNull(list, aClass.getModifierList()); - } + @Override + @Nullable + public PsiModifierList getModifierList() { + return getAnnotationList(); + } - return new Result(list.isEmpty() ? null : new PsiCompositeModifierList(getManager(), list), OOCB_DEPENDENCY); + @Override + public boolean hasModifierProperty(@NonNls @Nonnull final String name) { + return false; } - } - - @Override - @Nullable - public PsiModifierList getModifierList() { - return getAnnotationList(); - } - - @Override - public boolean hasModifierProperty(@NonNls @Nonnull final String name) { - return false; - } } diff --git a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/source/PsiAnnotationMethodImpl.java b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/source/PsiAnnotationMethodImpl.java index 2d87cd4ad..5928d8274 100644 --- a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/source/PsiAnnotationMethodImpl.java +++ b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/source/PsiAnnotationMethodImpl.java @@ -33,66 +33,71 @@ * @author ven */ public class PsiAnnotationMethodImpl extends PsiMethodImpl implements PsiAnnotationMethod { - private SoftReference myCachedDefaultValue = null; + private SoftReference myCachedDefaultValue = null; - public PsiAnnotationMethodImpl(final PsiMethodStub stub) { - super(stub, JavaStubElementTypes.ANNOTATION_METHOD); - } + public PsiAnnotationMethodImpl(final PsiMethodStub stub) { + super(stub, JavaStubElementTypes.ANNOTATION_METHOD); + } - public PsiAnnotationMethodImpl(final ASTNode node) { - super(node); - } + public PsiAnnotationMethodImpl(final ASTNode node) { + super(node); + } - @Override - public boolean hasModifierProperty(@Nonnull String name) { - return PsiModifier.ABSTRACT.equals(name) || PsiModifier.PUBLIC.equals(name) || super.hasModifierProperty(name); - } + @Override + public boolean hasModifierProperty(@Nonnull String name) { + return PsiModifier.ABSTRACT.equals(name) || PsiModifier.PUBLIC.equals(name) || super.hasModifierProperty(name); + } - @Override - protected void dropCached() { - myCachedDefaultValue = null; - } + @Override + protected void dropCached() { + myCachedDefaultValue = null; + } - @Override - public PsiAnnotationMemberValue getDefaultValue() { - final PsiMethodStub stub = getStub(); - if (stub != null) { - final String text = stub.getDefaultValueText(); - if (StringUtil.isEmpty(text)) return null; + @Override + public PsiAnnotationMemberValue getDefaultValue() { + final PsiMethodStub stub = getStub(); + if (stub != null) { + final String text = stub.getDefaultValueText(); + if (StringUtil.isEmpty(text)) { + return null; + } - if (myCachedDefaultValue != null) { - final PsiAnnotationMemberValue value = myCachedDefaultValue.get(); - if (value != null) { - return value; - } - } + if (myCachedDefaultValue != null) { + final PsiAnnotationMemberValue value = myCachedDefaultValue.get(); + if (value != null) { + return value; + } + } - @NonNls final String annoText = "@interface _Dummy_ { Class foo() default " + text + "; }"; - final PsiFileFactory factory = PsiFileFactory.getInstance(getProject()); - final PsiJavaFile file = (PsiJavaFile) factory.createFileFromText("a.java", JavaFileType.INSTANCE, annoText); - final PsiAnnotationMemberValue value = ((PsiAnnotationMethod) file.getClasses()[0].getMethods()[0]).getDefaultValue(); - myCachedDefaultValue = new SoftReference(value); - return value; - } + @NonNls final String annoText = "@interface _Dummy_ { Class foo() default " + text + "; }"; + final PsiFileFactory factory = PsiFileFactory.getInstance(getProject()); + final PsiJavaFile file = (PsiJavaFile)factory.createFileFromText("a.java", JavaFileType.INSTANCE, annoText); + final PsiAnnotationMemberValue value = ((PsiAnnotationMethod)file.getClasses()[0].getMethods()[0]).getDefaultValue(); + myCachedDefaultValue = new SoftReference(value); + return value; + } - myCachedDefaultValue = null; + myCachedDefaultValue = null; - final ASTNode node = getNode().findChildByRole(ChildRole.ANNOTATION_DEFAULT_VALUE); - if (node == null) return null; - return (PsiAnnotationMemberValue) node.getPsi(); - } + final ASTNode node = getNode().findChildByRole(ChildRole.ANNOTATION_DEFAULT_VALUE); + if (node == null) { + return null; + } + return (PsiAnnotationMemberValue)node.getPsi(); + } - @NonNls - public String toString() { - return "PsiAnnotationMethod:" + getName(); - } + @NonNls + public String toString() { + return "PsiAnnotationMethod:" + getName(); + } - @Override - public final void accept(@Nonnull PsiElementVisitor visitor) { - if (visitor instanceof JavaElementVisitor) { - ((JavaElementVisitor) visitor).visitAnnotationMethod(this); - } else { - visitor.visitElement(this); + @Override + public final void accept(@Nonnull PsiElementVisitor visitor) { + if (visitor instanceof JavaElementVisitor) { + ((JavaElementVisitor)visitor).visitAnnotationMethod(this); + } + else { + visitor.visitElement(this); + } } - } } \ No newline at end of file diff --git a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/source/PsiMethodImpl.java b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/source/PsiMethodImpl.java index 4d7169a01..41ddbcc97 100644 --- a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/source/PsiMethodImpl.java +++ b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/source/PsiMethodImpl.java @@ -55,341 +55,345 @@ import java.util.stream.Stream; public class PsiMethodImpl extends JavaStubPsiElement implements PsiMethod, Queryable { - private SoftReference myCachedType; - - public PsiMethodImpl(final PsiMethodStub stub) { - this(stub, JavaStubElementTypes.METHOD); - } - - protected PsiMethodImpl(final PsiMethodStub stub, final IStubElementType type) { - super(stub, type); - } - - public PsiMethodImpl(final ASTNode node) { - super(node); - } - - @Override - public void subtreeChanged() { - super.subtreeChanged(); - dropCached(); - } - - protected void dropCached() { - myCachedType = null; - } - - @Override - protected Object clone() { - PsiMethodImpl clone = (PsiMethodImpl)super.clone(); - clone.dropCached(); - return clone; - } - - @Override - public PsiClass getContainingClass() { - PsiElement parent = getParent(); - return parent instanceof PsiClass ? (PsiClass)parent : PsiTreeUtil.getParentOfType(this, PsiSyntheticClass.class); - } - - @Override - public PsiElement getContext() { - final PsiClass cc = getContainingClass(); - return cc != null ? cc : super.getContext(); - } - - @Override - public PsiIdentifier getNameIdentifier() { - return (PsiIdentifier)getNode().findChildByRoleAsPsiElement(ChildRole.NAME); - } - - @Override - @Nonnull - public PsiMethod[] findSuperMethods() { - return PsiSuperMethodImplUtil.findSuperMethods(this); - } - - @Override - @Nonnull - public PsiMethod[] findSuperMethods(boolean checkAccess) { - return PsiSuperMethodImplUtil.findSuperMethods(this, checkAccess); - } - - @Override - @Nonnull - public PsiMethod[] findSuperMethods(PsiClass parentClass) { - return PsiSuperMethodImplUtil.findSuperMethods(this, parentClass); - } - - @Override - @Nonnull - public List findSuperMethodSignaturesIncludingStatic(boolean checkAccess) { - return PsiSuperMethodImplUtil.findSuperMethodSignaturesIncludingStatic(this, checkAccess); - } - - @Override - public PsiMethod findDeepestSuperMethod() { - return PsiSuperMethodImplUtil.findDeepestSuperMethod(this); - } - - @Override - @Nonnull - public PsiMethod[] findDeepestSuperMethods() { - return PsiSuperMethodImplUtil.findDeepestSuperMethods(this); - } - - @Override - @Nonnull - public String getName() { - final String name; - final PsiMethodStub stub = getGreenStub(); - if (stub != null) { - name = stub.getName(); - } - else { - final PsiIdentifier nameIdentifier = getNameIdentifier(); - name = nameIdentifier == null ? null : nameIdentifier.getText(); - } - - return name != null ? name : ""; - } - - @Override - @Nonnull - public HierarchicalMethodSignature getHierarchicalMethodSignature() { - return PsiSuperMethodImplUtil.getHierarchicalMethodSignature(this); - } - - @Override - public PsiElement setName(@Nonnull String name) throws IncorrectOperationException { - final PsiIdentifier identifier = getNameIdentifier(); - if (identifier == null) { - throw new IncorrectOperationException("Empty name: " + this); - } - PsiImplUtil.setName(identifier, name); - return this; - } - - @Override - public PsiTypeElement getReturnTypeElement() { - if (isConstructor()) { - return null; - } - return (PsiTypeElement)getNode().findChildByRoleAsPsiElement(ChildRole.TYPE); - } - - @Override - public PsiTypeParameterList getTypeParameterList() { - return getRequiredStubOrPsiChild(JavaStubElementTypes.TYPE_PARAMETER_LIST); - } - - @Override - public boolean hasTypeParameters() { - return PsiImplUtil.hasTypeParameters(this); - } - - @Override - @Nonnull - public PsiTypeParameter[] getTypeParameters() { - return PsiImplUtil.getTypeParameters(this); - } - - @Override - public PsiType getReturnType() { - if (isConstructor()) { - return null; - } - - PsiMethodStub stub = getStub(); - if (stub != null) { - PsiType type = SoftReference.dereference(myCachedType); - if (type == null) { - type = JavaSharedImplUtil.createTypeFromStub(this, stub.getReturnTypeText()); - myCachedType = new SoftReference<>(type); - } - return type; - } - - myCachedType = null; - PsiTypeElement typeElement = getReturnTypeElement(); - return typeElement != null ? JavaSharedImplUtil.getType(typeElement, getParameterList()) : null; - } - - @Override - @Nonnull - public PsiModifierList getModifierList() { - return getRequiredStubOrPsiChild(JavaStubElementTypes.MODIFIER_LIST); - } - - @Override - public boolean hasModifierProperty(@Nonnull String name) { - return getModifierList().hasModifierProperty(name); - } - - @Override - @Nonnull - public PsiParameterList getParameterList() { - PsiParameterList list = getStubOrPsiChild(JavaStubElementTypes.PARAMETER_LIST); - if (list == null) { - return LanguageCachedValueUtil.getCachedValue(this, () -> { - LightParameterListBuilder lightList = new LightParameterListBuilder(getManager(), getLanguage()) { - @Override - public String getText() { + private SoftReference myCachedType; + + public PsiMethodImpl(final PsiMethodStub stub) { + this(stub, JavaStubElementTypes.METHOD); + } + + protected PsiMethodImpl(final PsiMethodStub stub, final IStubElementType type) { + super(stub, type); + } + + public PsiMethodImpl(final ASTNode node) { + super(node); + } + + @Override + public void subtreeChanged() { + super.subtreeChanged(); + dropCached(); + } + + protected void dropCached() { + myCachedType = null; + } + + @Override + protected Object clone() { + PsiMethodImpl clone = (PsiMethodImpl)super.clone(); + clone.dropCached(); + return clone; + } + + @Override + public PsiClass getContainingClass() { + PsiElement parent = getParent(); + return parent instanceof PsiClass ? (PsiClass)parent : PsiTreeUtil.getParentOfType(this, PsiSyntheticClass.class); + } + + @Override + public PsiElement getContext() { + final PsiClass cc = getContainingClass(); + return cc != null ? cc : super.getContext(); + } + + @Override + public PsiIdentifier getNameIdentifier() { + return (PsiIdentifier)getNode().findChildByRoleAsPsiElement(ChildRole.NAME); + } + + @Override + @Nonnull + public PsiMethod[] findSuperMethods() { + return PsiSuperMethodImplUtil.findSuperMethods(this); + } + + @Override + @Nonnull + public PsiMethod[] findSuperMethods(boolean checkAccess) { + return PsiSuperMethodImplUtil.findSuperMethods(this, checkAccess); + } + + @Override + @Nonnull + public PsiMethod[] findSuperMethods(PsiClass parentClass) { + return PsiSuperMethodImplUtil.findSuperMethods(this, parentClass); + } + + @Override + @Nonnull + public List findSuperMethodSignaturesIncludingStatic(boolean checkAccess) { + return PsiSuperMethodImplUtil.findSuperMethodSignaturesIncludingStatic(this, checkAccess); + } + + @Override + public PsiMethod findDeepestSuperMethod() { + return PsiSuperMethodImplUtil.findDeepestSuperMethod(this); + } + + @Override + @Nonnull + public PsiMethod[] findDeepestSuperMethods() { + return PsiSuperMethodImplUtil.findDeepestSuperMethods(this); + } + + @Override + @Nonnull + public String getName() { + final String name; + final PsiMethodStub stub = getGreenStub(); + if (stub != null) { + name = stub.getName(); + } + else { + final PsiIdentifier nameIdentifier = getNameIdentifier(); + name = nameIdentifier == null ? null : nameIdentifier.getText(); + } + + return name != null ? name : ""; + } + + @Override + @Nonnull + public HierarchicalMethodSignature getHierarchicalMethodSignature() { + return PsiSuperMethodImplUtil.getHierarchicalMethodSignature(this); + } + + @Override + public PsiElement setName(@Nonnull String name) throws IncorrectOperationException { + final PsiIdentifier identifier = getNameIdentifier(); + if (identifier == null) { + throw new IncorrectOperationException("Empty name: " + this); + } + PsiImplUtil.setName(identifier, name); + return this; + } + + @Override + public PsiTypeElement getReturnTypeElement() { + if (isConstructor()) { return null; - } - }; - PsiClass aClass = getContainingClass(); - if (aClass != null) { - PsiRecordComponent[] recordComponents = aClass.getRecordComponents(); - for (PsiRecordComponent component : recordComponents) { - String name = component.getName(); - lightList.addParameter(new LightCompactConstructorParameter(name, component.getType(), this, component)); - } } + return (PsiTypeElement)getNode().findChildByRoleAsPsiElement(ChildRole.TYPE); + } - return CachedValueProvider.Result.create(lightList, this, PsiModificationTracker.MODIFICATION_COUNT); - }); + @Override + public PsiTypeParameterList getTypeParameterList() { + return getRequiredStubOrPsiChild(JavaStubElementTypes.TYPE_PARAMETER_LIST); } - return list; - } - @Override - @Nonnull - public PsiReferenceList getThrowsList() { - PsiReferenceList child = getStubOrPsiChild(JavaStubElementTypes.THROWS_LIST); - if (child != null) { - return child; + @Override + public boolean hasTypeParameters() { + return PsiImplUtil.hasTypeParameters(this); } - PsiMethodStub stub = getStub(); - Stream children = - stub != null ? stub.getChildrenStubs().stream().map(s -> s.getClass().getSimpleName() + " : " + s.getStubType()) : Stream.of( - getChildren()).map(e -> e.getClass() - .getSimpleName() + " : " + e.getNode().getElementType()); - throw new AssertionError("Missing throws list, file=" + getContainingFile() + " children:\n" + children.collect(Collectors.joining("\n"))); - } - - @Override - public PsiCodeBlock getBody() { - return (PsiCodeBlock)getNode().findChildByRoleAsPsiElement(ChildRole.METHOD_BODY); - } - - @Override - @Nonnull - public CompositeElement getNode() { - return (CompositeElement)super.getNode(); - } - - @Override - public boolean isDeprecated() { - final PsiMethodStub stub = getGreenStub(); - if (stub != null) { - return stub.isDeprecated() || stub.hasDeprecatedAnnotation() && PsiImplUtil.isDeprecatedByAnnotation(this); - } - - return PsiImplUtil.isDeprecatedByDocTag(this) || PsiImplUtil.isDeprecatedByAnnotation(this); - } - - @Override - public PsiDocComment getDocComment() { - final PsiMethodStub stub = getGreenStub(); - if (stub != null && !stub.hasDocComment()) { - return null; - } - - return (PsiDocComment)getNode().findChildByRoleAsPsiElement(ChildRole.DOC_COMMENT); - } - - @Override - public boolean isConstructor() { - final PsiMethodStub stub = getGreenStub(); - if (stub != null) { - return stub.isConstructor(); - } - - return getNode().findChildByRole(ChildRole.TYPE) == null; - } - - @Override - public boolean isVarArgs() { - final PsiMethodStub stub = getGreenStub(); - if (stub != null) { - return stub.isVarArgs(); - } - - return PsiImplUtil.isVarArgs(this); - } - - @Override - public void accept(@Nonnull PsiElementVisitor visitor) { - if (visitor instanceof JavaElementVisitor) { - ((JavaElementVisitor)visitor).visitMethod(this); - } - else { - visitor.visitElement(this); - } - } - - @Override - public String toString() { - return "PsiMethod:" + getName(); - } - - @Override - public boolean processDeclarations(@Nonnull PsiScopeProcessor processor, - @Nonnull ResolveState state, - PsiElement lastParent, - @Nonnull PsiElement place) { - return PsiImplUtil.processDeclarationsInMethod(this, processor, state, lastParent, place); - - } - - @Override - @Nonnull - public MethodSignature getSignature(@Nonnull PsiSubstitutor substitutor) { - if (substitutor == PsiSubstitutor.EMPTY) { - return LanguageCachedValueUtil.getCachedValue(this, () -> - { - MethodSignature signature = MethodSignatureBackedByPsiMethod.create(this, PsiSubstitutor.EMPTY); - return CachedValueProvider.Result.create(signature, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); - }); - } - return MethodSignatureBackedByPsiMethod.create(this, substitutor); - } - - @Override - public PsiElement getOriginalElement() { - final PsiClass containingClass = getContainingClass(); - if (containingClass != null) { - PsiElement original = containingClass.getOriginalElement(); - if (original != containingClass) { - final PsiMethod originalMethod = ((PsiClass)original).findMethodBySignature(this, false); - if (originalMethod != null) { - return originalMethod; + @Override + @Nonnull + public PsiTypeParameter[] getTypeParameters() { + return PsiImplUtil.getTypeParameters(this); + } + + @Override + public PsiType getReturnType() { + if (isConstructor()) { + return null; } - } - } - return this; - } - - @Override - public ItemPresentation getPresentation() { - return ItemPresentationProvider.getItemPresentation(this); - } - - @Override - public boolean isEquivalentTo(final PsiElement another) { - return PsiClassImplUtil.isMethodEquivalentTo(this, another); - } - - @Override - @Nonnull - public SearchScope getUseScope() { - return ApplicationManager.getApplication().runReadAction((Computable)() -> PsiImplUtil.getMemberUseScope(this)); - } - - @Override - public void putInfo(@Nonnull Map info) { - info.put("methodName", getName()); - } + + PsiMethodStub stub = getStub(); + if (stub != null) { + PsiType type = SoftReference.dereference(myCachedType); + if (type == null) { + type = JavaSharedImplUtil.createTypeFromStub(this, stub.getReturnTypeText()); + myCachedType = new SoftReference<>(type); + } + return type; + } + + myCachedType = null; + PsiTypeElement typeElement = getReturnTypeElement(); + return typeElement != null ? JavaSharedImplUtil.getType(typeElement, getParameterList()) : null; + } + + @Override + @Nonnull + public PsiModifierList getModifierList() { + return getRequiredStubOrPsiChild(JavaStubElementTypes.MODIFIER_LIST); + } + + @Override + public boolean hasModifierProperty(@Nonnull String name) { + return getModifierList().hasModifierProperty(name); + } + + @Override + @Nonnull + public PsiParameterList getParameterList() { + PsiParameterList list = getStubOrPsiChild(JavaStubElementTypes.PARAMETER_LIST); + if (list == null) { + return LanguageCachedValueUtil.getCachedValue(this, () -> { + LightParameterListBuilder lightList = new LightParameterListBuilder(getManager(), getLanguage()) { + @Override + public String getText() { + return null; + } + }; + PsiClass aClass = getContainingClass(); + if (aClass != null) { + PsiRecordComponent[] recordComponents = aClass.getRecordComponents(); + for (PsiRecordComponent component : recordComponents) { + String name = component.getName(); + lightList.addParameter(new LightCompactConstructorParameter(name, component.getType(), this, component)); + } + } + + return CachedValueProvider.Result.create(lightList, this, PsiModificationTracker.MODIFICATION_COUNT); + }); + } + return list; + } + + @Override + @Nonnull + public PsiReferenceList getThrowsList() { + PsiReferenceList child = getStubOrPsiChild(JavaStubElementTypes.THROWS_LIST); + if (child != null) { + return child; + } + + PsiMethodStub stub = getStub(); + Stream children = + stub != null ? stub.getChildrenStubs().stream().map(s -> s.getClass().getSimpleName() + " : " + s.getStubType()) : Stream.of( + getChildren()).map(e -> e.getClass() + .getSimpleName() + " : " + e.getNode().getElementType()); + throw new AssertionError( + "Missing throws list, file=" + getContainingFile() + " children:\n" + + children.collect(Collectors.joining("\n")) + ); + } + + @Override + public PsiCodeBlock getBody() { + return (PsiCodeBlock)getNode().findChildByRoleAsPsiElement(ChildRole.METHOD_BODY); + } + + @Override + @Nonnull + public CompositeElement getNode() { + return (CompositeElement)super.getNode(); + } + + @Override + public boolean isDeprecated() { + final PsiMethodStub stub = getGreenStub(); + if (stub != null) { + return stub.isDeprecated() || stub.hasDeprecatedAnnotation() && PsiImplUtil.isDeprecatedByAnnotation(this); + } + + return PsiImplUtil.isDeprecatedByDocTag(this) || PsiImplUtil.isDeprecatedByAnnotation(this); + } + + @Override + public PsiDocComment getDocComment() { + final PsiMethodStub stub = getGreenStub(); + if (stub != null && !stub.hasDocComment()) { + return null; + } + + return (PsiDocComment)getNode().findChildByRoleAsPsiElement(ChildRole.DOC_COMMENT); + } + + @Override + public boolean isConstructor() { + final PsiMethodStub stub = getGreenStub(); + if (stub != null) { + return stub.isConstructor(); + } + + return getNode().findChildByRole(ChildRole.TYPE) == null; + } + + @Override + public boolean isVarArgs() { + final PsiMethodStub stub = getGreenStub(); + if (stub != null) { + return stub.isVarArgs(); + } + + return PsiImplUtil.isVarArgs(this); + } + + @Override + public void accept(@Nonnull PsiElementVisitor visitor) { + if (visitor instanceof JavaElementVisitor) { + ((JavaElementVisitor)visitor).visitMethod(this); + } + else { + visitor.visitElement(this); + } + } + + @Override + public String toString() { + return "PsiMethod:" + getName(); + } + + @Override + public boolean processDeclarations( + @Nonnull PsiScopeProcessor processor, + @Nonnull ResolveState state, + PsiElement lastParent, + @Nonnull PsiElement place + ) { + return PsiImplUtil.processDeclarationsInMethod(this, processor, state, lastParent, place); + } + + @Override + @Nonnull + public MethodSignature getSignature(@Nonnull PsiSubstitutor substitutor) { + if (substitutor == PsiSubstitutor.EMPTY) { + return LanguageCachedValueUtil.getCachedValue(this, () -> + { + MethodSignature signature = MethodSignatureBackedByPsiMethod.create(this, PsiSubstitutor.EMPTY); + return CachedValueProvider.Result.create(signature, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); + }); + } + return MethodSignatureBackedByPsiMethod.create(this, substitutor); + } + + @Override + public PsiElement getOriginalElement() { + final PsiClass containingClass = getContainingClass(); + if (containingClass != null) { + PsiElement original = containingClass.getOriginalElement(); + if (original != containingClass) { + final PsiMethod originalMethod = ((PsiClass)original).findMethodBySignature(this, false); + if (originalMethod != null) { + return originalMethod; + } + } + } + return this; + } + + @Override + public ItemPresentation getPresentation() { + return ItemPresentationProvider.getItemPresentation(this); + } + + @Override + public boolean isEquivalentTo(final PsiElement another) { + return PsiClassImplUtil.isMethodEquivalentTo(this, another); + } + + @Override + @Nonnull + public SearchScope getUseScope() { + return ApplicationManager.getApplication().runReadAction((Computable)() -> PsiImplUtil.getMemberUseScope(this)); + } + + @Override + public void putInfo(@Nonnull Map info) { + info.put("methodName", getName()); + } } \ No newline at end of file diff --git a/plugin/src/main/java/com/intellij/java/impl/find/findUsages/JavaFindUsagesHandler.java b/plugin/src/main/java/com/intellij/java/impl/find/findUsages/JavaFindUsagesHandler.java index 8a5176b7a..e247bbb62 100644 --- a/plugin/src/main/java/com/intellij/java/impl/find/findUsages/JavaFindUsagesHandler.java +++ b/plugin/src/main/java/com/intellij/java/impl/find/findUsages/JavaFindUsagesHandler.java @@ -82,24 +82,59 @@ public AbstractFindUsagesDialog getFindUsagesDialog( ) { PsiElement element = getPsiElement(); if (element instanceof PsiPackage) { - return new FindPackageUsagesDialog(element, getProject(), myFactory.getFindPackageOptions(), - toShowInNewTab, mustOpenInNewTab, isSingleFile, this); + return new FindPackageUsagesDialog( + element, + getProject(), + myFactory.getFindPackageOptions(), + toShowInNewTab, + mustOpenInNewTab, + isSingleFile, + this + ); } if (element instanceof PsiClass) { - return new FindClassUsagesDialog(element, getProject(), myFactory.getFindClassOptions(), toShowInNewTab, - mustOpenInNewTab, isSingleFile, this); + return new FindClassUsagesDialog( + element, + getProject(), + myFactory.getFindClassOptions(), + toShowInNewTab, + mustOpenInNewTab, + isSingleFile, + this + ); } if (element instanceof PsiMethod) { - return new FindMethodUsagesDialog(element, getProject(), myFactory.getFindMethodOptions(), toShowInNewTab, - mustOpenInNewTab, isSingleFile, this); + return new FindMethodUsagesDialog( + element, + getProject(), + myFactory.getFindMethodOptions(), + toShowInNewTab, + mustOpenInNewTab, + isSingleFile, + this + ); } if (element instanceof PsiVariable) { - return new FindVariableUsagesDialog(element, getProject(), myFactory.getFindVariableOptions(), - toShowInNewTab, mustOpenInNewTab, isSingleFile, this); + return new FindVariableUsagesDialog( + element, + getProject(), + myFactory.getFindVariableOptions(), + toShowInNewTab, + mustOpenInNewTab, + isSingleFile, + this + ); } if (ThrowSearchUtil.isSearchable(element)) { - return new FindThrowUsagesDialog(element, getProject(), myFactory.getFindThrowOptions(), toShowInNewTab, - mustOpenInNewTab, isSingleFile, this); + return new FindThrowUsagesDialog( + element, + getProject(), + myFactory.getFindThrowOptions(), + toShowInNewTab, + mustOpenInNewTab, + isSingleFile, + this + ); } return super.getFindUsagesDialog(isSingleFile, toShowInNewTab, mustOpenInNewTab); } @@ -179,13 +214,21 @@ public PsiElement[] getSecondaryElements() { .variableNameToPropertyName(fieldName, VariableKind.FIELD); Set accessors = new HashSet<>(); boolean isStatic = field.isStatic(); - PsiMethod getter = PropertyUtil.findPropertyGetterWithType(propertyName, isStatic, field.getType(), - List.of(containingClass.getMethods()).iterator()); + PsiMethod getter = PropertyUtil.findPropertyGetterWithType( + propertyName, + isStatic, + field.getType(), + List.of(containingClass.getMethods()).iterator() + ); if (getter != null) { accessors.add(getter); } - PsiMethod setter = PropertyUtil.findPropertySetterWithType(propertyName, isStatic, field.getType(), - List.of(containingClass.getMethods()).iterator()); + PsiMethod setter = PropertyUtil.findPropertySetterWithType( + propertyName, + isStatic, + field.getType(), + List.of(containingClass.getMethods()).iterator() + ); if (setter != null) { accessors.add(setter); } @@ -253,8 +296,8 @@ public boolean processElementUsages( @Override protected boolean isSearchForTextOccurencesAvailable(@Nonnull PsiElement psiElement, boolean isSingleFile) { - return !isSingleFile && new JavaNonCodeSearchElementDescriptionProvider().getElementDescription(psiElement, - NonCodeSearchDescriptionLocation.NON_JAVA) != null; + return !isSingleFile && new JavaNonCodeSearchElementDescriptionProvider() + .getElementDescription(psiElement, NonCodeSearchDescriptionLocation.NON_JAVA) != null; } @Nonnull From dacb461b71ebbc9ff48b15f7087bac27646151ba Mon Sep 17 00:00:00 2001 From: UNV Date: Thu, 24 Apr 2025 23:12:36 +0300 Subject: [PATCH 2/2] Refactoring of callers of DefaultPsiElementFinderImpl.processPackageDirectories. --- .../java/language/psi/PsiElementFinder.java | 14 +- .../java/language/psi/util/PsiUtil.java | 823 +++++++++--------- .../impl/psi/NonClasspathClassFinder.java | 126 +-- .../psi/impl/DefaultPsiElementFinderImpl.java | 44 +- .../impl/psi/impl/JavaPsiFacadeImpl.java | 50 +- .../language/impl/psi/impl/PsiImplUtil.java | 311 ++++--- .../impl/psi/impl/PsiSuperMethodImplUtil.java | 83 +- .../impl/psi/impl/file/PsiPackageImpl.java | 95 +- .../impl/source/PsiAnnotationMethodImpl.java | 33 +- .../impl/psi/impl/source/PsiMethodImpl.java | 130 +-- 10 files changed, 901 insertions(+), 808 deletions(-) diff --git a/java-language-api/src/main/java/com/intellij/java/language/psi/PsiElementFinder.java b/java-language-api/src/main/java/com/intellij/java/language/psi/PsiElementFinder.java index 02856ecdd..ab5388fde 100644 --- a/java-language-api/src/main/java/com/intellij/java/language/psi/PsiElementFinder.java +++ b/java-language-api/src/main/java/com/intellij/java/language/psi/PsiElementFinder.java @@ -15,9 +15,9 @@ */ package com.intellij.java.language.psi; +import consulo.annotation.access.RequiredReadAction; import consulo.annotation.component.ComponentScope; import consulo.annotation.component.ExtensionAPI; -import consulo.application.util.function.Processor; import consulo.component.extension.ExtensionPointName; import consulo.language.psi.PsiDirectory; import consulo.language.psi.PsiFile; @@ -147,17 +147,19 @@ public PsiClass[] getClasses(@Nonnull PsiJavaPackage psiPackage, @Nonnull Global * A method to optimize resolve (to only search classes in a package which might be there) */ @Nonnull + @RequiredReadAction public Set getClassNames(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { return getClassNames(getClasses(psiPackage, scope)); } @Nonnull + @RequiredReadAction protected static Set getClassNames(@Nonnull PsiClass[] classes) { if (classes.length == 0) { return Collections.emptySet(); } - final HashSet names = new HashSet(); + HashSet names = new HashSet<>(); for (PsiClass aClass : classes) { ContainerUtil.addIfNotNull(names, aClass.getName()); } @@ -167,7 +169,7 @@ protected static Set getClassNames(@Nonnull PsiClass[] classes) { public boolean processPackageDirectories( @Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope, - @Nonnull Processor consumer + @Nonnull Predicate consumer ) { return processPackageDirectories(psiPackage, scope, consumer, false); } @@ -175,7 +177,7 @@ public boolean processPackageDirectories( public boolean processPackageDirectories( @Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope, - @Nonnull Processor consumer, + @Nonnull Predicate consumer, boolean includeLibrarySources ) { return true; @@ -191,6 +193,7 @@ public boolean processPackageDirectories( * @see PsiJavaPackage#getClasses(GlobalSearchScope) */ @Nonnull + @RequiredReadAction public PsiClass[] getClasses(@Nullable String className, @Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { PsiClass[] allClasses = getClasses(psiPackage, scope); if (className == null) { @@ -200,6 +203,7 @@ public PsiClass[] getClasses(@Nullable String className, @Nonnull PsiJavaPackage } @Nonnull + @RequiredReadAction public static PsiClass[] filterByName(@Nonnull String className, @Nonnull PsiClass[] classes) { if (classes.length == 0) { return PsiClass.EMPTY_ARRAY; @@ -207,7 +211,7 @@ public static PsiClass[] filterByName(@Nonnull String className, @Nonnull PsiCla if (classes.length == 1) { return className.equals(classes[0].getName()) ? classes : PsiClass.EMPTY_ARRAY; } - List foundClasses = new SmartList(); + List foundClasses = new SmartList<>(); for (PsiClass psiClass : classes) { if (className.equals(psiClass.getName())) { foundClasses.add(psiClass); diff --git a/java-language-api/src/main/java/com/intellij/java/language/psi/util/PsiUtil.java b/java-language-api/src/main/java/com/intellij/java/language/psi/util/PsiUtil.java index 169bf1b81..501c2f124 100644 --- a/java-language-api/src/main/java/com/intellij/java/language/psi/util/PsiUtil.java +++ b/java-language-api/src/main/java/com/intellij/java/language/psi/util/PsiUtil.java @@ -26,6 +26,7 @@ import com.intellij.java.language.psi.infos.MethodCandidateInfo.ApplicabilityLevel; import com.intellij.java.language.psi.javadoc.PsiDocComment; import consulo.annotation.access.RequiredReadAction; +import consulo.annotation.access.RequiredWriteAction; import consulo.document.util.TextRange; import consulo.java.language.module.extension.JavaModuleExtension; import consulo.java.language.module.util.JavaClassNames; @@ -54,7 +55,6 @@ import jakarta.annotation.Nullable; import org.intellij.lang.annotations.MagicConstant; import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NonNls; import java.util.*; import java.util.function.Predicate; @@ -70,8 +70,8 @@ public final class PsiUtil extends PsiUtilCore { public static final int ACCESS_LEVEL_PRIVATE = 1; public static final Key VALID_VOID_TYPE_IN_CODE_FRAGMENT = Key.create("VALID_VOID_TYPE_IN_CODE_FRAGMENT"); - - private static final Set IGNORED_NAMES = Set.of("ignore", + private static final Set IGNORED_NAMES = Set.of( + "ignore", "ignore1", "ignore2", "ignore3", @@ -82,24 +82,25 @@ public final class PsiUtil extends PsiUtilCore { "ignored2", "ignored3", "ignored4", - "ignored5"); + "ignored5" + ); private PsiUtil() { } public static boolean isOnAssignmentLeftHand(@Nonnull PsiExpression expr) { PsiElement parent = PsiTreeUtil.skipParentsOfType(expr, PsiParenthesizedExpression.class); - return parent instanceof PsiAssignmentExpression && PsiTreeUtil.isAncestor(((PsiAssignmentExpression) parent).getLExpression(), - expr, - false); + return parent instanceof PsiAssignmentExpression assignment + && PsiTreeUtil.isAncestor(assignment.getLExpression(), expr, false); } public static boolean isAccessibleFromPackage(@Nonnull PsiModifierListOwner element, @Nonnull PsiJavaPackage aPackage) { + //noinspection SimplifiableIfStatement if (element.hasModifierProperty(PsiModifier.PUBLIC)) { return true; } - return !element.hasModifierProperty(PsiModifier.PRIVATE) && JavaPsiFacade.getInstance(element.getProject()) - .isInPackage(element, aPackage); + return !element.hasModifierProperty(PsiModifier.PRIVATE) + && JavaPsiFacade.getInstance(element.getProject()).isInPackage(element, aPackage); } public static boolean isAccessedForWriting(@Nonnull PsiExpression expr) { @@ -107,12 +108,12 @@ public static boolean isAccessedForWriting(@Nonnull PsiExpression expr) { return true; } PsiElement parent = PsiTreeUtil.skipParentsOfType(expr, PsiParenthesizedExpression.class); - if (parent instanceof PsiPrefixExpression) { - IElementType tokenType = ((PsiPrefixExpression) parent).getOperationTokenType(); + if (parent instanceof PsiPrefixExpression prefixExpr) { + IElementType tokenType = prefixExpr.getOperationTokenType(); return tokenType == JavaTokenType.PLUSPLUS || tokenType == JavaTokenType.MINUSMINUS; } - else if (parent instanceof PsiPostfixExpression) { - IElementType tokenType = ((PsiPostfixExpression) parent).getOperationTokenType(); + else if (parent instanceof PsiPostfixExpression postfixExpr) { + IElementType tokenType = postfixExpr.getOperationTokenType(); return tokenType == JavaTokenType.PLUSPLUS || tokenType == JavaTokenType.MINUSMINUS; } else { @@ -122,20 +123,21 @@ else if (parent instanceof PsiPostfixExpression) { public static boolean isAccessedForReading(@Nonnull PsiExpression expr) { PsiElement parent = PsiTreeUtil.skipParentsOfType(expr, PsiParenthesizedExpression.class); - return !(parent instanceof PsiAssignmentExpression) || !PsiTreeUtil.isAncestor(((PsiAssignmentExpression) parent).getLExpression(), - expr, - false) || ((PsiAssignmentExpression) parent) - .getOperationTokenType() != JavaTokenType.EQ; + return !(parent instanceof PsiAssignmentExpression assignment) + || !PsiTreeUtil.isAncestor(assignment.getLExpression(), expr, false) + || assignment.getOperationTokenType() != JavaTokenType.EQ; } public static boolean isAccessible(@Nonnull PsiMember member, @Nonnull PsiElement place, @Nullable PsiClass accessObjectClass) { return isAccessible(place.getProject(), member, place, accessObjectClass); } - public static boolean isAccessible(@Nonnull Project project, - @Nonnull PsiMember member, - @Nonnull PsiElement place, - @Nullable PsiClass accessObjectClass) { + public static boolean isAccessible( + @Nonnull Project project, + @Nonnull PsiMember member, + @Nonnull PsiElement place, + @Nullable PsiClass accessObjectClass + ) { return JavaPsiFacade.getInstance(project).getResolveHelper().isAccessible(member, place, accessObjectClass); } @@ -145,17 +147,15 @@ public static JavaResolveResult getAccessObjectClass(@Nonnull PsiExpression expr return JavaResolveResult.EMPTY; } PsiType type = expression.getType(); - if (type instanceof PsiClassType) { - return ((PsiClassType) type).resolveGenerics(); + if (type instanceof PsiClassType classType) { + return classType.resolveGenerics(); } - if (type instanceof PsiDisjunctionType) { - final PsiType lub = ((PsiDisjunctionType) type).getLeastUpperBound(); - if (lub instanceof PsiClassType) { - return ((PsiClassType) lub).resolveGenerics(); - } + if (type instanceof PsiDisjunctionType disjunctionType + && disjunctionType.getLeastUpperBound() instanceof PsiClassType lub) { + return lub.resolveGenerics(); } - if (type == null && expression instanceof PsiReferenceExpression) { - JavaResolveResult resolveResult = ((PsiReferenceExpression) expression).advancedResolve(false); + if (type == null && expression instanceof PsiReferenceExpression refExpr) { + JavaResolveResult resolveResult = refExpr.advancedResolve(false); if (resolveResult.getElement() instanceof PsiClass) { return resolveResult; } @@ -173,18 +173,20 @@ public static boolean isConstantExpression(@Nullable PsiExpression expression) { } // todo: move to PsiThrowsList? - public static void addException(@Nonnull PsiMethod method, @Nonnull @NonNls String exceptionFQName) throws IncorrectOperationException { + @RequiredWriteAction + public static void addException(@Nonnull PsiMethod method, @Nonnull String exceptionFQName) throws IncorrectOperationException { PsiClass exceptionClass = JavaPsiFacade.getInstance(method.getProject()).findClass(exceptionFQName, method.getResolveScope()); addException(method, exceptionClass, exceptionFQName); } + @RequiredWriteAction public static void addException(@Nonnull PsiMethod method, @Nonnull PsiClass exceptionClass) throws IncorrectOperationException { addException(method, exceptionClass, exceptionClass.getQualifiedName()); } - private static void addException(@Nonnull PsiMethod method, - @Nullable PsiClass exceptionClass, - @Nullable String exceptionName) throws IncorrectOperationException { + @RequiredWriteAction + private static void addException(@Nonnull PsiMethod method, @Nullable PsiClass exceptionClass, @Nullable String exceptionName) + throws IncorrectOperationException { assert exceptionClass != null || exceptionName != null : "One of exceptionName, exceptionClass must be not null"; PsiReferenceList throwsList = method.getThrowsList(); PsiJavaCodeReferenceElement[] refs = throwsList.getReferenceElements(); @@ -193,7 +195,7 @@ private static void addException(@Nonnull PsiMethod method, if (ref.isReferenceTo(exceptionClass)) { return; } - PsiClass aClass = (PsiClass) ref.resolve(); + PsiClass aClass = (PsiClass)ref.resolve(); if (exceptionClass == null || aClass == null) { continue; } @@ -236,7 +238,8 @@ else if (exceptionClass.isInheritor(aClass, true)) { } // todo: move to PsiThrowsList? - public static void removeException(@Nonnull PsiMethod method, @NonNls String exceptionClass) throws IncorrectOperationException { + @RequiredWriteAction + public static void removeException(@Nonnull PsiMethod method, String exceptionClass) throws IncorrectOperationException { PsiJavaCodeReferenceElement[] refs = method.getThrowsList().getReferenceElements(); for (PsiJavaCodeReferenceElement ref : refs) { if (ref.getCanonicalText().equals(exceptionClass)) { @@ -264,19 +267,19 @@ public static PsiElement getTopLevelEnclosingCodeBlock(@Nullable PsiElement elem blockSoFar = element; } - if (parent instanceof PsiMethod && parent.getParent() instanceof PsiClass && !isLocalOrAnonymousClass((PsiClass) parent.getParent())) { + if (parent instanceof PsiMethod && parent.getParent() instanceof PsiClass psiClass && !isLocalOrAnonymousClass(psiClass)) { break; } if (parent instanceof PsiClassInitializer && !(parent.getParent() instanceof PsiAnonymousClass)) { break; } - if (parent instanceof PsiField && ((PsiField) parent).getInitializer() == element) { + if (parent instanceof PsiField field && field.getInitializer() == element) { blockSoFar = element; } if (parent instanceof PsiClassLevelDeclarationStatement) { parent = parent.getParent(); } - if (element instanceof PsiClass && !isLocalOrAnonymousClass((PsiClass) element)) { + if (element instanceof PsiClass psiClass && !isLocalOrAnonymousClass(psiClass)) { break; } if (element instanceof PsiFile && PsiUtilCore.getTemplateLanguageFile(element) != null) { @@ -311,57 +314,58 @@ public static boolean isAbstractClass(@Nonnull PsiClass clazz) { @Nullable public static PsiElement getVariableCodeBlock(@Nonnull PsiVariable variable, @Nullable PsiElement context) { PsiElement codeBlock = null; - if (variable instanceof PsiParameter) { - PsiElement declarationScope = ((PsiParameter) variable).getDeclarationScope(); - if (declarationScope instanceof PsiCatchSection) { - codeBlock = ((PsiCatchSection) declarationScope).getCatchBlock(); + if (variable instanceof PsiParameter param) { + PsiElement declarationScope = param.getDeclarationScope(); + if (declarationScope instanceof PsiCatchSection catchSection) { + codeBlock = catchSection.getCatchBlock(); } - else if (declarationScope instanceof PsiForeachStatement) { - codeBlock = ((PsiForeachStatement) declarationScope).getBody(); + else if (declarationScope instanceof PsiForeachStatement foreachStmt) { + codeBlock = foreachStmt.getBody(); } - else if (declarationScope instanceof PsiMethod) { - codeBlock = ((PsiMethod) declarationScope).getBody(); + else if (declarationScope instanceof PsiMethod method) { + codeBlock = method.getBody(); } - else if (declarationScope instanceof PsiLambdaExpression) { - codeBlock = ((PsiLambdaExpression) declarationScope).getBody(); + else if (declarationScope instanceof PsiLambdaExpression lambda) { + codeBlock = lambda.getBody(); } } else if (variable instanceof PsiResourceVariable) { - final PsiElement resourceList = variable.getParent(); + PsiElement resourceList = variable.getParent(); return resourceList != null ? resourceList.getParent() : null; // use try statement as topmost } else if (variable instanceof PsiLocalVariable && variable.getParent() instanceof PsiForStatement) { return variable.getParent(); } - else if (variable instanceof PsiField && context != null) { - final PsiClass aClass = ((PsiField) variable).getContainingClass(); + else if (variable instanceof PsiField field && context != null) { + PsiClass aClass = field.getContainingClass(); while (context != null && context.getParent() != aClass) { context = context.getParent(); if (context instanceof PsiClassLevelDeclarationStatement) { return null; } } - return context instanceof PsiMethod ? ((PsiMethod) context).getBody() : context instanceof PsiClassInitializer ? ((PsiClassInitializer) context).getBody() : null; + return context instanceof PsiMethod method ? method.getBody() + : context instanceof PsiClassInitializer classInitializer ? classInitializer.getBody() : null; } else { - final PsiElement scope = variable.getParent() == null ? null : variable.getParent().getParent(); + PsiElement scope = variable.getParent() == null ? null : variable.getParent().getParent(); codeBlock = getTopLevelEnclosingCodeBlock(variable, scope); - if (codeBlock != null && codeBlock.getParent() instanceof PsiSwitchStatement) { - codeBlock = codeBlock.getParent().getParent(); + if (codeBlock != null && codeBlock.getParent() instanceof PsiSwitchStatement switchStmt) { + codeBlock = switchStmt.getParent(); } } return codeBlock; } public static boolean isIncrementDecrementOperation(@Nonnull PsiElement element) { - if (element instanceof PsiPostfixExpression) { - final IElementType sign = ((PsiPostfixExpression) element).getOperationTokenType(); + if (element instanceof PsiPostfixExpression postfixExpr) { + IElementType sign = postfixExpr.getOperationTokenType(); if (sign == JavaTokenType.PLUSPLUS || sign == JavaTokenType.MINUSMINUS) { return true; } } - else if (element instanceof PsiPrefixExpression) { - final IElementType sign = ((PsiPrefixExpression) element).getOperationTokenType(); + else if (element instanceof PsiPrefixExpression prefixExpr) { + IElementType sign = prefixExpr.getOperationTokenType(); if (sign == JavaTokenType.PLUSPLUS || sign == JavaTokenType.MINUSMINUS) { return true; } @@ -369,19 +373,20 @@ else if (element instanceof PsiPrefixExpression) { return false; } + @RequiredReadAction public static List getSwitchResultExpressions(PsiSwitchExpression switchExpression) { PsiCodeBlock body = switchExpression.getBody(); if (body != null) { List result = new ArrayList<>(); PsiStatement[] statements = body.getStatements(); for (PsiStatement statement : statements) { - if (statement instanceof PsiSwitchLabeledRuleStatement) { - PsiStatement ruleBody = ((PsiSwitchLabeledRuleStatement) statement).getBody(); - if (ruleBody instanceof PsiExpressionStatement) { - result.add(((PsiExpressionStatement) ruleBody).getExpression()); + if (statement instanceof PsiSwitchLabeledRuleStatement switchLabeledRuleStmt) { + PsiStatement ruleBody = switchLabeledRuleStmt.getBody(); + if (ruleBody instanceof PsiExpressionStatement ruleBodyStmt) { + result.add(ruleBodyStmt.getExpression()); } - else if (ruleBody instanceof PsiBlockStatement) { - collectSwitchResultExpressions(result, ruleBody); + else if (ruleBody instanceof PsiBlockStatement blockStmt) { + collectSwitchResultExpressions(result, blockStmt); } } else { @@ -393,6 +398,7 @@ else if (ruleBody instanceof PsiBlockStatement) { return Collections.emptyList(); } + @RequiredReadAction private static void collectSwitchResultExpressions(@Nonnull List result, @Nonnull PsiElement container) { List yields = new ArrayList<>(); addStatements(yields, container, PsiYieldStatement.class, element -> element instanceof PsiSwitchExpression); @@ -427,7 +433,7 @@ public static int getAccessLevel(@Nonnull PsiModifierList modifierList) { @PsiModifier.ModifierConstant @Nullable public static String getAccessModifier(@AccessLevel int accessLevel) { - @SuppressWarnings("UnnecessaryLocalVariable") @PsiModifier.ModifierConstant final String modifier = + @SuppressWarnings("UnnecessaryLocalVariable") @PsiModifier.ModifierConstant String modifier = accessLevel > accessModifiers.length ? null : accessModifiers[accessLevel - 1]; return modifier; } @@ -445,16 +451,16 @@ public static String getAccessModifier(@AccessLevel int accessLevel) { public static boolean isStatement(@Nonnull PsiElement element) { PsiElement parent = element.getParent(); - if (element instanceof PsiExpressionListStatement) { + if (element instanceof PsiExpressionListStatement exprListStmt) { // statement list allowed in for() init or update only if (!(parent instanceof PsiForStatement)) { return false; } - PsiForStatement forStatement = (PsiForStatement) parent; - if (!(element == forStatement.getInitialization() || element == forStatement.getUpdate())) { + PsiForStatement forStatement = (PsiForStatement)parent; + if (!(exprListStmt == forStatement.getInitialization() || exprListStmt == forStatement.getUpdate())) { return false; } - PsiExpressionList expressionList = ((PsiExpressionListStatement) element).getExpressionList(); + PsiExpressionList expressionList = exprListStmt.getExpressionList(); for (PsiExpression expression : expressionList.getExpressions()) { if (!isStatement(expression)) { return false; @@ -463,9 +469,10 @@ public static boolean isStatement(@Nonnull PsiElement element) { return true; } - if (element instanceof PsiExpressionStatement) { - return parent instanceof PsiSwitchLabeledRuleStatement && ((PsiSwitchLabeledRuleStatement) parent).getEnclosingSwitchBlock() instanceof PsiSwitchExpression || - isStatement(((PsiExpressionStatement) element).getExpression()); + if (element instanceof PsiExpressionStatement exprStmt) { + return parent instanceof PsiSwitchLabeledRuleStatement switchLabeledRuleStmt + && switchLabeledRuleStmt.getEnclosingSwitchBlock() instanceof PsiSwitchExpression + || isStatement(exprStmt.getExpression()); } if (element instanceof PsiDeclarationStatement) { @@ -475,7 +482,7 @@ public static boolean isStatement(@Nonnull PsiElement element) { if (parent instanceof PsiCodeFragment) { return true; } - if (!(parent instanceof PsiForStatement) || ((PsiForStatement) parent).getBody() == element) { + if (!(parent instanceof PsiForStatement forStmt && forStmt.getBody() != element)) { return false; } } @@ -492,8 +499,8 @@ public static boolean isStatement(@Nonnull PsiElement element) { if (element instanceof PsiMethodCallExpression) { return true; } - if (element instanceof PsiNewExpression) { - return !(((PsiNewExpression) element).getType() instanceof PsiArrayType); + if (element instanceof PsiNewExpression newExpr) { + return !(newExpr.getType() instanceof PsiArrayType); } return element instanceof PsiCodeBlock; @@ -512,6 +519,7 @@ public static PsiElement getEnclosingStatement(PsiElement element) { @Nullable + @RequiredReadAction public static PsiElement getElementInclusiveRange(@Nonnull PsiElement scope, @Nonnull TextRange range) { PsiElement psiElement = scope.findElementAt(range.getStartOffset()); while (psiElement != null && !psiElement.getTextRange().contains(range)) { @@ -525,49 +533,41 @@ public static PsiElement getElementInclusiveRange(@Nonnull PsiElement scope, @No @Nullable public static PsiClass resolveClassInType(@Nullable PsiType type) { - if (type instanceof PsiClassType) { - return ((PsiClassType) type).resolve(); + if (type instanceof PsiClassType classType) { + return classType.resolve(); } - if (type instanceof PsiArrayType) { - return resolveClassInType(((PsiArrayType) type).getComponentType()); + if (type instanceof PsiArrayType arrayType) { + return resolveClassInType(arrayType.getComponentType()); } - if (type instanceof PsiDisjunctionType) { - final PsiType lub = ((PsiDisjunctionType) type).getLeastUpperBound(); - if (lub instanceof PsiClassType) { - return ((PsiClassType) lub).resolve(); - } + if (type instanceof PsiDisjunctionType disjunctionType && disjunctionType.getLeastUpperBound() instanceof PsiClassType lub) { + return lub.resolve(); } return null; } @Nullable public static PsiClass resolveClassInClassTypeOnly(@Nullable PsiType type) { - return type instanceof PsiClassType ? ((PsiClassType) type).resolve() : null; + return type instanceof PsiClassType classType ? classType.resolve() : null; } public static PsiClassType.ClassResolveResult resolveGenericsClassInType(@Nullable PsiType type) { - if (type instanceof PsiClassType) { - final PsiClassType classType = (PsiClassType) type; + if (type instanceof PsiClassType classType) { return classType.resolveGenerics(); } - if (type instanceof PsiArrayType) { - return resolveGenericsClassInType(((PsiArrayType) type).getComponentType()); + if (type instanceof PsiArrayType arrayType) { + return resolveGenericsClassInType(arrayType.getComponentType()); } - if (type instanceof PsiDisjunctionType) { - final PsiType lub = ((PsiDisjunctionType) type).getLeastUpperBound(); - if (lub instanceof PsiClassType) { - return ((PsiClassType) lub).resolveGenerics(); - } + if (type instanceof PsiDisjunctionType disjunctionType && disjunctionType.getLeastUpperBound() instanceof PsiClassType lub) { + return lub.resolveGenerics(); } return PsiClassType.ClassResolveResult.EMPTY; } @Nonnull public static PsiType convertAnonymousToBaseType(@Nonnull PsiType type) { - PsiClass psiClass = resolveClassInType(type); - if (psiClass instanceof PsiAnonymousClass) { + if (resolveClassInType(type) instanceof PsiAnonymousClass aClass) { int dims = type.getArrayDimensions(); - type = ((PsiAnonymousClass) psiClass).getBaseClassType(); + type = aClass.getBaseClassType(); while (dims != 0) { type = type.createArrayType(); dims--; @@ -576,78 +576,96 @@ public static PsiType convertAnonymousToBaseType(@Nonnull PsiType type) { return type; } - public static boolean isApplicable(@Nonnull PsiMethod method, - @Nonnull PsiSubstitutor substitutorForMethod, - @Nonnull PsiExpressionList argList) { + @RequiredReadAction + public static boolean isApplicable( + @Nonnull PsiMethod method, + @Nonnull PsiSubstitutor substitutorForMethod, + @Nonnull PsiExpressionList argList + ) { return getApplicabilityLevel(method, substitutorForMethod, argList) != ApplicabilityLevel.NOT_APPLICABLE; } - public static boolean isApplicable(@Nonnull PsiMethod method, - @Nonnull PsiSubstitutor substitutorForMethod, - @Nonnull PsiExpression[] argList) { - final PsiType[] types = ContainerUtil.map2Array(argList, PsiType.class, PsiExpression.EXPRESSION_TO_TYPE); + @RequiredReadAction + public static boolean isApplicable( + @Nonnull PsiMethod method, + @Nonnull PsiSubstitutor substitutorForMethod, + @Nonnull PsiExpression[] argList + ) { + PsiType[] types = ContainerUtil.map2Array(argList, PsiType.class, PsiExpression.EXPRESSION_TO_TYPE); return getApplicabilityLevel(method, substitutorForMethod, types, getLanguageLevel(method)) != ApplicabilityLevel.NOT_APPLICABLE; } @MethodCandidateInfo.ApplicabilityLevelConstant - public static int getApplicabilityLevel(@Nonnull PsiMethod method, - @Nonnull PsiSubstitutor substitutorForMethod, - @Nonnull PsiExpressionList argList) { + @RequiredReadAction + public static int getApplicabilityLevel( + @Nonnull PsiMethod method, + @Nonnull PsiSubstitutor substitutorForMethod, + @Nonnull PsiExpressionList argList + ) { return getApplicabilityLevel(method, substitutorForMethod, argList.getExpressionTypes(), getLanguageLevel(argList)); } @MethodCandidateInfo.ApplicabilityLevelConstant - public static int getApplicabilityLevel(@Nonnull final PsiMethod method, - @Nonnull final PsiSubstitutor substitutorForMethod, - @Nonnull final PsiType[] args, - @Nonnull final LanguageLevel languageLevel) { + @RequiredReadAction + public static int getApplicabilityLevel( + @Nonnull PsiMethod method, + @Nonnull PsiSubstitutor substitutorForMethod, + @Nonnull PsiType[] args, + @Nonnull LanguageLevel languageLevel + ) { return getApplicabilityLevel(method, substitutorForMethod, args, languageLevel, true, true); } - public interface ApplicabilityChecker { - ApplicabilityChecker ASSIGNABILITY_CHECKER = new ApplicabilityChecker() { - @Override - public boolean isApplicable(PsiType left, PsiType right, boolean allowUncheckedConversion, int argId) { - return TypeConversionUtil.isAssignable(left, right, allowUncheckedConversion); - } - }; + ApplicabilityChecker ASSIGNABILITY_CHECKER = + (left, right, allowUncheckedConversion, argId) -> TypeConversionUtil.isAssignable(left, right, allowUncheckedConversion); boolean isApplicable(PsiType left, PsiType right, boolean allowUncheckedConversion, int argId); } @MethodCandidateInfo.ApplicabilityLevelConstant - public static int getApplicabilityLevel(@Nonnull final PsiMethod method, - @Nonnull final PsiSubstitutor substitutorForMethod, - @Nonnull final PsiType[] args, - @Nonnull final LanguageLevel languageLevel, - final boolean allowUncheckedConversion, - final boolean checkVarargs) { - return getApplicabilityLevel(method, + @RequiredReadAction + public static int getApplicabilityLevel( + @Nonnull PsiMethod method, + @Nonnull PsiSubstitutor substitutorForMethod, + @Nonnull PsiType[] args, + @Nonnull LanguageLevel languageLevel, + boolean allowUncheckedConversion, + boolean checkVarargs + ) { + return getApplicabilityLevel( + method, substitutorForMethod, args, languageLevel, allowUncheckedConversion, checkVarargs, - ApplicabilityChecker.ASSIGNABILITY_CHECKER); + ApplicabilityChecker.ASSIGNABILITY_CHECKER + ); } @MethodCandidateInfo.ApplicabilityLevelConstant - public static int getApplicabilityLevel(@Nonnull final PsiMethod method, - @Nonnull final PsiSubstitutor substitutorForMethod, - @Nonnull final PsiType[] args, - @Nonnull final LanguageLevel languageLevel, - final boolean allowUncheckedConversion, - final boolean checkVarargs, - @Nonnull final ApplicabilityChecker function) { - final PsiParameter[] parms = method.getParameterList().getParameters(); + @RequiredReadAction + public static int getApplicabilityLevel( + @Nonnull PsiMethod method, + @Nonnull PsiSubstitutor substitutorForMethod, + @Nonnull PsiType[] args, + @Nonnull LanguageLevel languageLevel, + boolean allowUncheckedConversion, + boolean checkVarargs, + @Nonnull ApplicabilityChecker function + ) { + PsiParameter[] parms = method.getParameterList().getParameters(); if (args.length < parms.length - 1) { return ApplicabilityLevel.NOT_APPLICABLE; } - final PsiClass containingClass = method.getContainingClass(); - final boolean isRaw = - containingClass != null && isRawSubstitutor(method, substitutorForMethod) && isRawSubstitutor(containingClass, substitutorForMethod); + PsiClass containingClass = method.getContainingClass(); + boolean isRaw = + containingClass != null && isRawSubstitutor(method, substitutorForMethod) && isRawSubstitutor( + containingClass, + substitutorForMethod + ); if (!areFirstArgumentsApplicable(args, parms, languageLevel, substitutorForMethod, isRaw, allowUncheckedConversion, function)) { return ApplicabilityLevel.NOT_APPLICABLE; } @@ -665,8 +683,9 @@ public static int getApplicabilityLevel(@Nonnull final PsiMethod method, } if (isRaw) { - final PsiType erasedParamType = TypeConversionUtil.erasure(parmType); - if (erasedParamType != null && function.isApplicable(erasedParamType, argType, allowUncheckedConversion, parms.length - 1)) { + PsiType erasedParamType = TypeConversionUtil.erasure(parmType); + if (erasedParamType != null + && function.isApplicable(erasedParamType, argType, allowUncheckedConversion, parms.length - 1)) { return ApplicabilityLevel.FIXED_ARITY; } } @@ -680,19 +699,18 @@ public static int getApplicabilityLevel(@Nonnull final PsiMethod method, if (lastParameter == null || !lastParameter.isVarArgs()) { return ApplicabilityLevel.NOT_APPLICABLE; } - PsiType lastParmType = getParameterType(lastParameter, languageLevel, substitutorForMethod); - if (!(lastParmType instanceof PsiArrayType)) { + PsiType lastParamType = getParameterType(lastParameter, languageLevel, substitutorForMethod); + if (!(lastParamType instanceof PsiArrayType arrayType)) { return ApplicabilityLevel.NOT_APPLICABLE; } - lastParmType = ((PsiArrayType) lastParmType).getComponentType(); - if (lastParmType instanceof PsiCapturedWildcardType && !JavaVersionService.getInstance() - .isAtLeast(((PsiCapturedWildcardType) lastParmType).getContext(), - JavaSdkVersion.JDK_1_8)) { - lastParmType = ((PsiCapturedWildcardType) lastParmType).getWildcard(); + lastParamType = arrayType.getComponentType(); + if (lastParamType instanceof PsiCapturedWildcardType capturedWildcardType + && !JavaVersionService.getInstance().isAtLeast(capturedWildcardType.getContext(), JavaSdkVersion.JDK_1_8)) { + lastParamType = capturedWildcardType.getWildcard(); } for (int i = parms.length - 1; i < args.length; i++) { PsiType argType = args[i]; - if (argType == null || !function.isApplicable(lastParmType, argType, allowUncheckedConversion, i)) { + if (argType == null || !function.isApplicable(lastParamType, argType, allowUncheckedConversion, i)) { return ApplicabilityLevel.NOT_APPLICABLE; } } @@ -702,22 +720,24 @@ public static int getApplicabilityLevel(@Nonnull final PsiMethod method, return ApplicabilityLevel.NOT_APPLICABLE; } - private static boolean areFirstArgumentsApplicable(@Nonnull PsiType[] args, - @Nonnull final PsiParameter[] parms, - @Nonnull LanguageLevel languageLevel, - @Nonnull final PsiSubstitutor substitutorForMethod, - boolean isRaw, - boolean allowUncheckedConversion, - ApplicabilityChecker function) { + private static boolean areFirstArgumentsApplicable( + @Nonnull PsiType[] args, + @Nonnull PsiParameter[] parms, + @Nonnull LanguageLevel languageLevel, + @Nonnull PsiSubstitutor substitutorForMethod, + boolean isRaw, + boolean allowUncheckedConversion, + ApplicabilityChecker function + ) { for (int i = 0; i < parms.length - 1; i++) { - final PsiType type = args[i]; + PsiType type = args[i]; if (type == null) { return false; } - final PsiParameter parameter = parms[i]; - final PsiType substitutedParmType = getParameterType(parameter, languageLevel, substitutorForMethod); + PsiParameter parameter = parms[i]; + PsiType substitutedParmType = getParameterType(parameter, languageLevel, substitutorForMethod); if (isRaw) { - final PsiType substErasure = TypeConversionUtil.erasure(substitutedParmType); + PsiType substErasure = TypeConversionUtil.erasure(substitutedParmType); if (substErasure != null && !function.isApplicable(substErasure, type, allowUncheckedConversion, i)) { return false; } @@ -729,14 +749,16 @@ else if (!function.isApplicable(substitutedParmType, type, allowUncheckedConvers return true; } - private static PsiType getParameterType(@Nonnull final PsiParameter parameter, - @Nonnull LanguageLevel languageLevel, - @Nonnull final PsiSubstitutor substitutor) { - PsiType parmType = parameter.getType(); - if (parmType instanceof PsiClassType) { - parmType = ((PsiClassType) parmType).setLanguageLevel(languageLevel); + private static PsiType getParameterType( + @Nonnull PsiParameter parameter, + @Nonnull LanguageLevel languageLevel, + @Nonnull PsiSubstitutor substitutor + ) { + PsiType paramType = parameter.getType(); + if (paramType instanceof PsiClassType classType) { + paramType = classType.setLanguageLevel(languageLevel); } - return substitutor.substitute(parmType); + return substitutor.substitute(paramType); } /** @@ -744,14 +766,16 @@ private static PsiType getParameterType(@Nonnull final PsiParameter parameter, * class Foo<T extends Number>{} types Foo<?> and Foo<? extends Number> * would be equivalent */ - public static boolean equalOnEquivalentClasses(PsiClassType thisClassType, - @Nonnull PsiClass aClass, - PsiClassType otherClassType, - @Nonnull PsiClass bClass) { + public static boolean equalOnEquivalentClasses( + PsiClassType thisClassType, + @Nonnull PsiClass aClass, + PsiClassType otherClassType, + @Nonnull PsiClass bClass + ) { PsiClassType capture1 = !PsiCapturedWildcardType.isCapture() - ? thisClassType : (PsiClassType) captureToplevelWildcards(thisClassType, aClass); + ? thisClassType : (PsiClassType)captureToplevelWildcards(thisClassType, aClass); PsiClassType capture2 = !PsiCapturedWildcardType.isCapture() - ? otherClassType : (PsiClassType) captureToplevelWildcards(otherClassType, bClass); + ? otherClassType : (PsiClassType)captureToplevelWildcards(otherClassType, bClass); PsiClassType.ClassResolveResult result1 = capture1.resolveGenerics(); PsiClassType.ClassResolveResult result2 = capture2.resolveGenerics(); @@ -759,10 +783,12 @@ public static boolean equalOnEquivalentClasses(PsiClassType thisClassType, return equalOnEquivalentClasses(result1.getSubstitutor(), aClass, result2.getSubstitutor(), bClass); } - private static boolean equalOnEquivalentClasses(@Nonnull PsiSubstitutor s1, - @Nonnull PsiClass aClass, - @Nonnull PsiSubstitutor s2, - @Nonnull PsiClass bClass) { + private static boolean equalOnEquivalentClasses( + @Nonnull PsiSubstitutor s1, + @Nonnull PsiClass aClass, + @Nonnull PsiSubstitutor s2, + @Nonnull PsiClass bClass + ) { if (s1 == s2 && aClass == bClass) { return true; } @@ -782,7 +808,7 @@ private static boolean equalOnEquivalentClasses(@Nonnull PsiSubstitutor s1, return false; } } - if (aClass.hasModifierProperty(PsiModifier.STATIC)) { + if (aClass.isStatic()) { return true; } PsiClass containingClass1 = aClass.getContainingClass(); @@ -807,14 +833,14 @@ private static boolean equalOnEquivalentClasses(@Nonnull PsiSubstitutor s1, /** * @deprecated use more generic {@link #isCompileTimeConstant(PsiVariable)} instead */ - public static boolean isCompileTimeConstant(@Nonnull final PsiField field) { - return isCompileTimeConstant((PsiVariable) field); + public static boolean isCompileTimeConstant(@Nonnull PsiField field) { + return isCompileTimeConstant((PsiVariable)field); } /** * JLS 15.28 */ - public static boolean isCompileTimeConstant(@Nonnull final PsiVariable field) { + public static boolean isCompileTimeConstant(@Nonnull PsiVariable field) { return field.hasModifierProperty(PsiModifier.FINAL) && (TypeConversionUtil.isPrimitiveAndNotNull(field.getType()) || field.getType() .equalsToText( JAVA_LANG_STRING)) && field.hasInitializer() @@ -825,7 +851,7 @@ public static boolean allMethodsHaveSameSignature(@Nonnull PsiMethod[] methods) if (methods.length == 0) { return true; } - final MethodSignature methodSignature = methods[0].getSignature(PsiSubstitutor.EMPTY); + MethodSignature methodSignature = methods[0].getSignature(PsiSubstitutor.EMPTY); for (int i = 1; i < methods.length; i++) { PsiMethod method = methods[i]; if (!methodSignature.equals(method.getSignature(PsiSubstitutor.EMPTY))) { @@ -838,12 +864,12 @@ public static boolean allMethodsHaveSameSignature(@Nonnull PsiMethod[] methods) @Nullable public static PsiExpression deparenthesizeExpression(PsiExpression expression) { while (true) { - if (expression instanceof PsiParenthesizedExpression) { - expression = ((PsiParenthesizedExpression) expression).getExpression(); + if (expression instanceof PsiParenthesizedExpression parenExpr) { + expression = parenExpr.getExpression(); continue; } - if (expression instanceof PsiTypeCastExpression) { - expression = ((PsiTypeCastExpression) expression).getOperand(); + if (expression instanceof PsiTypeCastExpression typeCast) { + expression = typeCast.getOperand(); continue; } return expression; @@ -854,12 +880,13 @@ public static PsiExpression deparenthesizeExpression(PsiExpression expression) { * Checks whether given class is inner (as opposed to nested) */ public static boolean isInnerClass(@Nonnull PsiClass aClass) { - return !aClass.hasModifierProperty(PsiModifier.STATIC) && aClass.getContainingClass() != null; + return !aClass.isStatic() && aClass.getContainingClass() != null; } @Nullable - public static PsiElement findModifierInList(@Nonnull final PsiModifierList modifierList, @NonNls String modifier) { - final PsiElement[] children = modifierList.getChildren(); + @RequiredReadAction + public static PsiElement findModifierInList(@Nonnull PsiModifierList modifierList, String modifier) { + PsiElement[] children = modifierList.getChildren(); for (PsiElement child : children) { if (child.getText().equals(modifier)) { return child; @@ -870,9 +897,8 @@ public static PsiElement findModifierInList(@Nonnull final PsiModifierList modif @Nullable public static PsiClass getTopLevelClass(@Nonnull PsiElement element) { - final PsiFile file = element.getContainingFile(); - if (file instanceof PsiClassOwner) { - final PsiClass[] classes = ((PsiClassOwner) file).getClasses(); + if (element.getContainingFile() instanceof PsiClassOwner classOwner) { + PsiClass[] classes = classOwner.getClasses(); for (PsiClass aClass : classes) { if (PsiTreeUtil.isAncestor(aClass, element, false)) { return aClass; @@ -895,8 +921,8 @@ public static PsiModifierListOwner getEnclosingStaticElement(@Nonnull PsiElement if (parent instanceof PsiFile) { break; } - if (parent instanceof PsiModifierListOwner && ((PsiModifierListOwner) parent).hasModifierProperty(PsiModifier.STATIC)) { - return (PsiModifierListOwner) parent; + if (parent instanceof PsiModifierListOwner modifierListOwner && modifierListOwner.hasModifierProperty(PsiModifier.STATIC)) { + return (PsiModifierListOwner)parent; } parent = parent.getParent(); } @@ -904,45 +930,45 @@ public static PsiModifierListOwner getEnclosingStaticElement(@Nonnull PsiElement } @Nullable - public static PsiType getTypeByPsiElement(@Nonnull final PsiElement element) { - if (element instanceof PsiVariable) { - return ((PsiVariable) element).getType(); + public static PsiType getTypeByPsiElement(@Nonnull PsiElement element) { + if (element instanceof PsiVariable variable) { + return variable.getType(); } - else if (element instanceof PsiMethod) { - return ((PsiMethod) element).getReturnType(); + else if (element instanceof PsiMethod method) { + return method.getReturnType(); } return null; } @Nonnull - public static PsiType captureToplevelWildcards(@Nonnull final PsiType type, @Nonnull final PsiElement context) { - if (type instanceof PsiClassType) { - final PsiClassType.ClassResolveResult result = ((PsiClassType) type).resolveGenerics(); - final PsiClass aClass = result.getElement(); + public static PsiType captureToplevelWildcards(@Nonnull PsiType type, @Nonnull PsiElement context) { + if (type instanceof PsiClassType classType) { + PsiClassType.ClassResolveResult result = classType.resolveGenerics(); + PsiClass aClass = result.getElement(); if (aClass != null) { - final PsiSubstitutor substitutor = result.getSubstitutor(); + PsiSubstitutor substitutor = result.getSubstitutor(); PsiSubstitutor captureSubstitutor = substitutor; for (PsiTypeParameter typeParameter : typeParametersIterable(aClass)) { - final PsiType substituted = substitutor.substitute(typeParameter); - if (substituted instanceof PsiWildcardType) { - captureSubstitutor = - captureSubstitutor.put(typeParameter, PsiCapturedWildcardType.create((PsiWildcardType) substituted, context, typeParameter)); + if (substitutor.substitute(typeParameter) instanceof PsiWildcardType wildcardType) { + captureSubstitutor = captureSubstitutor.put( + typeParameter, + PsiCapturedWildcardType.create(wildcardType, context, typeParameter) + ); } } if (captureSubstitutor != substitutor) { Map substitutionMap = null; for (PsiTypeParameter typeParameter : typeParametersIterable(aClass)) { - final PsiType substituted = substitutor.substitute(typeParameter); - if (substituted instanceof PsiWildcardType) { + if (substitutor.substitute(typeParameter) instanceof PsiWildcardType wildcardType) { if (substitutionMap == null) { - substitutionMap = new HashMap(substitutor.getSubstitutionMap()); + substitutionMap = new HashMap<>(substitutor.getSubstitutionMap()); } - final PsiCapturedWildcardType capturedWildcard = (PsiCapturedWildcardType) captureSubstitutor.substitute(typeParameter); + PsiCapturedWildcardType capturedWildcard = + (PsiCapturedWildcardType)captureSubstitutor.substitute(typeParameter); LOG.assertTrue(capturedWildcard != null); - final PsiType upperBound = - PsiCapturedWildcardType.captureUpperBound(typeParameter, (PsiWildcardType) substituted, captureSubstitutor); + PsiType upperBound = PsiCapturedWildcardType.captureUpperBound(typeParameter, wildcardType, captureSubstitutor); if (upperBound != null) { capturedWildcard.setUpperBound(upperBound); } @@ -951,52 +977,52 @@ public static PsiType captureToplevelWildcards(@Nonnull final PsiType type, @Non } if (substitutionMap != null) { - final PsiElementFactory factory = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory(); - final PsiSubstitutor newSubstitutor = factory.createSubstitutor(substitutionMap); + PsiElementFactory factory = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory(); + PsiSubstitutor newSubstitutor = factory.createSubstitutor(substitutionMap); return factory.createType(aClass, newSubstitutor); } } } } - else if (type instanceof PsiArrayType) { - return captureToplevelWildcards(((PsiArrayType) type).getComponentType(), context).createArrayType(); + else if (type instanceof PsiArrayType arrayType) { + return captureToplevelWildcards(arrayType.getComponentType(), context).createArrayType(); } return type; } - public static PsiType captureTypeParameterBounds(@Nonnull PsiTypeParameter typeParameter, - PsiType substituted, - PsiElement context, - PsiSubstitutor captureSubstitutor) { + public static PsiType captureTypeParameterBounds( + @Nonnull PsiTypeParameter typeParameter, + PsiType substituted, + PsiElement context, + PsiSubstitutor captureSubstitutor + ) { PsiType oldSubstituted = substituted; PsiElement captureContext = context; - if (substituted instanceof PsiCapturedWildcardType) { - final PsiCapturedWildcardType captured = (PsiCapturedWildcardType) substituted; + if (substituted instanceof PsiCapturedWildcardType captured) { substituted = captured.getWildcard(); captureContext = captured.getContext(); } PsiType glb = null; - if (substituted instanceof PsiWildcardType) { - final PsiType[] boundTypes = typeParameter.getExtendsListTypes(); + if (substituted instanceof PsiWildcardType wildcardType) { + PsiType[] boundTypes = typeParameter.getExtendsListTypes(); PsiManager manager = typeParameter.getManager(); - PsiType originalBound = !((PsiWildcardType) substituted).isSuper() ? ((PsiWildcardType) substituted).getBound() : null; + PsiType originalBound = !wildcardType.isSuper() ? wildcardType.getBound() : null; glb = originalBound; for (PsiType boundType : boundTypes) { PsiType substitutedBoundType = captureSubstitutor.substitute(boundType); - if (substitutedBoundType != null && !(substitutedBoundType instanceof PsiWildcardType) && !substitutedBoundType.equalsToText( - JavaClassNames.JAVA_LANG_OBJECT)) { - if (originalBound instanceof PsiArrayType && substitutedBoundType instanceof PsiArrayType && !originalBound.isAssignableFrom( - substitutedBoundType) && !substitutedBoundType - .isAssignableFrom(originalBound)) { + if (substitutedBoundType != null && !(substitutedBoundType instanceof PsiWildcardType) + && !substitutedBoundType.equalsToText(JavaClassNames.JAVA_LANG_OBJECT)) { + if (originalBound instanceof PsiArrayType && substitutedBoundType instanceof PsiArrayType + && !originalBound.isAssignableFrom(substitutedBoundType) + && !substitutedBoundType.isAssignableFrom(originalBound)) { continue; } - if (originalBound == null || !TypeConversionUtil.erasure(substitutedBoundType) - .isAssignableFrom(TypeConversionUtil.erasure(originalBound)) && !TypeConversionUtil.erasure - (substitutedBoundType) - .isAssignableFrom( - originalBound)) { //erasure is essential to avoid infinite recursion + if (originalBound == null + || !TypeConversionUtil.erasure(substitutedBoundType).isAssignableFrom(TypeConversionUtil.erasure(originalBound)) + && !TypeConversionUtil.erasure(substitutedBoundType).isAssignableFrom(originalBound)) { + //erasure is essential to avoid infinite recursion if (glb == null) { glb = substitutedBoundType; @@ -1008,20 +1034,21 @@ public static PsiType captureTypeParameterBounds(@Nonnull PsiTypeParameter typeP } } - if (glb != null && !((PsiWildcardType) substituted).isSuper()) { - substituted = glb instanceof PsiCapturedWildcardType ? ((PsiCapturedWildcardType) glb).getWildcard() : PsiWildcardType.createExtends( - manager, - glb); + if (glb != null && !((PsiWildcardType)substituted).isSuper()) { + substituted = glb instanceof PsiCapturedWildcardType capturedWildcardType + ? capturedWildcardType.getWildcard() + : PsiWildcardType.createExtends(manager, glb); } } if (captureContext != null) { - substituted = - oldSubstituted instanceof PsiCapturedWildcardType && substituted.equals(((PsiCapturedWildcardType) oldSubstituted).getWildcard()) ? oldSubstituted : captureSubstitutor - .substitute(typeParameter); + substituted = oldSubstituted instanceof PsiCapturedWildcardType capturedWildcardType + && substituted.equals(capturedWildcardType.getWildcard()) + ? oldSubstituted + : captureSubstitutor.substitute(typeParameter); LOG.assertTrue(substituted instanceof PsiCapturedWildcardType); if (glb != null) { - ((PsiCapturedWildcardType) substituted).setUpperBound(glb); + ((PsiCapturedWildcardType)substituted).setUpperBound(glb); } } return substituted; @@ -1032,11 +1059,12 @@ public static boolean isInsideJavadocComment(PsiElement element) { } @Nonnull + @RequiredReadAction public static List getParameterTypeElements(@Nonnull PsiParameter parameter) { PsiTypeElement typeElement = parameter.getTypeElement(); - return typeElement != null && typeElement.getType() instanceof PsiDisjunctionType ? PsiTreeUtil.getChildrenOfTypeAsList(typeElement, - PsiTypeElement.class) : Collections.singletonList - (typeElement); + return typeElement != null && typeElement.getType() instanceof PsiDisjunctionType + ? PsiTreeUtil.getChildrenOfTypeAsList(typeElement, PsiTypeElement.class) + : Collections.singletonList(typeElement); } public static void checkIsIdentifier(@Nonnull PsiManager manager, String text) throws IncorrectOperationException { @@ -1055,29 +1083,29 @@ public static VirtualFile getJarFile(@Nonnull PsiElement candidate) { } public static boolean isAnnotationMethod(PsiElement element) { - if (!(element instanceof PsiAnnotationMethod)) { + if (!(element instanceof PsiAnnotationMethod annotationMethod)) { return false; } - PsiClass psiClass = ((PsiAnnotationMethod) element).getContainingClass(); + PsiClass psiClass = annotationMethod.getContainingClass(); return psiClass != null && psiClass.isAnnotationType(); } @PsiModifier.ModifierConstant - public static String getMaximumModifierForMember(final PsiClass aClass) { + public static String getMaximumModifierForMember(PsiClass aClass) { return getMaximumModifierForMember(aClass, true); } @PsiModifier.ModifierConstant - public static String getMaximumModifierForMember(final PsiClass aClass, boolean allowPublicAbstract) { + public static String getMaximumModifierForMember(PsiClass aClass, boolean allowPublicAbstract) { String modifier = PsiModifier.PUBLIC; - if (!allowPublicAbstract && aClass.hasModifierProperty(PsiModifier.ABSTRACT) && !aClass.isEnum()) { + if (!allowPublicAbstract && aClass.isAbstract() && !aClass.isEnum()) { modifier = PsiModifier.PROTECTED; } else if (aClass.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) || aClass.isEnum()) { modifier = PsiModifier.PACKAGE_LOCAL; } - else if (aClass.hasModifierProperty(PsiModifier.PRIVATE)) { + else if (aClass.isPrivate()) { modifier = PsiModifier.PRIVATE; } @@ -1094,7 +1122,7 @@ public static Iterator typeParametersIterator(@Nonnull PsiType } @Nonnull - public static List typeParametersIterable(@Nonnull final PsiTypeParameterListOwner owner) { + public static List typeParametersIterable(@Nonnull PsiTypeParameterListOwner owner) { List result = null; PsiTypeParameterListOwner currentOwner = owner; @@ -1102,14 +1130,14 @@ public static List typeParametersIterable(@Nonnull final PsiTy PsiTypeParameter[] typeParameters = currentOwner.getTypeParameters(); if (typeParameters.length > 0) { if (result == null) { - result = new ArrayList(typeParameters.length); + result = new ArrayList<>(typeParameters.length); } for (int i = typeParameters.length - 1; i >= 0; i--) { result.add(typeParameters[i]); } } - if (currentOwner.hasModifierProperty(PsiModifier.STATIC)) { + if (currentOwner.isStatic()) { break; } currentOwner = currentOwner.getContainingClass(); @@ -1123,10 +1151,8 @@ public static List typeParametersIterable(@Nonnull final PsiTy public static boolean canBeOverriden(@Nonnull PsiMethod method) { PsiClass parentClass = method.getContainingClass(); - return parentClass != null && !method.isConstructor() && !method.hasModifierProperty(PsiModifier.STATIC) && !method.hasModifierProperty( - PsiModifier.FINAL) && !method.hasModifierProperty - (PsiModifier.PRIVATE) && !(parentClass instanceof PsiAnonymousClass) && !parentClass.hasModifierProperty( - PsiModifier.FINAL); + return parentClass != null && !method.isConstructor() && !method.isStatic() && !method.isFinal() && !method.isPrivate() + && !(parentClass instanceof PsiAnonymousClass) && !parentClass.isFinal(); } @Nonnull @@ -1140,25 +1166,31 @@ public static PsiElement[] mapElements(@Nonnull ResolveResult[] candidates) { @Nullable public static PsiMember findEnclosingConstructorOrInitializer(PsiElement expression) { - PsiMember parent = - PsiTreeUtil.getParentOfType(expression, PsiClassInitializer.class, PsiEnumConstantInitializer.class, PsiMethod.class, PsiField.class); - if (parent instanceof PsiMethod && !((PsiMethod) parent).isConstructor()) { + PsiMember parent = PsiTreeUtil.getParentOfType( + expression, + PsiClassInitializer.class, + PsiEnumConstantInitializer.class, + PsiMethod.class, + PsiField.class + ); + if (parent instanceof PsiMethod method && !method.isConstructor()) { return null; } - if (parent instanceof PsiField && parent.hasModifierProperty(PsiModifier.STATIC)) { + if (parent instanceof PsiField && parent.isStatic()) { return null; } return parent; } - public static boolean checkName(@Nonnull PsiElement element, @Nonnull String name, final PsiElement context) { - if (element instanceof PsiMetaOwner) { - final PsiMetaData data = ((PsiMetaOwner) element).getMetaData(); + @RequiredReadAction + public static boolean checkName(@Nonnull PsiElement element, @Nonnull String name, PsiElement context) { + if (element instanceof PsiMetaOwner metaOwner) { + PsiMetaData data = metaOwner.getMetaData(); if (data != null) { return name.equals(data.getName(context)); } } - return element instanceof PsiNamedElement && name.equals(((PsiNamedElement) element).getName()); + return element instanceof PsiNamedElement namedElem && name.equals(namedElem.getName()); } public static boolean isRawSubstitutor(@Nonnull PsiTypeParameterListOwner owner, @Nonnull PsiSubstitutor substitutor) { @@ -1176,30 +1208,37 @@ public static boolean isRawSubstitutor(@Nonnull PsiTypeParameterListOwner owner, public static final Key FILE_LANGUAGE_LEVEL_KEY = Key.create("FORCE_LANGUAGE_LEVEL"); - public static boolean isLanguageLevel5OrHigher(@Nonnull final PsiElement element) { + @RequiredReadAction + public static boolean isLanguageLevel5OrHigher(@Nonnull PsiElement element) { return getLanguageLevel(element).isAtLeast(LanguageLevel.JDK_1_5); } - public static boolean isLanguageLevel6OrHigher(@Nonnull final PsiElement element) { + @RequiredReadAction + public static boolean isLanguageLevel6OrHigher(@Nonnull PsiElement element) { return getLanguageLevel(element).isAtLeast(LanguageLevel.JDK_1_6); } - public static boolean isLanguageLevel7OrHigher(@Nonnull final PsiElement element) { + @RequiredReadAction + public static boolean isLanguageLevel7OrHigher(@Nonnull PsiElement element) { return getLanguageLevel(element).isAtLeast(LanguageLevel.JDK_1_7); } - public static boolean isLanguageLevel8OrHigher(@Nonnull final PsiElement element) { + @RequiredReadAction + public static boolean isLanguageLevel8OrHigher(@Nonnull PsiElement element) { return getLanguageLevel(element).isAtLeast(LanguageLevel.JDK_1_8); } - public static boolean isLanguageLevel9OrHigher(@Nonnull final PsiElement element) { + @RequiredReadAction + public static boolean isLanguageLevel9OrHigher(@Nonnull PsiElement element) { return getLanguageLevel(element).isAtLeast(LanguageLevel.JDK_1_9); } - public static boolean isLanguageLevel10OrHigher(@Nonnull final PsiElement element) { + @RequiredReadAction + public static boolean isLanguageLevel10OrHigher(@Nonnull PsiElement element) { return getLanguageLevel(element).isAtLeast(LanguageLevel.JDK_10); } + @RequiredReadAction public static boolean isLanguageLevel11OrHigher(@Nonnull PsiElement element) { return getLanguageLevel(element).isAtLeast(LanguageLevel.JDK_11); } @@ -1233,13 +1272,13 @@ public static boolean isAvailable(@Nonnull JavaFeature feature, @Nonnull PsiElem @Nonnull @RequiredReadAction public static LanguageLevel getLanguageLevel(@Nonnull PsiElement element) { - if (element instanceof PsiDirectory) { - return JavaDirectoryService.getInstance().getLanguageLevel((PsiDirectory) element); + if (element instanceof PsiDirectory directory) { + return JavaDirectoryService.getInstance().getLanguageLevel(directory); } PsiFile file = element.getContainingFile(); - if (file instanceof PsiJavaFile) { - return ((PsiJavaFile) file).getLanguageLevel(); + if (file instanceof PsiJavaFile javaFile) { + return javaFile.getLanguageLevel(); } if (file != null) { @@ -1255,7 +1294,7 @@ public static LanguageLevel getLanguageLevel(@Nonnull PsiElement element) { } public static boolean isInstantiatable(@Nonnull PsiClass clazz) { - return !clazz.hasModifierProperty(PsiModifier.ABSTRACT) && clazz.hasModifierProperty(PsiModifier.PUBLIC) && hasDefaultConstructor(clazz); + return !clazz.isAbstract() && clazz.isPublic() && hasDefaultConstructor(clazz); } public static boolean hasDefaultConstructor(@Nonnull PsiClass clazz) { @@ -1270,28 +1309,30 @@ public static boolean hasDefaultConstructor(@Nonnull PsiClass clazz, boolean all return hasDefaultCtrInHierarchy(clazz, allowProtected, checkModifiers, null); } - private static boolean hasDefaultCtrInHierarchy(@Nonnull PsiClass clazz, - boolean allowProtected, - boolean checkModifiers, - @Nullable Set visited) { - final PsiMethod[] constructors = clazz.getConstructors(); + private static boolean hasDefaultCtrInHierarchy( + @Nonnull PsiClass clazz, + boolean allowProtected, + boolean checkModifiers, + @Nullable Set visited + ) { + PsiMethod[] constructors = clazz.getConstructors(); if (constructors.length > 0) { for (PsiMethod cls : constructors) { - if ((!checkModifiers || cls.hasModifierProperty(PsiModifier.PUBLIC) || allowProtected && cls.hasModifierProperty(PsiModifier.PROTECTED)) && cls.getParameterList() - .getParametersCount() - == 0) { + if ((!checkModifiers || cls.isPublic() || allowProtected && cls.isProtected()) + && cls.getParameterList().getParametersCount() == 0) { return true; } } } else { - final PsiClass superClass = clazz.getSuperClass(); + PsiClass superClass = clazz.getSuperClass(); if (superClass == null) { return true; } if (visited == null) { - visited = new HashSet(); + visited = new HashSet<>(); } + //noinspection SimplifiableIfStatement if (!visited.add(clazz)) { return false; } @@ -1301,32 +1342,33 @@ private static boolean hasDefaultCtrInHierarchy(@Nonnull PsiClass clazz, } @Nullable - public static PsiType extractIterableTypeParameter(@Nullable PsiType psiType, final boolean eraseTypeParameter) { - final PsiType type = substituteTypeParameter(psiType, JavaClassNames.JAVA_LANG_ITERABLE, 0, eraseTypeParameter); + public static PsiType extractIterableTypeParameter(@Nullable PsiType psiType, boolean eraseTypeParameter) { + PsiType type = substituteTypeParameter(psiType, JavaClassNames.JAVA_LANG_ITERABLE, 0, eraseTypeParameter); return type != null ? type : substituteTypeParameter(psiType, JavaClassNames.JAVA_UTIL_COLLECTION, 0, eraseTypeParameter); } @Nullable - public static PsiType substituteTypeParameter(@Nullable final PsiType psiType, - @Nonnull final String superClass, - final int typeParamIndex, - final boolean eraseTypeParameter) { + public static PsiType substituteTypeParameter( + @Nullable PsiType psiType, + @Nonnull String superClass, + int typeParamIndex, + boolean eraseTypeParameter + ) { if (psiType == null) { return null; } - if (!(psiType instanceof PsiClassType)) { + if (!(psiType instanceof PsiClassType classType)) { return null; } - final PsiClassType classType = (PsiClassType) psiType; - final PsiClassType.ClassResolveResult classResolveResult = classType.resolveGenerics(); - final PsiClass psiClass = classResolveResult.getElement(); + PsiClassType.ClassResolveResult classResolveResult = classType.resolveGenerics(); + PsiClass psiClass = classResolveResult.getElement(); if (psiClass == null) { return null; } - final PsiClass baseClass = JavaPsiFacade.getInstance(psiClass.getProject()).findClass(superClass, psiClass.getResolveScope()); + PsiClass baseClass = JavaPsiFacade.getInstance(psiClass.getProject()).findClass(superClass, psiClass.getResolveScope()); if (baseClass == null) { return null; } @@ -1335,91 +1377,89 @@ public static PsiType substituteTypeParameter(@Nullable final PsiType psiType, return null; } - final PsiTypeParameter[] parameters = baseClass.getTypeParameters(); + PsiTypeParameter[] parameters = baseClass.getTypeParameters(); if (parameters.length <= typeParamIndex) { return PsiType.getJavaLangObject(psiClass.getManager(), psiClass.getResolveScope()); } - final PsiSubstitutor substitutor = - TypeConversionUtil.getSuperClassSubstitutor(baseClass, psiClass, classResolveResult.getSubstitutor()); - final PsiType type = substitutor.substitute(parameters[typeParamIndex]); + PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(baseClass, psiClass, classResolveResult.getSubstitutor()); + PsiType type = substitutor.substitute(parameters[typeParamIndex]); if (type == null && eraseTypeParameter) { return TypeConversionUtil.typeParameterErasure(parameters[typeParamIndex]); } return type; } - public static final Comparator BY_POSITION = new Comparator() { - @Override - public int compare(PsiElement o1, PsiElement o2) { - return compareElementsByPosition(o1, o2); - } - }; + public static final Comparator BY_POSITION = PsiUtilCore::compareElementsByPosition; - public static void setModifierProperty(@Nonnull PsiModifierListOwner owner, - @Nonnull @PsiModifier.ModifierConstant String property, - boolean value) { - final PsiModifierList modifierList = owner.getModifierList(); + public static void setModifierProperty( + @Nonnull PsiModifierListOwner owner, + @Nonnull @PsiModifier.ModifierConstant String property, + boolean value + ) { + PsiModifierList modifierList = owner.getModifierList(); assert modifierList != null : owner; modifierList.setModifierProperty(property, value); } - public static boolean isTryBlock(@Nullable final PsiElement element) { + public static boolean isTryBlock(@Nullable PsiElement element) { if (element == null) { return false; } - final PsiElement parent = element.getParent(); - return parent instanceof PsiTryStatement && element == ((PsiTryStatement) parent).getTryBlock(); + PsiElement parent = element.getParent(); + return parent instanceof PsiTryStatement tryStmt && element == tryStmt.getTryBlock(); } - public static boolean isElseBlock(@Nullable final PsiElement element) { + public static boolean isElseBlock(@Nullable PsiElement element) { if (element == null) { return false; } - final PsiElement parent = element.getParent(); - return parent instanceof PsiIfStatement && element == ((PsiIfStatement) parent).getElseBranch(); + PsiElement parent = element.getParent(); + return parent instanceof PsiIfStatement ifStmt && element == ifStmt.getElseBranch(); } public static boolean isJavaToken(@Nullable PsiElement element, IElementType type) { - return element instanceof PsiJavaToken && ((PsiJavaToken) element).getTokenType() == type; + return element instanceof PsiJavaToken javaToken && javaToken.getTokenType() == type; } public static boolean isJavaToken(@Nullable PsiElement element, @Nonnull TokenSet types) { - return element instanceof PsiJavaToken && types.contains(((PsiJavaToken) element).getTokenType()); + return element instanceof PsiJavaToken javaToken && types.contains(javaToken.getTokenType()); } - public static boolean isCatchParameter(@Nullable final PsiElement element) { + public static boolean isCatchParameter(@Nullable PsiElement element) { return element instanceof PsiParameter && element.getParent() instanceof PsiCatchSection; } - public static boolean isIgnoredName(@Nullable final String name) { + public static boolean isIgnoredName(@Nullable String name) { return name != null && IGNORED_NAMES.contains(name); } @Nullable - public static PsiMethod[] getResourceCloserMethodsForType(@Nonnull final PsiClassType resourceType) { - final PsiClass resourceClass = resourceType.resolve(); + public static PsiMethod[] getResourceCloserMethodsForType(@Nonnull PsiClassType resourceType) { + PsiClass resourceClass = resourceType.resolve(); if (resourceClass == null) { return null; } - final Project project = resourceClass.getProject(); - final JavaPsiFacade facade = JavaPsiFacade.getInstance(project); - final PsiClass autoCloseable = - facade.findClass(JavaClassNames.JAVA_LANG_AUTO_CLOSEABLE, (GlobalSearchScope) ProjectScopes.getLibrariesScope(project)); + Project project = resourceClass.getProject(); + JavaPsiFacade facade = JavaPsiFacade.getInstance(project); + PsiClass autoCloseable = + facade.findClass(JavaClassNames.JAVA_LANG_AUTO_CLOSEABLE, (GlobalSearchScope)ProjectScopes.getLibrariesScope(project)); if (autoCloseable == null) { return null; } if (JavaClassSupers.getInstance() - .getSuperClassSubstitutor(autoCloseable, + .getSuperClassSubstitutor( + autoCloseable, resourceClass, resourceType.getResolveScope(), - PsiSubstitutor.EMPTY) == null) { + PsiSubstitutor.EMPTY + ) == null) { return null; } - final PsiMethod[] closes = autoCloseable.findMethodsByName("close", false); + PsiMethod[] closes = autoCloseable.findMethodsByName("close", false); if (closes.length == 1) { return resourceClass.findMethodsBySignature(closes[0], true); } @@ -1428,8 +1468,7 @@ public static PsiMethod[] getResourceCloserMethodsForType(@Nonnull final PsiClas @Nullable public static PsiMethod getResourceCloserMethod(@Nonnull PsiResourceListElement resource) { - PsiType resourceType = resource.getType(); - return resourceType instanceof PsiClassType ? getResourceCloserMethodForType((PsiClassType) resourceType) : null; + return resource.getType() instanceof PsiClassType resourceType ? getResourceCloserMethodForType(resourceType) : null; } /** @@ -1437,40 +1476,42 @@ public static PsiMethod getResourceCloserMethod(@Nonnull PsiResourceListElement */ @SuppressWarnings("unused") public static PsiMethod getResourceCloserMethod(@Nonnull PsiResourceVariable resource) { - return getResourceCloserMethod((PsiResourceListElement) resource); + return getResourceCloserMethod((PsiResourceListElement)resource); } @Nullable - public static PsiMethod getResourceCloserMethodForType(@Nonnull final PsiClassType resourceType) { - final PsiClass resourceClass = resourceType.resolve(); + public static PsiMethod getResourceCloserMethodForType(@Nonnull PsiClassType resourceType) { + PsiClass resourceClass = resourceType.resolve(); if (resourceClass == null) { return null; } - final Project project = resourceClass.getProject(); - final JavaPsiFacade facade = JavaPsiFacade.getInstance(project); - final PsiClass autoCloseable = - facade.findClass(JavaClassNames.JAVA_LANG_AUTO_CLOSEABLE, (GlobalSearchScope) ProjectScopes.getLibrariesScope(project)); + Project project = resourceClass.getProject(); + JavaPsiFacade facade = JavaPsiFacade.getInstance(project); + PsiClass autoCloseable = + facade.findClass(JavaClassNames.JAVA_LANG_AUTO_CLOSEABLE, (GlobalSearchScope)ProjectScopes.getLibrariesScope(project)); if (autoCloseable == null) { return null; } if (JavaClassSupers.getInstance() - .getSuperClassSubstitutor(autoCloseable, + .getSuperClassSubstitutor( + autoCloseable, resourceClass, resourceType.getResolveScope(), - PsiSubstitutor.EMPTY) == null) { + PsiSubstitutor.EMPTY + ) == null) { return null; } - final PsiMethod[] closes = autoCloseable.findMethodsByName("close", false); + PsiMethod[] closes = autoCloseable.findMethodsByName("close", false); return closes.length == 1 ? resourceClass.findMethodBySignature(closes[0], true) : null; } @Nullable public static PsiExpression skipParenthesizedExprDown(PsiExpression initializer) { - while (initializer instanceof PsiParenthesizedExpression) { - initializer = ((PsiParenthesizedExpression) initializer).getExpression(); + while (initializer instanceof PsiParenthesizedExpression parenExpr) { + initializer = parenExpr.getExpression(); } return initializer; } @@ -1493,9 +1534,9 @@ public static void ensureValidType(@Nonnull PsiType type, @Nullable String custo LOG.error("PsiType resurrected: " + type + " of " + type.getClass() + " " + customMessage); return; } - if (type instanceof PsiClassType) { + if (type instanceof PsiClassType classType) { try { - PsiClass psiClass = ((PsiClassType) type).resolve(); // should throw exception + PsiClass psiClass = classType.resolve(); // should throw exception if (psiClass != null) { ensureValid(psiClass); } @@ -1510,8 +1551,8 @@ public static void ensureValidType(@Nonnull PsiType type, @Nullable String custo @Nullable public static String getMemberQualifiedName(@Nonnull PsiMember member) { - if (member instanceof PsiClass) { - return ((PsiClass) member).getQualifiedName(); + if (member instanceof PsiClass psiClass) { + return psiClass.getQualifiedName(); } PsiClass containingClass = member.getContainingClass(); @@ -1525,20 +1566,22 @@ public static String getMemberQualifiedName(@Nonnull PsiMember member) { return className + "." + member.getName(); } + @RequiredReadAction public static boolean isFromDefaultPackage(PsiClass aClass) { - return isFromDefaultPackage((PsiElement) aClass); + return isFromDefaultPackage((PsiElement)aClass); } + @RequiredReadAction public static boolean isFromDefaultPackage(PsiElement element) { PsiFile containingFile = element.getContainingFile(); - if (containingFile instanceof PsiClassOwner) { - return StringUtil.isEmpty(((PsiClassOwner) containingFile).getPackageName()); + if (containingFile instanceof PsiClassOwner classOwner) { + return StringUtil.isEmpty(classOwner.getPackageName()); } if (containingFile instanceof JavaCodeFragment) { PsiElement context = containingFile.getContext(); - if (context instanceof PsiPackage) { - return StringUtil.isEmpty(((PsiPackage) context).getName()); + if (context instanceof PsiPackage psiPackage) { + return StringUtil.isEmpty(psiPackage.getName()); } if (context != null && context != containingFile) { return isFromDefaultPackage(context); @@ -1548,33 +1591,33 @@ public static boolean isFromDefaultPackage(PsiElement element) { return false; } - static boolean checkSameExpression(PsiElement templateExpr, final PsiExpression expression) { + static boolean checkSameExpression(PsiElement templateExpr, PsiExpression expression) { return templateExpr.equals(skipParenthesizedExprDown(expression)); } public static boolean isCondition(PsiElement expr, PsiElement parent) { - if (parent instanceof PsiIfStatement) { - if (checkSameExpression(expr, ((PsiIfStatement) parent).getCondition())) { + if (parent instanceof PsiIfStatement ifStmt) { + if (checkSameExpression(expr, ifStmt.getCondition())) { return true; } } - else if (parent instanceof PsiWhileStatement) { - if (checkSameExpression(expr, ((PsiWhileStatement) parent).getCondition())) { + else if (parent instanceof PsiWhileStatement whileStmt) { + if (checkSameExpression(expr, whileStmt.getCondition())) { return true; } } - else if (parent instanceof PsiForStatement) { - if (checkSameExpression(expr, ((PsiForStatement) parent).getCondition())) { + else if (parent instanceof PsiForStatement forStmt) { + if (checkSameExpression(expr, forStmt.getCondition())) { return true; } } - else if (parent instanceof PsiDoWhileStatement) { - if (checkSameExpression(expr, ((PsiDoWhileStatement) parent).getCondition())) { + else if (parent instanceof PsiDoWhileStatement doWhileStmt) { + if (checkSameExpression(expr, doWhileStmt.getCondition())) { return true; } } - else if (parent instanceof PsiConditionalExpression) { - if (checkSameExpression(expr, ((PsiConditionalExpression) parent).getCondition())) { + else if (parent instanceof PsiConditionalExpression condExpr) { + if (checkSameExpression(expr, condExpr.getCondition())) { return true; } } @@ -1582,39 +1625,47 @@ else if (parent instanceof PsiConditionalExpression) { } @Nonnull + @RequiredReadAction public static PsiReturnStatement[] findReturnStatements(@Nonnull PsiMethod method) { return findReturnStatements(method.getBody()); } @Nonnull + @RequiredReadAction public static PsiReturnStatement[] findReturnStatements(@Nullable PsiCodeBlock body) { - List vector = new ArrayList<>(); + List list = new ArrayList<>(); if (body != null) { - addStatements(vector, body, PsiReturnStatement.class, statement -> false); + addStatements(list, body, PsiReturnStatement.class, statement -> false); } - return vector.toArray(PsiReturnStatement.EMPTY_ARRAY); + return list.toArray(PsiReturnStatement.EMPTY_ARRAY); } - private static void addStatements(@Nonnull List vector, - @Nonnull PsiElement element, - @Nonnull Class clazz, - @Nonnull Predicate stopAt) { + @RequiredReadAction + private static void addStatements( + @Nonnull List list, + @Nonnull PsiElement element, + @Nonnull Class clazz, + @Nonnull Predicate stopAt + ) { if (PsiTreeUtil.instanceOf(element, clazz)) { //noinspection unchecked - vector.add((T) element); + list.add((T)element); } else if (!(element instanceof PsiClass) && !(element instanceof PsiLambdaExpression) && !stopAt.test(element)) { PsiElement[] children = element.getChildren(); for (PsiElement child : children) { - addStatements(vector, child, clazz, stopAt); + addStatements(list, child, clazz, stopAt); } } } + @RequiredReadAction public static boolean isPackageEmpty(@Nonnull PsiDirectory[] directories, @Nonnull String packageName) { for (PsiDirectory directory : directories) { for (PsiFile file : directory.getFiles()) { - if (file instanceof PsiClassOwner && packageName.equals(((PsiClassOwner) file).getPackageName()) && ((PsiClassOwner) file).getClasses().length > 0) { + if (file instanceof PsiClassOwner classOwner + && packageName.equals(classOwner.getPackageName()) + && classOwner.getClasses().length > 0) { return false; } } @@ -1625,25 +1676,21 @@ public static boolean isPackageEmpty(@Nonnull PsiDirectory[] directories, @Nonnu @Nonnull public static PsiModifierListOwner preferCompiledElement(@Nonnull PsiModifierListOwner element) { - PsiElement original = element.getOriginalElement(); - return original instanceof PsiModifierListOwner ? (PsiModifierListOwner) original : element; + return element.getOriginalElement() instanceof PsiModifierListOwner modifierListOwner ? modifierListOwner : element; } + @RequiredReadAction public static boolean isModuleFile(@Nonnull PsiFile file) { - return file instanceof PsiJavaFile && ((PsiJavaFile) file).getModuleDeclaration() != null; + return file instanceof PsiJavaFile javaFile && javaFile.getModuleDeclaration() != null; } public static boolean canBeOverridden(@Nonnull PsiMethod method) { PsiClass parentClass = method.getContainingClass(); - return parentClass != null && - !method.isConstructor() && - !method.hasModifierProperty(PsiModifier.STATIC) && - !method.hasModifierProperty(PsiModifier.FINAL) && - !method.hasModifierProperty(PsiModifier.PRIVATE) && - !(parentClass instanceof PsiAnonymousClass) && - !parentClass.hasModifierProperty(PsiModifier.FINAL); + return parentClass != null && !method.isConstructor() && !method.isStatic() && !method.isFinal() && !method.isPrivate() + && !(parentClass instanceof PsiAnonymousClass) && !parentClass.isFinal(); } + @RequiredReadAction public static boolean isArrayClass(@Nullable PsiElement psiClass) { return psiClass != null && psiClass.getManager().areElementsEquivalent( psiClass, JavaPsiFacade.getElementFactory(psiClass.getProject()).getArrayClass(getLanguageLevel(psiClass))); diff --git a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/NonClasspathClassFinder.java b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/NonClasspathClassFinder.java index 9f23eae09..7ed3af2d1 100644 --- a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/NonClasspathClassFinder.java +++ b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/NonClasspathClassFinder.java @@ -20,9 +20,9 @@ import com.intellij.java.language.psi.PsiClassOwner; import com.intellij.java.language.psi.PsiElementFinder; import com.intellij.java.language.psi.PsiJavaPackage; +import consulo.annotation.access.RequiredReadAction; import consulo.application.util.LowMemoryWatcher; import consulo.application.util.function.CommonProcessors; -import consulo.application.util.function.Processor; import consulo.component.messagebus.MessageBusConnection; import consulo.java.language.module.extension.JavaModuleExtension; import consulo.language.psi.PsiDirectory; @@ -37,7 +37,7 @@ import consulo.util.collection.ContainerUtil; import consulo.util.collection.MultiMap; import consulo.util.lang.StringUtil; -import consulo.util.lang.ref.Ref; +import consulo.util.lang.ref.SimpleReference; import consulo.virtualFileSystem.VirtualFile; import consulo.virtualFileSystem.event.BulkFileListener; import consulo.virtualFileSystem.event.VFileEvent; @@ -48,6 +48,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.function.Predicate; /** * @author peter @@ -91,8 +92,8 @@ protected PackageDirectoryCache getCache(@Nullable GlobalSearchScope scope) { } @Nonnull - protected static PackageDirectoryCache createCache(@Nonnull final List roots) { - final MultiMap map = MultiMap.create(); + protected static PackageDirectoryCache createCache(@Nonnull List roots) { + MultiMap map = MultiMap.create(); map.putValues("", roots); return new PackageDirectoryCache(map); } @@ -110,21 +111,24 @@ public List getClassRoots() { } @Override - public PsiClass findClass(@Nonnull final String qualifiedName, @Nonnull GlobalSearchScope scope) { - final Ref result = Ref.create(); - processDirectories(StringUtil.getPackageName(qualifiedName), scope, dir -> - { - VirtualFile virtualFile = findChild(dir, StringUtil.getShortName(qualifiedName), myFileExtensions); - final PsiFile file = virtualFile == null ? null : myManager.findFile(virtualFile); - if (file instanceof PsiClassOwner) { - final PsiClass[] classes = ((PsiClassOwner) file).getClasses(); - if (classes.length == 1) { - result.set(classes[0]); - return false; + public PsiClass findClass(@Nonnull String qualifiedName, @Nonnull GlobalSearchScope scope) { + SimpleReference result = SimpleReference.create(); + processDirectories( + StringUtil.getPackageName(qualifiedName), + scope, + dir -> { + VirtualFile virtualFile = findChild(dir, StringUtil.getShortName(qualifiedName), myFileExtensions); + PsiFile file = virtualFile == null ? null : myManager.findFile(virtualFile); + if (file instanceof PsiClassOwner classOwner) { + PsiClass[] classes = classOwner.getClasses(); + if (classes.length == 1) { + result.set(classes[0]); + return false; + } } + return true; } - return true; - }); + ); return result.get(); } @@ -133,42 +137,48 @@ public PsiClass findClass(@Nonnull final String qualifiedName, @Nonnull GlobalSe @Nonnull @Override public PsiClass[] getClasses(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { - final List result = ContainerUtil.newArrayList(); - processDirectories(psiPackage.getQualifiedName(), scope, dir -> - { - for (final VirtualFile file : dir.getChildren()) { - if (!file.isDirectory() && ArrayUtil.contains(file.getExtension(), myFileExtensions)) { - final PsiFile psi = myManager.findFile(file); - if (psi instanceof PsiClassOwner) { - ContainerUtil.addAll(result, ((PsiClassOwner) psi).getClasses()); + List result = new ArrayList<>(); + processDirectories( + psiPackage.getQualifiedName(), + scope, + dir -> { + for (VirtualFile file : dir.getChildren()) { + if (!file.isDirectory() && ArrayUtil.contains(file.getExtension(), myFileExtensions)) { + PsiFile psi = myManager.findFile(file); + if (psi instanceof PsiClassOwner classOwner) { + ContainerUtil.addAll(result, classOwner.getClasses()); + } } } + return true; } - return true; - }); + ); return result.toArray(new PsiClass[result.size()]); } - @Nonnull @Override + @RequiredReadAction public Set getClassNames(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { - final Set result = new HashSet<>(); - processDirectories(psiPackage.getQualifiedName(), scope, dir -> - { - for (final VirtualFile file : dir.getChildren()) { - if (!file.isDirectory() && ArrayUtil.contains(file.getExtension(), myFileExtensions)) { - result.add(file.getNameWithoutExtension()); + Set result = new HashSet<>(); + processDirectories( + psiPackage.getQualifiedName(), + scope, + dir -> { + for (VirtualFile file : dir.getChildren()) { + if (!file.isDirectory() && ArrayUtil.contains(file.getExtension(), myFileExtensions)) { + result.add(file.getNameWithoutExtension()); + } } + return true; } - return true; - }); + ); return result; } @Override public PsiJavaPackage findPackage(@Nonnull String qualifiedName) { - final CommonProcessors.FindFirstProcessor processor = new CommonProcessors.FindFirstProcessor<>(); + CommonProcessors.FindFirstProcessor processor = new CommonProcessors.FindFirstProcessor<>(); processDirectories(qualifiedName, ALL_SCOPE, processor); return processor.getFoundValue() != null ? createPackage(qualifiedName) : null; } @@ -178,24 +188,38 @@ private PsiPackageImpl createPackage(String qualifiedName) { } @Override - public boolean processPackageDirectories(@Nonnull final PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope, @Nonnull final Processor consumer, boolean - includeLibrarySources) { - return processDirectories(psiPackage.getQualifiedName(), scope, dir -> - { - final PsiDirectory psiDirectory = psiPackage.getManager().findDirectory(dir); - return psiDirectory == null || consumer.process(psiDirectory); - }); + public boolean processPackageDirectories( + @Nonnull PsiJavaPackage psiPackage, + @Nonnull GlobalSearchScope scope, + @Nonnull Predicate consumer, + boolean includeLibrarySources + ) { + return processDirectories( + psiPackage.getQualifiedName(), + scope, + dir -> { + PsiDirectory psiDirectory = psiPackage.getManager().findDirectory(dir); + return psiDirectory == null || consumer.test(psiDirectory); + } + ); } - private boolean processDirectories(@Nonnull String qualifiedName, @Nonnull final GlobalSearchScope scope, @Nonnull final Processor processor) { - return ContainerUtil.process(getCache(scope).getDirectoriesByPackageName(qualifiedName), file -> !scope.contains(file) || processor.process(file)); + private boolean processDirectories( + @Nonnull String qualifiedName, + @Nonnull GlobalSearchScope scope, + @Nonnull Predicate processor + ) { + return ContainerUtil.process( + getCache(scope).getDirectoriesByPackageName(qualifiedName), + file -> !scope.contains(file) || processor.test(file) + ); } @Nonnull @Override public PsiJavaPackage[] getSubPackages(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { - final String pkgName = psiPackage.getQualifiedName(); - final Set names = getCache(scope).getSubpackageNames(pkgName); + String pkgName = psiPackage.getQualifiedName(); + Set names = getCache(scope).getSubpackageNames(pkgName); if (names.isEmpty()) { return super.getSubPackages(psiPackage, scope); } @@ -210,7 +234,7 @@ public PsiJavaPackage[] getSubPackages(@Nonnull PsiJavaPackage psiPackage, @Nonn @Nonnull @Override public PsiClass[] findClasses(@Nonnull String qualifiedName, @Nonnull GlobalSearchScope scope) { - final PsiClass psiClass = findClass(qualifiedName, scope); + PsiClass psiClass = findClass(qualifiedName, scope); return psiClass == null ? PsiClass.EMPTY_ARRAY : new PsiClass[]{psiClass}; } @@ -218,8 +242,8 @@ public PsiClass[] findClasses(@Nonnull String qualifiedName, @Nonnull GlobalSear public static GlobalSearchScope addNonClasspathScope(@Nonnull Project project, @Nonnull GlobalSearchScope base) { GlobalSearchScope scope = base; for (PsiElementFinder finder : project.getExtensionList(PsiElementFinder.class)) { - if (finder instanceof NonClasspathClassFinder) { - scope = scope.uniteWith(NonClasspathDirectoriesScope.compose(((NonClasspathClassFinder) finder).getClassRoots())); + if (finder instanceof NonClasspathClassFinder nonClasspathClassFinder) { + scope = scope.uniteWith(NonClasspathDirectoriesScope.compose(nonClasspathClassFinder.getClassRoots())); } } return scope; diff --git a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/DefaultPsiElementFinderImpl.java b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/DefaultPsiElementFinderImpl.java index 4ced69b80..453354d9c 100644 --- a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/DefaultPsiElementFinderImpl.java +++ b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/DefaultPsiElementFinderImpl.java @@ -6,7 +6,6 @@ import consulo.annotation.component.ExtensionImpl; import consulo.application.dumb.DumbAware; import consulo.application.util.ReadActionProcessor; -import consulo.application.util.function.Processor; import consulo.language.content.FileIndexFacade; import consulo.language.psi.*; import consulo.language.psi.scope.GlobalSearchScope; @@ -22,6 +21,7 @@ import jakarta.inject.Inject; import java.util.*; +import java.util.function.Predicate; /** * @author VISTALL @@ -57,14 +57,14 @@ public PsiJavaPackage findPackage(@Nonnull String qualifiedName) { @Override @Nonnull public PsiJavaPackage[] getSubPackages(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { - final Map packagesMap = new HashMap<>(); - final String qualifiedName = psiPackage.getQualifiedName(); + Map packagesMap = new HashMap<>(); + String qualifiedName = psiPackage.getQualifiedName(); for (PsiDirectory dir : psiPackage.getDirectories(scope)) { PsiDirectory[] subDirs = dir.getSubdirectories(); for (PsiDirectory subDir : subDirs) { - final PsiJavaPackage aPackage = JavaDirectoryService.getInstance().getPackage(subDir); + PsiJavaPackage aPackage = JavaDirectoryService.getInstance().getPackage(subDir); if (aPackage != null) { - final String subQualifiedName = aPackage.getQualifiedName(); + String subQualifiedName = aPackage.getQualifiedName(); if (subQualifiedName.startsWith(qualifiedName) && !packagesMap.containsKey(subQualifiedName)) { packagesMap.put(aPackage.getQualifiedName(), aPackage); } @@ -76,15 +76,17 @@ public PsiJavaPackage[] getSubPackages(@Nonnull PsiJavaPackage psiPackage, @Nonn return packagesMap.values().toArray(new PsiJavaPackage[packagesMap.size()]); } - @Override @Nonnull - public PsiClass[] getClasses(@Nonnull PsiJavaPackage psiPackage, @Nonnull final GlobalSearchScope scope) { + @Override + @RequiredReadAction + public PsiClass[] getClasses(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { return getClasses(null, psiPackage, scope); } - @Override @Nonnull - public PsiClass[] getClasses(@Nullable String shortName, @Nonnull PsiJavaPackage psiPackage, @Nonnull final GlobalSearchScope scope) { + @Override + @RequiredReadAction + public PsiClass[] getClasses(@Nullable String shortName, @Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { List list = null; String packageName = psiPackage.getQualifiedName(); for (PsiDirectory dir : psiPackage.getDirectories(scope)) { @@ -125,6 +127,7 @@ public PsiClass[] getClasses(@Nullable String shortName, @Nonnull PsiJavaPackage @Nonnull @Override + @RequiredReadAction public Set getClassNames(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { Set names = null; FileIndexFacade facade = FileIndexFacade.getInstance(myProject); @@ -132,15 +135,16 @@ public Set getClassNames(@Nonnull PsiJavaPackage psiPackage, @Nonnull Gl for (PsiFile file : dir.getFiles()) { if (file instanceof PsiClassOwner && file.getViewProvider().getLanguages().size() == 1) { VirtualFile vFile = file.getVirtualFile(); - if (vFile != null && - !(file instanceof PsiCompiledElement) && - !facade.isInSourceContent(vFile) && - (!scope.isForceSearchingInLibrarySources() || !StubTreeLoader.getInstance().canHaveStub(vFile))) { + if (vFile != null + && !(file instanceof PsiCompiledElement) + && !facade.isInSourceContent(vFile) + && (!scope.isForceSearchingInLibrarySources() || !StubTreeLoader.getInstance().canHaveStub(vFile))) { continue; } - Set inFile = - file instanceof PsiClassOwnerEx ? ((PsiClassOwnerEx)file).getClassNames() : getClassNames(((PsiClassOwner)file).getClasses()); + Set inFile = file instanceof PsiClassOwnerEx classOwnerEx + ? classOwnerEx.getClassNames() + : getClassNames(((PsiClassOwner)file).getClasses()); if (inFile.isEmpty()) { continue; @@ -160,21 +164,21 @@ public Set getClassNames(@Nonnull PsiJavaPackage psiPackage, @Nonnull Gl @Override public boolean processPackageDirectories( @Nonnull PsiJavaPackage psiPackage, - @Nonnull final GlobalSearchScope scope, - @Nonnull final Processor consumer + @Nonnull GlobalSearchScope scope, + @Nonnull Predicate consumer ) { - final PsiManager psiManager = PsiManager.getInstance(myProject); + PsiManager psiManager = PsiManager.getInstance(myProject); return DirectoryIndex.getInstance(myProject) .getDirectoriesByPackageName(psiPackage.getQualifiedName(), false) .forEach(new ReadActionProcessor<>() { @RequiredReadAction @Override - public boolean processInReadAction(final VirtualFile dir) { + public boolean processInReadAction(VirtualFile dir) { if (!scope.contains(dir)) { return true; } PsiDirectory psiDir = psiManager.findDirectory(dir); - return psiDir == null || consumer.process(psiDir); + return psiDir == null || consumer.test(psiDir); } }); } diff --git a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/JavaPsiFacadeImpl.java b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/JavaPsiFacadeImpl.java index ad1af64b0..63e89786e 100644 --- a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/JavaPsiFacadeImpl.java +++ b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/JavaPsiFacadeImpl.java @@ -20,9 +20,9 @@ import com.intellij.java.language.impl.psi.impl.source.tree.JavaElementType; import com.intellij.java.language.psi.PsiElementFactory; import com.intellij.java.language.psi.*; +import consulo.annotation.access.RequiredReadAction; import consulo.annotation.component.ServiceImpl; import consulo.application.progress.ProgressIndicatorProvider; -import consulo.application.util.function.Processor; import consulo.java.language.module.extension.JavaModuleExtension; import consulo.language.psi.*; import consulo.language.psi.scope.GlobalSearchScope; @@ -84,7 +84,8 @@ public JavaPsiFacadeImpl( } @Override - public PsiClass findClass(@Nonnull final String qualifiedName, @Nonnull GlobalSearchScope scope) { + @RequiredReadAction + public PsiClass findClass(@Nonnull String qualifiedName, @Nonnull GlobalSearchScope scope) { ProgressIndicatorProvider.checkCanceled(); // We hope this method is being called often enough to cancel daemon processes smoothly if (DumbService.getInstance(getProject()).isDumb()) { @@ -106,10 +107,11 @@ public PsiClass findClass(@Nonnull final String qualifiedName, @Nonnull GlobalSe } @Nonnull + @RequiredReadAction private PsiClass[] findClassesInDumbMode(@Nonnull String qualifiedName, @Nonnull GlobalSearchScope scope) { - final String packageName = StringUtil.getPackageName(qualifiedName); - final PsiJavaPackage pkg = findPackage(packageName); - final String className = StringUtil.getShortName(qualifiedName); + String packageName = StringUtil.getPackageName(qualifiedName); + PsiJavaPackage pkg = findPackage(packageName); + String className = StringUtil.getShortName(qualifiedName); if (pkg == null && packageName.length() < qualifiedName.length()) { PsiClass[] containingClasses = findClassesInDumbMode(packageName, scope); if (containingClasses.length == 1) { @@ -126,8 +128,9 @@ private PsiClass[] findClassesInDumbMode(@Nonnull String qualifiedName, @Nonnull return pkg.findClassByShortName(className, scope); } - @Override @Nonnull + @Override + @RequiredReadAction public PsiClass[] findClasses(@Nonnull String qualifiedName, @Nonnull GlobalSearchScope scope) { if (DumbService.getInstance(getProject()).isDumb()) { return findClassesInDumbMode(qualifiedName, scope); @@ -147,13 +150,14 @@ private List finders() { return myProject.getExtensionList(PsiElementFinder.class); } - @Override @Nonnull + @Override public PsiConstantEvaluationHelper getConstantEvaluationHelper() { return myConstantEvaluationHelper; } @Override + @RequiredReadAction public PsiJavaPackage findPackage(@Nonnull String qualifiedName) { for (PsiElementFinder elementFinder : filteredFinders()) { PsiJavaPackage aPackage = elementFinder.findPackage(qualifiedName); @@ -223,6 +227,7 @@ public PsiNameHelper getNameHelper() { } @Nonnull + @RequiredReadAction public Set getClassNames(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { Set result = new HashSet<>(); for (PsiElementFinder finder : filteredFinders()) { @@ -249,6 +254,7 @@ public PsiClass[] getClasses(@Nonnull PsiJavaPackage psiPackage, @Nonnull Global } @Nonnull + @RequiredReadAction public PsiFile[] getPackageFiles(@Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope) { Predicate filter = null; @@ -259,7 +265,7 @@ public PsiFile[] getPackageFiles(@Nonnull PsiJavaPackage psiPackage, @Nonnull Gl filter = finderFilter; } else { - final Predicate oldFilter = filter; + Predicate oldFilter = filter; filter = psiFile -> oldFilter.test(psiFile) && finderFilter.test(psiFile); } } @@ -284,7 +290,7 @@ public PsiFile[] getPackageFiles(@Nonnull PsiJavaPackage psiPackage, @Nonnull Gl public boolean processPackageDirectories( @Nonnull PsiJavaPackage psiPackage, @Nonnull GlobalSearchScope scope, - @Nonnull Processor consumer + @Nonnull Predicate consumer ) { for (PsiElementFinder finder : filteredFinders()) { if (!finder.processPackageDirectories(psiPackage, scope, consumer)) { @@ -294,6 +300,7 @@ public boolean processPackageDirectories( return true; } + @RequiredReadAction public PsiClass[] findClassByShortName(String name, PsiJavaPackage psiPackage, GlobalSearchScope scope) { List result = null; for (PsiElementFinder finder : filteredFinders()) { @@ -313,8 +320,8 @@ public PsiClass[] findClassByShortName(String name, PsiJavaPackage psiPackage, G @Override public boolean isPartOfPackagePrefix(@Nonnull String packageName) { - final Collection packagePrefixes = JavaFileManager.getInstance(myProject).getNonTrivialPackagePrefixes(); - for (final String subpackageName : packagePrefixes) { + Collection packagePrefixes = JavaFileManager.getInstance(myProject).getNonTrivialPackagePrefixes(); + for (String subpackageName : packagePrefixes) { if (isSubpackageOf(subpackageName, packageName)) { return true; } @@ -328,12 +335,12 @@ private static boolean isSubpackageOf(@Nonnull String subpackageName, @Nonnull S @Override public boolean isInPackage(@Nonnull PsiElement element, @Nonnull PsiJavaPackage aPackage) { - final PsiFile file = FileContextUtil.getContextFile(element); - if (file instanceof JavaDummyHolder) { - return ((JavaDummyHolder)file).isInPackage(aPackage); + PsiFile file = FileContextUtil.getContextFile(element); + if (file instanceof JavaDummyHolder javaDummyHolder) { + return javaDummyHolder.isInPackage(aPackage); } - if (file instanceof PsiJavaFile) { - final String packageName = ((PsiJavaFile)file).getPackageName(); + if (file instanceof PsiJavaFile javaFile) { + String packageName = javaFile.getPackageName(); return packageName.equals(aPackage.getQualifiedName()); } return false; @@ -354,15 +361,8 @@ public boolean arePackagesTheSame(@Nonnull PsiElement element1, @Nonnull PsiElem PsiElement other = file1 instanceof JavaDummyHolder ? file2 : file1; return dummyHolder.isSamePackage(other); } - if (!(file1 instanceof PsiClassOwner)) { - return false; - } - if (!(file2 instanceof PsiClassOwner)) { - return false; - } - String package1 = ((PsiClassOwner)file1).getPackageName(); - String package2 = ((PsiClassOwner)file2).getPackageName(); - return Comparing.equal(package1, package2); + return file1 instanceof PsiClassOwner pco1 && file2 instanceof PsiClassOwner pco2 + && Objects.equals(pco1.getPackageName(), pco2.getPackageName()); } @Override diff --git a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/PsiImplUtil.java b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/PsiImplUtil.java index d6983eebc..4f513f943 100644 --- a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/PsiImplUtil.java +++ b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/PsiImplUtil.java @@ -29,7 +29,9 @@ import com.intellij.java.language.psi.javadoc.PsiDocComment; import com.intellij.java.language.psi.search.PackageScope; import com.intellij.java.language.psi.util.PsiUtil; -import consulo.application.ApplicationManager; +import consulo.annotation.access.RequiredReadAction; +import consulo.annotation.access.RequiredWriteAction; +import consulo.application.Application; import consulo.content.scope.SearchScope; import consulo.language.ast.ASTNode; import consulo.language.ast.FileASTNode; @@ -57,13 +59,12 @@ import consulo.util.dataholder.Key; import consulo.util.lang.Comparing; import consulo.util.lang.StringUtil; -import consulo.util.lang.function.PairFunction; import consulo.virtualFileSystem.VirtualFile; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; -import org.jetbrains.annotations.NonNls; import java.util.*; +import java.util.function.BiFunction; import java.util.function.Function; import static com.intellij.java.language.psi.PsiAnnotation.TargetType; @@ -110,7 +111,7 @@ private static PsiAnnotationMemberValue findDeclaredAttributeValueImpl( PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes(); for (PsiNameValuePair attribute : attributes) { - final String name = attribute.getName(); + String name = attribute.getName(); if (Objects.equals(name, attributeName) || attributeName == null && PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(name)) { return valueGetter.apply(attribute); } @@ -119,8 +120,9 @@ private static PsiAnnotationMemberValue findDeclaredAttributeValueImpl( } @Nullable - public static PsiAnnotationMemberValue findAttributeValue(@Nonnull PsiAnnotation annotation, @Nullable @NonNls String attributeName) { - final PsiAnnotationMemberValue value = findDeclaredAttributeValue(annotation, attributeName); + @RequiredReadAction + public static PsiAnnotationMemberValue findAttributeValue(@Nonnull PsiAnnotation annotation, @Nullable String attributeName) { + PsiAnnotationMemberValue value = findDeclaredAttributeValue(annotation, attributeName); if (value != null) { return value; } @@ -128,15 +130,12 @@ public static PsiAnnotationMemberValue findAttributeValue(@Nonnull PsiAnnotation if (attributeName == null) { attributeName = "value"; } - final PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement(); - if (referenceElement != null) { - PsiElement resolved = referenceElement.resolve(); - if (resolved != null) { - PsiMethod[] methods = ((PsiClass)resolved).findMethodsByName(attributeName, false); - for (PsiMethod method : methods) { - if (PsiUtil.isAnnotationMethod(method)) { - return ((PsiAnnotationMethod)method).getDefaultValue(); - } + PsiJavaCodeReferenceElement refElem = annotation.getNameReferenceElement(); + if (refElem != null && refElem.resolve() instanceof PsiClass resolvedClass) { + PsiMethod[] methods = resolvedClass.findMethodsByName(attributeName, false); + for (PsiMethod method : methods) { + if (PsiUtil.isAnnotationMethod(method)) { + return ((PsiAnnotationMethod)method).getDefaultValue(); } } } @@ -145,7 +144,7 @@ public static PsiAnnotationMemberValue findAttributeValue(@Nonnull PsiAnnotation @Nonnull public static PsiTypeParameter[] getTypeParameters(@Nonnull PsiTypeParameterListOwner owner) { - final PsiTypeParameterList typeParameterList = owner.getTypeParameterList(); + PsiTypeParameterList typeParameterList = owner.getTypeParameterList(); if (typeParameterList != null) { return typeParameterList.getTypeParameters(); } @@ -187,13 +186,18 @@ public static int getParameterIndex(@Nonnull PsiParameter parameter, @Nonnull Ps break; } } - String message = - parameter + ":" + parameter.getClass() + " not found among parameters: " + Arrays.asList(parameters) + "." + " parameterList' parent: " + parameterList.getParent() + ";" + - "" + " parameter.isValid()=" + parameter.isValid() + ";" + " parameterList.isValid()= " + parameterList.isValid() + ";" + " parameterList stub: " + (parameterList instanceof - StubBasedPsiElement ? ((StubBasedPsiElement)parameterList).getStub() : "---") + "; " + " parameter stub: " + (parameter instanceof StubBasedPsiElement ? ((StubBasedPsiElement) - parameter).getStub() : "---") + ";" + " suspect: " + suspect + " (index=" + i + "); " + (suspect == null ? null : suspect.getClass()) + " suspect stub: " + (suspect instanceof - StubBasedPsiElement ? ((StubBasedPsiElement)suspect).getStub() : suspect == null ? "-null-" : "---" + suspect.getClass()) + ";" + " parameter.equals(suspect) = " + parameter.equals - (suspect) + "; " + " parameter.getNode() == suspect.getNode(): " + (parameter.getNode() == (suspect == null ? null : suspect.getNode())) + "; " + "."; + String message = parameter + ":" + parameter.getClass() + " not found among parameters: " + Arrays.asList(parameters) + "." + + " parameterList' parent: " + parameterList.getParent() + ";" + + " parameter.isValid()=" + parameter.isValid() + ";" + + " parameterList.isValid()= " + parameterList.isValid() + ";" + + " parameterList stub: " + (parameterList instanceof StubBasedPsiElement sbpe ? sbpe.getStub() : "---") + "; " + + " parameter stub: " + (parameter instanceof StubBasedPsiElement sbpe ? sbpe.getStub() : "---") + ";" + + " suspect: " + suspect + " (index=" + i + "); " + + (suspect == null ? null : suspect.getClass()) + " suspect stub: " + + (suspect instanceof StubBasedPsiElement sbpe ? sbpe.getStub() : suspect == null ? "-null-" : "---" + suspect.getClass()) + ";" + + " parameter.equals(suspect) = " + parameter.equals(suspect) + "; " + + " parameter.getNode() == suspect.getNode(): " + + (parameter.getNode() == (suspect == null ? null : suspect.getNode())) + "; " + "."; LOG.error(message); return i; } @@ -217,40 +221,40 @@ public static Object[] getReferenceVariantsByFilter(@Nonnull PsiJavaCodeReferenc } public static boolean processDeclarationsInMethod( - @Nonnull final PsiMethod method, - @Nonnull final PsiScopeProcessor processor, - @Nonnull final ResolveState state, - final PsiElement lastParent, - @Nonnull final PsiElement place + @Nonnull PsiMethod method, + @Nonnull PsiScopeProcessor processor, + @Nonnull ResolveState state, + PsiElement lastParent, + @Nonnull PsiElement place ) { - final boolean fromBody = lastParent instanceof PsiCodeBlock; - final PsiTypeParameterList typeParameterList = method.getTypeParameterList(); + boolean fromBody = lastParent instanceof PsiCodeBlock; + PsiTypeParameterList typeParameterList = method.getTypeParameterList(); return processDeclarationsInMethodLike(method, processor, state, place, fromBody, typeParameterList); } public static boolean processDeclarationsInLambda( - @Nonnull final PsiLambdaExpression lambda, - @Nonnull final PsiScopeProcessor processor, - @Nonnull final ResolveState state, - final PsiElement lastParent, - @Nonnull final PsiElement place + @Nonnull PsiLambdaExpression lambda, + @Nonnull PsiScopeProcessor processor, + @Nonnull ResolveState state, + PsiElement lastParent, + @Nonnull PsiElement place ) { - final boolean fromBody = lastParent != null && lastParent == lambda.getBody(); + boolean fromBody = lastParent != null && lastParent == lambda.getBody(); return processDeclarationsInMethodLike(lambda, processor, state, place, fromBody, null); } private static boolean processDeclarationsInMethodLike( - @Nonnull final PsiParameterListOwner element, - @Nonnull final PsiScopeProcessor processor, - @Nonnull final ResolveState state, - @Nonnull final PsiElement place, - final boolean fromBody, - @Nullable final PsiTypeParameterList typeParameterList + @Nonnull PsiParameterListOwner element, + @Nonnull PsiScopeProcessor processor, + @Nonnull ResolveState state, + @Nonnull PsiElement place, + boolean fromBody, + @Nullable PsiTypeParameterList typeParameterList ) { processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, element); if (typeParameterList != null) { - final ElementClassHint hint = processor.getHint(ElementClassHint.KEY); + ElementClassHint hint = processor.getHint(ElementClassHint.KEY); if (hint == null || hint.shouldProcess(ElementClassHint.DeclarationKind.CLASS)) { if (!typeParameterList.processDeclarations(processor, state, null, place)) { return false; @@ -259,7 +263,7 @@ private static boolean processDeclarationsInMethodLike( } if (fromBody) { - final PsiParameter[] parameters = element.getParameterList().getParameters(); + PsiParameter[] parameters = element.getParameterList().getParameters(); for (PsiParameter parameter : parameters) { if (!processor.execute(parameter, state)) { return false; @@ -271,12 +275,12 @@ private static boolean processDeclarationsInMethodLike( } public static boolean processDeclarationsInResourceList( - @Nonnull final PsiResourceList resourceList, - @Nonnull final PsiScopeProcessor processor, - @Nonnull final ResolveState state, - final PsiElement lastParent + @Nonnull PsiResourceList resourceList, + @Nonnull PsiScopeProcessor processor, + @Nonnull ResolveState state, + PsiElement lastParent ) { - final ElementClassHint hint = processor.getHint(ElementClassHint.KEY); + ElementClassHint hint = processor.getHint(ElementClassHint.KEY); if (hint != null && !hint.shouldProcess(ElementClassHint.DeclarationKind.VARIABLE)) { return true; } @@ -294,7 +298,7 @@ public static boolean processDeclarationsInResourceList( } public static boolean hasTypeParameters(@Nonnull PsiTypeParameterListOwner owner) { - final PsiTypeParameterList typeParameterList = owner.getTypeParameterList(); + PsiTypeParameterList typeParameterList = owner.getTypeParameterList(); return typeParameterList != null && typeParameterList.getTypeParameters().length != 0; } @@ -311,17 +315,18 @@ public static PsiType[] typesByTypeElements(@Nonnull PsiTypeElement[] typeElemen for (int i = 0; i < types.length; i++) { types[i] = typeElements[i].getType(); } - if (types.length == 1 && types[0] instanceof PsiDiamondType) { - return ((PsiDiamondType)types[0]).resolveInferredTypes().getTypes(); + if (types.length == 1 && types[0] instanceof PsiDiamondType diamondType) { + return diamondType.resolveInferredTypes().getTypes(); } return types; } @Nonnull + @RequiredReadAction public static PsiType getType(@Nonnull PsiClassObjectAccessExpression classAccessExpression) { GlobalSearchScope resolveScope = classAccessExpression.getResolveScope(); PsiManager manager = classAccessExpression.getManager(); - final PsiClass classClass = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.lang.Class", resolveScope); + PsiClass classClass = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.lang.Class", resolveScope); if (classClass == null) { return new PsiClassReferenceType(new LightClassReference(manager, "Class", "java.lang.Class", resolveScope), null); } @@ -332,17 +337,17 @@ public static PsiType getType(@Nonnull PsiClassObjectAccessExpression classAcces PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; PsiType operandType = classAccessExpression.getOperand().getType(); - if (operandType instanceof PsiPrimitiveType && !PsiType.NULL.equals(operandType)) { - if (PsiType.VOID.equals(operandType)) { + if (operandType instanceof PsiPrimitiveType primitiveType && !PsiType.NULL.equals(primitiveType)) { + if (PsiType.VOID.equals(primitiveType)) { operandType = JavaPsiFacade.getInstance(manager.getProject()) .getElementFactory() .createTypeByFQClassName("java.lang.Void", classAccessExpression.getResolveScope()); } else { - operandType = ((PsiPrimitiveType)operandType).getBoxedType(classAccessExpression); + operandType = primitiveType.getBoxedType(classAccessExpression); } } - final PsiTypeParameter[] typeParameters = classClass.getTypeParameters(); + PsiTypeParameter[] typeParameters = classClass.getTypeParameters(); if (typeParameters.length == 1) { substitutor = substitutor.put(typeParameters[0], operandType); } @@ -426,15 +431,15 @@ public static PsiType normalizeWildcardTypeByPosition(@Nonnull PsiType type, @No PsiUtil.ensureValidType(type); PsiExpression topLevel = expression; - while (topLevel.getParent() instanceof PsiArrayAccessExpression && ((PsiArrayAccessExpression)topLevel.getParent()).getArrayExpression() == topLevel) { - topLevel = (PsiExpression)topLevel.getParent(); + while (topLevel.getParent() instanceof PsiArrayAccessExpression arrayAccess && arrayAccess.getArrayExpression() == topLevel) { + topLevel = arrayAccess; } if (topLevel instanceof PsiArrayAccessExpression && !PsiUtil.isAccessedForWriting(topLevel)) { return PsiUtil.captureToplevelWildcards(type, expression); } - final PsiType normalized = doNormalizeWildcardByPosition(type, expression, topLevel); + PsiType normalized = doNormalizeWildcardByPosition(type, expression, topLevel); LOG.assertTrue(normalized.isValid(), type); if (normalized instanceof PsiClassType && !PsiUtil.isAccessedForWriting(topLevel)) { return PsiUtil.captureToplevelWildcards(normalized, expression); @@ -444,40 +449,36 @@ public static PsiType normalizeWildcardTypeByPosition(@Nonnull PsiType type, @No } private static PsiType doNormalizeWildcardByPosition(PsiType type, @Nonnull PsiExpression expression, PsiExpression topLevel) { - if (type instanceof PsiCapturedWildcardType) { - final PsiWildcardType wildcardType = ((PsiCapturedWildcardType)type).getWildcard(); + if (type instanceof PsiCapturedWildcardType capturedWildcardType) { + PsiWildcardType wildcardType = capturedWildcardType.getWildcard(); if (expression instanceof PsiReferenceExpression && LambdaUtil.isLambdaReturnExpression(expression)) { - return type; + return capturedWildcardType; } if (PsiUtil.isAccessedForWriting(topLevel)) { return wildcardType.isSuper() ? wildcardType.getBound() : PsiCapturedWildcardType.create(wildcardType, expression); } else { - final PsiType upperBound = ((PsiCapturedWildcardType)type).getUpperBound(); + PsiType upperBound = capturedWildcardType.getUpperBound(); return upperBound instanceof PsiWildcardType ? doNormalizeWildcardByPosition(upperBound, expression, topLevel) : upperBound; } } - if (type instanceof PsiWildcardType) { - final PsiWildcardType wildcardType = (PsiWildcardType)type; - + if (type instanceof PsiWildcardType wildcardType) { if (PsiUtil.isAccessedForWriting(topLevel)) { return wildcardType.isSuper() ? wildcardType.getBound() : PsiCapturedWildcardType.create(wildcardType, expression); } + else if (wildcardType.isExtends()) { + return wildcardType.getBound(); + } else { - if (wildcardType.isExtends()) { - return wildcardType.getBound(); - } - else { - return PsiType.getJavaLangObject(expression.getManager(), expression.getResolveScope()); - } + return PsiType.getJavaLangObject(expression.getManager(), expression.getResolveScope()); } } - else if (type instanceof PsiArrayType) { - final PsiType componentType = ((PsiArrayType)type).getComponentType(); - final PsiType normalizedComponentType = doNormalizeWildcardByPosition(componentType, expression, topLevel); + else if (type instanceof PsiArrayType arrayType) { + PsiType componentType = arrayType.getComponentType(); + PsiType normalizedComponentType = doNormalizeWildcardByPosition(componentType, expression, topLevel); if (normalizedComponentType != componentType) { return normalizedComponentType.createArrayType(); } @@ -487,17 +488,17 @@ else if (type instanceof PsiArrayType) { } @Nonnull + @RequiredReadAction public static SearchScope getMemberUseScope(@Nonnull PsiMember member) { PsiFile file = member.getContainingFile(); PsiElement topElement = file == null ? member : file; Project project = topElement.getProject(); - final GlobalSearchScope maximalUseScope = ResolveScopeManager.getInstance(project).getUseScope(topElement); + GlobalSearchScope maximalUseScope = ResolveScopeManager.getInstance(project).getUseScope(topElement); if (isInServerPage(file)) { return maximalUseScope; } - PsiClass aClass = member.getContainingClass(); - if (aClass instanceof PsiAnonymousClass) { + if (member.getContainingClass() instanceof PsiAnonymousClass aClass) { //member from anonymous class can be called from outside the class PsiElement methodCallExpr = PsiUtil.isLanguageLevel8OrHigher(aClass) ? PsiTreeUtil.getTopmostParentOfType(aClass, PsiStatement.class) @@ -514,8 +515,8 @@ public static SearchScope getMemberUseScope(@Nonnull PsiMember member) { PsiClass topClass = PsiUtil.getTopLevelClass(member); return topClass != null ? new LocalSearchScope(topClass) : file == null ? maximalUseScope : new LocalSearchScope(file); } - if (file instanceof PsiJavaFile) { - PsiJavaPackage aPackage = JavaPsiFacade.getInstance(project).findPackage(((PsiJavaFile)file).getPackageName()); + if (file instanceof PsiJavaFile javaFile) { + PsiJavaPackage aPackage = JavaPsiFacade.getInstance(project).findPackage(javaFile.getPackageName()); if (aPackage != null) { SearchScope scope = PackageScope.packageScope(aPackage, false); return scope.intersectWith(maximalUseScope); @@ -524,16 +525,17 @@ public static SearchScope getMemberUseScope(@Nonnull PsiMember member) { return maximalUseScope; } - public static boolean isInServerPage(@Nullable final PsiElement element) { + public static boolean isInServerPage(@Nullable PsiElement element) { return getServerPageFile(element) != null; } @Nullable - public static ServerPageFile getServerPageFile(final PsiElement element) { - final PsiFile psiFile = PsiUtilCore.getTemplateLanguageFile(element); - return psiFile instanceof ServerPageFile ? (ServerPageFile)psiFile : null; + public static ServerPageFile getServerPageFile(PsiElement element) { + PsiFile psiFile = PsiUtilCore.getTemplateLanguageFile(element); + return psiFile instanceof ServerPageFile serverPageFile ? serverPageFile : null; } + @RequiredWriteAction public static PsiElement setName(@Nonnull PsiElement element, @Nonnull String name) throws IncorrectOperationException { PsiManager manager = element.getManager(); PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); @@ -553,22 +555,19 @@ public static boolean isDeprecatedByDocTag(@Nonnull PsiJavaDocumentedElement own @Nullable public static PsiJavaDocumentedElement findDocCommentOwner(@Nonnull PsiDocComment comment) { - PsiElement parent = comment.getParent(); - if (parent instanceof PsiJavaDocumentedElement) { - PsiJavaDocumentedElement owner = (PsiJavaDocumentedElement)parent; - if (owner.getDocComment() == comment) { - return owner; - } + if (comment.getParent() instanceof PsiJavaDocumentedElement owner && owner.getDocComment() == comment) { + return owner; } return null; } @Nullable + @RequiredReadAction public static PsiAnnotationMemberValue setDeclaredAttributeValue( @Nonnull PsiAnnotation psiAnnotation, @Nullable String attributeName, @Nullable PsiAnnotationMemberValue value, - @Nonnull PairFunction annotationCreator + @Nonnull BiFunction annotationCreator ) { PsiAnnotationMemberValue existing = psiAnnotation.findDeclaredAttributeValue(attributeName); if (value == null) { @@ -577,54 +576,54 @@ public static PsiAnnotationMemberValue setDeclaredAttributeValue( } existing.getParent().delete(); } + else if (existing != null) { + ((PsiNameValuePair)existing.getParent()).setValue(value); + } else { - if (existing != null) { - ((PsiNameValuePair)existing.getParent()).setValue(value); - } - else { - PsiNameValuePair[] attributes = psiAnnotation.getParameterList().getAttributes(); - if (attributes.length == 1) { - PsiNameValuePair attribute = attributes[0]; - if (attribute.getName() == null) { - PsiAnnotationMemberValue defValue = attribute.getValue(); - assert defValue != null : attribute; - attribute.replace(createNameValuePair( - defValue, - PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME + "=", - annotationCreator - )); - } + PsiNameValuePair[] attributes = psiAnnotation.getParameterList().getAttributes(); + if (attributes.length == 1) { + PsiNameValuePair attribute = attributes[0]; + if (attribute.getName() == null) { + PsiAnnotationMemberValue defValue = attribute.getValue(); + assert defValue != null : attribute; + attribute.replace(createNameValuePair( + defValue, + PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME + "=", + annotationCreator + )); } + } - boolean allowNoName = attributes.length == 0 && ("value".equals(attributeName) || null == attributeName); - final String namePrefix; - if (allowNoName) { - namePrefix = ""; - } - else { - namePrefix = attributeName + "="; - } - psiAnnotation.getParameterList().addBefore(createNameValuePair(value, namePrefix, annotationCreator), null); + boolean allowNoName = attributes.length == 0 && ("value".equals(attributeName) || null == attributeName); + String namePrefix; + if (allowNoName) { + namePrefix = ""; + } + else { + namePrefix = attributeName + "="; } + psiAnnotation.getParameterList().addBefore(createNameValuePair(value, namePrefix, annotationCreator), null); } return psiAnnotation.findDeclaredAttributeValue(attributeName); } + @RequiredReadAction private static PsiNameValuePair createNameValuePair( @Nonnull PsiAnnotationMemberValue value, @Nonnull String namePrefix, - @Nonnull PairFunction annotationCreator + @Nonnull BiFunction annotationCreator ) { - return annotationCreator.fun(value.getProject(), "@A(" + namePrefix + value.getText() + ")").getParameterList().getAttributes()[0]; + return annotationCreator.apply(value.getProject(), "@A(" + namePrefix + value.getText() + ")") + .getParameterList().getAttributes()[0]; } @Nullable - public static ASTNode skipWhitespaceAndComments(final ASTNode node) { + public static ASTNode skipWhitespaceAndComments(ASTNode node) { return skipWhitespaceCommentsAndTokens(node, TokenSet.EMPTY); } @Nullable - public static ASTNode skipWhitespaceCommentsAndTokens(final ASTNode node, TokenSet alsoSkip) { + public static ASTNode skipWhitespaceCommentsAndTokens(ASTNode node, TokenSet alsoSkip) { ASTNode element = node; while (true) { if (element == null) { @@ -641,8 +640,8 @@ public static ASTNode skipWhitespaceCommentsAndTokens(final ASTNode node, TokenS @Nullable public static PsiSwitchExpression findEnclosingSwitchExpression(@Nonnull PsiElement start) { for (PsiElement e = start; !isCodeBoundary(e); e = e.getParent()) { - if (e instanceof PsiSwitchExpression) { - return (PsiSwitchExpression)e; + if (e instanceof PsiSwitchExpression switchExpr) { + return switchExpr; } } return null; @@ -657,7 +656,7 @@ public static boolean isWhitespaceOrComment(ASTNode element) { } @Nullable - public static ASTNode skipWhitespaceAndCommentsBack(final ASTNode node) { + public static ASTNode skipWhitespaceAndCommentsBack(ASTNode node) { if (node == null) { return null; } @@ -688,9 +687,10 @@ public static ASTNode skipWhitespaceAndCommentsBack(final ASTNode node) { } @Nullable + @RequiredReadAction public static ASTNode findStatementChild(CompositePsiElement statement) { if (DebugUtil.CHECK_INSIDE_ATOMIC_ACTION_ENABLED) { - ApplicationManager.getApplication().assertReadAccessAllowed(); + statement.getApplication().assertReadAccessAllowed(); } for (ASTNode element = statement.getFirstChildNode(); element != null; element = element.getTreeNext()) { if (element.getPsi() instanceof PsiStatement) { @@ -700,8 +700,9 @@ public static ASTNode findStatementChild(CompositePsiElement statement) { return null; } + @RequiredReadAction public static PsiStatement[] getChildStatements(CompositeElement psiCodeBlock) { - ApplicationManager.getApplication().assertReadAccessAllowed(); + Application.get().assertReadAccessAllowed(); // no lock is needed because all chameleons are expanded already int count = 0; for (ASTNode child1 = psiCodeBlock.getFirstChildNode(); child1 != null; child1 = child1.getTreeNext()) { @@ -717,8 +718,8 @@ public static PsiStatement[] getChildStatements(CompositeElement psiCodeBlock) { int idx = 0; for (ASTNode child = psiCodeBlock.getFirstChildNode(); child != null && idx < count; child = child.getTreeNext()) { PsiElement element = child.getPsi(); - if (element instanceof PsiStatement) { - result[idx++] = (PsiStatement)element; + if (element instanceof PsiStatement stmt) { + result[idx++] = stmt; } } return result; @@ -730,24 +731,21 @@ public static boolean isVarArgs(@Nonnull PsiMethod method) { } public static PsiElement handleMirror(PsiElement element) { - return element instanceof PsiMirrorElement ? ((PsiMirrorElement)element).getPrototype() : element; + return element instanceof PsiMirrorElement mirrorElem ? mirrorElem.getPrototype() : element; } @Nullable public static PsiModifierList findNeighbourModifierList(@Nonnull PsiJavaCodeReferenceElement ref) { - PsiElement parent = PsiTreeUtil.skipParentsOfType(ref, PsiJavaCodeReferenceElement.class); - if (parent instanceof PsiTypeElement) { - PsiElement grandParent = parent.getParent(); - if (grandParent instanceof PsiModifierListOwner) { - return ((PsiModifierListOwner)grandParent).getModifierList(); - } + if (PsiTreeUtil.skipParentsOfType(ref, PsiJavaCodeReferenceElement.class) instanceof PsiTypeElement typeElement + && typeElement.getParent() instanceof PsiModifierListOwner modifierListOwner) { + return modifierListOwner.getModifierList(); } return null; } public static boolean isTypeAnnotation(@Nullable PsiElement element) { - return element instanceof PsiAnnotation && AnnotationTargetUtil.isTypeAnnotation((PsiAnnotation)element); + return element instanceof PsiAnnotation annotation && AnnotationTargetUtil.isTypeAnnotation(annotation); } public static void collectTypeUseAnnotations(@Nonnull PsiModifierList modifierList, @Nonnull List annotations) { @@ -768,7 +766,7 @@ public static List getTypeUseAnnotations(@Nonnull PsiModifierList for (PsiAnnotation annotation : modifierList.getAnnotations()) { if (isTypeAnnotation(annotation)) { if (result == null) { - result = new SmartList(); + result = new SmartList<>(); } result.add(annotation); } @@ -779,10 +777,11 @@ public static List getTypeUseAnnotations(@Nonnull PsiModifierList private static final Key TYPE_ANNO_MARK = Key.create("type.annotation.mark"); + @RequiredReadAction public static void markTypeAnnotations(@Nonnull PsiTypeElement typeElement) { PsiElement left = PsiTreeUtil.skipSiblingsBackward(typeElement, PsiComment.class, PsiWhiteSpace.class, PsiTypeParameterList.class); - if (left instanceof PsiModifierList) { - for (PsiAnnotation annotation : ((PsiModifierList)left).getAnnotations()) { + if (left instanceof PsiModifierList modifierList) { + for (PsiAnnotation annotation : modifierList.getAnnotations()) { if (AnnotationTargetUtil.isTypeAnnotation(annotation)) { annotation.putUserData(TYPE_ANNO_MARK, Boolean.TRUE); } @@ -790,10 +789,11 @@ public static void markTypeAnnotations(@Nonnull PsiTypeElement typeElement) { } } + @RequiredReadAction public static void deleteTypeAnnotations(@Nonnull PsiTypeElement typeElement) { PsiElement left = PsiTreeUtil.skipSiblingsBackward(typeElement, PsiComment.class, PsiWhiteSpace.class, PsiTypeParameterList.class); - if (left instanceof PsiModifierList) { - for (PsiAnnotation annotation : ((PsiModifierList)left).getAnnotations()) { + if (left instanceof PsiModifierList modifierList) { + for (PsiAnnotation annotation : modifierList.getAnnotations()) { if (TYPE_ANNO_MARK.get(annotation) == Boolean.TRUE) { annotation.delete(); } @@ -802,20 +802,16 @@ public static void deleteTypeAnnotations(@Nonnull PsiTypeElement typeElement) { } public static boolean isLeafElementOfType(@Nullable PsiElement element, IElementType type) { - return element instanceof LeafElement && ((LeafElement)element).getElementType() == type; + return element instanceof LeafElement leafElement && leafElement.getElementType() == type; } public static boolean isLeafElementOfType(PsiElement element, TokenSet tokenSet) { - return element instanceof LeafElement && tokenSet.contains(((LeafElement)element).getElementType()); + return element instanceof LeafElement leafElement && tokenSet.contains(leafElement.getElementType()); } - public static PsiType buildTypeFromTypeString( - @Nonnull final String typeName, - @Nonnull final PsiElement context, - @Nonnull final PsiFile psiFile - ) { + public static PsiType buildTypeFromTypeString(@Nonnull String typeName, @Nonnull PsiElement context, @Nonnull PsiFile psiFile) { PsiType resultType; - final PsiManager psiManager = psiFile.getManager(); + PsiManager psiManager = psiFile.getManager(); if (typeName.indexOf('<') != -1 || typeName.indexOf('[') != -1 || typeName.indexOf('.') == -1) { try { @@ -828,7 +824,7 @@ public static PsiType buildTypeFromTypeString( PsiClass aClass = JavaPsiFacade.getInstance(psiManager.getProject()).findClass(typeName, context.getResolveScope()); if (aClass == null) { - final LightClassReference ref = + LightClassReference ref = new LightClassReference(psiManager, PsiNameHelper.getShortClassName(typeName), typeName, PsiSubstitutor.EMPTY, psiFile); resultType = new PsiClassReferenceType(ref, null); } @@ -868,7 +864,7 @@ public static JavaResolveResult[] multiR } if (element instanceof PsiMethodReferenceExpression) { // method refs: do not cache results during parent conflict resolving, acceptable checks, etc - final Map map = LambdaUtil.ourFunctionTypes.get(); + Map map = LambdaUtil.ourFunctionTypes.get(); if (map != null && map.containsKey(element)) { return (JavaResolveResult[])resolver.resolve(element, psiFile, incompleteCode); } @@ -897,19 +893,16 @@ public static JavaResolveResult[] multiR */ @Nullable public static PsiSwitchLabelStatementBase getSwitchLabel(@Nonnull PsiExpression expression) { - PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent()); - if (parent instanceof PsiExpressionList) { - PsiElement grand = parent.getParent(); - if (grand instanceof PsiSwitchLabelStatementBase) { - return (PsiSwitchLabelStatementBase)grand; - } + if (PsiUtil.skipParenthesizedExprUp(expression.getParent()) instanceof PsiExpressionList exprList + && exprList.getParent() instanceof PsiSwitchLabelStatementBase switchLabelStmt) { + return switchLabelStmt; } return null; } public static VirtualFile getModuleVirtualFile(@Nonnull PsiJavaModule module) { - if (module instanceof AutomaticJavaModule) { - return ((AutomaticJavaModule)module).getRootVirtualFile(); + if (module instanceof AutomaticJavaModule automaticJavaModule) { + return automaticJavaModule.getRootVirtualFile(); } else { return module.getContainingFile().getVirtualFile(); diff --git a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/PsiSuperMethodImplUtil.java b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/PsiSuperMethodImplUtil.java index 332d01152..32d5dbcba 100644 --- a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/PsiSuperMethodImplUtil.java +++ b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/PsiSuperMethodImplUtil.java @@ -22,7 +22,6 @@ import com.intellij.java.language.psi.util.*; import consulo.application.progress.ProgressManager; import consulo.application.util.*; -import consulo.application.util.function.Processor; import consulo.java.language.module.util.JavaClassNames; import consulo.language.impl.psi.LightElement; import consulo.language.psi.PsiInvalidElementAccessException; @@ -37,12 +36,12 @@ import consulo.util.collection.SmartList; import consulo.util.dataholder.Key; import consulo.util.lang.Pair; - import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; import java.util.*; import java.util.function.Function; +import java.util.function.Predicate; public class PsiSuperMethodImplUtil { private static final Logger LOG = Logger.getInstance(PsiSuperMethodImplUtil.class); @@ -129,10 +128,10 @@ private static boolean canHaveSuperMethod(@Nonnull PsiMethod method, boolean che if (method.isConstructor()) { return false; } - if (!allowStaticMethod && method.hasModifierProperty(PsiModifier.STATIC)) { + if (!allowStaticMethod && method.isStatic()) { return false; } - if (checkAccess && method.hasModifierProperty(PsiModifier.PRIVATE)) { + if (checkAccess && method.isPrivate()) { return false; } PsiClass parentClass = method.getContainingClass(); @@ -161,8 +160,8 @@ private static Map buildMethodHier @Nonnull PsiClass aClass, @Nullable String nameHint, @Nonnull PsiSubstitutor substitutor, - final boolean includePrivates, - @Nonnull final Set visited, + boolean includePrivates, + @Nonnull Set visited, boolean isInRawContext, GlobalSearchScope resolveScope ) { @@ -176,11 +175,11 @@ public int hashCode(MethodSignature object) { @Override public boolean equals(MethodSignature o1, MethodSignature o2) { if (o1.equals(o2)) { - final PsiMethod method1 = ((MethodSignatureBackedByPsiMethod)o1).getMethod(); - final PsiType returnType1 = method1.getReturnType(); - final PsiMethod method2 = ((MethodSignatureBackedByPsiMethod)o2).getMethod(); - final PsiType returnType2 = method2.getReturnType(); - if (method1.hasModifierProperty(PsiModifier.STATIC) || method2.hasModifierProperty(PsiModifier.STATIC)) { + PsiMethod method1 = ((MethodSignatureBackedByPsiMethod)o1).getMethod(); + PsiType returnType1 = method1.getReturnType(); + PsiMethod method2 = ((MethodSignatureBackedByPsiMethod)o2).getMethod(); + PsiType returnType2 = method2.getReturnType(); + if (method1.isStatic() || method2.isStatic()) { return true; } @@ -188,8 +187,8 @@ public boolean equals(MethodSignature o1, MethodSignature o2) { return true; } - final PsiClass containingClass1 = method1.getContainingClass(); - final PsiClass containingClass2 = method2.getContainingClass(); + PsiClass containingClass1 = method1.getContainingClass(); + PsiClass containingClass2 = method2.getContainingClass(); if (containingClass1 != null && containingClass2 != null) { return containingClass1.isAnnotationType() || containingClass2.isAnnotationType(); } @@ -197,7 +196,7 @@ public boolean equals(MethodSignature o1, MethodSignature o2) { return false; } }); - final Map> sameParameterErasureMethods = + Map> sameParameterErasureMethods = Maps.newHashMap(MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY); Map map = Maps.newHashMap(new HashingStrategy() { @@ -239,10 +238,10 @@ public boolean equals(MethodSignature o1, MethodSignature o2) { if (nameHint != null && !nameHint.equals(method.getName())) { continue; } - if (!includePrivates && method.hasModifierProperty(PsiModifier.PRIVATE)) { + if (!includePrivates && method.isPrivate()) { continue; } - final MethodSignatureBackedByPsiMethod signature = + MethodSignatureBackedByPsiMethod signature = MethodSignatureBackedByPsiMethod.create(method, PsiSubstitutor.EMPTY, isInRawContext); HierarchicalMethodSignatureImpl newH = new HierarchicalMethodSignatureImpl(MethodSignatureBackedByPsiMethod.create(method, substitutor, isInRawContext)); @@ -259,7 +258,7 @@ public boolean equals(MethodSignature o1, MethodSignature o2) { map.put(signature, newH); } - final List superTypes = PsiClassImplUtil.getScopeCorrectedSuperTypes(aClass, resolveScope); + List superTypes = PsiClassImplUtil.getScopeCorrectedSuperTypes(aClass, resolveScope); for (PsiClassType.ClassResolveResult superTypeResolveResult : superTypes) { PsiClass superClass = superTypeResolveResult.getElement(); @@ -269,11 +268,11 @@ public boolean equals(MethodSignature o1, MethodSignature o2) { if (!visited.add(superClass)) { continue; // cyclic inheritance } - final PsiSubstitutor superSubstitutor = superTypeResolveResult.getSubstitutor(); + PsiSubstitutor superSubstitutor = superTypeResolveResult.getSubstitutor(); PsiSubstitutor finalSubstitutor = PsiSuperMethodUtil.obtainFinalSubstitutor(superClass, superSubstitutor, substitutor, isInRawContext); - final boolean isInRawContextSuper = + boolean isInRawContextSuper = (isInRawContext || PsiUtil.isRawSubstitutor(superClass, superSubstitutor)) && superClass.getTypeParameters().length != 0; Map superResult = buildMethodHierarchy(superClass, nameHint, finalSubstitutor, false, visited, isInRawContextSuper, resolveScope); @@ -400,16 +399,15 @@ private static boolean isSuperMethod( if (!superMethod.isConstructor() && !aClass.equals(superClass) && MethodSignatureUtil.isSubsignature(superSignatureHierarchical, hierarchicalMethodSignature) && superClass != null) { if (superClass.isInterface() || JavaClassNames.JAVA_LANG_OBJECT.equals(superClass.getQualifiedName())) { - if (superMethod.hasModifierProperty(PsiModifier.STATIC) - || superMethod.hasModifierProperty(PsiModifier.DEFAULT) && method.hasModifierProperty(PsiModifier.STATIC) + //noinspection SimplifiableIfStatement + if (superMethod.isStatic() + || superMethod.hasModifierProperty(PsiModifier.DEFAULT) && method.isStatic() && !InheritanceUtil.isInheritorOrSelf(containingClass, superClass, true)) { return false; } - if (superMethod.hasModifierProperty(PsiModifier.DEFAULT) || method.hasModifierProperty(PsiModifier.DEFAULT)) { - return superMethod.equals(method) || !InheritanceUtil.isInheritorOrSelf(superClass, containingClass, true); - } - return true; + return !(superMethod.hasModifierProperty(PsiModifier.DEFAULT) || method.hasModifierProperty(PsiModifier.DEFAULT)) + || superMethod.equals(method) || !InheritanceUtil.isInheritorOrSelf(superClass, containingClass, true); } if (containingClass != null) { @@ -441,7 +439,7 @@ public static Collection getVisibleSignatures(@Nonn } @Nonnull - public static HierarchicalMethodSignature getHierarchicalMethodSignature(@Nonnull final PsiMethod method) { + public static HierarchicalMethodSignature getHierarchicalMethodSignature(@Nonnull PsiMethod method) { Project project = method.getProject(); return CachedValuesManager.getManager(project) .getParameterizedCachedValue(method, HIERARCHICAL_SIGNATURE_KEY, HIERARCHICAL_SIGNATURE_PROVIDER, false, method); @@ -450,24 +448,21 @@ public static HierarchicalMethodSignature getHierarchicalMethodSignature(@Nonnul private static final Key> HIERARCHICAL_SIGNATURE_KEY = Key.create("HierarchicalMethodSignature"); private static final ParameterizedCachedValueProvider HIERARCHICAL_SIGNATURE_PROVIDER = - new ParameterizedCachedValueProvider() { - @Override - public CachedValueProvider.Result compute(PsiMethod method) { - PsiClass aClass = method.getContainingClass(); - HierarchicalMethodSignature result = null; - if (aClass != null) { - result = SIGNATURES_BY_NAME_KEY.getValue(aClass).get(method.getName()).get(method.getSignature(PsiSubstitutor.EMPTY)); - } - if (result == null) { - result = - new HierarchicalMethodSignatureImpl((MethodSignatureBackedByPsiMethod)method.getSignature(PsiSubstitutor.EMPTY)); - } + method -> { + PsiClass aClass = method.getContainingClass(); + HierarchicalMethodSignature result = null; + if (aClass != null) { + result = SIGNATURES_BY_NAME_KEY.getValue(aClass).get(method.getName()).get(method.getSignature(PsiSubstitutor.EMPTY)); + } + if (result == null) { + result = + new HierarchicalMethodSignatureImpl((MethodSignatureBackedByPsiMethod)method.getSignature(PsiSubstitutor.EMPTY)); + } - if (!method.isPhysical() && !(method instanceof SyntheticElement) && !(method instanceof LightElement)) { - return CachedValueProvider.Result.create(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT, method); - } - return CachedValueProvider.Result.create(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); + if (!method.isPhysical() && !(method instanceof SyntheticElement) && !(method instanceof LightElement)) { + return CachedValueProvider.Result.create(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT, method); } + return CachedValueProvider.Result.create(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); }; @Nonnull @@ -476,7 +471,7 @@ private static Map getSignaturesMa } // uses hierarchy signature tree if available, traverses class structure by itself otherwise - public static boolean processDirectSuperMethodsSmart(@Nonnull PsiMethod method, @Nonnull Processor superMethodProcessor) { + public static boolean processDirectSuperMethodsSmart(@Nonnull PsiMethod method, @Nonnull Predicate superMethodProcessor) { //boolean old = PsiSuperMethodUtil.isSuperMethod(method, superMethod); PsiClass aClass = method.getContainingClass(); @@ -493,7 +488,7 @@ public static boolean processDirectSuperMethodsSmart(@Nonnull PsiMethod method, if (signature != null) { List superSignatures = signature.getSuperSignatures(); for (HierarchicalMethodSignature superSignature : superSignatures) { - if (!superMethodProcessor.process(superSignature.getMethod())) { + if (!superMethodProcessor.test(superSignature.getMethod())) { return false; } } diff --git a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/file/PsiPackageImpl.java b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/file/PsiPackageImpl.java index dc69f56fe..698595c4b 100644 --- a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/file/PsiPackageImpl.java +++ b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/file/PsiPackageImpl.java @@ -42,18 +42,17 @@ import consulo.module.extension.ModuleExtension; import consulo.util.collection.ArrayFactory; import consulo.util.collection.ContainerUtil; -import consulo.util.lang.function.Condition; -import consulo.util.lang.function.Conditions; +import consulo.util.lang.function.Predicates; import consulo.util.lang.ref.SoftReference; import consulo.virtualFileSystem.VirtualFile; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; -import org.jetbrains.annotations.NonNls; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; +import java.util.function.Predicate; public class PsiPackageImpl extends PsiPackageBase implements PsiJavaPackage, Queryable { private static final Logger LOGGER = Logger.getInstance(PsiPackageImpl.class); @@ -75,25 +74,23 @@ public PsiPackageImpl( protected Collection getAllDirectories(boolean includeLibrarySource) { if (myDirectories == null) { myDirectories = - CachedValuesManager.getManager(myManager.getProject()) - .createCachedValue(new CachedValueProvider>() { - @Override - public Result> compute() { - final CommonProcessors.CollectProcessor processor = - new CommonProcessors.CollectProcessor(); - getFacade().processPackageDirectories(PsiPackageImpl.this, allScope(), processor); - return Result.create( - processor.getResults(), - PsiPackageImplementationHelper.getInstance().getDirectoryCachedValueDependencies(PsiPackageImpl.this) - ); - } - }, false); + CachedValuesManager.getManager(myManager.getProject()).createCachedValue( + () -> { + CommonProcessors.CollectProcessor processor = new CommonProcessors.CollectProcessor<>(); + getFacade().processPackageDirectories(PsiPackageImpl.this, allScope(), processor); + return CachedValueProvider.Result.create( + processor.getResults(), + PsiPackageImplementationHelper.getInstance().getDirectoryCachedValueDependencies(PsiPackageImpl.this) + ); + }, + false + ); } return myDirectories.getValue(); } @Override - public void handleQualifiedNameChange(@Nonnull final String newQualifiedName) { + public void handleQualifiedNameChange(@Nonnull String newQualifiedName) { PsiPackageImplementationHelper.getInstance().handleQualifiedNameChange(this, newQualifiedName); } @@ -122,14 +119,15 @@ public boolean isValid() { @Override public void accept(@Nonnull PsiElementVisitor visitor) { - if (visitor instanceof JavaElementVisitor) { - ((JavaElementVisitor)visitor).visitPackage(this); + if (visitor instanceof JavaElementVisitor javaElementVisitor) { + javaElementVisitor.visitPackage(this); } else { visitor.visitElement(this); } } + @Override public String toString() { return "PsiJavaPackage:" + getQualifiedName(); } @@ -144,20 +142,21 @@ protected GlobalSearchScope allScope() { return PsiPackageImplementationHelper.getInstance().adjustAllScope(this, GlobalSearchScope.allScope(getProject())); } - @Override @Nonnull + @Override public PsiClass[] getClasses(@Nonnull GlobalSearchScope scope) { return getFacade().getClasses(this, scope); } - @Override @Nonnull + @Override + @RequiredReadAction public PsiFile[] getFiles(@Nonnull GlobalSearchScope scope) { return getFacade().getPackageFiles(this, scope); } - @Override @Nullable + @Override public PsiModifierList getAnnotationList() { if (myAnnotationList == null) { myAnnotationList = @@ -166,14 +165,14 @@ public PsiModifierList getAnnotationList() { return myAnnotationList.getValue(); } - @Override @Nonnull + @Override public PsiJavaPackage[] getSubPackages() { return getFacade().getSubPackages(this, allScope()); } - @Override @Nonnull + @Override public PsiJavaPackage[] getSubPackages(@Nonnull GlobalSearchScope scope) { return getFacade().getSubPackages(this, scope); } @@ -187,6 +186,7 @@ private JavaPsiFacadeImpl getFacade() { return (JavaPsiFacadeImpl)JavaPsiFacade.getInstance(myManager.getProject()); } + @RequiredReadAction private Set getClassNamesCache() { SoftReference> ref = myPublicClassNamesCache; Set cache = ref == null ? null : ref.get(); @@ -202,38 +202,43 @@ public boolean isForceSearchingInLibrarySources() { }; } cache = getFacade().getClassNames(this, scope); - myPublicClassNamesCache = new SoftReference>(cache); + myPublicClassNamesCache = new SoftReference<>(cache); } return cache; } @Nonnull + @RequiredReadAction private PsiClass[] findClassesByName(String name, GlobalSearchScope scope) { - final String qName = getQualifiedName(); - final String classQName = !qName.isEmpty() ? qName + "." + name : name; + String qName = getQualifiedName(); + String classQName = !qName.isEmpty() ? qName + "." + name : name; return getFacade().findClasses(classQName, scope); } @Override + @RequiredReadAction public boolean containsClassNamed(String name) { return getClassNamesCache().contains(name); } @Nonnull @Override + @RequiredReadAction public PsiClass[] findClassByShortName(@Nonnull String name, @Nonnull GlobalSearchScope scope) { return getFacade().findClassByShortName(name, this, scope); } @Nullable + @RequiredReadAction private PsiJavaPackage findSubPackageByName(String name) { - final String qName = getQualifiedName(); - final String subpackageQName = qName.isEmpty() ? name : qName + "." + name; + String qName = getQualifiedName(); + String subpackageQName = qName.isEmpty() ? name : qName + "." + name; return getFacade().findPackage(subpackageQName); } @Override + @RequiredReadAction public boolean processDeclarations( @Nonnull PsiScopeProcessor processor, @Nonnull ResolveState state, @@ -245,21 +250,21 @@ public boolean processDeclarations( processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, this); ElementClassHint classHint = processor.getHint(ElementClassHint.KEY); - final Condition nameCondition = processor.getHint(JavaCompletionHints.NAME_FILTER); + Predicate nameCondition = processor.getHint(JavaCompletionHints.NAME_FILTER); NameHint providedNameHint = processor.getHint(NameHint.KEY); - final String providedName = providedNameHint == null ? null : providedNameHint.getName(state); + String providedName = providedNameHint == null ? null : providedNameHint.getName(state); if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.CLASS)) { if (providedName != null) { - final PsiClass[] classes = findClassByShortName(providedName, scope); - if (!processClasses(processor, state, classes, Conditions.alwaysTrue())) { + PsiClass[] classes = findClassByShortName(providedName, scope); + if (!processClasses(processor, state, classes, Predicates.alwaysTrue())) { return false; } } else { PsiClass[] classes = getClasses(scope); - if (!processClasses(processor, state, classes, nameCondition != null ? nameCondition : Conditions.alwaysTrue())) { + if (!processClasses(processor, state, classes, nameCondition != null ? nameCondition : Predicates.alwaysTrue())) { return false; } } @@ -276,7 +281,7 @@ public boolean processDeclarations( else { PsiPackage[] packs = getSubPackages(scope); for (PsiPackage pack : packs) { - final String packageName = pack.getName(); + String packageName = pack.getName(); if (packageName == null) { continue; } @@ -292,15 +297,16 @@ public boolean processDeclarations( return true; } + @RequiredReadAction private static boolean processClasses( @Nonnull PsiScopeProcessor processor, @Nonnull ResolveState state, @Nonnull PsiClass[] classes, - @Nonnull Condition nameCondition + @Nonnull Predicate nameCondition ) { for (PsiClass aClass : classes) { String name = aClass.getName(); - if (name != null && nameCondition.value(name)) { + if (name != null && nameCondition.test(name)) { try { if (!processor.execute(aClass, state)) { return false; @@ -318,7 +324,7 @@ private static boolean processClasses( } @Override - public void navigate(final boolean requestFocus) { + public void navigate(boolean requestFocus) { PsiPackageImplementationHelper.getInstance().navigate(this, requestFocus); } @@ -326,14 +332,15 @@ private class PackageAnnotationValueProvider implements CachedValueProvider compute() { - List list = new ArrayList(); + List list = new ArrayList<>(); for (PsiDirectory directory : getDirectories()) { PsiFile file = directory.findFile(PACKAGE_INFO_FILE); if (file != null) { PsiPackageStatement stmt = PsiTreeUtil.getChildOfType(file, PsiPackageStatement.class); if (stmt != null) { - final PsiModifierList modifierList = stmt.getAnnotationList(); + PsiModifierList modifierList = stmt.getAnnotationList(); if (modifierList != null) { list.add(modifierList); } @@ -341,13 +348,13 @@ public Result compute() { } } - final JavaPsiFacade facade = getFacade(); - final GlobalSearchScope scope = allScope(); + JavaPsiFacade facade = getFacade(); + GlobalSearchScope scope = allScope(); for (PsiClass aClass : facade.findClasses(getQualifiedName() + ".package-info", scope)) { ContainerUtil.addIfNotNull(list, aClass.getModifierList()); } - return new Result(list.isEmpty() ? null : new PsiCompositeModifierList(getManager(), list), OOCB_DEPENDENCY); + return new Result<>(list.isEmpty() ? null : new PsiCompositeModifierList(getManager(), list), OOCB_DEPENDENCY); } } @@ -358,7 +365,7 @@ public PsiModifierList getModifierList() { } @Override - public boolean hasModifierProperty(@NonNls @Nonnull final String name) { + public boolean hasModifierProperty(@Nonnull String name) { return false; } } diff --git a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/source/PsiAnnotationMethodImpl.java b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/source/PsiAnnotationMethodImpl.java index 5928d8274..540e6daab 100644 --- a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/source/PsiAnnotationMethodImpl.java +++ b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/source/PsiAnnotationMethodImpl.java @@ -20,13 +20,12 @@ import com.intellij.java.language.impl.psi.impl.java.stubs.PsiMethodStub; import com.intellij.java.language.impl.psi.impl.source.tree.ChildRole; import com.intellij.java.language.psi.*; +import consulo.annotation.access.RequiredReadAction; import consulo.language.ast.ASTNode; import consulo.language.psi.PsiElementVisitor; import consulo.language.psi.PsiFileFactory; import consulo.util.lang.StringUtil; import consulo.util.lang.ref.SoftReference; -import org.jetbrains.annotations.NonNls; - import jakarta.annotation.Nonnull; /** @@ -35,11 +34,11 @@ public class PsiAnnotationMethodImpl extends PsiMethodImpl implements PsiAnnotationMethod { private SoftReference myCachedDefaultValue = null; - public PsiAnnotationMethodImpl(final PsiMethodStub stub) { + public PsiAnnotationMethodImpl(PsiMethodStub stub) { super(stub, JavaStubElementTypes.ANNOTATION_METHOD); } - public PsiAnnotationMethodImpl(final ASTNode node) { + public PsiAnnotationMethodImpl(ASTNode node) { super(node); } @@ -54,47 +53,49 @@ protected void dropCached() { } @Override + @RequiredReadAction public PsiAnnotationMemberValue getDefaultValue() { - final PsiMethodStub stub = getStub(); + PsiMethodStub stub = getStub(); if (stub != null) { - final String text = stub.getDefaultValueText(); + String text = stub.getDefaultValueText(); if (StringUtil.isEmpty(text)) { return null; } if (myCachedDefaultValue != null) { - final PsiAnnotationMemberValue value = myCachedDefaultValue.get(); + PsiAnnotationMemberValue value = myCachedDefaultValue.get(); if (value != null) { return value; } } - @NonNls final String annoText = "@interface _Dummy_ { Class foo() default " + text + "; }"; - final PsiFileFactory factory = PsiFileFactory.getInstance(getProject()); - final PsiJavaFile file = (PsiJavaFile)factory.createFileFromText("a.java", JavaFileType.INSTANCE, annoText); - final PsiAnnotationMemberValue value = ((PsiAnnotationMethod)file.getClasses()[0].getMethods()[0]).getDefaultValue(); - myCachedDefaultValue = new SoftReference(value); + String annoText = "@interface _Dummy_ { Class foo() default " + text + "; }"; + PsiFileFactory factory = PsiFileFactory.getInstance(getProject()); + PsiJavaFile file = (PsiJavaFile)factory.createFileFromText("a.java", JavaFileType.INSTANCE, annoText); + PsiAnnotationMemberValue value = ((PsiAnnotationMethod)file.getClasses()[0].getMethods()[0]).getDefaultValue(); + myCachedDefaultValue = new SoftReference<>(value); return value; } myCachedDefaultValue = null; - final ASTNode node = getNode().findChildByRole(ChildRole.ANNOTATION_DEFAULT_VALUE); + ASTNode node = getNode().findChildByRole(ChildRole.ANNOTATION_DEFAULT_VALUE); if (node == null) { return null; } return (PsiAnnotationMemberValue)node.getPsi(); } - @NonNls + @Override + @RequiredReadAction public String toString() { return "PsiAnnotationMethod:" + getName(); } @Override public final void accept(@Nonnull PsiElementVisitor visitor) { - if (visitor instanceof JavaElementVisitor) { - ((JavaElementVisitor)visitor).visitAnnotationMethod(this); + if (visitor instanceof JavaElementVisitor elemVisitor) { + elemVisitor.visitAnnotationMethod(this); } else { visitor.visitElement(this); diff --git a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/source/PsiMethodImpl.java b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/source/PsiMethodImpl.java index 41ddbcc97..5c5c7808e 100644 --- a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/source/PsiMethodImpl.java +++ b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/source/PsiMethodImpl.java @@ -28,10 +28,11 @@ import com.intellij.java.language.psi.javadoc.PsiDocComment; import com.intellij.java.language.psi.util.MethodSignature; import com.intellij.java.language.psi.util.MethodSignatureBackedByPsiMethod; -import consulo.application.ApplicationManager; +import consulo.annotation.access.RequiredReadAction; +import consulo.annotation.access.RequiredWriteAction; +import consulo.application.Application; import consulo.application.util.CachedValueProvider; import consulo.application.util.Queryable; -import consulo.application.util.function.Computable; import consulo.content.scope.SearchScope; import consulo.language.ast.ASTNode; import consulo.language.impl.ast.CompositeElement; @@ -51,21 +52,22 @@ import java.util.List; import java.util.Map; +import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; public class PsiMethodImpl extends JavaStubPsiElement implements PsiMethod, Queryable { private SoftReference myCachedType; - public PsiMethodImpl(final PsiMethodStub stub) { + public PsiMethodImpl(PsiMethodStub stub) { this(stub, JavaStubElementTypes.METHOD); } - protected PsiMethodImpl(final PsiMethodStub stub, final IStubElementType type) { + protected PsiMethodImpl(PsiMethodStub stub, IStubElementType type) { super(stub, type); } - public PsiMethodImpl(final ASTNode node) { + public PsiMethodImpl(ASTNode node) { super(node); } @@ -88,17 +90,17 @@ protected Object clone() { @Override public PsiClass getContainingClass() { - PsiElement parent = getParent(); - return parent instanceof PsiClass ? (PsiClass)parent : PsiTreeUtil.getParentOfType(this, PsiSyntheticClass.class); + return getParent() instanceof PsiClass psiClass ? psiClass : PsiTreeUtil.getParentOfType(this, PsiSyntheticClass.class); } @Override public PsiElement getContext() { - final PsiClass cc = getContainingClass(); + PsiClass cc = getContainingClass(); return cc != null ? cc : super.getContext(); } @Override + @RequiredReadAction public PsiIdentifier getNameIdentifier() { return (PsiIdentifier)getNode().findChildByRoleAsPsiElement(ChildRole.NAME); } @@ -132,37 +134,39 @@ public PsiMethod findDeepestSuperMethod() { return PsiSuperMethodImplUtil.findDeepestSuperMethod(this); } - @Override @Nonnull + @Override public PsiMethod[] findDeepestSuperMethods() { return PsiSuperMethodImplUtil.findDeepestSuperMethods(this); } - @Override @Nonnull + @Override + @RequiredReadAction public String getName() { - final String name; - final PsiMethodStub stub = getGreenStub(); + String name; + PsiMethodStub stub = getGreenStub(); if (stub != null) { name = stub.getName(); } else { - final PsiIdentifier nameIdentifier = getNameIdentifier(); + PsiIdentifier nameIdentifier = getNameIdentifier(); name = nameIdentifier == null ? null : nameIdentifier.getText(); } return name != null ? name : ""; } - @Override @Nonnull + @Override public HierarchicalMethodSignature getHierarchicalMethodSignature() { return PsiSuperMethodImplUtil.getHierarchicalMethodSignature(this); } @Override + @RequiredWriteAction public PsiElement setName(@Nonnull String name) throws IncorrectOperationException { - final PsiIdentifier identifier = getNameIdentifier(); + PsiIdentifier identifier = getNameIdentifier(); if (identifier == null) { throw new IncorrectOperationException("Empty name: " + this); } @@ -171,6 +175,7 @@ public PsiElement setName(@Nonnull String name) throws IncorrectOperationExcepti } @Override + @RequiredReadAction public PsiTypeElement getReturnTypeElement() { if (isConstructor()) { return null; @@ -188,13 +193,14 @@ public boolean hasTypeParameters() { return PsiImplUtil.hasTypeParameters(this); } - @Override @Nonnull + @Override public PsiTypeParameter[] getTypeParameters() { return PsiImplUtil.getTypeParameters(this); } @Override + @RequiredReadAction public PsiType getReturnType() { if (isConstructor()) { return null; @@ -215,8 +221,8 @@ public PsiType getReturnType() { return typeElement != null ? JavaSharedImplUtil.getType(typeElement, getParameterList()) : null; } - @Override @Nonnull + @Override public PsiModifierList getModifierList() { return getRequiredStubOrPsiChild(JavaStubElementTypes.MODIFIER_LIST); } @@ -226,35 +232,40 @@ public boolean hasModifierProperty(@Nonnull String name) { return getModifierList().hasModifierProperty(name); } - @Override @Nonnull + @Override public PsiParameterList getParameterList() { PsiParameterList list = getStubOrPsiChild(JavaStubElementTypes.PARAMETER_LIST); if (list == null) { - return LanguageCachedValueUtil.getCachedValue(this, () -> { - LightParameterListBuilder lightList = new LightParameterListBuilder(getManager(), getLanguage()) { - @Override - public String getText() { - return null; - } - }; - PsiClass aClass = getContainingClass(); - if (aClass != null) { - PsiRecordComponent[] recordComponents = aClass.getRecordComponents(); - for (PsiRecordComponent component : recordComponents) { - String name = component.getName(); - lightList.addParameter(new LightCompactConstructorParameter(name, component.getType(), this, component)); + return LanguageCachedValueUtil.getCachedValue( + this, + () -> { + LightParameterListBuilder lightList = new LightParameterListBuilder(getManager(), getLanguage()) { + @Override + @RequiredReadAction + public String getText() { + return null; + } + }; + PsiClass aClass = getContainingClass(); + if (aClass != null) { + PsiRecordComponent[] recordComponents = aClass.getRecordComponents(); + for (PsiRecordComponent component : recordComponents) { + String name = component.getName(); + lightList.addParameter(new LightCompactConstructorParameter(name, component.getType(), this, component)); + } } - } - return CachedValueProvider.Result.create(lightList, this, PsiModificationTracker.MODIFICATION_COUNT); - }); + return CachedValueProvider.Result.create(lightList, this, PsiModificationTracker.MODIFICATION_COUNT); + } + ); } return list; } - @Override @Nonnull + @Override + @RequiredReadAction public PsiReferenceList getThrowsList() { PsiReferenceList child = getStubOrPsiChild(JavaStubElementTypes.THROWS_LIST); if (child != null) { @@ -262,10 +273,9 @@ public PsiReferenceList getThrowsList() { } PsiMethodStub stub = getStub(); - Stream children = - stub != null ? stub.getChildrenStubs().stream().map(s -> s.getClass().getSimpleName() + " : " + s.getStubType()) : Stream.of( - getChildren()).map(e -> e.getClass() - .getSimpleName() + " : " + e.getNode().getElementType()); + Stream children = stub != null + ? stub.getChildrenStubs().stream().map(s -> s.getClass().getSimpleName() + " : " + s.getStubType()) + : Stream.of(getChildren()).map(e -> e.getClass().getSimpleName() + " : " + e.getNode().getElementType()); throw new AssertionError( "Missing throws list, file=" + getContainingFile() + " children:\n" + children.collect(Collectors.joining("\n")) @@ -273,19 +283,21 @@ public PsiReferenceList getThrowsList() { } @Override + @RequiredReadAction public PsiCodeBlock getBody() { return (PsiCodeBlock)getNode().findChildByRoleAsPsiElement(ChildRole.METHOD_BODY); } - @Override @Nonnull + @Override + @RequiredReadAction public CompositeElement getNode() { return (CompositeElement)super.getNode(); } @Override public boolean isDeprecated() { - final PsiMethodStub stub = getGreenStub(); + PsiMethodStub stub = getGreenStub(); if (stub != null) { return stub.isDeprecated() || stub.hasDeprecatedAnnotation() && PsiImplUtil.isDeprecatedByAnnotation(this); } @@ -294,8 +306,9 @@ public boolean isDeprecated() { } @Override + @RequiredReadAction public PsiDocComment getDocComment() { - final PsiMethodStub stub = getGreenStub(); + PsiMethodStub stub = getGreenStub(); if (stub != null && !stub.hasDocComment()) { return null; } @@ -304,8 +317,9 @@ public PsiDocComment getDocComment() { } @Override + @RequiredReadAction public boolean isConstructor() { - final PsiMethodStub stub = getGreenStub(); + PsiMethodStub stub = getGreenStub(); if (stub != null) { return stub.isConstructor(); } @@ -315,7 +329,7 @@ public boolean isConstructor() { @Override public boolean isVarArgs() { - final PsiMethodStub stub = getGreenStub(); + PsiMethodStub stub = getGreenStub(); if (stub != null) { return stub.isVarArgs(); } @@ -325,8 +339,8 @@ public boolean isVarArgs() { @Override public void accept(@Nonnull PsiElementVisitor visitor) { - if (visitor instanceof JavaElementVisitor) { - ((JavaElementVisitor)visitor).visitMethod(this); + if (visitor instanceof JavaElementVisitor javaElementVisitor) { + javaElementVisitor.visitMethod(this); } else { visitor.visitElement(this); @@ -334,6 +348,7 @@ public void accept(@Nonnull PsiElementVisitor visitor) { } @Override + @RequiredReadAction public String toString() { return "PsiMethod:" + getName(); } @@ -352,22 +367,24 @@ public boolean processDeclarations( @Nonnull public MethodSignature getSignature(@Nonnull PsiSubstitutor substitutor) { if (substitutor == PsiSubstitutor.EMPTY) { - return LanguageCachedValueUtil.getCachedValue(this, () -> - { - MethodSignature signature = MethodSignatureBackedByPsiMethod.create(this, PsiSubstitutor.EMPTY); - return CachedValueProvider.Result.create(signature, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); - }); + return LanguageCachedValueUtil.getCachedValue( + this, + () -> { + MethodSignature signature = MethodSignatureBackedByPsiMethod.create(this, PsiSubstitutor.EMPTY); + return CachedValueProvider.Result.create(signature, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); + } + ); } return MethodSignatureBackedByPsiMethod.create(this, substitutor); } @Override public PsiElement getOriginalElement() { - final PsiClass containingClass = getContainingClass(); + PsiClass containingClass = getContainingClass(); if (containingClass != null) { PsiElement original = containingClass.getOriginalElement(); - if (original != containingClass) { - final PsiMethod originalMethod = ((PsiClass)original).findMethodBySignature(this, false); + if (original != containingClass && original instanceof PsiClass originalClass) { + PsiMethod originalMethod = originalClass.findMethodBySignature(this, false); if (originalMethod != null) { return originalMethod; } @@ -382,17 +399,18 @@ public ItemPresentation getPresentation() { } @Override - public boolean isEquivalentTo(final PsiElement another) { + public boolean isEquivalentTo(PsiElement another) { return PsiClassImplUtil.isMethodEquivalentTo(this, another); } @Override @Nonnull public SearchScope getUseScope() { - return ApplicationManager.getApplication().runReadAction((Computable)() -> PsiImplUtil.getMemberUseScope(this)); + return Application.get().runReadAction((Supplier)() -> PsiImplUtil.getMemberUseScope(this)); } @Override + @RequiredReadAction public void putInfo(@Nonnull Map info) { info.put("methodName", getName()); }