3.2 KiB
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 binary API wasn't changed in a way that make this change binary incompatible.
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
InlineExposed
- 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
InlineExposed
Note that Kotlin visibility of a field exposed by
lateinitproperty is the visibility of it's 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