diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationSignatureAnonymousTypeTransformer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationSignatureAnonymousTypeTransformer.kt new file mode 100644 index 00000000000..13e088d277c --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationSignatureAnonymousTypeTransformer.kt @@ -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? +} \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java index 69f594dfe94..620b9f3c4b4 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java @@ -88,6 +88,7 @@ public class DescriptorResolver { private final TypeApproximator typeApproximator; private final DeclarationReturnTypeSanitizer declarationReturnTypeSanitizer; private final DataFlowValueFactory dataFlowValueFactory; + private final Iterable anonymousTypeTransformers; public DescriptorResolver( @NotNull AnnotationResolver annotationResolver, @@ -106,7 +107,8 @@ public class DescriptorResolver { @NotNull Project project, @NotNull TypeApproximator approximator, @NotNull DeclarationReturnTypeSanitizer declarationReturnTypeSanitizer, - @NotNull DataFlowValueFactory dataFlowValueFactory + @NotNull DataFlowValueFactory dataFlowValueFactory, + @NotNull Iterable anonymousTypeTransformers ) { this.annotationResolver = annotationResolver; this.builtIns = builtIns; @@ -125,6 +127,7 @@ public class DescriptorResolver { typeApproximator = approximator; this.declarationReturnTypeSanitizer = declarationReturnTypeSanitizer; this.dataFlowValueFactory = dataFlowValueFactory; + this.anonymousTypeTransformers = anonymousTypeTransformers; } public List resolveSupertypes( @@ -977,8 +980,16 @@ public class DescriptorResolver { @NotNull DeclarationDescriptorWithVisibility descriptor, @NotNull KtDeclaration declaration, @NotNull KotlinType type, - @NotNull BindingTrace trace + @NotNull BindingTrace trace, + @NotNull Iterable anonymousTypeTransformers ) { + for (DeclarationSignatureAnonymousTypeTransformer transformer : anonymousTypeTransformers) { + KotlinType transformedType = transformer.transformAnonymousType(descriptor, type); + if (transformedType != null) { + return transformedType; + } + } + ClassifierDescriptor classifier = type.getConstructor().getDeclarationDescriptor(); if (classifier == null || !DescriptorUtils.isAnonymousObject(classifier) || DescriptorUtils.isLocal(descriptor)) { return type; @@ -996,7 +1007,6 @@ public class DescriptorResolver { return type; } - @Nullable private PropertySetterDescriptor resolvePropertySetterDescriptor( @NotNull LexicalScope scopeWithTypeParameters, @@ -1159,7 +1169,7 @@ public class DescriptorResolver { return wrappedTypeFactory.createRecursionIntolerantDeferredType(trace, () -> { PreliminaryDeclarationVisitor.Companion.createForDeclaration(function, trace, languageVersionSettings); 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); KotlinType sanitizedType = declarationReturnTypeSanitizer.sanitizeReturnType(approximatedType, wrappedTypeFactory, trace, languageVersionSettings); functionsTypingVisitor.checkTypesForReturnStatements(function, trace, sanitizedType); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt index 32ca3bd5528..ac120eb02da 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt @@ -31,7 +31,8 @@ class VariableTypeAndInitializerResolver( private val wrappedTypeFactory: WrappedTypeFactory, private val typeApproximator: TypeApproximator, private val declarationReturnTypeSanitizer: DeclarationReturnTypeSanitizer, - private val languageVersionSettings: LanguageVersionSettings + private val languageVersionSettings: LanguageVersionSettings, + private val anonymousTypeTransformers: Iterable ) { companion object { @JvmField @@ -82,7 +83,7 @@ class VariableTypeAndInitializerResolver( ) val initializerType = 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) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3AndroidIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3AndroidIT.kt index 5d014ebb552..682f0f3a1e1 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3AndroidIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3AndroidIT.kt @@ -1,6 +1,7 @@ package org.jetbrains.kotlin.gradle 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.test.KotlinTestUtils 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 open fun testDatabinding() { val project = Project("android-databinding", directoryPrefix = "kapt2") - - 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() - ) - } + setupDataBinding(project, "app") project.build("assembleDebug") { assertSuccessful() @@ -165,4 +169,26 @@ open class Kapt3AndroidIT : Kapt3BaseIT() { 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() + ) + } + } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/icAnonymousTypes/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/icAnonymousTypes/build.gradle new file mode 100644 index 00000000000..2adc83854a7 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/icAnonymousTypes/build.gradle @@ -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" +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/icAnonymousTypes/src/main/AndroidManifest.xml b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/icAnonymousTypes/src/main/AndroidManifest.xml new file mode 100644 index 00000000000..cfb195d6e5f --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/icAnonymousTypes/src/main/AndroidManifest.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/icAnonymousTypes/src/main/java/a.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/icAnonymousTypes/src/main/java/a.kt new file mode 100644 index 00000000000..f2ee7138688 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/icAnonymousTypes/src/main/java/a.kt @@ -0,0 +1,7 @@ +package test + +class CrashMe { + private val crashMe = object : CrashMe2(1000) { + // empty + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/icAnonymousTypes/src/main/java/b.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/icAnonymousTypes/src/main/java/b.kt new file mode 100644 index 00000000000..69845919630 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/icAnonymousTypes/src/main/java/b.kt @@ -0,0 +1,8 @@ +package test + +abstract class CrashMe2(value: Long) { + val crashMe2 = object : Any() { + // empty + } +} + diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/icAnonymousTypes/src/main/res/layout/activity_test.xml b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/icAnonymousTypes/src/main/res/layout/activity_test.xml new file mode 100644 index 00000000000..164b06ee3f4 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/icAnonymousTypes/src/main/res/layout/activity_test.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/Kapt3Plugin.kt b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/Kapt3Plugin.kt index f094e9b7001..e11a2f56a02 100644 --- a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/Kapt3Plugin.kt +++ b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/Kapt3Plugin.kt @@ -33,8 +33,11 @@ import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.CompilerConfigurationKey import org.jetbrains.kotlin.config.JVMConfigurationKeys 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.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_PROCESSOR_CLASSPATH_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.psi.KtFile 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.platform.JvmPlatform import org.jetbrains.kotlin.utils.decodePluginOptions import java.io.ByteArrayInputStream import java.io.File @@ -314,6 +319,19 @@ class Kapt3ComponentRegistrar : ComponentRegistrar { ) 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. @@ -340,6 +358,7 @@ class Kapt3ComponentRegistrar : ComponentRegistrar { return AnalysisResult.Companion.success(bindingTrace.bindingContext, module, shouldGenerateCode = false) } } + } enum class AptMode { diff --git a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/KaptAnonymousTypeTransformer.kt b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/KaptAnonymousTypeTransformer.kt new file mode 100644 index 00000000000..58cd0ac5b67 --- /dev/null +++ b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/KaptAnonymousTypeTransformer.kt @@ -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 + } +} \ No newline at end of file diff --git a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/AnonymousTypeHandler.kt b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/AnonymousTypeHandler.kt deleted file mode 100644 index 5a43a9d0fca..00000000000 --- a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/AnonymousTypeHandler.kt +++ /dev/null @@ -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 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 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) - } - }) - } -} \ No newline at end of file diff --git a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt index 255d5603607..b44170d4f78 100644 --- a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt +++ b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt @@ -107,8 +107,6 @@ class ClassFileToSourceStubConverter( private val signatureParser = SignatureParser(treeMaker) - private val anonymousTypeHandler = AnonymousTypeHandler(this) - private val kdocCommentKeeper = KDocCommentKeeper(kaptContext) private var done = false @@ -479,16 +477,16 @@ class ClassFileToSourceStubConverter( val typeExpression = if (isEnum(field.access)) treeMaker.SimpleName(treeMaker.getQualifiedName(type).substringAfterLast('.')) else - anonymousTypeHandler.getNonAnonymousType(descriptor) { - getNonErrorType((descriptor as? CallableDescriptor)?.returnType, RETURN_TYPE, - ktTypeProvider = { - val fieldOrigin = (kaptContext.origins[field]?.element as? KtCallableDeclaration) - ?.takeIf { it !is KtFunction } + getNonErrorType( + (descriptor as? CallableDescriptor)?.returnType, RETURN_TYPE, + ktTypeProvider = { + val fieldOrigin = (kaptContext.origins[field]?.element as? KtCallableDeclaration) + ?.takeIf { it !is KtFunction } - fieldOrigin?.typeReference - }, - ifNonError = { signatureParser.parseFieldSignature(field.signature, treeMaker.Type(type)) }) - } + fieldOrigin?.typeReference + }, + ifNonError = { signatureParser.parseFieldSignature(field.signature, treeMaker.Type(type)) } + ) val value = field.value @@ -646,19 +644,19 @@ class ClassFileToSourceStubConverter( } }) - val returnType = anonymousTypeHandler.getNonAnonymousType(descriptor) { - getNonErrorType(descriptor.returnType, RETURN_TYPE, - ktTypeProvider = { - val element = kaptContext.origins[method]?.element - when (element) { - is KtFunction -> element.typeReference - is KtProperty -> if (descriptor is PropertyGetterDescriptor) element.typeReference else null - is KtParameter -> if (descriptor is PropertyGetterDescriptor) element.typeReference else null - else -> null - } - }, - ifNonError = { genericSignature.returnType }) - } + val returnType = getNonErrorType( + descriptor.returnType, RETURN_TYPE, + ktTypeProvider = { + val element = kaptContext.origins[method]?.element + when (element) { + is KtFunction -> element.typeReference + is KtProperty -> if (descriptor is PropertyGetterDescriptor) element.typeReference else null + is KtParameter -> if (descriptor is PropertyGetterDescriptor) element.typeReference else null + else -> null + } + }, + ifNonError = { genericSignature.returnType } + ) return Pair(genericSignature, returnType) } diff --git a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/AbstractKotlinKapt3Test.kt b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/AbstractKotlinKapt3Test.kt index a2ec230fb38..410fcb9c0b5 100644 --- a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/AbstractKotlinKapt3Test.kt +++ b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/AbstractKotlinKapt3Test.kt @@ -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.config.JvmClasspathRoot import org.jetbrains.kotlin.codegen.* +import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor 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.KaptPaths import org.jetbrains.kotlin.kapt3.base.doAnnotationProcessing @@ -105,7 +107,9 @@ abstract class AbstractKotlinKapt3Test : CodegenTestCase() { addAnnotationProcessingRuntimeLibrary(myEnvironment) // 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)