wildcards in parameterized types?
Jamison Hope
jrh@theptrgroup.com
Thu Oct 6 23:33:00 GMT 2011
On Oct 6, 2011, at 2:59 PM, Per Bothner wrote:
> On 09/29/2011 07:21 PM, Jamison Hope wrote:
>> I've got a method that looks like this:
>>
>> public void foo(Class<?> c) { ... }
>>
>> which I call from Scheme like this:
>>
>> (*obj*:foo
>> com.example.SomeClass)
>>
>> and now (it's been a while since I recompiled this stuff, so
>> 'now' probably means ever since Kawa started having generics
>> a few months ago) I'm seeing this spurious warning message:
>>
>> [kawac] /path/to/usage.scm:94:2: warning - cannot convert literal (of
>> type java.lang.Class) to ClassType java.lang.Class<? extends
>> ClassType
>> java.lang.Object>
>>
>> Obviously the compiler is forgetting that java.lang.Object is
>> a superclass of every Java class and therefore my usage here
>> is necessarily safe.
>
> I think that's only part of it. The first thing IMO to "fix"
> is the type of com.example.SomeClass, so that it is (in Kawa syntax)
> java.lang.Class[com.example.SomeClass] so the type matches the
> type of the Java expression com.example.SomeClass.class.
>
> This should probably be done in QuoteExp.getInstance, though the
> important thing is that SchemeCompilation#checkDefaultBinding
> returns a correct ParameterizedType instance.
Presumably the ParameterizedType instance would be coerced to the
correct type when passed to a function expecting a Class instance.
What about in expressions like this:
#|kawa:4|# (*:get-methods java.lang.Object)
[public final void java.lang.Object.wait() throws
java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws
java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws
java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()]
If Kawa sees java.lang.Object as a ParameterizedType instead of as a
Class instance, then it'll look for ParameterizedType.getMethods()
instead of Class.getMethods(). Will java.lang.Object:class still
evaluate to the raw Class instance?
> It might be necessary at some point to do a similar parameterization
> for gnu.bytecode.ClassType (to handle not-yet-compiled class, for
> example).
> However, that may require some more though (should gnu.bytecode.Type
> also
> be parameterized?), so I'd defer that.
>
> Once the Kawa compiler is using the correct type, then we need to make
> sure it uses the correct subtype checking for these types. That
> doesn't
> seem to be implemented yet, but it's just A Small Matter Of
> Programming.
>
> I don't we need to be able to expression wildcards in Kawa to solve
> this particular problem - though at some point they would be
> desirable.
>
>> In Java, if the parameter type were "Class<? extends U>",
>> I could suppress the warning by calling *.asSubclass(U.class).
>>
>> But Kawa didn't like that, either:
>>
>> [kawac] /path/to/usage.scm:95:17: warning - cannot convert literal
>> (of
>> type java.lang.Class) to ClassType java.lang.Class<Type U>
>>
>>
>> The last I recall is that Kawa does not have syntax to express
>> wildcards. Is that still true?
>
> That is still true.
>
>> Is there any way to write an
>> invocation of foo(Class<?>) that won't trigger a warning?
>
> We could probably enhance with-compile-options with some suitable
> warning, perhaps some new "unchecked cast" warning. with-compile-
> options
> might not work in this context (where we're compiling literals), but
> could be fixed. However, it may be better to fix the typing before
> we try to suppress the warning; I suspect the warning will go away if
> we use the correct types.
> --
> --Per Bothner
> per@bothner.com http://per.bothner.com/
--
Jamison Hope
The PTR Group
www.theptrgroup.com
More information about the Kawa
mailing list