Merge remote-tracking branch 'origin/master' into BETA_JAVA16
Change-Id: I7d3092fb2520e1e0b348a73692d1a6865ac0a708
diff --git a/org.eclipse.jdt.debug.tests/java8/Bug571230.java b/org.eclipse.jdt.debug.tests/java8/Bug571230.java
new file mode 100644
index 0000000..52886cd
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/java8/Bug571230.java
@@ -0,0 +1,9 @@
+import java.util.ArrayList;
+import java.util.List;
+
+public class Bug571230 {
+ public static void main(String[] args) {
+ List<Integer> list = new ArrayList<>();
+ System.out.println(list);
+ }
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java
index b6c7744..ab32cb6 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java
@@ -487,6 +487,7 @@
cfgs.add(createLaunchConfiguration(jp, "Bug564486"));
cfgs.add(createLaunchConfiguration(jp, "Bug564801"));
cfgs.add(createLaunchConfiguration(jp, "Bug567801"));
+ cfgs.add(createLaunchConfiguration(jp, "Bug571230"));
loaded18 = true;
waitForBuild();
}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java
index 2334837..ff5a253 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java
@@ -90,6 +90,7 @@
import org.eclipse.jdt.debug.tests.core.WatchExpressionTests;
import org.eclipse.jdt.debug.tests.core.WorkingDirectoryTests;
import org.eclipse.jdt.debug.tests.core.WorkspaceSourceContainerTests;
+import org.eclipse.jdt.debug.tests.eval.BlockStatementEvaluationTests;
import org.eclipse.jdt.debug.tests.eval.GeneralEvalTests;
import org.eclipse.jdt.debug.tests.eval.GenericsEvalTests;
import org.eclipse.jdt.debug.tests.eval.LambdaVariableTest;
@@ -328,6 +329,7 @@
//add the complete eval suite
addTest(new TestSuite(GeneralEvalTests.class));
+ addTest(new TestSuite(BlockStatementEvaluationTests.class));
if (JavaProjectHelper.isJava8Compatible()) {
addTest(new TestSuite(LambdaVariableTest.class));
}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/EvalTestSuite.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/EvalTestSuite.java
index aca0228..db2b3b0 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/EvalTestSuite.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/EvalTestSuite.java
@@ -19,6 +19,7 @@
import org.eclipse.jdt.debug.tests.eval.ArrayAllocationTests;
import org.eclipse.jdt.debug.tests.eval.ArrayAssignmentTests;
import org.eclipse.jdt.debug.tests.eval.ArrayValueTests;
+import org.eclipse.jdt.debug.tests.eval.BlockStatementEvaluationTests;
import org.eclipse.jdt.debug.tests.eval.BooleanAssignmentOperatorsTests;
import org.eclipse.jdt.debug.tests.eval.BooleanOperatorsTests;
import org.eclipse.jdt.debug.tests.eval.ByteAssignmentOperatorsTests;
@@ -231,6 +232,7 @@
addTest(new TestSuite(LoopTests.class));
addTest(new TestSuite(LabelTests.class));
addTest(new TestSuite(TestsAnonymousClassVariable.class));
+ addTest(new TestSuite(BlockStatementEvaluationTests.class));
addTest(new TestSuite(TestsBreakpointConditions.class));
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/BlockStatementEvaluationTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/BlockStatementEvaluationTests.java
new file mode 100644
index 0000000..6610997
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/BlockStatementEvaluationTests.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Gayan Perera and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Gayan Perera - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.debug.tests.eval;
+
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.debug.core.IJavaThread;
+import org.eclipse.jdt.debug.tests.AbstractDebugTest;
+
+public class BlockStatementEvaluationTests extends AbstractDebugTest {
+ private IJavaThread javaThread;
+
+ @Override
+ protected IJavaProject getProjectContext() {
+ return get18Project();
+ }
+
+ public BlockStatementEvaluationTests(String name) {
+ super(name);
+ }
+
+ public void testEvaluate_ForLoopBlock_ShouldEvaluate() throws Exception {
+ debugWithBreakpoint("Bug571230", 7);
+ String snippet = "for(int i = 0; i < 5; i++){\n" + " list.add(i);\n" + "}";
+
+ doEval(javaThread, snippet);
+
+ snippet = "list.size()";
+ IValue value = doEval(javaThread, snippet);
+ assertEquals("wrong result : " + value.getValueString(), "5", value.getValueString());
+ }
+
+ public void testEvaluate_ForLoopBlockWithReturn_ShouldEvaluate() throws Exception {
+ debugWithBreakpoint("Bug571230", 7);
+ String snippet = "for(int i = 0; i < 5; i++){\n" + " list.add(i);\n" + " return list.size();\n" + "}";
+
+ IValue value = doEval(javaThread, snippet);
+ assertEquals("wrong result : " + value.getValueString(), "1", value.getValueString());
+ }
+
+ public void testEvaluate_ForLoopBlockWithReturnWithExpressionAtEnd_ShouldEvaluate() throws Exception {
+ debugWithBreakpoint("Bug571230", 7);
+ String snippet = "for(int i = 0; i < 5; i++){\n" + " list.add(i);\n" + " return list;\n" + "}\n" + "list.size()";
+
+ IValue value = doEval(javaThread, snippet);
+ assertEquals("wrong result : " + value.getReferenceTypeName(), "java.util.ArrayList<E>", value.getReferenceTypeName());
+ }
+
+ public void testEvaluate_IfBlock_ShouldEvaluate() throws Exception {
+ debugWithBreakpoint("Bug571230", 7);
+ String snippet = "if(list.isEmpty()){\n" + " list.add(10);\n" + "}";
+
+ doEval(javaThread, snippet);
+
+ snippet = "list.size() > 0";
+ IValue value = doEval(javaThread, snippet);
+ assertEquals("wrong result : " + value.getValueString(), "true", value.getValueString());
+ }
+
+ public void testEvaluate_IfElseWithReturnBlock_ShouldEvaluate() throws Exception {
+ debugWithBreakpoint("Bug571230", 7);
+ String snippet = "if(list.isEmpty()){\n" + " list.add(10);\n" + "} else {\n" + " return 10;" + "}";
+
+ doEval(javaThread, snippet);
+
+ snippet = "list.size() > 0";
+ IValue value = doEval(javaThread, snippet);
+ assertEquals("wrong result : " + value.getValueString(), "true", value.getValueString());
+ }
+
+ public void testEvaluate_IfElseWithReturnBlock_WithExpressionAtEnd_ShouldEvaluateExpression() throws Exception {
+ debugWithBreakpoint("Bug571230", 7);
+ String snippet = "if(list.isEmpty()){\n" + " list.add(10);\n" + "} else {\n" + " return 10;" + "}\n" + "list.size() > 0";
+
+ IValue value = doEval(javaThread, snippet);
+ assertEquals("wrong result : " + value.getValueString(), "true", value.getValueString());
+ }
+
+ private void debugWithBreakpoint(String testClass, int lineNumber) throws Exception {
+ createLineBreakpoint(lineNumber, testClass);
+ javaThread = launchToBreakpoint(testClass);
+ assertNotNull("The program did not suspend", javaThread);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ try {
+ terminateAndRemove(javaThread);
+ } finally {
+ super.tearDown();
+ removeAllBreakpoints();
+ }
+ }
+}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.properties b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.properties
index fac6a6f..3422552 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.properties
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.properties
@@ -1,5 +1,5 @@
###############################################################################
-# Copyright (c) 2000, 2018 IBM Corporation and others.
+# Copyright (c) 2000, 2021 IBM Corporation and others.
#
# This program and the accompanying materials
# are made available under the terms of the Eclipse Public License 2.0
@@ -34,7 +34,7 @@
VMArgumentsBlock_0=Use the -&XstartOnFirstThread argument when launching with SWT
VMArgumentsBlock_1=Use temporary JAR to speci&fy classpath (to avoid classpath length limitations)
VMArgumentsBlock_2=Use the -XX:+ShowCode&DetailsInExceptionMessages argument when launching
-VMArgumentsBlock_3=Use @&argfile when launching
+VMArgumentsBlock_3=Use @a&rgfile when launching
VMArgumentsBlock_VM_Arguments=VM Arguments
JavaConnectTab__Allow_termination_of_remote_VM_6=&Allow termination of remote VM
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/RemoteEvaluatorBuilder.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/RemoteEvaluatorBuilder.java
index 149ff12..1701071 100644
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/RemoteEvaluatorBuilder.java
+++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/RemoteEvaluatorBuilder.java
@@ -250,9 +250,9 @@
}
private boolean isParentInLocalBinding(ASTNode parent) {
- if (parent instanceof Name) {
+ if (parent instanceof QualifiedName) {
// this will avoid unwanted upward traversals
- if (isLocalBinding(((Name) parent).resolveBinding())) {
+ if (isLocalBinding(((QualifiedName) parent).getQualifier().resolveBinding())) {
return true;
}
// traverse upstream to see if a parent is already handled
@@ -1509,7 +1509,7 @@
// when having code like arr.length the length is identified as a field variable. But since the arr is
// already pushed as a variable we don't need to handle length here. So if we have chained field access like
// obj.f1.f2 we will only push the obj as a variable.
- if (!isLocalBinding(binding) && isParentInLocalBinding(node.getParent())) {
+ if (!isLocalBinding(binding) && !isParentInLocalBinding(node.getParent())) {
if (binding instanceof IVariableBinding) {
IVariableBinding vb = ((IVariableBinding) binding);
// For future optimization: Check for duplicates, so same value is only bound once
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/EvaluationSourceGenerator.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/EvaluationSourceGenerator.java
index c733adf..64b1dc8 100644
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/EvaluationSourceGenerator.java
+++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/EvaluationSourceGenerator.java
@@ -124,8 +124,12 @@
String returnString = "return "; //$NON-NLS-1$
int index = codeSnippet.lastIndexOf(returnString);
if (index == -1){
- if (needsReturn(lastSentence))
+ // empty lastSentence means we have statement block above which requires a empty return
+ if (needsReturn(lastSentence)) {
wordBuffer.append(returnString);
+ } else if (lastSentence.isBlank()) {
+ wordBuffer.append(returnString + ';');
+ }
}
else if (index > i){
if (!Character.isWhitespace(chars[index-1]) || !(Character.isWhitespace(chars[index+6]) || chars[index+6] == '}')){
@@ -147,11 +151,12 @@
else if (chars[chars.length -1] !=';' && chars[chars.length -1] =='}'){
int j = lastSentence.lastIndexOf('=') ;
int k = lastSentence.lastIndexOf("==") ; //$NON-NLS-1$
- if ( j != -1 && (j!=k))
+ if (j != -1 && (j != k))
wordBuffer.append(';');
}
- if(lastSentence.length() <= 1 && needsReturn(wordBuffer.toString())) {
+ // make sure last char is not at end of a block before treating this as a statement
+ if (lastSentence.length() <= 1 && needsReturn(wordBuffer.toString())) {
wordBuffer.insert(0, returnString).append(' ');
}
@@ -192,7 +197,9 @@
else if (count == 0 && (token == ITerminalSymbols.TokenNamethrow)){
return false;
}
- else if ( count == 0 && (token == ITerminalSymbols.TokenNameif || token == ITerminalSymbols.TokenNamewhile || token == ITerminalSymbols.TokenNamedo)) {
+ else if (count == 0 && (token == ITerminalSymbols.TokenNameif || token == ITerminalSymbols.TokenNamewhile
+ || token == ITerminalSymbols.TokenNamedo || token == ITerminalSymbols.TokenNamefor || token == ITerminalSymbols.TokenNametry
+ || token == ITerminalSymbols.TokenNameswitch)) {
return false;
}
else if (count ==1 && (token == ITerminalSymbols.TokenNameLBRACE || token == ITerminalSymbols.TokenNameEQUAL)){