Merge remote-tracking branch 'origin/master' into BETA_JAVA_12
Change-Id: Ibf50d6bdc251efb9404f80eabfb1bdac6a289452
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/DebugSuite.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/DebugSuite.java
index cd08506..a6f413b 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/DebugSuite.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/DebugSuite.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,6 +10,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Paul Pazderski - Bug 544133: signal end of test runner in any case
*******************************************************************************/
package org.eclipse.jdt.debug.tests;
@@ -31,7 +32,6 @@
*/
protected boolean fTesting = true;
-
/**
* Construct the test suite.
*/
@@ -52,18 +52,21 @@
Runnable r = new Runnable() {
@Override
public void run() {
- for (Enumeration<Test> e= tests(); e.hasMoreElements(); ) {
- if (result.shouldStop() ) {
- break;
+ try {
+ for (Enumeration<Test> e= tests(); e.hasMoreElements(); ) {
+ if (result.shouldStop()) {
+ break;
+ }
+ Test test= e.nextElement();
+ runTest(test, result);
}
- Test test= e.nextElement();
- runTest(test, result);
+ } finally {
+ fTesting = false;
+ display.wake();
}
- fTesting = false;
- display.wake();
}
};
- thread = new Thread(r);
+ thread = new Thread(r, "Test Runner");
thread.start();
} catch (Exception e) {
e.printStackTrace();
@@ -79,6 +82,4 @@
}
}
}
-
}
-
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ManualSuite.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ManualSuite.java
index a74b86e..669014d 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ManualSuite.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ManualSuite.java
@@ -13,25 +13,16 @@
*******************************************************************************/
package org.eclipse.jdt.debug.tests;
-import java.util.Enumeration;
-
import org.eclipse.jdt.debug.tests.core.RemoteJavaApplicationTests;
-import org.eclipse.swt.widgets.Display;
import junit.framework.Test;
-import junit.framework.TestResult;
import junit.framework.TestSuite;
/**
* Tests that are to be run manually by the debug team, in addition to
* automated tests.
*/
-public class ManualSuite extends TestSuite {
-
- /**
- * Flag that indicates test are in progress
- */
- protected boolean fTesting = true;
+public class ManualSuite extends DebugSuite {
/**
* Returns the suite. This is required to
@@ -55,48 +46,5 @@
addTest(new TestSuite(RemoteJavaApplicationTests.class));
}
-
- /**
- * Runs the tests and collects their result in a TestResult.
- * The debug tests cannot be run in the UI thread or the event
- * waiter blocks the UI when a resource changes.
- * @see junit.framework.TestSuite#run(junit.framework.TestResult)
- */
- @Override
- public void run(final TestResult result) {
- final Display display = Display.getCurrent();
- Thread thread = null;
- try {
- Runnable r = new Runnable() {
- @Override
- public void run() {
- for (Enumeration<Test> e= tests(); e.hasMoreElements(); ) {
- if (result.shouldStop() ) {
- break;
- }
- Test test= e.nextElement();
- runTest(test, result);
- }
- fTesting = false;
- display.wake();
- }
- };
- thread = new Thread(r);
- thread.start();
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- while (fTesting) {
- try {
- if (!display.readAndDispatch()) {
- display.sleep();
- }
- } catch (Throwable e) {
- e.printStackTrace();
- }
- }
- }
-
}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/LineTrackerTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/LineTrackerTests.java
index afd3f68..9528825 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/LineTrackerTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/LineTrackerTests.java
@@ -21,16 +21,20 @@
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;
import org.eclipse.debug.ui.console.IConsole;
import org.eclipse.debug.ui.console.IConsoleLineTrackerExtension;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
+import org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint;
+import org.eclipse.jdt.debug.core.JDIDebugModel;
import org.eclipse.jdt.debug.testplugin.ConsoleLineTracker;
import org.eclipse.jdt.debug.tests.AbstractDebugTest;
import org.eclipse.jdt.internal.debug.ui.IJDIPreferencesConstants;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.internal.debug.ui.console.JavaExceptionHyperLink;
import org.eclipse.jdt.internal.debug.ui.console.JavaStackTraceHyperlink;
+import org.eclipse.jdt.internal.debug.ui.propertypages.JavaBreakpointPage;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IRegion;
@@ -182,6 +186,77 @@
}
}
+ public void testJavaExceptionHyperLink() throws Exception {
+ ConsoleLineTracker.setDelegate(this);
+ fTarget = null;
+ IPreferenceStore jdiUIPreferences = JDIDebugUIPlugin.getDefault().getPreferenceStore();
+ boolean suspendOnException = jdiUIPreferences.getBoolean(IJDIPreferencesConstants.PREF_SUSPEND_ON_UNCAUGHT_EXCEPTIONS);
+ jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_SUSPEND_ON_UNCAUGHT_EXCEPTIONS, false);
+ try {
+ fTarget = launchAndTerminate("ThrowsNPE");
+
+ synchronized (fLock) {
+ if (!fStopped) {
+ fLock.wait(30000);
+ }
+ }
+ assertTrue("Never received 'start' notification", fStarted);
+ assertTrue("Never received 'stopped' notification", fStopped);
+ assertTrue("Console should be an IOCosnole", fConsole instanceof IOConsole);
+ IOConsole console = (IOConsole) fConsole;
+ IHyperlink[] hyperlinks = console.getHyperlinks();
+
+ // should be 1 exception hyperlink
+ int total = 0;
+ for (int i = 0; i < hyperlinks.length; i++) {
+ IHyperlink hyperlink = hyperlinks[i];
+ if (hyperlink instanceof JavaExceptionHyperLink) {
+ total++;
+ // should be followed by a stack trace hyperlink
+ assertTrue("Stack trace hyperlink missing", hyperlinks[i + 1] instanceof JavaStackTraceHyperlink);
+ }
+ }
+ assertEquals("Wrong number of exception hyperlinks", 1, total);
+ IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(JDIDebugModel.getPluginIdentifier());
+ IJavaExceptionBreakpoint foundBreakpoint = null;
+ for (int i = 0; i < breakpoints.length; i++) {
+ IBreakpoint breakpoint = breakpoints[i];
+ if (breakpoint instanceof IJavaExceptionBreakpoint) {
+ IJavaExceptionBreakpoint exceptionBreakpoint = (IJavaExceptionBreakpoint) breakpoint;
+ if ("java.lang.NullPointerException".equals(exceptionBreakpoint.getTypeName())) {
+ foundBreakpoint = exceptionBreakpoint;
+ break;
+ }
+ }
+ }
+ assertTrue("NPE breakpoint should not exist yet", foundBreakpoint == null);
+ IJavaExceptionBreakpoint ex = createExceptionBreakpoint("java.lang.NullPointerException", true, false);
+ ex.setEnabled(false);
+ JavaExceptionHyperLink exLink = (JavaExceptionHyperLink) hyperlinks[0];
+ exLink.linkActivated();
+ breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(JDIDebugModel.getPluginIdentifier());
+ foundBreakpoint = null;
+ for (int i = 0; i < breakpoints.length; i++) {
+ IBreakpoint breakpoint = breakpoints[i];
+ if (breakpoint instanceof IJavaExceptionBreakpoint) {
+ IJavaExceptionBreakpoint exceptionBreakpoint = (IJavaExceptionBreakpoint) breakpoint;
+ if ("java.lang.NullPointerException".equals(exceptionBreakpoint.getTypeName())) {
+ foundBreakpoint = exceptionBreakpoint;
+ break;
+ }
+ }
+ }
+ assertTrue("NPE breakpoint not found", foundBreakpoint != null);
+ assertTrue("NPE breakpoint not enabled", foundBreakpoint.isEnabled());
+ assertTrue("NPE breakpoint cancel enablement value not false", foundBreakpoint.getMarker().getAttribute(JavaBreakpointPage.ATTR_ENABLED_SETTING_ON_CANCEL, "").equals("false"));
+ } finally {
+ ConsoleLineTracker.setDelegate(null);
+ jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_SUSPEND_ON_UNCAUGHT_EXCEPTIONS, suspendOnException);
+ terminateAndRemove(fTarget);
+ }
+
+ }
+
/**
* @see org.eclipse.debug.ui.console.IConsoleLineTracker#dispose()
*/
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/console/JavaStackTraceConsoleFactory.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/console/JavaStackTraceConsoleFactory.java
index 3a8e3d6..15aee2a 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/console/JavaStackTraceConsoleFactory.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/console/JavaStackTraceConsoleFactory.java
@@ -68,10 +68,13 @@
public void openConsole(String initialText) {
if (fConsole == null) {
fConsole = new JavaStackTraceConsole();
- fConsole.initializeDocument();
+ if (initialText != null) {
+ fConsole.getDocument().set(initialText);
+ } else {
+ fConsole.initializeDocument();
+ }
fConsoleManager.addConsoles(new IConsole[] { fConsole });
- }
- if (initialText != null) {
+ } else if (initialText != null) {
fConsole.getDocument().set(initialText);
}
fConsoleManager.showConsoleView(fConsole);
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIDebugUIPreferenceInitializer.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIDebugUIPreferenceInitializer.java
index 523e16e..ed5690f 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIDebugUIPreferenceInitializer.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIDebugUIPreferenceInitializer.java
@@ -41,7 +41,7 @@
store.setDefault(IJDIPreferencesConstants.PREF_SHOW_QUALIFIED_NAMES, false);
// JavaStepFilterPreferencePage
- store.setDefault(IJDIPreferencesConstants.PREF_ACTIVE_FILTERS_LIST, "java.lang.ClassLoader"); //$NON-NLS-1$
+ store.setDefault(IJDIPreferencesConstants.PREF_ACTIVE_FILTERS_LIST, "java.lang.ClassLoader,org.eclipse.jdt.launching.internal.*"); //$NON-NLS-1$
store.setDefault(IJDIPreferencesConstants.PREF_INACTIVE_FILTERS_LIST, "com.ibm.*,com.sun.*,java.*,javax.*,jrockit.*,org.omg.*,sun.*,sunw.*"); //$NON-NLS-1$
store.setDefault(IJDIPreferencesConstants.PREF_STEP_THRU_FILTERS, true);
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDetailFormattersManager.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDetailFormattersManager.java
index 281fa06..9092730 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDetailFormattersManager.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDetailFormattersManager.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -33,6 +33,7 @@
import org.eclipse.debug.ui.IValueDetailListener;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.debug.core.IEvaluationRunnable;
import org.eclipse.jdt.debug.core.IJavaArray;
@@ -379,11 +380,16 @@
return fCacheMap.get(key);
}
String snippet = null;
+
if (type instanceof IJavaClassType) {
snippet = getDetailFormatter((IJavaClassType) type);
- } else if (type instanceof IJavaArrayType) {
- snippet = getArraySnippet((IJavaArray) javaObject);
}
+ if (type instanceof IJavaArrayType) {
+ if (JavaCore.compareJavaVersions(debugTarget.getVersion(), JavaCore.VERSION_9) < 0) {
+ snippet = getArraySnippet((IJavaArray) javaObject);
+ }
+ }
+
if (snippet != null) {
IJavaProject project = getJavaProject(javaObject, thread);
if (project != null) {
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaExceptionHyperLink.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaExceptionHyperLink.java
index 1c67f33..77f6cd6 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaExceptionHyperLink.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaExceptionHyperLink.java
@@ -68,6 +68,9 @@
if (breakpoint instanceof IJavaExceptionBreakpoint) {
IJavaExceptionBreakpoint exceptionBreakpoint = (IJavaExceptionBreakpoint) breakpoint;
if (fExceptionName.equals(exceptionBreakpoint.getTypeName())) {
+ // reset enabled setting to true but save original value to reset if user cancels dialog
+ exceptionBreakpoint.getMarker().setAttribute(JavaBreakpointPage.ATTR_ENABLED_SETTING_ON_CANCEL, Boolean.toString(exceptionBreakpoint.isEnabled()));
+ exceptionBreakpoint.setEnabled(true);
showProperties(exceptionBreakpoint);
return;
}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/InstalledJREsBlock.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/InstalledJREsBlock.java
index 0ab955f..ad1c819 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/InstalledJREsBlock.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/InstalledJREsBlock.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -991,7 +991,14 @@
IVMInstallType type = vmTypes[j];
IStatus status = type.validateInstallLocation(file);
if (status.isOK()) {
- found.add(file);
+ String filePath = file.getPath();
+ int index = filePath.lastIndexOf(File.separatorChar);
+ File newFile = file;
+ // remove bin folder from install location as java executables are found only under bin for Java 9 and above
+ if (index > 0 && filePath.substring(index + 1).equals("bin")) { //$NON-NLS-1$
+ newFile = new File(filePath.substring(0, index));
+ }
+ found.add(newFile);
types.add(type);
validLocation = true;
break;
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/JavaBreakpointPage.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/JavaBreakpointPage.java
index 7516044..cfbaa40 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/JavaBreakpointPage.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/JavaBreakpointPage.java
@@ -81,6 +81,11 @@
public static final String ATTR_DELETE_ON_CANCEL = JDIDebugUIPlugin.getUniqueIdentifier() + ".ATTR_DELETE_ON_CANCEL"; //$NON-NLS-1$
/**
+ * Attribute used to indicate resetting the enable attribute if cancel is pressed.
+ */
+ public static final String ATTR_ENABLED_SETTING_ON_CANCEL = JDIDebugUIPlugin.getUniqueIdentifier() + ".ATTR_ENABLED_SETTING_ON_CANCEL"; //$NON-NLS-1$
+
+ /**
* Constant for the empty string
*/
protected static final String EMPTY_STRING = ""; //$NON-NLS-1$
@@ -102,6 +107,7 @@
breakpoint.getMarker().setAttribute(ATTR_DELETE_ON_CANCEL, (String)null);
breakpoint.setRegistered(true);
}
+ breakpoint.getMarker().setAttribute(ATTR_ENABLED_SETTING_ON_CANCEL, (String) null);
doStore();
}
};
@@ -415,6 +421,12 @@
@Override
public boolean performCancel() {
try {
+ String enableSetting = getBreakpoint().getMarker().getAttribute(ATTR_ENABLED_SETTING_ON_CANCEL, null);
+ if (enableSetting != null) {
+ // if this is an old breakpoint we must reset enablement setting
+ boolean enabled = Boolean.parseBoolean(enableSetting);
+ getBreakpoint().setEnabled(enabled);
+ }
if (getBreakpoint().getMarker().getAttribute(ATTR_DELETE_ON_CANCEL) != null) {
// if this breakpoint is being created, delete on cancel
getBreakpoint().delete();
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/PropertyPageMessages.properties b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/PropertyPageMessages.properties
index c982cb4..904b158 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/PropertyPageMessages.properties
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/PropertyPageMessages.properties
@@ -59,7 +59,7 @@
JavaLineBreakpointPage_18=Line Breakpoint
JavaLineBreakpointPage_19=Watchpoint
JavaLineBreakpointPage_20=Method Breakpoint
-JavaVariableDetailsPane_choosePreviousExpression=<Choose a previously entered expression for debugging>
+JavaVariableDetailsPane_choosePreviousExpression=<Choose a previously entered expression>
JavaVariableDetailsPane_description=Java Variable Detail Pane Viewer
JavaVariableDetailsPane_historySeparator=Global history
JavaVariableDetailsPane_name=Java Variable Detail Pane Viewer
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariablesDetailPane.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariablesDetailPane.java
index 41399b1..01267e3 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariablesDetailPane.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariablesDetailPane.java
@@ -13,11 +13,14 @@
*******************************************************************************/
package org.eclipse.jdt.internal.debug.ui.variables;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Stack;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.List;
import java.util.regex.Pattern;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.internal.ui.SWTFactory;
import org.eclipse.debug.internal.ui.views.variables.details.DefaultDetailPane;
import org.eclipse.jdt.debug.core.IJavaVariable;
@@ -26,15 +29,18 @@
import org.eclipse.jdt.internal.debug.ui.propertypages.PropertyPageMessages;
import org.eclipse.jface.dialogs.DialogSettings;
import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.fieldassist.ControlDecoration;
+import org.eclipse.jface.fieldassist.FieldDecoration;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
@@ -57,15 +63,16 @@
private FocusListener focusListener;
private Combo fExpressionHistory;
private IDialogSettings fExpressionHistoryDialogSettings;
- private Map<IJavaVariable, Stack<String>> fLocalExpressionHistory;
- private int fSeparatorIndex;
- private static final int MAX_HISTORY_SIZE = 10;
+ private static final int MAX_HISTORY_SIZE = 20;
private static final String DS_SECTION_EXPRESSION_HISTORY = "expressionHistory"; //$NON-NLS-1$
private static final String DS_KEY_HISTORY_ENTRY_COUNT = "expressionHistoryEntryCount"; //$NON-NLS-1$
private static final String DS_KEY_HISTORY_ENTRY_PREFIX = "expressionHistoryEntry_"; //$NON-NLS-1$
private static final Pattern NEWLINE_PATTERN = Pattern.compile("\r\n|\r|\n"); //$NON-NLS-1$ ;
private IJavaVariable fVariable;
+ private IValue fValue;
+ private boolean textModified = false;
+
public JavaVariablesDetailPane() {
fExpressionHistoryDialogSettings = DialogSettings.getOrCreateSection(JDIDebugUIPlugin.getDefault().getDialogSettings(), DS_SECTION_EXPRESSION_HISTORY);
}
@@ -78,14 +85,14 @@
return c;
}
if (fExpressionHistoryDialogSettings != null) {
- fLocalExpressionHistory = new HashMap<>();
fExpressionHistory = SWTFactory.createCombo(parent, SWT.DROP_DOWN | SWT.READ_ONLY, 1, null);
fExpressionHistory.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
int historyIndex = fExpressionHistory.getSelectionIndex() - 1;
- if (historyIndex >= 0 && historyIndex != fSeparatorIndex && getSourceViewer() != null) {
+ if (historyIndex >= 0 && getSourceViewer() != null) {
getSourceViewer().getDocument().set(getExpressionHistory()[historyIndex]);
+ textModified = true;
}
}
});
@@ -96,20 +103,37 @@
}
Control newControl = super.createControl(parent);
SourceViewer viewer = getSourceViewer();
- focusListener = new FocusListener() {
+ // Light bulb for content assist hint
+ ControlDecoration decoration = new ControlDecoration(viewer.getControl(), SWT.TOP | SWT.LEFT);
+ decoration.setShowOnlyOnFocus(true);
+ FieldDecoration dec = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_CONTENT_PROPOSAL);
+ decoration.setImage(dec.getImage());
+ decoration.setDescriptionText(dec.getDescription());
+ focusListener = new FocusListener() {
@Override
public void focusLost(FocusEvent e) {
updateExpressionHistories();
- initializeExpressionHistoryDropDown();
+ fValue = null;
}
-
@Override
public void focusGained(FocusEvent e) {
-
+ fValue = null;
+ try {
+ if (fVariable != null) {
+ fValue = fVariable.getValue();
+ }
+ } catch (DebugException ex) {
+ }
}
};
viewer.getTextWidget().addFocusListener(focusListener);
+ viewer.getTextWidget().addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ textModified = true;
+ }
+ });
return newControl;
}
@@ -143,27 +167,8 @@
* @return an array of strings containing the history of Expressions
*/
private String[] getExpressionHistory() {
- fSeparatorIndex = -1;
-
// Get global history
- String[] globalItems = readExpressionHistory(fExpressionHistoryDialogSettings);
-
- // Get local history
- Stack<String> localHistory = fLocalExpressionHistory.get(fVariable);
- if (localHistory == null) {
- return globalItems;
- }
-
- // Create combined history
- int localHistorySize = Math.min(localHistory.size(), MAX_HISTORY_SIZE);
- String[] historyItems = new String[localHistorySize + globalItems.length + 1];
- for (int i = 0; i < localHistorySize; i++) {
- historyItems[i] = localHistory.get(localHistory.size() - i - 1);
- }
- fSeparatorIndex = localHistorySize;
- historyItems[localHistorySize] = getSeparatorLabel();
- System.arraycopy(globalItems, 0, historyItems, localHistorySize + 1, globalItems.length);
- return historyItems;
+ return readExpressionHistory(fExpressionHistoryDialogSettings);
}
/**
@@ -171,20 +176,18 @@
*/
private void updateExpressionHistories() {
String newItem = getSourceViewer().getDocument().get();
- if (newItem.length() == 0) {
+ if (newItem.length() == 0 || fValue == null) {
return;
}
- // Update local history
- Stack<String> localHistory = fLocalExpressionHistory.get(fVariable);
- if (localHistory == null) {
- localHistory = new Stack<>();
- fLocalExpressionHistory.put(fVariable, localHistory);
+ String oldValue = fValue.toString();
+ if (oldValue.charAt(0) == '"' && oldValue.charAt(oldValue.length() - 1) == '"') {
+ oldValue = oldValue.substring(1, oldValue.length() - 1);
}
-
- localHistory.remove(newItem);
- localHistory.push(newItem);
-
+ if (!textModified || newItem.equals(oldValue)) {
+ return;
+ }
+ textModified = false;
// Update global history
String[] globalItems = readExpressionHistory(fExpressionHistoryDialogSettings);
if (globalItems.length > 0 && newItem.equals(globalItems[0])) {
@@ -233,51 +236,19 @@
* the dialog settings
*/
private static void storeExpressionHistory(String[] expressions, IDialogSettings dialogSettings) {
- int length = Math.min(expressions.length, MAX_HISTORY_SIZE);
+ List<String> uniqueExpressions = new ArrayList<>(new LinkedHashSet<>(Arrays.asList(expressions)));
+ final int length = Math.min(uniqueExpressions.size(), MAX_HISTORY_SIZE);
int count = 0;
- outer: for (int i = 0; i < length; i++) {
- for (int j = 0; j < i; j++) {
- if (expressions[i].equals(expressions[j])) {
- break outer;
- }
+ for (String expression : uniqueExpressions) {
+ dialogSettings.put(DS_KEY_HISTORY_ENTRY_PREFIX + count, expression);
+ count++;
+ if (count >= length) {
+ break;
}
- dialogSettings.put(DS_KEY_HISTORY_ENTRY_PREFIX + count, expressions[i]);
- count = count + 1;
}
dialogSettings.put(DS_KEY_HISTORY_ENTRY_COUNT, count);
}
- /**
- * Returns the label for the history separator.
- *
- * @return the label for the history separator
- */
- private String getSeparatorLabel() {
- int borderWidth = fExpressionHistory.computeTrim(0, 0, 0, 0).width;
- Rectangle rect = fExpressionHistory.getBounds();
- int width = rect.width - borderWidth;
-
- GC gc = new GC(fExpressionHistory);
- gc.setFont(fExpressionHistory.getFont());
-
- int fSeparatorWidth = gc.getAdvanceWidth('-');
- String separatorLabel = PropertyPageMessages.JavaVariableDetailsPane_historySeparator;
- int fMessageLength = gc.textExtent(separatorLabel).x;
-
- gc.dispose();
-
- StringBuilder dashes = new StringBuilder();
- int chars = (((width - fMessageLength) / fSeparatorWidth) / 2) - 2;
- for (int i = 0; i < chars; i++) {
- dashes.append('-');
- }
-
- StringBuilder result = new StringBuilder();
- result.append(dashes);
- result.append(" " + separatorLabel + " "); //$NON-NLS-1$//$NON-NLS-2$
- result.append(dashes);
- return result.toString().trim();
- }
@Override
public String getDescription() {
@@ -324,9 +295,6 @@
if (fExpressionHistory != null) {
fExpressionHistory.dispose();
}
- if (fLocalExpressionHistory != null) {
- fLocalExpressionHistory.clear();
- }
if (focusListener != null && getSourceViewer() != null && getSourceViewer().getTextWidget() != null) {
getSourceViewer().getTextWidget().removeFocusListener(focusListener);
}
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/IJavaThread.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/IJavaThread.java
index 4b32c69..0bd9d04 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/IJavaThread.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/IJavaThread.java
@@ -259,10 +259,8 @@
/**
* Request to stops this thread with the given exception.<br>
- * The result will be the same as calling
- * java.lang.Thread#stop(java.lang.Throwable).<br>
- * If the thread is suspended when the method is called, the thread must be
- * resumed to complete the action.<br>
+ * The result will be the same as calling java.lang.Thread#stop(java.lang.Throwable).<br>
+ * If the thread is suspended when the method is called, the thread must be resumed to complete the action.<br>
*
* <em>exception</em> must represent an exception.
*
@@ -271,7 +269,7 @@
* @exception DebugException
* if the request fails
* @since 3.0
- * @see java.lang.Thread#stop(java.lang.Throwable)
+ * @see java.lang.Thread#stop()
*/
public void stop(IJavaObject exception) throws DebugException;
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JavaSourceLookupUtil.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JavaSourceLookupUtil.java
index 0639828..cbbbe50 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JavaSourceLookupUtil.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JavaSourceLookupUtil.java
@@ -62,29 +62,7 @@
} else {
IPackageFragmentRoot root = getPackageFragmentRoot(entry);
if (root == null) {
- String path = entry.getSourceAttachmentLocation();
- ISourceContainer container = null;
- if (path == null) {
- // use the archive itself
- path = entry.getLocation();
- }
- if (path != null) {
- // check if file or folder
- File file = new File(path);
- if (file.isDirectory()) {
- IResource resource = entry.getResource();
- if (resource instanceof IContainer) {
- container = new FolderSourceContainer((IContainer) resource, false);
- } else {
- container = new DirectorySourceContainer(file, false);
- }
- } else {
- container = new ExternalArchiveSourceContainer(path, true);
- }
- if (!containers.contains(container)) {
- containers.add(container);
- }
- }
+ addSourceAttachment(entry, containers);
} else {
ISourceContainer container = new PackageFragmentRootSourceContainer(root);
if (!containers.contains(container)) {
@@ -117,6 +95,39 @@
}
/**
+ * Tries to find and attach source containers for given runtime classpath entry
+ *
+ * @param entry
+ * non null
+ * @param containers
+ */
+ private static void addSourceAttachment(IRuntimeClasspathEntry entry, List<ISourceContainer> containers) {
+ String path = entry.getSourceAttachmentLocation();
+ ISourceContainer container = null;
+ if (path == null) {
+ // use the archive itself
+ path = entry.getLocation();
+ }
+ if (path != null) {
+ // check if file or folder
+ File file = new File(path);
+ if (file.isDirectory()) {
+ IResource resource = entry.getResource();
+ if (resource instanceof IContainer) {
+ container = new FolderSourceContainer((IContainer) resource, false);
+ } else {
+ container = new DirectorySourceContainer(file, false);
+ }
+ } else {
+ container = new ExternalArchiveSourceContainer(path, true);
+ }
+ if (!containers.contains(container)) {
+ containers.add(container);
+ }
+ }
+ }
+
+ /**
* Returns whether the source attachments of the given package fragment
* root and runtime classpath entry are equal.
* <p>
@@ -212,6 +223,7 @@
private static void getPackageFragmentRootContainers(IRuntimeClasspathEntry entry, List<ISourceContainer> containers) {
IJavaModel model = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot());
IPath entryPath = entry.getPath();
+ boolean found = false;
try {
IJavaProject[] jps = model.getJavaProjects();
for (int i = 0; i < jps.length; i++) {
@@ -225,6 +237,7 @@
PackageFragmentRootSourceContainer container = new PackageFragmentRootSourceContainer(root);
if (!containers.contains(container)) {
containers.add(container);
+ found = true;
}
}
}
@@ -234,5 +247,9 @@
catch (JavaModelException e) {
LaunchingPlugin.log(e);
}
+
+ if (!found) {
+ addSourceAttachment(entry, containers);
+ }
}
}
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMType.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMType.java
index 94e64da..25f6407 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMType.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMType.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -133,10 +133,11 @@
/**
* The list of locations in which to look for the java executable in candidate
- * VM install locations, relative to the VM install location.
+ * VM install locations, relative to the VM install location. From Java 9 onwards, there may not be a jre directory.
*/
private static final String[] fgCandidateJavaFiles = {"javaw", "javaw.exe", "java", "java.exe", "j9w", "j9w.exe", "j9", "j9.exe"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
- private static final String[] fgCandidateJavaLocations = {"bin" + File.separatorChar, JRE + File.separatorChar + "bin" + File.separatorChar}; //$NON-NLS-1$ //$NON-NLS-2$
+ private static final String[] fgCandidateJavaLocations = { File.separator, "bin" + File.separatorChar, //$NON-NLS-1$
+ JRE + File.separatorChar + "bin" + File.separatorChar };//$NON-NLS-1$
private static ILibraryLocationResolver[] fgLibraryLocationResolvers = null;
@@ -150,8 +151,19 @@
public static File findJavaExecutable(File vmInstallLocation) {
// Try each candidate in order. The first one found wins. Thus, the order
// of fgCandidateJavaLocations and fgCandidateJavaFiles is significant.
+
+ boolean isBin = false;
+ String filePath = vmInstallLocation.getPath();
+ int index = filePath.lastIndexOf(File.separatorChar);
+ if (index > 0 && filePath.substring(index + 1).equals("bin")) { //$NON-NLS-1$
+ isBin = true;
+ }
for (int i = 0; i < fgCandidateJavaFiles.length; i++) {
for (int j = 0; j < fgCandidateJavaLocations.length; j++) {
+ if (!isBin && j == 0) {
+ // search in "." only under bin for java executables for Java 9 and above
+ continue;
+ }
File javaFile = new File(vmInstallLocation, fgCandidateJavaLocations[j] + fgCandidateJavaFiles[i]);
if (javaFile.isFile()) {
return javaFile;
@@ -648,7 +660,9 @@
if (javaExecutable == null) {
status = new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), 0, LaunchingMessages.StandardVMType_Not_a_JDK_Root__Java_executable_was_not_found_1, null); //
} else {
- if (canDetectDefaultSystemLibraries(javaHome, javaExecutable)) {
+ File javaHomeNew = javaHome;
+
+ if (canDetectDefaultSystemLibraries(javaHomeNew, javaExecutable)) {
status = new Status(IStatus.OK, LaunchingPlugin.getUniqueIdentifier(), 0, LaunchingMessages.StandardVMType_ok_2, null);
} else {
status = new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), 0, LaunchingMessages.StandardVMType_Not_a_JDK_root__System_library_was_not_found__1, null);
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/JavaLaunchDelegate.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/JavaLaunchDelegate.java
index d2fbe86..b2e296f 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/JavaLaunchDelegate.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/JavaLaunchDelegate.java
@@ -93,12 +93,9 @@
// VM-specific attributes
Map<String, Object> vmAttributesMap = getVMSpecificAttributesMap(configuration);
- String[][] paths = getClasspathAndModulepath(configuration);
- if (paths == null || paths.length == 0) {
- return null;
- }
// Create VM config
- VMRunnerConfiguration runConfig = new VMRunnerConfiguration(mainTypeName, paths[0]);
+ // Bug 529435 :to move to getClasspathAndModulepath after java 8 is sunset
+ VMRunnerConfiguration runConfig = new VMRunnerConfiguration(mainTypeName, getClasspath(configuration));
runConfig.setProgramArguments(execArgs.getProgramArgumentsArray());
runConfig.setEnvironment(envp);
runConfig.setVMArguments(execArgs.getVMArgumentsArray());
@@ -127,7 +124,8 @@
runConfig.setBootClassPath(getBootpath(configuration));
} else if (supportsModule()) {
// module path
- if (paths.length > 1) {
+ String[][] paths = getClasspathAndModulepath(configuration);
+ if (paths != null && paths.length > 1) {
runConfig.setModulepath(paths[1]);
}
if (!configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_MODULE_CLI_OPTIONS, true)) {
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 6156c48..1b637af 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
@@ -28,6 +28,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
@@ -3485,8 +3486,7 @@
if (isUnnamed) {
Set<String> selected = new HashSet<>(Arrays.asList(modules));
List<IPackageFragmentRoot> allSystemRoots = Arrays.asList(prj.findUnfilteredPackageFragmentRoots(systemLibrary));
- Set<String> defaultModules = new HashSet<>(JavaProject.defaultRootModules(allSystemRoots));
-
+ Set<String> defaultModules = getDefaultModules(allSystemRoots);
Set<String> limit = new HashSet<>(defaultModules);
if (limit.retainAll(selected)) { // limit = selected ∩ default -- only add the option, if limit ⊂ default
if (limit.isEmpty()) {
@@ -3506,6 +3506,31 @@
}
}
+ private static Set<String> getDefaultModules(List<IPackageFragmentRoot> allSystemRoots) throws JavaModelException {
+ HashMap<String, String[]> moduleDescriptions = new HashMap<>();
+ for (IPackageFragmentRoot packageFragmentRoot : allSystemRoots) {
+ IModuleDescription module = packageFragmentRoot.getModuleDescription();
+ if (module != null) {
+ moduleDescriptions.put(module.getElementName(), module.getRequiredModuleNames());
+ }
+ }
+ HashSet<String> result = new HashSet<>();
+ HashSet<String> todo = new HashSet<>(JavaProject.defaultRootModules(allSystemRoots));
+ while (!todo.isEmpty()) {
+ HashSet<String> more = new HashSet<>();
+ for (String s : todo) {
+ if (result.add(s)) {
+ String[] requiredModules = moduleDescriptions.get(s);
+ if (requiredModules != null) {
+ Collections.addAll(more, requiredModules);
+ }
+ }
+ }
+ todo = more;
+ }
+ return result;
+ }
+
private static String joinedSortedList(Collection<String> list) {
String[] limitArray = list.toArray(new String[list.size()]);
Arrays.sort(limitArray);