Kapt3: Replace "my/package/Class$Inner" to "my/package/Class/Inner" in kapt3 class builder mode
This commit is contained in:
committed by
Yan Zhulanow
parent
65a9d9e8d2
commit
fc0b17c453
@@ -62,4 +62,12 @@ public class ClassBuilderMode {
|
|||||||
/* bodies = */ false,
|
/* bodies = */ false,
|
||||||
/* metadata = */ true,
|
/* metadata = */ true,
|
||||||
/* sourceRetention = */ true);
|
/* sourceRetention = */ true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function signatures + metadata (to support incremental compilation with kapt)
|
||||||
|
*/
|
||||||
|
public final static ClassBuilderMode KAPT3 = new ClassBuilderMode(
|
||||||
|
/* bodies = */ false,
|
||||||
|
/* metadata = */ true,
|
||||||
|
/* sourceRetention = */ true);
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-2
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
|
|||||||
import org.jetbrains.kotlin.fileClasses.FileClasses;
|
import org.jetbrains.kotlin.fileClasses.FileClasses;
|
||||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
|
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor;
|
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor;
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.TypeMappingConfiguration;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
@@ -81,6 +82,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
|||||||
private final GenerationState.GenerateClassFilter filter;
|
private final GenerationState.GenerateClassFilter filter;
|
||||||
private final JvmRuntimeTypes runtimeTypes;
|
private final JvmRuntimeTypes runtimeTypes;
|
||||||
private final JvmFileClassesProvider fileClassesProvider;
|
private final JvmFileClassesProvider fileClassesProvider;
|
||||||
|
private final TypeMappingConfiguration<Type> typeMappingConfiguration;
|
||||||
|
|
||||||
public CodegenAnnotatingVisitor(@NotNull GenerationState state) {
|
public CodegenAnnotatingVisitor(@NotNull GenerationState state) {
|
||||||
this.bindingTrace = state.getBindingTrace();
|
this.bindingTrace = state.getBindingTrace();
|
||||||
@@ -88,6 +90,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
|||||||
this.filter = state.getGenerateDeclaredClassFilter();
|
this.filter = state.getGenerateDeclaredClassFilter();
|
||||||
this.runtimeTypes = state.getJvmRuntimeTypes();
|
this.runtimeTypes = state.getJvmRuntimeTypes();
|
||||||
this.fileClassesProvider = state.getFileClassesProvider();
|
this.fileClassesProvider = state.getFileClassesProvider();
|
||||||
|
this.typeMappingConfiguration = state.getTypeMapper().getTypeMappingConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -232,8 +235,12 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
|||||||
private String getName(ClassDescriptor classDescriptor) {
|
private String getName(ClassDescriptor classDescriptor) {
|
||||||
String base = peekFromStack(nameStack);
|
String base = peekFromStack(nameStack);
|
||||||
Name descriptorName = safeIdentifier(classDescriptor.getName());
|
Name descriptorName = safeIdentifier(classDescriptor.getName());
|
||||||
return DescriptorUtils.isTopLevelDeclaration(classDescriptor) ? base.isEmpty() ? descriptorName
|
if (DescriptorUtils.isTopLevelDeclaration(classDescriptor)) {
|
||||||
.asString() : base + '/' + descriptorName : base + '$' + descriptorName;
|
return base.isEmpty() ? descriptorName.asString() : base + '/' + descriptorName;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return typeMappingConfiguration.getInnerClassNameFactory().invoke(base, descriptorName.asString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -325,7 +325,7 @@ public class InlineCodegen extends CallGenerator {
|
|||||||
assert callableDescriptor instanceof DeserializedCallableMemberDescriptor : "Not a deserialized function or proper: " + callableDescriptor;
|
assert callableDescriptor instanceof DeserializedCallableMemberDescriptor : "Not a deserialized function or proper: " + callableDescriptor;
|
||||||
|
|
||||||
KotlinTypeMapper.ContainingClassesInfo containingClasses =
|
KotlinTypeMapper.ContainingClassesInfo containingClasses =
|
||||||
KotlinTypeMapper.getContainingClassesForDeserializedCallable((DeserializedCallableMemberDescriptor) callableDescriptor);
|
state.getTypeMapper().getContainingClassesForDeserializedCallable((DeserializedCallableMemberDescriptor) callableDescriptor);
|
||||||
|
|
||||||
final ClassId containerId = containingClasses.getImplClassId();
|
final ClassId containerId = containingClasses.getImplClassId();
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiElement;
|
|||||||
import kotlin.Pair;
|
import kotlin.Pair;
|
||||||
import kotlin.Unit;
|
import kotlin.Unit;
|
||||||
import kotlin.collections.CollectionsKt;
|
import kotlin.collections.CollectionsKt;
|
||||||
|
import kotlin.jvm.functions.Function2;
|
||||||
import kotlin.jvm.functions.Function3;
|
import kotlin.jvm.functions.Function3;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -103,12 +104,32 @@ public class KotlinTypeMapper {
|
|||||||
private final boolean isJvm8Target;
|
private final boolean isJvm8Target;
|
||||||
|
|
||||||
private final TypeMappingConfiguration<Type> typeMappingConfiguration = new TypeMappingConfiguration<Type>() {
|
private final TypeMappingConfiguration<Type> typeMappingConfiguration = new TypeMappingConfiguration<Type>() {
|
||||||
|
private final Function2<String, String, String> defaultClassNameFactory
|
||||||
|
= TypeMappingConfiguration.Companion.getDEFAULT_INNER_CLASS_NAME_FACTORY();
|
||||||
|
|
||||||
|
private final Function2<String, String, String> innerClassNameFactory = new Function2<String, String, String>() {
|
||||||
|
@Override
|
||||||
|
public String invoke(String outer, String inner) {
|
||||||
|
if (classBuilderMode == ClassBuilderMode.KAPT3) {
|
||||||
|
return outer + '/' + inner;
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultClassNameFactory.invoke(outer, inner);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public KotlinType commonSupertype(@NotNull Collection<KotlinType> types) {
|
public KotlinType commonSupertype(@NotNull Collection<KotlinType> types) {
|
||||||
return CommonSupertypes.commonSupertype(types);
|
return CommonSupertypes.commonSupertype(types);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Function2<String, String, String> getInnerClassNameFactory() {
|
||||||
|
return innerClassNameFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public Type getPredefinedTypeForClass(@NotNull ClassDescriptor classDescriptor) {
|
public Type getPredefinedTypeForClass(@NotNull ClassDescriptor classDescriptor) {
|
||||||
@@ -139,6 +160,11 @@ public class KotlinTypeMapper {
|
|||||||
this.isJvm8Target = isJvm8Target;
|
this.isJvm8Target = isJvm8Target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public TypeMappingConfiguration<Type> getTypeMappingConfiguration() {
|
||||||
|
return typeMappingConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public BindingContext getBindingContext() {
|
public BindingContext getBindingContext() {
|
||||||
return bindingContext;
|
return bindingContext;
|
||||||
@@ -250,7 +276,7 @@ public class KotlinTypeMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static ContainingClassesInfo getContainingClassesForDeserializedCallable(
|
public ContainingClassesInfo getContainingClassesForDeserializedCallable(
|
||||||
@NotNull DeserializedCallableMemberDescriptor deserializedDescriptor
|
@NotNull DeserializedCallableMemberDescriptor deserializedDescriptor
|
||||||
) {
|
) {
|
||||||
DeclarationDescriptor parentDeclaration = deserializedDescriptor.getContainingDeclaration();
|
DeclarationDescriptor parentDeclaration = deserializedDescriptor.getContainingDeclaration();
|
||||||
@@ -269,14 +295,16 @@ public class KotlinTypeMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static ClassId getContainerClassIdForClassDescriptor(@NotNull ClassDescriptor classDescriptor) {
|
private ClassId getContainerClassIdForClassDescriptor(@NotNull ClassDescriptor classDescriptor) {
|
||||||
ClassId classId = DescriptorUtilsKt.getClassId(classDescriptor);
|
ClassId classId = DescriptorUtilsKt.getClassId(classDescriptor);
|
||||||
assert classId != null : "Deserialized class should have a ClassId: " + classDescriptor;
|
assert classId != null : "Deserialized class should have a ClassId: " + classDescriptor;
|
||||||
|
|
||||||
if (isInterface(classDescriptor)) {
|
if (isInterface(classDescriptor)) {
|
||||||
FqName relativeClassName = classId.getRelativeClassName();
|
FqName relativeClassName = classId.getRelativeClassName();
|
||||||
//TODO test nested trait fun inlining
|
//TODO test nested trait fun inlining
|
||||||
return new ClassId(classId.getPackageFqName(), Name.identifier(relativeClassName.shortName().asString() + JvmAbi.DEFAULT_IMPLS_SUFFIX));
|
String defaultImplsClassName = typeMappingConfiguration.getInnerClassNameFactory()
|
||||||
|
.invoke(relativeClassName.shortName().asString(), JvmAbi.DEFAULT_IMPLS_CLASS_NAME);
|
||||||
|
return new ClassId(classId.getPackageFqName(), Name.identifier(defaultImplsClassName));
|
||||||
}
|
}
|
||||||
|
|
||||||
return classId;
|
return classId;
|
||||||
@@ -437,7 +465,9 @@ public class KotlinTypeMapper {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Type mapDefaultImpls(@NotNull ClassDescriptor descriptor) {
|
public Type mapDefaultImpls(@NotNull ClassDescriptor descriptor) {
|
||||||
return Type.getObjectType(mapType(descriptor).getInternalName() + JvmAbi.DEFAULT_IMPLS_SUFFIX);
|
String defaultImplsClassName = typeMappingConfiguration.getInnerClassNameFactory().invoke(
|
||||||
|
mapType(descriptor).getInternalName(), JvmAbi.DEFAULT_IMPLS_CLASS_NAME);
|
||||||
|
return Type.getObjectType(defaultImplsClassName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -33,6 +33,11 @@ import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
|
|||||||
|
|
||||||
public final class JvmAbi {
|
public final class JvmAbi {
|
||||||
public static final String DEFAULT_IMPLS_CLASS_NAME = "DefaultImpls";
|
public static final String DEFAULT_IMPLS_CLASS_NAME = "DefaultImpls";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warning: use DEFAULT_IMPLS_CLASS_NAME and TypeMappingConfiguration.innerClassNameFactory when possible.
|
||||||
|
* This is false for KAPT3 mode.
|
||||||
|
*/
|
||||||
public static final String DEFAULT_IMPLS_SUFFIX = "$" + DEFAULT_IMPLS_CLASS_NAME;
|
public static final String DEFAULT_IMPLS_SUFFIX = "$" + DEFAULT_IMPLS_CLASS_NAME;
|
||||||
public static final String DEFAULT_IMPLS_DELEGATE_SUFFIX = "$defaultImpl";
|
public static final String DEFAULT_IMPLS_DELEGATE_SUFFIX = "$defaultImpl";
|
||||||
|
|
||||||
|
|||||||
+14
-4
@@ -42,6 +42,13 @@ private fun <T : Any> JvmTypeFactory<T>.boxTypeIfNeeded(possiblyPrimitiveType: T
|
|||||||
if (needBoxedType) boxType(possiblyPrimitiveType) else possiblyPrimitiveType
|
if (needBoxedType) boxType(possiblyPrimitiveType) else possiblyPrimitiveType
|
||||||
|
|
||||||
interface TypeMappingConfiguration<out T : Any> {
|
interface TypeMappingConfiguration<out T : Any> {
|
||||||
|
companion object {
|
||||||
|
val DEFAULT_INNER_CLASS_NAME_FACTORY = fun(outer: String, inner: String) = outer + "$" + inner
|
||||||
|
}
|
||||||
|
|
||||||
|
val innerClassNameFactory: (outer: String, inner: String) -> String
|
||||||
|
get() = DEFAULT_INNER_CLASS_NAME_FACTORY
|
||||||
|
|
||||||
fun commonSupertype(types: Collection<@JvmSuppressWildcards KotlinType>): KotlinType
|
fun commonSupertype(types: Collection<@JvmSuppressWildcards KotlinType>): KotlinType
|
||||||
fun getPredefinedTypeForClass(classDescriptor: ClassDescriptor): T?
|
fun getPredefinedTypeForClass(classDescriptor: ClassDescriptor): T?
|
||||||
fun processErrorType(kotlinType: KotlinType, descriptor: ClassDescriptor)
|
fun processErrorType(kotlinType: KotlinType, descriptor: ClassDescriptor)
|
||||||
@@ -126,7 +133,7 @@ fun <T : Any> mapType(
|
|||||||
factory.javaLangClassType
|
factory.javaLangClassType
|
||||||
else
|
else
|
||||||
typeMappingConfiguration.getPredefinedTypeForClass(descriptor.original)
|
typeMappingConfiguration.getPredefinedTypeForClass(descriptor.original)
|
||||||
?: factory.createObjectType(computeInternalName(descriptor.original))
|
?: factory.createObjectType(computeInternalName(descriptor.original, typeMappingConfiguration.innerClassNameFactory))
|
||||||
|
|
||||||
writeGenericType(kotlinType, jvmType, mode)
|
writeGenericType(kotlinType, jvmType, mode)
|
||||||
|
|
||||||
@@ -179,7 +186,10 @@ private fun <T : Any> mapBuiltInType(
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun computeInternalName(klass: ClassDescriptor): String {
|
internal fun computeInternalName(
|
||||||
|
klass: ClassDescriptor,
|
||||||
|
innerClassNameFactory: (outer: String, inner: String) -> String = TypeMappingConfiguration.DEFAULT_INNER_CLASS_NAME_FACTORY
|
||||||
|
): String {
|
||||||
val container = klass.containingDeclaration
|
val container = klass.containingDeclaration
|
||||||
|
|
||||||
val name = SpecialNames.safeIdentifier(klass.name).identifier
|
val name = SpecialNames.safeIdentifier(klass.name).identifier
|
||||||
@@ -190,8 +200,8 @@ internal fun computeInternalName(klass: ClassDescriptor): String {
|
|||||||
|
|
||||||
assert(container is ClassDescriptor) { "Unexpected container: $container for $klass" }
|
assert(container is ClassDescriptor) { "Unexpected container: $container for $klass" }
|
||||||
|
|
||||||
val containerInternalName = computeInternalName(container as ClassDescriptor)
|
val containerInternalName = computeInternalName(container as ClassDescriptor, innerClassNameFactory)
|
||||||
return if (klass.kind == ClassKind.ENUM_ENTRY) containerInternalName else containerInternalName + "$" + name
|
return if (klass.kind == ClassKind.ENUM_ENTRY) containerInternalName else innerClassNameFactory(containerInternalName, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getRepresentativeUpperBound(descriptor: TypeParameterDescriptor): KotlinType {
|
private fun getRepresentativeUpperBound(descriptor: TypeParameterDescriptor): KotlinType {
|
||||||
|
|||||||
Reference in New Issue
Block a user