assertion for EA-52184 - IAE: FileTypeManagerImpl.isFileIgnored

This commit is contained in:
Alexey Kudravtsev
2014-01-23 14:13:28 +04:00
parent ce5e01266b
commit 3c9a856960
4 changed files with 191 additions and 20 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 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,6 +15,7 @@
*/
package com.intellij.openapi.vfs;
import com.intellij.openapi.vfs.newvfs.events.VFilePropertyChangeEvent;
import org.jetbrains.annotations.NotNull;
/**
@@ -33,6 +34,7 @@ public class VirtualFilePropertyEvent extends VirtualFileEvent {
myPropertyName = propertyName;
myOldValue = oldValue;
myNewValue = newValue;
VFilePropertyChangeEvent.checkPropertyValuesCorrect(requestor, propertyName, oldValue, newValue);
}
/**
@@ -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.
@@ -19,8 +19,10 @@
*/
package com.intellij.openapi.vfs.newvfs.events;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileSystem;
import com.intellij.util.FileContentUtilCore;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -42,6 +44,32 @@ public class VFilePropertyChangeEvent extends VFileEvent {
myPropertyName = propertyName;
myOldValue = oldValue;
myNewValue = newValue;
checkPropertyValuesCorrect(requestor, propertyName, oldValue, newValue);
}
public static void checkPropertyValuesCorrect(Object requestor, @NotNull String propertyName, Object oldValue, Object newValue) {
if (Comparing.equal(oldValue, newValue) && FileContentUtilCore.FORCE_RELOAD_REQUESTOR != requestor) {
throw new IllegalArgumentException("Values must be different, got the same: " + oldValue);
}
if (VirtualFile.PROP_NAME.equals(propertyName)) {
if (oldValue == null) throw new IllegalArgumentException("oldName must not be null");
if (newValue == null) throw new IllegalArgumentException("newName must not be null");
}
else if (VirtualFile.PROP_ENCODING.equals(propertyName)) {
if (oldValue == null) throw new IllegalArgumentException("oldCharset must not be null");
}
else if (VirtualFile.PROP_WRITABLE.equals(propertyName)) {
if (!(oldValue instanceof Boolean)) throw new IllegalArgumentException("oldWriteable must be boolean, got "+oldValue);
if (!(newValue instanceof Boolean)) throw new IllegalArgumentException("newWriteable must be boolean, got "+newValue);
}
else if (VirtualFile.PROP_HIDDEN.equals(propertyName)) {
if (!(oldValue instanceof Boolean)) throw new IllegalArgumentException("oldHidden must be boolean, got "+oldValue);
if (!(newValue instanceof Boolean)) throw new IllegalArgumentException("newHidden must be boolean, got "+newValue);
}
else if (VirtualFile.PROP_SYMLINK_TARGET.equals(propertyName)) {
if (oldValue != null && !(oldValue instanceof String)) throw new IllegalArgumentException("oldSymTarget must be String, got "+oldValue);
if (newValue != null && !(newValue instanceof String)) throw new IllegalArgumentException("newSymTarget must be String, got "+newValue);
}
}
@NotNull
@@ -34,6 +34,7 @@ import com.intellij.openapi.vfs.newvfs.impl.VirtualFileSystemEntry;
import com.intellij.util.*;
import com.intellij.util.containers.ConcurrentIntObjectMap;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.EmptyIntHashSet;
import com.intellij.util.containers.StripedLockIntObjectConcurrentHashMap;
import com.intellij.util.io.ReplicatorInputStream;
import com.intellij.util.io.URLUtil;
@@ -361,7 +362,10 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
@Override
public void setWritable(@NotNull final VirtualFile file, final boolean writableFlag) throws IOException {
getDelegate(file).setWritable(file, writableFlag);
processEvent(new VFilePropertyChangeEvent(this, file, VirtualFile.PROP_WRITABLE, isWritable(file), writableFlag, false));
boolean oldWritable = isWritable(file);
if (oldWritable != writableFlag) {
processEvent(new VFilePropertyChangeEvent(this, file, VirtualFile.PROP_WRITABLE, oldWritable, writableFlag, false));
}
}
@Override
@@ -458,7 +462,10 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
@Override
public void renameFile(final Object requestor, @NotNull VirtualFile file, @NotNull String newName) throws IOException {
getDelegate(file).renameFile(requestor, file, newName);
processEvent(new VFilePropertyChangeEvent(requestor, file, VirtualFile.PROP_NAME, file.getName(), newName, false));
String oldName = file.getName();
if (!newName.equals(oldName)) {
processEvent(new VFilePropertyChangeEvent(requestor, file, VirtualFile.PROP_NAME, oldName, newName, false));
}
}
@Override
@@ -695,28 +702,34 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
}
}
ContainerUtil.quickSort(deletionEvents, DEPTH_COMPARATOR);
final TIntHashSet invalidIDs;
if (deletionEvents.isEmpty()) {
invalidIDs = EmptyIntHashSet.INSTANCE;
}
else {
ContainerUtil.quickSort(deletionEvents, DEPTH_COMPARATOR);
final TIntHashSet invalidIDs = new TIntHashSet(deletionEvents.size());
final Set<VirtualFile> dirsToBeDeleted = new THashSet<VirtualFile>(deletionEvents.size());
nextEvent:
for (EventWrapper wrapper : deletionEvents) {
final VirtualFile candidate = wrapper.event.getFile();
VirtualFile parent = candidate;
while (parent != null) {
if (dirsToBeDeleted.contains(parent)) {
invalidIDs.add(wrapper.id);
continue nextEvent;
invalidIDs = new TIntHashSet(deletionEvents.size());
final Set<VirtualFile> dirsToBeDeleted = new THashSet<VirtualFile>(deletionEvents.size());
nextEvent:
for (EventWrapper wrapper : deletionEvents) {
final VirtualFile candidate = wrapper.event.getFile();
VirtualFile parent = candidate;
while (parent != null) {
if (dirsToBeDeleted.contains(parent)) {
invalidIDs.add(wrapper.id);
continue nextEvent;
}
parent = parent.getParent();
}
parent = parent.getParent();
}
if (candidate.isDirectory()) {
dirsToBeDeleted.add(candidate);
if (candidate.isDirectory()) {
dirsToBeDeleted.add(candidate);
}
}
}
final List<VFileEvent> filtered = ContainerUtil.newArrayListWithCapacity(events.size() - invalidIDs.size());
final List<VFileEvent> filtered = new ArrayList<VFileEvent>(events.size() - invalidIDs.size());
for (int i = 0, size = events.size(); i < size; i++) {
final VFileEvent event = events.get(i);
if (event.isValid() && !(event instanceof VFileDeleteEvent && invalidIDs.contains(i))) {
@@ -0,0 +1,128 @@
/*
* 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.
* 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.util.containers;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import gnu.trove.TIntHashSet;
import gnu.trove.TIntIterator;
import gnu.trove.TIntProcedure;
import java.util.NoSuchElementException;
public class EmptyIntHashSet extends TIntHashSet {
public static final TIntHashSet INSTANCE = new EmptyIntHashSet();
public static final TIntIterator EMPTY_INT_ITERATOR = new TIntIterator(INSTANCE) {
@Override
public int next() {
throw new NoSuchElementException();
}
@Override
public boolean hasNext() {
return false;
}
@Override
public void remove() {
throw new NoSuchElementException();
}
};
private EmptyIntHashSet() {
super(0);
}
@Override
public boolean add(int val) {
throw new IncorrectOperationException();
}
@Override
public int[] toArray() {
return ArrayUtil.EMPTY_INT_ARRAY;
}
@Override
public TIntIterator iterator() {
return EMPTY_INT_ITERATOR;
}
@Override
public void clear() {
throw new IncorrectOperationException();
}
@Override
public int hashCode() {
return 0;
}
@Override
public boolean remove(int val) {
throw new IncorrectOperationException();
}
@Override
public boolean containsAll(int[] array) {
return false;
}
@Override
public boolean addAll(int[] array) {
throw new IncorrectOperationException();
}
@Override
public boolean removeAll(int[] array) {
throw new IncorrectOperationException();
}
@Override
public boolean retainAll(int[] array) {
throw new IncorrectOperationException();
}
@Override
public boolean contains(int val) {
return false;
}
@Override
public boolean forEach(TIntProcedure procedure) {
return true;
}
@Override
public boolean isEmpty() {
return true;
}
@Override
public int size() {
return 0;
}
@Override
public void compact() {
throw new IncorrectOperationException();
}
@Override
public String toString() {
return "Empty Int Hash Set";
}
}