Merge branch 'master' of git.labs.intellij.net:idea/community

This commit is contained in:
Irina Chernushina
2009-10-26 10:30:58 +03:00
6 changed files with 258 additions and 100 deletions
@@ -204,7 +204,7 @@ public class AbstractTreeUi {
}
private boolean isNodeActionsPending() {
boolean isNodeActionsPending() {
return !myNodeActions.isEmpty() || !myNodeChildrenActions.isEmpty();
}
@@ -1235,7 +1235,7 @@ public class AbstractTreeUi {
}
public boolean isReady() {
return isIdle() && !hasPendingWork();
return isIdle() && !hasPendingWork() && !isNodeActionsPending();
}
public boolean hasPendingWork() {
@@ -1750,11 +1750,11 @@ public class AbstractTreeUi {
final Object element = getBuilder().getTreeStructureElement((NodeDescriptor)o);
processActions(node, element, myNodeActions);
boolean childrenReady = !isLoadedInBackground(element);
processActions(node, element, myNodeActions, childrenReady ? myNodeChildrenActions : null);
if (childrenReady) {
processActions(node, element, myNodeChildrenActions);
processActions(node, element, myNodeChildrenActions, null);
}
if (!isUpdatingParent(node) && !isWorkerBusy()) {
@@ -1770,11 +1770,16 @@ public class AbstractTreeUi {
}
private void processActions(DefaultMutableTreeNode node, Object element, final Map<Object, List<NodeAction>> nodeActions) {
private void processActions(DefaultMutableTreeNode node, Object element, final Map<Object, List<NodeAction>> nodeActions, @Nullable final Map<Object, List<NodeAction>> secondaryNodeAction) {
final List<NodeAction> actions = nodeActions.get(element);
if (actions != null) {
nodeActions.remove(element);
List<NodeAction> secondary = secondaryNodeAction != null ? secondaryNodeAction.get(element) : null;
for (NodeAction each : actions) {
if (secondary != null && secondary.contains(each)) {
secondary.remove(each);
}
each.onReady(node);
}
}
@@ -2798,17 +2803,29 @@ public class AbstractTreeUi {
}
});
for (final Object toExpand : element) {
_expand(toExpand, new Runnable() {
public void run() {
done.setDone();
}
}, parentsOnly, checkIfInStructure, canSmartExpand);
}
expandNext(element, 0, parentsOnly, checkIfInStructure, canSmartExpand, done);
}
});
}
private void expandNext(final Object[] elements, final int index, final boolean parentsOnly, final boolean checkIfInStricture, final boolean canSmartExpand, final ActionCallback done) {
if (elements.length <= 0) {
done.setDone();
return;
}
if (index >= elements.length) {
return;
}
_expand(elements[index], new Runnable() {
public void run() {
done.setDone();
expandNext(elements, index + 1, parentsOnly, checkIfInStricture, canSmartExpand, done);
}
}, parentsOnly, checkIfInStricture, canSmartExpand);
}
public void collapseChildren(final Object element, @Nullable final Runnable onDone) {
runDone(new Runnable() {
public void run() {
@@ -20,6 +20,7 @@ import com.intellij.execution.PsiLocation;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.testIntegration.TestLocationProvider;
@@ -71,8 +72,10 @@ public class FileUrlProvider implements TestLocationProvider {
lineNumber = 1;
filePath = normalizedPath;
}
//Now we should seach file with most sutable path
final List<VirtualFile> virtualFiles = LocationProviderUtil.findSuitableFilesFor(filePath);
// Now we should search file with most suitable path
// here path may be absolute or relative
final String systemIndependentPath = FileUtil.toSystemIndependentName(filePath);
final List<VirtualFile> virtualFiles = TestsLocationProviderUtil.findSuitableFilesFor(systemIndependentPath, project);
if (virtualFiles.isEmpty()) {
return Collections.emptyList();
}
@@ -1,68 +0,0 @@
/*
* Copyright 2000-2009 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.execution.testframework.sm;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NonNls;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.ex.temp.TempFileSystem;
import com.intellij.openapi.application.ApplicationManager;
import java.util.List;
import java.util.Collections;
/**
* @author Roman Chernyatchik
*/
public class LocationProviderUtil {
@NonNls private static final String PROTOCOL_SEPARATOR = "://";
private LocationProviderUtil() {
}
@Nullable
public static String extractProtocol(@NotNull final String locationUrl) {
final int index = locationUrl.indexOf(PROTOCOL_SEPARATOR);
if (index >= 0) {
return locationUrl.substring(0, index);
}
return null;
}
@Nullable
public static String extractPath(@NotNull final String locationUrl) {
final int index = locationUrl.indexOf(PROTOCOL_SEPARATOR);
if (index >= 0) {
return locationUrl.substring(index + PROTOCOL_SEPARATOR.length());
}
return null;
}
public static List<VirtualFile> findSuitableFilesFor(final String filePath) {
final VirtualFile fileByPath = LocalFileSystem.getInstance().findFileByPath(filePath);
if (fileByPath != null) {
return Collections.singletonList(fileByPath);
}
// if we are in UnitTest mode probably TempFileSystem is used instead of LocaFileSystem
if (ApplicationManager.getApplication().isUnitTestMode()) {
final VirtualFile tempFileByPath = TempFileSystem.getInstance().findFileByPath(filePath);
return Collections.singletonList(tempFileByPath);
}
return Collections.emptyList();
}
}
@@ -0,0 +1,206 @@
/*
* Copyright 2000-2009 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.execution.testframework.sm;
import com.intellij.navigation.ChooseByNameContributor;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.ex.temp.TempFileSystem;
import com.intellij.psi.PsiFile;
import com.intellij.util.text.StringTokenizer;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/**
* @author Roman Chernyatchik
*/
public class TestsLocationProviderUtil {
@NonNls private static final String PROTOCOL_SEPARATOR = "://";
private static final int MIN_PROXIMITY_TRESHOLD = 1;
private TestsLocationProviderUtil() {
}
@Nullable
public static String extractProtocol(@NotNull final String locationUrl) {
final int index = locationUrl.indexOf(PROTOCOL_SEPARATOR);
if (index >= 0) {
return locationUrl.substring(0, index);
}
return null;
}
@Nullable
public static String extractPath(@NotNull final String locationUrl) {
final int index = locationUrl.indexOf(PROTOCOL_SEPARATOR);
if (index >= 0) {
return locationUrl.substring(index + PROTOCOL_SEPARATOR.length());
}
return null;
}
public static List<VirtualFile> findSuitableFilesFor(final String filePath, final Project project) {
final ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex();
// at first let's try to find file as is, by it's real path
// and check that file belongs to current project
// this location provider designed for tests thus we will check only project content
// (we cannot check just sources or tests folders because RM doesn't use it
final VirtualFile file = getByFullPath(filePath);
final boolean inProjectContent = file != null && (index.isInContent(file));
if (inProjectContent) {
return Collections.singletonList(file);
}
//split file by "/" in parts
final LinkedList<String> folders = new LinkedList<String>();
final StringTokenizer st = new StringTokenizer(filePath, "/", false);
String fileName = null;
while (st.hasMoreTokens()) {
final String pathComponent = st.nextToken();
if (st.hasMoreTokens()) {
folders.addFirst(pathComponent);
} else {
// last token
fileName = pathComponent;
}
}
//otherwise let's find all files with the same name and similar relative path
final List<FileInfo> filesInfo = collectCandidates(project, fileName);
if (filesInfo.isEmpty()) {
return Collections.emptyList();
}
// let's iterate relative path components and determine which files are closer to our relative path
for (String folderName : folders) {
for (FileInfo info : filesInfo) {
info.processRelativePathComponent(folderName);
}
}
// let's extract the closest files to relative path. For this we will find max proximity and and
// we also assume that relative files and folders should have at least one common parent folder - just
// to remove false positives on some cases
int maxProximity = 0;
for (FileInfo fileInfo : filesInfo) {
final int proximity = fileInfo.getProximity();
if (proximity > maxProximity) {
maxProximity = proximity;
}
}
if (maxProximity >= MIN_PROXIMITY_TRESHOLD) {
final List<VirtualFile> files = new ArrayList<VirtualFile>();
for (FileInfo info : filesInfo) {
if (info.getProximity() == maxProximity) {
files.add(info.getFile());
}
}
return files;
}
return Collections.emptyList();
}
//private static int compare(final FileInfo info1, final FileInfo info2) {
// final int proximity1 = info1.getProximity();
// final int proximity2 = info2.getProximity();
//
// return proximity2 - proximity1;
//}
private static List<FileInfo> collectCandidates(Project project, String fileName) {
final List<FileInfo> filesInfo = new ArrayList<FileInfo>();
final ChooseByNameContributor[] contributors = Extensions.getExtensions(ChooseByNameContributor.FILE_EP_NAME);
for (ChooseByNameContributor contributor : contributors) {
// let's find files with same name in project and libraries
final NavigationItem[] navigationItems = contributor.getItemsByName(fileName, fileName, project, true);
for (NavigationItem navigationItem : navigationItems) {
if (navigationItem instanceof PsiFile) {
final VirtualFile itemFile = ((PsiFile)navigationItem).getVirtualFile();
assert itemFile != null;
filesInfo.add(new FileInfo(itemFile));
}
}
}
return filesInfo;
}
@Nullable
private static VirtualFile getByFullPath(String filePath) {
final VirtualFile fileByPath = LocalFileSystem.getInstance().findFileByPath(filePath);
if (fileByPath != null) {
return fileByPath;
}
// if we are in UnitTest mode probably TempFileSystem is used instead of LocaFileSystem
if (ApplicationManager.getApplication().isUnitTestMode()) {
final VirtualFile tempFileByPath = TempFileSystem.getInstance().findFileByPath(filePath);
return tempFileByPath;
}
return null;
}
public static class FileInfo {
private final VirtualFile myFile;
private VirtualFile myCurrentFolder;
private int myProximity = 0;
public FileInfo(VirtualFile file) {
myFile = file;
myCurrentFolder = myFile.getParent();
}
public void processRelativePathComponent(final String folderName) {
if (myCurrentFolder == null) {
return;
}
if (!folderName.equals(myCurrentFolder.getName())) {
// if one of path components differs - no sense in checking others
myCurrentFolder = null;
return;
}
// common folder was found, let's increase proximity degree and move to parent folder
myProximity ++;
myCurrentFolder = myCurrentFolder.getParent();
}
public VirtualFile getFile() {
return myFile;
}
public int getProximity() {
return myProximity;
}
}
}
@@ -17,7 +17,7 @@ package com.intellij.execution.testframework.sm.runner;
import com.intellij.execution.Location;
import com.intellij.execution.testframework.*;
import com.intellij.execution.testframework.sm.LocationProviderUtil;
import com.intellij.execution.testframework.sm.TestsLocationProviderUtil;
import com.intellij.execution.testframework.sm.runner.states.*;
import com.intellij.execution.testframework.sm.runner.ui.TestsPresentationUtil;
import com.intellij.execution.testframework.ui.PrintableTestProxy;
@@ -136,8 +136,8 @@ public class SMTestProxy extends CompositePrintable implements PrintableTestProx
return null;
}
final String protocolId = LocationProviderUtil.extractProtocol(myLocationUrl);
final String path = LocationProviderUtil.extractPath(myLocationUrl);
final String protocolId = TestsLocationProviderUtil.extractProtocol(myLocationUrl);
final String path = TestsLocationProviderUtil.extractPath(myLocationUrl);
if (protocolId != null && path != null) {
for (TestLocationProvider provider : Extensions.getExtensions(TestLocationProvider.EP_NAME)) {
@@ -23,39 +23,39 @@ import com.intellij.testFramework.UsefulTestCase;
public class LocationProviderUtilTest extends UsefulTestCase {
public void testExtractProtocol() {
assertEquals(null,
LocationProviderUtil.extractProtocol(""));
TestsLocationProviderUtil.extractProtocol(""));
assertEquals(null,
LocationProviderUtil.extractProtocol("file:/"));
TestsLocationProviderUtil.extractProtocol("file:/"));
assertEquals("file",
LocationProviderUtil.extractProtocol("file://"));
TestsLocationProviderUtil.extractProtocol("file://"));
assertEquals("file",
LocationProviderUtil.extractProtocol("file:///some/path/file.rb:24"));
TestsLocationProviderUtil.extractProtocol("file:///some/path/file.rb:24"));
assertEquals("file",
LocationProviderUtil.extractProtocol("file://./some/path/file.rb:24"));
TestsLocationProviderUtil.extractProtocol("file://./some/path/file.rb:24"));
assertEquals("ruby_qn",
LocationProviderUtil.extractProtocol("ruby_qn://"));
TestsLocationProviderUtil.extractProtocol("ruby_qn://"));
assertEquals("ruby_qn",
LocationProviderUtil.extractProtocol("ruby_qn://A::B.method"));
TestsLocationProviderUtil.extractProtocol("ruby_qn://A::B.method"));
}
public void testExtractPath() {
assertEquals(null,
LocationProviderUtil.extractPath(""));
TestsLocationProviderUtil.extractPath(""));
assertEquals(null,
LocationProviderUtil.extractPath("file:/"));
TestsLocationProviderUtil.extractPath("file:/"));
assertEquals("",
LocationProviderUtil.extractPath("file://"));
TestsLocationProviderUtil.extractPath("file://"));
assertEquals("/some/path/file.rb:24",
LocationProviderUtil.extractPath("file:///some/path/file.rb:24"));
TestsLocationProviderUtil.extractPath("file:///some/path/file.rb:24"));
assertEquals("./some/path/file.rb:24",
LocationProviderUtil.extractPath("file://./some/path/file.rb:24"));
TestsLocationProviderUtil.extractPath("file://./some/path/file.rb:24"));
assertEquals("",
LocationProviderUtil.extractPath("ruby_qn://"));
TestsLocationProviderUtil.extractPath("ruby_qn://"));
assertEquals("A::B.method",
LocationProviderUtil.extractPath("ruby_qn://A::B.method"));
TestsLocationProviderUtil.extractPath("ruby_qn://A::B.method"));
}
}