IDEA-19738
authorAlexey Kudravtsev <cdr@intellij.com>
Wed, 17 Mar 2010 10:30:29 +0000 (13:30 +0300)
committerAlexey Kudravtsev <cdr@intellij.com>
Wed, 17 Mar 2010 10:34:25 +0000 (13:34 +0300)
java/java-impl/src/com/intellij/ide/actions/JavaQualifiedNameProvider.java
platform/lang-api/src/com/intellij/util/LogicalRootsManager.java
platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java
platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceHelper.java
platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PsiFileReferenceHelper.java
platform/platform-api/src/com/intellij/openapi/vfs/VirtualFile.java

index 606d1c801de685191a0d6ca54d96c5585fbdd484..0f9cfbc1817052400447ad316bb6c9e5fc82ae03 100644 (file)
  */
 package com.intellij.ide.actions;
 
+import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.RangeMarker;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.*;
 import com.intellij.psi.codeStyle.CodeStyleManager;
 import com.intellij.psi.codeStyle.JavaCodeStyleManager;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.RangeMarker;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
 import com.intellij.util.IncorrectOperationException;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.util.LogicalRoot;
+import com.intellij.util.LogicalRootsManager;
 import org.jetbrains.annotations.Nullable;
 
+import java.util.List;
+
 /**
  * @author yole
  */
@@ -69,24 +76,56 @@ public class JavaQualifiedNameProvider implements QualifiedNameProvider {
       return aClass;
     }
     final int endIndex = fqn.indexOf('#');
