Merge remote-tracking branch 'origin/master' into BETA_JAVA15

Change-Id: I242f68f633e6af1620f1ff5f072075b95fd7b89e
diff --git a/org.eclipse.jdt.debug.tests/java8/AnonymousEvaluator.java b/org.eclipse.jdt.debug.tests/java8/AnonymousEvaluator.java
new file mode 100644
index 0000000..0441a38
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/java8/AnonymousEvaluator.java
@@ -0,0 +1,20 @@
+import java.util.function.IntSupplier;
+
+public class AnonymousEvaluator {
+	public static void main(String[] args) {
+		int calc = calculate(new IntSup());
+	}
+
+	public static int calculate(IntSupplier supplier) {
+		return supplier.getAsInt() * 2;
+	}
+
+	private static class IntSup implements IntSupplier {
+
+		@Override
+		public int getAsInt() {
+			return 10 * 20;
+		}
+	}
+
+}
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 45a356c..bcce41a 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
@@ -476,6 +476,7 @@
 				cfgs.add(createLaunchConfiguration(jp, "Bug561715"));
 				cfgs.add(createLaunchConfiguration(jp, "Bug562056"));
 				cfgs.add(createLaunchConfiguration(jp, "RemoteEvaluator"));
+				cfgs.add(createLaunchConfiguration(jp, "AnonymousEvaluator"));
 	    		loaded18 = true;
 	    		waitForBuild();
 	        }
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ProcessTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ProcessTests.java
index 0618ccf..949830c 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ProcessTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ProcessTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -13,6 +13,9 @@
  *******************************************************************************/
 package org.eclipse.jdt.debug.tests.core;
 
+import java.io.File;
+
+import org.eclipse.core.runtime.Platform;
 import org.eclipse.debug.core.DebugException;
 import org.eclipse.debug.core.DebugPlugin;
 import org.eclipse.debug.core.ILaunchManager;
