JDK 13 RFR of JDK-8224687: Add clarifying overrides of Element.asType to more specific subinterfaces
Joe Darcy
joe.darcy at oracle.com
Thu May 30 21:47:19 UTC 2019
Hi Jon,
On 5/30/2019 11:47 AM, Jonathan Gibbons wrote:
>
> On 5/30/19 11:11 AM, Joe Darcy wrote:
>> Hi Ron,
>>
>> On 5/30/2019 10:44 AM, Ron Shapiro wrote:
>>> Is it within scope to return the specific subtypes as covariant
>>> return types? e.g. TypeParameterElement could return TypeVariable,
>>> TypeElement could return DeclaredType, etc.
>>>
>> Based on experience with the earlier apt API, it was a conscious
>> design choice for javax.lang.model to not use covariant returns in a
>> case like this even though it seems appealing. The issue is the that
>> the javax.lang.model is intended to be implemented by different
>> compilers, including compilers where the native declaration and type
>> hierarchies don't match the declaration and type hierarchies in the
>> javax.lang.model modeling interfaces. In particular, some compilers
>> might want to use a single type to implement many (or all) of the
>> javax.lang.model.element interfaces. Having covariant overrides would
>> interfere with such a reduced-type design.
>>
>> HTH,
>>
>> -Joe
>>
> Joe,
>
> I'm not sure I buy this variant of the "some compilers might want to
> use a single type" argument.
>
> If the "kind" (ElementKind or TypeKind) of the return is always a
> specific kind, then there is a presumption that it is safe to downcast
> the returned object to the corresponding specific subtype. That could
> be done equally well (or better) by declaring the return type of the
> method to be more specific.
The javax.lang.model spec makes statements in the root modeling
hierarchies like:
"To implement operations based on the class of an Element object, either
use a visitor or use the result of the getKind() method. Using
instanceof is not necessarily a reliable idiom for determining the
effective class of an object in this modeling hierarchy since an
implementation may choose to have a single object implement multiple
Element subinterfaces."
to document this situation. While it is true that if, say, the
ElementKind is PACKAGE, a cast to PackageElement should succeed, it is
*not* true that if an instanceof check against PackageElement succeeds,
the kind can be inferred to be PACKAGE.
If a compiler wanted to use the same implementation class for both
TypeElement, PackageElement, and TypeParameterElement. That would work
fine today since (by design) one class can implement all three
interfaces. However, covariants returns would prevent that coding
pattern since the return types of asType would not match (and bridge
methods wouldn't help as there would be multiple specializations).
>
> I understand the "some compilers might want to use a single type"
> argument, but that would only apply to internal implementation types,
> and surely not would not absolve the compiler from the responsibility
> of implementing specific subtypes where appropriate. In other words,
> there should be specified correspondence between "kind" and
> implemented interfaces.
During the development of JSR 269, the concerns over accommodating other
compilers were not entirely theoretical :-)
At least in this particular case, I don't see a lot of utility to pursue
covariant overrides of the asType method at this time. (The current
design also imposes fewer constraints on error handling situations.)
Cheers,
-Joe
More information about the compiler-dev
mailing list