Bug 573521 - Merge remote-tracking branch 'origin/master' into BETA_JAVA17
Change-Id: Ieaf05de3b9295ccf28011824319776e0d141e036
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DebugHoverTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DebugHoverTests.java
index 89d20be..f21e89c 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DebugHoverTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DebugHoverTests.java
@@ -912,6 +912,48 @@
}
}
+ public void testBug574969_onChainHover_preserveEditorSelection() throws Exception {
+ sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class));
+
+ final String typeName = "Bug572629";
+ final String expectedMethod = "main";
+ final int frameNumber = 1;
+ final int bpLine = 64;
+
+ IJavaBreakpoint bp = createLineBreakpoint(bpLine, "", typeName + ".java", typeName);
+ bp.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
+ IFile file = (IFile) bp.getMarker().getResource();
+ assertEquals(typeName + ".java", file.getName());
+
+ IJavaThread thread = null;
+ try {
+ thread = launchToBreakpoint(typeName);
+ CompilationUnitEditor part = openEditorAndValidateStack(expectedMethod, frameNumber, file, thread);
+
+ sync(() -> part.selectAndReveal(part.getViewer().getDocument().get().lastIndexOf("local.names"), "local.names".length()));
+
+ JavaDebugHover hover = new JavaDebugHover();
+ hover.setEditor(part);
+
+ int offset = part.getViewer().getDocument().get().lastIndexOf("local.names.length") + "local.names.".length();
+ IRegion region = new Region(offset, "length".length());
+ IVariable info = (IVariable) sync(() -> hover.getHoverInfo2(part.getViewer(), region));
+
+ assertNotNull(info);
+ assertEquals("local.names.length", info.getName());
+ assertEquals("1", info.getValue().getValueString());
+
+ ITextSelection selection = sync(() -> {
+ processUiEvents(100);
+ return (ITextSelection) part.getSelectionProvider().getSelection();
+ });
+ assertEquals(selection.getText(), "local.names");
+ } finally {
+ terminateAndRemove(thread);
+ removeAllBreakpoints();
+ }
+ }
+
private CompilationUnitEditor openEditorAndValidateStack(final String expectedMethod, final int expectedFramesNumber, IFile file, IJavaThread thread) throws Exception, DebugException {
// Let now all pending jobs proceed, ignore console jobs
sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class));
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugHover.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugHover.java
index 4076ce1..32ccf16 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugHover.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugHover.java
@@ -566,7 +566,7 @@
public void run() throws DebugException {
IAstEvaluationEngine engine = JDIDebugPlugin.getDefault().getEvaluationEngine(project, (IJavaDebugTarget) frame.getDebugTarget());
- engine.evaluate(snippet, frame, this, DebugEvent.EVALUATION, false);
+ engine.evaluate(snippet, frame, this, DebugEvent.EVALUATION_IMPLICIT, false);
}
public Optional<IEvaluationResult> getResult() {
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/DefaultProjectClasspathEntry.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/DefaultProjectClasspathEntry.java
index d2b45ab..8002e80 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/DefaultProjectClasspathEntry.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/DefaultProjectClasspathEntry.java
@@ -15,8 +15,10 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
@@ -199,6 +201,11 @@
* if unable to expand the classpath
*/
public static void expandProject(IClasspathEntry projectEntry, List<Object> expandedPath, List<IClasspathEntry> expanding, boolean excludeTestCode, boolean exportedEntriesOnly, IJavaProject rootProject, boolean isModularJVM) throws CoreException {
+ final Set<Object> visitedEntries = new HashSet<>();
+ expandProjectInternal(projectEntry, expandedPath, visitedEntries, expanding, excludeTestCode, exportedEntriesOnly, rootProject, isModularJVM);
+ }
+
+ public static void expandProjectInternal(IClasspathEntry projectEntry, List<Object> expandedPath, Set<Object> visitedEntries, List<IClasspathEntry> expanding, boolean excludeTestCode, boolean exportedEntriesOnly, IJavaProject rootProject, boolean isModularJVM) throws CoreException {
expanding.add(projectEntry);
// 1. Get the raw classpath
// 2. Replace source folder entries with a project entry
@@ -250,7 +257,7 @@
switch (entry.getEntryKind()) {
case IClasspathEntry.CPE_PROJECT:
if (!expanding.contains(entry)) {
- expandProject(entry, expandedPath, expanding, excludeTestCode, exportedEntriesOnly, rootProject, isModularJVM);
+ expandProjectInternal(entry, expandedPath, visitedEntries, expanding, excludeTestCode, exportedEntriesOnly, rootProject, isModularJVM);
}
break;
case IClasspathEntry.CPE_CONTAINER:
@@ -338,17 +345,20 @@
if (!expandedPath.contains(entry)) {
// resolve project relative paths - @see bug 57732 & bug 248466
if (entry.getEntryKind() != IClasspathEntry.CPE_SOURCE) {
- IPackageFragmentRoot[] roots = project.findPackageFragmentRoots(entry);
- for (int i = 0; i < roots.length; i++) {
- IPackageFragmentRoot root = roots[i];
- r = JavaRuntime.newArchiveRuntimeClasspathEntry(root.getPath(), entry.getSourceAttachmentPath(), entry.getSourceAttachmentRootPath(), entry.getAccessRules(), entry.getExtraAttributes(), entry.isExported());
- if (isModularJVM) {
- adjustClasspathProperty(r, entry);
- }
- r.setSourceAttachmentPath(entry.getSourceAttachmentPath());
- r.setSourceAttachmentRootPath(entry.getSourceAttachmentRootPath());
- if (!expandedPath.contains(r)) {
- expandedPath.add(r);
+ if (!visitedEntries.contains(entry)) {
+ visitedEntries.add(entry);
+ IPackageFragmentRoot[] roots = project.findPackageFragmentRoots(entry);
+ for (int i = 0; i < roots.length; i++) {
+ IPackageFragmentRoot root = roots[i];
+ r = JavaRuntime.newArchiveRuntimeClasspathEntry(root.getPath(), entry.getSourceAttachmentPath(), entry.getSourceAttachmentRootPath(), entry.getAccessRules(), entry.getExtraAttributes(), entry.isExported());
+ if (isModularJVM) {
+ adjustClasspathProperty(r, entry);
+ }
+ r.setSourceAttachmentPath(entry.getSourceAttachmentPath());
+ r.setSourceAttachmentRootPath(entry.getSourceAttachmentRootPath());
+ if (!expandedPath.contains(r)) {
+ expandedPath.add(r);
+ }
}
}
} else {
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/JavaRuntime.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/JavaRuntime.java
index 6caecc9..b9f2d8a 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/JavaRuntime.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/JavaRuntime.java
@@ -1663,41 +1663,59 @@
* @since 2.0
*/
public static IRuntimeClasspathEntry[] resolveRuntimeClasspath(IRuntimeClasspathEntry[] entries, ILaunchConfiguration configuration) throws CoreException {
- if (isModularConfiguration(configuration)) {
- IRuntimeClasspathEntry[] entries1 = getClasspathProvider(configuration).resolveClasspath(entries, configuration);
- ArrayList<IRuntimeClasspathEntry> entries2 = new ArrayList<>(entries1.length);
+ if (!isModularConfiguration(configuration)) {
+ return getClasspathProvider(configuration).resolveClasspath(entries, configuration);
+ }
+ IRuntimeClasspathEntry[] entries1 = getClasspathProvider(configuration).resolveClasspath(entries, configuration);
+ List<IRuntimeClasspathEntry> entries2 = new ArrayList<>(entries1.length);
+ IJavaProject project;
+ try {
+ project = JavaRuntime.getJavaProject(configuration);
+ } catch (CoreException e) {
+ project = null;
+ }
+ if (project == null) {
+ entries2.addAll(Arrays.asList(entries1));
+ } else {
+ // Add all entries except the one from JRE itself
+ IPackageFragmentRoot jreContainer = findJreContainer(project);
+ IPath canonicalJrePath = jreContainer != null ? JavaProject.canonicalizedPath(jreContainer.getPath()) : null;
+
for (IRuntimeClasspathEntry entry : entries1) {
switch (entry.getClasspathEntry().getEntryKind()) {
case IClasspathEntry.CPE_LIBRARY:
- try {
- IJavaProject project = JavaRuntime.getJavaProject(configuration);
- if (project == null) {
- entries2.add(entry);
- }
- else {
- IPackageFragmentRoot root = project.findPackageFragmentRoot(entry.getPath());
- if (root == null && !entry.getPath().lastSegment().contains("jrt-fs.jar")) { //$NON-NLS-1$
- entries2.add(entry);
- } else if (root != null && !root.getRawClasspathEntry().getPath().segment(0).contains("JRE_CONTAINER")) { //$NON-NLS-1$
- entries2.add(entry);
- }
- }
- }
- catch (CoreException ex) {
- // Not a java project
- if (!entry.getPath().lastSegment().contains("jrt-fs.jar")) { //$NON-NLS-1$
- entries2.add(entry);
- }
+ if (!entry.getPath().lastSegment().contains("jrt-fs.jar") //$NON-NLS-1$
+ && (canonicalJrePath == null || !canonicalJrePath.equals(JavaProject.canonicalizedPath(entry.getPath())))) {
+ entries2.add(entry);
}
break;
default:
entries2.add(entry);
-
}
}
- return entries2.toArray(new IRuntimeClasspathEntry[entries2.size()]);
}
- return getClasspathProvider(configuration).resolveClasspath(entries, configuration);
+ return entries2.toArray(new IRuntimeClasspathEntry[entries2.size()]);
+ }
+
+ /**
+ * Find the {@link IPackageFragmentRoot} of the JRE container for the given project, if it exists.
+ *
+ * @param project
+ * Java project
+ * @return the {@link IPackageFragmentRoot} for the JRE container or null if no JRE container is on the classpath
+ * @throws JavaModelException
+ */
+ private static IPackageFragmentRoot findJreContainer(IJavaProject project) throws JavaModelException {
+ IPackageFragmentRoot jreContainer = null;
+
+ IPackageFragmentRoot[] allPackageFragmentRoots = project.getAllPackageFragmentRoots();
+ for (IPackageFragmentRoot packageFragmentRoot : allPackageFragmentRoots) {
+ if (packageFragmentRoot.getRawClasspathEntry().getPath().segment(0).contains("JRE_CONTAINER")) { //$NON-NLS-1$
+ jreContainer = packageFragmentRoot;
+ break;
+ }
+ }
+ return jreContainer;
}
/**