@@ -64,7 +67,19 @@
 	 * @throws Exception
 	 */
 	public void testAlreadyTerminatedProcess() throws Exception {
-		Process process = DebugPlugin.exec(new String[]{"java"}, null);
+		Process process;
+		if (Platform.getOS().equals(Platform.OS_LINUX)) {
+			// printing env command
+			{
+				Runtime.getRuntime().exec("env");
+				Thread.sleep(500);
+
+			}
+			process = DebugPlugin.exec(new String[] { "java" }, new File("/tmp"));
+		} else {
+			process = DebugPlugin.exec(new String[] { "java" }, null);
+		}
+
 		boolean terminated = false;
 		int value = -1;
 		while (!terminated) {
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/RemoteEvaluatorTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/RemoteEvaluatorTests.java
index 4c9c93f..cfbf895 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/RemoteEvaluatorTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/RemoteEvaluatorTests.java
@@ -60,6 +60,34 @@
 		assertEquals("count is not 0", "0", value.getValueString());
 	}
 
+	public void testEvaluate_AnonymousClassInstance_WithSemicolon() throws Exception {
+		debugWithBreakpoint("AnonymousEvaluator", 6);
+		IValue value = evaluate("calculate(new IntSupplier() {\n" + 
+				"\n" + 
+				"			@Override\n" + 
+				"			public int getAsInt() {\n" + 
+				"				return 100 * 20;\n" + 
+				"			}\n" + 
+				"		});");
+
+		assertNotNull("result is null", value);
+		assertEquals("count is not 4000", "4000", value.getValueString());
+	}
+
+	public void testEvaluate_AnonymousClassInstance_WithoutSemicolon() throws Exception {
+		debugWithBreakpoint("AnonymousEvaluator", 6);
+		IValue value = evaluate("calculate(new IntSupplier() {\n" + 
+				"\n" + 
+				"			@Override\n" + 
+				"			public int getAsInt() {\n" + 
+				"				return 100 * 20;\n" + 
+				"			}\n" + 
+				"		})");
+
+		assertNotNull("result is null", value);
+		assertEquals("count is not 4000", "4000", value.getValueString());
+	}
+
 	@Override
 	protected IJavaProject getProjectContext() {
 		return get18Project();
diff --git a/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF b/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF
index 072c492..4a7d4f3 100644
--- a/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF
@@ -30,6 +30,7 @@
  org.eclipse.jdt.internal.debug.ui.threadgroups;x-internal:=true,
  org.eclipse.jdt.internal.debug.ui.variables;x-internal:=true
 Require-Bundle: org.eclipse.ui.ide;bundle-version="[3.5.0,4.0.0)",
+ org.eclipse.jface;bundle-version="[3.21.0,4.0.0)",
  org.eclipse.jface.text;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.ui.workbench.texteditor;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.ui.editors;bundle-version="[3.5.0,4.0.0)",
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugImages.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugImages.java
index 3be8d8f..50f3d04 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugImages.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugImages.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -13,15 +13,13 @@
  *******************************************************************************/
 package org.eclipse.jdt.internal.debug.ui;
 
-import java.net.URL;
-
 import org.eclipse.core.runtime.FileLocator;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Platform;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.resource.ImageRegistry;
 import org.eclipse.swt.graphics.Image;
 import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
 
 /**
  * Bundle of most images used by the Java debug plug-in.
@@ -239,15 +237,11 @@
      *              this plugin class is found (i.e. typically the packages directory)
      */
     private final static void declareRegistryImage(String key, String path) {
-        ImageDescriptor desc = ImageDescriptor.getMissingImageDescriptor();
-        Bundle bundle = Platform.getBundle(JDIDebugUIPlugin.getUniqueIdentifier());
-        URL url = null;
-        if (bundle != null){
-            url = FileLocator.find(bundle, new Path(path), null);
-            if(url != null) {
-            	desc = ImageDescriptor.createFromURL(url);
-            }
-        }
-        fgImageRegistry.put(key, desc);
+		Bundle bundle = FrameworkUtil.getBundle(JavaDebugImages.class);
+		if (bundle == null) {
+			fgImageRegistry.put(key, ImageDescriptor.getMissingImageDescriptor());
+		} else {
+			fgImageRegistry.put(key, ImageDescriptor.createFromURLSupplier(true, () -> FileLocator.find(bundle, new Path(path), null)));
+		}
     }
 }
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/ExecutionEnvironmentsPreferencePage.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/ExecutionEnvironmentsPreferencePage.java
index 265dd35..e45346b 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/ExecutionEnvironmentsPreferencePage.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/ExecutionEnvironmentsPreferencePage.java
@@ -191,7 +191,7 @@
 		table.setLayout(layout);
 		table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
 		fProfilesViewer = new TableViewer(table);
-		fProfilesViewer.setContentProvider(new ArrayContentProvider());
+		fProfilesViewer.setContentProvider(ArrayContentProvider.getInstance());
 		fProfilesViewer.setLabelProvider(new ExecutionEnvironmentsLabelProvider());
 		fProfilesViewer.setInput(JavaRuntime.getExecutionEnvironmentsManager().getExecutionEnvironments());
 
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/VMTypePage.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/VMTypePage.java
index 04500a3..b62e1e8 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/VMTypePage.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/VMTypePage.java
@@ -116,7 +116,7 @@
         data.widthHint = 300;
         fTypesViewer.getControl().setFont(composite.getFont());
         fTypesViewer.getControl().setLayoutData(data);
-        fTypesViewer.setContentProvider(new ArrayContentProvider());
+        fTypesViewer.setContentProvider(ArrayContentProvider.getInstance());
         fTypesViewer.setLabelProvider(new TypeLabelProvider());
 		fTypesViewer.setComparator(new ViewerComparator());
 		fTypesViewer.addDoubleClickListener(new IDoubleClickListener() {
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 34d5aa8..e6a77df 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
@@ -82,6 +82,11 @@
 		acceptFunctionalExpression(node, expectedResult);
 	}
 
+	public void acceptAnonymousClass(ClassInstanceCreation node, ITypeBinding expectedResult) {
+		acceptFunctionalExpression(node, expectedResult);
+	}
+
+
 	private void acceptFunctionalExpression(Expression node, ITypeBinding expectedResult) {
 		FunctionalEvalVisitor visitor = new FunctionalEvalVisitor();
 		node.accept(visitor);
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTInstructionCompiler.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTInstructionCompiler.java
index 7cf7a2b..5d20aa0 100644
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTInstructionCompiler.java
+++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTInstructionCompiler.java
@@ -1548,8 +1548,6 @@
 		if (!isActive()) {
 			return true;
 		}
-		setHasError(true);
-		addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Anonymous_type_declaration_cannot_be_used_in_an_evaluation_expression_2);
 		return false;
 	}
 
@@ -2008,9 +2006,22 @@
 			return true;
 		}
 
