Bug 425412 - [1.8][quick assist] Conversion from anonymous class to lambda loses parameterized type details
Summary: [1.8][quick assist] Conversion from anonymous class to lambda loses parameter...
Status: ASSIGNED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 4.3.1   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: JDT-UI-Inbox CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords:
Depends on:
Blocks: 424296
  Show dependency tree
 
Reported: 2014-01-10 10:09 EST by Noopur Gupta CLA
Modified: 2023-05-18 12:47 EDT (History)
8 users (show)

See Also:


Attachments
Fix + Test (5.21 KB, patch)
2014-01-14 03:28 EST, Noopur Gupta CLA
no flags Details | Diff
Combined patch on master (7.58 KB, patch)
2014-04-28 18:47 EDT, Markus Keller CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Noopur Gupta CLA 2014-01-10 10:09:01 EST
+++ This bug was initially created as a clone of Bug #424296 +++

Here is another case where conversion results in loss of information leading
to breakage: 

import java.util.List;


interface I<T> {
	void goo(List<T> i);
}


public class X {
	public static void main(String[] args) {
		I i = new I<String>() {

			@Override
			public void goo(List<String> k) {
				String s = k.get(0);
				
			}
			
		};
		
	}
}
Comment 1 Noopur Gupta CLA 2014-01-10 10:14:15 EST
We can cast the created lambda expression as follows: 

	I i = (I<String>) k -> {
		String s = k.get(0);
	};

However, when we convert this lambda expression back to the anonymous class, currently the unnecessary cast would remain in the code:

        I i = (I<String>) new I<String>() {
		@Override
		public void goo(List<String> k) {
			String s = k.get(0);
		}
	};

Markus, should unnecessary casts at lambda expressions be removed while converting them to anonymous classes?
Comment 2 Noopur Gupta CLA 2014-01-14 03:28:58 EST
Created attachment 238951 [details]
Fix + Test

Casting the lambda expression on creation.
Clean up "Remove unnecessary casts" should take care of removing the cast when converting back to the anonymous class.

Also, modified ASTNodes#getExplicitCast for getting the binding of the type implemented by the anonymous class in case of ClassInstanceCreation node (to be used in the comparison "targetType != referenceType").  Markus, please have a look if it is required.

The patch is based on mmathew/BETA_JAVA8 branch.
Comment 3 Noopur Gupta CLA 2014-02-07 07:46:34 EST
(In reply to Noopur Gupta from comment #2)
> Created attachment 238951 [details] [diff]
> Fix + Test
> 
> Casting the lambda expression on creation.

The patch casts the created lambda expression whenever the target type binding is not same as the the binding of the type implemented by the anonymous class.

This adds cast in some other cases also where it is not required. Examples:

		Comparator<?> cw1 = new Comparator() {
			@Override
			public int compare(Object w1, Object w2) {
				return 0;
			}
		};
		
		Comparator cw2 = new Comparator<Object>() {
			@Override
			public int compare(Object w1, Object w2) {
				return 0;
			}
		};
		
		Comparator<? extends Number> cw3 = new Comparator<Number>() {
			@Override
			public int compare(Number n1, Number n2) {
				return -0;
			}
		};

I will upload another patch with proper fix.
Comment 4 Noopur Gupta CLA 2014-02-19 07:47:24 EST
(In reply to Noopur Gupta from comment #3)
> The patch casts the created lambda expression whenever the target type
> binding is not same as the the binding of the type implemented by the
> anonymous class.
> 
> This adds cast in some other cases also where it is not required.

There could be multiple conditions involved in deciding the cast related to the target type and the anonymous class type being generic/parameterized/raw/implicitly parameterized with Object type/having sub types in bounds etc.

Hence, as decided, it is OK to produce unnecessary casts at some places.

Leaving the patch as it is and just updated the checks to use IBinding.isEqualTo(IBinding) instead of the operator.
Also, updated the tests accordingly with casts.
Released in branch mmathew/BETA_JAVA8 as:
http://git.eclipse.org/c/jdt/eclipse.jdt.ui.git/commit/?h=mmathew/BETA_JAVA8&id=7ac9de0f154fb3553d36df6bc22079e0d68fdc85
Comment 5 Noopur Gupta CLA 2014-04-22 07:02:26 EDT
Not a big fix and it can be handled with bug 423439.
Markus, please have a look.
Comment 6 Markus Keller CLA 2014-04-28 18:47:05 EDT
I see the problem, but I'm not sure if it's that relevant in practice.

But the effect on CleanUpTest18.testConvertToLambdaNestedWithImports() is quite bad, since it adds a cast that is really not necessary there:

    Executors.newSingleThreadExecutor().submit((Callable<String>) () -> "hi")

I'm not sure how the right solution will look like, but it needs to be smarter than the proposed change.


Here's a safe change that at least removes the redundant cast for the "Convert lambda to anonymous" operation: http://git.eclipse.org/c/jdt/eclipse.jdt.ui.git/commit/?id=996eb0c4700da938888ac62ab62f8a0b34dcd0e6
Comment 7 Markus Keller CLA 2014-04-28 18:47:19 EDT
Created attachment 242431 [details]
Combined patch on master
Comment 8 Eclipse Genie CLA 2019-05-29 05:42:29 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.
Comment 9 Dani Megert CLA 2019-05-29 08:37:04 EDT
Still an issue with I20190528-1800.
Comment 10 Eclipse Genie CLA 2021-05-19 18:30:41 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.
Comment 11 Eclipse Genie CLA 2023-05-18 12:47:53 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.