Community
Participate
Working Groups
2.1 stream New optional compilation problem got added to report non-static usage of static fields/methods. It should be surfaced in the preference page. JavaCore.COMPILER_PB_STATIC_ACCESS_RECEIVER
JDT/Core side was bug 21787
We should also add a quick fix for this.
Martin: Renaud again. I include below a (trivial) patch for this. Hope it's to your liking. I'll try to think about a quickfix too.
Created attachment 1849 [details] new field for compiler option "static member accessed through non-static reference"
Perfect! Released patch (reordered controls on the page). > 20020813
reopened for quick fix feature
I'm not making any more progress on this. I've got a patch that solves the most common case, where a simple variable makes a non-static reference to a field or method. E.g. File f = new File(); f.pathSeparator -> corrected to File.separator This patch is included below (note that I also factored the code to create an import statement into a new method addImportToProposal). But I'm having a hard time solving with more complicated cases (inner classes, references through method calls, references using this, etc.). Martin, maybe you want to take a crack at it?
Created attachment 1861 [details] quickfix for non-static access to static member
released > 20020819 Can you give examples where the quick fix failes? I didn't see a problem.
Here is a class I used for testing. MyInterface defines a constant N and MyInterfaceImpl defines staticField and staticMethod. The cases corrected OK are flagged with "works". The others don't -- I've been unable to find a simple solution that covers them all, partly because the correction expands to more than the problem node itself in the AST. This is the case with your foo().goo() example. class Outer { static class Inner { static class InnerInner { static class InnerInnerInner { static int staticField = 3; static void staticMethod() {}; } static InnerInnerInner iii = new InnerInnerInner(); } InnerInner ii = new InnerInner(); } class MyInterfaceImplInner { MyInterfaceImpl my = new MyInterfaceImpl(); } Inner _i = new Inner(); MyInterfaceImpl _s = new MyInterfaceImpl(); void correctThis() { _s.staticField += 1; // works int n; n = _s.N + 1; // works _s.staticMethod(); // works bug21804.Outer.this._s.staticField = 99; _i.ii.iii.staticField = 12; this._i.ii.iii.staticMethod(); } void correctInner() { Inner i = new Inner(); i.ii.iii.staticField = 123; i.ii.iii.staticMethod(); } void correctSubInner() { MyInterfaceImplInner miii = new MyInterfaceImplInner(); miii.my.staticField = 99; // works miii.my.staticMethod(); // works too } void correctThroughReferences() { MyInterface mi = new MyInterfaceImpl(); int n; n = mi.newInstance().N; } }
Thanks for the test code! Had to modify the test code to get it running, hope I did't corrected wrongly. Added code to getQualifier; the given cases work now all fine > 20020820 What is sometimes distracting that the compiler generates more than one marker for some statements: i.ii.iii.staticField = 123; // static access of iii, static access of staticField My latest test code: ---- import junit.samples.Outer.Inner.InnerInner.InnerInnerInner; public class MyInterfaceImpl { static int staticField; static int N; public static void staticMethod() { } public MyInterfaceImpl newInstance() { return null; } } class Outer { static class Inner { static class InnerInner { static class InnerInnerInner { static int staticField = 3; static void staticMethod() { }; } static InnerInnerInner iii = new InnerInnerInner(); } InnerInner ii = new InnerInner(); } static InnerInnerInner _m() { return null; } class MyInterfaceImplInner { MyInterfaceImpl my = new MyInterfaceImpl(); Inner _i = new Inner(); MyInterfaceImpl _s = new MyInterfaceImpl(); void correctThis() { _s.staticField += 1; int n; n = _s.N + 1; _s.staticMethod(); Outer.MyInterfaceImplInner.this._s.staticField = 99; _i.ii.iii.staticField = 12; this._i.ii.iii.staticMethod(); _m().staticField= 1; _m().staticMethod(); } void correctInner() { Inner i = new Inner(); i.ii.iii.staticField = 123; i.ii.iii.staticMethod(); } void correctSubInner() { MyInterfaceImplInner miii = new MyInterfaceImplInner(); miii.my.staticField = 99; miii.my.staticMethod(); } void correctThroughReferences() { MyInterfaceImpl mi = new MyInterfaceImpl(); int n; n = mi.newInstance().N; mi.newInstance().staticMethod(); } } }
Very cool, good job. So simple! I didn't figure out I could get the expression from the field access, and that would have solved it. Well, I think we're done with this. Feel like closing the bug?
Yes, closing the PR. Fixed. Renaud, thanks for you efforts!