Preface: Kotlin 1.3 will be able to read metadata of .class files
produced by Kotlin 1.4 (see KT-25972). Also, to simplify implementation
and to improve diagnostic messages, we're going to advance JVM metadata
version to 1.4.0 in Kotlin 1.4, and would like to keep it in sync with
the compiler version thereafter. This presents a problem: in an unlikely
event that before releasing 1.4, we find out that the metadata-reading
implementation in 1.3 was incorrect, we'd like to be able to fix the bug
in that implementation and _forbid_ 1.3 from reading metadata of 1.4.
But prior to this commit the only way to do this was to advance the
metadata version, in this case to 1.5, and that breaks the
metadata/compiler version equivalence we'd like to keep.
The solution is to add another boolean flag to the class file, called
"strict metadata version semantics", which signifies that if this class
file has metadata version 1.X, then it can only be read by the compilers
of versions 1.X and greater. This flag effectively disables the smooth
migration scenario proposed in KT-25972 (as does increasing metadata
version by 2), and will be used only in hopeless situations as in the
case described above.
* The members of Result are isSuccess, isFailure, exceptionOrNull, getOrNull
* The rest of API is implemented via inline-only extensions
* There are two internal functions to hide detailed mechanics of an internal
Result.Failure class: createFailure and throwOnFailure
* Result.toString is explicit: either Success(v) or Failure(x)
See KT-26538
Otherwise we're not trying to load annotations on the parameter of the
property setter in MemberDeserializer.loadProperty.
Note that after this commit, we could now also assume that if
getter/setter is default, it has no annotations, and thus use
Annotations.EMPTY for default getter/setter in loadProperty. However,
this would cause reflection to work incorrectly on classes compiled by
an older Kotlin compiler, so we'll still try to load annotations on
default accessors for an indefinite time.
#KT-25499 Fixed
In MemberDeserializer.loadProperty, we incorrectly passed 0 to
getAnnotations when loading annotations on property accessors in case
the protobuf field getter_flags/setter_flags was not present. The
correct behavior, as described in metadata.proto, was to pass a special
"default accessor flags" value, constructed from the main property
flags. Otherwise in case there were annotations both on the property and
on the accessor (as in PropertyAndAccessor.kt) and the accessor was
otherwise default, we would assume that it had no annotations and would
not load them in compiler and reflection
#KT-25499 In Progress
<IMPL_SUFFIX> for method is a method signature hash,
if method value parameter types contain inline class types,
otherwise 'impl'.
Constructor methods are named as 'constructor-<IMPL_SUFFIX>'.
Synthesized 'box' and 'unbox' methods are named as
'<METHOD_NAME>-<IMPL_SUFFIX>'.
Erased implementations of overriding and non-overriding methods
are named as '<METHOD_NAME>-<IMPL_SUFFIX>'.
Fully specialized implementation of 'equals' will have a special suffix.
Minimize AnnotationsImpl to leave it usable in simple scenarios where
there's no use-site targeted annotations, and use TargetedAnnotations in
the only place in the frontend (AnnotationResolverImpl) where use-sites
were needed.
Also, delete kdoc on Annotations.isEmpty to prevent readers from putting
too much thought into how it works. With the exception of a few places
in the frontend where use-site targeted annotations are still accessed
via the Annotations object, it's now an implementation detail and users
(such as backends, IDE) should not care about them at all, and instead
should just deal with the correct element when processing annotations
After this commit, it's overridden only in AnnotationsImpl and
CompositeAnnotations.
Note that although FilteredAnnotations did have a non-trivial
implementation, that class was only used in circumstances where
annotations with use-site targets could not be of any use, so it's safe
to return empty list there now. One could argue that the new semantics
makes more sense: filter "standard" annotations, but don't touch those
with use-site targets because they are not applied to this element
directly, thus should likely not be affected by the filtering
Instead of returning the list of targeted annotations in
loadCallableAnnotations, add two separate methods to load annotations on
the backing field and on the delegate field of the property
Add PropertyDescriptor.backingField/delegateField to store annotations
on the field directly in an otherwise almost empty descriptor instance,
instead of storing them with use-sites in the corresponding property
descriptor. Instead of AnnotationWithTarget, create AnnotationDescriptor
instances in AnnotationSplitter. Change DescriptorRenderer to render
annotations on "related" declarations when needed, with the explicit
use-site target if applicable.
Most changes in diagnostic test data are related to the fact that
annotations which are known to have an incompatible use-site to the
declaration they're applied at (such as `@param:`-annotation on a
function), are now not loaded at all. It's fine because the code is
erroneous, so it doesn't really matter how do we load annotations with
invalid targets (some of this logic is also changed freely in subsequent
commits). Some changes are also explained by the fact that for example
an annotation on the property which is only applicable to FIELD is now
rendered with an explicit use-site target `@field:`, regardless of
whether it did have that use-site target syntactically or not.
Basically, after this change there's no point in calling
Annotations.getUseSiteTargetedAnnotations/getAllAnnotations anymore
because it's easier and more intuitive to just use Annotations of the
corresponding descriptor -- the backing / delegate field (introduced in
this commit) or the extension receiver / setter parameter (related
behavior was fixed in previous commits). Usages of
use-site-target-related methods will be refactored out in subsequent
commits
Make it possible to specify annotations of the setter parameter when
constructing the default setter via DescriptorFactory; pass the split
annotations in DescriptorResolver.resolvePropertySetterDescriptor
#KT-25500 Fixed
Note that this change brings an incompatibility: `Array<Foo>::class`
will be seen as `Foo::class` by the old deserializer. We consider this
OK because the compiler never had any logic that relied on reading class
literal arguments correctly (otherwise it wouldn't have worked because
it could only see `Array<*>::class` before this commit), and the support
of annotations on types in JVM reflection is only available in the
upcoming 1.3 release (KT-16795)
#KT-22069 Fixed
These three methods are conflicting with existing extensions,
thus the behavior might be changed when switching to JDK 11
Probably, it's worth revisiting our strategy here,
e.g. by blacklisting all new methods in
#KT-24974 Fixed
Suspend functions and callable references to suspend lambdas are already
supported.
Support callSuspendBy of suspend function of big arity.
#KT-24854: Fixed
Avoid name clashes in cases such as
inline class Login(val login: String)
inline class Password(val password: String)
fun validate(login: Login) { ... }
fun validate(password: Password) { ... }