Bug 329294 - "Unable to resolve binding" error on inspect, display, or
watch of a variable
diff --git a/org.eclipse.jdt.debug.tests/testprograms/bug329294.java b/org.eclipse.jdt.debug.tests/testprograms/bug329294.java
new file mode 100644
index 0000000..c361502
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/testprograms/bug329294.java
@@ -0,0 +1,33 @@
+//breaking line comment
+public class bug329294 {
+	public static void main(String[] args) {
+		Inner1 i1 = new Inner1();
+		Inner2 i2 = new Inner2(i1) {
+			boolean isTrue() {
+				return fInner1.innerBool;
+			}
+		};
+		i2.isTrue();
+		i2.isNotTrue();
+		i2 = new Inner2(i1);
+		i2.isTrue();
+	}
+	private static class Inner1 {
+		boolean innerBool;
+	}
+	//breaking line comment
+	private static class Inner2 {
+		Inner1 fInner1 = null;
+		Inner2(Inner1 inner) {
+			fInner1 = inner;
+		}
+		
+		boolean isTrue() {
+			return fInner1.innerBool;
+		}
+		
+		boolean isNotTrue() {
+			return !fInner1.innerBool;
+		}
+	}
+}
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 ef43203..0d4b5f0 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
@@ -74,6 +74,7 @@
 import org.eclipse.debug.ui.ILaunchConfigurationTabGroup;
 import org.eclipse.debug.ui.actions.ToggleBreakpointAction;
 import org.eclipse.jdt.core.IAccessRule;
+import org.eclipse.jdt.core.IBuffer;
 import org.eclipse.jdt.core.IClassFile;
 import org.eclipse.jdt.core.IClasspathAttribute;
 import org.eclipse.jdt.core.IClasspathEntry;
@@ -88,6 +89,7 @@
 import org.eclipse.jdt.core.ISourceRange;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.Signature;
 import org.eclipse.jdt.debug.core.IJavaClassPrepareBreakpoint;
 import org.eclipse.jdt.debug.core.IJavaDebugTarget;
@@ -177,7 +179,8 @@
 			"org.eclipse.debug.tests.targets.ThreadStack", "org.eclipse.debug.tests.targets.HcrClass", "org.eclipse.debug.tests.targets.StepIntoSelectionClass", 
 			"WatchItemTests", "ArrayTests", "ByteArrayTests", "PerfLoop", "Console80Chars", "ConsoleStackTrace", "ConsoleVariableLineLength", "StackTraces", 
 			"ConsoleInput", "PrintConcatenation", "VariableDetails", "org.eclipse.debug.tests.targets.ArrayDetailTests", "ArrayDetailTestsDef", "ForceReturnTests", 
