Skip to content

Improve kotlinx.reflect.lite and rewrite it to use kotlinx.metadata.jvm under the hood #12

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

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,17 @@

## 1.1.0 (TBD)

* Add CallableMetadata.returnType
* Support property metadata with ClassMetadata.getProperty
* Allow to enumerate all declarations in a class with ClassMetadata.{functions,constructors,properties}
* Add CallableMetadata.{name,returnType,extensionReceiverType}
* Add FunctionMetadata.{isInline,isExternal,isOperator,isInfix,isSuspend}
* Add PropertyMetadata.{isLateinit,isConst}
* Add ClassMetadata.isData
* Add ClassMetadata.kind
* Add ConstructorMetadata.isPrimary
* Add DeclarationMetadata.visibility
* Add ParameterMetadata.hasDefaultValue
* Update to Kotlin 1.3

## 1.0.0 (Feb 15, 2016)

Expand Down
70 changes: 52 additions & 18 deletions ReadMe.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,55 @@
[![Kotlin](https://img.shields.io/badge/kotlin-1.0.0-blue.svg)](http://kotlinlang.org) [![Kotlin Slack](https://img.shields.io/badge/chat-kotlin%20slack-orange.svg)](http://kotlinslackin.herokuapp.com)

<a href="http://slack.kotlinlang.org/"><img src="http://slack.kotlinlang.org/badge.svg" height="20"></a>
[![GitHub license](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg?style=flat)](http://www.apache.org/licenses/LICENSE-2.0)
[![Download](https://api.bintray.com/packages/kotlin/kotlinx.reflect.lite/kotlinx.reflect.lite/images/download.svg)](https://bintray.com/kotlin/kotlinx.reflect.lite/kotlinx.reflect.lite/_latestVersion)

# kotlinx.reflect.lite

This library provides an API to introspect Kotlin symbols at runtime. Its main feature is the small size which makes it possible to use it on memory-constrained devices.
This library provides an API to introspect [Kotlin](https://kotlinlang.org) classes. Its main feature is the small size which makes it possible to use it on memory-constrained devices.

## Example

[ ![Download](https://api.bintray.com/packages/kotlin/kotlinx.reflect.lite/kotlinx.reflect.lite/images/download.svg) ](https://bintray.com/kotlin/kotlinx.reflect.lite/kotlinx.reflect.lite/_latestVersion)
Here's an example that outputs names of declarations in a Kotlin class, along with the names of their parameters:
```
import kotlinx.reflect.lite.ReflectionLite

class Example(val p: String) {
fun sum(x: Int, y: Int) = x + y
fun product(x: Double, y: Double) = x + y
fun <T> first(list: List<T>): T = list[0]
}

fun main(args: Array<String>) {
val metadata = ReflectionLite.loadClassMetadata(Example::class.java)!!
for (function in metadata.functions) {
println("function ${function.name} (${function.parameters.joinToString { p -> "${p.name}" }})")
}
for (constructor in metadata.constructors) {
println("constructor (${constructor.parameters.joinToString { p -> "${p.name}" }})")
}
for (property in metadata.properties) {
println("property ${property.name}")
}
}
```

Output:
```
function first (list)
function product (x, y)
function sum (x, y)
constructor (p)
property p
```

## How to use

To introspect a Kotlin class, use one of the methods in [`ReflectionLite.loadClassMetadata](https://github.com/Kotlin/kotlinx.reflect.lite/blob/master/src/main/java/kotlinx/reflect/lite/ReflectionLite.kt) to load metadata from a Java reflection Class object.

[ClassMetadata](https://github.com/Kotlin/kotlinx.reflect.lite/blob/master/src/main/java/kotlinx/reflect/lite/ClassMetadata.kt) allows to introspect Kotlin-specific features of the class, as well as its members. Explore [the available API](https://github.com/Kotlin/kotlinx.reflect.lite/tree/master/src/main/java/kotlinx/reflect/lite) for more details.

## Maven

Add jcenter repository (if you don't have it yet)
Add the jcenter repository:

```xml
<repository>
Expand All @@ -22,46 +62,40 @@ Add jcenter repository (if you don't have it yet)
</repository>
```

Add a dependency:
Add the dependency:

```xml
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx.reflect.lite</artifactId>
<version>1.0.0</version>
<version>1.1.0</version>
</dependency>
```

## Gradle

jcenter is configured by default in gradle however you may need to include it in some cases
jcenter is configured by default in Gradle, however you may need to include it manually in some cases:

```groovy
repositories {
jcenter()
}
```

Add a dependency:
Add the dependency:

```groovy
compile 'org.jetbrains.kotlinx:kotlinx.reflect.lite:1.0.0'
compile 'org.jetbrains.kotlinx:kotlinx.reflect.lite:1.1.0'
```

## FAQ

#### Why not just use Java reflection instead?

Java reflection cannot figure out Kotlin-specific features of the introspected program. For example, nullability of Kotlin types is erased in JVM bytecode.

Also parameter names were not supported in Java reflection until Java 8.
Java reflection cannot figure out Kotlin-specific features of the introspected program. There's a lot of information that cannot be easily represented in the JVM bytecode format: for example, nullability of Kotlin types, or different Kotlin modifiers (`data`, `lateinit`, `suspend`, ...), etc.

#### Why not just use Kotlin reflection instead?

While Kotlin has its own reflection library, its size is currently above 2Mb which may be unacceptable in some circumstances, for example on Android.

The size of the minimized version of this library is about 100Kb plus the dependency on protobuf-java.

#### What is supported?

Currently the only supported features are names of parameters and nullability of their types.
The size of the minimized version of this library is about 216Kb.
15 changes: 0 additions & 15 deletions copy.sh

This file was deleted.

62 changes: 58 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@

<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx.reflect.lite</artifactId>
<version>1.0.1</version>
<version>1.1.0</version>
<packaging>jar</packaging>
<url>https://github.com/Kotlin/kotlinx.reflect.lite</url>

<properties>
<kotlin.version>1.0.3</kotlin.version>
<kotlin.version>1.3.50</kotlin.version>
<junit.version>4.12</junit.version>
<protobuf.version>2.5.0</protobuf.version>
<proguard.plugin.version>2.0.11</proguard.plugin.version>
<protobuf.version>2.6.1</protobuf.version>
<proguard.plugin.version>2.0.14</proguard.plugin.version>
<kotlinx.metadata.version>0.1.0</kotlinx.metadata.version>

<kotlin.compiler.incremental>true</kotlin.compiler.incremental>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
Expand All @@ -36,6 +39,11 @@
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-metadata-jvm</artifactId>
<version>${kotlinx.metadata.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
Expand All @@ -44,6 +52,14 @@
</dependency>
</dependencies>

<repositories>
<repository>
<id>bintray-kotlin-kotlinx</id>
<name>bintray</name>
<url>https://kotlin.bintray.com/kotlinx</url>
</repository>
</repositories>

<build>
<plugins>
<plugin>
Expand Down Expand Up @@ -92,6 +108,35 @@
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<dependencyReducedPomLocation>${project.build.directory}/dependency-reduced-pom.xml</dependencyReducedPomLocation>
<artifactSet>
<excludes>
<exclude>org.jetbrains.kotlin:kotlin-stdlib</exclude>
<exclude>org.jetbrains:annotations</exclude>
</excludes>
</artifactSet>
<relocations>
<relocation>
<pattern>com.google.protobuf</pattern>
<shadedPattern>kotlinx.reflect.lite.protobuf</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>

<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
Expand All @@ -118,6 +163,15 @@
</execution>
</executions>
</plugin>

<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>

Expand Down
3 changes: 3 additions & 0 deletions reflect-lite.pro
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
}

-keepattributes *Annotation*
-keeppackagenames

#-dontshrink
#-dontoptimize
#-dontobfuscate

-dontnote
Loading