Map intrinsic companion objects in JavaToKotlinClassMap
Get rid of multiple usages of IntrinsicObjects where JavaToKotlinClassMap was already used, simplify code, and support loading of *CompanionObject as Kotlin built-in companions from Java code. Also fix a small bug where Boolean was considered a class with an intrinsic companion in IntrinsicObjects, although it was not
This commit is contained in:
@@ -17,7 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.codegen;
|
package org.jetbrains.kotlin.codegen;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.builtins.jvm.IntrinsicObjects;
|
import org.jetbrains.kotlin.builtins.CompanionObjectMapping;
|
||||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
|
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
|
||||||
@@ -34,7 +34,7 @@ public class FieldInfo {
|
|||||||
throw new UnsupportedOperationException("Can't create singleton field for class: " + classDescriptor);
|
throw new UnsupportedOperationException("Can't create singleton field for class: " + classDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNonCompanionObject(classDescriptor) || IntrinsicObjects.INSTANCE$.hasMappingToObject(classDescriptor)) {
|
if (isNonCompanionObject(classDescriptor) || CompanionObjectMapping.hasMappingToObject(classDescriptor)) {
|
||||||
Type type = typeMapper.mapType(classDescriptor);
|
Type type = typeMapper.mapType(classDescriptor);
|
||||||
return new FieldInfo(type, type, JvmAbi.INSTANCE_FIELD, true);
|
return new FieldInfo(type, type, JvmAbi.INSTANCE_FIELD, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||||
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
||||||
import org.jetbrains.kotlin.builtins.jvm.IntrinsicObjects;
|
|
||||||
import org.jetbrains.kotlin.codegen.*;
|
import org.jetbrains.kotlin.codegen.*;
|
||||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||||
import org.jetbrains.kotlin.codegen.binding.MutableClosure;
|
import org.jetbrains.kotlin.codegen.binding.MutableClosure;
|
||||||
@@ -339,16 +338,6 @@ public class JetTypeMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor instanceof ClassDescriptor) {
|
if (descriptor instanceof ClassDescriptor) {
|
||||||
FqName companionObjectMappedFqName = IntrinsicObjects.mapType((ClassDescriptor) descriptor);
|
|
||||||
if (companionObjectMappedFqName != null) {
|
|
||||||
Type asmType = asmTypeByFqNameWithoutInnerClasses(companionObjectMappedFqName);
|
|
||||||
if (signatureVisitor != null) {
|
|
||||||
signatureVisitor.writeAsmType(asmType);
|
|
||||||
}
|
|
||||||
|
|
||||||
return asmType;
|
|
||||||
}
|
|
||||||
|
|
||||||
Type asmType = kind.isForAnnotation() && KotlinBuiltIns.isKClass((ClassDescriptor) descriptor) ?
|
Type asmType = kind.isForAnnotation() && KotlinBuiltIns.isKClass((ClassDescriptor) descriptor) ?
|
||||||
AsmTypes.JAVA_CLASS_TYPE :
|
AsmTypes.JAVA_CLASS_TYPE :
|
||||||
computeAsmType((ClassDescriptor) descriptor.getOriginal());
|
computeAsmType((ClassDescriptor) descriptor.getOriginal());
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
import kotlin.jvm.internal.*;
|
||||||
|
|
||||||
|
public interface IntrinsicCompanionObject {
|
||||||
|
void testInt(IntCompanionObject i);
|
||||||
|
void testChar(CharCompanionObject c);
|
||||||
|
void testString(StringCompanionObject s);
|
||||||
|
void testEnum(EnumCompanionObject e);
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
public trait IntrinsicCompanionObject {
|
||||||
|
public abstract fun testChar(/*0*/ p0: kotlin.Char.Companion!): kotlin.Unit
|
||||||
|
public abstract fun testEnum(/*0*/ p0: kotlin.Enum.Companion!): kotlin.Unit
|
||||||
|
public abstract fun testInt(/*0*/ p0: kotlin.Int.Companion!): kotlin.Unit
|
||||||
|
public abstract fun testString(/*0*/ p0: kotlin.String.Companion!): kotlin.Unit
|
||||||
|
}
|
||||||
@@ -145,6 +145,12 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
|
|||||||
doTestCompiledJava(fileName);
|
doTestCompiledJava(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("IntrinsicCompanionObject.java")
|
||||||
|
public void testIntrinsicCompanionObject() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/IntrinsicCompanionObject.java");
|
||||||
|
doTestCompiledJava(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("MethodReferencesOuterClassTP.java")
|
@TestMetadata("MethodReferencesOuterClassTP.java")
|
||||||
public void testMethodReferencesOuterClassTP() throws Exception {
|
public void testMethodReferencesOuterClassTP() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/MethodReferencesOuterClassTP.java");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/MethodReferencesOuterClassTP.java");
|
||||||
|
|||||||
+6
@@ -3151,6 +3151,12 @@ public class JvmRuntimeDescriptorLoaderTestGenerated extends AbstractJvmRuntimeD
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("IntrinsicCompanionObject.java")
|
||||||
|
public void testIntrinsicCompanionObject() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/IntrinsicCompanionObject.java");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("MethodReferencesOuterClassTP.java")
|
@TestMetadata("MethodReferencesOuterClassTP.java")
|
||||||
public void testMethodReferencesOuterClassTP() throws Exception {
|
public void testMethodReferencesOuterClassTP() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/MethodReferencesOuterClassTP.java");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/MethodReferencesOuterClassTP.java");
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.builtins.jvm
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.CompanionObjectMapping
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import kotlin.platform.platformStatic
|
|
||||||
|
|
||||||
public object IntrinsicObjects : CompanionObjectMapping() {
|
|
||||||
private val kotlinJvmInternal = FqName("kotlin.jvm.internal")
|
|
||||||
|
|
||||||
public platformStatic fun mapType(classDescriptor: ClassDescriptor): FqName? {
|
|
||||||
if (!hasMappingToObject(classDescriptor)) return null
|
|
||||||
|
|
||||||
val containingDeclaration = classDescriptor.getContainingDeclaration()
|
|
||||||
val name = Name.identifier(containingDeclaration.getName().asString() + "CompanionObject")
|
|
||||||
return kotlinJvmInternal.child(name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+9
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.platform;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.kotlin.builtins.CompanionObjectMapping;
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||||
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||||
@@ -67,6 +68,12 @@ public class JavaToKotlinClassMap implements PlatformToKotlinClassMap {
|
|||||||
add(ClassId.topLevel(jvmType.getWrapperFqName()), builtIns.getPrimitiveClassDescriptor(jvmType.getPrimitiveType()));
|
add(ClassId.topLevel(jvmType.getWrapperFqName()), builtIns.getPrimitiveClassDescriptor(jvmType.getPrimitiveType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (ClassDescriptor descriptor : CompanionObjectMapping.allClassesWithIntrinsicCompanions()) {
|
||||||
|
ClassDescriptor companion = descriptor.getCompanionObjectDescriptor();
|
||||||
|
assert companion != null : "No companion object found for " + descriptor;
|
||||||
|
add(ClassId.topLevel(new FqName("kotlin.jvm.internal." + descriptor.getName().asString() + "CompanionObject")), companion);
|
||||||
|
}
|
||||||
|
|
||||||
addJavaToKotlin(classId(Deprecated.class), builtIns.getDeprecatedAnnotation());
|
addJavaToKotlin(classId(Deprecated.class), builtIns.getDeprecatedAnnotation());
|
||||||
|
|
||||||
addKotlinToJava(classId(Void.class), builtIns.getNothing());
|
addKotlinToJava(classId(Void.class), builtIns.getNothing());
|
||||||
@@ -77,6 +84,7 @@ public class JavaToKotlinClassMap implements PlatformToKotlinClassMap {
|
|||||||
* java.lang.String -> kotlin.String
|
* java.lang.String -> kotlin.String
|
||||||
* java.lang.Deprecated -> kotlin.deprecated
|
* java.lang.Deprecated -> kotlin.deprecated
|
||||||
* java.lang.Integer -> kotlin.Int
|
* java.lang.Integer -> kotlin.Int
|
||||||
|
* kotlin.jvm.internal.IntCompanionObject -> kotlin.Int.Companion
|
||||||
* java.util.List -> kotlin.List
|
* java.util.List -> kotlin.List
|
||||||
* java.lang.Void -> null
|
* java.lang.Void -> null
|
||||||
*/
|
*/
|
||||||
@@ -100,6 +108,7 @@ public class JavaToKotlinClassMap implements PlatformToKotlinClassMap {
|
|||||||
* E.g.
|
* E.g.
|
||||||
* kotlin.Throwable -> java.lang.Throwable
|
* kotlin.Throwable -> java.lang.Throwable
|
||||||
* kotlin.Int -> java.lang.Integer
|
* kotlin.Int -> java.lang.Integer
|
||||||
|
* kotlin.Int.Companion -> kotlin.jvm.internal.IntCompanionObject
|
||||||
* kotlin.Nothing -> java.lang.Void
|
* kotlin.Nothing -> java.lang.Void
|
||||||
* kotlin.IntArray -> null
|
* kotlin.IntArray -> null
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -18,16 +18,26 @@ package org.jetbrains.kotlin.builtins
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
|
import java.util.Collections
|
||||||
|
import kotlin.platform.platformStatic
|
||||||
|
|
||||||
public abstract class CompanionObjectMapping {
|
public object CompanionObjectMapping {
|
||||||
public fun hasMappingToObject(classDescriptor: ClassDescriptor): Boolean {
|
private val classes = linkedSetOf<ClassDescriptor>()
|
||||||
if (!DescriptorUtils.isCompanionObject(classDescriptor)) return false
|
|
||||||
|
|
||||||
val containingDeclaration = classDescriptor.getContainingDeclaration()
|
init {
|
||||||
if (containingDeclaration !is ClassDescriptor) return false
|
val builtIns = KotlinBuiltIns.getInstance()
|
||||||
|
for (type in PrimitiveType.NUMBER_TYPES) {
|
||||||
|
classes.add(builtIns.getPrimitiveClassDescriptor(type))
|
||||||
|
}
|
||||||
|
classes.add(builtIns.getString())
|
||||||
|
classes.add(builtIns.getEnum())
|
||||||
|
}
|
||||||
|
|
||||||
return KotlinBuiltIns.isPrimitiveType(containingDeclaration.getDefaultType()) ||
|
public platformStatic fun allClassesWithIntrinsicCompanions(): Set<ClassDescriptor> =
|
||||||
KotlinBuiltIns.getInstance().getString() == containingDeclaration ||
|
Collections.unmodifiableSet(classes)
|
||||||
KotlinBuiltIns.getInstance().getEnum() == containingDeclaration
|
|
||||||
|
public platformStatic fun hasMappingToObject(classDescriptor: ClassDescriptor): Boolean {
|
||||||
|
return DescriptorUtils.isCompanionObject(classDescriptor) &&
|
||||||
|
classDescriptor.getContainingDeclaration() in classes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 kotlin.reflect.jvm.internal
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.builtins.jvm.IntrinsicObjects
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
|
|
||||||
object InverseIntrinsicObjectsMapping {
|
|
||||||
private val map = linkedMapOf<FqName, ClassDescriptor>()
|
|
||||||
|
|
||||||
init {
|
|
||||||
for (descriptor in KotlinBuiltIns.getInstance().getBuiltInsPackageFragment().getMemberScope().getAllDescriptors()) {
|
|
||||||
val companion = (descriptor as? ClassDescriptor)?.getCompanionObjectDescriptor() ?: continue
|
|
||||||
IntrinsicObjects.mapType(companion)?.let { fqName ->
|
|
||||||
map[fqName] = companion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maps a FQ name of an internal JVM class representing a built-in companion object to the relevant Kotlin descriptor,
|
|
||||||
* e.g. [kotlin.jvm.internal.StringCompanionObject] -> class descriptor of [kotlin.String.Companion]
|
|
||||||
*/
|
|
||||||
fun mapJvmClassToKotlinDescriptor(javaFqName: FqName): ClassDescriptor? = map[javaFqName]
|
|
||||||
}
|
|
||||||
@@ -18,7 +18,6 @@ package kotlin.reflect.jvm.internal
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||||
import org.jetbrains.kotlin.builtins.jvm.IntrinsicObjects
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.structure.reflect.classId
|
import org.jetbrains.kotlin.load.java.structure.reflect.classId
|
||||||
@@ -60,12 +59,6 @@ object RuntimeTypeMapper {
|
|||||||
|
|
||||||
JavaToKotlinClassMap.INSTANCE.mapKotlinToJava(fqName)?.let { return it.desc }
|
JavaToKotlinClassMap.INSTANCE.mapKotlinToJava(fqName)?.let { return it.desc }
|
||||||
|
|
||||||
if (classDescriptor.isCompanionObject()) {
|
|
||||||
IntrinsicObjects.mapType(classDescriptor)?.let { fqName ->
|
|
||||||
return ClassId.topLevel(fqName).desc
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return classDescriptor.classId.desc
|
return classDescriptor.classId.desc
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,11 +76,7 @@ object RuntimeTypeMapper {
|
|||||||
|
|
||||||
val classId = klass.classId
|
val classId = klass.classId
|
||||||
if (!classId.isLocal()) {
|
if (!classId.isLocal()) {
|
||||||
val fqName = classId.asSingleFqName()
|
JavaToKotlinClassMap.INSTANCE.mapJavaToKotlin(classId.asSingleFqName())?.let { return it.classId }
|
||||||
val kotlinClass = JavaToKotlinClassMap.INSTANCE.mapJavaToKotlin(fqName)
|
|
||||||
kotlinClass?.let { return it.classId }
|
|
||||||
|
|
||||||
InverseIntrinsicObjectsMapping.mapJvmClassToKotlinDescriptor(fqName)?.let { return it.classId }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return classId
|
return classId
|
||||||
|
|||||||
+2
-2
@@ -35,9 +35,9 @@ class DefaultClassObjectIntrinsic(val fqName: FqName, val moduleName: String): O
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ObjectIntrinsics : CompanionObjectMapping() {
|
public class ObjectIntrinsics {
|
||||||
public fun getIntrinsic(classDescriptor: ClassDescriptor): ObjectIntrinsic {
|
public fun getIntrinsic(classDescriptor: ClassDescriptor): ObjectIntrinsic {
|
||||||
if (!hasMappingToObject(classDescriptor)) return NO_OBJECT_INTRINSIC
|
if (!CompanionObjectMapping.hasMappingToObject(classDescriptor)) return NO_OBJECT_INTRINSIC
|
||||||
|
|
||||||
val containingDeclaration = classDescriptor.getContainingDeclaration()
|
val containingDeclaration = classDescriptor.getContainingDeclaration()
|
||||||
val name = Name.identifier(containingDeclaration.getName().asString() + "CompanionObject")
|
val name = Name.identifier(containingDeclaration.getName().asString() + "CompanionObject")
|
||||||
|
|||||||
Reference in New Issue
Block a user