-    if (endIndex == -1) return null;
-    String className = fqn.substring(0, endIndex);
-    if (className == null) return null;
-    aClass = JavaPsiFacade.getInstance(project).findClass(className, GlobalSearchScope.allScope(project));
-    if (aClass == null) return null;
-    String memberName = fqn.substring(endIndex + 1);
-    PsiField field = aClass.findFieldByName(memberName, false);
-    if (field != null) {
-      return field;
+    if (endIndex != -1) {
+      String className = fqn.substring(0, endIndex);
+      if (className != null) {
+        aClass = JavaPsiFacade.getInstance(project).findClass(className, GlobalSearchScope.allScope(project));
+        if (aClass != null) {
+          String memberName = fqn.substring(endIndex + 1);
+          PsiField field = aClass.findFieldByName(memberName, false);
+          if (field != null) {
+            return field;
+          }
+          PsiMethod[] methods = aClass.findMethodsByName(memberName, false);
+          if (methods.length != 0) {
+            return methods[0];
+          }
+        }
+      }
+    }
+
+    VirtualFile file = findFile(fqn, project);
+    if (file != null) {
+      return PsiManager.getInstance(project).findFile(file);
     }
-    PsiMethod[] methods = aClass.findMethodsByName(memberName, false);
-    if (methods.length == 0) return null;
-    return methods[0];
+    return null;
+  }
+
+  private static VirtualFile findFile(String fqn, Project project) {
+    List<LogicalRoot> lr = LogicalRootsManager.getLogicalRootsManager(project).getLogicalRoots();
+    for (LogicalRoot root : lr) {
+      VirtualFile vfr = root.getVirtualFile();
+      if (vfr == null) continue;
+      VirtualFile virtualFile = vfr.findFileByRelativePath(fqn);
+      if (virtualFile != null) return virtualFile;
+    }
+    for (VirtualFile root : ProjectRootManager.getInstance(project).getContentRoots()) {
+      VirtualFile rel = root.findFileByRelativePath(fqn);
+      if (rel != null) {
+        return rel;
+      }
+    }
+    VirtualFile file = LocalFileSystem.getInstance().findFileByPath(fqn);
+    if (file != null) return file;
+    PsiFile[] files = JavaPsiFacade.getInstance(project).getShortNamesCache().getFilesByName(fqn);
+    for (PsiFile psiFile : files) {
+      VirtualFile virtualFile = psiFile.getVirtualFile();
+      if (virtualFile != null) return virtualFile;
+    }
+    return null;
   }
 
   public void insertQualifiedName(String fqn, final PsiElement element, final Editor editor, final Project project) {
-    if (!(element instanceof PsiMember)) return;
-    PsiMember targetElement = (PsiMember) element;
     final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
     Document document = editor.getDocument();
 
@@ -98,10 +137,13 @@ public class JavaQualifiedNameProvider implements QualifiedNameProvider {
     fqn = fqn.replace('#', '.');
     String toInsert;
     String suffix = "";
-    PsiElement elementToInsert = targetElement;
-    if (elementAtCaret != null && targetElement instanceof PsiMethod && PsiUtil.isInsideJavadocComment(elementAtCaret)) {
+
+    if (!(element instanceof PsiMember)) {
+      toInsert = fqn;
+    }
+    else if (elementAtCaret != null && element instanceof PsiMethod && PsiUtil.isInsideJavadocComment(elementAtCaret)) {
       // use fqn#methodName(ParamType)
-      PsiMethod method = (PsiMethod)targetElement;
+      PsiMethod method = (PsiMethod)element;
       PsiClass aClass = method.getContainingClass();
       String className = aClass == null ? "" : aClass.getQualifiedName();
       toInsert = className == null ? "" : className;
@@ -121,6 +163,8 @@ public class JavaQualifiedNameProvider implements QualifiedNameProvider {
       toInsert = fqn;
     }
     else {
+      PsiMember targetElement = (PsiMember)element;
+
       toInsert = targetElement.getName();
       if (targetElement instanceof PsiMethod) {
         suffix = "()";
@@ -177,7 +221,7 @@ public class JavaQualifiedNameProvider implements QualifiedNameProvider {
 
     if (elementAtCaret != null && elementAtCaret.isValid()) {
       try {
-        shortenReference(elementAtCaret, targetElement);
+        shortenReference(elementAtCaret, element);
       }
       catch (IncorrectOperationException e) {
         LOG.error(e);
@@ -192,7 +236,7 @@ public class JavaQualifiedNameProvider implements QualifiedNameProvider {
     }
 
     int caretOffset = rangeMarker.getEndOffset();
-    if (elementToInsert instanceof PsiMethod && ((PsiMethod)elementToInsert).getParameterList().getParametersCount() != 0 && StringUtil.endsWithChar(suffix,')')) {
+    if (element instanceof PsiMethod && ((PsiMethod)element).getParameterList().getParametersCount() != 0 && StringUtil.endsWithChar(suffix,')')) {
       caretOffset --;
     }
     editor.getCaretModel().moveToOffset(caretOffset);
@@ -240,7 +284,7 @@ public class JavaQualifiedNameProvider implements QualifiedNameProvider {
     return PsiTreeUtil.getParentOfType(prevElement, PsiNewExpression.class) != null;
   }
 
-  private static void shortenReference(PsiElement element, PsiMember elementToInsert) throws IncorrectOperationException {
+  private static void shortenReference(PsiElement element, PsiElement elementToInsert) throws IncorrectOperationException {
     while (element.getParent() instanceof PsiJavaCodeReferenceElement) {
       element = element.getParent();
       if (element == null) return;
index 31662c2cf138ffc12775653889b1551178423f40..de787138080b61da49898b99b5ccd3871d484438 100644 (file)
@@ -31,7 +31,7 @@ import java.util.List;
  * // TODO: merge with FileReferenceHelper & drop
  *
  * @author spleaner
- * @deprecated Use FileReferenceHelper instead
+ * @deprecated use {@link com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceHelper} instead
  */
 @Deprecated
 public abstract class LogicalRootsManager {
index 92785c7aa3c94c832a247b84be9e5a69690585ff..3e94db9bf54c901db7e7eb170e5f43454fb3ea06 100644 (file)
@@ -178,7 +178,9 @@ public class CopyReferenceAction extends AnAction {
     final Project project = file.getProject();
     final LogicalRoot logicalRoot = LogicalRootsManager.getLogicalRootsManager(project).findLogicalRoot(virtualFile);
     if (logicalRoot != null) {
-      return "/"+FileUtil.getRelativePath(VfsUtil.virtualToIoFile(logicalRoot.getVirtualFile()), VfsUtil.virtualToIoFile(virtualFile));
+      String logical = FileUtil.toSystemIndependentName(VfsUtil.virtualToIoFile(logicalRoot.getVirtualFile()).getPath());
+      String path = FileUtil.toSystemIndependentName(VfsUtil.virtualToIoFile(virtualFile).getPath());
+      return "/" + FileUtil.getRelativePath(logical, path, '/');
     }
 
     final VirtualFile contentRoot = ProjectRootManager.getInstance(project).getFileIndex().getContentRootForFile(virtualFile);
index 54cdf256278de5e10b8cd4f69ad9842259e421c3..d7748eee0e33176774e95a80727c8a896a37b508 100644 (file)
@@ -48,19 +48,19 @@ public abstract class FileReferenceHelper {
   }
 
   @Nullable
-  public PsiFileSystemItem getPsiFileSystemItem(final Project project, final @NotNull VirtualFile file) {
+  public PsiFileSystemItem getPsiFileSystemItem(final Project project, @NotNull final VirtualFile file) {
     final PsiManager psiManager = PsiManager.getInstance(project);
     return file.isDirectory() ? psiManager.findDirectory(file) : psiManager.findFile(file);
   }
 
   @Nullable
-  public abstract PsiFileSystemItem findRoot(final Project project, final @NotNull VirtualFile file);
+  public abstract PsiFileSystemItem findRoot(final Project project, @NotNull final VirtualFile file);
 
   @NotNull
   public abstract Collection<PsiFileSystemItem> getRoots(@NotNull Module module);
 
   @NotNull
-  public abstract Collection<PsiFileSystemItem> getContexts(final Project project, final @NotNull VirtualFile file);
+  public abstract Collection<PsiFileSystemItem> getContexts(final Project project, @NotNull final VirtualFile file);
 
-  public abstract boolean isMine(final Project project, final @NotNull VirtualFile file);
+  public abstract boolean isMine(final Project project, @NotNull final VirtualFile file);
 }
index 3a56932016ffccbe7fafb50bda2cb03fa468182f..61163438ed1a110078e0a190fec205ecc6f0ca45 100644 (file)
@@ -59,7 +59,7 @@ public class PsiFileReferenceHelper extends FileReferenceHelper {
   }
 
   @NotNull
-  public Collection<PsiFileSystemItem> getContexts(final Project project, final @NotNull VirtualFile file) {
+  public Collection<PsiFileSystemItem> getContexts(final Project project, @NotNull final VirtualFile file) {
     final PsiFileSystemItem item = getPsiFileSystemItem(project, file);
     if (item != null) {
       final PsiFileSystemItem parent = item.getParent();
@@ -102,7 +102,7 @@ public class PsiFileReferenceHelper extends FileReferenceHelper {
     return Collections.emptyList();
   }
 
-  public boolean isMine(final Project project, final @NotNull VirtualFile file) {
+  public boolean isMine(final Project project, @NotNull final VirtualFile file) {
     final ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex();
     return index.isInSourceContent(file);
   }
index aba97becb32bddc5172dcd9e4cbd1830ff232332..a26cfd9612c26f63c19bdca07200ad1ad6936bca 100644 (file)
@@ -22,6 +22,7 @@ import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.fileTypes.FileType;
 import com.intellij.openapi.fileTypes.FileTypeManager;
 import com.intellij.openapi.util.*;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.encoding.EncodingManager;
 import com.intellij.openapi.vfs.newvfs.events.VFilePropertyChangeEvent;
 import org.jetbrains.annotations.NonNls;
@@ -275,6 +276,7 @@ public abstract class VirtualFile extends UserDataHolderBase implements Modifica
   @Nullable
   public VirtualFile findFileByRelativePath(@NotNull @NonNls String relPath) {
     if (relPath.length() == 0) return this;
+    relPath = StringUtil.trimStart(relPath, "/");
 
     int index = relPath.indexOf('/');
     if (index < 0) index = relPath.length();