blob: 29b4fe8e1fe594139fa9db157b56e1378d231320 [file] [log] [blame]
/*
* Copyright 2000-2010 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.vcs.changes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vcs.FileStatusManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiFilter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Konstantin Bulenkov
*/
public class PsiChangeTracker {
private PsiChangeTracker() {
}
public static <T extends PsiElement> Map<T, FileStatus> getElementsChanged(PsiElement file,
PsiElement oldFile,
final PsiFilter<T> filter) {
final HashMap<T, FileStatus> result = new HashMap<T, FileStatus>();
final List<T> oldElements = new ArrayList<T>();
final List<T> elements = new ArrayList<T>();
if (file == null) {
oldFile.accept(filter.createVisitor(oldElements));
calculateStatuses(elements, oldElements, result, filter);
return result;
}
final Project project = file.getProject();
file.accept(filter.createVisitor(elements));
final VirtualFile vf = file.getContainingFile().getVirtualFile();
FileStatus status = vf == null ? null : FileStatusManager.getInstance(project).getStatus(vf);
if (status == null && oldFile == null) {
status = FileStatus.ADDED;
}
if (status == FileStatus.ADDED ||
status == FileStatus.DELETED ||
status == FileStatus.DELETED_FROM_FS ||
status == FileStatus.UNKNOWN) {
for (T element : elements) {
result.put(element, status);
}
return result;
}
if (oldFile == null) return result;
oldFile.accept(filter.createVisitor(oldElements));
calculateStatuses(elements, oldElements, result, filter);
return result;
}
private static <T extends PsiElement> Map<T, FileStatus> calculateStatuses(List<T> elements,
List<T> oldElements,
Map<T, FileStatus> result, PsiFilter<T> filter) {
for (T element : elements) {
T e = null;
for (T oldElement : oldElements) {
if (filter.areEquivalent(element, oldElement)) {
e = oldElement;
break;
}
}
if (e != null) {
oldElements.remove(e);
if (!element.getText().equals(e.getText())) {
result.put(element, FileStatus.MODIFIED);
}
}
else {
result.put(element, FileStatus.ADDED);
}
}
for (T oldElement : oldElements) {
result.put(oldElement, FileStatus.DELETED);
}
return result;
}
}