[type-annos-observers] Constraining type annotations to occur just before type
Alex Buckley
alex.buckley at oracle.com
Tue Apr 2 11:55:32 PDT 2013
I reiterate that compile-time errors are used _only_ when the program's
implied behavior would cause a run-time error. Type annotations cannot
cause that, so there is simply no case for a compile-time error about
type annotations "in the wrong place".
There is some confusion about what happens when an annotation type has
TYPE_USE added as a target. No previous code becomes illegal. And
forcing users to make a pass over their source is _never_ a feature of a
programming language.
I would add that even if type annotations were required to go at the end
of the modifier list, it is still possible to write:
public static final @Foo @Bar String s;
Is @Foo a declaration annotation or a type annotation? If it's a poorly
placed declaration annotation, then is @Bar the same, or a type
annotation? You can't tell. It's up to the IDE to help out, not the
compiler.
Alex
On 4/2/2013 1:02 AM, Srikanth S Adayapalam wrote:
> [I am sorry I was away from my mail for a few days and couldn't
> forward this feedback from Markus Keller of the Eclipse JDT team
> earlier - Srikanth]
>
> ----------------8<------------
>
>> However, we cannot say that decl. annotations must come before
>> traditional modifiers (private/public/static/final etc) because it has
>> been legal since Java SE 5.0 to mix them up. The only rule which could
>> possibly be added is "type annotations are not modifiers, and occur
>> after all modifiers (which include declaration annotations)".
>
> I agree we can't fix the Java 5 mix-up. The proposed rule sounds good.
>
>
>> I personally remain to be convinced that this rule is necessary.
>
> Allowing the TYPE_USE annotations not right in front of the variable or
> return type is even more absurd if the type is an array or qualified type:
>
> // Allowed (should be disallowed):
> @NonNull final String s2 = new @NonNull String();
>
> // The @NonNull annotates "String", not the whole return type "String[]":
> @NonNull final String[] s3 = new @NonNull String[] { };
>
> // Not allowed (annotation on package "java"):
> @NonNull final java.lang.String s4 = new @NonNull String();
>
> // What the user meant:
> final java.lang. at NonNull String s5 = new @NonNull String();
>
>
> I don't see any practical value in allowing TYPE_USE annotations to show up
> in front of other modifiers, but there's a clear reduction of confusion if
> they are only allowed at the end of the modifiers list.
>
> The compiler currently doesn't care much about the position of the
> annotations because it only marginally processes the annotations (for code
> generation). On the other hand, every tool that processes annotations is
> also affected by the torn-apart type references, since the AST becomes
> irregular.
>
> For refactoring tools, fetching the information from everywhere is a mess,
> and trivial rewrite operations like qualifying a type reference (compare s2
> with s4) need much more logic than necessary. For users who have to read or
> manually refactor such code, it's an even bigger mess.
>
> Since "conventions" in the JLS are not binding, they are not a big help in
> practice. Conventions are fine to help users avoid bugs from earlier
> versions of the spec. But a new spec should not contain new conventions if
> it's trivial to just set a standard and avoid digressions.
>
> Let's list the arguments:
>
> Pro rule:
> * Easier to understand for everybody
> * Easier to process by tools and humans that refactor code
> * If necessary, rule can be relaxed later; but it cannot be added later
>
> Contra rule:
> * Source code incompatibility with pre-Java-8 hacks that use
> declaration annotations to stand for type annotations.
> => When an annotation becomes a TYPE_USE annotation, existing code needs
> to be massaged anyway. As the examples above show, the pre-Java-8 hacks are
> incompatible with Java 8 anyway. I'd even declare it a feature that users
> are forced to make a pass over their source in that case.
> * Rule cannot be implemented by the parser since the grammar is ambiguous.
> The grammar cannot be fixed, since the parser cannot distinguish TYPE_USE
> from other annotations in these cases (the parser did not resolve the
> @Target yet). The rule needs to be enforced at a later compilation step.
> * Rule needs to be implemented
>
More information about the type-annotations-spec-observers
mailing list