-			"ForceReturnTestsTwo", "LogicalStructures", "BreakpointListenerTest", "LaunchHistoryTest", "LaunchHistoryTest2", "RunnableAppletImpl", "java6.AllInstancesTests"};
+			"ForceReturnTestsTwo", "LogicalStructures", "BreakpointListenerTest", "LaunchHistoryTest", "LaunchHistoryTest2", "RunnableAppletImpl", "java6.AllInstancesTests",
+			"bug329294"};
 	
 	/**
 	 * the default timeout
@@ -362,6 +365,7 @@
 				cfgs.add(createLaunchConfiguration(jp, "a.b.c.IntegerAccess"));
 				cfgs.add(createLaunchConfiguration(jp, "a.b.c.StepIntoSelectionWithGenerics"));
 				cfgs.add(createLaunchConfiguration(jp, "a.b.c.ConditionalsNearGenerics"));
+				cfgs.add(createLaunchConfiguration(jp, "a.b.c.bug329294WithGenerics"));
 				loaded15 = true;
 				waitForBuild();
 	        }
@@ -552,6 +556,20 @@
 	}
 	
 	/**
+	 * Sets the contents of the given {@link ICompilationUnit} to be the new contents provided
+	 * @param unit
+	 * @param contents the new {@link String} contents, cannot be <code>null</code>
+	 * @throws JavaModelException
+	 */
+	protected void setFileContents(ICompilationUnit unit, String contents) throws JavaModelException {
+		assertNotNull("You cannot set the new contents of an ICompilationUnit to null", contents);
+		IBuffer buffer = unit.getBuffer();
+		buffer.setContents(contents);
+		unit.save(null, true);
+		waitForBuild();
+	}
+	
+	/**
 	 * Sets the last relevant event set
 	 *
 	 * @param set event set
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 a228b948..eaaba3c 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
@@ -74,6 +74,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.GeneralEvalTests;
 import org.eclipse.jdt.debug.tests.eval.GenericsEvalTests;
 import org.eclipse.jdt.debug.tests.launching.ConfigurationEncodingTests;
 import org.eclipse.jdt.debug.tests.launching.ConfigurationResourceMappingTests;
@@ -303,7 +304,9 @@
 
 	// Open from Clipboard action tests - Need to use #suite() because the test has a custom setup
 		addTest(OpenFromClipboardTests.suite());
-		
-		//addTest(EvalTestSuite.suite());
+	
+	//add the complete eval suite
+		addTest(new TestSuite(GeneralEvalTests.class));
+		addTest(EvalTestSuite.suite());
 	}
 }
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/MiscBreakpointsTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/MiscBreakpointsTests.java
index e4921fc..e5cb2e7 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/MiscBreakpointsTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/MiscBreakpointsTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- *  Copyright (c) 2000, 2011 IBM Corporation and others.
+ *  Copyright (c) 2000, 2013 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
@@ -10,8 +10,6 @@
  *******************************************************************************/
 package org.eclipse.jdt.debug.tests.breakpoints;
 
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.jdt.core.IBuffer;
 import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.debug.core.IJavaDebugTarget;
@@ -29,6 +27,8 @@
 	private static final String COMPILE_ERROR_CONTENTS = 
 	 "public class CompileError {\npublic static void main(String[] args) {\nString foo = \"foo\" + bar;\n}	\n}";
 
