-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create documentation for the Kotlin Metadata JVM library #4675
base: master
Are you sure you want to change the base?
Conversation
docs/topics/metadata-jvm.md
Outdated
@@ -0,0 +1,399 @@ | |||
[//]: # (title: Kotlin Metadata JVM library) | |||
|
|||
The [`kotlinx-metadata-jvm`](https://github.com/JetBrains/kotlin/tree/master/libraries/kotlinx-metadata/jvm) library provides tools to read, modify, and generate metadata from Kotlin classes compiled for the JVM. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and further: the library is called kotlin-metadata-jvm
, without X
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to kotlin-metadata-jvm everywhere
docs/topics/metadata-jvm.md
Outdated
|
||
The [`kotlinx-metadata-jvm`](https://github.com/JetBrains/kotlin/tree/master/libraries/kotlinx-metadata/jvm) library provides tools to read, modify, and generate metadata from Kotlin classes compiled for the JVM. | ||
This metadata, stored in the [`@Metadata`](https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-metadata/) annotation within `.class` files, | ||
is used by libraries and tools to inspect Kotlin-specific constructs such as properties, functions, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would emphasise here that it is also used by Kotlin-reflect, and this is why it is important to keep it consistent with what is written in the class file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds like a good idea I like it:
How about modifying it like:
This metadata, stored in the @Metadata
annotation within .class
files,
is used by libraries and tools, such as kotlin-reflect
, to inspect Kotlin-specific constructs such as properties, functions,
and classes at runtime.
The
kotlin-reflect
library relies on metadata to retrieve Kotlin-specific class details at runtime.
Any inconsistencies between the metadata and the actual.class
file may lead to incorrect behavior when using reflection.
{style="note"}
docs/topics/metadata-jvm.md
Outdated
This metadata, stored in the [`@Metadata`](https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-metadata/) annotation within `.class` files, | ||
is used by libraries and tools to inspect Kotlin-specific constructs such as properties, functions, | ||
and classes at runtime. | ||
You can also use this library to adjust attributes for binary compatibility validation or to generate and embed metadata into `.class` files. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Binary compatibility validator does not 'adjust' attributes, it simply reads modifiers. What did you mean here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice catch thank you, I originally had something about ASM here but without it doesn't work. 😟
How about:
You can also use the Kotlin Metadata JVM library to read and analyze metadata for binary compatibility checks or to generate and embed metadata into .class
files.
|
||
## Add the library to your project | ||
|
||
To include the Kotlin Metadata JVM library in your project, add the appropriate dependency configuration based on your build tool. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd also would mention explicitly that it has the same version as kotlin-stdlib and Kotlin compiler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, added this line:
The Kotlin Metadata JVM library follows the same versioning as the Kotlin compiler and standard library. Ensure that the version you use matches your project's Kotlin version.
docs/topics/metadata-jvm.md
Outdated
|
||
```kotlin | ||
// Imports the necessary library | ||
import kotlin.Metadata |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kotlin.Metadata
is located in the standard library, so I'm not sure if 'Imports the necessary library' line is relevant here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point - tested it without and it works - removed this import from everywhere
docs/topics/metadata-jvm.md
Outdated
## Modify metadata | ||
|
||
You can use the `kotlinx-metadata-jvm` library to modify Kotlin class metadata, allowing you to adjust visibility attributes, | ||
remove specific declarations, or prepare metadata for binary compatibility checks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prepare metadata for binary compatibility checks
— also seems not related, see my explanation about BCV
|
||
You can use the `kotlinx-metadata-jvm` library to modify Kotlin class metadata, allowing you to adjust visibility attributes, | ||
remove specific declarations, or prepare metadata for binary compatibility checks. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would also emphasize that modifying metadata is essential if you modify the bytecode in certain ways.
Given that you already have the example of removing private functions, you can write something like this:
"The main goal of modifying metadata is that it should be consistent with existing bytecode. For example, if you are writing a tool like ProGuard, which shrinks the code and may delete some declarations, you have to delete the same declarations from the metadata as well. Let us imagine that we have a JVM tool that deletes private methods from .class files. For that tool to work with Kotlin, it would also have to delete private methods from metadata, which can be done the following way:"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great suggestion, thank you! 💯
I restructured the section a little
e.printStackTrace() | ||
} | ||
} | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can also mention that for readStrict/write
pair there is a convenient transform
shortcut: https://kotlinlang.org/api/kotlinx-metadata-jvm/kotlin-metadata-jvm/kotlin.metadata.jvm/-kotlin-class-metadata/-companion/transform.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice one - thank you! - I added it as a tip
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use the
transform()
function instead of separately callingreadStrict()
andwrite()
separately.
This function parses metadata, applies transformations via a lambda, and writes the modified metadata automatically.
{style="tip"}
These functions allow you to extract detailed information about classes or files, while addressing different compatibility requirements: | ||
|
||
* `readLenient()`: Use this function to read metadata, including metadata generated by newer Kotlin compiler versions. However, it doesn't support modifying or writing metadata. | ||
* `readStrict()`: Use this function when you need to modify and write metadata. The `readStrict()` function only works with metadata generated by Kotlin compiler versions fully supported by your project. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd also add a link somewhere to the 'Detailed explanation' section of the README in case someone would like to know more about future versions handling
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added it to the note below 👍
|
||
## What's next | ||
|
||
* [See the API reference for the Kotlin Metadata JVM library](https://kotlinlang.org/api/kotlinx-metadata-jvm/). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe mention 'Module metadata' section of the readme here? It seems lost for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added it like so - what do you think:
This PR is created to add new documentation for the Kotlin Metadata JVM library.
Related issue: KT-66421