WEB-6584 Files opened by URL should also be able to open scripts used in the file

This commit is contained in:
Vladimir Krivosheev
2014-04-30 15:29:02 +02:00
parent 1461ed0ad9
commit ab7c4be264
9 changed files with 139 additions and 18 deletions
@@ -183,6 +183,13 @@ public class FileReference implements PsiFileReference, FileReferenceOwner, PsiP
if (context instanceof PackagePrefixFileSystemItem) {
context = ((PackagePrefixFileSystemItem)context).getDirectory();
}
else if (context instanceof FileReferenceResolver) {
PsiFileSystemItem child = ((FileReferenceResolver)context).resolveFileReference(this, decoded);
if (child != null) {
result.add(new PsiElementResolveResult(getOriginalFile(child)));
return;
}
}
if (context.getParent() == null && FileUtil.namesEqual(decoded, context.getName())) {
// match filesystem roots
@@ -0,0 +1,10 @@
package com.intellij.psi.impl.source.resolve.reference.impl.providers;
import com.intellij.psi.PsiFileSystemItem;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface FileReferenceResolver {
@Nullable
PsiFileSystemItem resolveFileReference(@NotNull FileReference reference, @NotNull String name);
}
@@ -42,4 +42,5 @@ public abstract class HttpFileSystem extends DeprecatedVirtualFileSystem {
public abstract void removeFileListener(@NotNull HttpVirtualFileListener listener);
public abstract VirtualFile createChild(@NotNull VirtualFile parent, @NotNull String name, boolean isDirectory);
}
@@ -0,0 +1,36 @@
package com.intellij.psi.impl.source.resolve.reference.impl.providers;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.impl.http.HttpVirtualFile;
import com.intellij.psi.PsiFileSystemItem;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
final class HttpFileReferenceHelper extends FileReferenceHelper {
@Nullable
@Override
public PsiFileSystemItem findRoot(Project project, @NotNull VirtualFile file) {
VirtualFile root = file;
VirtualFile parent;
while ((parent = root.getParent()) != null) {
root = parent;
}
return getPsiFileSystemItem(project, root);
}
@NotNull
@Override
public Collection<PsiFileSystemItem> getContexts(Project project, @NotNull VirtualFile file) {
PsiFileSystemItem item = getPsiFileSystemItem(project, file);
return item == null ? Collections.<PsiFileSystemItem>emptyList() : Collections.singleton(item);
}
@Override
public boolean isMine(Project project, @NotNull VirtualFile file) {
return file instanceof HttpVirtualFile;
}
}
@@ -41,12 +41,7 @@ public abstract class HttpFileSystemBase extends HttpFileSystem {
}
public VirtualFile findFileByPath(@NotNull String path, boolean isDirectory) {
try {
return getRemoteFileManager().getOrCreateFile(Urls.newFromIdea(VirtualFileManager.constructUrl(myProtocol, path)), path, isDirectory);
}
catch (IOException e) {
return null;
}
return getRemoteFileManager().getOrCreateFile(null, Urls.newFromIdea(VirtualFileManager.constructUrl(myProtocol, path)), path, isDirectory);
}
@Override
@@ -69,16 +64,22 @@ public abstract class HttpFileSystemBase extends HttpFileSystem {
return file instanceof HttpVirtualFile && ((HttpVirtualFile)file).getFileInfo().getState() == RemoteFileState.DOWNLOADED;
}
@Override
@NotNull
public VirtualFile createChild(@NotNull VirtualFile parent, @NotNull String name, boolean isDirectory) {
return getRemoteFileManager().getOrCreateFile((VirtualFileImpl)parent, Urls.newFromIdea(parent.getUrl() + '/' + name), parent.getPath() + '/' + name, isDirectory);
}
@Override
@NotNull
public VirtualFile createChildDirectory(Object requestor, @NotNull VirtualFile vDir, @NotNull String dirName) throws IOException {
throw new UnsupportedOperationException();
return createChild(vDir, dirName, true);
}
@NotNull
@Override
public VirtualFile createChildFile(Object requestor, @NotNull VirtualFile vDir, @NotNull String fileName) throws IOException {
throw new UnsupportedOperationException();
return createChild(vDir, fileName, false);
}
@Override
@@ -24,8 +24,8 @@ import com.intellij.util.EventDispatcher;
import com.intellij.util.Url;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -55,17 +55,17 @@ public class RemoteFileManagerImpl extends RemoteFileManager implements Disposab
return myDefaultRemoteContentProvider;
}
public synchronized VirtualFileImpl getOrCreateFile(final @NotNull Url url, final @NotNull String path, final boolean directory) throws IOException {
public synchronized VirtualFileImpl getOrCreateFile(@Nullable VirtualFileImpl parent, @NotNull Url url, @NotNull String path, final boolean directory) {
Pair<Boolean, Url> key = Pair.create(directory, url);
VirtualFileImpl file = myRemoteFiles.get(key);
if (file == null) {
if (!directory) {
RemoteFileInfoImpl fileInfo = new RemoteFileInfoImpl(url, this);
file = new VirtualFileImpl(getHttpFileSystem(url), path, fileInfo);
fileInfo.addDownloadingListener(new MyDownloadingListener(file));
if (directory) {
file = new VirtualFileImpl(getHttpFileSystem(url), parent, path, null);
}
else {
file = new VirtualFileImpl(getHttpFileSystem(url), path, null);
RemoteFileInfoImpl fileInfo = new RemoteFileInfoImpl(url, this);
file = new VirtualFileImpl(getHttpFileSystem(url), parent, path, fileInfo);
fileInfo.addDownloadingListener(new MyDownloadingListener(file));
}
myRemoteFiles.put(key, file);
}
@@ -18,17 +18,22 @@ package com.intellij.openapi.vfs.impl.http;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileSystem;
import com.intellij.util.ArrayUtil;
import com.intellij.util.FileContentUtilCore;
import com.intellij.util.SmartList;
import com.intellij.util.UriUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
class VirtualFileImpl extends HttpVirtualFile {
private final HttpFileSystemBase myFileSystem;
@@ -38,7 +43,16 @@ class VirtualFileImpl extends HttpVirtualFile {
private final String myParentPath;
private final String myName;
VirtualFileImpl(HttpFileSystemBase fileSystem, String path, @Nullable final RemoteFileInfoImpl fileInfo) {
private List<VirtualFile> myChildren;
VirtualFileImpl(@NotNull HttpFileSystemBase fileSystem, @Nullable VirtualFileImpl parent, String path, @Nullable RemoteFileInfoImpl fileInfo) {
if (parent != null) {
if (parent.myChildren == null) {
parent.myChildren = new SmartList<VirtualFile>();
}
parent.myChildren.add(this);
}
myFileSystem = fileSystem;
myPath = path;
myFileInfo = fileInfo;
@@ -142,7 +156,20 @@ class VirtualFileImpl extends HttpVirtualFile {
@Override
public VirtualFile[] getChildren() {
return EMPTY_ARRAY;
return ContainerUtil.isEmpty(myChildren) ? EMPTY_ARRAY : myChildren.toArray(new VirtualFile[myChildren.size()]);
}
@Nullable
@Override
public VirtualFile findChild(@NotNull @NonNls String name) {
if (!ContainerUtil.isEmpty(myChildren)) {
for (VirtualFile child : myChildren) {
if (StringUtil.equals(child.getNameSequence(), name)) {
return child;
}
}
}
return null;
}
@Override
@@ -744,6 +744,7 @@
<psi.fileReferenceHelper implementation="com.intellij.psi.impl.source.resolve.reference.impl.providers.PsiFileReferenceHelper"/>
<psi.fileReferenceHelper implementation="com.intellij.psi.impl.source.resolve.reference.impl.providers.JarFileReferenceHelper"/>
<psi.fileReferenceHelper implementation="com.intellij.psi.impl.source.resolve.reference.impl.providers.HttpFileReferenceHelper"/>
<psi.fileReferenceHelper implementation="com.intellij.psi.impl.source.resolve.reference.impl.providers.NullFileReferenceHelper" order="last"/>
<projectConfigurable instance="com.intellij.openapi.vfs.encoding.FileEncodingConfigurable"/>
@@ -16,21 +16,30 @@
package com.intellij.psi.impl.source.html;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.ex.http.HttpFileSystem;
import com.intellij.openapi.vfs.impl.http.HttpVirtualFile;
import com.intellij.psi.FileViewProvider;
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.FileReferenceResolver;
import com.intellij.psi.impl.source.tree.CompositeElement;
import com.intellij.psi.impl.source.xml.XmlFileImpl;
import com.intellij.psi.xml.XmlDocument;
import com.intellij.psi.xml.XmlElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author maxim
*/
public class HtmlFileImpl extends XmlFileImpl {
public class HtmlFileImpl extends XmlFileImpl implements FileReferenceResolver {
public HtmlFileImpl(FileViewProvider provider) {
super(provider, XmlElementType.HTML_FILE);
}
public String toString() {
return "HtmlFile:" + getName();
}
@@ -41,4 +50,33 @@ public class HtmlFileImpl extends XmlFileImpl {
ASTNode node = treeElement.findChildByType(XmlElementType.HTML_DOCUMENT);
return node != null ? (XmlDocument)node.getPsi() : null;
}
@Nullable
@Override
public PsiFileSystemItem resolveFileReference(@NotNull FileReference reference, @NotNull String name) {
VirtualFile file = getVirtualFile();
if (!(file instanceof HttpVirtualFile)) {
return null;
}
VirtualFile childFile = file.findChild(name);
HttpFileSystem fileSystem = (HttpFileSystem)getVirtualFile().getFileSystem();
if (childFile == null) {
childFile = fileSystem.createChild(getVirtualFile(), name, !reference.isLast());
}
if (childFile.isDirectory()) {
// pre create children
VirtualFile childParent = childFile;
FileReference[] references = reference.getFileReferenceSet().getAllReferences();
for (int i = reference.getIndex() + 1, n = references.length; i < n; i++) {
FileReference childReference = references[i];
childParent = fileSystem.createChild(childParent, childReference.decode(childReference.getText()), i != (n - 1));
}
return getManager().findDirectory(childFile);
}
else {
return getManager().findFile(childFile);
}
}
}