Merge remote-tracking branch 'origin/master'

This commit is contained in:
Alexander Lobas
2012-04-16 16:56:36 +04:00
18 changed files with 277 additions and 208 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -284,9 +284,7 @@ public class ArtifactManagerImpl extends ArtifactManager implements ProjectCompo
ContainerUtil.addIfNotNull(request, requestsToRemove);
}
final LocalFileSystem fileSystem = LocalFileSystem.getInstance();
fileSystem.removeWatchedRoots(requestsToRemove);
final Set<LocalFileSystem.WatchRequest> newRequests = fileSystem.addRootsToWatch(toAdd, true);
Set<LocalFileSystem.WatchRequest> newRequests = LocalFileSystem.getInstance().replaceWatchedRoots(requestsToRemove, toAdd, true);
for (LocalFileSystem.WatchRequest request : newRequests) {
myWatchedOutputs.put(request.getRootPath(), request);
}
@@ -300,9 +300,9 @@ public class RefJavaManagerImpl extends RefJavaManager {
public void export(final RefEntity refEntity, final Element element) {
if (refEntity instanceof RefElement) {
final PsiElement psiElement = ((RefElement)refEntity).getElement();
if (psiElement != null) {
final PsiFile psiFile = psiElement.getContainingFile();
final SmartPsiElementPointer pointer = ((RefElement)refEntity).getPointer();
if (pointer != null) {
final PsiFile psiFile = pointer.getContainingFile();
if (psiFile instanceof PsiJavaFile) {
appendPackageElement(element, ((PsiJavaFile)psiFile).getPackageName());
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -98,12 +98,7 @@ public class CompilerProjectExtensionImpl extends CompilerProjectExtension {
public void setCompilerOutputUrl(String compilerOutputUrl) {
VirtualFilePointer pointer = VirtualFilePointerManager.getInstance().create(compilerOutputUrl, myProject, null);
setCompilerOutputPointer(pointer);
final LocalFileSystem.WatchRequest watchRequest =
LocalFileSystem.getInstance().addRootToWatch(ProjectRootManagerImpl.extractLocalPath(compilerOutputUrl), true);
if (myCompilerOutputWatchRequest != null) {
LocalFileSystem.getInstance().removeWatchedRoot(myCompilerOutputWatchRequest);
}
myCompilerOutputWatchRequest = watchRequest;
myCompilerOutputWatchRequest = LocalFileSystem.getInstance().replaceWatchedRoot(myCompilerOutputWatchRequest, compilerOutputUrl, true);
}
@NotNull
@@ -25,6 +25,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.Consumer;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
@@ -45,7 +46,7 @@ public class ClassLiteralGetter {
PsiElement position = parameters.getPosition();
if (classParameter instanceof PsiWildcardType) {
final PsiWildcardType wildcardType = (PsiWildcardType)classParameter;
classParameter = wildcardType.getBound();
classParameter = wildcardType.isSuper() ? wildcardType.getSuperBound() : wildcardType.getExtendsBound();
addInheritors = wildcardType.isExtends() && classParameter instanceof PsiClassType;
} else if (!matcher.getPrefix().isEmpty()) {
addInheritors = true;
@@ -19,6 +19,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Key;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -66,6 +67,11 @@ public class PsiWildcardType extends PsiType {
public static PsiWildcardType changeBound(@NotNull PsiWildcardType type, @NotNull PsiType newBound) {
LOG.assertTrue(type.getBound() != null);
if (type.myIsExtending) {
if (newBound.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
return createUnbounded(type.myManager);
}
}
return new PsiWildcardType(type.myManager, type.myIsExtending, newBound);
}
@@ -659,7 +659,7 @@ public class TypeConversionUtil {
return left.equals(right) || isAssignable(((PsiCapturedWildcardType)left).getLowerBound(), right, false);
}
if (right instanceof PsiCapturedWildcardType) {
return isAssignable(left, ((PsiCapturedWildcardType)right).getUpperBound(), false);
return isAssignable(left, ((PsiCapturedWildcardType)right).getUpperBound(), allowUncheckedConversion);
}
if (left instanceof PsiWildcardType) {
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import java.util.Iterator;
import java.util.*;
public class Test {
public static void bar() {
@@ -24,4 +24,16 @@ public class Test {
public static Class<? extends Iterator> foo() {
return null;
}
}
}
class Example {
static List<? extends AbstractTreeNode> treeNodes = null;
public static void main(String[] args) {
for (AbstractTreeNode<String> treeNode : treeNodes) {
}
}
}
class AbstractTreeNode<T> {}
@@ -1,6 +1,6 @@
class D<T> {
void foo(D<?> x){
bar<error descr="'bar(D<? extends java.lang.Object>, D<? super java.lang.Object>)' in 'D' cannot be applied to '(D<capture<?>>, D<capture<?>>)'">(x,x)</error>;
bar<error descr="'bar(D<?>, D<? super java.lang.Object>)' in 'D' cannot be applied to '(D<capture<?>>, D<capture<?>>)'">(x,x)</error>;
}
<T> void bar(D<? extends T> x, D<? super T> y){}
}
@@ -87,6 +87,13 @@ public abstract class RefElementImpl extends RefEntityImpl implements RefElement
if (myIsDeleted) return false;
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
public Boolean compute() {
final PsiFile file = myID.getContainingFile();
//no need to check resolve in offline mode
if (ApplicationManager.getApplication().isHeadlessEnvironment()) {
return file != null && file.isPhysical();
}
final PsiElement element = getElement();
return element != null && element.isPhysical();
}
@@ -43,6 +43,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectUtil;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Segment;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
@@ -210,8 +211,8 @@ public class RefManagerImpl extends RefManager {
if (refEntity instanceof RefElement) {
final RefElement refElement = (RefElement)refEntity;
PsiElement psiElement = refElement.getElement();
PsiFile psiFile = psiElement.getContainingFile();
final SmartPsiElementPointer pointer = refElement.getPointer();
PsiFile psiFile = pointer.getContainingFile();
Element fileElement = new Element("file");
Element lineElement = new Element("line");
@@ -220,9 +221,10 @@ public class RefManagerImpl extends RefManager {
fileElement.addContent(virtualFile.getUrl());
if (actualLine == -1) {
final Document document = PsiDocumentManager.getInstance(refElement.getRefManager().getProject()).getDocument(psiFile);
final Document document = PsiDocumentManager.getInstance(pointer.getProject()).getDocument(psiFile);
LOG.assertTrue(document != null);
lineElement.addContent(String.valueOf(document.getLineNumber(psiElement.getTextOffset()) + 1));
final Segment range = pointer.getRange();
lineElement.addContent(String.valueOf(range != null ? (document.getLineNumber(range.getStartOffset()) + 1) : -1));
}
else {
lineElement.addContent(String.valueOf(actualLine));
@@ -614,12 +614,7 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
private void addRootsToWatch() {
final Set<String> rootPaths = getAllRoots(false);
if (rootPaths == null) return;
final Set<LocalFileSystem.WatchRequest> newRootsToWatch = LocalFileSystem.getInstance().addRootsToWatch(rootPaths, true);
//remove old requests after adding new ones, helps avoiding unnecessary synchronizations
LocalFileSystem.getInstance().removeWatchedRoots(myRootsToWatch);
myRootsToWatch = newRootsToWatch;
myRootsToWatch = LocalFileSystem.getInstance().replaceWatchedRoots(myRootsToWatch, rootPaths, true);
}
@Nullable
@@ -1,3 +1,18 @@
/*
* Copyright 2000-2012 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.openapi.roots.impl.libraries;
import com.intellij.openapi.Disposable;
@@ -12,17 +27,15 @@ import com.intellij.openapi.vfs.newvfs.events.*;
import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
/**
* @author ksafonov
*/
public abstract class JarDirectoryWatcher implements Disposable {
private final JarDirectories myJarDirectories;
private MessageBusConnection myBusConnection = null;
private final List<LocalFileSystem.WatchRequest> myWatchRequests = new ArrayList<LocalFileSystem.WatchRequest>();
private Collection<LocalFileSystem.WatchRequest> myWatchRequests = Collections.emptySet();
public JarDirectoryWatcher(JarDirectories jarDirectories) {
myJarDirectories = jarDirectories;
@@ -30,21 +43,39 @@ public abstract class JarDirectoryWatcher implements Disposable {
public void updateWatchedRoots() {
final LocalFileSystem fs = LocalFileSystem.getInstance();
if (!myWatchRequests.isEmpty()) {
fs.removeWatchedRoots(myWatchRequests);
myWatchRequests.clear();
}
if (!myJarDirectories.isEmpty()) {
final Set<String> recursiveRoots = new HashSet<String>();
final Set<String> flatRoots = new HashSet<String>();
final VirtualFileManager fm = VirtualFileManager.getInstance();
for (OrderRootType rootType : myJarDirectories.getRootTypes()) {
for (String url : myJarDirectories.getDirectories(rootType)) {
if (fm.getFileSystem(VirtualFileManager.extractProtocol(url)) instanceof LocalFileSystem) {
final boolean watchRecursively = myJarDirectories.isRecursive(rootType, url);
final LocalFileSystem.WatchRequest request = fs.addRootToWatch(VirtualFileManager.extractPath(url), watchRecursively);
myWatchRequests.add(request);
final String path = VirtualFileManager.extractPath(url);
(watchRecursively ? recursiveRoots : flatRoots).add(path);
}
}
}
if (flatRoots.isEmpty()) {
myWatchRequests = fs.replaceWatchedRoots(myWatchRequests, recursiveRoots, true);
}
else if (recursiveRoots.isEmpty()) {
myWatchRequests = fs.replaceWatchedRoots(myWatchRequests, flatRoots, false);
}
else {
fs.removeWatchedRoots(myWatchRequests);
final int rootsTotal = flatRoots.size() + recursiveRoots.size();
if (rootsTotal > 0) {
myWatchRequests = new ArrayList<LocalFileSystem.WatchRequest>(rootsTotal);
myWatchRequests.addAll(fs.addRootsToWatch(flatRoots, false));
myWatchRequests.addAll(fs.addRootsToWatch(recursiveRoots, true));
}
else {
myWatchRequests = Collections.emptySet();
}
}
if (myBusConnection == null) {
myBusConnection = ApplicationManager.getApplication().getMessageBus().connect();
myBusConnection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener() {
@@ -58,17 +89,18 @@ public abstract class JarDirectoryWatcher implements Disposable {
for (VFileEvent event : events) {
if (event instanceof VFileCopyEvent) {
final VFileCopyEvent copyEvent = (VFileCopyEvent)event;
final VirtualFile file = copyEvent.getFile();
if (isUnderJarDirectory(copyEvent.getNewParent() + "/" + copyEvent.getNewChildName()) ||
isUnderJarDirectory(copyEvent.getFile().getUrl())) {
file != null && isUnderJarDirectory(file.getUrl())) {
changesDetected = true;
break;
}
}
else if (event instanceof VFileMoveEvent) {
final VFileMoveEvent moveEvent = (VFileMoveEvent)event;
final VirtualFile file = moveEvent.getFile();
if (isUnderJarDirectory(file.getUrl()) || isUnderJarDirectory(moveEvent.getOldParent().getUrl() + "/" + file.getName())) {
if (file != null &&
(isUnderJarDirectory(file.getUrl()) || isUnderJarDirectory(moveEvent.getOldParent().getUrl() + "/" + file.getName()))) {
changesDetected = true;
break;
}
@@ -106,11 +138,7 @@ public abstract class JarDirectoryWatcher implements Disposable {
}
}
else {
final MessageBusConnection connection = myBusConnection;
if (connection != null) {
myBusConnection = null;
connection.disconnect();
}
cleanup();
}
}
@@ -118,13 +146,19 @@ public abstract class JarDirectoryWatcher implements Disposable {
@Override
public void dispose() {
cleanup();
}
private void cleanup() {
if (!myWatchRequests.isEmpty()) {
LocalFileSystem.getInstance().removeWatchedRoots(myWatchRequests);
myWatchRequests.clear();
myWatchRequests = Collections.emptySet();
}
if (myBusConnection != null) {
myBusConnection.disconnect();
final MessageBusConnection connection = myBusConnection;
if (connection != null) {
myBusConnection = null;
connection.disconnect();
}
}
}
@@ -25,8 +25,11 @@ import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import static java.util.Collections.singleton;
public abstract class LocalFileSystem extends NewVirtualFileSystem {
@NonNls public static final String PROTOCOL = "file";
@NonNls public static final String PROTOCOL_PREFIX = PROTOCOL + "://";
@@ -125,14 +128,34 @@ public abstract class LocalFileSystem extends NewVirtualFileSystem {
}
@Nullable
public abstract WatchRequest addRootToWatch(@NotNull final String rootPath, final boolean toWatchRecursively);
public WatchRequest addRootToWatch(@NotNull final String rootPath, final boolean watchRecursively) {
final Set<WatchRequest> result = addRootsToWatch(singleton(rootPath), watchRecursively);
return result.size() == 1 ? result.iterator().next() : null;
}
@NotNull
public abstract Set<WatchRequest> addRootsToWatch(@NotNull final Collection<String> rootPaths, final boolean toWatchRecursively);
public abstract Set<WatchRequest> addRootsToWatch(@NotNull final Collection<String> rootPaths, final boolean watchRecursively);
public abstract void removeWatchedRoots(@NotNull final Collection<WatchRequest> rootsToWatch);
public void removeWatchedRoot(@Nullable final WatchRequest watchRequest) {
if (watchRequest != null) {
removeWatchedRoots(singleton(watchRequest));
}
}
public abstract void removeWatchedRoot(@NotNull final WatchRequest watchRequest);
public abstract void removeWatchedRoots(@NotNull final Collection<WatchRequest> watchRequests);
@Nullable
public WatchRequest replaceWatchedRoot(@Nullable final WatchRequest watchRequest,
@NotNull final String rootPath,
final boolean watchRecursively) {
final Set<WatchRequest> requests = watchRequest != null ? singleton(watchRequest) : Collections.<WatchRequest>emptySet();
final Set<WatchRequest> result = replaceWatchedRoots(requests, singleton(rootPath), watchRecursively);
return result.size() == 1 ? result.iterator().next() : null;
}
public abstract Set<WatchRequest> replaceWatchedRoots(@NotNull final Collection<WatchRequest> watchRequests,
@NotNull final Collection<String> rootPaths,
final boolean watchRecursively);
public abstract void registerAuxiliaryFileOperationsHandler(@NotNull LocalFileOperationsHandler handler);
@@ -15,12 +15,11 @@
*/
package com.intellij.openapi.vfs.impl.local;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.io.FileAttributes;
import com.intellij.openapi.util.io.FileSystemUtil;
import com.intellij.openapi.util.io.FileUtil;
@@ -114,6 +113,12 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
public void disposeComponent() {
}
@Override
@NotNull
public String getComponentName() {
return "LocalFileSystem";
}
@TestOnly
public void cleanupForNextTest(Set<VirtualFile> survivors) throws IOException {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@@ -231,31 +236,29 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
private void setUpFileWatcher() {
final Application application = ApplicationManager.getApplication();
if (application.isDisposeInProgress() || !myWatcher.isOperational()) return;
if (application.isDisposeInProgress()) return;
final AccessToken token = application.acquireReadActionLock();
try {
synchronized (myLock) {
final WatchRequestImpl[] watchRequests = normalizeRootsForRefresh();
final List<String> myRecursiveRoots = new ArrayList<String>();
final List<String> myFlatRoots = new ArrayList<String>();
if (myWatcher.isOperational()) {
application.runReadAction(new Runnable() {
@Override
public void run() {
synchronized (myLock) {
final WatchRequestImpl[] watchRequests = normalizeRootsForRefresh();
List<String> myRecursiveRoots = new ArrayList<String>();
List<String> myFlatRoots = new ArrayList<String>();
for (WatchRequestImpl root : watchRequests) {
if (root.isToWatchRecursively()) {
myRecursiveRoots.add(root.myFSRootPath);
}
else {
myFlatRoots.add(root.myFSRootPath);
}
}
myWatcher.setWatchRoots(myRecursiveRoots, myFlatRoots);
for (WatchRequestImpl watchRequest : watchRequests) {
if (watchRequest.isToWatchRecursively()) {
myRecursiveRoots.add(watchRequest.myFSRootPath);
}
else {
myFlatRoots.add(watchRequest.myFSRootPath);
}
}
});
myWatcher.setWatchRoots(myRecursiveRoots, myFlatRoots);
}
}
finally {
token.finish();
}
}
@@ -280,48 +283,6 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
}
}
@Override
@NotNull
public String getComponentName() {
return "LocalFileSystem";
}
@Override
public WatchRequest addRootToWatch(@NotNull final String rootPath, final boolean toWatchRecursively) {
if (rootPath.length() == 0 || !myWatcher.isOperational()) return null;
Application app = ApplicationManager.getApplication();
return app.runReadAction(new Computable<WatchRequest>() {
@Override
public WatchRequest compute() {
synchronized (myLock) {
final WatchRequestImpl result = new WatchRequestImpl(rootPath, toWatchRecursively);
boolean alreadyWatched = isAlreadyWatched(result);
if (!alreadyWatched) {
final VirtualFile existingFile = findFileByPathIfCached(rootPath);
if (existingFile != null) {
final ModalityState modalityState = ModalityState.defaultModalityState();
RefreshQueue.getInstance().refresh(true, toWatchRecursively, null, modalityState, existingFile);
if (existingFile.isDirectory() && !toWatchRecursively && existingFile instanceof NewVirtualFile) {
for (VirtualFile child : ((NewVirtualFile)existingFile).getCachedChildren()) {
RefreshQueue.getInstance().refresh(true, false, null, modalityState, child);
}
}
}
}
myRootsToWatch.add(result);
if (alreadyWatched) {
result.myDominated = true;
return result;
}
myCachedNormalizedRequests = null;
setUpFileWatcher();
return result;
}
}
});
}
private boolean isAlreadyWatched(final WatchRequestImpl request) {
for (final WatchRequestImpl current : normalizeRootsForRefresh()) {
if (dominates(current, request)) return true;
@@ -339,74 +300,114 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
@Override
@NotNull
public Set<WatchRequest> addRootsToWatch(@NotNull final Collection<String> rootPaths, final boolean toWatchRecursively) {
if (!myWatcher.isOperational()) return Collections.emptySet();
public Set<WatchRequest> addRootsToWatch(@NotNull final Collection<String> rootPaths, final boolean watchRecursively) {
if (rootPaths.isEmpty() || !myWatcher.isOperational()) {
return Collections.emptySet();
}
else {
return replaceWatchedRoots(Collections.<WatchRequest>emptySet(), rootPaths, watchRecursively);
}
}
final Set<WatchRequest> result = new HashSet<WatchRequest>();
final Set<VirtualFile> filesToSynchronize = new HashSet<VirtualFile>();
@Override
public void removeWatchedRoots(@NotNull final Collection<WatchRequest> watchRequests) {
if (watchRequests.isEmpty()) return;
Application application = ApplicationManager.getApplication();
application.runReadAction(new Runnable() {
public void run() {
synchronized (myLock) {
for (String rootPath : rootPaths) {
LOG.assertTrue(rootPath != null);
if (rootPath.length() > 0) {
final WatchRequestImpl request = new WatchRequestImpl(rootPath, toWatchRecursively);
final VirtualFile existingFile = findFileByPathIfCached(rootPath);
if (existingFile != null) {
if (!isAlreadyWatched(request)) {
filesToSynchronize.add(existingFile);
}
}
result.add(request);
myRootsToWatch.add(request); //add in any case, safe to add inplace without copying myRootsToWatch before the loop
}
}
final AccessToken token = ApplicationManager.getApplication().acquireReadActionLock();
try {
synchronized (myLock) {
final boolean update = doRemoveWatchedRoots(watchRequests);
if (update) {
myCachedNormalizedRequests = null;
setUpFileWatcher();
}
}
});
}
finally {
token.finish();
}
}
if (!application.isUnitTestMode() && !filesToSynchronize.isEmpty()) {
for (VirtualFile file : filesToSynchronize) {
if (file instanceof NewVirtualFile && file.getFileSystem() instanceof LocalFileSystem) {
((NewVirtualFile)file).markDirtyRecursively();
@Override
public Set<WatchRequest> replaceWatchedRoots(@NotNull final Collection<WatchRequest> watchRequests,
@NotNull final Collection<String> rootPaths,
final boolean watchRecursively) {
if (rootPaths.isEmpty() || !myWatcher.isOperational()) {
removeWatchedRoots(watchRequests);
return Collections.emptySet();
}
final Set<WatchRequest> result = new HashSet<WatchRequest>();
final Set<VirtualFile> filesToSync = new HashSet<VirtualFile>();
final AccessToken token = ApplicationManager.getApplication().acquireReadActionLock();
try {
synchronized (myLock) {
final boolean update = doAddRootsToWatch(rootPaths, watchRecursively, result, filesToSync) ||
doRemoveWatchedRoots(watchRequests);
if (update) {
myCachedNormalizedRequests = null;
setUpFileWatcher();
}
}
refreshFiles(filesToSynchronize, true, toWatchRecursively, null);
}
finally {
token.finish();
}
syncFiles(filesToSync, watchRecursively);
return result;
}
@Override
public void removeWatchedRoot(@NotNull final WatchRequest watchRequest) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
synchronized (myLock) {
if (myRootsToWatch.remove((WatchRequestImpl)watchRequest) && !((WatchRequestImpl)watchRequest).myDominated) {
myCachedNormalizedRequests = null;
setUpFileWatcher();
private boolean doAddRootsToWatch(@NotNull final Collection<String> roots,
final boolean recursively,
@NotNull final Set<WatchRequest> results,
@NotNull final Set<VirtualFile> filesToSync) {
boolean update = false;
for (String root : roots) {
final WatchRequestImpl result = new WatchRequestImpl(root, recursively);
final boolean alreadyWatched = isAlreadyWatched(result);
if (!alreadyWatched) {
final VirtualFile existingFile = findFileByPathIfCached(root);
if (existingFile != null) {
if (existingFile.isDirectory() && !recursively && existingFile instanceof NewVirtualFile) {
filesToSync.addAll(((NewVirtualFile)existingFile).getCachedChildren());
}
}
}
});
result.myDominated = alreadyWatched;
myRootsToWatch.add(result);
results.add(result);
update |= !alreadyWatched;
}
return update;
}
@Override
public void removeWatchedRoots(@NotNull final Collection<WatchRequest> rootsToWatch) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
synchronized (myLock) {
if (myRootsToWatch.removeAll(rootsToWatch)) {
myCachedNormalizedRequests = null;
setUpFileWatcher();
}
}
private void syncFiles(@NotNull final Set<VirtualFile> filesToSync, final boolean watchRecursively) {
if (filesToSync.isEmpty() || ApplicationManager.getApplication().isUnitTestMode()) return;
for (VirtualFile file : filesToSync) {
if (file instanceof NewVirtualFile && file.getFileSystem() instanceof LocalFileSystem) {
((NewVirtualFile)file).markDirtyRecursively();
}
});
}
refreshFiles(filesToSync, true, watchRecursively, null);
}
private boolean doRemoveWatchedRoots(@NotNull final Collection<WatchRequest> watchRequests) {
boolean update = false;
for (WatchRequest watchRequest : watchRequests) {
final boolean wasWatched = myRootsToWatch.remove((WatchRequestImpl)watchRequest) && !((WatchRequestImpl)watchRequest).myDominated;
update |= wasWatched;
}
return update;
}
@Override
@@ -181,24 +181,19 @@ public class Win32LocalFileSystem extends LocalFileSystemBase {
}
}
@Override
public WatchRequest addRootToWatch(@NotNull String rootPath, boolean toWatchRecursively) {
throw new UnsupportedOperationException();
}
@NotNull
@Override
public Set<WatchRequest> addRootsToWatch(@NotNull Collection<String> rootPaths, boolean toWatchRecursively) {
public Set<WatchRequest> addRootsToWatch(@NotNull Collection<String> rootPaths, boolean watchRecursively) {
throw new UnsupportedOperationException();
}
@Override
public void removeWatchedRoots(@NotNull Collection<WatchRequest> rootsToWatch) {
public void removeWatchedRoots(@NotNull Collection<WatchRequest> watchRequests) {
throw new UnsupportedOperationException();
}
@Override
public void removeWatchedRoot(@NotNull WatchRequest watchRequest) {
public Set<WatchRequest> replaceWatchedRoots(@NotNull Collection<WatchRequest> watchRequests, @NotNull Collection<String> rootPaths, boolean watchRecursively) {
throw new UnsupportedOperationException();
}
@@ -81,24 +81,20 @@ public class MockLocalFileSystem extends LocalFileSystem {
public void refreshFiles(@NotNull Iterable<VirtualFile> files, boolean async, boolean recursive, @Nullable Runnable onFinish) {
}
@Override
@Nullable
public WatchRequest addRootToWatch(@NotNull final String rootPath, final boolean toWatchRecursively) {
throw new UnsupportedOperationException("'addRootToWatch' not implemented in " + getClass().getName());
}
@Override
@NotNull
public Set<WatchRequest> addRootsToWatch(@NotNull final Collection<String> rootPaths, final boolean toWatchRecursively) {
throw new UnsupportedOperationException("'addRootsToWatch' not implemented in " + getClass().getName());
public Set<WatchRequest> addRootsToWatch(@NotNull final Collection<String> rootPaths, final boolean watchRecursively) {
throw new UnsupportedOperationException("Not implemented in " + getClass().getName());
}
@Override
public void removeWatchedRoots(@NotNull final Collection<WatchRequest> rootsToWatch) {
throw new UnsupportedOperationException("Not implemented in " + getClass().getName());
}
@Override
public void removeWatchedRoot(@NotNull final WatchRequest watchRequest) {
public Set<WatchRequest> replaceWatchedRoots(@NotNull Collection<WatchRequest> watchRequests, @NotNull Collection<String> rootPaths, boolean watchRecursively) {
throw new UnsupportedOperationException("Not implemented in " + getClass().getName());
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -19,10 +19,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.VcsDirectoryMapping;
import com.intellij.openapi.vfs.LocalFileSystem;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
* @author irengrig
@@ -51,17 +48,25 @@ public class FileWatchRequestModifier implements Runnable {
final List<VcsDirectoryMapping> deleted = new LinkedList<VcsDirectoryMapping>(myDirectoryMappingWatches.keySet());
deleted.removeAll(copy);
final Map<String, VcsDirectoryMapping> toAdd = new HashMap<String, VcsDirectoryMapping>();
for (VcsDirectoryMapping mapping : added) {
if (mapping.isDefaultMapping()) continue;
final LocalFileSystem.WatchRequest watchRequest = myLfs.addRootToWatch(mapping.getDirectory(), true);
myDirectoryMappingWatches.put(mapping, watchRequest);
if (!mapping.isDefaultMapping()) {
toAdd.put(mapping.getDirectory(), mapping);
}
}
final Collection<LocalFileSystem.WatchRequest> toRemove = new ArrayList<LocalFileSystem.WatchRequest>();
for (VcsDirectoryMapping mapping : deleted) {
if (mapping.isDefaultMapping()) continue;
final LocalFileSystem.WatchRequest removed = myDirectoryMappingWatches.remove(mapping);
if (removed != null) {
myLfs.removeWatchedRoot(removed);
toRemove.add(removed);
}
}
final Set<LocalFileSystem.WatchRequest> requests = myLfs.replaceWatchedRoots(toRemove, toAdd.keySet(), true);
for (LocalFileSystem.WatchRequest request : requests) {
myDirectoryMappingWatches.put(toAdd.get(request.getRootPath()), request);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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,6 +17,7 @@ package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.javaee.ExternalResourceManager;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -31,6 +32,7 @@ import com.intellij.openapi.roots.WatchedRootsProvider;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
@@ -166,26 +168,23 @@ public class FetchExtResourceAction extends BaseExtResourceAction implements Wat
});
}
private void fetchDtd(final Project project, final String dtdUrl, final String url, final ProgressIndicator indicator)
throws IOException {
private void fetchDtd(final Project project, final String dtdUrl, final String url, final ProgressIndicator indicator) throws IOException {
final String extResourcesPath = getExternalResourcesPath();
final File extResources = new File(extResourcesPath);
final boolean alreadyExists = extResources.exists();
extResources.mkdirs();
LOG.assertTrue(extResources.exists());
LOG.assertTrue(extResources.mkdirs() || extResources.exists(), extResources);
final PsiManager psiManager = PsiManager.getInstance(project);
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
public void run() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(
extResources.getAbsolutePath().replace(File.separatorChar, '/'));
LOG.assertTrue(vFile != null);
if (!alreadyExists) LocalFileSystem.getInstance().addRootToWatch(vFile.getPath(), true);
}
});
final AccessToken token = ApplicationManager.getApplication().acquireWriteActionLock(FetchExtResourceAction.class);
try {
final String path = FileUtil.toSystemIndependentName(extResources.getAbsolutePath());
final VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(path);
LOG.assertTrue(vFile != null, path);
}
finally {
token.finish();
}
}
}, indicator.getModalityState());