+	private static final String ORIGINAL_CONTENTS = "public class CompileError {\npublic static void main(String[] args) {\n}\n}";
+	
 	/**
 	 * Constructor
 	 * @param name
@@ -72,10 +72,7 @@
 		
 		IType type = get14Project().findType(typeName);
 		ICompilationUnit cu = type.getCompilationUnit();
-		IBuffer buffer = cu.getBuffer();
-		buffer.setContents(COMPILE_ERROR_CONTENTS);
-		cu.save(new NullProgressMonitor(), true);
-        waitForBuild();
+		setFileContents(cu, COMPILE_ERROR_CONTENTS);
 		
 		IJavaThread javaThread = null;
 		try {
@@ -89,6 +86,8 @@
             getPrefStore().setValue(IJDIPreferencesConstants.PREF_SUSPEND_ON_COMPILATION_ERRORS, false);
 			terminateAndRemove(javaThread);
 			removeAllBreakpoints();
+			//restore the file to remove compile errors
+			setFileContents(cu, ORIGINAL_CONTENTS);
 		}		
 	}
 
@@ -104,10 +103,7 @@
 		
 		IType type = get14Project().findType(typeName);
 		ICompilationUnit cu = type.getCompilationUnit();
-		IBuffer buffer = cu.getBuffer();
-		buffer.setContents(COMPILE_ERROR_CONTENTS);
-		cu.save(new NullProgressMonitor(), true);
-        waitForBuild();
+		setFileContents(cu, COMPILE_ERROR_CONTENTS);
 		
 		IJavaDebugTarget debugTarget = null;
 		try {
@@ -115,6 +111,7 @@
 		} finally {
 			terminateAndRemove(debugTarget);
 			removeAllBreakpoints();
+			setFileContents(cu, ORIGINAL_CONTENTS);
 		}		
 	}
 
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/GeneralEvalTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/GeneralEvalTests.java
new file mode 100644
index 0000000..451025f
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/GeneralEvalTests.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) Mar 6, 2013 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.debug.tests.eval;
+
+import org.eclipse.jdt.debug.core.IJavaThread;
+import org.eclipse.jdt.debug.tests.AbstractDebugTest;
+
+/**
+ * Tests that evaluations in non-generified source
+ * 
+ * @since 3.8.100
+ */
+public class GeneralEvalTests extends AbstractDebugTest {
+
+	
+	/**
+	 * @param name
+	 */
+	public GeneralEvalTests(String name) {
+		super(name);
+	}
+
+	/**
+	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=329294
+	 * @throws Exception
+	 */
+	public void testInnerType1() throws Exception {
+		IJavaThread thread = null;
+		try {
+			String typename = "bug329294";
+			createLineBreakpoint(22, typename);
+			thread = launchToBreakpoint(typename);
+			assertNotNull("The program did not suspend", thread);
+			String snippet = "inner";
+			doEval(thread, snippet);
+		}
+		finally {
+			removeAllBreakpoints();
+			terminateAndRemove(thread);
+		}
+	}
+	
+	/**
+	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=329294
+	 * @throws Exception
+	 */
+	public void testInnerType2() throws Exception {
+		IJavaThread thread = null;
+		try {
+			String typename = "bug329294";
+			createLineBreakpoint(26, typename);
+			thread = launchToBreakpoint(typename);
+			assertNotNull("The program did not suspend", thread);
+			String snippet = "fInner1.innerBool";
+			doEval(thread, snippet);
+		}
+		finally {
+			removeAllBreakpoints();
+			terminateAndRemove(thread);
+		}
+	}
+	
+	/**
+	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=329294
+	 * @throws Exception
+	 */
+	public void testInnerType3() throws Exception {
+		IJavaThread thread = null;
+		try {
+			String typename = "bug329294";
+			createLineBreakpoint(30, typename);
+			thread = launchToBreakpoint(typename);
+			assertNotNull("The program did not suspend", thread);
+			String snippet = "!fInner1.innerBool";
+			doEval(thread, snippet);
+		}
+		finally {
+			removeAllBreakpoints();
+			terminateAndRemove(thread);
+		}
+	}
+	
+	/**
+	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=329294
+	 * @throws Exception
+	 */
+	public void testInnerAnonymousType() throws Exception {
+		IJavaThread thread = null;
+		try {
+			String typename = "bug329294";
+			createLineBreakpoint(7, typename);
+			thread = launchToBreakpoint(typename);
+			assertNotNull("The program did not suspend", thread);
+			String snippet = "fInner1.innerBool";
+			doEval(thread, snippet);
+		}
+		finally {
+			removeAllBreakpoints();
+			terminateAndRemove(thread);
+		}
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/GenericsEvalTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/GenericsEvalTests.java
index 2ed3972..af8bd4a 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/GenericsEvalTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/GenericsEvalTests.java
@@ -261,4 +261,84 @@
 			terminateAndRemove(thread);
 		}
 	}
