Bug 311849 - [quick fix] @SuppressWarnings does not work as expected inside a for loop
Summary: [quick fix] @SuppressWarnings does not work as expected inside a for loop
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.6   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.6 RC1   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 105668
  Show dependency tree
 
Reported: 2010-05-06 06:11 EDT by Raksha Vasisht CLA
Modified: 2010-05-17 07:50 EDT (History)
5 users (show)

See Also:
frederic_fusier: review+


Attachments
Proposed fix + regression tests (3.90 KB, patch)
2010-05-06 10:23 EDT, Olivier Thomann CLA
no flags Details | Diff
Proposed fix + regression test (6.08 KB, patch)
2010-05-10 15:31 EDT, Olivier Thomann CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Raksha Vasisht CLA 2010-05-06 06:11:19 EDT
Build id : I20100504-0800

Test case:

import java.util.*;

class Bug {
    @SuppressWarnings("rawtypes")
    void foo(ArrayList arg) {
        for (
        		boolean a= arg.add(1), b= arg.add(1);
        		Boolean.FALSE;
        		) {
        	System.out.println(a && b);
        }
    }
}

1) Invoke quick fix on the first fragment(a= arg.add(1)) adds the SuppressWarnings("unchecked") in the beginning of the expression but does not apply to the whole declaration expression . Can still see the warning on the second declaration fragment. (b= arg.add(1))

2)If quick fix is invoked on the second fragment, it results in another "unchecked" token being added with a warning and quick fix proposal to remove it as unnecessary: 

 for (
        		@SuppressWarnings({ "unchecked", "unchecked" })
				boolean a= arg.add(1), b= arg.add(1);
        		Boolean.FALSE;
        		) {

Expected: Should apply to the whole expression similar to the field declaration :
import java.util.*;

class Bug {
	@SuppressWarnings("rawtypes")
	ArrayList arg;
	@SuppressWarnings("unchecked")
	boolean a= arg.add(1), b= arg.add(1);
}
Comment 1 Olivier Thomann CLA 2010-05-06 08:12:47 EDT
I'll investigate for 3.6RC1
Comment 2 Olivier Thomann CLA 2010-05-06 10:23:52 EDT
Created attachment 167310 [details]
Proposed fix + regression tests
Comment 3 Olivier Thomann CLA 2010-05-06 10:24:09 EDT
Srikanth, please review.
Comment 4 Markus Keller CLA 2010-05-06 13:57:57 EDT
Note that the quick fix is still in the works (bug 105668), so you need to put the @SuppressWarnings("unchecked") at the right place manually.

The proposed fix works fine for me (though it's a little strange that declarationSourceStart/End means the whole field for FieldDeclarations but only a single variable for LocalDeclarations...).
Comment 5 Olivier Thomann CLA 2010-05-06 14:09:26 EDT
(In reply to comment #4)
> Note that the quick fix is still in the works (bug 105668), so you need to put
> the @SuppressWarnings("unchecked") at the right place manually.
Bug 105668 is tagged as RC1. So I thought this one should be fixed quickly as it blocks a RC1 bug.
 
> The proposed fix works fine for me (though it's a little strange that
> declarationSourceStart/End means the whole field for FieldDeclarations but only
> a single variable for LocalDeclarations...).
This is the case since the beginning for historical reasons. I won't change that now for sure. Sometimes we have to live with inconsistencies :-).
Comment 6 Markus Keller CLA 2010-05-06 14:22:10 EDT
(In reply to comment #5)
Thanks, +1 then.

A comment in declarationSourceStart about the different usages would make this more easily understandable. +1 for adding that if you agree.
Comment 7 Olivier Thomann CLA 2010-05-06 14:39:18 EDT
Released for 3.6RC1.
Added regression tests in:
org.eclipse.jdt.core.tests.compiler.regression.AnnotationTest#test287
org.eclipse.jdt.core.tests.compiler.regression.AnnotationTest#test288

Note org.eclipse.jdt.core.tests.compiler.regression.AnnotationTest#test288 would pass without the fix. It is there to ensure that field declaration source ends cover multiple fields declarations in case we want to fix to change that in the future.
Comment 8 Srikanth Sankaran CLA 2010-05-06 23:22:36 EDT
(In reply to comment #3)
> Srikanth, please review.

Patch looks good. Note that the junits references does not
reference this bug number, but the related bug# 304031
instead.
Comment 9 Raksha Vasisht CLA 2010-05-07 09:32:49 EDT
(In reply to comment #7)

Verified. Thanks for the quick fix Olivier!
Comment 10 Markus Keller CLA 2010-05-10 13:51:42 EDT
The fix only works if the locals don't have other annotations.

E.g. here, it still warns on the second arg.add(..) because of @Other (same with @Deprecated):

import java.util.*;

class Bug {
    @SuppressWarnings("rawtypes")
    void foo(ArrayList arg) {
        for (
//                @Deprecated
                @Other
                @SuppressWarnings("unchecked")
                boolean a = arg.add(1), b = arg.add(2);
                Boolean.FALSE; ) {
            System.out.println(a && b);
        }
    }
}

@interface Other { }
Comment 11 Olivier Thomann CLA 2010-05-10 15:31:58 EDT
Created attachment 167791 [details]
Proposed fix + regression test

Good catch. I got caught by the return statement. So only the first annotation would be checked.
This patch fixes that issue.
Comment 12 Olivier Thomann CLA 2010-05-10 15:33:10 EDT
Frédéric, Markus, please review.
I would like this to be part of tomorrow's JDT contribution.
Comment 13 Frederic Fusier CLA 2010-05-10 16:24:02 EDT
Patch looks good to me.
Comment 14 Olivier Thomann CLA 2010-05-10 17:00:33 EDT
Released for 3.6RC1.
New regression test added in:
org.eclipse.jdt.core.tests.compiler.regression.AnnotationTest#test289
Comment 15 Ayushman Jain CLA 2010-05-17 04:57:09 EDT
I noticed one inconsistency. In the following code

import java.util.*;

class Bug {
	
    @SuppressWarnings("rawtypes")
    void foo(ArrayList arg) {
    	@SuppressWarnings("unchecked")  // bad: unnecessary suppressWarnings warn
    	boolean aa = arg.add(1),  // good: local variable a never read warning
                bb = arg.add(1);
        if (bb)
        	System.out.println("hi");

    }
}

If either aa, or bb is not read the suppressWarnings annotation is warned by the compiler as unnecessary. This is a bogus warning since the annotation applies for atleast one variable in the declaration series.
Olivier, what do you think?
Comment 16 Markus Keller CLA 2010-05-17 06:47:32 EDT
(In reply to comment #15)
Good catch, that's a regression compared to 3.6M7. Please open a new bug for this (we don't reopen bugs after the target milestone has already shipped).
Comment 17 Ayushman Jain CLA 2010-05-17 06:56:09 EDT
Raised bug 313109 for FUP.
Comment 18 Ayushman Jain CLA 2010-05-17 06:58:21 EDT
Verified for 3.6 RC1 using build I20100513-1500.
Comment 19 Jay Arthanareeswaran CLA 2010-05-17 07:50:06 EDT
Verified.