Is there some decompiler for Kotlin files that decompile into kotlin *.kt files
Asked Answered
M

2

12

I try to learn how to decompile Android program(APK) and found this site Decompilers online . It´s working grate for java code but when there are Kotlin files code the decompiler produces java code and it mixes Kotlin and java.

Here's what I see from the file ColorCircle.kt. As you see Kotlin Lazy is there and other Kotlin code. My questions are: Is there some other decompiler for Kotlin files that decompile into kotlin *.kt files?
Can I have Kotlin imports in *.java files without problems?

package io.coolbe.vai.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import io.coolbe.vai.C1300R;
import java.util.HashMap;
import kotlin.Lazy;
import kotlin.Metadata;
import kotlin.jvm.functions.Function0;
import kotlin.jvm.internal.Intrinsics;
import kotlin.jvm.internal.PropertyReference1Impl;
import kotlin.jvm.internal.Reflection;
import kotlin.reflect.KProperty;
import org.jetbrains.annotations.NotNull;

@Metadata(bv = {1, 0, 3}, d1 = {"\u0000>\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0010\u0007\n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0002\b\u0005\n\u0002\u0010\b\n\u0002\b\u0002\n\u0002\u0010\u0002\n\u0000\n\u0002\u0018\u0002\n\u0000\u0018\u00002\u00020\u0001B\u000f\b\u0016\u0012\u0006\u0010\u0002\u001a\u00020\u0003¢\u0006\u0002\u0010\u0004B\u0017\b\u0016\u0012\u0006\u0010\u0002\u001a\u00020\u0003\u0012\u0006\u0010\u0005\u001a\u00020\u0006¢\u0006\u0002\u0010\u0007J\u0010\u0010\u0014\u001a\u00020\u00152\u0006\u0010\u0016\u001a\u00020\u0017H\u0014R\u000e\u0010\b\u001a\u00020\tX\u000e¢\u0006\u0002\n\u0000R\u000e\u0010\n\u001a\u00020\tX\u000e¢\u0006\u0002\n\u0000R\u001b\u0010\u000b\u001a\u00020\f8BX\u0002¢\u0006\f\n\u0004\b\u000f\u0010\u0010\u001a\u0004\b\r\u0010\u000eR\u000e\u0010\u0011\u001a\u00020\u0012X\u000e¢\u0006\u0002\n\u0000R\u000e\u0010\u0013\u001a\u00020\tX\u000e¢\u0006\u0002\n\u0000¨\u0006\u0018"}, d2 = {"Lio/coolbe/vai/view/ColoredCircle;", "Landroid/view/View;", "context", "Landroid/content/Context;", "(Landroid/content/Context;)V", "attrs", "Landroid/util/AttributeSet;", "(Landroid/content/Context;Landroid/util/AttributeSet;)V", "offsetX", "", "offsetY", "paint", "Landroid/graphics/Paint;", "getPaint", "()Landroid/graphics/Paint;", "paint$delegate", "Lkotlin/Lazy;", "strokeColor", "", "strokeWidth", "onDraw", "", "canvas", "Landroid/graphics/Canvas;", "app_release"}, k = 1, mv = {1, 1, 13})
/* compiled from: ColoredCircle.kt */
public final class ColoredCircle extends View {
    static final /* synthetic */ KProperty[] $$delegatedProperties = new KProperty[]{Reflection.property1(new PropertyReference1Impl(Reflection.getOrCreateKotlinClass(ColoredCircle.class), "paint", "getPaint()Landroid/graphics/Paint;"))};
    private HashMap _$_findViewCache;
    private float offsetX;
    private float offsetY;
    private final Lazy paint$delegate;
    private int strokeColor;
    private float strokeWidth;

    private final Paint getPaint() {
        Lazy lazy = this.paint$delegate;
        KProperty kProperty = $$delegatedProperties[0];
        return (Paint) lazy.getValue();
    }

    public vaid _$_clearFindViewByIdCache() {
        HashMap hashMap = this._$_findViewCache;
        if (hashMap != null) {
            hashMap.clear();
        }
    }