+	
+	/**
+	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=329294
+	 * @throws Exception
+	 */
+	public void testLineCommentEvalGenerics1() throws Exception {
+		IJavaThread thread = null;
+		try {
+			String type = "a.b.c.bug329294WithGenerics";
+			createLineBreakpoint(8, type);
+			thread = launchToBreakpoint(type);
+			assertNotNull("The program did not suspend", thread);
+			String snippet = "fInner1.innerBool";
+			doEval(thread, snippet);
+		}
+		finally {
+			removeAllBreakpoints();
+			terminateAndRemove(thread);
+		}
+	}
+	
+	/**
+	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=329294
+	 * @throws Exception
+	 */
+	public void testLineCommentEvalGenerics2() throws Exception {
+		IJavaThread thread = null;
+		try {
+			String type = "a.b.c.bug329294WithGenerics";
+			createLineBreakpoint(23, type);
+			thread = launchToBreakpoint(type);
+			assertNotNull("The program did not suspend", thread);
+			String snippet = "inner";
+			doEval(thread, snippet);
+		}
+		finally {
+			removeAllBreakpoints();
+			terminateAndRemove(thread);
+		}
+	}
+	
+	/**
+	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=329294
+	 * @throws Exception
+	 */
+	public void testLineCommentEvalGenerics3() throws Exception {
+		IJavaThread thread = null;
+		try {
+			String type = "a.b.c.bug329294WithGenerics";
+			createLineBreakpoint(27, type);
+			thread = launchToBreakpoint(type);
+			assertNotNull("The program did not suspend", thread);
+			String snippet = "fInner1.innerBool";
+			doEval(thread, snippet);
+		}
+		finally {
+			removeAllBreakpoints();
+			terminateAndRemove(thread);
+		}
+	}
+	
+	/**
+	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=329294
+	 * @throws Exception
+	 */
+	public void testLineCommentEvalGenerics4() throws Exception {
+		IJavaThread thread = null;
+		try {
+			String type = "a.b.c.bug329294WithGenerics";
+			createLineBreakpoint(31, type);
+			thread = launchToBreakpoint(type);
+			assertNotNull("The program did not suspend", thread);
+			String snippet = "!fInner1.innerBool";
+			doEval(thread, snippet);
+		}
+		finally {
+			removeAllBreakpoints();
+			terminateAndRemove(thread);
+		}
+	}
 }
diff --git a/org.eclipse.jdt.debug.tests/testsource-j2se-1.5/a/b/c/bug329294WithGenerics.java b/org.eclipse.jdt.debug.tests/testsource-j2se-1.5/a/b/c/bug329294WithGenerics.java
new file mode 100644
index 0000000..55fa081
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/testsource-j2se-1.5/a/b/c/bug329294WithGenerics.java
@@ -0,0 +1,34 @@
+package a.b.c;
+//breaking line comment
+public class bug329294WithGenerics {
+	public static void main(String[] args) {
+		Inner1<String> i1 = new Inner1<String>();
+		Inner2<String> i2 = new Inner2<String>(i1) {
+			boolean isTrue() {
+				return fInner1.innerBool;
+			}
+		};
+		i2.isTrue();
+		i2.isNotTrue();
+		i2 = new Inner2<String>(i1);
+		i2.isTrue();
+	}
+	private static class Inner1<T> {
+		boolean innerBool;
+	}
+	//breaking line comment
+	private static class Inner2<T> {
+		Inner1<T> fInner1 = null;
+		Inner2(Inner1<T> inner) {
+			fInner1 = inner;
+		}
+		
+		<E> boolean isTrue() {
+			return fInner1.innerBool;
+		}
+		
+		boolean isNotTrue() {
+			return !fInner1.innerBool;
+		}
+	}
+}
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 d752a0f..127b636 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
@@ -188,7 +188,7 @@
 				options.put(key, JavaCore.IGNORE);
 			}
 		}
-		options.put(JavaCore.COMPILER_TASK_TAGS, ""); //$NON-NLS-1$
+		options.remove(JavaCore.COMPILER_TASK_TAGS);
 		return options;
 	}
 
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/SourceBasedSourceGenerator.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/SourceBasedSourceGenerator.java
index 837bac0..3037fb7 100644
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/SourceBasedSourceGenerator.java
+++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/SourceBasedSourceGenerator.java
@@ -20,10 +20,10 @@
 import java.util.Stack;
 
 import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.ISourceRange;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.Signature;
-import org.eclipse.jdt.core.SourceRange;
 import org.eclipse.jdt.core.dom.ASTNode;
 import org.eclipse.jdt.core.dom.ASTVisitor;
 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
