diff --git a/compiler/testData/multiModule/java/custom/a/a.kt b/compiler/testData/multiModule/java/custom/a/a.kt index f954a30920f..e2081bd7023 100644 --- a/compiler/testData/multiModule/java/custom/a/a.kt +++ b/compiler/testData/multiModule/java/custom/a/a.kt @@ -7,5 +7,5 @@ public class KotlinA: AClass() { fun paramA(p: AClass) {} - @AAnnotation fun annoA() {} + @AAnnotation(AEnum.AX) fun annoA() {} } \ No newline at end of file diff --git a/compiler/testData/multiModule/java/custom/a/custom/AAnnotation.java b/compiler/testData/multiModule/java/custom/a/custom/AAnnotation.java index df5c3e6744f..8d2be04b5c5 100644 --- a/compiler/testData/multiModule/java/custom/a/custom/AAnnotation.java +++ b/compiler/testData/multiModule/java/custom/a/custom/AAnnotation.java @@ -1,5 +1,5 @@ package custom; public @interface AAnnotation { - + AEnum value(); } \ No newline at end of file diff --git a/compiler/testData/multiModule/java/custom/a/custom/AClass.java b/compiler/testData/multiModule/java/custom/a/custom/AClass.java index 3eb480aa2ef..f9ad8973b6d 100644 --- a/compiler/testData/multiModule/java/custom/a/custom/AClass.java +++ b/compiler/testData/multiModule/java/custom/a/custom/AClass.java @@ -3,6 +3,6 @@ package custom; public class AClass { public AClass returnA() {} public void paramA(AClass a) {} - @AAnnotation + @AAnnotation(AEnum.AX) public void annoA() {} } \ No newline at end of file diff --git a/compiler/testData/multiModule/java/custom/a/custom/AEnum.java b/compiler/testData/multiModule/java/custom/a/custom/AEnum.java new file mode 100644 index 00000000000..4942fac16cd --- /dev/null +++ b/compiler/testData/multiModule/java/custom/a/custom/AEnum.java @@ -0,0 +1,5 @@ +package custom; + +public enum AEnum { + AX; +} \ No newline at end of file diff --git a/compiler/testData/multiModule/java/custom/b/b.kt b/compiler/testData/multiModule/java/custom/b/b.kt index a0cbbbf1cd0..ed4ec4919f1 100644 --- a/compiler/testData/multiModule/java/custom/b/b.kt +++ b/compiler/testData/multiModule/java/custom/b/b.kt @@ -11,7 +11,7 @@ public class KotlinB: AClass() { public fun returnB(): BClass { } - @AAnnotation fun annoA() {} + @AAnnotation(AEnum.AX) fun annoA() {} @BAnnotation fun annoB() {} } \ No newline at end of file diff --git a/compiler/testData/multiModule/java/custom/b/custom/BClass.java b/compiler/testData/multiModule/java/custom/b/custom/BClass.java index 91d26a05ae3..6e229777c13 100644 --- a/compiler/testData/multiModule/java/custom/b/custom/BClass.java +++ b/compiler/testData/multiModule/java/custom/b/custom/BClass.java @@ -3,7 +3,7 @@ package custom; public class BClass extends AClass { public AClass returnA() {} public void paramA(AClass a) {} - @AAnnotation + @AAnnotation(AEnum.AX) public void annoA() {} public BClass returnB() {} public void paramB(BClass b) {} diff --git a/compiler/testData/multiModule/java/custom/c/c.kt b/compiler/testData/multiModule/java/custom/c/c.kt index 4d8e03cc5e2..aaf87df4303 100644 --- a/compiler/testData/multiModule/java/custom/c/c.kt +++ b/compiler/testData/multiModule/java/custom/c/c.kt @@ -11,7 +11,7 @@ public class KotlinC: AClass() { public fun returnB(): BClass { } - @AAnnotation fun annoA() {} + @AAnnotation(AEnum.AX) fun annoA() {} @BAnnotation fun annoB() {} } \ No newline at end of file diff --git a/compiler/testData/multiModule/java/custom/c/custom/CClass.java b/compiler/testData/multiModule/java/custom/c/custom/CClass.java index 3a052557996..66b111909f1 100644 --- a/compiler/testData/multiModule/java/custom/c/custom/CClass.java +++ b/compiler/testData/multiModule/java/custom/c/custom/CClass.java @@ -3,7 +3,7 @@ package custom; public class CClass extends BClass { public AClass returnA() {} public void paramA(AClass a) {} - @AAnnotation + @AAnnotation(AEnum.AX) public void annoA() {} public BClass returnB() {} public void paramB(BClass b) {} diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/MultiModuleJavaAnalysisCustomTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/MultiModuleJavaAnalysisCustomTest.kt index 449631e6005..8379d15785c 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/MultiModuleJavaAnalysisCustomTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/MultiModuleJavaAnalysisCustomTest.kt @@ -34,6 +34,7 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.platform.JvmBuiltIns import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.CompilerEnvironment +import org.jetbrains.kotlin.resolve.constants.EnumValue import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.jvm.JvmAnalyzerFacade import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters @@ -85,7 +86,7 @@ class MultiModuleJavaAnalysisCustomTest : KtUsefulTestCase() { val configuration = KotlinTestUtils.compilerConfigurationForTests( ConfigurationKind.JDK_ONLY, TestJdkKind.MOCK_JDK, emptyList(), moduleDirs.toList() ) - return KotlinCoreEnvironment.createForTests(testRootDisposable!!, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) + return KotlinCoreEnvironment.createForTests(testRootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) } private fun setupModules(environment: KotlinCoreEnvironment, moduleDirs: Array): List { @@ -151,9 +152,22 @@ class MultiModuleJavaAnalysisCustomTest : KtUsefulTestCase() { it.type.constructor.declarationDescriptor!! }.forEach { checkDescriptor(it, callable) } - callable.annotations.map { - it.type.constructor.declarationDescriptor!! - }.forEach { checkDescriptor(it, callable) } + callable.annotations.forEach { + val annotationClassDescriptor = it.type.constructor.declarationDescriptor as ClassDescriptor + checkDescriptor(annotationClassDescriptor, callable) + + Assert.assertEquals( + "Annotation value arguments number is not equal to number of parameters in $callable", + annotationClassDescriptor.constructors.single().valueParameters.size, it.allValueArguments.size) + + it.allValueArguments.forEach { + val argument = it.value + if (argument is EnumValue) { + Assert.assertEquals("Enum entry name should be X", "X", argument.value.name.identifier.last().toString()) + checkDescriptor(argument.value, callable) + } + } + } } private fun checkSupertypes(classDescriptor: ClassDescriptor) { diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/LazyJavaPackageFragmentProvider.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/LazyJavaPackageFragmentProvider.kt index 921ea7490a0..68d99a875f3 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/LazyJavaPackageFragmentProvider.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/LazyJavaPackageFragmentProvider.kt @@ -16,26 +16,18 @@ package org.jetbrains.kotlin.load.java.lazy -import org.jetbrains.kotlin.builtins.ReflectionTypes -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentProvider -import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment -import org.jetbrains.kotlin.load.java.structure.JavaClass import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.storage.MemoizedFunctionToNullable import org.jetbrains.kotlin.utils.emptyOrSingletonList class LazyJavaPackageFragmentProvider( - components: JavaResolverComponents, - module: ModuleDescriptor, - reflectionTypes: ReflectionTypes + components: JavaResolverComponents ) : PackageFragmentProvider { - private val c = - LazyJavaResolverContext(components, this, FragmentClassResolver(), module, reflectionTypes, TypeParameterResolver.EMPTY) + private val c = LazyJavaResolverContext(components, TypeParameterResolver.EMPTY) private val packageFragments: MemoizedFunctionToNullable = c.storageManager.createMemoizedFunctionWithNullableValues { @@ -53,24 +45,4 @@ class LazyJavaPackageFragmentProvider( override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean) = getPackageFragment(fqName)?.getSubPackageFqNames().orEmpty() - - fun getClass(javaClass: JavaClass): ClassDescriptor? = c.javaClassResolver.resolveClass(javaClass) - - private inner class FragmentClassResolver : LazyJavaClassResolver { - override fun resolveClass(javaClass: JavaClass): ClassDescriptor? { - val fqName = javaClass.fqName - if (fqName != null && javaClass.isKotlinLightClass) { - return c.components.javaResolverCache.getClassResolvedFromSource(fqName) - } - - javaClass.outerClass?.let { outerClass -> - val outerClassScope = resolveClass(outerClass)?.unsubstitutedInnerClassesScope - return outerClassScope?.getContributedClassifier(javaClass.name, NoLookupLocation.FROM_JAVA_LOADER) as? ClassDescriptor - } - - if (fqName == null) return null - - return getPackageFragment(fqName.parent())?.findClassifierByJavaClass(javaClass) - } - } } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/context.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/context.kt index 2548e5cca55..a2d086360a0 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/context.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/context.kt @@ -47,7 +47,9 @@ class JavaResolverComponents( val moduleClassResolver: ModuleClassResolver, val packageMapper: PackagePartProvider, val supertypeLoopChecker: SupertypeLoopChecker, - val lookupTracker: LookupTracker + val lookupTracker: LookupTracker, + val module: ModuleDescriptor, + val reflectionTypes: ReflectionTypes ) { fun replace( javaResolverCache: JavaResolverCache = this.javaResolverCache @@ -55,30 +57,28 @@ class JavaResolverComponents( storageManager, finder, kotlinClassFinder, deserializedDescriptorResolver, externalAnnotationResolver, signaturePropagator, errorReporter, javaResolverCache, javaPropertyInitializerEvaluator, samConversionResolver, sourceElementFactory, - moduleClassResolver, packageMapper, supertypeLoopChecker, lookupTracker) + moduleClassResolver, packageMapper, supertypeLoopChecker, lookupTracker, module, reflectionTypes) } open class LazyJavaResolverContext( val components: JavaResolverComponents, - val packageFragmentProvider: LazyJavaPackageFragmentProvider, - val javaClassResolver: LazyJavaClassResolver, - val module: ModuleDescriptor, - val reflectionTypes: ReflectionTypes, val typeParameterResolver: TypeParameterResolver ) { val typeResolver = LazyJavaTypeResolver(this, typeParameterResolver) val storageManager: StorageManager get() = components.storageManager + + val module: ModuleDescriptor get() = components.module } fun LazyJavaResolverContext.child( typeParameterResolver: TypeParameterResolver -) = LazyJavaResolverContext(components, packageFragmentProvider, javaClassResolver, module, reflectionTypes, typeParameterResolver) +) = LazyJavaResolverContext(components, typeParameterResolver) fun LazyJavaResolverContext.replaceComponents( components: JavaResolverComponents -) = LazyJavaResolverContext(components, packageFragmentProvider, javaClassResolver, module, reflectionTypes, typeParameterResolver) +) = LazyJavaResolverContext(components, typeParameterResolver) fun LazyJavaResolverContext.child( containingDeclaration: DeclarationDescriptor, diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt index cf3a2b84512..fdd9aff5b07 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt @@ -118,8 +118,7 @@ class LazyJavaAnnotationDescriptor( val containingJavaClass = element.containingClass - //TODO: (module refactoring) moduleClassResolver should be used here - val enumClass = c.javaClassResolver.resolveClass(containingJavaClass) ?: return null + val enumClass = c.components.moduleClassResolver.resolveClass(containingJavaClass) ?: return null val classifier = enumClass.unsubstitutedInnerClassesScope.getContributedClassifier(element.name, NoLookupLocation.FROM_JAVA_LOADER) if (classifier !is ClassDescriptor) return null diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/resolvers.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/resolvers.kt index 616caae30c0..bcd3e408061 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/resolvers.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/resolvers.kt @@ -16,20 +16,13 @@ package org.jetbrains.kotlin.load.java.lazy -import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaTypeParameterDescriptor -import org.jetbrains.kotlin.load.java.structure.JavaClass import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter import org.jetbrains.kotlin.load.java.structure.JavaTypeParameterListOwner import org.jetbrains.kotlin.utils.mapToIndex -//TODO: (module refactoring) usages of this interface should be replaced by ModuleClassResolver -interface LazyJavaClassResolver { - fun resolveClass(javaClass: JavaClass): ClassDescriptor? -} - interface TypeParameterResolver { object EMPTY : TypeParameterResolver { override fun resolveTypeParameter(javaTypeParameter: JavaTypeParameter): TypeParameterDescriptor? = null diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt index 46c5c930b12..98fd5370ab2 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt @@ -133,7 +133,7 @@ class LazyJavaTypeResolver( private fun mapKotlinClass(fqName: FqName): ClassDescriptor? { if (attr.isForAnnotationParameter && fqName == JAVA_LANG_CLASS_FQ_NAME) { - return c.reflectionTypes.kClass + return c.components.reflectionTypes.kClass } val javaToKotlin = JavaToKotlinClassMap.INSTANCE diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/resolve/jvm/JavaDescriptorResolver.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/resolve/jvm/JavaDescriptorResolver.kt index d35bc8baeb5..6ceab0b3ac8 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/resolve/jvm/JavaDescriptorResolver.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/resolve/jvm/JavaDescriptorResolver.kt @@ -17,11 +17,28 @@ package org.jetbrains.kotlin.resolve.jvm import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.incremental.components.NoLookupLocation +import org.jetbrains.kotlin.load.java.components.JavaResolverCache import org.jetbrains.kotlin.load.java.lazy.LazyJavaPackageFragmentProvider import org.jetbrains.kotlin.load.java.structure.JavaClass -class JavaDescriptorResolver(val packageFragmentProvider: LazyJavaPackageFragmentProvider) { +class JavaDescriptorResolver( + val packageFragmentProvider: LazyJavaPackageFragmentProvider, + private val javaResolverCache: JavaResolverCache +) { fun resolveClass(javaClass: JavaClass): ClassDescriptor? { - return packageFragmentProvider.getClass(javaClass) + val fqName = javaClass.fqName + if (fqName != null && javaClass.isKotlinLightClass) { + return javaResolverCache.getClassResolvedFromSource(fqName) + } + + javaClass.outerClass?.let { outerClass -> + val outerClassScope = resolveClass(outerClass)?.unsubstitutedInnerClassesScope + return outerClassScope?.getContributedClassifier(javaClass.name, NoLookupLocation.FROM_JAVA_LOADER) as? ClassDescriptor + } + + if (fqName == null) return null + + return packageFragmentProvider.getPackageFragments(fqName.parent()).firstOrNull()?.findClassifierByJavaClass(javaClass) } } diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/kotlin/reflect/RuntimeModuleData.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/kotlin/reflect/RuntimeModuleData.kt index 5a38b926a07..4c471d65de7 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/kotlin/reflect/RuntimeModuleData.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/kotlin/reflect/RuntimeModuleData.kt @@ -55,19 +55,19 @@ class RuntimeModuleData private constructor(val deserialization: Deserialization val deserializedDescriptorResolver = DeserializedDescriptorResolver(RuntimeErrorReporter) val singleModuleClassResolver = SingleModuleClassResolver() val runtimePackageFacadeProvider = RuntimePackagePartProvider(classLoader) + val javaResolverCache = JavaResolverCache.EMPTY val globalJavaResolverContext = JavaResolverComponents( storageManager, ReflectJavaClassFinder(classLoader), reflectKotlinClassFinder, deserializedDescriptorResolver, - ExternalAnnotationResolver.EMPTY, SignaturePropagator.DO_NOTHING, RuntimeErrorReporter, JavaResolverCache.EMPTY, + ExternalAnnotationResolver.EMPTY, SignaturePropagator.DO_NOTHING, RuntimeErrorReporter, javaResolverCache, JavaPropertyInitializerEvaluator.DoNothing, SamConversionResolver, RuntimeSourceElementFactory, singleModuleClassResolver, - runtimePackageFacadeProvider, SupertypeLoopChecker.EMPTY, LookupTracker.DO_NOTHING + runtimePackageFacadeProvider, SupertypeLoopChecker.EMPTY, LookupTracker.DO_NOTHING, module, ReflectionTypes(module) ) - val lazyJavaPackageFragmentProvider = - LazyJavaPackageFragmentProvider(globalJavaResolverContext, module, ReflectionTypes(module)) + val lazyJavaPackageFragmentProvider = LazyJavaPackageFragmentProvider(globalJavaResolverContext) builtIns.setOwnerModuleDescriptor(module) - val javaDescriptorResolver = JavaDescriptorResolver(lazyJavaPackageFragmentProvider) + val javaDescriptorResolver = JavaDescriptorResolver(lazyJavaPackageFragmentProvider, javaResolverCache) val javaClassDataFinder = JavaClassDataFinder(reflectKotlinClassFinder, deserializedDescriptorResolver) val notFoundClasses = NotFoundClasses(storageManager, module) val binaryClassAnnotationAndConstantLoader = BinaryClassAnnotationAndConstantLoaderImpl(