    public View _$_findCachedViewById(int i) {
        if (this._$_findViewCache == null) {
            this._$_findViewCache = new HashMap();
        }
        View view = (View) this._$_findViewCache.get(Integer.valueOf(i));
        if (view != null) {
            return view;
        }
        view = findViewById(i);
        this._$_findViewCache.put(Integer.valueOf(i), view);
        return view;
    }

    public ColoredCircle(@NotNull Context context) {
        Intrinsics.checkParameterIsNotNull(context, "context");
        super(context);
        this.strokeColor = -7829368;
        this.strokeWidth = 10.0f;
        this.paint$delegate = LazyKt__LazyJVMKt.lazy((Function0) new ColoredCircle$paint$2(this));
    }

    public ColoredCircle(@NotNull Context context, @NotNull AttributeSet attributeSet) {
        Intrinsics.checkParameterIsNotNull(context, "context");
        Intrinsics.checkParameterIsNotNull(attributeSet, "attrs");
        super(context, attributeSet);
        this.strokeColor = -7829368;
        this.strokeWidth = 10.0f;
        this.paint$delegate = LazyKt__LazyJVMKt.lazy(new ColoredCircle$paint$2(this));
        context = context.getTheme().obtainStyledAttributes(attributeSet, C1300R.styleable.ColoredCircle, 0, 0);
        try {
            this.offsetX = context.getDimension(0, this.offsetX);
            this.offsetY = context.getDimension(1, this.offsetY);
            this.strokeColor = context.getColor(2, this.strokeColor);
            this.strokeWidth = context.getDimension(3, this.strokeWidth);
        } finally {
            context.recycle();
        }
    }

    protected vaid onDraw(@NotNull Canvas canvas) {
        Intrinsics.checkParameterIsNotNull(canvas, "canvas");
        super.onDraw(canvas);
        float f = (float) getLayoutParams().width;
        float f2 = (float) getLayoutParams().height;
        float f3 = (float) 2;
        float min = (Math.min(f, f2) / f3) - (this.strokeWidth / f3);
        canvas.save();
        canvas.translate(this.offsetX, this.offsetY);
        canvas.drawCircle(f / f3, f2 / f3, min, getPaint());
        canvas.restore();
    }
}
Moisten answered 11/3, 2019 at 7:10 Comment(3)
It doesn't mix Kotlin and Java, it's just that Kotlin uses some bytecode magic to make some of its features work, and this usually results in nonsense code when decompiling.Fabien
Possible duplicate of Kotlin Decompiler generates erroneous code - Is it possible to prevent?Fabien
In the code sample in my question there are both Kotlin and Java mixed?!Moisten
E
7

Is there som other decompiler for Kotlin files that decompile into kotlin *.kt files?

Currently, there is no "comfortable" decompiler to do .class -> .kt.

There are several famous decompiler do .class -> .java, but they just suits for the bytecode Java compiler generated. If you try to use them for decompile some bytecode generated by Kotlin, you can see something weird even errorness. This is caused by some tricks used to write and compile Kotlin.

Then, in most of the time, you can't use the decompiler output directly.

Can I have Kotlin imports in *.java files without problems?

This is a question related to the "100% interoperable with the Java". Kotlin can be imported in a .java file nearly without problems (I am not sure if there will be questions when we pass Java Lambda into Kotlin, but the common way of function calling is surely no problems).

Emulsify answered 11/3, 2019 at 8:2 Comment(2)
Hi, 3 years has passed, so I wonder whether there is such compiler now? Thanks!Batholith
@Batholith In my test, the main Java decompilers, like JD-GUI, JaDX or FernFlower, still supports Kotlin poor like 3 years ago. IDEA builtin decompiler shows "demangled" function signatures, but doesn't show the compiled code of method body. Some personal effort like GitHub: Earthcomputer/kotlin-decompiler may do something great, however I can't test it, because I didn't compile that successfully due to the proxy of company.Emulsify
L
0

This can be accomplished now, though its not perfect. I was able to do this using Vineflower which is a fork of Fernflower. The only quirk I encountered was it saving Kotlin code in .java files, but as far as I could tell it was otherwise correct. It's not as reliable as jd-gui but it's an excellent starting point.

Example usage:

$ mkdir out
$ java -jar vineflower.jar example.jar out/

At the time of writing, Kotlin decompilation is enabled by default (--kt-decompile-kotlin).

Longsighted answered 16/8, 2024 at 3:28 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.