Skip to content

Commit

Permalink
Class, method, and constructor declarations (#307)
Browse files Browse the repository at this point in the history
* Function declarations

* Fix top-level functions

* Constructor support + some code cleanup

* Commit test changes

* fix duplicated super calls in default constructors

* Generify InvocationExprent parameter removal

* Completely redo kotlin annotation declarations (again)

* Update metadata

* Add `override` guessing and context receivers

* Kotlin's Contracts!

* Minor code cleanup

* Update from upstream changes

* Update contract test

* Fix constructor oddities

* Commit constructor test changes

* Import InvocationKind

* Fix some bugs with suspend functions and odd constructor oddities

* Trim metadata jar + fix Kotlin test

* Fix a handful of missing method issues and clarify error

* Fix a contract issue with receiver types
  • Loading branch information
sschr15 authored Jan 21, 2024
1 parent 9dc14fc commit 773cd96
Show file tree
Hide file tree
Showing 63 changed files with 3,990 additions and 2,573 deletions.
Binary file modified plugins/kotlin/libs/metadata.jar
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
package org.vineflower.kotlin;

import kotlin.reflect.jvm.internal.impl.metadata.ProtoBuf;
import kotlin.reflect.jvm.internal.impl.metadata.jvm.JvmProtoBuf;
import kotlin.reflect.jvm.internal.impl.protobuf.ExtensionRegistryLite;
import kotlinx.metadata.internal.metadata.ProtoBuf;
import kotlinx.metadata.internal.metadata.jvm.JvmProtoBuf;
import kotlinx.metadata.internal.protobuf.ExtensionRegistryLite;
import org.jetbrains.java.decompiler.api.plugin.LanguageChooser;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger;
import org.jetbrains.java.decompiler.util.Key;
import org.vineflower.kotlin.metadata.BitEncoding;
import org.jetbrains.java.decompiler.modules.decompiler.exps.AnnotationExprent;
import org.jetbrains.java.decompiler.modules.decompiler.exps.ConstExprent;
import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent;
import org.jetbrains.java.decompiler.modules.decompiler.exps.NewExprent;
import org.jetbrains.java.decompiler.struct.StructClass;
import org.jetbrains.java.decompiler.struct.attr.StructAnnotationAttribute;
import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute;
import org.jetbrains.java.decompiler.util.Key;
import org.vineflower.kotlin.metadata.BitEncoding;
import org.vineflower.kotlin.metadata.MetadataNameResolver;

import java.io.ByteArrayInputStream;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.vineflower.kotlin;

import kotlin.reflect.jvm.internal.impl.metadata.ProtoBuf;
import kotlinx.metadata.internal.metadata.ProtoBuf;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.util.Key;
import org.vineflower.kotlin.metadata.MetadataNameResolver;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
package org.vineflower.kotlin;

import org.jetbrains.java.decompiler.main.ClassesProcessor;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.collectors.ImportCollector;
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor;
import org.jetbrains.java.decompiler.struct.StructContext;
import org.jetbrains.java.decompiler.util.TextBuffer;
import org.vineflower.kotlin.util.KTypes;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class KotlinImportCollector {
private static final String[] AUTO_KOTLIN_IMPORTS = {
public class KotlinImportCollector extends ImportCollector {
public static final String[] AUTO_KOTLIN_IMPORTS = {
"annotation",
"collections",
"comparisons",
Expand All @@ -17,45 +26,48 @@ public class KotlinImportCollector {
"text",
};

private final ImportCollector parent;

public KotlinImportCollector(ImportCollector parent) {
this.parent = parent;
}
super(parent);

public void writeImports(TextBuffer buffer, boolean addSeparator) {
TextBuffer buf = new TextBuffer();
parent.writeImports(buf, false);
String[] imports = buf.convertToStringAndAllowDataDiscard().split("\n");
boolean imported = false;
for (String line : imports) {
if (line.isBlank()) {
continue;
}
line = line.trim();
String importLine = line.substring(7, line.length() - 1);
String[] parts = importLine.split("\\.");

// Don't include automatic kotlin imports
if (parts.length == 2 && parts[0].equals("kotlin")) {
continue;
} else if (parts.length == 3 && parts[0].equals("kotlin") && Arrays.binarySearch(AUTO_KOTLIN_IMPORTS, parts[1]) >= 0) {
continue;
// Any class that Kotlin "overrides" requires explicit non-imported references
for (String className : KTypes.KOTLIN_TO_JAVA_LANG.keySet()) {
String simpleName = className.substring(className.lastIndexOf('/') + 1);
String packageName = className.substring(0, className.lastIndexOf('/')).replace('/', '.');
if (!mapSimpleNames.containsKey(simpleName)) {
mapSimpleNames.put(simpleName, packageName);
}
}

buffer.append("import ");
boolean first = true;
for (String part : parts) {
if (!first) {
buffer.append(".");
}
first = false;
buffer.append(KotlinWriter.toValidKotlinIdentifier(part));
for (String className : KTypes.KOTLIN_TO_JAVA_UTIL.keySet()) {
String simpleName = className.substring(className.lastIndexOf('/') + 1);
String packageName = className.substring(0, className.lastIndexOf('/')).replace('/', '.');
if (!mapSimpleNames.containsKey(simpleName)) {
mapSimpleNames.put(simpleName, packageName);
}
buffer.appendLineSeparator();
imported = true;
}
if (imported && addSeparator) {
}

@Override
protected boolean keepImport(Map.Entry<String, String> ent) {
if (!super.keepImport(ent)) return false;
if (ent.getValue().equals("kotlin")) return false;
for (String autoImport : AUTO_KOTLIN_IMPORTS) {
if (ent.getValue().equals("kotlin." + autoImport)) return false;
}
return true;
}

@Override
public void writeImports(TextBuffer buffer, boolean addSeparator) {
if (DecompilerContext.getOption(IFernflowerPreferences.REMOVE_IMPORTS)) {
return;
}

List<String> imports = packImports();
for (String imp : imports) {
buffer.append("import ").append(imp).appendLineSeparator();
}
if (addSeparator && !imports.isEmpty()) {
buffer.appendLineSeparator();
}
}
Expand Down
Loading

0 comments on commit 773cd96

Please sign in to comment.