Move common jvm classes from :core:descriptors.jvm to :core:compiler.common.jvm
This commit is contained in:
@@ -8,6 +8,7 @@ javaHome = rootProject.extra["JDK_16"] as String
|
||||
|
||||
dependencies {
|
||||
api(project(":core:compiler.common"))
|
||||
api(project(":core:metadata.jvm"))
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.builtins.jvm
|
||||
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents
|
||||
import org.jetbrains.kotlin.load.kotlin.signatures
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||
import java.io.Serializable
|
||||
import java.util.*
|
||||
|
||||
object JvmBuiltInsSignatures {
|
||||
val DROP_LIST_METHOD_SIGNATURES: Set<String> =
|
||||
SignatureBuildingComponents.inJavaUtil(
|
||||
"Collection",
|
||||
"toArray()[Ljava/lang/Object;", "toArray([Ljava/lang/Object;)[Ljava/lang/Object;"
|
||||
) + "java/lang/annotation/Annotation.annotationType()Ljava/lang/Class;"
|
||||
|
||||
val BLACK_LIST_METHOD_SIGNATURES: Set<String> =
|
||||
signatures {
|
||||
buildPrimitiveValueMethodsSet() +
|
||||
|
||||
inJavaUtil("List", "sort(Ljava/util/Comparator;)V") +
|
||||
|
||||
inJavaLang(
|
||||
"String",
|
||||
"codePointAt(I)I", "codePointBefore(I)I", "codePointCount(II)I", "compareToIgnoreCase(Ljava/lang/String;)I",
|
||||
"concat(Ljava/lang/String;)Ljava/lang/String;", "contains(Ljava/lang/CharSequence;)Z",
|
||||
"contentEquals(Ljava/lang/CharSequence;)Z", "contentEquals(Ljava/lang/StringBuffer;)Z",
|
||||
"endsWith(Ljava/lang/String;)Z", "equalsIgnoreCase(Ljava/lang/String;)Z", "getBytes()[B", "getBytes(II[BI)V",
|
||||
"getBytes(Ljava/lang/String;)[B", "getBytes(Ljava/nio/charset/Charset;)[B", "getChars(II[CI)V",
|
||||
"indexOf(I)I", "indexOf(II)I", "indexOf(Ljava/lang/String;)I", "indexOf(Ljava/lang/String;I)I",
|
||||
"intern()Ljava/lang/String;", "isEmpty()Z", "lastIndexOf(I)I", "lastIndexOf(II)I",
|
||||
"lastIndexOf(Ljava/lang/String;)I", "lastIndexOf(Ljava/lang/String;I)I", "matches(Ljava/lang/String;)Z",
|
||||
"offsetByCodePoints(II)I", "regionMatches(ILjava/lang/String;II)Z", "regionMatches(ZILjava/lang/String;II)Z",
|
||||
"replaceAll(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", "replace(CC)Ljava/lang/String;",
|
||||
"replaceFirst(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
|
||||
"replace(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;",
|
||||
"split(Ljava/lang/String;I)[Ljava/lang/String;", "split(Ljava/lang/String;)[Ljava/lang/String;",
|
||||
"startsWith(Ljava/lang/String;I)Z", "startsWith(Ljava/lang/String;)Z", "substring(II)Ljava/lang/String;",
|
||||
"substring(I)Ljava/lang/String;", "toCharArray()[C", "toLowerCase()Ljava/lang/String;",
|
||||
"toLowerCase(Ljava/util/Locale;)Ljava/lang/String;", "toUpperCase()Ljava/lang/String;",
|
||||
"toUpperCase(Ljava/util/Locale;)Ljava/lang/String;", "trim()Ljava/lang/String;",
|
||||
"isBlank()Z", "lines()Ljava/util/stream/Stream;", "repeat(I)Ljava/lang/String;"
|
||||
) +
|
||||
|
||||
inJavaLang("Double", "isInfinite()Z", "isNaN()Z") +
|
||||
inJavaLang("Float", "isInfinite()Z", "isNaN()Z") +
|
||||
|
||||
inJavaLang("Enum", "getDeclaringClass()Ljava/lang/Class;", "finalize()V")
|
||||
}
|
||||
|
||||
private fun buildPrimitiveValueMethodsSet(): Set<String> =
|
||||
signatures {
|
||||
listOf(JvmPrimitiveType.BOOLEAN, JvmPrimitiveType.CHAR).flatMapTo(LinkedHashSet()) {
|
||||
inJavaLang(it.wrapperFqName.shortName().asString(), "${it.javaKeywordName}Value()${it.desc}")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val WHITE_LIST_METHOD_SIGNATURES: Set<String> =
|
||||
signatures {
|
||||
inJavaLang(
|
||||
"CharSequence",
|
||||
"codePoints()Ljava/util/stream/IntStream;", "chars()Ljava/util/stream/IntStream;"
|
||||
) +
|
||||
|
||||
inJavaUtil(
|
||||
"Iterator",
|
||||
"forEachRemaining(Ljava/util/function/Consumer;)V"
|
||||
) +
|
||||
|
||||
inJavaLang(
|
||||
"Iterable",
|
||||
"forEach(Ljava/util/function/Consumer;)V", "spliterator()Ljava/util/Spliterator;"
|
||||
) +
|
||||
|
||||
inJavaLang(
|
||||
"Throwable",
|
||||
"setStackTrace([Ljava/lang/StackTraceElement;)V", "fillInStackTrace()Ljava/lang/Throwable;",
|
||||
"getLocalizedMessage()Ljava/lang/String;", "printStackTrace()V", "printStackTrace(Ljava/io/PrintStream;)V",
|
||||
"printStackTrace(Ljava/io/PrintWriter;)V", "getStackTrace()[Ljava/lang/StackTraceElement;",
|
||||
"initCause(Ljava/lang/Throwable;)Ljava/lang/Throwable;", "getSuppressed()[Ljava/lang/Throwable;",
|
||||
"addSuppressed(Ljava/lang/Throwable;)V"
|
||||
) +
|
||||
|
||||
inJavaUtil(
|
||||
"Collection",
|
||||
"spliterator()Ljava/util/Spliterator;", "parallelStream()Ljava/util/stream/Stream;",
|
||||
"stream()Ljava/util/stream/Stream;", "removeIf(Ljava/util/function/Predicate;)Z"
|
||||
) +
|
||||
|
||||
inJavaUtil(
|
||||
"List",
|
||||
"replaceAll(Ljava/util/function/UnaryOperator;)V"
|
||||
) +
|
||||
|
||||
inJavaUtil(
|
||||
"Map",
|
||||
"getOrDefault(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
|
||||
"forEach(Ljava/util/function/BiConsumer;)V", "replaceAll(Ljava/util/function/BiFunction;)V",
|
||||
"merge(Ljava/lang/Object;Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;",
|
||||
"computeIfPresent(Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;",
|
||||
"putIfAbsent(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
|
||||
"replace(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Z",
|
||||
"replace(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
|
||||
"computeIfAbsent(Ljava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object;",
|
||||
"compute(Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;"
|
||||
)
|
||||
}
|
||||
|
||||
val MUTABLE_METHOD_SIGNATURES: Set<String> =
|
||||
signatures {
|
||||
inJavaUtil("Collection", "removeIf(Ljava/util/function/Predicate;)Z") +
|
||||
|
||||
inJavaUtil("List", "replaceAll(Ljava/util/function/UnaryOperator;)V", "sort(Ljava/util/Comparator;)V") +
|
||||
|
||||
inJavaUtil(
|
||||
"Map",
|
||||
"computeIfAbsent(Ljava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object;",
|
||||
"computeIfPresent(Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;",
|
||||
"compute(Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;",
|
||||
"merge(Ljava/lang/Object;Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;",
|
||||
"putIfAbsent(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
|
||||
"remove(Ljava/lang/Object;Ljava/lang/Object;)Z", "replaceAll(Ljava/util/function/BiFunction;)V",
|
||||
"replace(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
|
||||
"replace(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Z"
|
||||
)
|
||||
}
|
||||
|
||||
val BLACK_LIST_CONSTRUCTOR_SIGNATURES: Set<String> =
|
||||
signatures {
|
||||
buildPrimitiveStringConstructorsSet() +
|
||||
inJavaLang("Float", *constructors("D")) +
|
||||
inJavaLang(
|
||||
"String", *constructors(
|
||||
"[C", "[CII", "[III", "[BIILjava/lang/String;",
|
||||
"[BIILjava/nio/charset/Charset;",
|
||||
"[BLjava/lang/String;",
|
||||
"[BLjava/nio/charset/Charset;",
|
||||
"[BII", "[B",
|
||||
"Ljava/lang/StringBuffer;",
|
||||
"Ljava/lang/StringBuilder;"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val WHITE_LIST_CONSTRUCTOR_SIGNATURES: Set<String> =
|
||||
signatures {
|
||||
inJavaLang("Throwable", *constructors("Ljava/lang/String;Ljava/lang/Throwable;ZZ"))
|
||||
}
|
||||
|
||||
private fun buildPrimitiveStringConstructorsSet(): Set<String> =
|
||||
signatures {
|
||||
listOf(
|
||||
JvmPrimitiveType.BOOLEAN, JvmPrimitiveType.BYTE, JvmPrimitiveType.DOUBLE, JvmPrimitiveType.FLOAT,
|
||||
JvmPrimitiveType.BYTE, JvmPrimitiveType.INT, JvmPrimitiveType.LONG, JvmPrimitiveType.SHORT
|
||||
).flatMapTo(LinkedHashSet()) {
|
||||
// java/lang/<Wrapper>.<init>(Ljava/lang/String;)V
|
||||
inJavaLang(it.wrapperFqName.shortName().asString(), *constructors("Ljava/lang/String;"))
|
||||
}
|
||||
}
|
||||
|
||||
fun isSerializableInJava(fqName: FqNameUnsafe): Boolean {
|
||||
if (isArrayOrPrimitiveArray(fqName)) {
|
||||
return true
|
||||
}
|
||||
val javaClassId = JavaToKotlinClassMap.mapKotlinToJava(fqName) ?: return false
|
||||
val classViaReflection = try {
|
||||
Class.forName(javaClassId.asSingleFqName().asString())
|
||||
} catch (e: ClassNotFoundException) {
|
||||
return false
|
||||
}
|
||||
return Serializable::class.java.isAssignableFrom(classViaReflection)
|
||||
}
|
||||
|
||||
fun isArrayOrPrimitiveArray(fqName: FqNameUnsafe): Boolean {
|
||||
return fqName == StandardNames.FqNames.array || StandardNames.isPrimitiveArray(fqName)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.load.java
|
||||
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaPackage
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
interface JavaClassFinder {
|
||||
data class Request(
|
||||
val classId: ClassId,
|
||||
@Suppress("ArrayInDataClass")
|
||||
val previouslyFoundClassFileContent: ByteArray? = null,
|
||||
val outerClass: JavaClass? = null
|
||||
)
|
||||
|
||||
fun findClass(request: Request): JavaClass?
|
||||
fun findClass(classId: ClassId): JavaClass? = findClass(Request(classId))
|
||||
|
||||
fun findPackage(fqName: FqName): JavaPackage?
|
||||
|
||||
fun knownClassNamesInPackage(packageFqName: FqName): Set<String>?
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.load.java;
|
||||
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
|
||||
|
||||
@SuppressWarnings("PointlessBitwiseExpression")
|
||||
public final class JvmAnnotationNames {
|
||||
public static final FqName METADATA_FQ_NAME = new FqName("kotlin.Metadata");
|
||||
public static final String METADATA_DESC = "L" + JvmClassName.byFqNameWithoutInnerClasses(METADATA_FQ_NAME).getInternalName() + ";";
|
||||
|
||||
public static final String METADATA_VERSION_FIELD_NAME = "mv";
|
||||
public static final String BYTECODE_VERSION_FIELD_NAME = "bv";
|
||||
public static final String KIND_FIELD_NAME = "k";
|
||||
public static final String METADATA_DATA_FIELD_NAME = "d1";
|
||||
public static final String METADATA_STRINGS_FIELD_NAME = "d2";
|
||||
public static final String METADATA_EXTRA_STRING_FIELD_NAME = "xs";
|
||||
public static final String METADATA_PACKAGE_NAME_FIELD_NAME = "pn";
|
||||
public static final String METADATA_MULTIFILE_CLASS_NAME_FIELD_NAME = METADATA_EXTRA_STRING_FIELD_NAME;
|
||||
public static final String METADATA_EXTRA_INT_FIELD_NAME = "xi";
|
||||
|
||||
public static final int METADATA_MULTIFILE_PARTS_INHERIT_FLAG = 1 << 0;
|
||||
public static final int METADATA_PRE_RELEASE_FLAG = 1 << 1;
|
||||
public static final int METADATA_SCRIPT_FLAG = 1 << 2;
|
||||
public static final int METADATA_STRICT_VERSION_SEMANTICS_FLAG = 1 << 3;
|
||||
public static final int METADATA_JVM_IR_FLAG = 1 << 4;
|
||||
public static final int METADATA_JVM_IR_STABLE_ABI_FLAG = 1 << 5;
|
||||
|
||||
public static final Name DEFAULT_ANNOTATION_MEMBER_NAME = Name.identifier("value");
|
||||
|
||||
public static final FqName JETBRAINS_NOT_NULL_ANNOTATION = new FqName("org.jetbrains.annotations.NotNull");
|
||||
public static final FqName JETBRAINS_NULLABLE_ANNOTATION = new FqName("org.jetbrains.annotations.Nullable");
|
||||
public static final FqName JETBRAINS_MUTABLE_ANNOTATION = new FqName("org.jetbrains.annotations.Mutable");
|
||||
public static final FqName JETBRAINS_READONLY_ANNOTATION = new FqName("org.jetbrains.annotations.ReadOnly");
|
||||
|
||||
public static final FqName READONLY_ANNOTATION = new FqName("kotlin.annotations.jvm.ReadOnly");
|
||||
public static final FqName MUTABLE_ANNOTATION = new FqName("kotlin.annotations.jvm.Mutable");
|
||||
|
||||
public static final FqName PURELY_IMPLEMENTS_ANNOTATION = new FqName("kotlin.jvm.PurelyImplements");
|
||||
|
||||
public static final FqName KOTLIN_JVM_INTERNAL = new FqName("kotlin.jvm.internal");
|
||||
|
||||
// Just for internal use: there is no such real classes in bytecode
|
||||
public static final FqName ENHANCED_NULLABILITY_ANNOTATION = new FqName("kotlin.jvm.internal.EnhancedNullability");
|
||||
public static final FqName ENHANCED_MUTABILITY_ANNOTATION = new FqName("kotlin.jvm.internal.EnhancedMutability");
|
||||
|
||||
public static final FqName PARAMETER_NAME_FQ_NAME = new FqName("kotlin.annotations.jvm.internal.ParameterName");
|
||||
public static final FqName DEFAULT_VALUE_FQ_NAME = new FqName("kotlin.annotations.jvm.internal.DefaultValue");
|
||||
public static final FqName DEFAULT_NULL_FQ_NAME = new FqName("kotlin.annotations.jvm.internal.DefaultNull");
|
||||
|
||||
private JvmAnnotationNames() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.load.java
|
||||
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
val NULLABLE_ANNOTATIONS: List<FqName> = listOf(
|
||||
JvmAnnotationNames.JETBRAINS_NULLABLE_ANNOTATION,
|
||||
FqName("androidx.annotation.Nullable"),
|
||||
FqName("android.support.annotation.Nullable"),
|
||||
FqName("android.annotation.Nullable"),
|
||||
FqName("com.android.annotations.Nullable"),
|
||||
FqName("org.eclipse.jdt.annotation.Nullable"),
|
||||
FqName("org.checkerframework.checker.nullness.qual.Nullable"),
|
||||
FqName("javax.annotation.Nullable"),
|
||||
FqName("javax.annotation.CheckForNull"),
|
||||
FqName("edu.umd.cs.findbugs.annotations.CheckForNull"),
|
||||
FqName("edu.umd.cs.findbugs.annotations.Nullable"),
|
||||
FqName("edu.umd.cs.findbugs.annotations.PossiblyNull"),
|
||||
FqName("io.reactivex.annotations.Nullable")
|
||||
)
|
||||
|
||||
val JAVAX_NONNULL_ANNOTATION: FqName = FqName("javax.annotation.Nonnull")
|
||||
val JAVAX_CHECKFORNULL_ANNOTATION: FqName = FqName("javax.annotation.CheckForNull")
|
||||
|
||||
val NOT_NULL_ANNOTATIONS: List<FqName> = listOf(
|
||||
JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION,
|
||||
FqName("edu.umd.cs.findbugs.annotations.NonNull"),
|
||||
FqName("androidx.annotation.NonNull"),
|
||||
FqName("android.support.annotation.NonNull"),
|
||||
FqName("android.annotation.NonNull"),
|
||||
FqName("com.android.annotations.NonNull"),
|
||||
FqName("org.eclipse.jdt.annotation.NonNull"),
|
||||
FqName("org.checkerframework.checker.nullness.qual.NonNull"),
|
||||
FqName("lombok.NonNull"),
|
||||
FqName("io.reactivex.annotations.NonNull")
|
||||
)
|
||||
|
||||
val COMPATQUAL_NULLABLE_ANNOTATION: FqName = FqName("org.checkerframework.checker.nullness.compatqual.NullableDecl")
|
||||
val COMPATQUAL_NONNULL_ANNOTATION: FqName = FqName("org.checkerframework.checker.nullness.compatqual.NonNullDecl")
|
||||
|
||||
val ANDROIDX_RECENTLY_NULLABLE_ANNOTATION: FqName = FqName("androidx.annotation.RecentlyNullable")
|
||||
val ANDROIDX_RECENTLY_NON_NULL_ANNOTATION: FqName = FqName("androidx.annotation.RecentlyNonNull")
|
||||
|
||||
val NULLABILITY_ANNOTATIONS: Set<FqName> = mutableSetOf<FqName>() +
|
||||
NULLABLE_ANNOTATIONS +
|
||||
JAVAX_NONNULL_ANNOTATION +
|
||||
NOT_NULL_ANNOTATIONS +
|
||||
COMPATQUAL_NULLABLE_ANNOTATION +
|
||||
COMPATQUAL_NONNULL_ANNOTATION +
|
||||
ANDROIDX_RECENTLY_NULLABLE_ANNOTATION +
|
||||
ANDROIDX_RECENTLY_NON_NULL_ANNOTATION
|
||||
|
||||
val READ_ONLY_ANNOTATIONS: List<FqName> = listOf(
|
||||
JvmAnnotationNames.JETBRAINS_READONLY_ANNOTATION,
|
||||
JvmAnnotationNames.READONLY_ANNOTATION
|
||||
)
|
||||
|
||||
val MUTABLE_ANNOTATIONS: List<FqName> = listOf(
|
||||
JvmAnnotationNames.JETBRAINS_MUTABLE_ANNOTATION,
|
||||
JvmAnnotationNames.MUTABLE_ANNOTATION
|
||||
)
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.load.java.typeEnhancement
|
||||
|
||||
enum class TypeComponentPosition {
|
||||
FLEXIBLE_LOWER,
|
||||
FLEXIBLE_UPPER,
|
||||
INFLEXIBLE
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.load.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.serialization.deserialization.KotlinMetadataFinder
|
||||
|
||||
interface KotlinClassFinder : KotlinMetadataFinder {
|
||||
fun findKotlinClassOrContent(classId: ClassId): Result?
|
||||
|
||||
fun findKotlinClassOrContent(javaClass: JavaClass): Result?
|
||||
|
||||
sealed class Result {
|
||||
fun toKotlinJvmBinaryClass(): KotlinJvmBinaryClass? = (this as? KotlinClass)?.kotlinJvmBinaryClass
|
||||
|
||||
class KotlinClass(val kotlinJvmBinaryClass: KotlinJvmBinaryClass, val byteContent: ByteArray? = null) : Result() {
|
||||
operator fun component1(): KotlinJvmBinaryClass = kotlinJvmBinaryClass
|
||||
operator fun component2(): ByteArray? = byteContent
|
||||
}
|
||||
|
||||
class ClassFileContent(
|
||||
@Suppress("ArrayInDataClass")
|
||||
val content: ByteArray
|
||||
) : Result()
|
||||
}
|
||||
}
|
||||
|
||||
fun KotlinClassFinder.findKotlinClass(classId: ClassId): KotlinJvmBinaryClass? =
|
||||
findKotlinClassOrContent(classId)?.toKotlinJvmBinaryClass()
|
||||
|
||||
fun KotlinClassFinder.findKotlinClass(javaClass: JavaClass): KotlinJvmBinaryClass? =
|
||||
findKotlinClassOrContent(javaClass)?.toKotlinJvmBinaryClass()
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.load.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.constants.ClassLiteralValue
|
||||
|
||||
interface KotlinJvmBinaryClass {
|
||||
val classId: ClassId
|
||||
|
||||
/**
|
||||
* @return path to the class file (to be reported to the user upon error)
|
||||
*/
|
||||
val location: String
|
||||
|
||||
fun loadClassAnnotations(visitor: AnnotationVisitor, cachedContents: ByteArray?)
|
||||
|
||||
fun visitMembers(visitor: MemberVisitor, cachedContents: ByteArray?)
|
||||
|
||||
val classHeader: KotlinClassHeader
|
||||
|
||||
interface MemberVisitor {
|
||||
// TODO: abstract signatures for methods and fields instead of ASM 'desc' strings?
|
||||
|
||||
fun visitMethod(name: Name, desc: String): MethodAnnotationVisitor?
|
||||
|
||||
fun visitField(name: Name, desc: String, initializer: Any?): AnnotationVisitor?
|
||||
}
|
||||
|
||||
interface AnnotationVisitor {
|
||||
fun visitAnnotation(classId: ClassId, source: SourceElement): AnnotationArgumentVisitor?
|
||||
|
||||
fun visitEnd()
|
||||
}
|
||||
|
||||
interface MethodAnnotationVisitor : AnnotationVisitor {
|
||||
fun visitParameterAnnotation(index: Int, classId: ClassId, source: SourceElement): AnnotationArgumentVisitor?
|
||||
}
|
||||
|
||||
interface AnnotationArgumentVisitor {
|
||||
fun visit(name: Name?, value: Any?)
|
||||
|
||||
fun visitClassLiteral(name: Name, value: ClassLiteralValue)
|
||||
|
||||
fun visitEnum(name: Name, enumClassId: ClassId, enumEntryName: Name)
|
||||
|
||||
fun visitAnnotation(name: Name, classId: ClassId): AnnotationArgumentVisitor?
|
||||
|
||||
fun visitArray(name: Name): AnnotationArrayArgumentVisitor?
|
||||
|
||||
fun visitEnd()
|
||||
}
|
||||
|
||||
interface AnnotationArrayArgumentVisitor {
|
||||
fun visit(value: Any?)
|
||||
|
||||
fun visitEnum(enumClassId: ClassId, enumEntryName: Name)
|
||||
|
||||
fun visitClassLiteral(value: ClassLiteralValue)
|
||||
|
||||
fun visitEnd()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.load.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
||||
import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMemberSignature
|
||||
|
||||
// The purpose of this class is to hold a unique signature of either a method or a field, so that annotations on a member can be put
|
||||
// into a map indexed by these signatures
|
||||
@Suppress("DataClassPrivateConstructor")
|
||||
data class MemberSignature private constructor(val signature: String) {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun fromMethod(nameResolver: NameResolver, signature: JvmProtoBuf.JvmMethodSignature): MemberSignature {
|
||||
return fromMethodNameAndDesc(nameResolver.getString(signature.name), nameResolver.getString(signature.desc))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun fromMethodNameAndDesc(name: String, desc: String): MemberSignature {
|
||||
return MemberSignature(name + desc)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun fromFieldNameAndDesc(name: String, desc: String): MemberSignature {
|
||||
return MemberSignature("$name#$desc")
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun fromJvmMemberSignature(signature: JvmMemberSignature): MemberSignature = when (signature) {
|
||||
is JvmMemberSignature.Method -> fromMethodNameAndDesc(signature.name, signature.desc)
|
||||
is JvmMemberSignature.Field -> fromFieldNameAndDesc(signature.name, signature.desc)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun fromMethodSignatureAndParameterIndex(signature: MemberSignature, index: Int): MemberSignature {
|
||||
return MemberSignature("${signature.signature}@$index")
|
||||
}
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.load.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import java.util.*
|
||||
|
||||
inline fun <T> signatures(block: SignatureBuildingComponents.() -> T) = with(SignatureBuildingComponents, block)
|
||||
|
||||
object SignatureBuildingComponents {
|
||||
fun javaLang(name: String): String = "java/lang/$name"
|
||||
fun javaUtil(name: String): String = "java/util/$name"
|
||||
fun javaFunction(name: String): String = "java/util/function/$name"
|
||||
|
||||
fun constructors(vararg signatures: String): Array<String> = signatures.map { "<init>($it)V" }.toTypedArray()
|
||||
|
||||
fun inJavaLang(name: String, vararg signatures: String): Set<String> = inClass(javaLang(name), *signatures)
|
||||
fun inJavaUtil(name: String, vararg signatures: String): Set<String> = inClass(javaUtil(name), *signatures)
|
||||
|
||||
fun inClass(internalName: String, vararg signatures: String): Set<String> = signatures.mapTo(LinkedHashSet()) { "$internalName.$it" }
|
||||
fun signature(classId: ClassId, jvmDescriptor: String): String = signature(classId.internalName, jvmDescriptor)
|
||||
fun signature(internalName: String, jvmDescriptor: String): String = "$internalName.$jvmDescriptor"
|
||||
|
||||
fun jvmDescriptor(name: String, parameters: List<String>, ret: String = "V"): String =
|
||||
"$name(${parameters.joinToString("") { escapeClassName(it) }})${escapeClassName(internalName = ret)}"
|
||||
|
||||
private fun escapeClassName(internalName: String): String = if (internalName.length > 1) "L$internalName;" else internalName
|
||||
}
|
||||
|
||||
val ClassId.internalName: String
|
||||
get() {
|
||||
return JvmClassName.byClassId(JavaToKotlinClassMap.mapKotlinToJava(asSingleFqName().toUnsafe()) ?: this).internalName
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.load.kotlin.header
|
||||
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader.MultifileClassKind.DELEGATING
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader.MultifileClassKind.INHERITING
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmBytecodeBinaryVersion
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
|
||||
|
||||
class KotlinClassHeader(
|
||||
val kind: Kind,
|
||||
val metadataVersion: JvmMetadataVersion,
|
||||
val bytecodeVersion: JvmBytecodeBinaryVersion,
|
||||
val data: Array<String>?,
|
||||
val incompatibleData: Array<String>?,
|
||||
val strings: Array<String>?,
|
||||
private val extraString: String?,
|
||||
val extraInt: Int,
|
||||
val packageName: String?
|
||||
) {
|
||||
// See kotlin.Metadata
|
||||
enum class Kind(val id: Int) {
|
||||
UNKNOWN(0),
|
||||
CLASS(1),
|
||||
FILE_FACADE(2),
|
||||
SYNTHETIC_CLASS(3),
|
||||
MULTIFILE_CLASS(4),
|
||||
MULTIFILE_CLASS_PART(5);
|
||||
|
||||
companion object {
|
||||
private val entryById = values().associateBy(Kind::id)
|
||||
|
||||
@JvmStatic
|
||||
fun getById(id: Int) = entryById[id] ?: UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
enum class MultifileClassKind {
|
||||
DELEGATING,
|
||||
INHERITING;
|
||||
}
|
||||
|
||||
val multifileClassName: String?
|
||||
get() = extraString.takeIf { kind == Kind.MULTIFILE_CLASS_PART }
|
||||
|
||||
val multifilePartNames: List<String>
|
||||
get() = data.takeIf { kind == Kind.MULTIFILE_CLASS }?.asList().orEmpty()
|
||||
|
||||
// TODO: use in incremental compilation
|
||||
@Suppress("unused")
|
||||
val multifileClassKind: MultifileClassKind?
|
||||
get() = if (kind == Kind.MULTIFILE_CLASS || kind == Kind.MULTIFILE_CLASS_PART) {
|
||||
if ((extraInt and JvmAnnotationNames.METADATA_MULTIFILE_PARTS_INHERIT_FLAG) != 0)
|
||||
INHERITING
|
||||
else
|
||||
DELEGATING
|
||||
} else null
|
||||
|
||||
val isUnstableJvmIrBinary: Boolean
|
||||
get() = (extraInt and JvmAnnotationNames.METADATA_JVM_IR_FLAG) != 0 &&
|
||||
(extraInt and JvmAnnotationNames.METADATA_JVM_IR_STABLE_ABI_FLAG == 0)
|
||||
|
||||
val isPreRelease: Boolean
|
||||
get() = (extraInt and JvmAnnotationNames.METADATA_PRE_RELEASE_FLAG) != 0
|
||||
|
||||
val isScript: Boolean
|
||||
get() = (extraInt and JvmAnnotationNames.METADATA_SCRIPT_FLAG) != 0
|
||||
|
||||
override fun toString() = "$kind version=$metadataVersion"
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.jvm;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.name.ClassId;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
|
||||
public class JvmClassName {
|
||||
@NotNull
|
||||
public static JvmClassName byInternalName(@NotNull String internalName) {
|
||||
return new JvmClassName(internalName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JvmClassName byClassId(@NotNull ClassId classId) {
|
||||
FqName packageFqName = classId.getPackageFqName();
|
||||
String relativeClassName = classId.getRelativeClassName().asString().replace('.', '$');
|
||||
return packageFqName.isRoot()
|
||||
? new JvmClassName(relativeClassName)
|
||||
: new JvmClassName(packageFqName.asString().replace('.', '/') + "/" + relativeClassName);
|
||||
}
|
||||
|
||||
/**
|
||||
* WARNING: fq name cannot be uniquely mapped to JVM class name.
|
||||
*/
|
||||
@NotNull
|
||||
public static JvmClassName byFqNameWithoutInnerClasses(@NotNull FqName fqName) {
|
||||
JvmClassName r = new JvmClassName(fqName.asString().replace('.', '/'));
|
||||
r.fqName = fqName;
|
||||
return r;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JvmClassName byFqNameWithoutInnerClasses(@NotNull String fqName) {
|
||||
return byFqNameWithoutInnerClasses(new FqName(fqName));
|
||||
}
|
||||
|
||||
// Internal name: kotlin/Map$Entry
|
||||
// FqName: kotlin.Map.Entry
|
||||
|
||||
private final String internalName;
|
||||
private FqName fqName;
|
||||
|
||||
private JvmClassName(@NotNull String internalName) {
|
||||
this.internalName = internalName;
|
||||
}
|
||||
|
||||
/**
|
||||
* WARNING: internal name cannot be reliably converted to FQ name.
|
||||
*
|
||||
* This method treats all dollar characters ('$') in the internal name as inner class separators.
|
||||
* So it _will work incorrectly_ for classes where dollar characters are a part of the identifier.
|
||||
*
|
||||
* E.g. JvmClassName("org/foo/bar/Baz$quux").getFqNameForClassNameWithoutDollars() -> FqName("org.foo.bar.Baz.quux")
|
||||
*/
|
||||
@NotNull
|
||||
public FqName getFqNameForClassNameWithoutDollars() {
|
||||
if (fqName == null) {
|
||||
this.fqName = new FqName(internalName.replace('$', '.').replace('/', '.'));
|
||||
}
|
||||
return fqName;
|
||||
}
|
||||
|
||||
/**
|
||||
* WARNING: internal name cannot be reliably converted to FQ name.
|
||||
*
|
||||
* This method treats all dollar characters ('$') in the internal name as a part of the identifier.
|
||||
* So it _will work incorrectly_ for inner classes.
|
||||
*
|
||||
* E.g. JvmClassName("org/foo/bar/Baz$quux").getFqNameForTopLevelClassMaybeWithDollars() -> FqName("org.foo.bar.Baz$quux")
|
||||
*/
|
||||
@NotNull
|
||||
public FqName getFqNameForTopLevelClassMaybeWithDollars() {
|
||||
return new FqName(internalName.replace('/', '.'));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FqName getPackageFqName() {
|
||||
int lastSlash = internalName.lastIndexOf("/");
|
||||
if (lastSlash == -1) return FqName.ROOT;
|
||||
return new FqName(internalName.substring(0, lastSlash).replace('/', '.'));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getInternalName() {
|
||||
return internalName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return internalName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
return internalName.equals(((JvmClassName) o).internalName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return internalName.hashCode();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user