From 9659afa868ea850463bb96850155aea7800d593e Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 7 Jun 2013 19:37:36 +0400 Subject: [PATCH] SPI: initial container modifications --- .../src/com/intellij/spi/psi/SPIFile.java | 88 ++++++++++++++++++- .../impl/search/SPIReferencesSearcher.java | 84 ++++++++++++------ 2 files changed, 140 insertions(+), 32 deletions(-) diff --git a/java/java-impl/src/com/intellij/spi/psi/SPIFile.java b/java/java-impl/src/com/intellij/spi/psi/SPIFile.java index 9f1e8106878a..a3858c50ccb3 100644 --- a/java/java-impl/src/com/intellij/spi/psi/SPIFile.java +++ b/java/java-impl/src/com/intellij/spi/psi/SPIFile.java @@ -29,6 +29,9 @@ import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.List; + /** * User: anna */ @@ -47,6 +50,35 @@ public class SPIFile extends PsiFileBase { })); } + @NotNull + @Override + public PsiReference[] getReferences() { + final List refs = new ArrayList(); + int idx = 0; + int d; + final String fileName = getName(); + while ((d = fileName.indexOf(".", idx)) > -1) { + final PsiPackage aPackage = JavaPsiFacade.getInstance(getProject()).findPackage(fileName.substring(0, d)); + if (aPackage != null) { + refs.add(new SPIFileName2PackageReference(this, aPackage)); + } + idx = d + 1; + } + final PsiReference reference = getReference(); + PsiElement resolve = reference.resolve(); + while (resolve instanceof PsiClass) { + resolve = ((PsiClass)resolve).getContainingClass(); + if (resolve != null) { + final String jvmClassName = ClassUtil.getJVMClassName((PsiClass)resolve); + if (jvmClassName != null) { + refs.add(new SPIFileName2PackageReference(this, resolve)); + } + } + } + refs.add(reference); + return refs.toArray(new PsiReference[refs.size()]); + } + @NotNull @Override public FileType getFileType() { @@ -69,10 +101,12 @@ public class SPIFile extends PsiFileBase { @Override public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { - final String className = ClassUtil.getJVMClassName(myClass); - if (className != null) { - final String newFileName = className.substring(0, className.lastIndexOf(myClass.getName())) + newElementName; - return getElement().setName(newFileName); + if (myClass != null) { + final String className = ClassUtil.getJVMClassName(myClass); + if (className != null) { + final String newFileName = className.substring(0, className.lastIndexOf(myClass.getName())) + newElementName; + return getElement().setName(newFileName); + } } return getElement(); } @@ -94,4 +128,50 @@ public class SPIFile extends PsiFileBase { return ArrayUtil.EMPTY_OBJECT_ARRAY; } } + + private static class SPIFileName2PackageReference extends PsiReferenceBase { + private final PsiElement myPackageOrContainingClass; + + public SPIFileName2PackageReference(PsiFile file, @NotNull PsiElement psiPackage) { + super(file, new TextRange(0, 0), false); + myPackageOrContainingClass = psiPackage; + } + + @NotNull + @Override + public String getCanonicalText() { + return myPackageOrContainingClass instanceof PsiPackage + ? ((PsiPackage)myPackageOrContainingClass).getQualifiedName() : ClassUtil.getJVMClassName((PsiClass)myPackageOrContainingClass); + } + + @Nullable + @Override + public PsiElement resolve() { + return myPackageOrContainingClass; + } + + @Override + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + return getElement().setName(newElementName + getElement().getName().substring(getCanonicalText().length())); + } + + @Override + public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { + if (element instanceof PsiPackage) { + return handleElementRename(((PsiPackage)element).getQualifiedName()); + } else if (element instanceof PsiClass) { + final String className = ClassUtil.getJVMClassName((PsiClass)element); + if (className != null) { + return handleElementRename(className); + } + } + return getElement(); + } + + @NotNull + @Override + public Object[] getVariants() { + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + } } diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/SPIReferencesSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/SPIReferencesSearcher.java index 6ffe6247d4e7..080c800c89f4 100644 --- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/SPIReferencesSearcher.java +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/SPIReferencesSearcher.java @@ -18,11 +18,9 @@ package com.intellij.psi.impl.search; import com.intellij.lang.spi.SPILanguage; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.QueryExecutorBase; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiReference; +import com.intellij.psi.*; import com.intellij.psi.search.FilenameIndex; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.SearchScope; @@ -33,32 +31,62 @@ import org.jetbrains.annotations.NotNull; public class SPIReferencesSearcher extends QueryExecutorBase { @Override - public void processQuery(@NotNull ReferencesSearch.SearchParameters p, @NotNull Processor consumer) { - final PsiElement element = p.getElementToSearch(); - if (!(element instanceof PsiClass)) { - return; - } - final SearchScope scope = p.getEffectiveSearchScope(); + public void processQuery(@NotNull final ReferencesSearch.SearchParameters p, @NotNull Processor consumer) { + final SearchScope scope = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public SearchScope compute() { + return p.getEffectiveSearchScope(); + } + }); if (!(scope instanceof GlobalSearchScope)) return; - final PsiClass aClass = (PsiClass)element; - final String jvmClassName = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public String compute() { - return ClassUtil.getJVMClassName(aClass); + + final PsiElement element = p.getElementToSearch(); + if (element instanceof PsiClass) { + final PsiClass aClass = (PsiClass)element; + final String jvmClassName = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public String compute() { + return ClassUtil.getJVMClassName(aClass); + } + }); + + if (jvmClassName == null) return; + final PsiFile[] files = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public PsiFile[] compute() { + return FilenameIndex.getFilesByName(aClass.getProject(), jvmClassName, (GlobalSearchScope)scope); + } + }); + for (PsiFile file : files) { + if (file.getLanguage() == SPILanguage.INSTANCE) { + final PsiReference reference = file.getReference(); + if (reference != null) { + consumer.process(reference); + } + } } - }); - if (jvmClassName == null) return; - final PsiFile[] files = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiFile[] compute() { - return FilenameIndex.getFilesByName(aClass.getProject(), jvmClassName, (GlobalSearchScope)scope); - } - }); - for (PsiFile file : files) { - if (file.getLanguage() == SPILanguage.INSTANCE) { - final PsiReference reference = file.getReference(); - if (reference != null) { - consumer.process(reference); + } else if (element instanceof PsiPackage) { + final String qualifiedName = ((PsiPackage)element).getQualifiedName(); + final Project project = element.getProject(); + final String[] filenames = FilenameIndex.getAllFilenames(project); + for (final String filename : filenames) { + if (filename.startsWith(qualifiedName + ".")) { + final PsiFile[] files = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public PsiFile[] compute() { + return FilenameIndex.getFilesByName(project, filename, (GlobalSearchScope)scope); + } + }); + for (PsiFile file : files) { + if (file.getLanguage() == SPILanguage.INSTANCE) { + final PsiReference[] references = file.getReferences(); + for (PsiReference reference : references) { + if (reference.getCanonicalText().equals(qualifiedName)) { + consumer.process(reference); + } + } + } + } } } }