+		String rewrittenLocalType = null;
 		if (node.getAnonymousClassDeclaration() != null) {
-			setHasError(true);
-			addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Anonymous_type_declaration_cannot_be_used_in_an_evaluation_expression_7);
+			try {
+				RemoteEvaluatorBuilder builder = makeBuilder(node);
+				builder.acceptAnonymousClass(node, node.getType().resolveBinding());
+				RemoteEvaluator remoteEvaluator = builder.build();
+				push(new RemoteOperator(builder.getSnippet(), node.getStartPosition(), remoteEvaluator));
+
+				push(new PushType(getTypeName(node.getType().resolveBinding())));
+				storeInstruction();
+				return false;
+
+			} catch (JavaModelException | DebugException e) {
+				addErrorMessage(e.getMessage());
+				setHasError(true);
+			}
 		}
 
 		IMethodBinding methodBinding = node.resolveConstructorBinding();
@@ -2026,10 +2037,7 @@
 		boolean isInstanceMemberType = typeBinding.isMember()
 				&& !Modifier.isStatic(typeBinding.getModifiers());
 
-		if (isALocalType(typeBinding)) {
-			setHasError(true);
-			addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Constructor_of_a_local_type_cannot_be_used_in_an_evaluation_expression_8);
-		}
+		boolean isLocalType = isALocalType(typeBinding);
 
 		if (containsALocalType(methodBinding)) {
 			setHasError(true);
@@ -2057,12 +2065,18 @@
 			paramCount++;
 		}
 
-		String signature = getMethodSignature(methodBinding,
-				enclosingTypeSignature).replace('.', '/');
+		String signature = null;
+		if(isLocalType) {
+			String methodSignature = getMethodSignature(methodBinding, null);
+			signature = methodSignature.replace(methodBinding.getReturnType().getQualifiedName(), rewrittenLocalType).replace('.', '/');
+		} else {
+			signature = getMethodSignature(methodBinding,
+					enclosingTypeSignature).replace('.', '/');
+		}
 
 		push(new Constructor(signature, paramCount, fCounter));
 
