From 340bc7a46a90c1087de0b1a89390d1dc50c553de Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 3 Jan 2014 16:10:41 +0100 Subject: [PATCH] platform: fake root considered harmful --- .../impl/providers/FileReference.java | 9 +++- .../impl/providers/FileReferenceSet.java | 18 ++++++++ .../intellij/openapi/vfs/LocalFileSystem.java | 12 +++--- .../TestDataReferenceContributor.java | 21 ++++------ .../lang/ant/dom/AntDomFileReferenceSet.java | 35 ++++++++-------- .../python/psi/RootFileReferenceSet.java | 41 +++++++------------ 6 files changed, 71 insertions(+), 65 deletions(-) diff --git a/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReference.java b/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReference.java index 3c7b035d1706..706c5127ed7a 100644 --- a/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReference.java +++ b/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReference.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -24,6 +24,7 @@ import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; @@ -189,7 +190,11 @@ public class FileReference implements PsiFileReference, FileReferenceOwner, PsiP context = ((PackagePrefixFileSystemItem)context).getDirectory(); } - if (context instanceof PsiDirectory && caseSensitivityApplies((PsiDirectory)context, caseSensitive)) { + if (context.getParent() == null && FileUtil.namesEqual(decoded, context.getName())) { + // match filesystem roots + result.add(new PsiElementResolveResult(getOriginalFile(context))); + } + else if (context instanceof PsiDirectory && caseSensitivityApplies((PsiDirectory)context, caseSensitive)) { // optimization: do not load all children into VFS PsiDirectory directory = (PsiDirectory)context; PsiFileSystemItem child = directory.findFile(decoded); diff --git a/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java b/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java index b0988599cd0a..628d386cee24 100644 --- a/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java +++ b/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java @@ -28,6 +28,8 @@ import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.util.Function; +import com.intellij.util.NullableFunction; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -413,6 +415,22 @@ public class FileReferenceSet { return list; } + @NotNull + protected Collection toFileSystemItems(VirtualFile... files) { + return toFileSystemItems(Arrays.asList(files)); + } + + @NotNull + protected Collection toFileSystemItems(@NotNull Collection files) { + final PsiManager manager = getElement().getManager(); + return ContainerUtil.mapNotNull(files, new NullableFunction() { + @Override + public PsiFileSystemItem fun(VirtualFile file) { + return file != null ? manager.findDirectory(file) : null; + } + }); + } + protected Condition getReferenceCompletionFilter() { return Conditions.alwaysTrue(); } diff --git a/platform/platform-api/src/com/intellij/openapi/vfs/LocalFileSystem.java b/platform/platform-api/src/com/intellij/openapi/vfs/LocalFileSystem.java index 58b546955906..c524f2c5eabe 100644 --- a/platform/platform-api/src/com/intellij/openapi/vfs/LocalFileSystem.java +++ b/platform/platform-api/src/com/intellij/openapi/vfs/LocalFileSystem.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -17,7 +17,6 @@ package com.intellij.openapi.vfs; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.vfs.newvfs.ManagingFS; -import com.intellij.openapi.vfs.newvfs.NewVirtualFile; import com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem; import com.intellij.util.Processor; import com.intellij.util.io.fs.IFile; @@ -101,12 +100,11 @@ public abstract class LocalFileSystem extends NewVirtualFileSystem { public abstract void refreshFiles(@NotNull Iterable files, boolean async, boolean recursive, @Nullable Runnable onFinish); - @NotNull + /** @deprecated fake root considered harmful (to remove in IDEA 14) */ public final VirtualFile getRoot() { - final String rootPath = SystemInfo.isWindows ? "" : "/"; - final NewVirtualFile root = ManagingFS.getInstance().findRoot(rootPath, this); - assert root != null : SystemInfo.OS_NAME; - return root; + VirtualFile[] roots = ManagingFS.getInstance().getLocalRoots(); + assert roots.length > 0 : SystemInfo.OS_NAME; + return roots[0]; } public interface WatchRequest { diff --git a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceContributor.java b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceContributor.java index 28de8d3d124d..dbe3cf2910e5 100644 --- a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceContributor.java +++ b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataReferenceContributor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -21,26 +21,26 @@ import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.newvfs.ManagingFS; import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileInfoManager; import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference; import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet; +import com.intellij.util.ArrayUtil; import com.intellij.util.ProcessingContext; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collection; -import java.util.Collections; import static com.intellij.patterns.PsiJavaPatterns.literalExpression; import static com.intellij.testAssistant.TestDataLineMarkerProvider.*; /** - * User: zolotov - * Date: 9/20/13 + * @author zolotov + * @since 9/20/13 */ public class TestDataReferenceContributor extends PsiReferenceContributor { @Override @@ -82,13 +82,7 @@ public class TestDataReferenceContributor extends PsiReferenceContributor { @NotNull @Override public Collection computeDefaultContexts() { - final VirtualFile localSystemRoot = LocalFileSystem.getInstance().getRoot(); - final PsiManager psiManager = PsiManager.getInstance(getElement().getProject()); - final PsiDirectory psiRoot = psiManager.findDirectory(localSystemRoot); - if (psiRoot != null) { - return Collections.singleton(psiRoot); - } - return super.computeDefaultContexts(); + return toFileSystemItems(ManagingFS.getInstance().getLocalRoots()); } @Override @@ -118,8 +112,9 @@ public class TestDataReferenceContributor extends PsiReferenceContributor { variants.add(FileInfoManager.getFileLookupItem(contentPsiRoot, CONTENT_ROOT_VARIABLE, contentPsiRoot.getIcon(0)) .withTypeText(contentPsiRoot.getVirtualFile().getPath(), true)); } - return variants.toArray(new Object[variants.size()]); + return ArrayUtil.toObjectArray(variants); } + return super.getVariants(); } diff --git a/plugins/ant/src/com/intellij/lang/ant/dom/AntDomFileReferenceSet.java b/plugins/ant/src/com/intellij/lang/ant/dom/AntDomFileReferenceSet.java index bd6225c97857..6587164c94d0 100644 --- a/plugins/ant/src/com/intellij/lang/ant/dom/AntDomFileReferenceSet.java +++ b/plugins/ant/src/com/intellij/lang/ant/dom/AntDomFileReferenceSet.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -20,22 +20,20 @@ import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.newvfs.ManagingFS; import com.intellij.psi.ElementManipulators; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiFileSystemItem; import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference; import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet; import com.intellij.psi.xml.XmlAttributeValue; -import com.intellij.psi.xml.XmlElement; import com.intellij.util.xml.GenericAttributeValue; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collection; -import java.util.Collections; public class AntDomFileReferenceSet extends FileReferenceSet { - private final GenericAttributeValue myValue; public AntDomFileReferenceSet(final GenericAttributeValue attribValue, boolean validateFileRefs) { @@ -67,11 +65,13 @@ public class AntDomFileReferenceSet extends FileReferenceSet { } return path; } - + + @Override protected boolean isSoft() { return true; } + @Override public FileReference createFileReference(final TextRange range, final int index, final String text) { return new AntDomFileReference(this, range, index, text); } @@ -82,28 +82,34 @@ public class AntDomFileReferenceSet extends FileReferenceSet { } @Nullable + @Override public String getPathString() { return myValue.getStringValue(); } + @Override public boolean isAbsolutePathReference() { if (super.isAbsolutePathReference()) { return true; } - return FileUtil.isAbsolute(getPathString()); + + String path = getPathString(); + return path != null && FileUtil.isAbsolute(path); } @NotNull + @Override public Collection computeDefaultContexts() { final AntDomElement element = myValue.getParentOfType(AntDomElement.class, false); final AntDomProject containingProject = element != null? element.getAntProject() : null; + if (containingProject != null) { - VirtualFile root = null; if (isAbsolutePathReference()) { - root = LocalFileSystem.getInstance().getRoot(); + return toFileSystemItems(ManagingFS.getInstance().getLocalRoots()); } else { - + VirtualFile root = null; + if (element instanceof AntDomAnt) { final PsiFileSystemItem dirValue = ((AntDomAnt)element).getAntFileDir().getValue(); if (dirValue instanceof PsiDirectory) { @@ -123,18 +129,13 @@ public class AntDomFileReferenceSet extends FileReferenceSet { root = LocalFileSystem.getInstance().findFileByPath(basedir); } } - } - if (root != null) { - final XmlElement xmlElement = containingProject.getXmlElement(); - if (xmlElement != null) { - final PsiDirectory directory = xmlElement.getManager().findDirectory(root); - if (directory != null) { - return Collections.singleton(directory); - } + if (root != null) { + return toFileSystemItems(root); } } } + return super.computeDefaultContexts(); } } diff --git a/python/openapi/src/com/jetbrains/python/psi/RootFileReferenceSet.java b/python/openapi/src/com/jetbrains/python/psi/RootFileReferenceSet.java index 36cf4d270278..8fd92a3b6fd9 100644 --- a/python/openapi/src/com/jetbrains/python/psi/RootFileReferenceSet.java +++ b/python/openapi/src/com/jetbrains/python/psi/RootFileReferenceSet.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -15,20 +15,20 @@ */ package com.jetbrains.python.psi; -import com.google.common.collect.Lists; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.*; +import com.intellij.openapi.vfs.newvfs.ManagingFS; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiFileSystemItem; +import com.intellij.psi.PsiReferenceProvider; import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet; -import com.jetbrains.python.psi.PyStringLiteralExpression; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collection; -import java.util.Collections; /** * Resolves absolute paths from FS root, not content roots @@ -41,7 +41,8 @@ public class RootFileReferenceSet extends FileReferenceSet { int startInElement, PsiReferenceProvider provider, boolean caseSensitive, - boolean endingSlashNotAllowed, @Nullable FileType[] suitableFileTypes) { + boolean endingSlashNotAllowed, + @Nullable FileType[] suitableFileTypes) { super(str, element, startInElement, provider, caseSensitive, endingSlashNotAllowed, suitableFileTypes); } @@ -49,6 +50,7 @@ public class RootFileReferenceSet extends FileReferenceSet { super(s, element, offset, provider, sensitive); } + @Override public boolean isAbsolutePathReference() { if (!ApplicationManager.getApplication().isUnitTestMode()) { return FileUtil.isAbsolute(getPathString()); @@ -61,26 +63,13 @@ public class RootFileReferenceSet extends FileReferenceSet { @NotNull @Override public Collection computeDefaultContexts() { - final PsiFile file = getContainingFile(); - if (file != null) { + PsiFile file = getContainingFile(); + if (file == null) return ContainerUtil.emptyList(); - if (isAbsolutePathReference()) { - if (!ApplicationManager.getApplication().isUnitTestMode()) { - VirtualFile root = LocalFileSystem.getInstance().getRoot(); - PsiDirectory directory = file.getManager().findDirectory(root); - if (directory != null) { - return Lists.newArrayList(directory); - } - } - else { - return super.computeDefaultContexts(); - } - } - else { - return super.computeDefaultContexts(); - } + if (isAbsolutePathReference() && !ApplicationManager.getApplication().isUnitTestMode()) { + return toFileSystemItems(ManagingFS.getInstance().getLocalRoots()); } - return Collections.emptyList(); + return super.computeDefaultContexts(); } }