Bug 569413 avoid using 'this' as field name

removed the lambda field binding 'this' as it is a reserved word in the
AST/evaluator (hence the error) and is already present in the outer
context

Change-Id: Ie564dbc96d481bf44a4f1f64b8950aff1dc959f7
Signed-off-by: Amedeo Santarelli <asantare@outlook.com>
Reviewed-on: https://git.eclipse.org/r/c/jdt/eclipse.jdt.debug/+/179804
Reviewed-by: Gayan Perera <gayanper@gmail.com>
Reviewed-by: Sarika Sinha <sarika.sinha@in.ibm.com>
Tested-by: JDT Bot <jdt-bot@eclipse.org>
diff --git a/org.eclipse.jdt.debug.tests/java8/Bug569413.java b/org.eclipse.jdt.debug.tests/java8/Bug569413.java
new file mode 100644
index 0000000..76ff99b
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/java8/Bug569413.java
@@ -0,0 +1,41 @@
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class Bug569413 {
+
+	public static void main(String[] args) {
+		new Bug569413().test();
+	}
+
+	List<TestClass> packageProcessors = Arrays.asList(new TestClass());
+	Map<String, TestClass> basePackages = new HashMap<>();
+
+	void test() {
+		packageProcessors.forEach(pp -> {
+			Set<String> pkgs = pp.getPackagesToMap();
+			pp.getPackagesToMap().forEach(p -> {
+				// just to make pkgs variable visible for evaluation
+				int a = pkgs.size();
+				basePackages.put(p, pp);
+			});
+		});
+
+		packageProcessors.forEach(pp -> {
+			pp.getPackagesToMap().forEach(p -> {
+				basePackages.put(p, null);
+			});
+		});
+	}
+
+	static class TestClass {
+
+		public Set<String> getPackagesToMap() {
+			return new LinkedHashSet<>(Arrays.asList("ab", "b", "c"));
+		}
+
+	}
+}
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 56668be..c9411c9 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
@@ -494,6 +494,7 @@
 				cfgs.add(createLaunchConfiguration(jp, "Bug567801"));
 				cfgs.add(createLaunchConfiguration(jp, "Bug571230"));
 				cfgs.add(createLaunchConfiguration(jp, "Bug572629"));
+				cfgs.add(createLaunchConfiguration(jp, "Bug569413"));
 	    		loaded18 = true;
 	    		waitForBuild();
 	        }
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/LambdaVariableTest.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/LambdaVariableTest.java
index 53b5be3..a76989a 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/LambdaVariableTest.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/LambdaVariableTest.java
@@ -15,6 +15,7 @@
 
 import org.eclipse.debug.core.model.IValue;
 import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.Signature;
 import org.eclipse.jdt.debug.core.IJavaThread;
 import org.eclipse.jdt.debug.tests.AbstractDebugTest;
 
@@ -145,6 +146,35 @@
 		assertEquals("Actual value is not true", "true", value.getValueString());
 	}
 
+	public void testEvaluate_Bug569413_NestedLambdaCapturedParameters() throws Exception {
+		debugWithBreakpoint("Bug569413", 23);
+
+		IValue pValue = doEval(javaThread, "p");
+		assertEquals("wrong type : ", "java.lang.String", pValue.getReferenceTypeName());
+		assertEquals("wrong result : ", "ab", pValue.getValueString());
+
+		IValue ppValue = doEval(javaThread, "pp");
+		assertEquals("wrong type : ", "Bug569413$TestClass", ppValue.getReferenceTypeName());
+
+		IValue pkgsVar = doEval(javaThread, "pkgs");
+		assertEquals("wrong type : ", "java.util.LinkedHashSet", Signature.getTypeErasure(pkgsVar.getReferenceTypeName()));
+		IValue pkgsValue = doEval(javaThread, "pkgs.toString()");
+		assertEquals("wrong result : ", "[ab, b, c]", pkgsValue.getValueString());
+
+		IValue thisBasePackages = doEval(javaThread, "this.basePackages");
+		assertEquals("wrong type : ", "java.util.HashMap", Signature.getTypeErasure(thisBasePackages.getReferenceTypeName()));
+		IValue thisBasePackagesSize = doEval(javaThread, "this.basePackages.size()");
+		assertEquals("wrong result : ", "0", thisBasePackagesSize.getValueString());
+	}
+
+	public void testEvaluate_Bug569413_NestedLambdaCapturedParameterAndNull() throws Exception {
+		debugWithBreakpoint("Bug569413", 29);
+
+		IValue value = doEval(javaThread, "p");
+		assertEquals("wrong type : ", "java.lang.String", value.getReferenceTypeName());
+		assertEquals("wrong result : ", "ab", value.getValueString());
+	}
+
 	private void debugWithBreakpoint(String testClass, int lineNumber) throws Exception {
 		createLineBreakpoint(lineNumber, testClass);
 		javaThread = launchToBreakpoint(testClass);
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 7dff265..fba88a9 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
@@ -497,14 +497,14 @@
 				if (synVars.length + 1 == allFields.size()) {
 					while (listIterator.hasNext()) {
 						FieldImpl field = (FieldImpl) listIterator.next();
-						String newName = field.name();
+						// remove 'this' field from the fields of the lambda
 						if (i == 0) {
-							newName = "this"; //$NON-NLS-1$
+							listIterator.remove();
 						} else {
-							newName = synVars[i - 1].getName();
+							String newName = synVars[i - 1].getName();
+							FieldImpl newField = createRenamedCopy(field, newName);
+							listIterator.set(newField);
 						}
-						FieldImpl newField = createRenamedCopy(field, newName);
-						listIterator.set(newField);
 						i++;
 					}
 				}