@@ -309,12 +309,33 @@
 	 *         type name context, false otherwise
 	 */
 	private boolean isRightType(ASTNode node) {
-		SourceRange range = new SourceRange(node.getStartPosition(),
-				node.getLength());
-		try {
-			return fType.getSourceRange().equals(range);
-		} catch (JavaModelException e) {
-			JDIDebugPlugin.log(e.getStatus());
+		switch(node.getNodeType()) {
+			case ASTNode.ANNOTATION_TYPE_DECLARATION:
+			case ASTNode.ENUM_DECLARATION:
+			case ASTNode.TYPE_DECLARATION: {
+				AbstractTypeDeclaration decl = (AbstractTypeDeclaration) node;
+				if(fType.getElementName().equals(decl.getName().getIdentifier())) {
+					try {
+						return fType.getFlags() == decl.getModifiers();
+					}
+					catch(JavaModelException jme) {
+						return true;
+					}
+				}
+				break;
+			}
+			case ASTNode.CLASS_INSTANCE_CREATION: {
+				//we only get here when anonymous types are found
+				ClassInstanceCreation cic = (ClassInstanceCreation) node;
+				try {
+					ISourceRange name = fType.getNameRange();
+					return name.getOffset() >= cic.getStartPosition() && 
+							name.getOffset()+name.getLength() <= cic.getStartPosition()+cic.getLength();
+				} catch (JavaModelException e) {
+					JDIDebugPlugin.log(e.getStatus());
+				}
+				break;
+			}
 		}
 		return false;
 	}
@@ -1557,8 +1578,6 @@
 	 */
 	@Override
 	public boolean visit(MethodDeclaration node) {
-		String name = node.getName().toString();
-		System.out.println(name);
 		int firstLine = fCompilationUnit.getLineNumber(node.getStartPosition());
 		int lastLine = fCompilationUnit.getLineNumber(node.getStartPosition() + node.getLength());
 		
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JavaDebugUtils.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JavaDebugUtils.java
index 6482c7f..f565bae 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JavaDebugUtils.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JavaDebugUtils.java
@@ -237,29 +237,20 @@
 				}
 				if (innerTypeName.length() > 0) {
 					try {
-						Integer.parseInt(innerTypeName.substring(0, 1)); // throws
-																			// NFE
-																			// if
-																			// not
-																			// an
-																			// integer
-
+						Integer.parseInt(innerTypeName.substring(0, 1)); // throws NFE if not an integer
 						// perform expensive lookup for anonymous types:
 						ASTParser parser = ASTParser.newParser(AST.JLS4);
 						parser.setResolveBindings(true);
 						parser.setSource(type.getTypeRoot());
-						CompilationUnit cu = (CompilationUnit) parser
-								.createAST(null);
+						CompilationUnit cu = (CompilationUnit) parser.createAST(null);
 						cu.accept(new ASTVisitor(false) {
 							@Override
 							public boolean visit(AnonymousClassDeclaration node) {
 								ITypeBinding binding = node.resolveBinding();
 								if (binding == null)
 									return false;
-								if (qualifiedName.equals(binding
-										.getBinaryName()))
-									throw new ResultException((IType) binding
-											.getJavaElement());
+								if (qualifiedName.equals(binding.getBinaryName()))
+									throw new ResultException((IType) binding.getJavaElement());
 								return true;
 							}
 
@@ -268,10 +259,8 @@
 								ITypeBinding binding = node.resolveBinding();
 								if (binding == null)
 									return false;
-								if (qualifiedName.equals(binding
-										.getBinaryName()))
-									throw new ResultException((IType) binding
-											.getJavaElement());
+								if (qualifiedName.equals(binding.getBinaryName()))
+									throw new ResultException((IType) binding.getJavaElement());
 								return true;
 							}
 						});