mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
extract handling of package prefixes to a separate PsiElementFinder
This commit is contained in:
@@ -71,7 +71,6 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx implements Disposable {
|
||||
private final ConcurrentMap<String, PsiPackage> myPackageCache = new ConcurrentHashMap<String, PsiPackage>();
|
||||
private final Project myProject;
|
||||
private final JavaFileManager myFileManager;
|
||||
private final PackagePrefixIndex myPackagePrefixIndex;
|
||||
|
||||
|
||||
public JavaPsiFacadeImpl(Project project,
|
||||
@@ -89,10 +88,6 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx implements Disposable {
|
||||
ContainerUtil.addAll(elementFinders, myProject.getExtensions(PsiElementFinder.EP_NAME));
|
||||
myElementFinders = elementFinders.toArray(new PsiElementFinder[elementFinders.size()]);
|
||||
|
||||
myPackagePrefixIndex = new PackagePrefixIndex(myProject);
|
||||
|
||||
boolean isProjectDefault = project.isDefault();
|
||||
|
||||
myFileManager = new JavaFileManagerImpl(psiManager, projectRootManagerEx, psiManager.getFileManager(), bus);
|
||||
|
||||
final PsiModificationTrackerImpl modificationTracker = (PsiModificationTrackerImpl)psiManager.getModificationTracker();
|
||||
@@ -216,15 +211,13 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx implements Disposable {
|
||||
return aPackage;
|
||||
}
|
||||
|
||||
if (DumbService.getInstance(getProject()).isDumb()) {
|
||||
aPackage = findPackageDefault(qualifiedName);
|
||||
if (aPackage != null) {
|
||||
return ConcurrencyUtil.cacheOrGet(myPackageCache, qualifiedName, aPackage);
|
||||
}
|
||||
return null;
|
||||
DumbService dumbService = DumbService.getInstance(getProject());
|
||||
List<PsiElementFinder> finders = Arrays.asList(myElementFinders);
|
||||
if (dumbService.isDumb()) {
|
||||
finders = dumbService.filterByDumbAwareness(finders);
|
||||
}
|
||||
|
||||
for (PsiElementFinder finder : myElementFinders) {
|
||||
for (PsiElementFinder finder : finders) {
|
||||
aPackage = finder.findPackage(qualifiedName);
|
||||
if (aPackage != null) {
|
||||
return ConcurrencyUtil.cacheOrGet(myPackageCache, qualifiedName, aPackage);
|
||||
@@ -303,16 +296,6 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx implements Disposable {
|
||||
return myFileManager;
|
||||
}
|
||||
|
||||
public boolean packagePrefixExists(String packageQName) {
|
||||
for (final String prefix : myPackagePrefixIndex.getAllPackagePrefixes(null)) {
|
||||
if (StringUtil.startsWithConcatenationOf(prefix, packageQName, ".") || prefix.equals(packageQName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiPackage findPackageDefault(String qualifiedName) {
|
||||
final PsiPackage aPackage = myFileManager.findPackage(qualifiedName);
|
||||
@@ -321,10 +304,6 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx implements Disposable {
|
||||
if (migrationPackage != null) return migrationPackage;
|
||||
}
|
||||
|
||||
if (packagePrefixExists(qualifiedName)) {
|
||||
return new PsiPackageImpl((PsiManagerEx)PsiManager.getInstance(myProject), qualifiedName);
|
||||
}
|
||||
|
||||
return aPackage;
|
||||
}
|
||||
|
||||
@@ -371,15 +350,6 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx implements Disposable {
|
||||
}
|
||||
}
|
||||
}
|
||||
for (final String prefix : myPackagePrefixIndex.getAllPackagePrefixes(scope)) {
|
||||
if (StringUtil.isEmpty(qualifiedName) || StringUtil.startsWithConcatenationOf(prefix, qualifiedName, ".")) {
|
||||
final int i = prefix.indexOf('.', qualifiedName.length() + 1);
|
||||
String childName = i >= 0 ? prefix.substring(0, i) : prefix;
|
||||
if (!packagesMap.containsKey(childName)) {
|
||||
packagesMap.put(childName, new PsiPackageImpl((PsiManagerEx)psiPackage.getManager(), childName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
packagesMap.remove(qualifiedName); // avoid SOE caused by returning a package as a subpackage of itself
|
||||
return packagesMap.values().toArray(new PsiPackage[packagesMap.size()]);
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.psi.impl;
|
||||
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElementFinder;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.PsiPackage;
|
||||
import com.intellij.psi.impl.file.PsiPackageImpl;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class PackagePrefixElementFinder extends PsiElementFinder implements DumbAware {
|
||||
private final Project myProject;
|
||||
private final PackagePrefixIndex myPackagePrefixIndex;
|
||||
|
||||
public PackagePrefixElementFinder(Project project) {
|
||||
myProject = project;
|
||||
myPackagePrefixIndex = new PackagePrefixIndex(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiClass findClass(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClass[] findClasses(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
|
||||
return PsiClass.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiPackage findPackage(@NotNull String qualifiedName) {
|
||||
if (packagePrefixExists(qualifiedName)) {
|
||||
return new PsiPackageImpl((PsiManagerEx)PsiManager.getInstance(myProject), qualifiedName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiPackage[] getSubPackages(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
|
||||
final Map<String, PsiPackage> packagesMap = new HashMap<String, PsiPackage>();
|
||||
final String qualifiedName = psiPackage.getQualifiedName();
|
||||
|
||||
for (final String prefix : myPackagePrefixIndex.getAllPackagePrefixes(scope)) {
|
||||
if (StringUtil.isEmpty(qualifiedName) || StringUtil.startsWithConcatenationOf(prefix, qualifiedName, ".")) {
|
||||
final int i = prefix.indexOf('.', qualifiedName.length() + 1);
|
||||
String childName = i >= 0 ? prefix.substring(0, i) : prefix;
|
||||
if (!packagesMap.containsKey(childName)) {
|
||||
packagesMap.put(childName, new PsiPackageImpl((PsiManagerEx)psiPackage.getManager(), childName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
packagesMap.remove(qualifiedName); // avoid SOE caused by returning a package as a subpackage of itself
|
||||
return packagesMap.values().toArray(new PsiPackage[packagesMap.size()]);
|
||||
}
|
||||
|
||||
public boolean packagePrefixExists(String packageQName) {
|
||||
for (final String prefix : myPackagePrefixIndex.getAllPackagePrefixes(null)) {
|
||||
if (StringUtil.startsWithConcatenationOf(prefix, packageQName, ".") || prefix.equals(packageQName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static PackagePrefixElementFinder getInstance(Project project) {
|
||||
for (PsiElementFinder o : Extensions.getExtensions(PsiElementFinder.EP_NAME, project)) {
|
||||
if (o instanceof PackagePrefixElementFinder) {
|
||||
return (PackagePrefixElementFinder) o;
|
||||
}
|
||||
}
|
||||
throw new UnsupportedOperationException("couldn't find self");
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,7 @@ import com.intellij.openapi.wm.ToolWindowId;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.JavaPsiFacadeImpl;
|
||||
import com.intellij.psi.impl.PackagePrefixElementFinder;
|
||||
import com.intellij.psi.impl.PsiManagerEx;
|
||||
import com.intellij.psi.impl.migration.PsiMigrationImpl;
|
||||
import com.intellij.psi.impl.source.tree.java.PsiCompositeModifierList;
|
||||
@@ -180,7 +181,7 @@ public class PsiPackageImpl extends PsiPackageBase implements PsiPackage, Querya
|
||||
public boolean isValid() {
|
||||
final CommonProcessors.FindFirstProcessor<PsiDirectory> processor = new CommonProcessors.FindFirstProcessor<PsiDirectory>();
|
||||
getFacade().processPackageDirectories(this, allScope(), processor);
|
||||
return processor.getFoundValue() != null || getFacade().packagePrefixExists(getQualifiedName());
|
||||
return processor.getFoundValue() != null || PackagePrefixElementFinder.getInstance(getProject()).packagePrefixExists(getQualifiedName());
|
||||
}
|
||||
|
||||
public void accept(@NotNull PsiElementVisitor visitor) {
|
||||
|
||||
@@ -1122,6 +1122,8 @@
|
||||
<treeCopyHandler implementation="com.intellij.psi.impl.source.tree.JavaTreeCopyHandler"/>
|
||||
<treeGenerator implementation="com.intellij.psi.impl.source.tree.JavaTreeGenerator"/>
|
||||
|
||||
<java.elementFinder implementation="com.intellij.psi.impl.PackagePrefixElementFinder"/>
|
||||
|
||||
<projectService serviceImplementation="com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable"/>
|
||||
<projectService serviceInterface="com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemsSettings"
|
||||
serviceImplementation="com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemsSettingsImpl"/>
|
||||
|
||||
Reference in New Issue
Block a user