typetools / typetools/checker-framework
Overriding methods should inherit annotations
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 1.1k
- Forks
- 440
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 134
Description
At the moment, the annotations on an overriding method are determined
independently of the annotations on the overridden method and the overriding
method is checked for correct behavioral subtyping.
This allows us to use the same defaulting scheme for all methods, making the
meaning of an un-annotated method uniform.
However, this also means that the annotation effort is higher than we might
want.
Consider a superclass that contains declaration and type annotations:
class Super {
@DA
@TA Object foo(@TB Object p) {...}
}
Let's assume these annotations do not correspond to the defaults for
those locations.
Now in a subclass we might want to override the method:
class Sub extends Super {
@Override
Object foo(Object p) {...}
}
This class will have normal defaulting applied, resulting in something like:
class Sub extends Super {
@DefaultDA
@Override
@DefaultTA Object foo(@DefaultTA Object p) {...}
}
The Checker Framework might now issue errors for three reasons:
-
incompatible method overriding, for the declaration annotation, if
@DefaultDAand@DAare incompatible. For example, if Super.foo is
declared@Pure, also the overriding method must be pure. -
incompatible return type, if
@DefaultTAis a
supertype of@TA. For example, if Super.foo returns@NonNullObject, the
overriding method may not default to@NullableObject.
Return types may only get "narrower", i.e. change covariantly. -
incompatible parameter type, if
@DefaultTAis a
subtype of@TB. For example, if Super.foo takes@NullableObject, the
overriding method may not default to@NonNullObject.
Parameter types may only get "wider", i.e. change contravariantly.
So far the Checker Framework philosophy was that the programmer must
make such annotations explicit to prevent any possible misunderstanding
in what the code actually means.
We could add an -AinheritAnnotations option, such that the defaulting for the
subclass would be changed to copy the annotations from an overridden method.
For example, the above unannotated code would be interpreted as:
class Sub extends Super {
@DA
@TA Object foo(@TB Object p) {...}
}
and the programmer doesn't have any annotation effort.
The potential downside is that the programmer might be confused by
error messages.
A few design considerations:
- Do we want to distinguish whether only declaration annotations are inherited
from whether type annotations are? - How does this feature interact with
@DefaultQualifiersin scope? - Can we make error messages depend on whether the annotation was
inherited?
Original issue reported on code.google.com by wdi...@gmail.com on 2 Dec 2013 at 3:35
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Review the proposed -AinheritAnnotations option and the defaulting and overriding behavior shown in the superclass and subclass examples. Resolve whether declaration and type annotations are inherited separately, how @DefaultQualifiers interacts, and whether diagnostics distinguish inherited annotations; the issue is done when these design questions have an agreed implementation and validation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100