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.)



More information about the compiler-dev mailing list