[non-308] Scoping problem with Resolve and javac 6 vs. 7 vs. Eclipse
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Thu Jan 17 03:10:04 PST 2013
On 17/01/13 10:57, Werner Dietl wrote:
>>>> You are right about the fact that the original example erroneously pass
>>>> in
>>>> JDK 7 - this has been fixed in the JDK 8 repo. I.e. your code doesn't
>>>> compile (regardless of Clazz/Itf) with JDK 8.
>>> OK. So that means that the JDK 8 Resolve wouldn't compile with JDK 8 :-)
>> I don't think so - since the build always use the latest compiler (built
>> with a bootstrap javac) to build the compiler bits. Where is the code that
>> you are say it shouldn't compile?
> langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java line
> 761 in TL (line 760 in type-annotations).
> The call to "report" is of the same form as the ScopingBug example or not?
> The call is forbidden for me in Eclipse and it sounds like Eclipse's
> behavior is correct in this case.
The problem seems to be caused by varargs - i.e. if the outer method is
a varargs, javac will let the call compile - that's why Resolve works.
This is a bug. Please go ahead and refactor the outer Resolve method.
Revised example:
interface Itf {
void foo(String s);
}
class Clazz implements Itf {
public void foo(String s) {}
}
class ScopingBug {
Object o = new Object() {
private void foo(String p, Object... o) {
System.out.println("Called foo");
}
public String toString() {
Itf i = new Clazz() {
@Override
public void foo(String s) {
foo(s, 5);
}
};
i.foo("xx");
return "yyy";
} };
}
Maurizio
>
> cu, WMD.
>
>
>
>>>> On 17/01/13 10:36, Werner Dietl wrote:
>>>>> Thanks for the quick reply, Maurizio!
>>>>>
>>>>> On Thu, Jan 17, 2013 at 2:24 AM, Maurizio Cimadamore
>>>>> <maurizio.cimadamore at oracle.com> wrote:
>>>>>> Hi Werner,
>>>>>> this behavior is correct, method lookup begins by choosing the class in
>>>>>> which to search the method. Such a class is the class defining at least
>>>>>> a
>>>>>> method with the same name as the one to be found, starting from the
>>>>>> innermost class. If no match is found, the search continue in the next
>>>>>> enclosing scope. Here you have that the class to search for 'foo' is
>>>>>> the
>>>>>> inner class, as the inner class has a member method named 'foo'.
>>>>>> Unfortunately, the inner class' foo method is not the one you want to
>>>>>> call.
>>>>> I'm not quite sure I understand your explanation. You are saying that
>>>>> the attached program should fail, right?
>>>>> However, compiling it with javac 1.7.0_09 works and executes correctly.
>>>>>
>>>>> Your explanation makes sense when the anonymous inner class
>>>>> instantiation is changed to "new Itf() {", where I get the same error
>>>>> message from Eclipse and javac 1.7.0.
>>>>>
>>>>>
>>>>>> To solve the problem, note that you can always access the enclosing
>>>>>> class
>>>>>> version of the method by doing this:
>>>>>>
>>>>>> ScopingBug.this.foo(s, 5);
>>>>> Unfortunately, we cannot do this in Resolve line 760, because method
>>>>> "report" that is being called is from an anonymous inner class.
>>>>> Renaming the method would solve this.
>>>>>
>>>>> cu, WMD.
>>>>>
>>>>>
>>>>>> On 17/01/13 10:16, Werner Dietl wrote:
>>>>>>> Since pulling in the latest jdk8/tl changesets, I'm having a build
>>>>>>> problem in Eclipse in javac.comp.Resolve line 760.
>>>>>>> The command-line build succeeds, which made me curious.
>>>>>>>
>>>>>>> I reduced the issue to the attached file.
>>>>>>>
>>>>>>> With a javac 1.6.0_24 compiler I get:
>>>>>>>
>>>>>>> ScopingBug.java:18: cannot find symbol
>>>>>>> symbol: method foo(java.lang.String,int)
>>>>>>>
>>>>>>> With javac 1.7.0_09 this compiles and runs. The test could be
>>>>>>> minimized some more to only illustrate the scoping problem; I expanded
>>>>>>> it to make it executable and the compiled program runs correctly.
>>>>>>>
>>>>>>> The Eclipse 3.7.2 compiler in 1.7 compliance level raises an "not
>>>>>>> applicable" error for the call of foo.
>>>>>>>
>>>>>>> Is this a known issue for javac 6 and Eclipse? Or is javac 7 wrong?
>>>>>>>
>>>>>>> The work-around is easy: don't do the ugly overloading. Could we apply
>>>>>>> such a workaround in Resolve to make my Eclipse-build happy?
>>>>>>>
>>>>>>> To make the example even more interesting, change line 15 to:
>>>>>>>
>>>>>>> Itf i = new Itf() {
>>>>>>>
>>>>>>> that is, instead of using the class Clazz use the interface Itf.
>>>>>>> I would have assumed that this doesn't make a difference. However, now
>>>>>>> javac 7 fails with the same error as Eclipse:
>>>>>>>
>>>>>>> ScopingBug.java:18: error: method foo in class <anonymous Itf> cannot
>>>>>>> be applied to given types;
>>>>>>> foo(s, 5);
>>>>>>> ^
>>>>>>> required: String
>>>>>>> found: String,int
>>>>>>> reason: actual and formal argument lists differ in length
>>>>>>>
>>>>>>> Is this behavior intended?
>>>>>>>
>>>>>>> Thanks,
>>>>>>> cu, WMD.
>>>>>>>
>>>
>
>
More information about the type-annotations-dev
mailing list