Kapt: Do not write references to anonymous classes to stubs & metadata (#KT-25374)

This commit is contained in:
Yan Zhulanow
2018-07-13 22:34:58 +03:00
parent 43f5971863
commit ef210d7122
14 changed files with 277 additions and 188 deletions
@@ -0,0 +1,13 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. 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.resolve
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
import org.jetbrains.kotlin.types.KotlinType
interface DeclarationSignatureAnonymousTypeTransformer {
fun transformAnonymousType(descriptor: DeclarationDescriptorWithVisibility, type: KotlinType): KotlinType?
}
@@ -88,6 +88,7 @@ public class DescriptorResolver {
private final TypeApproximator typeApproximator; private final TypeApproximator typeApproximator;
private final DeclarationReturnTypeSanitizer declarationReturnTypeSanitizer; private final DeclarationReturnTypeSanitizer declarationReturnTypeSanitizer;
private final DataFlowValueFactory dataFlowValueFactory; private final DataFlowValueFactory dataFlowValueFactory;
private final Iterable<DeclarationSignatureAnonymousTypeTransformer> anonymousTypeTransformers;
public DescriptorResolver( public DescriptorResolver(
@NotNull AnnotationResolver annotationResolver, @NotNull AnnotationResolver annotationResolver,
@@ -106,7 +107,8 @@ public class DescriptorResolver {
@NotNull Project project, @NotNull Project project,
@NotNull TypeApproximator approximator, @NotNull TypeApproximator approximator,
@NotNull DeclarationReturnTypeSanitizer declarationReturnTypeSanitizer, @NotNull DeclarationReturnTypeSanitizer declarationReturnTypeSanitizer,
@NotNull DataFlowValueFactory dataFlowValueFactory @NotNull DataFlowValueFactory dataFlowValueFactory,
@NotNull Iterable<DeclarationSignatureAnonymousTypeTransformer> anonymousTypeTransformers
) { ) {
this.annotationResolver = annotationResolver; this.annotationResolver = annotationResolver;
this.builtIns = builtIns; this.builtIns = builtIns;
@@ -125,6 +127,7 @@ public class DescriptorResolver {
typeApproximator = approximator; typeApproximator = approximator;
this.declarationReturnTypeSanitizer = declarationReturnTypeSanitizer; this.declarationReturnTypeSanitizer = declarationReturnTypeSanitizer;
this.dataFlowValueFactory = dataFlowValueFactory; this.dataFlowValueFactory = dataFlowValueFactory;
this.anonymousTypeTransformers = anonymousTypeTransformers;
} }
public List<KotlinType> resolveSupertypes( public List<KotlinType> resolveSupertypes(
@@ -977,8 +980,16 @@ public class DescriptorResolver {
@NotNull DeclarationDescriptorWithVisibility descriptor, @NotNull DeclarationDescriptorWithVisibility descriptor,
@NotNull KtDeclaration declaration, @NotNull KtDeclaration declaration,
@NotNull KotlinType type, @NotNull KotlinType type,
@NotNull BindingTrace trace @NotNull BindingTrace trace,
@NotNull Iterable<DeclarationSignatureAnonymousTypeTransformer> anonymousTypeTransformers
) { ) {
for (DeclarationSignatureAnonymousTypeTransformer transformer : anonymousTypeTransformers) {
KotlinType transformedType = transformer.transformAnonymousType(descriptor, type);
if (transformedType != null) {
return transformedType;
}
}
ClassifierDescriptor classifier = type.getConstructor().getDeclarationDescriptor(); ClassifierDescriptor classifier = type.getConstructor().getDeclarationDescriptor();
if (classifier == null || !DescriptorUtils.isAnonymousObject(classifier) || DescriptorUtils.isLocal(descriptor)) { if (classifier == null || !DescriptorUtils.isAnonymousObject(classifier) || DescriptorUtils.isLocal(descriptor)) {
return type; return type;
@@ -996,7 +1007,6 @@ public class DescriptorResolver {
return type; return type;
} }
@Nullable @Nullable
private PropertySetterDescriptor resolvePropertySetterDescriptor( private PropertySetterDescriptor resolvePropertySetterDescriptor(
@NotNull LexicalScope scopeWithTypeParameters, @NotNull LexicalScope scopeWithTypeParameters,
@@ -1159,7 +1169,7 @@ public class DescriptorResolver {
return wrappedTypeFactory.createRecursionIntolerantDeferredType(trace, () -> { return wrappedTypeFactory.createRecursionIntolerantDeferredType(trace, () -> {
PreliminaryDeclarationVisitor.Companion.createForDeclaration(function, trace, languageVersionSettings); PreliminaryDeclarationVisitor.Companion.createForDeclaration(function, trace, languageVersionSettings);
KotlinType type = expressionTypingServices.getBodyExpressionType(trace, scope, dataFlowInfo, function, functionDescriptor); KotlinType type = expressionTypingServices.getBodyExpressionType(trace, scope, dataFlowInfo, function, functionDescriptor);
KotlinType publicType = transformAnonymousTypeIfNeeded(functionDescriptor, function, type, trace); KotlinType publicType = transformAnonymousTypeIfNeeded(functionDescriptor, function, type, trace, anonymousTypeTransformers);
UnwrappedType approximatedType = typeApproximator.approximateDeclarationType(publicType, false, languageVersionSettings); UnwrappedType approximatedType = typeApproximator.approximateDeclarationType(publicType, false, languageVersionSettings);
KotlinType sanitizedType = declarationReturnTypeSanitizer.sanitizeReturnType(approximatedType, wrappedTypeFactory, trace, languageVersionSettings); KotlinType sanitizedType = declarationReturnTypeSanitizer.sanitizeReturnType(approximatedType, wrappedTypeFactory, trace, languageVersionSettings);
functionsTypingVisitor.checkTypesForReturnStatements(function, trace, sanitizedType); functionsTypingVisitor.checkTypesForReturnStatements(function, trace, sanitizedType);
@@ -31,7 +31,8 @@ class VariableTypeAndInitializerResolver(
private val wrappedTypeFactory: WrappedTypeFactory, private val wrappedTypeFactory: WrappedTypeFactory,
private val typeApproximator: TypeApproximator, private val typeApproximator: TypeApproximator,
private val declarationReturnTypeSanitizer: DeclarationReturnTypeSanitizer, private val declarationReturnTypeSanitizer: DeclarationReturnTypeSanitizer,
private val languageVersionSettings: LanguageVersionSettings private val languageVersionSettings: LanguageVersionSettings,
private val anonymousTypeTransformers: Iterable<DeclarationSignatureAnonymousTypeTransformer>
) { ) {
companion object { companion object {
@JvmField @JvmField
@@ -82,7 +83,7 @@ class VariableTypeAndInitializerResolver(
) )
val initializerType = val initializerType =
resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace, local) resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace, local)
transformAnonymousTypeIfNeeded(variableDescriptor, variable, initializerType, trace) transformAnonymousTypeIfNeeded(variableDescriptor, variable, initializerType, trace, anonymousTypeTransformers)
} }
else -> resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace, local) else -> resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace, local)
@@ -1,6 +1,7 @@
package org.jetbrains.kotlin.gradle package org.jetbrains.kotlin.gradle
import org.jetbrains.kotlin.gradle.util.isLegacyAndroidGradleVersion import org.jetbrains.kotlin.gradle.util.isLegacyAndroidGradleVersion
import org.jetbrains.kotlin.gradle.util.getFileByName
import org.jetbrains.kotlin.gradle.util.modify import org.jetbrains.kotlin.gradle.util.modify
import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.KotlinTestUtils
import org.junit.Test import org.junit.Test
@@ -126,29 +127,32 @@ open class Kapt3AndroidIT : Kapt3BaseIT() {
} }
} }
@Test
fun testICWithAnonymousClasses() {
val project = Project("icAnonymousTypes", directoryPrefix = "kapt2")
setupDataBinding(project, null)
project.build("assembleDebug") {
assertSuccessful()
assertKaptSuccessful()
}
val aKt = project.projectDir.getFileByName("a.kt").also { assert(it.exists()) }
aKt.modify {
assert(it.contains("CrashMe2(1000)"))
it.replace("CrashMe2(1000)", "CrashMe2(2000)")
}
project.build("assembleDebug") {
assertSuccessful()
assertKaptSuccessful()
}
}
@Test @Test
open fun testDatabinding() { open fun testDatabinding() {
val project = Project("android-databinding", directoryPrefix = "kapt2") val project = Project("android-databinding", directoryPrefix = "kapt2")
setupDataBinding(project, "app")
if (!isLegacyAndroidGradleVersion(androidGradlePluginVersion)) {
project.setupWorkingDir()
// With new AGP, there's no need in the Databinding kapt dependency:
project.gradleBuildScript("app").modify {
it.lines().filterNot {
it.contains("kapt \"com.android.databinding:compiler")
}.joinToString("\n")
}
// Workaround for KT-24915
project.gradleBuildScript("app").appendText(
"\n" + """
afterEvaluate {
kaptDebugKotlin.dependsOn dataBindingExportFeaturePackageIdsDebug
}
""".trimIndent()
)
}
project.build("assembleDebug") { project.build("assembleDebug") {
assertSuccessful() assertSuccessful()
@@ -165,4 +169,26 @@ open class Kapt3AndroidIT : Kapt3BaseIT() {
assertNotContains("The following options were not recognized by any processor") assertNotContains("The following options were not recognized by any processor")
} }
} }
private fun setupDataBinding(project: Project, projectName: String?) {
if (!isLegacyAndroidGradleVersion(androidGradlePluginVersion)) {
project.setupWorkingDir()
// With new AGP, there's no need in the Databinding kapt dependency:
project.gradleBuildScript(projectName).modify {
it.lines().filterNot {
it.contains("kapt \"com.android.databinding:compiler")
}.joinToString("\n")
}
// Workaround for KT-24915
project.gradleBuildScript(projectName).appendText(
"\n" + """
afterEvaluate {
kaptDebugKotlin.dependsOn dataBindingExportFeaturePackageIdsDebug
}
""".trimIndent()
)
}
}
} }
@@ -0,0 +1,46 @@
buildscript {
repositories {
mavenLocal()
jcenter()
maven { url 'https://maven.google.com' }
}
dependencies {
classpath "com.android.tools.build:gradle:$android_tools_version"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 27
buildToolsVersion "27.0.3"
defaultConfig {
applicationId "org.kotlinlang.test"
minSdkVersion 16
targetSdkVersion 27
versionCode 1
versionName "1.0"
}
dataBinding {
enabled true
}
}
repositories {
mavenLocal()
jcenter()
maven { url 'https://maven.google.com' }
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
kapt "com.android.databinding:compiler:$android_tools_version"
}
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.databinding">
<application android:label="test">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
@@ -0,0 +1,7 @@
package test
class CrashMe {
private val crashMe = object : CrashMe2(1000) {
// empty
}
}
@@ -0,0 +1,8 @@
package test
abstract class CrashMe2(value: Long) {
val crashMe2 = object : Any() {
// empty
}
}
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="vertical"/>
</layout>
@@ -33,8 +33,11 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.CompilerConfigurationKey import org.jetbrains.kotlin.config.CompilerConfigurationKey
import org.jetbrains.kotlin.config.JVMConfigurationKeys import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.container.ComponentProvider import org.jetbrains.kotlin.container.ComponentProvider
import org.jetbrains.kotlin.container.StorageComponentContainer
import org.jetbrains.kotlin.container.useInstance
import org.jetbrains.kotlin.context.ProjectContext import org.jetbrains.kotlin.context.ProjectContext
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.ANNOTATION_PROCESSORS_OPTION import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.ANNOTATION_PROCESSORS_OPTION
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.ANNOTATION_PROCESSOR_CLASSPATH_OPTION import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.ANNOTATION_PROCESSOR_CLASSPATH_OPTION
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.APT_MODE_OPTION import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.APT_MODE_OPTION
@@ -59,7 +62,9 @@ import org.jetbrains.kotlin.kapt3.base.log
import org.jetbrains.kotlin.kapt3.util.MessageCollectorBackedKaptLogger import org.jetbrains.kotlin.kapt3.util.MessageCollectorBackedKaptLogger
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
import org.jetbrains.kotlin.utils.decodePluginOptions import org.jetbrains.kotlin.utils.decodePluginOptions
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
import java.io.File import java.io.File
@@ -314,6 +319,19 @@ class Kapt3ComponentRegistrar : ComponentRegistrar {
) )
AnalysisHandlerExtension.registerExtension(project, kapt3AnalysisCompletedHandlerExtension) AnalysisHandlerExtension.registerExtension(project, kapt3AnalysisCompletedHandlerExtension)
StorageComponentContainerContributor.registerExtension(project, KaptComponentContributor())
}
class KaptComponentContributor : StorageComponentContainerContributor {
override fun registerModuleComponents(
container: StorageComponentContainer,
platform: TargetPlatform,
moduleDescriptor: ModuleDescriptor
) {
if (platform != JvmPlatform) return
container.useInstance(KaptAnonymousTypeTransformer())
}
} }
/* This extension simply disables both code analysis and code generation. /* This extension simply disables both code analysis and code generation.
@@ -340,6 +358,7 @@ class Kapt3ComponentRegistrar : ComponentRegistrar {
return AnalysisResult.Companion.success(bindingTrace.bindingContext, module, shouldGenerateCode = false) return AnalysisResult.Companion.success(bindingTrace.bindingContext, module, shouldGenerateCode = false)
} }
} }
} }
enum class AptMode { enum class AptMode {
@@ -0,0 +1,73 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. 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.kapt3
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
import org.jetbrains.kotlin.resolve.DeclarationSignatureAnonymousTypeTransformer
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils.isAnonymousObject
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeProjectionImpl
import org.jetbrains.kotlin.types.replace
import org.jetbrains.kotlin.types.typeUtil.builtIns
import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
class KaptAnonymousTypeTransformer : DeclarationSignatureAnonymousTypeTransformer {
override fun transformAnonymousType(descriptor: DeclarationDescriptorWithVisibility, type: KotlinType): KotlinType? {
if (DescriptorUtils.isLocal(descriptor))
return type
return convertPossiblyAnonymousType(type)
}
private fun convertPossiblyAnonymousType(type: KotlinType): KotlinType {
val declaration = type.constructor.declarationDescriptor as? ClassDescriptor ?: return type
if (KotlinBuiltIns.isArray(type)) {
val elementTypeProjection = type.arguments.singleOrNull()
if (elementTypeProjection != null && !elementTypeProjection.isStarProjection) {
return type.builtIns.getArrayType(
elementTypeProjection.projectionKind,
convertPossiblyAnonymousType(elementTypeProjection.type)
)
}
}
val actualType = when {
isAnonymousObject(declaration) -> findMostSuitableParentForAnonymousType(declaration)
else -> type
}
if (actualType.arguments.isEmpty()) return actualType
val arguments = actualType.arguments.map { typeArg ->
if (typeArg.isStarProjection)
return@map typeArg
TypeProjectionImpl(typeArg.projectionKind, convertPossiblyAnonymousType(typeArg.type))
}
return actualType.replace(newArguments = arguments)
}
private fun findMostSuitableParentForAnonymousType(descriptor: ClassDescriptor): KotlinType {
descriptor.getSuperClassNotAny()?.let { return it.defaultType }
val sortedSuperTypes = descriptor.typeConstructor.supertypes
.sortedBy { it.constructor.declarationDescriptor?.name?.asString() ?: "" }
for (candidate in sortedSuperTypes) {
if (!candidate.isAnyOrNullableAny())
return candidate
}
return descriptor.builtIns.anyType
}
}
@@ -1,137 +0,0 @@
/*
* Copyright 2010-2017 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.kapt3.stubs
import com.sun.tools.javac.code.BoundKind
import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.kapt3.base.mapJList
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeProjectionImpl
import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
import org.jetbrains.kotlin.resolve.DescriptorUtils.isAnonymousObject
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.replace
import org.jetbrains.kotlin.types.typeUtil.builtIns
class AnonymousTypeHandler(private val converter: ClassFileToSourceStubConverter) {
fun <T : JCTree.JCExpression?> getNonAnonymousType(descriptor: DeclarationDescriptor?, f: () -> T): T {
val classType = when (descriptor) {
is ClassDescriptor -> descriptor.defaultType
is CallableDescriptor -> descriptor.returnType
else -> null
} ?: return f()
return getNonAnonymousType(classType, f)
}
fun <T : JCTree.JCExpression?> getNonAnonymousType(type: KotlinType, f: () -> T): T {
if (!checkIfAnonymousRecursively(type)) return f()
@Suppress("UNCHECKED_CAST")
return convertKotlinType(convertPossiblyAnonymousType(type)) as T
}
private fun checkIfAnonymousRecursively(type: KotlinType): Boolean {
val declaration = type.constructor.declarationDescriptor as? ClassDescriptor ?: return false
if (isAnonymousObject(declaration)) return true
return type.arguments.any {
if (it.isStarProjection) return@any false
checkIfAnonymousRecursively(it.type)
}
}
private fun convertPossiblyAnonymousType(type: KotlinType): KotlinType {
val declaration = type.constructor.declarationDescriptor as? ClassDescriptor ?: return type
if (KotlinBuiltIns.isArray(type)) {
val elementTypeProjection = type.arguments.singleOrNull()
if (elementTypeProjection != null && !elementTypeProjection.isStarProjection) {
return type.builtIns.getArrayType(
elementTypeProjection.projectionKind,
convertPossiblyAnonymousType(elementTypeProjection.type)
)
}
}
val actualType = when {
isAnonymousObject(declaration) -> findMostSuitableParentForAnonymousType(declaration)
else -> type
}
if (actualType.arguments.isEmpty()) return actualType
val arguments = actualType.arguments.map { typeArg ->
if (typeArg.isStarProjection) return@map typeArg
TypeProjectionImpl(typeArg.projectionKind, convertPossiblyAnonymousType(typeArg.type))
}
return actualType.replace(arguments)
}
private fun findMostSuitableParentForAnonymousType(descriptor: ClassDescriptor): KotlinType {
descriptor.getSuperClassNotAny()?.let { return it.defaultType }
val sortedSuperTypes = descriptor.typeConstructor.supertypes
.sortedBy { it.constructor.declarationDescriptor?.name?.asString() ?: "" }
for (candidate in sortedSuperTypes) {
if (!candidate.isAnyOrNullableAny()) return candidate
}
return descriptor.builtIns.anyType
}
private fun convertKotlinType(type: KotlinType): JCTree.JCExpression {
val treeMaker = converter.treeMaker
if (KotlinBuiltIns.isArray(type)) {
val elementTypeProjection = type.arguments.single()
val elementType = if (elementTypeProjection.isStarProjection || elementTypeProjection.projectionKind == Variance.IN_VARIANCE) {
type.builtIns.anyType
} else {
elementTypeProjection.type
}
return treeMaker.TypeArray(convertKotlinType(elementType))
}
val typeMapper = converter.kaptContext.generationState.typeMapper
// Primitive types can't be anonymous, so if we get here, we want to map a class type or its generic argument
val selfType = treeMaker.Type(typeMapper.mapType(type, null, TypeMappingMode.GENERIC_ARGUMENT))
if (type.arguments.isEmpty()) return selfType
return treeMaker.TypeApply(selfType, mapJList(type.arguments) { projection ->
if (projection.isStarProjection) return@mapJList treeMaker.Wildcard(treeMaker.TypeBoundKind(BoundKind.UNBOUND), null)
val renderedArg = convertKotlinType(projection.type)
when (projection.projectionKind) {
Variance.INVARIANT -> renderedArg
Variance.OUT_VARIANCE -> treeMaker.Wildcard(treeMaker.TypeBoundKind(BoundKind.EXTENDS), renderedArg)
Variance.IN_VARIANCE -> treeMaker.Wildcard(treeMaker.TypeBoundKind(BoundKind.SUPER), renderedArg)
}
})
}
}
@@ -107,8 +107,6 @@ class ClassFileToSourceStubConverter(
private val signatureParser = SignatureParser(treeMaker) private val signatureParser = SignatureParser(treeMaker)
private val anonymousTypeHandler = AnonymousTypeHandler(this)
private val kdocCommentKeeper = KDocCommentKeeper(kaptContext) private val kdocCommentKeeper = KDocCommentKeeper(kaptContext)
private var done = false private var done = false
@@ -479,16 +477,16 @@ class ClassFileToSourceStubConverter(
val typeExpression = if (isEnum(field.access)) val typeExpression = if (isEnum(field.access))
treeMaker.SimpleName(treeMaker.getQualifiedName(type).substringAfterLast('.')) treeMaker.SimpleName(treeMaker.getQualifiedName(type).substringAfterLast('.'))
else else
anonymousTypeHandler.getNonAnonymousType(descriptor) { getNonErrorType(
getNonErrorType((descriptor as? CallableDescriptor)?.returnType, RETURN_TYPE, (descriptor as? CallableDescriptor)?.returnType, RETURN_TYPE,
ktTypeProvider = { ktTypeProvider = {
val fieldOrigin = (kaptContext.origins[field]?.element as? KtCallableDeclaration) val fieldOrigin = (kaptContext.origins[field]?.element as? KtCallableDeclaration)
?.takeIf { it !is KtFunction } ?.takeIf { it !is KtFunction }
fieldOrigin?.typeReference fieldOrigin?.typeReference
}, },
ifNonError = { signatureParser.parseFieldSignature(field.signature, treeMaker.Type(type)) }) ifNonError = { signatureParser.parseFieldSignature(field.signature, treeMaker.Type(type)) }
} )
val value = field.value val value = field.value
@@ -646,19 +644,19 @@ class ClassFileToSourceStubConverter(
} }
}) })
val returnType = anonymousTypeHandler.getNonAnonymousType(descriptor) { val returnType = getNonErrorType(
getNonErrorType(descriptor.returnType, RETURN_TYPE, descriptor.returnType, RETURN_TYPE,
ktTypeProvider = { ktTypeProvider = {
val element = kaptContext.origins[method]?.element val element = kaptContext.origins[method]?.element
when (element) { when (element) {
is KtFunction -> element.typeReference is KtFunction -> element.typeReference
is KtProperty -> if (descriptor is PropertyGetterDescriptor) element.typeReference else null is KtProperty -> if (descriptor is PropertyGetterDescriptor) element.typeReference else null
is KtParameter -> if (descriptor is PropertyGetterDescriptor) element.typeReference else null is KtParameter -> if (descriptor is PropertyGetterDescriptor) element.typeReference else null
else -> null else -> null
} }
}, },
ifNonError = { genericSignature.returnType }) ifNonError = { genericSignature.returnType }
} )
return Pair(genericSignature, returnType) return Pair(genericSignature, returnType)
} }
@@ -30,7 +30,9 @@ import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
import org.jetbrains.kotlin.kapt3.* import org.jetbrains.kotlin.kapt3.*
import org.jetbrains.kotlin.kapt3.Kapt3ComponentRegistrar.KaptComponentContributor
import org.jetbrains.kotlin.kapt3.base.KaptContext import org.jetbrains.kotlin.kapt3.base.KaptContext
import org.jetbrains.kotlin.kapt3.base.KaptPaths import org.jetbrains.kotlin.kapt3.base.KaptPaths
import org.jetbrains.kotlin.kapt3.base.doAnnotationProcessing import org.jetbrains.kotlin.kapt3.base.doAnnotationProcessing
@@ -105,7 +107,9 @@ abstract class AbstractKotlinKapt3Test : CodegenTestCase() {
addAnnotationProcessingRuntimeLibrary(myEnvironment) addAnnotationProcessingRuntimeLibrary(myEnvironment)
// Use light analysis mode in tests // Use light analysis mode in tests
AnalysisHandlerExtension.registerExtension(myEnvironment.project, PartialAnalysisHandlerExtension()) val project = myEnvironment.project
AnalysisHandlerExtension.registerExtension(project, PartialAnalysisHandlerExtension())
StorageComponentContainerContributor.registerExtension(project, KaptComponentContributor())
loadMultiFiles(files) loadMultiFiles(files)