mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git.labs.intellij.net:idea/community
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
-68
@@ -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();
|
||||
}
|
||||
}
|
||||
+206
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -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)) {
|
||||
|
||||
+14
-14
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user