This method was introduced in c204e8fc67 "just in case" and was never
used. Therefore we're free to change its semantics and use it in all new
generated code (with API version >= 1.4), without even worrying that the
newly used API will leak from inline functions in stdlib when used with
an older API version. Since we agreed to change the type of thrown
exceptions to java.lang.NPE in KT-22275, invoke a new method
throwJavaNpe now which throws that exception instead of KNPE.
Note that the additional method that takes an exception message is still
unused and exists just in case we need to use it in the future. The new
method throwJavaNpe is public also "just in case" we need to invoke it
in the future; currently it's not invoked from the bytecode.
#KT-22275 In Progress
Kotlin Public API binary compatibility validation tool
This tool allows to dump binary API of a Kotlin library that is public in sense of Kotlin visibilities and ensure that the public binary API wasn't changed in a way that make this change binary incompatible.
How to run
Compile and run tests. CasesPublicAPITest verifies the tool itself,
and RuntimePublicAPITest dumps the public API of kotlin-stdlib,
kotlin-stdlib-jdk7/8, and kotlin-reflect jars,
which must be built beforehand with gradle. Use clean assemble tasks,
since the incremental compilation currently doesn't produce all the required output.
When substantial changes are made to the public API, it may be convenient to overwrite
the entire dump and compare changes later before committing: pass -Doverwrite.output=true
property to the test to do so.
Also you can use shared run configuration "Binary compatibility tests", which also overwrites the results when they differ.
What constitutes the public API
Classes
A class is considered to be effectively public if all of the following conditions are met:
- it has public or protected JVM access (
ACC_PUBLICorACC_PROTECTED) - it has one of the following visibilities in Kotlin:
- no visibility (means no Kotlin declaration corresponds to this compiled class)
- public
- protected
- internal, only in case if the class is annotated with
PublishedApi
- it isn't a local class
- it isn't a synthetic class with mappings for
whentableswitches ($WhenMappings) - it contains at least one effectively public member, in case if the class corresponds to a kotlin file with top-level members or a multifile facade
- in case if the class is a member in another class, it is contained in the effectively public class
- in case if the class is a protected member in another class, it is contained in the non-final class
Members
A member of the class (i.e. a field or a method) is considered to be effectively public if all of the following conditions are met:
-
it has public or protected JVM access (
ACC_PUBLICorACC_PROTECTED) -
it has one of the following visibilities in Kotlin:
- no visibility (means no Kotlin declaration corresponds to this class member)
- public
- protected
- internal, only in case if the class is annotated with
PublishedApi
Note that Kotlin visibility of a field exposed by
lateinitproperty is the visibility of its setter. -
in case if the member is protected, it is contained in non-final class
-
it isn't a synthetic access method for a private field
What makes an incompatible change to the public binary API
Class changes
For a class a binary incompatible change is:
- changing the full class name (including package and containing classes)
- changing the superclass, so that the class no longer has the previous superclass in the inheritance chain
- changing the set of implemented interfaces so that the class no longer implements interfaces it had implemented before
- changing one of the following access flags:
ACC_PUBLIC,ACC_PROTECTED,ACC_PRIVATE— lessening the class visibilityACC_FINAL— making non-final class finalACC_ABSTRACT— making non-abstract class abstractACC_INTERFACE— changing class to interface and vice versaACC_ANNOTATION— changing annotation to interface and vice versa
Class member changes
For a class member a binary incompatible change is:
- changing its name
- changing its descriptor (erased return type and parameter types for methods); this includes changing field to method and vice versa
- changing one of the following access flags:
ACC_PUBLIC,ACC_PROTECTED,ACC_PRIVATE— lessening the member visibilityACC_FINAL— making non-final field or method finalACC_ABSTRACT— making non-abstract method abstractACC_STATIC— changing instance member to static and vice versa