Bug 516319 - [1.8] Variables view should show captured lambda variables

Change-Id: Ie6587c1036864600fec00577d9a1152f3ad4423f
Signed-off-by: Andrey Loskutov <loskutov@gmx.de>
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/LambdaUtils.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/LambdaUtils.java
index 21b37d0..be9dfbc 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/LambdaUtils.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/LambdaUtils.java
@@ -28,19 +28,8 @@
 /**
  * Utility class for Lambda Expressions and Stack frames Place holder for all Lambda operation encapsulation.
  */
-public class LambdaUtils {
+public class LambdaUtils extends org.eclipse.jdt.internal.debug.core.model.LambdaUtils {
 
-	/**
-	 * Evaluates if the input frame is a lambda frame.
-	 *
-	 * @param frame
-	 *            the frame which needs to be evaluated
-	 * @return <code>True</code> if the frame is a lambda frame else return <code>False</Code>
-	 * @since 3.8
-	 */
-	public static boolean isLambdaFrame(IJavaStackFrame frame) throws DebugException {
-		return frame.isSynthetic() && frame.getName().startsWith("lambda$"); //$NON-NLS-1$
-	}
 
 	private static int indexOf(IJavaStackFrame frame, IStackFrame[] stackFrames) {
 		int j = 0;
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JDILambdaVariable.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JDILambdaVariable.java
new file mode 100644
index 0000000..c1fe70f
--- /dev/null
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JDILambdaVariable.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2018 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.debug.core.logicalstructures;
+
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IVariable;
+import org.eclipse.jdt.debug.core.IJavaStackFrame;
+import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
+import org.eclipse.jdt.internal.debug.core.model.JDIVariable;
+
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.Type;
+import com.sun.jdi.Value;
+
+/**
+ * Represents the return value after a "step-return".
+ */
+public class JDILambdaVariable extends JDIVariable {
+
+	private ObjectReference fObject;
+
+	public JDILambdaVariable(JDIDebugTarget target, IJavaStackFrame frame, ObjectReference object) {
+		super(target);
+		this.fObject = object;
+	}
+
+	@Override
+	protected Value retrieveValue() {
+		return fObject;
+	}
+
+	/**
+	 * @see IVariable#getName()
+	 */
+	@Override
+	public String getName() {
+		return "Lambda"; //$NON-NLS-1$
+	}
+
+	@Override
+	public String getSignature() throws DebugException {
+		return null;
+	}
+
+	@Override
+	public String getGenericSignature() throws DebugException {
+		return null;
+	}
+
+	@Override
+	public String getReferenceTypeName() throws DebugException {
+		return null;
+	}
+
+	@Override
+	protected Type getUnderlyingType() throws DebugException {
+		return null;
+	}
+}
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIStackFrame.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIStackFrame.java
index 01e8e16..5b554f4 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIStackFrame.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIStackFrame.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -41,6 +41,7 @@
 import org.eclipse.jdt.debug.core.IJavaValue;
 import org.eclipse.jdt.debug.core.IJavaVariable;
 import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
+import org.eclipse.jdt.internal.debug.core.logicalstructures.JDILambdaVariable;
 import org.eclipse.jdt.internal.debug.core.logicalstructures.JDIReturnValueVariable;
 import org.eclipse.jdt.internal.debug.core.model.MethodResult.ResultType;
 
@@ -356,6 +357,14 @@
 						fVariables.add(new JDIThisVariable(
 								(JDIDebugTarget) getDebugTarget(), t));
 					}
+					if (LambdaUtils.isLambdaFrame(this)) {
+						List<IJavaStackFrame> frames = fThread.computeStackFrames();
+						int previousIndex = frames.indexOf(this) + 1;
+						if (previousIndex > 0 && previousIndex < frames.size()) {
+							IJavaStackFrame previousFrame = frames.get(previousIndex);
+							fVariables.add(new JDILambdaVariable((JDIDebugTarget) getDebugTarget(), previousFrame, ((JDIStackFrame) previousFrame).getUnderlyingThisObject()));
+						}
+					}
 				}
 				addStepReturnValue(fVariables);
 				// add locals
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/LambdaUtils.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/LambdaUtils.java
new file mode 100644
index 0000000..57e32c8
--- /dev/null
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/LambdaUtils.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2018 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.debug.core.model;
+
+
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.jdt.debug.core.IJavaStackFrame;
+
+/**
+ * Utility class for Lambda Expressions and Stack frames Place holder for all Lambda operation encapsulation.
+ */
+public class LambdaUtils {
+
+	/**
+	 * Evaluates if the input frame is a lambda frame.
+	 *
+	 * @param frame
+	 *            the frame which needs to be evaluated
+	 * @return <code>True</code> if the frame is a lambda frame else return <code>False</Code>
+	 * @since 3.8
+	 */
+	public static boolean isLambdaFrame(IJavaStackFrame frame) throws DebugException {
+		return frame.isSynthetic() && frame.getName().startsWith("lambda$"); //$NON-NLS-1$
+	}
+
+	}