-		push(new PushType(getTypeName(typeBinding)));
+		push(new PushType(isLocalType ? rewrittenLocalType : getTypeName(typeBinding)));
 		storeInstruction();
 
 		if (isInstanceMemberType) {
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/EvaluationEngineMessages.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/EvaluationEngineMessages.java
index 138371d..ae75890 100644
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/EvaluationEngineMessages.java
+++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/EvaluationEngineMessages.java
@@ -19,7 +19,6 @@
 public class EvaluationEngineMessages extends NLS {
 	private static final String BUNDLE_NAME = "org.eclipse.jdt.internal.debug.eval.ast.engine.EvaluationEngineMessages";//$NON-NLS-1$
 
-	public static String ASTInstructionCompiler_Anonymous_type_declaration_cannot_be_used_in_an_evaluation_expression_2;
 	public static String ASTInstructionCompiler_Assert_statement_cannot_be_used_in_an_evaluation_expression_3;
 	public static String ASTInstructionCompiler_Unrecognized_assignment_operator____4;
 
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/EvaluationEngineMessages.properties b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/EvaluationEngineMessages.properties
index 125c9ce..61f40cd 100644
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/EvaluationEngineMessages.properties
+++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/EvaluationEngineMessages.properties
@@ -13,7 +13,6 @@
 # Jesper Steen Moller - 427089: [1.8] Change value in Variables view with lambda or method reference
 ###############################################################################
 
-ASTInstructionCompiler_Anonymous_type_declaration_cannot_be_used_in_an_evaluation_expression_2=Anonymous type declaration cannot be used in an evaluation expression
 ASTInstructionCompiler_Assert_statement_cannot_be_used_in_an_evaluation_expression_3=Assert statement cannot be used in an evaluation expression
 ASTInstructionCompiler_Unrecognized_assignment_operator____4=Unrecognized assignment operator :
 
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 3146f70..c733adf 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
@@ -112,7 +112,8 @@
 		int i ;
 		for (i=0; i < chars.length; i++) {
 			// copy everything before the last statement or if whitespace
-			if (i<= semicolonIndex || Character.isWhitespace(chars[i]) || chars[i] == '}'){
+			if (i<= semicolonIndex || Character.isWhitespace(chars[i]) || chars[i] == '}' 
+					|| (i > 0 && (chars[i - 1] == '}' && (chars[i] == ')' || chars[i] == ',')))) {
 				wordBuffer.append(codeSnippet.charAt(i));
 			}
 			else
@@ -131,7 +132,7 @@
 				if (needsReturn(lastSentence))
 					wordBuffer.append(returnString);
 			}
-		} else if (chars[chars.length -1] !='}' && ( i+7 > chars.length || (i + 7 <= chars.length && !codeSnippet.substring(i, i+7).equals(returnString)))){
+		} else if (chars[chars.length -1] !='}' && ( (i+7 > chars.length && lastSentence.length() > 1) || (i + 7 <= chars.length && !codeSnippet.substring(i, i+7).equals(returnString)))){
 			// add return if last statement does not have return
 			if (needsReturn(lastSentence))
 				wordBuffer.append(returnString);
@@ -149,6 +150,11 @@
 			if ( j != -1 && (j!=k))
 				wordBuffer.append(';');
 		}
+		
+		if(lastSentence.length() <= 1 && needsReturn(wordBuffer.toString())) {
+			wordBuffer.insert(0, returnString).append(' ');
+		}
+		
 		return wordBuffer.toString();
 	}
 
@@ -225,8 +231,20 @@
 				else if ( (count == 3 || count == 1 ) && token == ITerminalSymbols.TokenNameIdentifier ){
 					 return false;
 				}
-				else {
-					return true;
+				else if (count == 0 && token == ITerminalSymbols.TokenNamereturn) {
+					return false;
+				} else {
+					// ignore and continue the tokens specified here, handling following types of statements
+					// {return i > 0;}, {/**/};{return true;}
+					switch (token) {
+						case ITerminalSymbols.TokenNameLBRACE:
+						case ITerminalSymbols.TokenNameRBRACE:
+						case ITerminalSymbols.TokenNameSEMICOLON:
+							token = scanner.getNextToken();
+							break;
+						default:
+							return true;
+					}
 				}
 
 			}
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/ConditionalBreakpointHandler.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/ConditionalBreakpointHandler.java
index 79e66c0..57a1473 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/ConditionalBreakpointHandler.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/ConditionalBreakpointHandler.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2017 IBM Corporation and others.
+ * Copyright (c) 2009, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -107,6 +107,9 @@
 			JDIThread thread = (JDIThread) result.getThread();
 			if (result.hasErrors()) {
 				DebugException exception = result.getException();
+				if (exception == null) {
+					return DONT_SUSPEND;
+				}
 				Throwable wrappedException = exception.getStatus()
 						.getException();
 				if (wrappedException instanceof VMDisconnectedException) {