Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 406619 - [1.8][compiler] Incorrect suggestion that method can be made static.
Summary: [1.8][compiler] Incorrect suggestion that method can be made static.
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.3   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: BETA J8   Edit
Assignee: shankha banerjee CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-04-26 03:21 EDT by Srikanth Sankaran CLA
Modified: 2013-05-08 01:27 EDT (History)
3 users (show)

See Also:
srikanth_sankaran: review+


Attachments
Patch (1.05 KB, patch)
2013-05-02 06:27 EDT, shankha banerjee CLA
no flags Details | Diff
Shankha's patch (posted incorrectly at bug 406859 (3.71 KB, patch)
2013-05-08 01:00 EDT, Srikanth Sankaran CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Srikanth Sankaran CLA 2013-04-26 03:21:49 EDT
BETA_JAVA8:

I get a hint from the compiler that default method foo of I can be declared
static. Default methods cannot be static.

// ---
interface I {
	default int foo(int x, int y) {
		System.out.println("I.foo(" + x + "," + y + ")");
		return 10;
	}
}
Comment 1 Srikanth Sankaran CLA 2013-04-26 03:22:55 EDT
Shankha, this should be easy to fix. Please note that this warning is
disabled by default. You can turn it on by using window + preferences
and searching for static.
Comment 2 shankha banerjee CLA 2013-05-02 05:35:20 EDT
Is there a need to add the test case (mentioned in  Description Srikanth Sankaran 2013-04-26 03:21:49 EDT ) to RunAllJava8 tests.

Thanks.
Comment 3 shankha banerjee CLA 2013-05-02 06:27:30 EDT
Created attachment 230394 [details]
Patch

The issue happens after a call to 

			if (!this.binding.isStatic() && (this.bits & ASTNode.CanBeStatic) != 0 && !this.isDefaultMethod()) {
				if(!this.binding.isOverriding() && !this.binding.isImplementing()) {
					if (this.binding.isPrivate() || this.binding.isFinal() || this.binding.declaringClass.isFinal()) {
						this.scope.problemReporter().methodCanBeDeclaredStatic(this);
					} else {
						this.scope.problemReporter().methodCanBePotentiallyDeclaredStatic(this);
					}
				}

methodCanBePotentiallyDeclaredStatic(this). The solution could have been to 
have the check (!this.isDefaultMethod()) in the else part. In my opinion putting the check at the top (in the if condition) makes sure we do not lead to either of the warnings in case the method is a default method. I do not have a corresponding test case to prove my point. 

Please let me know if a test case should be added in RunAllJava8 tests. 

Thanks
Comment 4 shankha banerjee CLA 2013-05-02 06:28:57 EDT
RunAllJava8 tests RunAllJDTCoreTests is clean.
Comment 5 Srikanth Sankaran CLA 2013-05-03 03:15:18 EDT
(In reply to comment #2)
> Is there a need to add the test case (mentioned in  Description Srikanth
> Sankaran 2013-04-26 03:21:49 EDT ) to RunAllJava8 tests.


A test should always accompany every fix that gets released unless it is very
hard to write a test due to concurrency issues. The test should not be added
directly to RunAllJava8 tests - it should in this case be added to InterfaceMethodsTest.java which gets picked up by RunAllJava8Tests
Comment 6 shankha banerjee CLA 2013-05-03 03:16:50 EDT
(In reply to comment #5)
> (In reply to comment #2)
> > Is there a need to add the test case (mentioned in  Description Srikanth
> > Sankaran 2013-04-26 03:21:49 EDT ) to RunAllJava8 tests.
> 
> 
> A test should always accompany every fix that gets released unless it is very
> hard to write a test due to concurrency issues. The test should not be added
> directly to RunAllJava8 tests - it should in this case be added to
> InterfaceMethodsTest.java which gets picked up by RunAllJava8Tests

Okay. I will update the patch with the test and re post it. 

Thanks
Comment 7 Srikanth Sankaran CLA 2013-05-08 01:00:24 EDT
Created attachment 230625 [details]
Shankha's patch (posted incorrectly at bug 406859
Comment 8 shankha banerjee CLA 2013-05-08 01:05:15 EDT
Thanks. Sorry about posting it in the wrong attachment. 

I am trying to make the following call:
public void testStaticMethod14() {
		runConformTest(
			new String[] {
				"X.java",
				"interface X {\n" +
				"	default int foo() {\n" +
				"		return 10;\n" +
				"	}\n" +
				"}\n",
			},
			new String[] {"-Dcompliance=1.8"});
	}

which in turn  makes a call to 

protected void runConformTest(String[] testFiles, String[] vmArguments) {
		runTest(
			// test directory preparation
			true /* flush output directory */,
			testFiles /* test files */,
			// compiler options
			null /* no class libraries */,
			null /* no custom options */,
			false /* do not perform statements recovery */,
			null /* no custom requestor */,
			// compiler results
			false /* expecting no compiler errors */,
			null /* do not check compiler log */,
			// runtime options
			false /* do not force execution */,
			vmArguments /* vm arguments */,
			// runtime results
			null /* expected output string */,
			null /* do not check error string */,
			// javac options
			JavacTestOptions.DEFAULT /* default javac test options */);
	}

I wish to pass the correct compliance level 1.8 from the interface test method function. 

Thanks
Comment 9 Srikanth Sankaran CLA 2013-05-08 01:27:55 EDT
Review comments:

(1) In the test, apart from bug link, please also provide the bug title.
(2) I renamed the test from being testStaticMethod14 to test406619.

Fix looks good. I released it here: http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?h=BETA_JAVA8&id=1c82ab4ca7a7921e02eb1c1295505414f94bc64d.


Please take a look at how the test has been written. 

If you want a test to be run only at certain level or to be skipped
at some levels, you can do like it is being done in
org.eclipse.jdt.core.tests.compiler.parser.ComplianceDiagnoseTest.testBug399778a
or org.eclipse.jdt.core.tests.compiler.parser.ComplianceDiagnoseTest.testBug399780

But

InterfaceMethodsTest runs already only in 1.8 mode, 

When writing a test, you want to copy + paste if possible from similar tests.
Searching for the message, "can potentially be declared as static" pulls up
some matches in ProblemTypeAndMethodsTests.java. From there I copied a suitable
test to InterfaceMethodsTests.java and modified it.