Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 349032

Summary: Can't traverse Map.Entry in display mode
Product: [Eclipse Project] JDT Reporter: david borsodi <zellermester>
Component: DebugAssignee: Sarika Sinha <sarika.sinha>
Status: VERIFIED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: gubespam, Michael_Rennie, robertmarkbram, sarika.sinha, vsingleton
Version: 3.6.2Keywords: contributed
Target Milestone: 4.4 M6Flags: Michael_Rennie: review+
Hardware: PC   
OS: Windows XP   
Whiteboard:
Attachments:
Description Flags
Considering Parameterized type as Object Michael_Rennie: review+

Description david borsodi CLA 2011-06-10 09:58:31 EDT
Build Identifier: 20110218-0911

While debugging a desktop application, I tried to evaluate the follwoing expression on the display tab:
for(java.util.Map.Entry<String,Object> o : extraParams.entrySet()) {
	System.out.println(o.getKey() + " " + o.getValue());
}
The following exception occurs:
An internal error occurred during: "JDI thread evaluations".
Invalid primitive signature: "Ljava.util.Map$Entry;"

Reproducible: Always

Steps to Reproduce:
1. Debug some code with a map in it
2. Try to evaluate the expression above
Comment 1 Mike M CLA 2012-02-13 17:31:39 EST
I'm also seeing this when putting similar code as the condition for a conditional breakpoint.

Version: Indigo Release
Build id: 20110615-0604
Comment 2 Michael Rennie CLA 2012-02-14 10:45:42 EST
(In reply to comment #1)
> I'm also seeing this when putting similar code as the condition for a
> conditional breakpoint.
> 
> Version: Indigo Release
> Build id: 20110615-0604

Also confirmed in 

Version: 4.2.0
Build id: I20120214-0600

Haven't looked yet but I am guessing we are not correctly handling the jump statements for the new for loop structure.

Also here is a complete runnable snippet to reproduce the problem:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

public class Snippet {
	
	void evalGenericMap() {
		HashMap<String, Object> mymap = new HashMap<String, Object>();
		mymap.put("one", new Integer(1));
		mymap.put("two", new Double(2.0));
		//BP below, select for loop and Ctrl+Shift+D
		for (Entry<String, Object> elems : mymap.entrySet()) {
			//for loop fails to eval
			System.out.println(elems.getKey() + " " +elems.getValue());
		}
		for (Iterator<Entry<String, Object>> i = mymap.entrySet().iterator(); i.hasNext();) {
			//for loop evals just fine
			Entry<String , Object> entry = i.next();
			System.out.println(entry.getKey() + " " + entry.getValue());
		}
	}
	
	public static void main(String[] args) {
		Snippet snippet = new Snippet();
		snippet.evalGenericMap();
	}
}
Comment 3 vernon singleton CLA 2014-01-24 08:29:09 EST
I'm still seeing this in:
Eclipse IDE for Java EE Developers 2.0.1.20130919-0803

Here is a simple snippet that fails:

java.util.HashMap<String, Object> map = new java.util.HashMap<String, Object>();
map.put("two", new Double(4.2));
for (java.util.Map.Entry<String, Object> entry : map.entrySet()) {
   System.out.println(entry.getKey() + " " + entry.getValue());
}
Comment 4 Sarika Sinha CLA 2014-01-27 07:23:22 EST
java/util/Map$Entry is evaluated as Primitive type in 
org.eclipse.jdt.internal.debug.eval.ast.engine.ASTInstructionCompiler.visit(EnhancedForStatement)

org.eclipse.jdt.internal.debug.eval.ast.engine.ASTInstructionCompiler.getTypeId(Type) might needs to be modified to evaluate ParameterizedType as Object type.
Comment 5 Michael Rennie CLA 2014-01-30 11:29:35 EST
(In reply to Sarika Sinha from comment #4)
> java/util/Map$Entry is evaluated as Primitive type in 
> org.eclipse.jdt.internal.debug.eval.ast.engine.ASTInstructionCompiler.
> visit(EnhancedForStatement)
> 
> org.eclipse.jdt.internal.debug.eval.ast.engine.ASTInstructionCompiler.
> getTypeId(Type) might needs to be modified to evaluate ParameterizedType as
> Object type.

Looks like the logic for resolving the type kind is bogus, it does not handle ParameterizedType (which is not a subclass of SimpleType).

At a minimum will will need to add a call to type.isParameterizedType() in ASTInstructionCompiler.getTypeId and return Instruction.T_Object (currently it returns Instruction.T_Unknown for parameterized types)
Comment 6 Sarika Sinha CLA 2014-01-31 04:58:58 EST
Created attachment 239515 [details]
Considering Parameterized type as Object

Parameterized type is considered is unKnown type and turns to be Primitive which has been modified to be considered as Object and non Primitive.
Comment 7 Michael Rennie CLA 2014-02-04 23:41:29 EST
Pushed patch to: http://git.eclipse.org/c/jdt/eclipse.jdt.debug.git/commit/?id=d3fb8a17a2acb440ca71716dd914d498dcdd6ad5

Now that the evaluation succeeds, it is a little weird that you see the return value of the eval as 'false' - which is the result of the last message send instruction: Iterator.hasNext(). I opened bug 427429 for investigation into making the return result of evals more clear.

Thanks Sarika
Comment 8 Sarika Sinha CLA 2014-03-05 04:48:52 EST
Verified in
Version: Luna (4.4)
Build id: I20140303-2000