JDK 9 RFR of JDK-8074977: Constructor.getAnnotatedParameterTypes returns wrong value
Peter Levart
peter.levart at gmail.com
Sat May 20 21:48:23 UTC 2017
Hi Joe,
Thanks for explanation.
Regarding your patch. Take a look here:
http://cr.openjdk.java.net/~plevart/jdk9-dev/8074977_ConstructorParameterAnnotations/webrev.01/
I just want to point out that the logic could be centralized for
classical and type annotations. What do you think?
Regards, Peter
On 05/20/2017 11:38 PM, joe darcy wrote:
> Hi Peter,
>
>
> On 5/20/2017 11:00 AM, Peter Levart wrote:
>> Hi Joe,
>>
>> So enum classes, anonymous classes and local classes don't have a
>> standard way of passing synthetic/implicit constructor parameters?
>
> Right; there is no standardized or mandated way for compilers to do
> that. Such details are intentionally outside of what the JLS specifies.
>
> Since non-static member classes can be referred to and instances
> instantiated from outside of the enclosing class, there has to be a
> standardized linkage model in that case for separate compilation, etc.
> and that is covered in the JLS. This isn't the case for local and
> anonymous classes since there isn't a way to refer to such classes
> from outside of their immediate declaration context. The instances of
> such types can be returned of course and then it is possible for
> people to getClass().getConstructors()... their way into the issue.
>
>
>> Do various compilers do it differently than javac?
>
> IIRC, ecj does compile enum classes differently than javac.
>
>>
>> It's unfortunate but if # of parameter annotations arrays is less
>> than the # of parameters, Parameter.getAnnotations() may return wrong
>> annotations or throw IndexOutOfBoundException for enums, anonymous
>> and local classes. Can't we do anything for them? At least for code
>> compiled by javac?
>>
>> For example, javac compiles enum classes so that they always prefix
>> constructor source parameters with a pair of (String name, int
>> ordinal, ...) and so do anonymous enum subclasses provided by enum
>> constants (i.e. clazz.isAnonymousClass() &&
>> clazz.getSuperclass().isEnum())
>>
>> Non-static local classes are compiled so that constructor source
>> parameters are prefixed with a single parameter (OuterClass
>> outerInstance, ...), while any captured variables follow source
>> parameters
>
> A wrinkle with local classes is that if they occur in a static
> context, such as a static initializer block, there is no leading outer
> instance parameter.
>
> This is admittedly not a 100% solution to parameter mismatches and
> annotations; however, it is an improvement over the current state of
> affairs.
>
> Ideally, the code for something like Parameters.getAnnotations could
> do something like look at the synthetic bit and pair up natural
> parameters with annotations if there was a mismatch in the number of
> parameters and annotations. Unfortunately, the Parameters.isSynthetic
> API wasn't introduced until JDK 8 and that information doesn't have to
> be available.
>
> Cheers,
>
> -Joe
>
>>
>> Static local classes are compiled so that constructor source
>> parameters come 1st, followed by any captured variables.
>>
>> etc...
>>
>> Regards, Peter
>>
>>
>> On 05/19/2017 11:31 PM, joe darcy wrote:
>>> Hello,
>>>
>>> Please review the webrev to fix
>>>
>>> JDK-8074977: Constructor.getAnnotatedParameterTypes returns
>>> wrong value
>>> http://cr.openjdk.java.net/~darcy/8074977.3/
>>>
>>> To condense a complicated situation, there are cases where the
>>> number of parameters present for a constructor in source code and
>>> the number of parameters present for that constructor in the class
>>> file differ. One of those cases occurs for the constructor of a
>>> non-static member class [1] where there is a leading parameter to
>>> accept the outer this argument.
>>>
>>> Bug JDK-8074977 reports on a situation where the type annotations on
>>> constructor parameters are incorrectly reported. Essentially, an
>>> off-by-one error is the cause since the annotation information is
>>> stored with respect to the number of parameters present in the
>>> source and an additional parameter is present at runtime.
>>>
>>> An analogous situation exists for declaration annotations and
>>> constructor parameters, declaration annotations being the
>>> traditional flavor of annotations.
>>>
>>> Type annotations and declaration annotations are read using
>>> different APIs so require separate fixes to detect the additional
>>> parameter and make the necessary adjustments in the returned
>>> information.
>>>
>>> The regression tests cover both the type annotation reading API and
>>> the two ways of reading declaration annotations on parameters,
>>> calling getParameterAnnotations on the constructor or call
>>> getParameters on the constructor and then calling getAnnotations on
>>> each parameter. The getParameters API was added in JDK 8.
>>>
>>> Static member and non-static member classes are used as test cases,
>>> as are constructors with and without generic type information.
>>>
>>> Thanks,
>>>
>>> -Joe
>>>
>>> [1]
>>> https://blogs.oracle.com/darcy/nested,-inner,-member,-and-top-level-classes
>>>
>>
>
More information about the core-libs-dev
mailing list